1193323Sed//===-- PPCJITInfo.cpp - Implement the JIT interfaces for the PowerPC -----===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the JIT interfaces for the 32-bit PowerPC target. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#define DEBUG_TYPE "jit" 15193323Sed#include "PPCJITInfo.h" 16193323Sed#include "PPCRelocations.h" 17193323Sed#include "PPCTargetMachine.h" 18249423Sdim#include "llvm/IR/Function.h" 19193323Sed#include "llvm/Support/Debug.h" 20198090Srdivacky#include "llvm/Support/ErrorHandling.h" 21249423Sdim#include "llvm/Support/Memory.h" 22198090Srdivacky#include "llvm/Support/raw_ostream.h" 23193323Sedusing namespace llvm; 24193323Sed 25193323Sedstatic TargetJITInfo::JITCompilerFn JITCompilerFunction; 26193323Sed 27193323Sed#define BUILD_ADDIS(RD,RS,IMM16) \ 28193323Sed ((15 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535)) 29193323Sed#define BUILD_ORI(RD,RS,UIMM16) \ 30193323Sed ((24 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 31193323Sed#define BUILD_ORIS(RD,RS,UIMM16) \ 32193323Sed ((25 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 33193323Sed#define BUILD_RLDICR(RD,RS,SH,ME) \ 34193323Sed ((30 << 26) | ((RS) << 21) | ((RD) << 16) | (((SH) & 31) << 11) | \ 35193323Sed (((ME) & 63) << 6) | (1 << 2) | ((((SH) >> 5) & 1) << 1)) 36193323Sed#define BUILD_MTSPR(RS,SPR) \ 37193323Sed ((31 << 26) | ((RS) << 21) | ((SPR) << 16) | (467 << 1)) 38193323Sed#define BUILD_BCCTRx(BO,BI,LINK) \ 39193323Sed ((19 << 26) | ((BO) << 21) | ((BI) << 16) | (528 << 1) | ((LINK) & 1)) 40193323Sed#define BUILD_B(TARGET, LINK) \ 41193323Sed ((18 << 26) | (((TARGET) & 0x00FFFFFF) << 2) | ((LINK) & 1)) 42193323Sed 43193323Sed// Pseudo-ops 44193323Sed#define BUILD_LIS(RD,IMM16) BUILD_ADDIS(RD,0,IMM16) 45193323Sed#define BUILD_SLDI(RD,RS,IMM6) BUILD_RLDICR(RD,RS,IMM6,63-IMM6) 46193323Sed#define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9) 47193323Sed#define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK) 48193323Sed 49193323Sedstatic void EmitBranchToAt(uint64_t At, uint64_t To, bool isCall, bool is64Bit){ 50193323Sed intptr_t Offset = ((intptr_t)To - (intptr_t)At) >> 2; 51193323Sed unsigned *AtI = (unsigned*)(intptr_t)At; 52193323Sed 53193323Sed if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 54193323Sed AtI[0] = BUILD_B(Offset, isCall); // b/bl target 55193323Sed } else if (!is64Bit) { 56193323Sed AtI[0] = BUILD_LIS(12, To >> 16); // lis r12, hi16(address) 57193323Sed AtI[1] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 58193323Sed AtI[2] = BUILD_MTCTR(12); // mtctr r12 59193323Sed AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl 60193323Sed } else { 61193323Sed AtI[0] = BUILD_LIS(12, To >> 48); // lis r12, hi16(address) 62193323Sed AtI[1] = BUILD_ORI(12, 12, To >> 32); // ori r12, r12, lo16(address) 63193323Sed AtI[2] = BUILD_SLDI(12, 12, 32); // sldi r12, r12, 32 64193323Sed AtI[3] = BUILD_ORIS(12, 12, To >> 16); // oris r12, r12, hi16(address) 65193323Sed AtI[4] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 66193323Sed AtI[5] = BUILD_MTCTR(12); // mtctr r12 67193323Sed AtI[6] = BUILD_BCTR(isCall); // bctr/bctrl 68193323Sed } 69193323Sed} 70193323Sed 71193323Sedextern "C" void PPC32CompilationCallback(); 72193323Sedextern "C" void PPC64CompilationCallback(); 73193323Sed 74263508Sdim// The first clause of the preprocessor directive looks wrong, but it is 75263508Sdim// necessary when compiling this code on non-PowerPC hosts. 76263508Sdim#if (!defined(__ppc__) && !defined(__powerpc__)) || defined(__powerpc64__) || defined(__ppc64__) 77263508Sdimvoid PPC32CompilationCallback() { 78263508Sdim llvm_unreachable("This is not a 32bit PowerPC, you can't execute this!"); 79263508Sdim} 80263508Sdim#elif !defined(__ELF__) 81193323Sed// CompilationCallback stub - We can't use a C function with inline assembly in 82193323Sed// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 83193323Sed// write our own wrapper, which does things our way, so we have complete control 84193323Sed// over register saving and restoring. 85193323Sedasm( 86193323Sed ".text\n" 87193323Sed ".align 2\n" 88193323Sed ".globl _PPC32CompilationCallback\n" 89193323Sed"_PPC32CompilationCallback:\n" 90193323Sed // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 91193323Sed // FIXME: need to save v[0-19] for altivec? 92193323Sed // FIXME: could shrink frame 93193323Sed // Set up a proper stack frame 94193323Sed // FIXME Layout 95224145Sdim // PowerPC32 ABI linkage - 24 bytes 96193323Sed // parameters - 32 bytes 97193323Sed // 13 double registers - 104 bytes 98193323Sed // 8 int registers - 32 bytes 99193323Sed "mflr r0\n" 100193323Sed "stw r0, 8(r1)\n" 101193323Sed "stwu r1, -208(r1)\n" 102193323Sed // Save all int arg registers 103193323Sed "stw r10, 204(r1)\n" "stw r9, 200(r1)\n" 104193323Sed "stw r8, 196(r1)\n" "stw r7, 192(r1)\n" 105193323Sed "stw r6, 188(r1)\n" "stw r5, 184(r1)\n" 106193323Sed "stw r4, 180(r1)\n" "stw r3, 176(r1)\n" 107193323Sed // Save all call-clobbered FP regs. 108193323Sed "stfd f13, 168(r1)\n" "stfd f12, 160(r1)\n" 109193323Sed "stfd f11, 152(r1)\n" "stfd f10, 144(r1)\n" 110193323Sed "stfd f9, 136(r1)\n" "stfd f8, 128(r1)\n" 111193323Sed "stfd f7, 120(r1)\n" "stfd f6, 112(r1)\n" 112193323Sed "stfd f5, 104(r1)\n" "stfd f4, 96(r1)\n" 113193323Sed "stfd f3, 88(r1)\n" "stfd f2, 80(r1)\n" 114193323Sed "stfd f1, 72(r1)\n" 115193323Sed // Arguments to Compilation Callback: 116193323Sed // r3 - our lr (address of the call instruction in stub plus 4) 117193323Sed // r4 - stub's lr (address of instruction that called the stub plus 4) 118193323Sed // r5 - is64Bit - always 0. 119193323Sed "mr r3, r0\n" 120193323Sed "lwz r2, 208(r1)\n" // stub's frame 121193323Sed "lwz r4, 8(r2)\n" // stub's lr 122193323Sed "li r5, 0\n" // 0 == 32 bit 123249423Sdim "bl _LLVMPPCCompilationCallback\n" 124193323Sed "mtctr r3\n" 125193323Sed // Restore all int arg registers 126193323Sed "lwz r10, 204(r1)\n" "lwz r9, 200(r1)\n" 127193323Sed "lwz r8, 196(r1)\n" "lwz r7, 192(r1)\n" 128193323Sed "lwz r6, 188(r1)\n" "lwz r5, 184(r1)\n" 129193323Sed "lwz r4, 180(r1)\n" "lwz r3, 176(r1)\n" 130193323Sed // Restore all FP arg registers 131193323Sed "lfd f13, 168(r1)\n" "lfd f12, 160(r1)\n" 132193323Sed "lfd f11, 152(r1)\n" "lfd f10, 144(r1)\n" 133193323Sed "lfd f9, 136(r1)\n" "lfd f8, 128(r1)\n" 134193323Sed "lfd f7, 120(r1)\n" "lfd f6, 112(r1)\n" 135193323Sed "lfd f5, 104(r1)\n" "lfd f4, 96(r1)\n" 136193323Sed "lfd f3, 88(r1)\n" "lfd f2, 80(r1)\n" 137193323Sed "lfd f1, 72(r1)\n" 138193323Sed // Pop 3 frames off the stack and branch to target 139193323Sed "lwz r1, 208(r1)\n" 140193323Sed "lwz r2, 8(r1)\n" 141193323Sed "mtlr r2\n" 142193323Sed "bctr\n" 143193323Sed ); 144193323Sed 145263508Sdim#else 146263508Sdim// ELF PPC 32 support 147193323Sed 148193323Sed// CompilationCallback stub - We can't use a C function with inline assembly in 149193323Sed// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 150193323Sed// write our own wrapper, which does things our way, so we have complete control 151193323Sed// over register saving and restoring. 152193323Sedasm( 153193323Sed ".text\n" 154193323Sed ".align 2\n" 155193323Sed ".globl PPC32CompilationCallback\n" 156193323Sed"PPC32CompilationCallback:\n" 157193323Sed // Make space for 8 ints r[3-10] and 8 doubles f[1-8] and the 158193323Sed // FIXME: need to save v[0-19] for altivec? 159193323Sed // FIXME: could shrink frame 160193323Sed // Set up a proper stack frame 161193323Sed // FIXME Layout 162193323Sed // 8 double registers - 64 bytes 163193323Sed // 8 int registers - 32 bytes 164193323Sed "mflr 0\n" 165193323Sed "stw 0, 4(1)\n" 166193323Sed "stwu 1, -104(1)\n" 167193323Sed // Save all int arg registers 168193323Sed "stw 10, 100(1)\n" "stw 9, 96(1)\n" 169193323Sed "stw 8, 92(1)\n" "stw 7, 88(1)\n" 170193323Sed "stw 6, 84(1)\n" "stw 5, 80(1)\n" 171193323Sed "stw 4, 76(1)\n" "stw 3, 72(1)\n" 172193323Sed // Save all call-clobbered FP regs. 173193323Sed "stfd 8, 64(1)\n" 174193323Sed "stfd 7, 56(1)\n" "stfd 6, 48(1)\n" 175193323Sed "stfd 5, 40(1)\n" "stfd 4, 32(1)\n" 176193323Sed "stfd 3, 24(1)\n" "stfd 2, 16(1)\n" 177193323Sed "stfd 1, 8(1)\n" 178193323Sed // Arguments to Compilation Callback: 179193323Sed // r3 - our lr (address of the call instruction in stub plus 4) 180193323Sed // r4 - stub's lr (address of instruction that called the stub plus 4) 181193323Sed // r5 - is64Bit - always 0. 182193323Sed "mr 3, 0\n" 183193323Sed "lwz 5, 104(1)\n" // stub's frame 184193323Sed "lwz 4, 4(5)\n" // stub's lr 185193323Sed "li 5, 0\n" // 0 == 32 bit 186249423Sdim "bl LLVMPPCCompilationCallback\n" 187193323Sed "mtctr 3\n" 188193323Sed // Restore all int arg registers 189193323Sed "lwz 10, 100(1)\n" "lwz 9, 96(1)\n" 190193323Sed "lwz 8, 92(1)\n" "lwz 7, 88(1)\n" 191193323Sed "lwz 6, 84(1)\n" "lwz 5, 80(1)\n" 192193323Sed "lwz 4, 76(1)\n" "lwz 3, 72(1)\n" 193193323Sed // Restore all FP arg registers 194193323Sed "lfd 8, 64(1)\n" 195193323Sed "lfd 7, 56(1)\n" "lfd 6, 48(1)\n" 196193323Sed "lfd 5, 40(1)\n" "lfd 4, 32(1)\n" 197193323Sed "lfd 3, 24(1)\n" "lfd 2, 16(1)\n" 198193323Sed "lfd 1, 8(1)\n" 199193323Sed // Pop 3 frames off the stack and branch to target 200193323Sed "lwz 1, 104(1)\n" 201193323Sed "lwz 0, 4(1)\n" 202193323Sed "mtlr 0\n" 203193323Sed "bctr\n" 204193323Sed ); 205193323Sed#endif 206193323Sed 207263508Sdim#if !defined(__powerpc64__) && !defined(__ppc64__) 208263508Sdimvoid PPC64CompilationCallback() { 209263508Sdim llvm_unreachable("This is not a 64bit PowerPC, you can't execute this!"); 210263508Sdim} 211263508Sdim#else 212263508Sdim# ifdef __ELF__ 213193323Sedasm( 214193323Sed ".text\n" 215193323Sed ".align 2\n" 216224145Sdim ".globl PPC64CompilationCallback\n" 217239462Sdim ".section \".opd\",\"aw\",@progbits\n" 218224145Sdim ".align 3\n" 219224145Sdim"PPC64CompilationCallback:\n" 220224145Sdim ".quad .L.PPC64CompilationCallback,.TOC.@tocbase,0\n" 221224145Sdim ".size PPC64CompilationCallback,24\n" 222224145Sdim ".previous\n" 223224145Sdim ".align 4\n" 224224145Sdim ".type PPC64CompilationCallback,@function\n" 225224145Sdim".L.PPC64CompilationCallback:\n" 226263508Sdim# else 227224145Sdimasm( 228224145Sdim ".text\n" 229224145Sdim ".align 2\n" 230193323Sed ".globl _PPC64CompilationCallback\n" 231193323Sed"_PPC64CompilationCallback:\n" 232263508Sdim# endif 233193323Sed // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 234193323Sed // FIXME: need to save v[0-19] for altivec? 235193323Sed // Set up a proper stack frame 236193323Sed // Layout 237193323Sed // PowerPC64 ABI linkage - 48 bytes 238193323Sed // parameters - 64 bytes 239193323Sed // 13 double registers - 104 bytes 240193323Sed // 8 int registers - 64 bytes 241224145Sdim "mflr 0\n" 242224145Sdim "std 0, 16(1)\n" 243224145Sdim "stdu 1, -280(1)\n" 244193323Sed // Save all int arg registers 245224145Sdim "std 10, 272(1)\n" "std 9, 264(1)\n" 246224145Sdim "std 8, 256(1)\n" "std 7, 248(1)\n" 247224145Sdim "std 6, 240(1)\n" "std 5, 232(1)\n" 248224145Sdim "std 4, 224(1)\n" "std 3, 216(1)\n" 249193323Sed // Save all call-clobbered FP regs. 250224145Sdim "stfd 13, 208(1)\n" "stfd 12, 200(1)\n" 251224145Sdim "stfd 11, 192(1)\n" "stfd 10, 184(1)\n" 252224145Sdim "stfd 9, 176(1)\n" "stfd 8, 168(1)\n" 253224145Sdim "stfd 7, 160(1)\n" "stfd 6, 152(1)\n" 254224145Sdim "stfd 5, 144(1)\n" "stfd 4, 136(1)\n" 255224145Sdim "stfd 3, 128(1)\n" "stfd 2, 120(1)\n" 256224145Sdim "stfd 1, 112(1)\n" 257193323Sed // Arguments to Compilation Callback: 258193323Sed // r3 - our lr (address of the call instruction in stub plus 4) 259193323Sed // r4 - stub's lr (address of instruction that called the stub plus 4) 260193323Sed // r5 - is64Bit - always 1. 261224145Sdim "mr 3, 0\n" // return address (still in r0) 262224145Sdim "ld 5, 280(1)\n" // stub's frame 263224145Sdim "ld 4, 16(5)\n" // stub's lr 264224145Sdim "li 5, 1\n" // 1 == 64 bit 265263508Sdim# ifdef __ELF__ 266249423Sdim "bl LLVMPPCCompilationCallback\n" 267224145Sdim "nop\n" 268263508Sdim# else 269249423Sdim "bl _LLVMPPCCompilationCallback\n" 270263508Sdim# endif 271224145Sdim "mtctr 3\n" 272193323Sed // Restore all int arg registers 273224145Sdim "ld 10, 272(1)\n" "ld 9, 264(1)\n" 274224145Sdim "ld 8, 256(1)\n" "ld 7, 248(1)\n" 275224145Sdim "ld 6, 240(1)\n" "ld 5, 232(1)\n" 276224145Sdim "ld 4, 224(1)\n" "ld 3, 216(1)\n" 277193323Sed // Restore all FP arg registers 278224145Sdim "lfd 13, 208(1)\n" "lfd 12, 200(1)\n" 279224145Sdim "lfd 11, 192(1)\n" "lfd 10, 184(1)\n" 280224145Sdim "lfd 9, 176(1)\n" "lfd 8, 168(1)\n" 281224145Sdim "lfd 7, 160(1)\n" "lfd 6, 152(1)\n" 282224145Sdim "lfd 5, 144(1)\n" "lfd 4, 136(1)\n" 283224145Sdim "lfd 3, 128(1)\n" "lfd 2, 120(1)\n" 284224145Sdim "lfd 1, 112(1)\n" 285193323Sed // Pop 3 frames off the stack and branch to target 286224145Sdim "ld 1, 280(1)\n" 287224145Sdim "ld 0, 16(1)\n" 288224145Sdim "mtlr 0\n" 289224145Sdim // XXX: any special TOC handling in the ELF case for JIT? 290193323Sed "bctr\n" 291193323Sed ); 292193323Sed#endif 293193323Sed 294234353Sdimextern "C" { 295249423SdimLLVM_LIBRARY_VISIBILITY void * 296249423SdimLLVMPPCCompilationCallback(unsigned *StubCallAddrPlus4, 297249423Sdim unsigned *OrigCallAddrPlus4, 298249423Sdim bool is64Bit) { 299193323Sed // Adjust the pointer to the address of the call instruction in the stub 300193323Sed // emitted by emitFunctionStub, rather than the instruction after it. 301193323Sed unsigned *StubCallAddr = StubCallAddrPlus4 - 1; 302193323Sed unsigned *OrigCallAddr = OrigCallAddrPlus4 - 1; 303193323Sed 304193323Sed void *Target = JITCompilerFunction(StubCallAddr); 305193323Sed 306193323Sed // Check to see if *OrigCallAddr is a 'bl' instruction, and if we can rewrite 307193323Sed // it to branch directly to the destination. If so, rewrite it so it does not 308193323Sed // need to go through the stub anymore. 309193323Sed unsigned OrigCallInst = *OrigCallAddr; 310193323Sed if ((OrigCallInst >> 26) == 18) { // Direct call. 311193323Sed intptr_t Offset = ((intptr_t)Target - (intptr_t)OrigCallAddr) >> 2; 312193323Sed 313193323Sed if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 314193323Sed // Clear the original target out. 315193323Sed OrigCallInst &= (63 << 26) | 3; 316193323Sed // Fill in the new target. 317193323Sed OrigCallInst |= (Offset & ((1 << 24)-1)) << 2; 318193323Sed // Replace the call. 319193323Sed *OrigCallAddr = OrigCallInst; 320193323Sed } 321193323Sed } 322193323Sed 323193323Sed // Assert that we are coming from a stub that was created with our 324193323Sed // emitFunctionStub. 325193323Sed if ((*StubCallAddr >> 26) == 18) 326193323Sed StubCallAddr -= 3; 327193323Sed else { 328193323Sed assert((*StubCallAddr >> 26) == 19 && "Call in stub is not indirect!"); 329193323Sed StubCallAddr -= is64Bit ? 9 : 6; 330193323Sed } 331193323Sed 332193323Sed // Rewrite the stub with an unconditional branch to the target, for any users 333193323Sed // who took the address of the stub. 334193323Sed EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit); 335202375Srdivacky sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4); 336193323Sed 337193323Sed // Put the address of the target function to call and the address to return to 338193323Sed // after calling the target function in a place that is easy to get on the 339193323Sed // stack after we restore all regs. 340193323Sed return Target; 341193323Sed} 342234353Sdim} 343193323Sed 344193323Sed 345193323Sed 346193323SedTargetJITInfo::LazyResolverFn 347193323SedPPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) { 348193323Sed JITCompilerFunction = Fn; 349193323Sed return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback; 350193323Sed} 351193323Sed 352199989SrdivackyTargetJITInfo::StubLayout PPCJITInfo::getStubLayout() { 353199989Srdivacky // The stub contains up to 10 4-byte instructions, aligned at 4 bytes: 3 354199989Srdivacky // instructions to save the caller's address if this is a lazy-compilation 355199989Srdivacky // stub, plus a 1-, 4-, or 7-instruction sequence to load an arbitrary address 356199989Srdivacky // into a register and jump through it. 357199989Srdivacky StubLayout Result = {10*4, 4}; 358199989Srdivacky return Result; 359199989Srdivacky} 360199989Srdivacky 361193323Sed#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 362193323Seddefined(__APPLE__) 363193323Sedextern "C" void sys_icache_invalidate(const void *Addr, size_t len); 364193323Sed#endif 365193323Sed 366193323Sedvoid *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn, 367193323Sed JITCodeEmitter &JCE) { 368193323Sed // If this is just a call to an external function, emit a branch instead of a 369193323Sed // call. The code is the same except for one bit of the last instruction. 370193323Sed if (Fn != (void*)(intptr_t)PPC32CompilationCallback && 371193323Sed Fn != (void*)(intptr_t)PPC64CompilationCallback) { 372199989Srdivacky void *Addr = (void*)JCE.getCurrentPCValue(); 373193323Sed JCE.emitWordBE(0); 374193323Sed JCE.emitWordBE(0); 375193323Sed JCE.emitWordBE(0); 376193323Sed JCE.emitWordBE(0); 377193323Sed JCE.emitWordBE(0); 378193323Sed JCE.emitWordBE(0); 379193323Sed JCE.emitWordBE(0); 380199989Srdivacky EmitBranchToAt((intptr_t)Addr, (intptr_t)Fn, false, is64Bit); 381199989Srdivacky sys::Memory::InvalidateInstructionCache(Addr, 7*4); 382199989Srdivacky return Addr; 383193323Sed } 384193323Sed 385199989Srdivacky void *Addr = (void*)JCE.getCurrentPCValue(); 386193323Sed if (is64Bit) { 387193323Sed JCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1) 388193323Sed JCE.emitWordBE(0x7d6802a6); // mflr r11 389193323Sed JCE.emitWordBE(0xf9610060); // std r11, 96(r1) 390195340Sed } else if (TM.getSubtargetImpl()->isDarwinABI()){ 391193323Sed JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 392193323Sed JCE.emitWordBE(0x7d6802a6); // mflr r11 393193323Sed JCE.emitWordBE(0x91610028); // stw r11, 40(r1) 394193323Sed } else { 395193323Sed JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 396193323Sed JCE.emitWordBE(0x7d6802a6); // mflr r11 397193323Sed JCE.emitWordBE(0x91610024); // stw r11, 36(r1) 398193323Sed } 399193323Sed intptr_t BranchAddr = (intptr_t)JCE.getCurrentPCValue(); 400193323Sed JCE.emitWordBE(0); 401193323Sed JCE.emitWordBE(0); 402193323Sed JCE.emitWordBE(0); 403193323Sed JCE.emitWordBE(0); 404193323Sed JCE.emitWordBE(0); 405193323Sed JCE.emitWordBE(0); 406193323Sed JCE.emitWordBE(0); 407193323Sed EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit); 408199989Srdivacky sys::Memory::InvalidateInstructionCache(Addr, 10*4); 409199989Srdivacky return Addr; 410193323Sed} 411193323Sed 412193323Sed 413193323Sedvoid PPCJITInfo::relocate(void *Function, MachineRelocation *MR, 414193323Sed unsigned NumRelocs, unsigned char* GOTBase) { 415193323Sed for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { 416193323Sed unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; 417193323Sed intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); 418193323Sed switch ((PPC::RelocationType)MR->getRelocationType()) { 419198090Srdivacky default: llvm_unreachable("Unknown relocation type!"); 420193323Sed case PPC::reloc_pcrel_bx: 421193323Sed // PC-relative relocation for b and bl instructions. 422193323Sed ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 423193323Sed assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) && 424193323Sed "Relocation out of range!"); 425193323Sed *RelocPos |= (ResultPtr & ((1 << 24)-1)) << 2; 426193323Sed break; 427193323Sed case PPC::reloc_pcrel_bcx: 428193323Sed // PC-relative relocation for BLT,BLE,BEQ,BGE,BGT,BNE, or other 429193323Sed // bcx instructions. 430193323Sed ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 431193323Sed assert(ResultPtr >= -(1 << 13) && ResultPtr < (1 << 13) && 432193323Sed "Relocation out of range!"); 433193323Sed *RelocPos |= (ResultPtr & ((1 << 14)-1)) << 2; 434193323Sed break; 435193323Sed case PPC::reloc_absolute_high: // high bits of ref -> low 16 of instr 436193323Sed case PPC::reloc_absolute_low: { // low bits of ref -> low 16 of instr 437193323Sed ResultPtr += MR->getConstantVal(); 438193323Sed 439193323Sed // If this is a high-part access, get the high-part. 440193323Sed if (MR->getRelocationType() == PPC::reloc_absolute_high) { 441193323Sed // If the low part will have a carry (really a borrow) from the low 442193323Sed // 16-bits into the high 16, add a bit to borrow from. 443193323Sed if (((int)ResultPtr << 16) < 0) 444193323Sed ResultPtr += 1 << 16; 445193323Sed ResultPtr >>= 16; 446193323Sed } 447193323Sed 448193323Sed // Do the addition then mask, so the addition does not overflow the 16-bit 449193323Sed // immediate section of the instruction. 450193323Sed unsigned LowBits = (*RelocPos + ResultPtr) & 65535; 451193323Sed unsigned HighBits = *RelocPos & ~65535; 452193323Sed *RelocPos = LowBits | HighBits; // Slam into low 16-bits 453193323Sed break; 454193323Sed } 455193323Sed case PPC::reloc_absolute_low_ix: { // low bits of ref -> low 14 of instr 456193323Sed ResultPtr += MR->getConstantVal(); 457193323Sed // Do the addition then mask, so the addition does not overflow the 16-bit 458193323Sed // immediate section of the instruction. 459193323Sed unsigned LowBits = (*RelocPos + ResultPtr) & 0xFFFC; 460193323Sed unsigned HighBits = *RelocPos & 0xFFFF0003; 461193323Sed *RelocPos = LowBits | HighBits; // Slam into low 14-bits. 462193323Sed break; 463193323Sed } 464193323Sed } 465193323Sed } 466193323Sed} 467193323Sed 468193323Sedvoid PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { 469193323Sed EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit); 470202375Srdivacky sys::Memory::InvalidateInstructionCache(Old, 7*4); 471193323Sed} 472