mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
X86 JIT PIC jumptable support.
llvm-svn: 45616
This commit is contained in:
parent
377c720459
commit
759f389846
@ -58,6 +58,7 @@ protected:
|
|||||||
/// all code emission requests will be ignored (this is the buffer overflow
|
/// all code emission requests will be ignored (this is the buffer overflow
|
||||||
/// condition).
|
/// condition).
|
||||||
unsigned char *CurBufferPtr;
|
unsigned char *CurBufferPtr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~MachineCodeEmitter() {}
|
virtual ~MachineCodeEmitter() {}
|
||||||
|
|
||||||
|
@ -55,6 +55,13 @@ namespace llvm {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getPICJumpTableEntry - Returns the value of the jumptable entry for the
|
||||||
|
/// specific basic block.
|
||||||
|
virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase) {
|
||||||
|
assert(0 && "This target doesn't implement getPICJumpTableEntry!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// LazyResolverFn - This typedef is used to represent the function that
|
/// LazyResolverFn - This typedef is used to represent the function that
|
||||||
/// unresolved call points should invoke. This is a target specific
|
/// unresolved call points should invoke. This is a target specific
|
||||||
/// function that knows how to walk the stack and find out which stub the
|
/// function that knows how to walk the stack and find out which stub the
|
||||||
|
@ -341,7 +341,7 @@ namespace {
|
|||||||
/// JumpTableBase - A pointer to the first entry in the jump table.
|
/// JumpTableBase - A pointer to the first entry in the jump table.
|
||||||
///
|
///
|
||||||
void *JumpTableBase;
|
void *JumpTableBase;
|
||||||
|
|
||||||
/// Resolver - This contains info about the currently resolved functions.
|
/// Resolver - This contains info about the currently resolved functions.
|
||||||
JITResolver Resolver;
|
JITResolver Resolver;
|
||||||
public:
|
public:
|
||||||
@ -380,7 +380,7 @@ namespace {
|
|||||||
|
|
||||||
virtual intptr_t getConstantPoolEntryAddress(unsigned Entry) const;
|
virtual intptr_t getConstantPoolEntryAddress(unsigned Entry) const;
|
||||||
virtual intptr_t getJumpTableEntryAddress(unsigned Entry) const;
|
virtual intptr_t getJumpTableEntryAddress(unsigned Entry) const;
|
||||||
|
|
||||||
virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
|
virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
|
||||||
assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
|
assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
|
||||||
MBBLocations[MBB->getNumber()] && "MBB not emitted!");
|
MBBLocations[MBB->getNumber()] && "MBB not emitted!");
|
||||||
@ -616,8 +616,10 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
|
|||||||
// Store the offset of the basic block for this jump table slot in the
|
// Store the offset of the basic block for this jump table slot in the
|
||||||
// memory we allocated for the jump table in 'initJumpTableInfo'
|
// memory we allocated for the jump table in 'initJumpTableInfo'
|
||||||
intptr_t Base = (intptr_t)SlotPtr;
|
intptr_t Base = (intptr_t)SlotPtr;
|
||||||
for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi)
|
for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
|
||||||
*SlotPtr++ = (intptr_t)getMachineBasicBlockAddress(MBBs[mi]) - Base;
|
intptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]);
|
||||||
|
*SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?");
|
assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?");
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "x86-emitter"
|
#define DEBUG_TYPE "x86-emitter"
|
||||||
#include "X86InstrInfo.h"
|
#include "X86InstrInfo.h"
|
||||||
|
#include "X86JITInfo.h"
|
||||||
#include "X86Subtarget.h"
|
#include "X86Subtarget.h"
|
||||||
#include "X86TargetMachine.h"
|
#include "X86TargetMachine.h"
|
||||||
#include "X86Relocations.h"
|
#include "X86Relocations.h"
|
||||||
@ -37,19 +38,19 @@ namespace {
|
|||||||
const TargetData *TD;
|
const TargetData *TD;
|
||||||
TargetMachine &TM;
|
TargetMachine &TM;
|
||||||
MachineCodeEmitter &MCE;
|
MachineCodeEmitter &MCE;
|
||||||
intptr_t PICBase;
|
intptr_t PICBaseOffset;
|
||||||
bool Is64BitMode;
|
bool Is64BitMode;
|
||||||
bool IsPIC;
|
bool IsPIC;
|
||||||
public:
|
public:
|
||||||
static char ID;
|
static char ID;
|
||||||
explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
|
explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
|
||||||
: MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm),
|
: MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm),
|
||||||
MCE(mce), PICBase(0), Is64BitMode(false),
|
MCE(mce), PICBaseOffset(0), Is64BitMode(false),
|
||||||
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
|
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
|
||||||
Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
|
Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
|
||||||
const X86InstrInfo &ii, const TargetData &td, bool is64)
|
const X86InstrInfo &ii, const TargetData &td, bool is64)
|
||||||
: MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm),
|
: MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm),
|
||||||
MCE(mce), PICBase(0), Is64BitMode(is64),
|
MCE(mce), PICBaseOffset(0), Is64BitMode(is64),
|
||||||
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
|
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
|
||||||
|
|
||||||
bool runOnMachineFunction(MachineFunction &MF);
|
bool runOnMachineFunction(MachineFunction &MF);
|
||||||
@ -148,7 +149,7 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
|
|||||||
bool isLazy /* = false */) {
|
bool isLazy /* = false */) {
|
||||||
intptr_t RelocCST = 0;
|
intptr_t RelocCST = 0;
|
||||||
if (Reloc == X86::reloc_picrel_word)
|
if (Reloc == X86::reloc_picrel_word)
|
||||||
RelocCST = PICBase;
|
RelocCST = PICBaseOffset;
|
||||||
else if (Reloc == X86::reloc_pcrel_word)
|
else if (Reloc == X86::reloc_pcrel_word)
|
||||||
RelocCST = PCAdj;
|
RelocCST = PCAdj;
|
||||||
MachineRelocation MR = isLazy
|
MachineRelocation MR = isLazy
|
||||||
@ -166,7 +167,7 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
|
|||||||
/// be emitted to the current location in the function, and allow it to be PC
|
/// be emitted to the current location in the function, and allow it to be PC
|
||||||
/// relative.
|
/// relative.
|
||||||
void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
|
void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
|
||||||
intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBase : 0;
|
intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBaseOffset : 0;
|
||||||
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
|
||||||
Reloc, ES, RelocCST));
|
Reloc, ES, RelocCST));
|
||||||
if (Reloc == X86::reloc_absolute_dword)
|
if (Reloc == X86::reloc_absolute_dword)
|
||||||
@ -182,7 +183,7 @@ void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
|
|||||||
intptr_t PCAdj /* = 0 */) {
|
intptr_t PCAdj /* = 0 */) {
|
||||||
intptr_t RelocCST = 0;
|
intptr_t RelocCST = 0;
|
||||||
if (Reloc == X86::reloc_picrel_word)
|
if (Reloc == X86::reloc_picrel_word)
|
||||||
RelocCST = PICBase;
|
RelocCST = PICBaseOffset;
|
||||||
else if (Reloc == X86::reloc_pcrel_word)
|
else if (Reloc == X86::reloc_pcrel_word)
|
||||||
RelocCST = PCAdj;
|
RelocCST = PCAdj;
|
||||||
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
|
||||||
@ -199,7 +200,7 @@ void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
|
|||||||
intptr_t PCAdj /* = 0 */) {
|
intptr_t PCAdj /* = 0 */) {
|
||||||
intptr_t RelocCST = 0;
|
intptr_t RelocCST = 0;
|
||||||
if (Reloc == X86::reloc_picrel_word)
|
if (Reloc == X86::reloc_picrel_word)
|
||||||
RelocCST = PICBase;
|
RelocCST = PICBaseOffset;
|
||||||
else if (Reloc == X86::reloc_pcrel_word)
|
else if (Reloc == X86::reloc_pcrel_word)
|
||||||
RelocCST = PCAdj;
|
RelocCST = PCAdj;
|
||||||
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
|
||||||
@ -615,13 +616,17 @@ void Emitter::emitInstruction(const MachineInstr &MI,
|
|||||||
case X86::FP_REG_KILL:
|
case X86::FP_REG_KILL:
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case X86::MOVPC32r:
|
case X86::MOVPC32r: {
|
||||||
// This emits the "call" portion of this pseudo instruction.
|
// This emits the "call" portion of this pseudo instruction.
|
||||||
MCE.emitByte(BaseOpcode);
|
MCE.emitByte(BaseOpcode);
|
||||||
emitConstant(0, sizeOfImm(Desc));
|
emitConstant(0, sizeOfImm(Desc));
|
||||||
PICBase = MCE.getCurrentPCOffset();
|
// Remember PIC base.
|
||||||
|
PICBaseOffset = MCE.getCurrentPCOffset();
|
||||||
|
X86JITInfo *JTI = dynamic_cast<X86JITInfo*>(TM.getJITInfo());
|
||||||
|
JTI->setPICBase(MCE.getCurrentPCValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
CurOp = NumOps;
|
CurOp = NumOps;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -440,6 +440,12 @@ void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
|
|||||||
return MCE.finishFunctionStub(0);
|
return MCE.finishFunctionStub(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getPICJumpTableEntry - Returns the value of the jumptable entry for the
|
||||||
|
/// specific basic block.
|
||||||
|
intptr_t X86JITInfo::getPICJumpTableEntry(intptr_t BB, intptr_t Entry) {
|
||||||
|
return BB - PICBase;
|
||||||
|
}
|
||||||
|
|
||||||
/// relocate - Before the JIT can run a block of code that has been emitted,
|
/// relocate - Before the JIT can run a block of code that has been emitted,
|
||||||
/// it must rewrite the code to contain the actual addresses of any
|
/// it must rewrite the code to contain the actual addresses of any
|
||||||
/// referenced global symbols.
|
/// referenced global symbols.
|
||||||
|
@ -21,6 +21,7 @@ namespace llvm {
|
|||||||
|
|
||||||
class X86JITInfo : public TargetJITInfo {
|
class X86JITInfo : public TargetJITInfo {
|
||||||
X86TargetMachine &TM;
|
X86TargetMachine &TM;
|
||||||
|
intptr_t PICBase;
|
||||||
public:
|
public:
|
||||||
X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;}
|
X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;}
|
||||||
|
|
||||||
@ -40,6 +41,10 @@ namespace llvm {
|
|||||||
/// address.
|
/// address.
|
||||||
virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
|
virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
|
||||||
|
|
||||||
|
/// getPICJumpTableEntry - Returns the value of the jumptable entry for the
|
||||||
|
/// specific basic block.
|
||||||
|
virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase);
|
||||||
|
|
||||||
/// getLazyResolverFunction - Expose the lazy resolver to the JIT.
|
/// getLazyResolverFunction - Expose the lazy resolver to the JIT.
|
||||||
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
|
virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
|
||||||
|
|
||||||
@ -48,6 +53,11 @@ namespace llvm {
|
|||||||
/// referenced global symbols.
|
/// referenced global symbols.
|
||||||
virtual void relocate(void *Function, MachineRelocation *MR,
|
virtual void relocate(void *Function, MachineRelocation *MR,
|
||||||
unsigned NumRelocs, unsigned char* GOTBase);
|
unsigned NumRelocs, unsigned char* GOTBase);
|
||||||
|
|
||||||
|
/// setPICBase / getPICBase - Getter / setter of PICBase, used to compute
|
||||||
|
/// PIC jumptable entry.
|
||||||
|
void setPICBase(intptr_t Base) { PICBase = Base; }
|
||||||
|
intptr_t getPICBase() const { return PICBase; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user