Chromium Code Reviews| Index: src/IceInstX8664.cpp |
| diff --git a/src/IceInstX8664.cpp b/src/IceInstX8664.cpp |
| index da09a9e295444649fe5506ca8384cccf319e3144..93691dace6b6bacc99ac946eaf2a1a5ce95a3634 100644 |
| --- a/src/IceInstX8664.cpp |
| +++ b/src/IceInstX8664.cpp |
| @@ -89,19 +89,50 @@ MachineTraits<TargetX8664>::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty, |
| } |
| } |
| +namespace { |
| +static int32_t getRematerializableOffset(Variable *Var, |
| + const Ice::TargetX8664 *Target) { |
| + int32_t Disp = Var->getStackOffset(); |
| + SizeT RegNum = static_cast<SizeT>(Var->getRegNum()); |
| + if (RegNum == Target->getFrameReg()) { |
| + Disp += Target->getFrameFixedAllocaOffset(); |
| + } else if (RegNum != Target->getStackReg()) { |
| + llvm::report_fatal_error("Unexpected rematerializable register type"); |
| + } |
| + return Disp; |
| +} |
| +} // end of anonymous namespace |
| + |
| void MachineTraits<TargetX8664>::X86OperandMem::emit(const Cfg *Func) const { |
| if (!BuildDefs::dump()) |
| return; |
| + const auto *Target = static_cast<const Ice::TargetX8664 *>(Func->getTarget()); |
| + // If the base is rematerializable, we need to replace it with the correct |
| + // physical register (esp or ebp), and update the Offset. |
|
Jim Stichnoth
2015/12/20 19:27:37
Should that be rsp/rbp?
John
2015/12/21 13:41:31
Not necessarily. Because x32, even though we manip
|
| + int32_t Disp = 0; |
| + if (getBase() && getBase()->isRematerializable()) { |
| + Disp += getRematerializableOffset(getBase(), Target); |
| + } |
| + // The index should never be rematerializable. But if we ever allow it, then |
| + // we should make sure the rematerialization offset is shifted by the Shift |
| + // value. |
| + if (getIndex()) |
| + assert(!getIndex()->isRematerializable()); |
| Ostream &Str = Func->getContext()->getStrEmit(); |
| // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading |
| // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr. |
| - if (!Offset) { |
| + if (getOffset() == 0 && Disp == 0) { |
|
Jim Stichnoth
2015/12/20 19:27:37
Here and below, I think getOffset() should be comp
John
2015/12/21 13:41:31
Done.
|
| // No offset, emit nothing. |
| + } else if (getOffset() == 0 && Disp != 0) { |
| + Str << Disp; |
| } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
| - if (Base == nullptr || CI->getValue()) |
| + if (Base == nullptr || CI->getValue() || Disp != 0) |
| // Emit a non-zero offset without a leading '$'. |
| - Str << CI->getValue(); |
| + Str << CI->getValue() + Disp; |
| } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
| + // TODO(sehr): ConstantRelocatable still needs updating for |
| + // rematerializable base/index and Disp. |
| + assert(Disp == 0); |
| CR->emitWithoutPrefix(Func->getTarget()); |
| } else { |
| llvm_unreachable("Invalid offset type for x86 mem operand"); |
| @@ -127,6 +158,11 @@ void MachineTraits<TargetX8664>::X86OperandMem::dump(const Cfg *Func, |
| return; |
| bool Dumped = false; |
| Str << "["; |
| + int32_t Disp = 0; |
| + const auto *Target = static_cast<const Ice::TargetX8664 *>(Func->getTarget()); |
| + if (getBase() && getBase()->isRematerializable()) { |
| + Disp += getRematerializableOffset(getBase(), Target); |
| + } |
| if (Base) { |
| if (Func) |
| Base->dump(Func); |
| @@ -145,6 +181,12 @@ void MachineTraits<TargetX8664>::X86OperandMem::dump(const Cfg *Func, |
| Index->dump(Str); |
| Dumped = true; |
| } |
| + if (Disp) { |
| + if (Disp > 0) |
| + Str << "+"; |
| + Str << Disp; |
| + Dumped = true; |
| + } |
| // Pretty-print the Offset. |
| bool OffsetIsZero = false; |
| bool OffsetIsNegative = false; |
| @@ -172,23 +214,24 @@ void MachineTraits<TargetX8664>::X86OperandMem::dump(const Cfg *Func, |
| MachineTraits<TargetX8664>::Address |
| MachineTraits<TargetX8664>::X86OperandMem::toAsmAddress( |
| MachineTraits<TargetX8664>::Assembler *Asm, |
| - const Ice::TargetLowering *Target) const { |
| - // TODO(sehr): handle rematerializable base/index. |
| + const Ice::TargetLowering *TargetLowering) const { |
| + const auto *Target = static_cast<const Ice::TargetX8664 *>(TargetLowering); |
| (void)Target; |
|
Jim Stichnoth
2015/12/20 19:27:37
remove this
John
2015/12/21 13:41:31
Done.
|
| - if (getBase()) |
| - assert(!getBase()->isRematerializable()); |
| + int32_t Disp = 0; |
| + if (getBase() && getBase()->isRematerializable()) { |
| + Disp += getRematerializableOffset(getBase(), Target); |
| + } |
| if (getIndex()) |
| assert(!getIndex()->isRematerializable()); |
| - int32_t Disp = 0; |
| AssemblerFixup *Fixup = nullptr; |
| // Determine the offset (is it relocatable?) |
| if (getOffset()) { |
| if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
| - Disp = static_cast<int32_t>(CI->getValue()); |
| + Disp += static_cast<int32_t>(CI->getValue()); |
| } else if (const auto CR = |
| llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
| - Disp = CR->getOffset() - 4; |
| - Fixup = Asm->createFixup(PcRelFixup, CR); |
| + Disp += CR->getOffset(); |
| + Fixup = Asm->createFixup(RelFixup, CR); |
| } else { |
| llvm_unreachable("Unexpected offset type"); |
| } |