summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/utils/x86/assembler_x86.cc24
-rw-r--r--compiler/utils/x86/assembler_x86.h6
-rw-r--r--compiler/utils/x86/assembler_x86_test.cc4
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.cc23
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.h6
-rw-r--r--compiler/utils/x86_64/assembler_x86_64_test.cc5
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");
}