Commit 94c4c8e7 by Jim Stichnoth

Subzero: Fix emission of 16-bit immediates.

The operand type needs to be propagated into EmitImmediate() and EmitComplex() so that we know whether to emit the 2-byte or 4-byte form. BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/607353002
parent fddef241
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
namespace Ice { namespace Ice {
namespace x86 { namespace x86 {
const Type BrokenType = IceType_i32;
class DirectCallRelocation : public AssemblerFixup { class DirectCallRelocation : public AssemblerFixup {
public: public:
static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind, static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind,
...@@ -105,7 +107,7 @@ void AssemblerX86::pushl(const Address &address) { ...@@ -105,7 +107,7 @@ void AssemblerX86::pushl(const Address &address) {
void AssemblerX86::pushl(const Immediate &imm) { void AssemblerX86::pushl(const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x68); EmitUint8(0x68);
EmitImmediate(imm); EmitImmediate(BrokenType, imm);
} }
void AssemblerX86::popl(GPRRegister reg) { void AssemblerX86::popl(GPRRegister reg) {
...@@ -139,7 +141,7 @@ void AssemblerX86::setcc(CondX86::BrCond condition, ByteRegister dst) { ...@@ -139,7 +141,7 @@ void AssemblerX86::setcc(CondX86::BrCond condition, ByteRegister dst) {
void AssemblerX86::movl(GPRRegister dst, const Immediate &imm) { void AssemblerX86::movl(GPRRegister dst, const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xB8 + dst); EmitUint8(0xB8 + dst);
EmitImmediate(imm); EmitImmediate(BrokenType, imm);
} }
void AssemblerX86::movl(GPRRegister dst, GPRRegister src) { void AssemblerX86::movl(GPRRegister dst, GPRRegister src) {
...@@ -164,7 +166,7 @@ void AssemblerX86::movl(const Address &dst, const Immediate &imm) { ...@@ -164,7 +166,7 @@ void AssemblerX86::movl(const Address &dst, const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xC7); EmitUint8(0xC7);
EmitOperand(0, dst); EmitOperand(0, dst);
EmitImmediate(imm); EmitImmediate(BrokenType, imm);
} }
void AssemblerX86::movzxb(GPRRegister dst, ByteRegister src) { void AssemblerX86::movzxb(GPRRegister dst, ByteRegister src) {
...@@ -1131,7 +1133,7 @@ void AssemblerX86::fincstp() { ...@@ -1131,7 +1133,7 @@ void AssemblerX86::fincstp() {
void AssemblerX86::cmpl(GPRRegister reg, const Immediate &imm) { void AssemblerX86::cmpl(GPRRegister reg, const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitComplex(7, Operand(reg), imm); EmitComplex(BrokenType, 7, Operand(reg), imm);
} }
void AssemblerX86::cmpl(GPRRegister reg0, GPRRegister reg1) { void AssemblerX86::cmpl(GPRRegister reg0, GPRRegister reg1) {
...@@ -1154,7 +1156,7 @@ void AssemblerX86::cmpl(const Address &address, GPRRegister reg) { ...@@ -1154,7 +1156,7 @@ void AssemblerX86::cmpl(const Address &address, GPRRegister reg) {
void AssemblerX86::cmpl(const Address &address, const Immediate &imm) { void AssemblerX86::cmpl(const Address &address, const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitComplex(7, address, imm); EmitComplex(BrokenType, 7, address, imm);
} }
void AssemblerX86::cmpb(const Address &address, const Immediate &imm) { void AssemblerX86::cmpb(const Address &address, const Immediate &imm) {
...@@ -1187,11 +1189,11 @@ void AssemblerX86::testl(GPRRegister reg, const Immediate &immediate) { ...@@ -1187,11 +1189,11 @@ void AssemblerX86::testl(GPRRegister reg, const Immediate &immediate) {
} else if (reg == RegX8632::Encoded_Reg_eax) { } else if (reg == RegX8632::Encoded_Reg_eax) {
// Use short form if the destination is EAX. // Use short form if the destination is EAX.
EmitUint8(0xA9); EmitUint8(0xA9);
EmitImmediate(immediate); EmitImmediate(BrokenType, immediate);
} else { } else {
EmitUint8(0xF7); EmitUint8(0xF7);
EmitOperand(0, Operand(reg)); EmitOperand(0, Operand(reg));
EmitImmediate(immediate); EmitImmediate(BrokenType, immediate);
} }
} }
...@@ -1225,7 +1227,7 @@ void AssemblerX86::And(Type Ty, GPRRegister dst, const Immediate &imm) { ...@@ -1225,7 +1227,7 @@ void AssemblerX86::And(Type Ty, GPRRegister dst, const Immediate &imm) {
} }
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
EmitComplex(4, Operand(dst), imm); EmitComplex(Ty, 4, Operand(dst), imm);
} }
void AssemblerX86::Or(Type Ty, GPRRegister dst, GPRRegister src) { void AssemblerX86::Or(Type Ty, GPRRegister dst, GPRRegister src) {
...@@ -1258,7 +1260,7 @@ void AssemblerX86::Or(Type Ty, GPRRegister dst, const Immediate &imm) { ...@@ -1258,7 +1260,7 @@ void AssemblerX86::Or(Type Ty, GPRRegister dst, const Immediate &imm) {
} }
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
EmitComplex(1, Operand(dst), imm); EmitComplex(Ty, 1, Operand(dst), imm);
} }
void AssemblerX86::Xor(Type Ty, GPRRegister dst, GPRRegister src) { void AssemblerX86::Xor(Type Ty, GPRRegister dst, GPRRegister src) {
...@@ -1291,7 +1293,7 @@ void AssemblerX86::Xor(Type Ty, GPRRegister dst, const Immediate &imm) { ...@@ -1291,7 +1293,7 @@ void AssemblerX86::Xor(Type Ty, GPRRegister dst, const Immediate &imm) {
} }
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
EmitComplex(6, Operand(dst), imm); EmitComplex(Ty, 6, Operand(dst), imm);
} }
void AssemblerX86::add(Type Ty, GPRRegister dst, GPRRegister src) { void AssemblerX86::add(Type Ty, GPRRegister dst, GPRRegister src) {
...@@ -1324,7 +1326,7 @@ void AssemblerX86::add(Type Ty, GPRRegister reg, const Immediate &imm) { ...@@ -1324,7 +1326,7 @@ void AssemblerX86::add(Type Ty, GPRRegister reg, const Immediate &imm) {
} }
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
EmitComplex(0, Operand(reg), imm); EmitComplex(Ty, 0, Operand(reg), imm);
} }
void AssemblerX86::adc(Type Ty, GPRRegister dst, GPRRegister src) { void AssemblerX86::adc(Type Ty, GPRRegister dst, GPRRegister src) {
...@@ -1357,7 +1359,7 @@ void AssemblerX86::adc(Type Ty, GPRRegister reg, const Immediate &imm) { ...@@ -1357,7 +1359,7 @@ void AssemblerX86::adc(Type Ty, GPRRegister reg, const Immediate &imm) {
} }
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
EmitComplex(2, Operand(reg), imm); EmitComplex(Ty, 2, Operand(reg), imm);
} }
void AssemblerX86::sub(Type Ty, GPRRegister dst, GPRRegister src) { void AssemblerX86::sub(Type Ty, GPRRegister dst, GPRRegister src) {
...@@ -1390,7 +1392,7 @@ void AssemblerX86::sub(Type Ty, GPRRegister reg, const Immediate &imm) { ...@@ -1390,7 +1392,7 @@ void AssemblerX86::sub(Type Ty, GPRRegister reg, const Immediate &imm) {
} }
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
EmitComplex(5, Operand(reg), imm); EmitComplex(Ty, 5, Operand(reg), imm);
} }
void AssemblerX86::sbb(Type Ty, GPRRegister dst, GPRRegister src) { void AssemblerX86::sbb(Type Ty, GPRRegister dst, GPRRegister src) {
...@@ -1423,7 +1425,7 @@ void AssemblerX86::sbb(Type Ty, GPRRegister reg, const Immediate &imm) { ...@@ -1423,7 +1425,7 @@ void AssemblerX86::sbb(Type Ty, GPRRegister reg, const Immediate &imm) {
} }
if (Ty == IceType_i16) if (Ty == IceType_i16)
EmitOperandSizeOverride(); EmitOperandSizeOverride();
EmitComplex(3, Operand(reg), imm); EmitComplex(Ty, 3, Operand(reg), imm);
} }
void AssemblerX86::cbw() { void AssemblerX86::cbw() {
...@@ -1498,7 +1500,7 @@ void AssemblerX86::imull(GPRRegister reg, const Immediate &imm) { ...@@ -1498,7 +1500,7 @@ void AssemblerX86::imull(GPRRegister reg, const Immediate &imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_); AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x69); EmitUint8(0x69);
EmitOperand(reg, Operand(reg)); EmitOperand(reg, Operand(reg));
EmitImmediate(imm); EmitImmediate(BrokenType, imm);
} }
void AssemblerX86::imull(GPRRegister reg, const Address &address) { void AssemblerX86::imull(GPRRegister reg, const Address &address) {
...@@ -1987,8 +1989,11 @@ void AssemblerX86::EmitOperand(int rm, const Operand &operand) { ...@@ -1987,8 +1989,11 @@ void AssemblerX86::EmitOperand(int rm, const Operand &operand) {
} }
} }
void AssemblerX86::EmitImmediate(const Immediate &imm) { void AssemblerX86::EmitImmediate(Type Ty, const Immediate &imm) {
EmitInt32(imm.value()); if (Ty == IceType_i16)
EmitInt16(imm.value());
else
EmitInt32(imm.value());
} }
void AssemblerX86::EmitComplexI8(int rm, const Operand &operand, void AssemblerX86::EmitComplexI8(int rm, const Operand &operand,
...@@ -2007,7 +2012,7 @@ void AssemblerX86::EmitComplexI8(int rm, const Operand &operand, ...@@ -2007,7 +2012,7 @@ void AssemblerX86::EmitComplexI8(int rm, const Operand &operand,
} }
} }
void AssemblerX86::EmitComplex(int rm, const Operand &operand, void AssemblerX86::EmitComplex(Type Ty, int rm, const Operand &operand,
const Immediate &immediate) { const Immediate &immediate) {
assert(rm >= 0 && rm < 8); assert(rm >= 0 && rm < 8);
if (immediate.is_int8()) { if (immediate.is_int8()) {
...@@ -2018,11 +2023,11 @@ void AssemblerX86::EmitComplex(int rm, const Operand &operand, ...@@ -2018,11 +2023,11 @@ void AssemblerX86::EmitComplex(int rm, const Operand &operand,
} else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) { } else if (operand.IsRegister(RegX8632::Encoded_Reg_eax)) {
// Use short form if the destination is eax. // Use short form if the destination is eax.
EmitUint8(0x05 + (rm << 3)); EmitUint8(0x05 + (rm << 3));
EmitImmediate(immediate); EmitImmediate(Ty, immediate);
} else { } else {
EmitUint8(0x81); EmitUint8(0x81);
EmitOperand(rm, operand); EmitOperand(rm, operand);
EmitImmediate(immediate); EmitImmediate(Ty, immediate);
} }
} }
......
...@@ -700,6 +700,7 @@ public: ...@@ -700,6 +700,7 @@ public:
private: private:
inline void EmitUint8(uint8_t value); inline void EmitUint8(uint8_t value);
inline void EmitInt16(int16_t value);
inline void EmitInt32(int32_t value); inline void EmitInt32(int32_t value);
inline void EmitRegisterOperand(int rm, int reg); inline void EmitRegisterOperand(int rm, int reg);
inline void EmitXmmRegisterOperand(int rm, XmmRegister reg); inline void EmitXmmRegisterOperand(int rm, XmmRegister reg);
...@@ -707,10 +708,11 @@ private: ...@@ -707,10 +708,11 @@ private:
inline void EmitOperandSizeOverride(); inline void EmitOperandSizeOverride();
void EmitOperand(int rm, const Operand &operand); void EmitOperand(int rm, const Operand &operand);
void EmitImmediate(const Immediate &imm); void EmitImmediate(Type ty, const Immediate &imm);
void EmitComplexI8(int rm, const Operand &operand, void EmitComplexI8(int rm, const Operand &operand,
const Immediate &immediate); const Immediate &immediate);
void EmitComplex(int rm, const Operand &operand, const Immediate &immediate); void EmitComplex(Type Ty, int rm, const Operand &operand,
const Immediate &immediate);
void EmitLabel(Label *label, intptr_t instruction_size); void EmitLabel(Label *label, intptr_t instruction_size);
void EmitLabelLink(Label *label); void EmitLabelLink(Label *label);
void EmitNearLabelLink(Label *label); void EmitNearLabelLink(Label *label);
...@@ -728,6 +730,10 @@ inline void AssemblerX86::EmitUint8(uint8_t value) { ...@@ -728,6 +730,10 @@ inline void AssemblerX86::EmitUint8(uint8_t value) {
buffer_.Emit<uint8_t>(value); buffer_.Emit<uint8_t>(value);
} }
inline void AssemblerX86::EmitInt16(int16_t value) {
buffer_.Emit<int16_t>(value);
}
inline void AssemblerX86::EmitInt32(int32_t value) { inline void AssemblerX86::EmitInt32(int32_t value) {
buffer_.Emit<int32_t>(value); buffer_.Emit<int32_t>(value);
} }
......
...@@ -44,6 +44,67 @@ entry: ...@@ -44,6 +44,67 @@ entry:
; CHECK-LABEL: testXor8Imm8NotEAX ; CHECK-LABEL: testXor8Imm8NotEAX
; CHECK: 80 f{{[1-3]}} 7f xor {{[^a]}}l, 127 ; CHECK: 80 f{{[1-3]}} 7f xor {{[^a]}}l, 127
define internal i32 @testXor16Imm8(i32 %arg) {
entry:
%arg_i16 = trunc i32 %arg to i16
%result_i16 = xor i16 %arg_i16, 127
%result = zext i16 %result_i16 to i32
ret i32 %result
}
; CHECK-LABEL: testXor16Imm8
; CHECK: 66 83 f0 7f xor ax, 127
define internal i32 @testXor16Imm8Neg(i32 %arg) {
entry:
%arg_i16 = trunc i32 %arg to i16
%result_i16 = xor i16 %arg_i16, -128
%result = zext i16 %result_i16 to i32
ret i32 %result
}
; CHECK-LABEL: testXor16Imm8Neg
; CHECK: 66 83 f0 80 xor ax, 128
define internal i32 @testXor16Imm16Eax(i32 %arg) {
entry:
%arg_i16 = trunc i32 %arg to i16
%tmp = xor i16 %arg_i16, 1024
%result_i16 = add i16 %tmp, 1
%result = zext i16 %result_i16 to i32
ret i32 %result
}
; CHECK-LABEL: testXor16Imm16Eax
; CHECK: 66 35 00 04 xor ax, 1024
; CHECK-NEXT: add ax, 1
define internal i32 @testXor16Imm16NegEax(i32 %arg) {
entry:
%arg_i16 = trunc i32 %arg to i16
%tmp = xor i16 %arg_i16, -256
%result_i16 = add i16 %tmp, 1
%result = zext i16 %result_i16 to i32
ret i32 %result
}
; CHECK-LABEL: testXor16Imm16NegEax
; CHECK: 66 35 00 ff xor ax, 65280
; CHECK-NEXT: add ax, 1
define internal i32 @testXor16Imm16NotEAX(i32 %arg_i32, i32 %arg2_i32, i32 %arg3_i32) {
entry:
%arg = trunc i32 %arg_i32 to i16
%arg2 = trunc i32 %arg2_i32 to i16
%arg3 = trunc i32 %arg3_i32 to i16
%x = xor i16 %arg, 32767
%x2 = xor i16 %arg2, 32767
%x3 = xor i16 %arg3, 32767
%add1 = add i16 %x, %x2
%add2 = add i16 %add1, %x3
%result = zext i16 %add2 to i32
ret i32 %result
}
; CHECK-LABEL: testXor16Imm16NotEAX
; CHECK: 66 81 f{{[1-3]}} ff 7f xor {{[^a]}}x, 32767
; CHECK-NEXT: 66 81 f{{[1-3]}} ff 7f xor {{[^a]}}x, 32767
define internal i32 @testXor32Imm8(i32 %arg) { define internal i32 @testXor32Imm8(i32 %arg) {
entry: entry:
%result = xor i32 %arg, 127 %result = xor i32 %arg, 127
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment