LLVM API Documentation
00001 //===-- PPCJITInfo.cpp - Implement the JIT interfaces for the PowerPC -----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the JIT interfaces for the 32-bit PowerPC target. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #define DEBUG_TYPE "jit" 00015 #include "PPCJITInfo.h" 00016 #include "PPCRelocations.h" 00017 #include "PPCTargetMachine.h" 00018 #include "llvm/Function.h" 00019 #include "llvm/CodeGen/MachineCodeEmitter.h" 00020 #include "llvm/System/Memory.h" 00021 #include "llvm/Support/Debug.h" 00022 using namespace llvm; 00023 00024 static TargetJITInfo::JITCompilerFn JITCompilerFunction; 00025 00026 #define BUILD_ADDIS(RD,RS,IMM16) \ 00027 ((15 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535)) 00028 #define BUILD_ORI(RD,RS,UIMM16) \ 00029 ((24 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 00030 #define BUILD_ORIS(RD,RS,UIMM16) \ 00031 ((25 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 00032 #define BUILD_RLDICR(RD,RS,SH,ME) \ 00033 ((30 << 26) | ((RS) << 21) | ((RD) << 16) | (((SH) & 31) << 11) | \ 00034 (((ME) & 63) << 6) | (1 << 2) | ((((SH) >> 5) & 1) << 1)) 00035 #define BUILD_MTSPR(RS,SPR) \ 00036 ((31 << 26) | ((RS) << 21) | ((SPR) << 16) | (467 << 1)) 00037 #define BUILD_BCCTRx(BO,BI,LINK) \ 00038 ((19 << 26) | ((BO) << 21) | ((BI) << 16) | (528 << 1) | ((LINK) & 1)) 00039 #define BUILD_B(TARGET, LINK) \ 00040 ((18 << 26) | (((TARGET) & 0x00FFFFFF) << 2) | ((LINK) & 1)) 00041 00042 // Pseudo-ops 00043 #define BUILD_LIS(RD,IMM16) BUILD_ADDIS(RD,0,IMM16) 00044 #define BUILD_SLDI(RD,RS,IMM6) BUILD_RLDICR(RD,RS,IMM6,63-IMM6) 00045 #define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9) 00046 #define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK) 00047 00048 static void EmitBranchToAt(uint64_t At, uint64_t To, bool isCall, bool is64Bit){ 00049 intptr_t Offset = ((intptr_t)To - (intptr_t)At) >> 2; 00050 unsigned *AtI = (unsigned*)(intptr_t)At; 00051 00052 if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 00053 AtI[0] = BUILD_B(Offset, isCall); // b/bl target 00054 } else if (!is64Bit) { 00055 AtI[0] = BUILD_LIS(12, To >> 16); // lis r12, hi16(address) 00056 AtI[1] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 00057 AtI[2] = BUILD_MTCTR(12); // mtctr r12 00058 AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl 00059 } else { 00060 AtI[0] = BUILD_LIS(12, To >> 48); // lis r12, hi16(address) 00061 AtI[1] = BUILD_ORI(12, 12, To >> 32); // ori r12, r12, lo16(address) 00062 AtI[2] = BUILD_SLDI(12, 12, 32); // sldi r12, r12, 32 00063 AtI[3] = BUILD_ORIS(12, 12, To >> 16); // oris r12, r12, hi16(address) 00064 AtI[4] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 00065 AtI[5] = BUILD_MTCTR(12); // mtctr r12 00066 AtI[6] = BUILD_BCTR(isCall); // bctr/bctrl 00067 } 00068 } 00069 00070 extern "C" void PPC32CompilationCallback(); 00071 extern "C" void PPC64CompilationCallback(); 00072 00073 #if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 00074 !(defined(__ppc64__) || defined(__FreeBSD__)) 00075 // CompilationCallback stub - We can't use a C function with inline assembly in 00076 // it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 00077 // write our own wrapper, which does things our way, so we have complete control 00078 // over register saving and restoring. 00079 asm( 00080 ".text\n" 00081 ".align 2\n" 00082 ".globl _PPC32CompilationCallback\n" 00083 "_PPC32CompilationCallback:\n" 00084 // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 00085 // FIXME: need to save v[0-19] for altivec? 00086 // FIXME: could shrink frame 00087 // Set up a proper stack frame 00088 // FIXME Layout 00089 // PowerPC64 ABI linkage - 24 bytes 00090 // parameters - 32 bytes 00091 // 13 double registers - 104 bytes 00092 // 8 int registers - 32 bytes 00093 "mflr r0\n" 00094 "stw r0, 8(r1)\n" 00095 "stwu r1, -208(r1)\n" 00096 // Save all int arg registers 00097 "stw r10, 204(r1)\n" "stw r9, 200(r1)\n" 00098 "stw r8, 196(r1)\n" "stw r7, 192(r1)\n" 00099 "stw r6, 188(r1)\n" "stw r5, 184(r1)\n" 00100 "stw r4, 180(r1)\n" "stw r3, 176(r1)\n" 00101 // Save all call-clobbered FP regs. 00102 "stfd f13, 168(r1)\n" "stfd f12, 160(r1)\n" 00103 "stfd f11, 152(r1)\n" "stfd f10, 144(r1)\n" 00104 "stfd f9, 136(r1)\n" "stfd f8, 128(r1)\n" 00105 "stfd f7, 120(r1)\n" "stfd f6, 112(r1)\n" 00106 "stfd f5, 104(r1)\n" "stfd f4, 96(r1)\n" 00107 "stfd f3, 88(r1)\n" "stfd f2, 80(r1)\n" 00108 "stfd f1, 72(r1)\n" 00109 // Arguments to Compilation Callback: 00110 // r3 - our lr (address of the call instruction in stub plus 4) 00111 // r4 - stub's lr (address of instruction that called the stub plus 4) 00112 // r5 - is64Bit - always 0. 00113 "mr r3, r0\n" 00114 "lwz r2, 208(r1)\n" // stub's frame 00115 "lwz r4, 8(r2)\n" // stub's lr 00116 "li r5, 0\n" // 0 == 32 bit 00117 "bl _PPCCompilationCallbackC\n" 00118 "mtctr r3\n" 00119 // Restore all int arg registers 00120 "lwz r10, 204(r1)\n" "lwz r9, 200(r1)\n" 00121 "lwz r8, 196(r1)\n" "lwz r7, 192(r1)\n" 00122 "lwz r6, 188(r1)\n" "lwz r5, 184(r1)\n" 00123 "lwz r4, 180(r1)\n" "lwz r3, 176(r1)\n" 00124 // Restore all FP arg registers 00125 "lfd f13, 168(r1)\n" "lfd f12, 160(r1)\n" 00126 "lfd f11, 152(r1)\n" "lfd f10, 144(r1)\n" 00127 "lfd f9, 136(r1)\n" "lfd f8, 128(r1)\n" 00128 "lfd f7, 120(r1)\n" "lfd f6, 112(r1)\n" 00129 "lfd f5, 104(r1)\n" "lfd f4, 96(r1)\n" 00130 "lfd f3, 88(r1)\n" "lfd f2, 80(r1)\n" 00131 "lfd f1, 72(r1)\n" 00132 // Pop 3 frames off the stack and branch to target 00133 "lwz r1, 208(r1)\n" 00134 "lwz r2, 8(r1)\n" 00135 "mtlr r2\n" 00136 "bctr\n" 00137 ); 00138 00139 #elif defined(__PPC__) && !defined(__ppc64__) 00140 // Linux & FreeBSD / PPC 32 support 00141 00142 // CompilationCallback stub - We can't use a C function with inline assembly in 00143 // it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 00144 // write our own wrapper, which does things our way, so we have complete control 00145 // over register saving and restoring. 00146 asm( 00147 ".text\n" 00148 ".align 2\n" 00149 ".globl PPC32CompilationCallback\n" 00150 "PPC32CompilationCallback:\n" 00151 // Make space for 8 ints r[3-10] and 8 doubles f[1-8] and the 00152 // FIXME: need to save v[0-19] for altivec? 00153 // FIXME: could shrink frame 00154 // Set up a proper stack frame 00155 // FIXME Layout 00156 // 8 double registers - 64 bytes 00157 // 8 int registers - 32 bytes 00158 "mflr 0\n" 00159 "stw 0, 4(1)\n" 00160 "stwu 1, -104(1)\n" 00161 // Save all int arg registers 00162 "stw 10, 100(1)\n" "stw 9, 96(1)\n" 00163 "stw 8, 92(1)\n" "stw 7, 88(1)\n" 00164 "stw 6, 84(1)\n" "stw 5, 80(1)\n" 00165 "stw 4, 76(1)\n" "stw 3, 72(1)\n" 00166 // Save all call-clobbered FP regs. 00167 "stfd 8, 64(1)\n" 00168 "stfd 7, 56(1)\n" "stfd 6, 48(1)\n" 00169 "stfd 5, 40(1)\n" "stfd 4, 32(1)\n" 00170 "stfd 3, 24(1)\n" "stfd 2, 16(1)\n" 00171 "stfd 1, 8(1)\n" 00172 // Arguments to Compilation Callback: 00173 // r3 - our lr (address of the call instruction in stub plus 4) 00174 // r4 - stub's lr (address of instruction that called the stub plus 4) 00175 // r5 - is64Bit - always 0. 00176 "mr 3, 0\n" 00177 "lwz 5, 104(1)\n" // stub's frame 00178 "lwz 4, 4(5)\n" // stub's lr 00179 "li 5, 0\n" // 0 == 32 bit 00180 "bl PPCCompilationCallbackC\n" 00181 "mtctr 3\n" 00182 // Restore all int arg registers 00183 "lwz 10, 100(1)\n" "lwz 9, 96(1)\n" 00184 "lwz 8, 92(1)\n" "lwz 7, 88(1)\n" 00185 "lwz 6, 84(1)\n" "lwz 5, 80(1)\n" 00186 "lwz 4, 76(1)\n" "lwz 3, 72(1)\n" 00187 // Restore all FP arg registers 00188 "lfd 8, 64(1)\n" 00189 "lfd 7, 56(1)\n" "lfd 6, 48(1)\n" 00190 "lfd 5, 40(1)\n" "lfd 4, 32(1)\n" 00191 "lfd 3, 24(1)\n" "lfd 2, 16(1)\n" 00192 "lfd 1, 8(1)\n" 00193 // Pop 3 frames off the stack and branch to target 00194 "lwz 1, 104(1)\n" 00195 "lwz 0, 4(1)\n" 00196 "mtlr 0\n" 00197 "bctr\n" 00198 ); 00199 #else 00200 void PPC32CompilationCallback() { 00201 assert(0 && "This is not a power pc, you can't execute this!"); 00202 abort(); 00203 } 00204 #endif 00205 00206 #if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 00207 defined(__ppc64__) 00208 asm( 00209 ".text\n" 00210 ".align 2\n" 00211 ".globl _PPC64CompilationCallback\n" 00212 "_PPC64CompilationCallback:\n" 00213 // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 00214 // FIXME: need to save v[0-19] for altivec? 00215 // Set up a proper stack frame 00216 // Layout 00217 // PowerPC64 ABI linkage - 48 bytes 00218 // parameters - 64 bytes 00219 // 13 double registers - 104 bytes 00220 // 8 int registers - 64 bytes 00221 "mflr r0\n" 00222 "std r0, 16(r1)\n" 00223 "stdu r1, -280(r1)\n" 00224 // Save all int arg registers 00225 "std r10, 272(r1)\n" "std r9, 264(r1)\n" 00226 "std r8, 256(r1)\n" "std r7, 248(r1)\n" 00227 "std r6, 240(r1)\n" "std r5, 232(r1)\n" 00228 "std r4, 224(r1)\n" "std r3, 216(r1)\n" 00229 // Save all call-clobbered FP regs. 00230 "stfd f13, 208(r1)\n" "stfd f12, 200(r1)\n" 00231 "stfd f11, 192(r1)\n" "stfd f10, 184(r1)\n" 00232 "stfd f9, 176(r1)\n" "stfd f8, 168(r1)\n" 00233 "stfd f7, 160(r1)\n" "stfd f6, 152(r1)\n" 00234 "stfd f5, 144(r1)\n" "stfd f4, 136(r1)\n" 00235 "stfd f3, 128(r1)\n" "stfd f2, 120(r1)\n" 00236 "stfd f1, 112(r1)\n" 00237 // Arguments to Compilation Callback: 00238 // r3 - our lr (address of the call instruction in stub plus 4) 00239 // r4 - stub's lr (address of instruction that called the stub plus 4) 00240 // r5 - is64Bit - always 1. 00241 "mr r3, r0\n" 00242 "ld r2, 280(r1)\n" // stub's frame 00243 "ld r4, 16(r2)\n" // stub's lr 00244 "li r5, 1\n" // 1 == 64 bit 00245 "bl _PPCCompilationCallbackC\n" 00246 "mtctr r3\n" 00247 // Restore all int arg registers 00248 "ld r10, 272(r1)\n" "ld r9, 264(r1)\n" 00249 "ld r8, 256(r1)\n" "ld r7, 248(r1)\n" 00250 "ld r6, 240(r1)\n" "ld r5, 232(r1)\n" 00251 "ld r4, 224(r1)\n" "ld r3, 216(r1)\n" 00252 // Restore all FP arg registers 00253 "lfd f13, 208(r1)\n" "lfd f12, 200(r1)\n" 00254 "lfd f11, 192(r1)\n" "lfd f10, 184(r1)\n" 00255 "lfd f9, 176(r1)\n" "lfd f8, 168(r1)\n" 00256 "lfd f7, 160(r1)\n" "lfd f6, 152(r1)\n" 00257 "lfd f5, 144(r1)\n" "lfd f4, 136(r1)\n" 00258 "lfd f3, 128(r1)\n" "lfd f2, 120(r1)\n" 00259 "lfd f1, 112(r1)\n" 00260 // Pop 3 frames off the stack and branch to target 00261 "ld r1, 280(r1)\n" 00262 "ld r2, 16(r1)\n" 00263 "mtlr r2\n" 00264 "bctr\n" 00265 ); 00266 #else 00267 void PPC64CompilationCallback() { 00268 assert(0 && "This is not a power pc, you can't execute this!"); 00269 abort(); 00270 } 00271 #endif 00272 00273 extern "C" void *PPCCompilationCallbackC(unsigned *StubCallAddrPlus4, 00274 unsigned *OrigCallAddrPlus4, 00275 bool is64Bit) { 00276 // Adjust the pointer to the address of the call instruction in the stub 00277 // emitted by emitFunctionStub, rather than the instruction after it. 00278 unsigned *StubCallAddr = StubCallAddrPlus4 - 1; 00279 unsigned *OrigCallAddr = OrigCallAddrPlus4 - 1; 00280 00281 void *Target = JITCompilerFunction(StubCallAddr); 00282 00283 // Check to see if *OrigCallAddr is a 'bl' instruction, and if we can rewrite 00284 // it to branch directly to the destination. If so, rewrite it so it does not 00285 // need to go through the stub anymore. 00286 unsigned OrigCallInst = *OrigCallAddr; 00287 if ((OrigCallInst >> 26) == 18) { // Direct call. 00288 intptr_t Offset = ((intptr_t)Target - (intptr_t)OrigCallAddr) >> 2; 00289 00290 if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 00291 // Clear the original target out. 00292 OrigCallInst &= (63 << 26) | 3; 00293 // Fill in the new target. 00294 OrigCallInst |= (Offset & ((1 << 24)-1)) << 2; 00295 // Replace the call. 00296 *OrigCallAddr = OrigCallInst; 00297 } 00298 } 00299 00300 // Assert that we are coming from a stub that was created with our 00301 // emitFunctionStub. 00302 if ((*StubCallAddr >> 26) == 18) 00303 StubCallAddr -= 3; 00304 else { 00305 assert((*StubCallAddr >> 26) == 19 && "Call in stub is not indirect!"); 00306 StubCallAddr -= is64Bit ? 9 : 6; 00307 } 00308 00309 // Rewrite the stub with an unconditional branch to the target, for any users 00310 // who took the address of the stub. 00311 EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit); 00312 00313 // Put the address of the target function to call and the address to return to 00314 // after calling the target function in a place that is easy to get on the 00315 // stack after we restore all regs. 00316 return Target; 00317 } 00318 00319 00320 00321 TargetJITInfo::LazyResolverFn 00322 PPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) { 00323 JITCompilerFunction = Fn; 00324 return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback; 00325 } 00326 00327 #if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 00328 defined(__APPLE__) 00329 extern "C" void sys_icache_invalidate(const void *Addr, size_t len); 00330 #endif 00331 00332 void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn, 00333 MachineCodeEmitter &MCE) { 00334 // If this is just a call to an external function, emit a branch instead of a 00335 // call. The code is the same except for one bit of the last instruction. 00336 if (Fn != (void*)(intptr_t)PPC32CompilationCallback && 00337 Fn != (void*)(intptr_t)PPC64CompilationCallback) { 00338 MCE.startGVStub(F, 7*4); 00339 intptr_t Addr = (intptr_t)MCE.getCurrentPCValue(); 00340 MCE.emitWordBE(0); 00341 MCE.emitWordBE(0); 00342 MCE.emitWordBE(0); 00343 MCE.emitWordBE(0); 00344 MCE.emitWordBE(0); 00345 MCE.emitWordBE(0); 00346 MCE.emitWordBE(0); 00347 EmitBranchToAt(Addr, (intptr_t)Fn, false, is64Bit); 00348 sys::Memory::InvalidateInstructionCache((void*)Addr, 7*4); 00349 return MCE.finishGVStub(F); 00350 } 00351 00352 MCE.startGVStub(F, 10*4); 00353 intptr_t Addr = (intptr_t)MCE.getCurrentPCValue(); 00354 if (is64Bit) { 00355 MCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1) 00356 MCE.emitWordBE(0x7d6802a6); // mflr r11 00357 MCE.emitWordBE(0xf9610060); // std r11, 96(r1) 00358 } else if (TM.getSubtargetImpl()->isMachoABI()){ 00359 MCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 00360 MCE.emitWordBE(0x7d6802a6); // mflr r11 00361 MCE.emitWordBE(0x91610028); // stw r11, 40(r1) 00362 } else { 00363 MCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 00364 MCE.emitWordBE(0x7d6802a6); // mflr r11 00365 MCE.emitWordBE(0x91610024); // stw r11, 36(r1) 00366 } 00367 intptr_t BranchAddr = (intptr_t)MCE.getCurrentPCValue(); 00368 MCE.emitWordBE(0); 00369 MCE.emitWordBE(0); 00370 MCE.emitWordBE(0); 00371 MCE.emitWordBE(0); 00372 MCE.emitWordBE(0); 00373 MCE.emitWordBE(0); 00374 MCE.emitWordBE(0); 00375 EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit); 00376 sys::Memory::InvalidateInstructionCache((void*)Addr, 10*4); 00377 return MCE.finishGVStub(F); 00378 } 00379 00380 00381 void PPCJITInfo::relocate(void *Function, MachineRelocation *MR, 00382 unsigned NumRelocs, unsigned char* GOTBase) { 00383 for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { 00384 unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; 00385 intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); 00386 switch ((PPC::RelocationType)MR->getRelocationType()) { 00387 default: assert(0 && "Unknown relocation type!"); 00388 case PPC::reloc_pcrel_bx: 00389 // PC-relative relocation for b and bl instructions. 00390 ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 00391 assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) && 00392 "Relocation out of range!"); 00393 *RelocPos |= (ResultPtr & ((1 << 24)-1)) << 2; 00394 break; 00395 case PPC::reloc_pcrel_bcx: 00396 // PC-relative relocation for BLT,BLE,BEQ,BGE,BGT,BNE, or other 00397 // bcx instructions. 00398 ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 00399 assert(ResultPtr >= -(1 << 13) && ResultPtr < (1 << 13) && 00400 "Relocation out of range!"); 00401 *RelocPos |= (ResultPtr & ((1 << 14)-1)) << 2; 00402 break; 00403 case PPC::reloc_absolute_high: // high bits of ref -> low 16 of instr 00404 case PPC::reloc_absolute_low: { // low bits of ref -> low 16 of instr 00405 ResultPtr += MR->getConstantVal(); 00406 00407 // If this is a high-part access, get the high-part. 00408 if (MR->getRelocationType() == PPC::reloc_absolute_high) { 00409 // If the low part will have a carry (really a borrow) from the low 00410 // 16-bits into the high 16, add a bit to borrow from. 00411 if (((int)ResultPtr << 16) < 0) 00412 ResultPtr += 1 << 16; 00413 ResultPtr >>= 16; 00414 } 00415 00416 // Do the addition then mask, so the addition does not overflow the 16-bit 00417 // immediate section of the instruction. 00418 unsigned LowBits = (*RelocPos + ResultPtr) & 65535; 00419 unsigned HighBits = *RelocPos & ~65535; 00420 *RelocPos = LowBits | HighBits; // Slam into low 16-bits 00421 break; 00422 } 00423 case PPC::reloc_absolute_low_ix: { // low bits of ref -> low 14 of instr 00424 ResultPtr += MR->getConstantVal(); 00425 // Do the addition then mask, so the addition does not overflow the 16-bit 00426 // immediate section of the instruction. 00427 unsigned LowBits = (*RelocPos + ResultPtr) & 0xFFFC; 00428 unsigned HighBits = *RelocPos & 0xFFFF0003; 00429 *RelocPos = LowBits | HighBits; // Slam into low 14-bits. 00430 break; 00431 } 00432 } 00433 } 00434 } 00435 00436 void PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { 00437 EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit); 00438 }