From 6c4178330d64747201d2f20e8d8b2ede9ab4ee58 Mon Sep 17 00:00:00 2001 From: "m.m.capewell@googlemail.com" Date: Fri, 21 Mar 2014 13:04:20 +0000 Subject: [PATCH] ARM: Fix Q register encoding Fix Q register encoding for registers other than Q0. Also, fix value in NeonSize enumeration. BUG= R=ulan@chromium.org Review URL: https://codereview.chromium.org/207523005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20163 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/assembler-arm.h | 5 +++-- src/arm/constants-arm.h | 2 +- src/arm/disasm-arm.cc | 6 ++++-- src/arm/simulator-arm.cc | 6 ++++-- test/cctest/test-assembler-arm.cc | 21 ++++++++++++++++++++- test/cctest/test-disasm-arm.cc | 4 +++- 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h index 49881cf..727b054 100644 --- a/src/arm/assembler-arm.h +++ b/src/arm/assembler-arm.h @@ -379,8 +379,9 @@ struct QwNeonRegister { } void split_code(int* vm, int* m) const { ASSERT(is_valid()); - *m = (code_ & 0x10) >> 4; - *vm = code_ & 0x0F; + int encoded_code = code_ << 1; + *m = (encoded_code & 0x10) >> 4; + *vm = encoded_code & 0x0F; } int code_; diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index 78bb66c..14f4705 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -343,7 +343,7 @@ enum NeonSize { Neon8 = 0x0, Neon16 = 0x1, Neon32 = 0x2, - Neon64 = 0x4 + Neon64 = 0x3 }; // ----------------------------------------------------------------------------- diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc index 49e4126..0d9f7ec 100644 --- a/src/arm/disasm-arm.cc +++ b/src/arm/disasm-arm.cc @@ -1566,7 +1566,8 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && (instr->Bit(4) == 1)) { // vmovl signed - int Vd = (instr->Bit(22) << 4) | instr->VdValue(); + if ((instr->VdValue() & 1) != 0) Unknown(instr); + int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); int Vm = (instr->Bit(5) << 4) | instr->VmValue(); int imm3 = instr->Bits(21, 19); out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, @@ -1579,7 +1580,8 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && (instr->Bit(4) == 1)) { // vmovl unsigned - int Vd = (instr->Bit(22) << 4) | instr->VdValue(); + if ((instr->VdValue() & 1) != 0) Unknown(instr); + int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); int Vm = (instr->Bit(5) << 4) | instr->VmValue(); int imm3 = instr->Bits(21, 19); out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index a7fccdd..8f7c1e8 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -3470,7 +3470,8 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && (instr->Bit(4) == 1)) { // vmovl signed - int Vd = (instr->Bit(22) << 4) | instr->VdValue(); + if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); + int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); int Vm = (instr->Bit(5) << 4) | instr->VmValue(); int imm3 = instr->Bits(21, 19); if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); @@ -3493,7 +3494,8 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && (instr->Bit(4) == 1)) { // vmovl unsigned - int Vd = (instr->Bit(22) << 4) | instr->VdValue(); + if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); + int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); int Vm = (instr->Bit(5) << 4) | instr->VmValue(); int imm3 = instr->Bits(21, 19); if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc index b21dc34..9c1c04f 100644 --- a/test/cctest/test-assembler-arm.cc +++ b/test/cctest/test-assembler-arm.cc @@ -1266,6 +1266,10 @@ TEST(15) { uint32_t dstA1; uint32_t dstA2; uint32_t dstA3; + uint32_t dstA4; + uint32_t dstA5; + uint32_t dstA6; + uint32_t dstA7; } T; T t; @@ -1291,7 +1295,14 @@ TEST(15) { __ add(r4, r0, Operand(OFFSET_OF(T, dstA0))); __ vst1(Neon8, NeonListOperand(d0, 2), NeonMemOperand(r4)); - __ ldm(ia_w, sp, r4.bit() | pc.bit()); + // The same expansion, but with different source and destination registers. + __ add(r4, r0, Operand(OFFSET_OF(T, srcA0))); + __ vld1(Neon8, NeonListOperand(d1), NeonMemOperand(r4)); + __ vmovl(NeonU8, q1, d1); + __ add(r4, r0, Operand(OFFSET_OF(T, dstA4))); + __ vst1(Neon8, NeonListOperand(d2, 2), NeonMemOperand(r4)); + + __ ldm(ia_w, sp, r4.bit() | pc.bit()); CodeDesc desc; assm.GetCode(&desc); @@ -1326,6 +1337,10 @@ TEST(15) { t.dstA1 = 0; t.dstA2 = 0; t.dstA3 = 0; + t.dstA4 = 0; + t.dstA5 = 0; + t.dstA6 = 0; + t.dstA7 = 0; Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(0x01020304, t.dst0); @@ -1340,6 +1355,10 @@ TEST(15) { CHECK_EQ(0x00410042, t.dstA1); CHECK_EQ(0x00830084, t.dstA2); CHECK_EQ(0x00810082, t.dstA3); + CHECK_EQ(0x00430044, t.dstA4); + CHECK_EQ(0x00410042, t.dstA5); + CHECK_EQ(0x00830084, t.dstA6); + CHECK_EQ(0x00810082, t.dstA7); } } diff --git a/test/cctest/test-disasm-arm.cc b/test/cctest/test-disasm-arm.cc index 56f093e..a5a2b2f 100644 --- a/test/cctest/test-disasm-arm.cc +++ b/test/cctest/test-disasm-arm.cc @@ -687,8 +687,10 @@ TEST(Neon) { "f421420f vld1.8 {d4, d5, d6, d7}, [r1]"); COMPARE(vst1(Neon16, NeonListOperand(d17, 4), NeonMemOperand(r9)), "f449124f vst1.16 {d17, d18, d19, d20}, [r9]"); + COMPARE(vmovl(NeonU8, q3, d1), + "f3886a11 vmovl.u8 q3, d1"); COMPARE(vmovl(NeonU8, q4, d2), - "f3884a12 vmovl.u8 q4, d2"); + "f3888a12 vmovl.u8 q4, d2"); } VERIFY_RUN(); -- 2.7.4