Index: src/IceInstX8632.cpp |
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp |
index 28fa07b61ceaef4f0da09692a1c6f7a4702aaab5..e533d57adcdefbdcc535c09e3ba5f46894bd7586 100644 |
--- a/src/IceInstX8632.cpp |
+++ b/src/IceInstX8632.cpp |
@@ -77,9 +77,9 @@ void MachineTraits<TargetX8632>::X86Operand::dump(const Cfg *, |
MachineTraits<TargetX8632>::X86OperandMem::X86OperandMem( |
Cfg *Func, Type Ty, Variable *Base, Constant *Offset, Variable *Index, |
- uint16_t Shift, SegmentRegisters SegmentReg) |
+ uint16_t Shift, SegmentRegisters SegmentReg, bool IsPIC) |
: X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
- Shift(Shift), SegmentReg(SegmentReg), Randomized(false) { |
+ Shift(Shift), SegmentReg(SegmentReg), IsPIC(IsPIC) { |
assert(Shift <= 3); |
Vars = nullptr; |
NumVars = 0; |
@@ -99,8 +99,9 @@ MachineTraits<TargetX8632>::X86OperandMem::X86OperandMem( |
} |
namespace { |
-static int32_t GetRematerializableOffset(Variable *Var, |
- const Ice::TargetX8632 *Target) { |
+ |
+int32_t GetRematerializableOffset(Variable *Var, |
+ const Ice::TargetX8632 *Target) { |
int32_t Disp = Var->getStackOffset(); |
SizeT RegNum = static_cast<SizeT>(Var->getRegNum()); |
if (RegNum == Target->getFrameReg()) { |
@@ -110,11 +111,29 @@ static int32_t GetRematerializableOffset(Variable *Var, |
} |
return Disp; |
} |
+ |
+void validateMemOperandPIC(const MachineTraits<TargetX8632>::X86OperandMem *Mem, |
+ bool UseNonsfi) { |
+ if (!BuildDefs::asserts()) |
+ return; |
+ const bool HasCR = |
+ Mem->getOffset() && llvm::isa<ConstantRelocatable>(Mem->getOffset()); |
+ (void)HasCR; |
+ const bool IsPIC = Mem->getIsPIC(); |
+ (void)IsPIC; |
+ if (UseNonsfi) |
+ assert(HasCR == IsPIC); |
+ else |
+ assert(!IsPIC); |
+} |
+ |
} // end of anonymous namespace |
void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const { |
if (!BuildDefs::dump()) |
return; |
+ const bool UseNonsfi = Func->getContext()->getFlags().getUseNonsfi(); |
+ validateMemOperandPIC(this, UseNonsfi); |
const auto *Target = static_cast<const Ice::TargetX8632 *>(Func->getTarget()); |
// If the base is rematerializable, we need to replace it with the correct |
// physical register (esp or ebp), and update the Offset. |
@@ -134,9 +153,9 @@ void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const { |
} |
// Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading |
// '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr. |
- if (getOffset() == 0 && Disp == 0) { |
+ if (getOffset() == nullptr && Disp == 0) { |
// No offset, emit nothing. |
- } else if (getOffset() == 0 && Disp != 0) { |
+ } else if (getOffset() == nullptr && Disp != 0) { |
Str << Disp; |
} else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
if (getBase() == nullptr || CI->getValue() || Disp != 0) |
@@ -147,7 +166,7 @@ void MachineTraits<TargetX8632>::X86OperandMem::emit(const Cfg *Func) const { |
// TODO(sehr): ConstantRelocatable still needs updating for |
// rematerializable base/index and Disp. |
assert(Disp == 0); |
- CR->emitWithoutPrefix(Target); |
+ CR->emitWithoutPrefix(Target, UseNonsfi ? "@GOTOFF" : ""); |
} else { |
llvm_unreachable("Invalid offset type for x86 mem operand"); |
} |
@@ -242,8 +261,10 @@ MachineTraits<TargetX8632>::Address |
MachineTraits<TargetX8632>::X86OperandMem::toAsmAddress( |
MachineTraits<TargetX8632>::Assembler *Asm, |
const Ice::TargetLowering *TargetLowering) const { |
- int32_t Disp = 0; |
const auto *Target = static_cast<const Ice::TargetX8632 *>(TargetLowering); |
+ const bool UseNonsfi = Target->getGlobalContext()->getFlags().getUseNonsfi(); |
+ validateMemOperandPIC(this, UseNonsfi); |
+ int32_t Disp = 0; |
if (getBase() && getBase()->isRematerializable()) { |
Disp += GetRematerializableOffset(getBase(), Target); |
} |
@@ -260,7 +281,7 @@ MachineTraits<TargetX8632>::X86OperandMem::toAsmAddress( |
} else if (const auto CR = |
llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
Disp += CR->getOffset(); |
- Fixup = Asm->createFixup(RelFixup, CR); |
+ Fixup = Asm->createFixup(Target->getRelFixup(), CR); |
} else { |
llvm_unreachable("Unexpected offset type"); |
} |