Index: src/IceInstX8632.cpp |
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp |
index e2d39c3ea4b30905e61b7744cf5cb1d065fad131..a783149c0204e4af7654164d08d78159c73afa1f 100644 |
--- a/src/IceInstX8632.cpp |
+++ b/src/IceInstX8632.cpp |
@@ -1831,7 +1831,8 @@ 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); |
@@ -1918,6 +1919,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() << " "; |
@@ -1927,10 +1960,6 @@ void InstX8632Fld::dump(const Cfg *Func) const { |
void InstX8632Fstp::emit(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrEmit(); |
assert(getSrcSize() == 0); |
- if (getDest() == NULL) { |
Jim Stichnoth
2014/10/08 19:09:41
I think "fstp st(0)" might possibly be used in the
jvoung (off chromium)
2014/10/08 20:51:47
Okay, so the benefit of that is it can avoid alloc
Jim Stichnoth
2014/10/08 21:10:28
Yes, thanks!
|
- Str << "\tfstp\tst(0)\n"; |
- return; |
- } |
if (!getDest()->hasReg()) { |
Str << "\tfstp\t"; |
getDest()->emit(Func); |
@@ -1951,6 +1980,32 @@ 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(); |
+ 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); |