| Index: src/IceInstX8632.cpp
|
| diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
|
| index 28fa07b61ceaef4f0da09692a1c6f7a4702aaab5..1b66b6b7ec55582e329bca08a83278e0f92b5f89 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->getAbsFixup(), CR);
|
| } else {
|
| llvm_unreachable("Unexpected offset type");
|
| }
|
|
|