this is an initial patch to switch the ppc64 jit over to working in PIC mode,
authorChris Lattner <sabre@nondot.org>
Fri, 8 Dec 2006 04:54:03 +0000 (04:54 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 8 Dec 2006 04:54:03 +0000 (04:54 +0000)
which allows the code to be above the 2G marker.  We still need to JIT emit
dyld stubs to support external, weak, common, etc globals, but that will
happen tomorrow.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32348 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCCodeEmitter.cpp
lib/Target/PowerPC/PPCJITInfo.cpp
lib/Target/PowerPC/PPCTargetMachine.cpp

index 7f5e86fb93f07b64065dbf6b371af6967dce35bd..3857c6a3edbbaed113808e479e82b022bb7a1240 100644 (file)
@@ -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,
index 24a62fe2304268aeaa43d4b77a6eb7102810b44b..e3858f4c8946ea7ca7c05a203dd9f770926f6196 100644 (file)
@@ -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
index dde998f5a7f1e95e8985e3eccc0ecb673f37bf9d..9dcbc0487008b778cc131576ed608f2776dad78e 100644 (file)
@@ -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));