Chromium Code Reviews| Index: src/IceInstX86BaseImpl.h |
| diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h |
| index 29565580dc2a88edc230406008db932da03a8eee..9b3fdc03331fd7bf237c8a35208cbf76319c33f3 100644 |
| --- a/src/IceInstX86BaseImpl.h |
| +++ b/src/IceInstX86BaseImpl.h |
| @@ -717,7 +717,8 @@ void emitIASRegOpTyGPR( |
| } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Imm->getValue())); |
| } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| - AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
| + AssemblerFixup *Fixup = |
| + Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); |
| (Asm->*(Emitter.GPRImm))(Ty, VarReg, Immediate(Reloc->getOffset(), Fixup)); |
| } else if (const auto Split = llvm::dyn_cast< |
| typename InstX86Base<Machine>::Traits::VariableSplit>(Src)) { |
| @@ -746,7 +747,8 @@ void emitIASAddrOpTyGPR( |
| } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Imm->getValue())); |
| } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
| - AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
| + AssemblerFixup *Fixup = |
| + Asm->createFixup(InstX86Base<Machine>::Traits::RelFixup, Reloc); |
| (Asm->*(Emitter.AddrImm))(Ty, Addr, Immediate(Reloc->getOffset(), Fixup)); |
| } else { |
| llvm_unreachable("Unexpected operand type"); |
| @@ -917,8 +919,8 @@ void emitIASRegOpTyXMM( |
| template <class Machine, typename DReg_t, typename SReg_t, |
| DReg_t (*destEnc)(int32_t), SReg_t (*srcEnc)(int32_t)> |
| -void emitIASCastRegOp(const Cfg *Func, Type DispatchTy, const Variable *Dest, |
| - const Operand *Src, |
| +void emitIASCastRegOp(const Cfg *Func, Type DestTy, const Variable *Dest, |
| + Type SrcTy, const Operand *Src, |
| const typename InstX86Base<Machine>::Traits::Assembler:: |
| template CastEmitterRegOp<DReg_t, SReg_t> &Emitter) { |
| typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| @@ -928,18 +930,18 @@ void emitIASCastRegOp(const Cfg *Func, Type DispatchTy, const Variable *Dest, |
| if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| if (SrcVar->hasReg()) { |
| SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
| - (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); |
| + (Asm->*(Emitter.RegReg))(DestTy, DestReg, SrcTy, SrcReg); |
| } else { |
| typename InstX86Base<Machine>::Traits::Address SrcStackAddr = |
| static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| Func->getTarget()) |
| ->stackVarToAsmOperand(SrcVar); |
| - (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); |
| + (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, SrcStackAddr); |
| } |
| } else if (const auto Mem = llvm::dyn_cast< |
| typename InstX86Base<Machine>::Traits::X86OperandMem>(Src)) { |
| Mem->emitSegmentOverride(Asm); |
| - (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); |
| + (Asm->*(Emitter.RegAddr))(DestTy, DestReg, SrcTy, Mem->toAsmAddress(Asm)); |
| } else { |
| llvm_unreachable("Unexpected operand type"); |
| } |
| @@ -1387,6 +1389,11 @@ void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const { |
| InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| Str << "\tcltd"; |
| break; |
| + case IceType_i64: |
| + assert(this->getDest()->getRegNum() == |
| + InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| + Str << "\tcdto"; |
| + break; |
| } |
| } |
| @@ -1418,6 +1425,11 @@ void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { |
| InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| Asm->cdq(); |
| break; |
| + case IceType_i64: |
| + assert(this->getDest()->getRegNum() == |
| + InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
| + Asm->cqo(); |
| + break; |
| } |
| } |
| @@ -1580,7 +1592,8 @@ void InstX86Cmov<Machine>::emitIAS(const Cfg *Func) const { |
| assert(this->getSrcSize() == 2); |
| Operand *Src = this->getSrc(1); |
| Type SrcTy = Src->getType(); |
| - assert(SrcTy == IceType_i16 || SrcTy == IceType_i32); |
| + assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 || |
| + (InstX86Base<Machine>::Traits::Is64Bit)); |
| typename InstX86Base<Machine>::Traits::Assembler *Asm = |
| Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
| if (const auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| @@ -1802,7 +1815,11 @@ void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const { |
| switch (Variant) { |
| case Si2ss: { |
| assert(isScalarIntegerType(SrcTy)); |
| - assert(typeWidthInBytes(SrcTy) <= 4); |
| + if (!InstX86Base<Machine>::Traits::Is64Bit) { |
| + assert(typeWidthInBytes(SrcTy) <= 4); |
| + } else { |
| + assert(SrcTy == IceType_i32 || SrcTy == IceType_i64); |
| + } |
| assert(isScalarFloatingType(DestTy)); |
| static const typename InstX86Base<Machine>::Traits::Assembler:: |
| template CastEmitterRegOp< |
| @@ -1816,13 +1833,17 @@ void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const { |
| typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm, |
| InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR>( |
| - Func, DestTy, Dest, Src, Emitter); |
| + Func, DestTy, Dest, SrcTy, Src, Emitter); |
| return; |
| } |
| case Tss2si: { |
| assert(isScalarFloatingType(SrcTy)); |
| assert(isScalarIntegerType(DestTy)); |
| - assert(typeWidthInBytes(DestTy) <= 4); |
| + if (!InstX86Base<Machine>::Traits::Is64Bit) { |
| + assert(typeWidthInBytes(DestTy) <= 4); |
| + } else { |
| + assert(DestTy == IceType_i32 || DestTy == IceType_i64); |
| + } |
| static const typename InstX86Base<Machine>::Traits::Assembler:: |
| template CastEmitterRegOp< |
| typename InstX86Base<Machine>::Traits::RegisterSet::GPRRegister, |
| @@ -1835,7 +1856,7 @@ void InstX86Cvt<Machine>::emitIAS(const Cfg *Func) const { |
| typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister, |
| InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR, |
| InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm>( |
| - Func, SrcTy, Dest, Src, Emitter); |
| + Func, DestTy, Dest, SrcTy, Src, Emitter); |
| return; |
| } |
| case Float2float: { |
| @@ -2232,6 +2253,11 @@ template <class Machine> void InstX86Lea<Machine>::emit(const Cfg *Func) const { |
| this->getDest()->emit(Func); |
| } |
| +inline bool isIntegerConstant(const Operand *Op) { |
| + return llvm::dyn_cast<ConstantInteger32>(Op) != nullptr || |
|
Jim Stichnoth
2015/08/10 16:08:04
Use isa<> instead of dyn_cast<> .
John
2015/08/10 20:41:17
Done.
|
| + llvm::dyn_cast<ConstantInteger64>(Op) != nullptr; |
| +} |
| + |
| template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
| if (!BuildDefs::dump()) |
| return; |
| @@ -2240,11 +2266,16 @@ template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
| Operand *Src = this->getSrc(0); |
| Type SrcTy = Src->getType(); |
| Type DestTy = this->getDest()->getType(); |
| - Str << "\tmov" |
| - << (!isScalarFloatingType(DestTy) |
| - ? this->getWidthString(SrcTy) |
| - : InstX86Base<Machine>::Traits::TypeAttributes[DestTy].SdSsString) |
| - << "\t"; |
| + if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| + isIntegerConstant(Src)) { |
| + Str << "\tmovabs\t"; |
| + } else { |
| + Str << "\tmov" |
| + << (!isScalarFloatingType(DestTy) |
| + ? this->getWidthString(SrcTy) |
| + : InstX86Base<Machine>::Traits::TypeAttributes[DestTy] |
| + .SdSsString) << "\t"; |
| + } |
| // For an integer truncation operation, src is wider than dest. |
| // Ideally, we use a mov instruction whose data width matches the |
| // narrower dest. This is a problem if e.g. src is a register like |
| @@ -2308,6 +2339,22 @@ void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const { |
| assert(isScalarIntegerType(DestTy)); |
| // Widen DestTy for truncation (see above note). We should only do this |
| // when both Src and Dest are integer types. |
| + if (InstX86Base<Machine>::Traits::Is64Bit && DestTy == IceType_i64 && |
| + isIntegerConstant(Src)) { |
| + uint64_t value = -1; |
| + if (const auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src)) { |
| + value = C64->getValue(); |
| + } else { |
| + const auto *C32 = llvm::dyn_cast<ConstantInteger32>(Src); |
|
Jim Stichnoth
2015/08/10 16:08:04
Can probably use llvm::cast<> which would do the a
John
2015/08/10 20:41:17
Done.
|
| + assert(C32 != nullptr); |
| + value = C32->getValue(); |
| + } |
| + Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>() |
| + ->movabs(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| + Dest->getRegNum()), |
| + value); |
| + return; |
| + } |
| if (isScalarIntegerType(SrcTy)) { |
| DestTy = SrcTy; |
| } |
| @@ -2351,14 +2398,19 @@ void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { |
| const auto SrcVar = llvm::cast<Variable>(this->getSrc(0)); |
| // For insert/extract element (one of Src/Dest is an Xmm vector and |
| // the other is an int type). |
| - if (SrcVar->getType() == IceType_i32) { |
| - assert(isVectorType(Dest->getType())); |
| + if (SrcVar->getType() == IceType_i32 || |
| + (InstX86Base<Machine>::Traits::Is64Bit && |
| + SrcVar->getType() == IceType_i64)) { |
| + assert(isVectorType(Dest->getType()) || |
| + (isScalarFloatingType(Dest->getType()) && |
| + typeWidthInBytes(SrcVar->getType()) == |
| + typeWidthInBytes(Dest->getType()))); |
| assert(Dest->hasReg()); |
| typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister DestReg = |
| InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( |
| Dest->getRegNum()); |
| if (SrcVar->hasReg()) { |
| - Asm->movd(DestReg, |
| + Asm->movd(SrcVar->getType(), DestReg, |
| InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| SrcVar->getRegNum())); |
| } else { |
| @@ -2366,17 +2418,23 @@ void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { |
| static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| Func->getTarget()) |
| ->stackVarToAsmOperand(SrcVar)); |
| - Asm->movd(DestReg, StackAddr); |
| + Asm->movd(SrcVar->getType(), DestReg, StackAddr); |
| } |
| } else { |
| - assert(isVectorType(SrcVar->getType())); |
| + assert(isVectorType(SrcVar->getType()) || |
| + (isScalarFloatingType(SrcVar->getType()) && |
| + typeWidthInBytes(SrcVar->getType()) == |
| + typeWidthInBytes(Dest->getType()))); |
| assert(SrcVar->hasReg()); |
| - assert(Dest->getType() == IceType_i32); |
| + assert(Dest->getType() == IceType_i32 || |
| + (InstX86Base<Machine>::Traits::Is64Bit && |
| + Dest->getType() == IceType_i64)); |
| typename InstX86Base<Machine>::Traits::RegisterSet::XmmRegister SrcReg = |
| InstX86Base<Machine>::Traits::RegisterSet::getEncodedXmm( |
| SrcVar->getRegNum()); |
| if (Dest->hasReg()) { |
| - Asm->movd(InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| + Asm->movd(Dest->getType(), |
| + InstX86Base<Machine>::Traits::RegisterSet::getEncodedGPR( |
| Dest->getRegNum()), |
| SrcReg); |
| } else { |
| @@ -2384,7 +2442,7 @@ void InstX86Movd<Machine>::emitIAS(const Cfg *Func) const { |
| static_cast<typename InstX86Base<Machine>::Traits::TargetLowering *>( |
| Func->getTarget()) |
| ->stackVarToAsmOperand(Dest)); |
| - Asm->movd(StackAddr, SrcReg); |
| + Asm->movd(Dest->getType(), StackAddr, SrcReg); |
| } |
| } |
| } |