diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 7f5e86fb93f..3857c6a3edb 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -31,6 +31,10 @@ namespace { 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); @@ -77,6 +81,7 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 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); @@ -102,7 +107,9 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { 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; } } @@ -129,6 +136,15 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { 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: @@ -136,6 +152,7 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { case PPC::ADDIS: case PPC::ADDIS8: Reloc = PPC::reloc_absolute_high; // Pointer to symbol + rv >>= 16; break; case PPC::LI: case PPC::LI8: @@ -156,6 +173,7 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { case PPC::STFS: case PPC::STFD: Reloc = PPC::reloc_absolute_low; + rv &= 0xFFFF; break; case PPC::LWA: @@ -163,6 +181,8 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { case PPC::STD: case PPC::STD_32: Reloc = PPC::reloc_absolute_low_ix; + rv &= 0xFFFF; + rv >>= 2; break; } } @@ -185,8 +205,7 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { 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, diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp index 24a62fe2304..e3858f4c894 100644 --- a/lib/Target/PowerPC/PPCJITInfo.cpp +++ b/lib/Target/PowerPC/PPCJITInfo.cpp @@ -103,6 +103,7 @@ asm( // 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 @@ -164,6 +165,7 @@ asm( // 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 diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index dde998f5a7f..9dcbc048700 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -135,9 +135,17 @@ bool PPCTargetMachine::addObjectWriter(FunctionPassManager &PM, bool Fast, 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));