TargetMachine &TM;
MachineCodeEmitter &MCE;
+ /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
+ /// its address in the function into this pointer.
+ void *MovePCtoLROffset;
+
/// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
///
int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
do {
+ MovePCtoLROffset = 0;
MCE.startFunction(MF);
for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
emitBasicBlock(*BB);
break; // pseudo opcode, no side effects
case PPC::MovePCtoLR:
case PPC::MovePCtoLR8:
- assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
+ assert(TM.getRelocationModel() == Reloc::PIC_);
+ MovePCtoLROffset = (void*)MCE.getCurrentPCValue();
+ MCE.emitWordBE(0x48000005); // bl 1
break;
}
}
if (MI.getOpcode() == PPC::BL || MI.getOpcode() == PPC::BL8)
Reloc = PPC::reloc_pcrel_bx;
else {
+ // If in PIC mode, we need to encode the negated address of the
+ // 'movepctolr' into the unrelocated field. After relocation, we'll have
+ // &gv-&movepctolr in the imm field. Once &movepctolr is added to the imm
+ // field, we get &gv.
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
+ rv = -(intptr_t)MovePCtoLROffset - 4;
+ }
+
switch (MI.getOpcode()) {
default: MI.dump(); assert(0 && "Unknown instruction for relocation!");
case PPC::LIS:
case PPC::ADDIS:
case PPC::ADDIS8:
Reloc = PPC::reloc_absolute_high; // Pointer to symbol
+ rv >>= 16;
break;
case PPC::LI:
case PPC::LI8:
case PPC::STFS:
case PPC::STFD:
Reloc = PPC::reloc_absolute_low;
+ rv &= 0xFFFF;
break;
case PPC::LWA:
case PPC::STD:
case PPC::STD_32:
Reloc = PPC::reloc_absolute_low_ix;
+ rv &= 0xFFFF;
+ rv >>= 2;
break;
}
}
unsigned Opcode = MI.getOpcode();
if (Opcode == PPC::B || Opcode == PPC::BL || Opcode == PPC::BLA)
Reloc = PPC::reloc_pcrel_bx;
- else
- // BLT,BLE,BEQ,BGE,BGT,BNE, or other bcx instruction
+ else // BCC instruction
Reloc = PPC::reloc_pcrel_bcx;
MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
Reloc,
// Arguments to Compilation Callback:
// r3 - our lr (address of the call instruction in stub plus 4)
// r4 - stub's lr (address of instruction that called the stub plus 4)
+ // r5 - is64Bit - always 0.
"mr r3, r0\n"
"lwz r2, 208(r1)\n" // stub's frame
"lwz r4, 8(r2)\n" // stub's lr
// Arguments to Compilation Callback:
// r3 - our lr (address of the call instruction in stub plus 4)
// r4 - stub's lr (address of instruction that called the stub plus 4)
+ // r5 - is64Bit - always 1.
"mr r3, r0\n"
"ld r2, 208(r1)\n" // stub's frame
"ld r4, 16(r2)\n" // stub's lr
bool PPCTargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast,
MachineCodeEmitter &MCE) {
- // The JIT should use the static relocation model.
+ // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64.
// FIXME: This should be moved to TargetJITInfo!!
- setRelocationModel(Reloc::Static);
+ if (Subtarget.isPPC64()) {
+ // We use PIC codegen in ppc64 mode, because otherwise we'd have to use many
+ // instructions to materialize arbitrary global variable + function +
+ // constant pool addresses.
+ setRelocationModel(Reloc::PIC_);
+ } else {
+ setRelocationModel(Reloc::Static);
+ }
+
// Machine code emitter pass for PowerPC.
PM.add(createPPCCodeEmitterPass(*this, MCE));