| Index: src/IceInstX8632.cpp
|
| diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
|
| index 3fd74f94beeae4e7de44eb76ebb1e2cc58ab66c0..72d75458f7153317f42bea8fcf30132c60be3bee 100644
|
| --- a/src/IceInstX8632.cpp
|
| +++ b/src/IceInstX8632.cpp
|
| @@ -478,10 +478,66 @@ void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
|
| Str << "\n";
|
| }
|
|
|
| +void emitIASVarTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
|
| + const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
|
| + x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
|
| + intptr_t StartPosition = Asm->GetPosition();
|
| + if (Var->hasReg()) {
|
| + // We cheat a little and use GPRRegister even for byte operations.
|
| + RegX8632::GPRRegister VarReg =
|
| + RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
|
| + (Asm->*(Emitter.Reg))(Ty, VarReg);
|
| + } else {
|
| + x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
|
| + ->stackVarToAsmOperand(Var));
|
| + (Asm->*(Emitter.Addr))(Ty, StackAddr);
|
| + }
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + emitIASBytes(Str, Asm, StartPosition);
|
| +}
|
| +
|
| +void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
|
| + const Operand *Src,
|
| + const x86::AssemblerX86::GPREmitterRegOp &Emitter) {
|
| + x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
|
| + intptr_t StartPosition = Asm->GetPosition();
|
| + assert(Var->hasReg());
|
| + // We cheat a little and use GPRRegister even for byte operations.
|
| + RegX8632::GPRRegister VarReg =
|
| + RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
|
| + if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) {
|
| + if (SrcVar->hasReg()) {
|
| + RegX8632::GPRRegister SrcReg;
|
| + if (Ty == IceType_i8 || Ty == IceType_i1) {
|
| + SrcReg = static_cast<RegX8632::GPRRegister>(
|
| + RegX8632::getEncodedByteReg(SrcVar->getRegNum()));
|
| + } else {
|
| + SrcReg = RegX8632::getEncodedGPR(SrcVar->getRegNum());
|
| + }
|
| + (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
|
| + } else {
|
| + x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
|
| + ->stackVarToAsmOperand(SrcVar);
|
| + (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
|
| + }
|
| + } else if (const OperandX8632Mem *Mem =
|
| + llvm::dyn_cast<OperandX8632Mem>(Src)) {
|
| + x86::Address SrcAddr = Mem->toAsmAddress(Asm);
|
| + (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr);
|
| + } else if (const ConstantInteger32 *Imm =
|
| + llvm::dyn_cast<ConstantInteger32>(Src)) {
|
| + (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
|
| + } else {
|
| + llvm_unreachable("Unexpected operand type");
|
| + }
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + emitIASBytes(Str, Asm, StartPosition);
|
| +}
|
| +
|
| void
|
| emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
|
| const Operand *Src,
|
| - const x86::AssemblerX86::TypedXmmEmitters &Emitter) {
|
| + const x86::AssemblerX86::XmmEmitterTwoOps &Emitter) {
|
| x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
|
| intptr_t StartPosition = Asm->GetPosition();
|
| assert(Var->hasReg());
|
| @@ -586,54 +642,75 @@ template <> const char *InstX8632Pblendvb::Opcode = "pblendvb";
|
| template <> const char *InstX8632Pextr::Opcode = "pextr";
|
| template <> const char *InstX8632Pshufd::Opcode = "pshufd";
|
|
|
| +// Inplace GPR ops
|
| +template <>
|
| +const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = {
|
| + &x86::AssemblerX86::bswap, NULL /* only a reg form exists */};
|
| +template <>
|
| +const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = {
|
| + &x86::AssemblerX86::neg, &x86::AssemblerX86::neg};
|
| +
|
| +// Unary GPR ops
|
| +template <>
|
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = {
|
| + &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL};
|
| +template <>
|
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = {
|
| + &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL};
|
| +template <>
|
| +const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = {
|
| + /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL};
|
| +
|
| +// Unary XMM ops
|
| +template <>
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Sqrtss::Emitter = {
|
| + &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL};
|
| +
|
| // Binary XMM ops
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Addss::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addss::Emitter = {
|
| &x86::AssemblerX86::addss, &x86::AssemblerX86::addss, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Addps::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Addps::Emitter = {
|
| &x86::AssemblerX86::addps, &x86::AssemblerX86::addps, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Divss::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divss::Emitter = {
|
| &x86::AssemblerX86::divss, &x86::AssemblerX86::divss, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Divps::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Divps::Emitter = {
|
| &x86::AssemblerX86::divps, &x86::AssemblerX86::divps, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulss::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulss::Emitter = {
|
| &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Mulps::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Mulps::Emitter = {
|
| &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Padd::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Padd::Emitter = {
|
| &x86::AssemblerX86::padd, &x86::AssemblerX86::padd, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Pand::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pand::Emitter = {
|
| &x86::AssemblerX86::pand, &x86::AssemblerX86::pand, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Pandn::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pandn::Emitter = {
|
| &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Pmuludq::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pmuludq::Emitter = {
|
| &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Por::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Por::Emitter = {
|
| &x86::AssemblerX86::por, &x86::AssemblerX86::por, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Psub::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Psub::Emitter = {
|
| &x86::AssemblerX86::psub, &x86::AssemblerX86::psub, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Pxor::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Pxor::Emitter = {
|
| &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Sqrtss::Emitter = {
|
| - &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss, NULL};
|
| -template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Subss::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subss::Emitter = {
|
| &x86::AssemblerX86::subss, &x86::AssemblerX86::subss, NULL};
|
| template <>
|
| -const x86::AssemblerX86::TypedXmmEmitters InstX8632Subps::Emitter = {
|
| +const x86::AssemblerX86::XmmEmitterTwoOps InstX8632Subps::Emitter = {
|
| &x86::AssemblerX86::subps, &x86::AssemblerX86::subps, NULL};
|
|
|
| template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
|
| @@ -1125,7 +1202,7 @@ 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::TypedXmmEmitters Emitter = {
|
| + const static x86::AssemblerX86::XmmEmitterTwoOps Emitter = {
|
| &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss, NULL};
|
| emitIASVarOperandTyXMM(Func, Ty, Src0, getSrc(1), Emitter);
|
| }
|
| @@ -1300,6 +1377,42 @@ template <> void InstX8632Mov::emit(const Cfg *Func) const {
|
| }
|
| }
|
|
|
| +template <> void InstX8632Movd::emitIAS(const Cfg *Func) const {
|
| + x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
|
| + intptr_t StartPosition = Asm->GetPosition();
|
| + assert(getSrcSize() == 1);
|
| + const Variable *Dest = getDest();
|
| + const Variable *Src = llvm::cast<Variable>(getSrc(0));
|
| + // For insert/extract element (one of Src/Dest is an Xmm vector and
|
| + // the other is an int type).
|
| + if (Src->getType() == IceType_i32) {
|
| + assert(isVectorType(Dest->getType()));
|
| + assert(Dest->hasReg());
|
| + RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
|
| + if (Src->hasReg()) {
|
| + Asm->movd(DestReg, RegX8632::getEncodedGPR(Src->getRegNum()));
|
| + } else {
|
| + x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
|
| + ->stackVarToAsmOperand(Src));
|
| + Asm->movd(DestReg, StackAddr);
|
| + }
|
| + } else {
|
| + assert(isVectorType(Src->getType()));
|
| + assert(Src->hasReg());
|
| + assert(Dest->getType() == IceType_i32);
|
| + RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum());
|
| + if (Dest->hasReg()) {
|
| + Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg);
|
| + } else {
|
| + x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
|
| + ->stackVarToAsmOperand(Dest));
|
| + Asm->movd(StackAddr, SrcReg);
|
| + }
|
| + }
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + emitIASBytes(Str, Asm, StartPosition);
|
| +}
|
| +
|
| template <> void InstX8632Movp::emit(const Cfg *Func) const {
|
| // TODO(wala,stichnot): movups works with all vector operands, but
|
| // there exist other instructions (movaps, movdqa, movdqu) that may
|
|
|