diff options
| -rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 24 | ||||
| -rw-r--r-- | compiler/utils/x86/assembler_x86.h | 6 | ||||
| -rw-r--r-- | compiler/utils/x86/assembler_x86_test.cc | 4 | ||||
| -rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.cc | 23 | ||||
| -rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 6 | ||||
| -rw-r--r-- | compiler/utils/x86_64/assembler_x86_64_test.cc | 5 |
6 files changed, 54 insertions, 14 deletions
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index 9fcede5e97..8640e2db0e 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -2100,6 +2100,14 @@ void X86Assembler::addl(const Address& address, const Immediate& imm) { } +void X86Assembler::addw(const Address& address, const Immediate& imm) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + CHECK(imm.is_uint16() || imm.is_int16()) << imm.value(); + EmitUint8(0x66); + EmitComplex(0, address, imm, /* is_16_op */ true); +} + + void X86Assembler::adcl(Register reg, const Immediate& imm) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitComplex(2, Operand(reg), imm); @@ -2751,14 +2759,20 @@ void X86Assembler::EmitOperand(int reg_or_opcode, const Operand& operand) { } -void X86Assembler::EmitImmediate(const Immediate& imm) { - EmitInt32(imm.value()); +void X86Assembler::EmitImmediate(const Immediate& imm, bool is_16_op) { + if (is_16_op) { + EmitUint8(imm.value() & 0xFF); + EmitUint8(imm.value() >> 8); + } else { + EmitInt32(imm.value()); + } } void X86Assembler::EmitComplex(int reg_or_opcode, const Operand& operand, - const Immediate& immediate) { + const Immediate& immediate, + bool is_16_op) { CHECK_GE(reg_or_opcode, 0); CHECK_LT(reg_or_opcode, 8); if (immediate.is_int8()) { @@ -2769,11 +2783,11 @@ void X86Assembler::EmitComplex(int reg_or_opcode, } else if (operand.IsRegister(EAX)) { // Use short form if the destination is eax. EmitUint8(0x05 + (reg_or_opcode << 3)); - EmitImmediate(immediate); + EmitImmediate(immediate, is_16_op); } else { EmitUint8(0x81); EmitOperand(reg_or_opcode, operand); - EmitImmediate(immediate); + EmitImmediate(immediate, is_16_op); } } diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index f3b516cb7e..a085677083 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -634,6 +634,7 @@ class X86Assembler FINAL : public Assembler { void addl(const Address& address, Register reg); void addl(const Address& address, const Immediate& imm); + void addw(const Address& address, const Immediate& imm); void adcl(Register dst, Register src); void adcl(Register reg, const Immediate& imm); @@ -817,8 +818,9 @@ class X86Assembler FINAL : public Assembler { inline void EmitOperandSizeOverride(); void EmitOperand(int rm, const Operand& operand); - void EmitImmediate(const Immediate& imm); - void EmitComplex(int rm, const Operand& operand, const Immediate& immediate); + void EmitImmediate(const Immediate& imm, bool is_16_op = false); + void EmitComplex( + int rm, const Operand& operand, const Immediate& immediate, bool is_16_op = false); void EmitLabel(Label* label, int instruction_size); void EmitLabelLink(Label* label); void EmitLabelLink(NearLabel* label); diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc index 36c5c3c0c4..937dd80c4e 100644 --- a/compiler/utils/x86/assembler_x86_test.cc +++ b/compiler/utils/x86/assembler_x86_test.cc @@ -258,6 +258,10 @@ TEST_F(AssemblerX86Test, MovlLoad) { DriverStr(RepeatRA(&x86::X86Assembler::movl, "movl {mem}, %{reg}"), "movl-load"); } +TEST_F(AssemblerX86Test, Addw) { + DriverStr(RepeatAI(&x86::X86Assembler::addw, /*imm_bytes*/ 2U, "addw ${imm}, {mem}"), "addw"); +} + TEST_F(AssemblerX86Test, MovlStore) { DriverStr(RepeatAR(&x86::X86Assembler::movl, "movl %{reg}, {mem}"), "movl-store"); } diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index 51f61ca756..feabf260af 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -2608,6 +2608,15 @@ void X86_64Assembler::addl(const Address& address, const Immediate& imm) { } +void X86_64Assembler::addw(const Address& address, const Immediate& imm) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + CHECK(imm.is_uint16() || imm.is_int16()) << imm.value(); + EmitUint8(0x66); + EmitOptionalRex32(address); + EmitComplex(0, address, imm, /* is_16_op */ true); +} + + void X86_64Assembler::subl(CpuRegister dst, CpuRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitOptionalRex32(dst, src); @@ -3387,8 +3396,11 @@ void X86_64Assembler::EmitOperand(uint8_t reg_or_opcode, const Operand& operand) } -void X86_64Assembler::EmitImmediate(const Immediate& imm) { - if (imm.is_int32()) { +void X86_64Assembler::EmitImmediate(const Immediate& imm, bool is_16_op) { + if (is_16_op) { + EmitUint8(imm.value() & 0xFF); + EmitUint8(imm.value() >> 8); + } else if (imm.is_int32()) { EmitInt32(static_cast<int32_t>(imm.value())); } else { EmitInt64(imm.value()); @@ -3398,7 +3410,8 @@ void X86_64Assembler::EmitImmediate(const Immediate& imm) { void X86_64Assembler::EmitComplex(uint8_t reg_or_opcode, const Operand& operand, - const Immediate& immediate) { + const Immediate& immediate, + bool is_16_op) { CHECK_GE(reg_or_opcode, 0); CHECK_LT(reg_or_opcode, 8); if (immediate.is_int8()) { @@ -3409,11 +3422,11 @@ void X86_64Assembler::EmitComplex(uint8_t reg_or_opcode, } else if (operand.IsRegister(CpuRegister(RAX))) { // Use short form if the destination is eax. EmitUint8(0x05 + (reg_or_opcode << 3)); - EmitImmediate(immediate); + EmitImmediate(immediate, is_16_op); } else { EmitUint8(0x81); EmitOperand(reg_or_opcode, operand); - EmitImmediate(immediate); + EmitImmediate(immediate, is_16_op); } } diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index 0d24a751c0..7a5fdb502f 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -693,6 +693,7 @@ class X86_64Assembler FINAL : public Assembler { void addl(CpuRegister reg, const Address& address); void addl(const Address& address, CpuRegister reg); void addl(const Address& address, const Immediate& imm); + void addw(const Address& address, const Immediate& imm); void addq(CpuRegister reg, const Immediate& imm); void addq(CpuRegister dst, CpuRegister src); @@ -904,8 +905,9 @@ class X86_64Assembler FINAL : public Assembler { void EmitOperandSizeOverride(); void EmitOperand(uint8_t rm, const Operand& operand); - void EmitImmediate(const Immediate& imm); - void EmitComplex(uint8_t rm, const Operand& operand, const Immediate& immediate); + void EmitImmediate(const Immediate& imm, bool is_16_op = false); + void EmitComplex( + uint8_t rm, const Operand& operand, const Immediate& immediate, bool is_16_op = false); void EmitLabel(Label* label, int instruction_size); void EmitLabelLink(Label* label); void EmitLabelLink(NearLabel* label); diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc index 0cb3ffd39f..5e6c83396a 100644 --- a/compiler/utils/x86_64/assembler_x86_64_test.cc +++ b/compiler/utils/x86_64/assembler_x86_64_test.cc @@ -578,6 +578,11 @@ TEST_F(AssemblerX86_64Test, AddlImm) { "add ${imm}, %{reg}"), "addli"); } +TEST_F(AssemblerX86_64Test, Addw) { + DriverStr( + RepeatAI(&x86_64::X86_64Assembler::addw, /*imm_bytes*/2U, "addw ${imm}, {mem}"), "addw"); +} + TEST_F(AssemblerX86_64Test, ImulqReg1) { DriverStr(RepeatR(&x86_64::X86_64Assembler::imulq, "imulq %{reg}"), "imulq"); } |