Commit 479e5633 by Jan Voung

emitIAS for fld and fstp

BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/634333002
parent 699bf02c
......@@ -1919,7 +1919,7 @@ template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const {
assert(Dest->hasReg() && Src->hasReg());
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
Asm->movss(RegX8632::getEncodedXmm(Dest->getRegNum()),
Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()),
RegX8632::getEncodedXmm(Src->getRegNum()));
Ostream &Str = Func->getContext()->getStrEmit();
emitIASBytes(Str, Asm, StartPosition);
......@@ -2006,6 +2006,38 @@ void InstX8632Fld::emit(const Cfg *Func) const {
Str << "\n";
}
void InstX8632Fld::emitIAS(const Cfg *Func) const {
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
assert(getSrcSize() == 1);
const Operand *Src = getSrc(0);
Type Ty = Src->getType();
if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
if (Var->hasReg()) {
// This is a physical xmm register, so we need to spill it to a
// temporary stack slot.
x86::Immediate Width(typeWidthInBytes(Ty));
Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum()));
Asm->fld(Ty, StackSlot);
Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
} else {
x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
->stackVarToAsmOperand(Var));
Asm->fld(Ty, StackAddr);
}
} else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
Asm->fld(Ty, Mem->toAsmAddress(Asm));
} else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
} else {
llvm_unreachable("Unexpected operand type");
}
Ostream &Str = Func->getContext()->getStrEmit();
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Fld::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
Str << "fld." << getSrc(0)->getType() << " ";
......@@ -2015,6 +2047,10 @@ void InstX8632Fld::dump(const Cfg *Func) const {
void InstX8632Fstp::emit(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrEmit();
assert(getSrcSize() == 0);
// TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
// "partially" delete the fstp if the Dest is unused.
// Even if Dest is unused, the fstp should be kept for the SideEffects
// of popping the stack.
if (getDest() == NULL) {
Str << "\tfstp\tst(0)\n";
return;
......@@ -2039,6 +2075,42 @@ void InstX8632Fstp::emit(const Cfg *Func) const {
Str << "\tadd\tesp, " << Width << "\n";
}
void InstX8632Fstp::emitIAS(const Cfg *Func) const {
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
intptr_t StartPosition = Asm->GetPosition();
assert(getSrcSize() == 0);
const Variable *Dest = getDest();
// TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
// "partially" delete the fstp if the Dest is unused.
// Even if Dest is unused, the fstp should be kept for the SideEffects
// of popping the stack.
if (Dest == NULL) {
Asm->fstp(RegX8632::getEncodedSTReg(0));
Ostream &Str = Func->getContext()->getStrEmit();
emitIASBytes(Str, Asm, StartPosition);
return;
}
Type Ty = Dest->getType();
if (!Dest->hasReg()) {
x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
->stackVarToAsmOperand(Dest));
Asm->fstp(Ty, StackAddr);
} else {
// Dest is a physical (xmm) register, so st(0) needs to go through
// memory. Hack this by creating a temporary stack slot, spilling
// st(0) there, loading it into the xmm register, and deallocating
// the stack slot.
x86::Immediate Width(typeWidthInBytes(Ty));
Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
Asm->fstp(Ty, StackSlot);
Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot);
Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
}
Ostream &Str = Func->getContext()->getStrEmit();
emitIASBytes(Str, Asm, StartPosition);
}
void InstX8632Fstp::dump(const Cfg *Func) const {
Ostream &Str = Func->getContext()->getStrDump();
dumpDest(Func);
......
......@@ -88,6 +88,21 @@
X(SegReg_GS, "gs") \
//#define X(val, name)
// X87 ST(n) registers.
#define X87ST_REGX8632_TABLE \
/* enum value, encode, name */ \
X(X87ST_First, = 0, "st(0)") \
X(X87ST_0, = 0, "st(0)") \
X(X87ST_1, = 1, "st(1)") \
X(X87ST_2, = 2, "st(2)") \
X(X87ST_3, = 3, "st(3)") \
X(X87ST_4, = 4, "st(4)") \
X(X87ST_5, = 5, "st(5)") \
X(X87ST_6, = 6, "st(6)") \
X(X87ST_7, = 7, "st(7)") \
X(X87ST_Last, = 7, "st(7)") \
//#define X(val, encode, name)
#define ICEINSTX8632BR_TABLE \
/* enum value, encode, opposite, dump, emit */ \
X(Br_o, = 0, Br_no, "o", "jo") \
......
......@@ -1352,6 +1352,7 @@ public:
return new (Func->allocate<InstX8632Fld>()) InstX8632Fld(Func, Src);
}
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override;
static bool classof(const Inst *Inst) { return isClassof(Inst, Fld); }
......@@ -1369,6 +1370,7 @@ public:
return new (Func->allocate<InstX8632Fstp>()) InstX8632Fstp(Func, Dest);
}
void emit(const Cfg *Func) const override;
void emitIAS(const Cfg *Func) const override;
void dump(const Cfg *Func) const override;
static bool classof(const Inst *Inst) { return isClassof(Inst, Fstp); }
......
......@@ -36,7 +36,7 @@ enum AllRegisters {
#undef X
};
// An enum of GPR Registers. The enum value does match encoding used
// An enum of GPR Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum GPRRegister {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
......@@ -47,7 +47,7 @@ enum GPRRegister {
Encoded_Not_GPR = -1
};
// An enum of XMM Registers. The enum value does match encoding used
// An enum of XMM Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum XmmRegister {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
......@@ -58,7 +58,7 @@ enum XmmRegister {
Encoded_Not_Xmm = -1
};
// An enum of Byte Registers. The enum value does match encoding used
// An enum of Byte Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum ByteRegister {
#define X(val, encode) Encoded_##val encode,
......@@ -67,6 +67,15 @@ enum ByteRegister {
Encoded_Not_ByteReg = -1
};
// An enum of X87 Stack Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum X87STRegister {
#define X(val, encode, name) Encoded_##val encode,
X87ST_REGX8632_TABLE
#undef X
Encoded_Not_X87STReg = -1
};
static inline GPRRegister getEncodedGPR(int32_t RegNum) {
assert(Reg_GPR_First <= RegNum && RegNum <= Reg_GPR_Last);
return GPRRegister(RegNum - Reg_GPR_First);
......@@ -91,6 +100,11 @@ static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) {
return getEncodedGPR(RegNum);
}
static inline X87STRegister getEncodedSTReg(int32_t RegNum) {
assert(Encoded_X87ST_First <= RegNum && RegNum <= Encoded_X87ST_Last);
return X87STRegister(RegNum);
}
} // end of namespace RegX8632
} // end of namespace Ice
......
......@@ -272,25 +272,25 @@ void AssemblerX86::rep_movsb() {
EmitUint8(0xA4);
}
void AssemblerX86::movss(XmmRegister dst, const Address &src) {
void AssemblerX86::movss(Type Ty, XmmRegister dst, const Address &src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xF3);
EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
EmitUint8(0x0F);
EmitUint8(0x10);
EmitOperand(dst, src);
}
void AssemblerX86::movss(const Address &dst, XmmRegister src) {
void AssemblerX86::movss(Type Ty, const Address &dst, XmmRegister src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xF3);
EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
EmitUint8(0x0F);
EmitUint8(0x11);
EmitOperand(src, dst);
}
void AssemblerX86::movss(XmmRegister dst, XmmRegister src) {
void AssemblerX86::movss(Type Ty, XmmRegister dst, XmmRegister src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xF3);
EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2);
EmitUint8(0x0F);
EmitUint8(0x11);
EmitXmmRegisterOperand(src, dst);
......@@ -416,40 +416,22 @@ void AssemblerX86::divss(Type Ty, XmmRegister dst, const Address &src) {
EmitOperand(dst, src);
}
void AssemblerX86::flds(const Address &src) {
void AssemblerX86::fld(Type Ty, const Address &src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xD9);
EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
EmitOperand(0, src);
}
void AssemblerX86::fstps(const Address &dst) {
void AssemblerX86::fstp(Type Ty, const Address &dst) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xD9);
EmitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD);
EmitOperand(3, dst);
}
void AssemblerX86::movsd(XmmRegister dst, const Address &src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xF2);
EmitUint8(0x0F);
EmitUint8(0x10);
EmitOperand(dst, src);
}
void AssemblerX86::movsd(const Address &dst, XmmRegister src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xF2);
EmitUint8(0x0F);
EmitUint8(0x11);
EmitOperand(src, dst);
}
void AssemblerX86::movsd(XmmRegister dst, XmmRegister src) {
void AssemblerX86::fstp(X87STRegister st) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xF2);
EmitUint8(0x0F);
EmitUint8(0x11);
EmitXmmRegisterOperand(src, dst);
EmitUint8(0xDD);
EmitUint8(0xD8 + st);
}
void AssemblerX86::movaps(XmmRegister dst, XmmRegister src) {
......@@ -1236,18 +1218,6 @@ void AssemblerX86::roundsd(XmmRegister dst, XmmRegister src,
EmitUint8(static_cast<uint8_t>(mode) | 0x8);
}
void AssemblerX86::fldl(const Address &src) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xDD);
EmitOperand(0, src);
}
void AssemblerX86::fstpl(const Address &dst) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xDD);
EmitOperand(3, dst);
}
void AssemblerX86::fnstcw(const Address &dst) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0xD9);
......
......@@ -36,6 +36,7 @@ class ConstantRelocatable;
using RegX8632::GPRRegister;
using RegX8632::XmmRegister;
using RegX8632::ByteRegister;
using RegX8632::X87STRegister;
namespace x86 {
......@@ -455,9 +456,9 @@ public:
void rep_movsb();
void movss(XmmRegister dst, const Address &src);
void movss(const Address &dst, XmmRegister src);
void movss(XmmRegister dst, XmmRegister src);
void movss(Type Ty, XmmRegister dst, const Address &src);
void movss(Type Ty, const Address &dst, XmmRegister src);
void movss(Type Ty, XmmRegister dst, XmmRegister src);
void movd(XmmRegister dst, GPRRegister src);
void movd(XmmRegister dst, const Address &src);
......@@ -477,10 +478,6 @@ public:
void divss(Type Ty, XmmRegister dst, XmmRegister src);
void divss(Type Ty, XmmRegister dst, const Address &src);
void movsd(XmmRegister dst, const Address &src);
void movsd(const Address &dst, XmmRegister src);
void movsd(XmmRegister dst, XmmRegister src);
void movaps(XmmRegister dst, XmmRegister src);
void movups(XmmRegister dst, XmmRegister src);
......@@ -598,11 +595,9 @@ public:
};
void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
void flds(const Address &src);
void fstps(const Address &dst);
void fldl(const Address &src);
void fstpl(const Address &dst);
void fld(Type Ty, const Address &src);
void fstp(Type Ty, const Address &dst);
void fstp(X87STRegister st);
void fnstcw(const Address &dst);
void fldcw(const Address &src);
......
......@@ -416,7 +416,7 @@ entry:
; CALLTARGETS-LABEL: signed64ToDouble
; CHECK: call -4
; CALLTARGETS: call cvtsi64tod
; CHECK: fstp
; CHECK: fstp qword
define internal float @signed64ToFloat(i64 %a) {
entry:
......@@ -427,7 +427,7 @@ entry:
; CALLTARGETS-LABEL: signed64ToFloat
; CHECK: call -4
; CALLTARGETS: call cvtsi64tof
; CHECK: fstp
; CHECK: fstp dword
define internal double @unsigned64ToDouble(i64 %a) {
entry:
......@@ -500,7 +500,7 @@ entry:
; CALLTARGETS-LABEL: unsigned32ToDouble
; CHECK: call -4
; CALLTARGETS: call cvtui32tod
; CHECK: fstp
; CHECK: fstp qword
define internal float @unsigned32ToFloat(i32 %a) {
entry:
......@@ -511,7 +511,7 @@ entry:
; CALLTARGETS-LABEL: unsigned32ToFloat
; CHECK: call -4
; CALLTARGETS: call cvtui32tof
; CHECK: fstp
; CHECK: fstp dword
define internal double @signed16ToDouble(i32 %a) {
entry:
......@@ -521,7 +521,7 @@ entry:
}
; CHECK-LABEL: signed16ToDouble
; CHECK: cvtsi2sd
; CHECK: fld
; CHECK: fld qword
define internal float @signed16ToFloat(i32 %a) {
entry:
......@@ -531,7 +531,7 @@ entry:
}
; CHECK-LABEL: signed16ToFloat
; CHECK: cvtsi2ss
; CHECK: fld
; CHECK: fld dword
define internal double @unsigned16ToDouble(i32 %a) {
entry:
......
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