Index: src/IceInstX8632.cpp |
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp |
index 8930a17a634df5632b8f8d914d0b0fef059c2356..18b4b44a9be24eb9890d26c160b1d64ccca47f35 100644 |
--- a/src/IceInstX8632.cpp |
+++ b/src/IceInstX8632.cpp |
@@ -267,13 +267,15 @@ InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
addSource(Mem); |
} |
-InstX8632StoreP::InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
+InstX8632StoreP::InstX8632StoreP(Cfg *Func, Variable *Value, |
+ OperandX8632Mem *Mem) |
: InstX8632(Func, InstX8632::StoreP, 2, NULL) { |
addSource(Value); |
addSource(Mem); |
} |
-InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
+InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Variable *Value, |
+ OperandX8632Mem *Mem) |
: InstX8632(Func, InstX8632::StoreQ, 2, NULL) { |
addSource(Value); |
addSource(Mem); |
@@ -536,6 +538,27 @@ void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
emitIASBytes(Str, Asm, StartPosition); |
} |
+void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, |
+ const Operand *Src, |
+ const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ intptr_t StartPosition = Asm->GetPosition(); |
+ // Src can only be Reg or Immediate. |
+ if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
+ assert(SrcVar->hasReg()); |
+ RegX8632::GPRRegister SrcReg = |
+ RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
+ (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
+ } else if (const ConstantInteger32 *Imm = |
+ llvm::dyn_cast<ConstantInteger32>(Src)) { |
+ (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); |
+ } else { |
+ llvm_unreachable("Unexpected operand type"); |
+ } |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ emitIASBytes(Str, Asm, StartPosition); |
+} |
+ |
void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
const Operand *Src, |
const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { |
@@ -595,10 +618,9 @@ void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
emitIASBytes(Str, Asm, StartPosition); |
} |
-void |
-emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
+void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
const Operand *Src, |
- const x86::AssemblerX86::XmmEmitterTwoOps &Emitter) { |
+ const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { |
x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
intptr_t StartPosition = Asm->GetPosition(); |
assert(Var->hasReg()); |
@@ -627,6 +649,41 @@ emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
emitIASBytes(Str, Asm, StartPosition); |
} |
+void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
+ const Operand *Src, |
+ const x86::AssemblerX86::XmmEmitterMovOps Emitter) { |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ intptr_t StartPosition = Asm->GetPosition(); |
+ if (Dest->hasReg()) { |
+ RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
+ if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
+ if (SrcVar->hasReg()) { |
+ (Asm->*(Emitter.XmmXmm))(DestReg, |
+ RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
+ } else { |
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
+ ->stackVarToAsmOperand(SrcVar)); |
+ (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
+ } |
+ } else if (const OperandX8632Mem *SrcMem = |
+ llvm::dyn_cast<OperandX8632Mem>(Src)) { |
+ (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
+ } else { |
+ llvm_unreachable("Unexpected operand type"); |
+ } |
+ } else { |
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
+ ->stackVarToAsmOperand(Dest)); |
+ // Src must be a register in this case. |
+ const Variable *SrcVar = llvm::cast<Variable>(Src); |
+ assert(SrcVar->hasReg()); |
+ (Asm->*(Emitter.AddrXmm))(StackAddr, |
+ RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
+ } |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ emitIASBytes(Str, Asm, StartPosition); |
+} |
+ |
bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
const Variable *Src = llvm::dyn_cast<const Variable>(Source); |
if (Src == NULL) |
@@ -692,7 +749,7 @@ template <> const char *InstX8632Sar::Opcode = "sar"; |
template <> const char *InstX8632Psra::Opcode = "psra"; |
template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; |
template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; |
-template <> const char *InstX8632Movss::Opcode = "movss"; |
+template <> const char *InstX8632MovssRegs::Opcode = "movss"; |
// Ternary ops |
template <> const char *InstX8632Insertps::Opcode = "insertps"; |
template <> const char *InstX8632Shufps::Opcode = "shufps"; |
@@ -724,8 +781,8 @@ const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { |
// Unary XMM ops |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = { |
- &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { |
+ &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss}; |
// Binary GPR ops |
template <> |
@@ -766,59 +823,59 @@ const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { |
// Binary XMM ops |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = { |
- &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addss::Emitter = { |
+ &x86::AssemblerX86::addss, &x86::AssemblerX86::addss}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = { |
- &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addps::Emitter = { |
+ &x86::AssemblerX86::addps, &x86::AssemblerX86::addps}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = { |
- &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divss::Emitter = { |
+ &x86::AssemblerX86::divss, &x86::AssemblerX86::divss}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divps::Emitter = { |
- &x86::AssemblerX86::divps, &x86::AssemblerX86::divps, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divps::Emitter = { |
+ &x86::AssemblerX86::divps, &x86::AssemblerX86::divps}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulss::Emitter = { |
- &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulss::Emitter = { |
+ &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulps::Emitter = { |
- &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulps::Emitter = { |
+ &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Padd::Emitter = { |
- &x86::AssemblerX86::padd, &x86::AssemblerX86::padd, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Padd::Emitter = { |
+ &x86::AssemblerX86::padd, &x86::AssemblerX86::padd}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pand::Emitter = { |
- &x86::AssemblerX86::pand, &x86::AssemblerX86::pand, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pand::Emitter = { |
+ &x86::AssemblerX86::pand, &x86::AssemblerX86::pand}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pandn::Emitter = { |
- &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pandn::Emitter = { |
+ &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpeq::Emitter = { |
- &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = { |
+ &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pcmpgt::Emitter = { |
- &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = { |
+ &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmull::Emitter = { |
- &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmull::Emitter = { |
+ &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = { |
- &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmuludq::Emitter = { |
+ &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Por::Emitter = { |
- &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Por::Emitter = { |
+ &x86::AssemblerX86::por, &x86::AssemblerX86::por}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Psub::Emitter = { |
- &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Psub::Emitter = { |
+ &x86::AssemblerX86::psub, &x86::AssemblerX86::psub}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pxor::Emitter = { |
- &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pxor::Emitter = { |
+ &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subss::Emitter = { |
- &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subss::Emitter = { |
+ &x86::AssemblerX86::subss, &x86::AssemblerX86::subss}; |
template <> |
-const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = { |
- &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL}; |
+const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subps::Emitter = { |
+ &x86::AssemblerX86::subps, &x86::AssemblerX86::subps}; |
// Binary XMM Shift ops |
template <> |
@@ -886,7 +943,7 @@ template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const { |
assert(InstructionSetIsValid); |
assert(getSrcSize() == 2); |
Type ElementTy = typeElementType(Ty); |
- emitIASVarOperandTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
+ emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
} |
template <> void InstX8632Subss::emit(const Cfg *Func) const { |
@@ -1364,6 +1421,31 @@ void InstX8632Icmp::emit(const Cfg *Func) const { |
Str << "\n"; |
} |
+void InstX8632Icmp::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 2); |
+ const Operand *Src0 = getSrc(0); |
+ const Operand *Src1 = getSrc(1); |
+ Type Ty = Src0->getType(); |
+ static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { |
+ &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, |
+ &x86::AssemblerX86::cmp}; |
+ static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { |
+ &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp}; |
+ if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
+ if (SrcVar0->hasReg()) { |
+ emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
+ } else { |
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
+ ->stackVarToAsmOperand(SrcVar0)); |
+ emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
+ } |
+ } else if (const OperandX8632Mem *SrcMem0 = |
+ llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
+ } |
+} |
+ |
void InstX8632Icmp::dump(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrDump(); |
Str << "cmp." << getSrc(0)->getType() << " "; |
@@ -1388,9 +1470,9 @@ void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
assert(llvm::isa<Variable>(getSrc(0))); |
const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); |
Type Ty = Src0->getType(); |
- const static x86::AssemblerX86::XmmEmitterTwoOps Emitter = { |
- &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss, NULL}; |
- emitIASVarOperandTyXMM(Func, Ty, Src0, getSrc(1), Emitter); |
+ const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { |
+ &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss}; |
+ emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); |
} |
void InstX8632Ucomiss::dump(const Cfg *Func) const { |
@@ -1405,6 +1487,14 @@ void InstX8632UD2::emit(const Cfg *Func) const { |
Str << "\tud2\n"; |
} |
+void InstX8632UD2::emitIAS(const Cfg *Func) const { |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ intptr_t StartPosition = Asm->GetPosition(); |
+ Asm->ud2(); |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ emitIASBytes(Str, Asm, StartPosition); |
+} |
+ |
void InstX8632UD2::dump(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrDump(); |
Str << "ud2\n"; |
@@ -1420,6 +1510,33 @@ void InstX8632Test::emit(const Cfg *Func) const { |
Str << "\n"; |
} |
+void InstX8632Test::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 2); |
+ const Operand *Src0 = getSrc(0); |
+ const Operand *Src1 = getSrc(1); |
+ Type Ty = Src0->getType(); |
+ // The Reg/Addr form of test is not encodeable. |
+ static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { |
+ &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test}; |
+ static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { |
+ &x86::AssemblerX86::test, &x86::AssemblerX86::test}; |
+ if (const Variable *SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
+ if (SrcVar0->hasReg()) { |
+ emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
+ } else { |
+ llvm_unreachable("Nothing actually generates this so it's untested"); |
+ x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
+ ->stackVarToAsmOperand(SrcVar0)); |
+ emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
+ } |
+ } else if (const OperandX8632Mem *SrcMem0 = |
+ llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
+ llvm_unreachable("Nothing actually generates this so it's untested"); |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
+ } |
+} |
+ |
void InstX8632Test::dump(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrDump(); |
Str << "test." << getSrc(0)->getType() << " "; |
@@ -1474,6 +1591,19 @@ void InstX8632StoreP::emit(const Cfg *Func) const { |
Str << "\n"; |
} |
+void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ intptr_t StartPosition = Asm->GetPosition(); |
+ assert(getSrcSize() == 2); |
+ const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
+ const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
+ assert(Src->hasReg()); |
+ Asm->movups(DestMem->toAsmAddress(Asm), |
+ RegX8632::getEncodedXmm(Src->getRegNum())); |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ emitIASBytes(Str, Asm, StartPosition); |
+} |
+ |
void InstX8632StoreP::dump(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrDump(); |
Str << "storep." << getSrc(0)->getType() << " "; |
@@ -1494,6 +1624,19 @@ void InstX8632StoreQ::emit(const Cfg *Func) const { |
Str << "\n"; |
} |
+void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ intptr_t StartPosition = Asm->GetPosition(); |
+ assert(getSrcSize() == 2); |
+ const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
+ const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
+ assert(Src->hasReg()); |
+ Asm->movq(DestMem->toAsmAddress(Asm), |
+ RegX8632::getEncodedXmm(Src->getRegNum())); |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ emitIASBytes(Str, Asm, StartPosition); |
+} |
+ |
void InstX8632StoreQ::dump(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrDump(); |
Str << "storeq." << getSrc(0)->getType() << " "; |
@@ -1621,6 +1764,17 @@ template <> void InstX8632Movp::emit(const Cfg *Func) const { |
Str << "\n"; |
} |
+template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 1); |
+ assert(isVectorType(getDest()->getType())); |
+ const Variable *Dest = getDest(); |
+ const Operand *Src = getSrc(0); |
+ const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { |
+ &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, |
+ &x86::AssemblerX86::movups}; |
+ emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
+} |
+ |
template <> void InstX8632Movq::emit(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrEmit(); |
assert(getSrcSize() == 1); |
@@ -1633,6 +1787,34 @@ template <> void InstX8632Movq::emit(const Cfg *Func) const { |
Str << "\n"; |
} |
+template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { |
+ assert(getSrcSize() == 1); |
+ assert(getDest()->getType() == IceType_i64 || |
+ getDest()->getType() == IceType_f64); |
+ const Variable *Dest = getDest(); |
+ const Operand *Src = getSrc(0); |
+ const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { |
+ &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, |
+ &x86::AssemblerX86::movq}; |
+ emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
+} |
+ |
+template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { |
+ // This is Binop variant is only intended to be used for reg-reg moves |
+ // where part of the Dest register is untouched. |
+ assert(getSrcSize() == 2); |
+ const Variable *Dest = getDest(); |
+ assert(Dest == getSrc(0)); |
+ const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
+ assert(Dest->hasReg() && Src->hasReg()); |
+ x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
+ intptr_t StartPosition = Asm->GetPosition(); |
+ Asm->movss(RegX8632::getEncodedXmm(Dest->getRegNum()), |
+ RegX8632::getEncodedXmm(Src->getRegNum())); |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ emitIASBytes(Str, Asm, StartPosition); |
+} |
+ |
void InstX8632Movsx::emit(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrEmit(); |
assert(getSrcSize() == 1); |