Index: src/IceTargetLoweringX8632.cpp |
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
index a09629c477d7f6f4032eeeca09580128c0464a1d..724084fea9736670096588e0c6e2cd564491a58e 100644 |
--- a/src/IceTargetLoweringX8632.cpp |
+++ b/src/IceTargetLoweringX8632.cpp |
@@ -99,6 +99,14 @@ template <> |
llvm::SmallBitVector |
TargetX86Base<TargetX8632>::ScratchRegs = llvm::SmallBitVector(); |
+template <> |
+FixupKind TargetX86Base<TargetX8632>::PcRelFixup = |
John
2015/12/22 15:44:38
I know this will be painful to change, but pic(k)
Jim Stichnoth
2015/12/28 07:54:07
New naming scheme described in a previous comment.
|
+ TargetX86Base<TargetX8632>::Traits::FixupKindPcRel; |
+ |
+template <> |
+FixupKind TargetX86Base<TargetX8632>::RelFixup = |
+ TargetX86Base<TargetX8632>::Traits::FixupKindAbs; |
+ |
} // end of namespace X86Internal |
//------------------------------------------------------------------------------ |
@@ -229,7 +237,8 @@ void TargetX8632::lowerCall(const InstCall *Instr) { |
break; |
} |
} |
- Operand *CallTarget = legalize(Instr->getCallTarget()); |
+ Operand *CallTarget = |
+ legalize(Instr->getCallTarget(), Legal_Reg | Legal_Imm | Legal_AddrAbs); |
const bool NeedSandboxing = Ctx->getFlags().getUseSandboxing(); |
if (NeedSandboxing) { |
if (llvm::isa<Constant>(CallTarget)) { |
@@ -403,6 +412,21 @@ void TargetX8632::addProlog(CfgNode *Node) { |
Context.init(Node); |
Context.setInsertPoint(Context.getCur()); |
+ // If there is a non-deleted InstX86GetIP instruction, we need to move it to |
+ // the point after the stack frame has stabilized but before |
+ // register-allocated in-args are copied into their home registers. |
+ X86Internal::InstX86GetIP<TargetX8632> *GetIPInst = nullptr; |
+ if (Ctx->getFlags().getUseNonsfi()) { |
+ for (Inst &Instr : Node->getInsts()) { |
+ if (auto *GetIP = |
+ llvm::dyn_cast<X86Internal::InstX86GetIP<TargetX8632>>(&Instr)) { |
+ if (!Instr.isDeleted()) |
+ GetIPInst = GetIP; |
+ break; |
+ } |
+ } |
+ } |
+ |
llvm::SmallBitVector CalleeSaves = |
getRegisterSet(RegSet_CalleeSave, RegSet_None); |
RegsUsed = llvm::SmallBitVector(CalleeSaves.size()); |
@@ -544,6 +568,27 @@ void TargetX8632::addProlog(CfgNode *Node) { |
if (!IsEbpBasedFrame) |
BasicFrameOffset += SpillAreaSizeBytes; |
+ // Delete any existing InstX86GetIP instruction and reinsert it here. Also, |
+ // insert the call to the helper function and the spill to the stack, to |
+ // simplify emission. |
+ if (GetIPInst) { |
+ GetIPInst->setDeleted(); |
+ Variable *Dest = GetIPInst->getDest(); |
+ Variable *CallDest = |
+ Dest->hasReg() ? Dest |
+ : getPhysicalRegister(Traits::RegisterSet::Reg_eax); |
+ // Call the getIP_<reg> helper. |
+ IceString RegName = Traits::getRegName(CallDest->getRegNum()); |
+ Constant *CallTarget = Ctx->getConstantExternSym(H_getIP_prefix + RegName); |
+ Context.insert<Traits::Insts::Call>(CallDest, CallTarget); |
+ // Insert a new version of InstX86GetIP. |
+ Context.insert<X86Internal::InstX86GetIP<TargetX8632>>(CallDest); |
+ // Spill the register to its home stack location if necessary. |
+ if (!Dest->hasReg()) { |
+ _mov(Dest, CallDest); |
+ } |
+ } |
+ |
const VarList &Args = Func->getArgs(); |
size_t InArgsSizeBytes = 0; |
unsigned NumXmmArgs = 0; |
@@ -684,8 +729,10 @@ void TargetX8632::emitJumpTable(const Cfg *Func, |
if (!BuildDefs::dump()) |
return; |
Ostream &Str = Ctx->getStrEmit(); |
- IceString MangledName = Ctx->mangleName(Func->getFunctionName()); |
- Str << "\t.section\t.rodata." << MangledName |
+ const bool UseNonsfi = Ctx->getFlags().getUseNonsfi(); |
+ const IceString MangledName = Ctx->mangleName(Func->getFunctionName()); |
+ const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata."; |
+ Str << "\t.section\t" << Prefix << MangledName |
<< "$jumptable,\"a\",@progbits\n"; |
Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":"; |
@@ -844,11 +891,12 @@ void TargetDataX8632::lowerConstants() { |
} |
void TargetDataX8632::lowerJumpTables() { |
+ const bool IsPIC = Ctx->getFlags().getUseNonsfi(); |
switch (Ctx->getFlags().getOutFileType()) { |
case FT_Elf: { |
ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
for (const JumpTableData &JT : Ctx->getJumpTables()) |
- Writer->writeJumpTable(JT, TargetX8632::Traits::RelFixup); |
+ Writer->writeJumpTable(JT, TargetX8632::Traits::FixupKindAbs, IsPIC); |
} break; |
case FT_Asm: |
// Already emitted from Cfg |
@@ -857,8 +905,9 @@ void TargetDataX8632::lowerJumpTables() { |
if (!BuildDefs::dump()) |
return; |
Ostream &Str = Ctx->getStrEmit(); |
+ const IceString Prefix = IsPIC ? ".data.rel.ro." : ".rodata."; |
for (const JumpTableData &JT : Ctx->getJumpTables()) { |
- Str << "\t.section\t.rodata." << JT.getFunctionName() |
+ Str << "\t.section\t" << Prefix << JT.getFunctionName() |
<< "$jumptable,\"a\",@progbits\n"; |
Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n"; |
Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":"; |
@@ -874,11 +923,12 @@ void TargetDataX8632::lowerJumpTables() { |
void TargetDataX8632::lowerGlobals(const VariableDeclarationList &Vars, |
const IceString &SectionSuffix) { |
+ const bool IsPIC = Ctx->getFlags().getUseNonsfi(); |
switch (Ctx->getFlags().getOutFileType()) { |
case FT_Elf: { |
ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
- Writer->writeDataSection(Vars, TargetX8632::Traits::RelFixup, |
- SectionSuffix); |
+ Writer->writeDataSection(Vars, TargetX8632::Traits::FixupKindAbs, |
+ SectionSuffix, IsPIC); |
} break; |
case FT_Asm: |
case FT_Iasm: { |