Index: src/IceInstX86BaseImpl.h |
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h |
index 6428f53642272f70413d5a0d16c0ae8b69d215ab..e109bf2a3350cfab526e87ce517f9411ecf908a5 100644 |
--- a/src/IceInstX86BaseImpl.h |
+++ b/src/IceInstX86BaseImpl.h |
@@ -1384,38 +1384,35 @@ void InstX86Cbwdq<Machine>::emit(const Cfg *Func) const { |
Ostream &Str = Func->getContext()->getStrEmit(); |
assert(this->getSrcSize() == 1); |
Operand *Src0 = this->getSrc(0); |
- assert(llvm::isa<Variable>(Src0)); |
+ int32_t DestReg = this->getDest()->getRegNum(); |
+ int32_t SrcReg = llvm::cast<Variable>(Src0)->getRegNum(); |
+ (void)DestReg; |
+ (void)SrcReg; |
switch (Src0->getType()) { |
default: |
llvm_unreachable("unexpected source type!"); |
break; |
case IceType_i8: |
- assert(llvm::cast<Variable>(Src0)->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
+ assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax || |
+ DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah); |
Str << "\t" |
<< "cbtw"; |
break; |
case IceType_i16: |
- assert(llvm::cast<Variable>(Src0)->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
+ assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
Str << "\t" |
<< "cwtd"; |
break; |
case IceType_i32: |
- assert(llvm::cast<Variable>(Src0)->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
+ assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
Str << "\t" |
<< "cltd"; |
break; |
case IceType_i64: |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
Str << "\t" |
<< "cdto"; |
break; |
@@ -1428,35 +1425,32 @@ void InstX86Cbwdq<Machine>::emitIAS(const Cfg *Func) const { |
Func->getAssembler<typename InstX86Base<Machine>::Traits::Assembler>(); |
assert(this->getSrcSize() == 1); |
Operand *Src0 = this->getSrc(0); |
- assert(llvm::isa<Variable>(Src0)); |
+ int32_t DestReg = this->getDest()->getRegNum(); |
+ int32_t SrcReg = llvm::cast<Variable>(Src0)->getRegNum(); |
+ (void)DestReg; |
+ (void)SrcReg; |
switch (Src0->getType()) { |
default: |
llvm_unreachable("unexpected source type!"); |
break; |
case IceType_i8: |
- assert(llvm::cast<Variable>(Src0)->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
+ assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_al); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax || |
+ DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ah); |
Asm->cbw(); |
break; |
case IceType_i16: |
- assert(llvm::cast<Variable>(Src0)->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
+ assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_ax); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_dx); |
Asm->cwd(); |
break; |
case IceType_i32: |
- assert(llvm::cast<Variable>(Src0)->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
+ assert(SrcReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_eax); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
Asm->cdq(); |
break; |
case IceType_i64: |
- assert(this->getDest()->getRegNum() == |
- InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
+ assert(DestReg == InstX86Base<Machine>::Traits::RegisterSet::Reg_edx); |
Asm->cqo(); |
break; |
} |
@@ -2278,32 +2272,29 @@ template <class Machine> void InstX86Mov<Machine>::emit(const Cfg *Func) const { |
} else { |
Str << "\tmov" |
<< (!isScalarFloatingType(DestTy) |
- ? this->getWidthString(SrcTy) |
+ ? this->getWidthString(DestTy) |
: 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 esi or si where there is no 8-bit |
- // version of the register. To be safe, we instead widen the dest to match |
- // src. This works even for stack-allocated dest variables because |
- // typeWidthOnStack() pads to a 4-byte boundary even if only a lower portion |
- // is used. |
+ // For an integer truncation operation, src is wider than dest. In this case, |
+ // we use a mov instruction whose data width matches the narrower dest. |
// TODO: This assert disallows usages such as copying a floating |
// point value between a vector and a scalar (which movss is used for). Clean |
// this up. |
assert(Func->getTarget()->typeWidthInBytesOnStack(DestTy) == |
Func->getTarget()->typeWidthInBytesOnStack(SrcTy)); |
- Src->emit(Func); |
+ const Operand *NewSrc = Src; |
+ if (auto *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
+ int32_t NewRegNum = Variable::NoRegister; |
+ if (SrcVar->hasReg()) |
+ NewRegNum = InstX86Base<Machine>::Traits::getGprForType( |
+ DestTy, SrcVar->getRegNum()); |
+ if (SrcTy != DestTy) |
+ NewSrc = SrcVar->asType(DestTy, NewRegNum); |
+ } |
+ NewSrc->emit(Func); |
Str << ", "; |
- int32_t NewRegNum = Variable::NoRegister; |
- if (this->getDest()->hasReg()) |
- NewRegNum = InstX86Base<Machine>::Traits::getGprForType( |
- SrcTy, this->getDest()->getRegNum()); |
- const Variable *NewDest = SrcTy == DestTy |
- ? this->getDest() |
- : this->getDest()->asType(SrcTy, NewRegNum); |
- NewDest->emit(Func); |
+ this->getDest()->emit(Func); |
} |
template <class Machine> |
@@ -2330,13 +2321,8 @@ void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const { |
Machine>::Traits::Assembler::GPREmitterAddrOp GPRAddrEmitter = { |
&InstX86Base<Machine>::Traits::Assembler::mov, |
&InstX86Base<Machine>::Traits::Assembler::mov}; |
- // 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 esi or si where there is no 8-bit |
- // version of the register. To be safe, we instead widen the dest to match |
- // src. This works even for stack-allocated dest variables because |
- // typeWidthOnStack() pads to a 4-byte boundary even if only a lower portion |
- // is used. |
+ // For an integer truncation operation, src is wider than dest. In this case, |
+ // we use a mov instruction whose data width matches the narrower dest. |
// TODO: This assert disallows usages such as copying a floating |
// point value between a vector and a scalar (which movss is used for). Clean |
// this up. |
@@ -2366,7 +2352,7 @@ void InstX86Mov<Machine>::emitIAS(const Cfg *Func) const { |
return; |
} |
if (isScalarIntegerType(SrcTy)) { |
- DestTy = SrcTy; |
+ SrcTy = DestTy; |
} |
emitIASRegOpTyGPR<Machine>(Func, DestTy, Dest, Src, GPRRegEmitter); |
return; |