| Index: src/IceInstX8664.cpp
|
| diff --git a/src/IceInstX8664.cpp b/src/IceInstX8664.cpp
|
| index da09a9e295444649fe5506ca8384cccf319e3144..6c8d9823ee6cd0fec55b32bbf0a6981c006c0126 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 (stack or base pointer), and update the Offset.
|
| + 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() == nullptr && Disp == 0) {
|
| // No offset, emit nothing.
|
| + } else if (getOffset() == nullptr && 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,23 @@ 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.
|
| - (void)Target;
|
| - if (getBase())
|
| - assert(!getBase()->isRematerializable());
|
| + const Ice::TargetLowering *TargetLowering) const {
|
| + const auto *Target = static_cast<const Ice::TargetX8664 *>(TargetLowering);
|
| + 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 (getOffset() != nullptr) {
|
| 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");
|
| }
|
|
|