diff options
Diffstat (limited to 'compiler/utils')
| -rw-r--r-- | compiler/utils/arm/assembler_arm.h | 4 | ||||
| -rw-r--r-- | compiler/utils/arm/assembler_thumb2.cc | 35 | ||||
| -rw-r--r-- | compiler/utils/arm/assembler_thumb2_test.cc | 10 | ||||
| -rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 30 | ||||
| -rw-r--r-- | compiler/utils/x86/assembler_x86.h | 5 |
5 files changed, 69 insertions, 15 deletions
diff --git a/compiler/utils/arm/assembler_arm.h b/compiler/utils/arm/assembler_arm.h index 8730f52eca..dd0dba2df4 100644 --- a/compiler/utils/arm/assembler_arm.h +++ b/compiler/utils/arm/assembler_arm.h @@ -100,6 +100,10 @@ class ShifterOperand { return rm_; } + Register GetSecondRegister() const { + return rs_; + } + enum Type { kUnknown = -1, kRegister, diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc index 6d0571e263..e8eb019af3 100644 --- a/compiler/utils/arm/assembler_thumb2.cc +++ b/compiler/utils/arm/assembler_thumb2.cc @@ -826,7 +826,9 @@ void Thumb2Assembler::Emit32BitDataProcessing(Condition cond ATTRIBUTE_UNUSED, // Check special cases. if ((opcode == SUB || opcode == ADD) && (so.GetImmediate() < (1u << 12))) { if (opcode == SUB) { - thumb_opcode = 5U /* 0b0101 */; + if (!set_cc) { + thumb_opcode = 5U /* 0b0101 */; + } } else { thumb_opcode = 0; } @@ -836,13 +838,14 @@ void Thumb2Assembler::Emit32BitDataProcessing(Condition cond ATTRIBUTE_UNUSED, uint32_t imm3 = (imm >> 8) & 7U /* 0b111 */; uint32_t imm8 = imm & 0xff; - encoding = B31 | B30 | B29 | B28 | B25 | - thumb_opcode << 21 | - rn << 16 | - rd << 8 | - i << 26 | - imm3 << 12 | - imm8; + encoding = B31 | B30 | B29 | B28 | + (set_cc ? B20 : B25) | + thumb_opcode << 21 | + rn << 16 | + rd << 8 | + i << 26 | + imm3 << 12 | + imm8; } else { // Modified immediate. uint32_t imm = ModifiedImmediate(so.encodingThumb()); @@ -858,13 +861,13 @@ void Thumb2Assembler::Emit32BitDataProcessing(Condition cond ATTRIBUTE_UNUSED, imm; } } else if (so.IsRegister()) { - // Register (possibly shifted) - encoding = B31 | B30 | B29 | B27 | B25 | - thumb_opcode << 21 | - (set_cc ? 1 : 0) << 20 | - rn << 16 | - rd << 8 | - so.encodingThumb(); + // Register (possibly shifted) + encoding = B31 | B30 | B29 | B27 | B25 | + thumb_opcode << 21 | + (set_cc ? 1 : 0) << 20 | + rn << 16 | + rd << 8 | + so.encodingThumb(); } Emit32(encoding); } @@ -921,6 +924,8 @@ void Thumb2Assembler::Emit16BitDataProcessing(Condition cond, use_immediate = true; immediate = so.GetImmediate(); } else { + CHECK(!(so.IsRegister() && so.IsShift() && so.GetSecondRegister() != kNoRegister)) + << "No register-shifted register instruction available in thumb"; // Adjust rn and rd: only two registers will be emitted. switch (opcode) { case AND: diff --git a/compiler/utils/arm/assembler_thumb2_test.cc b/compiler/utils/arm/assembler_thumb2_test.cc index ebea9d4262..d802852caf 100644 --- a/compiler/utils/arm/assembler_thumb2_test.cc +++ b/compiler/utils/arm/assembler_thumb2_test.cc @@ -227,4 +227,14 @@ TEST_F(AssemblerThumb2Test, eor) { DriverStr(expected, "abs"); } +TEST_F(AssemblerThumb2Test, sub) { + __ subs(arm::R1, arm::R0, arm::ShifterOperand(42)); + __ sub(arm::R1, arm::R0, arm::ShifterOperand(42)); + + const char* expected = + "subs r1, r0, #42\n" + "subw r1, r0, #42\n"; + DriverStr(expected, "sub"); +} + } // namespace art diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index 8f4208b417..90170ceed5 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -451,6 +451,36 @@ void X86Assembler::movsd(XmmRegister dst, XmmRegister src) { } +void X86Assembler::movhpd(XmmRegister dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x16); + EmitOperand(dst, src); +} + + +void X86Assembler::movhpd(const Address& dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x17); + EmitOperand(src, dst); +} + + +void X86Assembler::psrldq(XmmRegister reg, const Immediate& shift_count) { + DCHECK(shift_count.is_uint8()); + + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x73); + EmitXmmRegisterOperand(3, reg); + EmitUint8(shift_count.value()); +} + + void X86Assembler::psrlq(XmmRegister reg, const Immediate& shift_count) { DCHECK(shift_count.is_uint8()); diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index 2dde90744e..4d20db03a9 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -277,6 +277,11 @@ class X86Assembler FINAL : public Assembler { void psrlq(XmmRegister reg, const Immediate& shift_count); void punpckldq(XmmRegister dst, XmmRegister src); + void movhpd(XmmRegister dst, const Address& src); + void movhpd(const Address& dst, XmmRegister src); + + void psrldq(XmmRegister reg, const Immediate& shift_count); + void addsd(XmmRegister dst, XmmRegister src); void addsd(XmmRegister dst, const Address& src); void subsd(XmmRegister dst, XmmRegister src); |