PPCJITInfo.cpp revision 2a9ddfb903ae3baede7282348afae1f750905248
121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman//===-- PPCJITInfo.cpp - Implement the JIT interfaces for the PowerPC -----===// 2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman// 39b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// The LLVM Compiler Infrastructure 49b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman// 89b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner//===----------------------------------------------------------------------===// 99b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// 109b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// This file implements the JIT interfaces for the 32-bit PowerPC target. 119b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// 129b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner//===----------------------------------------------------------------------===// 139b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 149b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define DEBUG_TYPE "jit" 15b9459b731a0b6345d1e14083fcfa6508646ba81dChris Lattner#include "PPCJITInfo.h" 1616e71f2f70811c69c56052dd146324fe20e31db5Chris Lattner#include "PPCRelocations.h" 172fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray#include "PPCTargetMachine.h" 1851cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray#include "llvm/Function.h" 19bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner#include "llvm/System/Memory.h" 2055fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng#include "llvm/Support/Debug.h" 219b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattnerusing namespace llvm; 229b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 239b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattnerstatic TargetJITInfo::JITCompilerFn JITCompilerFunction; 249b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 259b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_ADDIS(RD,RS,IMM16) \ 269b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((15 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535)) 279b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_ORI(RD,RS,UIMM16) \ 289b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((24 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 2906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_ORIS(RD,RS,UIMM16) \ 3006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ((25 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 3106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_RLDICR(RD,RS,SH,ME) \ 3206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ((30 << 26) | ((RS) << 21) | ((RD) << 16) | (((SH) & 31) << 11) | \ 33eb63b0a9d5089dd3119ba9c3cad9cf9ad79df0f7Chris Lattner (((ME) & 63) << 6) | (1 << 2) | ((((SH) >> 5) & 1) << 1)) 349b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_MTSPR(RS,SPR) \ 359b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((31 << 26) | ((RS) << 21) | ((SPR) << 16) | (467 << 1)) 369b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_BCCTRx(BO,BI,LINK) \ 379b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((19 << 26) | ((BO) << 21) | ((BI) << 16) | (528 << 1) | ((LINK) & 1)) 3806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_B(TARGET, LINK) \ 3906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ((18 << 26) | (((TARGET) & 0x00FFFFFF) << 2) | ((LINK) & 1)) 409b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 419b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// Pseudo-ops 429b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_LIS(RD,IMM16) BUILD_ADDIS(RD,0,IMM16) 4306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_SLDI(RD,RS,IMM6) BUILD_RLDICR(RD,RS,IMM6,63-IMM6) 449b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9) 459b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK) 469b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanstatic void EmitBranchToAt(uint64_t At, uint64_t To, bool isCall, bool is64Bit){ 4806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman intptr_t Offset = ((intptr_t)To - (intptr_t)At) >> 2; 4906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman unsigned *AtI = (unsigned*)(intptr_t)At; 509b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 5106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 5206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[0] = BUILD_B(Offset, isCall); // b/bl target 5306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } else if (!is64Bit) { 5406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[0] = BUILD_LIS(12, To >> 16); // lis r12, hi16(address) 5506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[1] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 5606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[2] = BUILD_MTCTR(12); // mtctr r12 5706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl 5806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } else { 5906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[0] = BUILD_LIS(12, To >> 48); // lis r12, hi16(address) 6006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[1] = BUILD_ORI(12, 12, To >> 32); // ori r12, r12, lo16(address) 6106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[2] = BUILD_SLDI(12, 12, 32); // sldi r12, r12, 32 6206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[3] = BUILD_ORIS(12, 12, To >> 16); // oris r12, r12, hi16(address) 6306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[4] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 6406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[5] = BUILD_MTCTR(12); // mtctr r12 6506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[6] = BUILD_BCTR(isCall); // bctr/bctrl 6606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 679b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 689b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 6973278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattnerextern "C" void PPC32CompilationCallback(); 7006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanextern "C" void PPC64CompilationCallback(); 7173278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner 727be164c0eaa6c1ab2e69262036e54870176c10a4Chris Lattner#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 73e7a83dfac62eb01a1dcc71b98363d3bf3a893a6cChris Lattner !(defined(__ppc64__) || defined(__FreeBSD__)) 7473278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in 7573278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 7673278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// write our own wrapper, which does things our way, so we have complete control 7773278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// over register saving and restoring. 7873278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattnerasm( 7973278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".text\n" 8073278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".align 2\n" 8173278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".globl _PPC32CompilationCallback\n" 8273278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner"_PPC32CompilationCallback:\n" 835425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 845425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // FIXME: need to save v[0-19] for altivec? 8506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // FIXME: could shrink frame 865425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Set up a proper stack frame 8718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // FIXME Layout 8818e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // PowerPC64 ABI linkage - 24 bytes 8918e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // parameters - 32 bytes 9018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 13 double registers - 104 bytes 9118e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 8 int registers - 32 bytes 920eadd73bd78b00379e9f78d1a372bcd28efe855cJim Laskey "mflr r0\n" 9318e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stw r0, 8(r1)\n" 9418e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stwu r1, -208(r1)\n" 955425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Save all int arg registers 965425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r10, 204(r1)\n" "stw r9, 200(r1)\n" 975425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r8, 196(r1)\n" "stw r7, 192(r1)\n" 985425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r6, 188(r1)\n" "stw r5, 184(r1)\n" 995425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r4, 180(r1)\n" "stw r3, 176(r1)\n" 10073278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner // Save all call-clobbered FP regs. 1015425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f13, 168(r1)\n" "stfd f12, 160(r1)\n" 1025425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f11, 152(r1)\n" "stfd f10, 144(r1)\n" 1035425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f9, 136(r1)\n" "stfd f8, 128(r1)\n" 1045425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f7, 120(r1)\n" "stfd f6, 112(r1)\n" 1055425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f5, 104(r1)\n" "stfd f4, 96(r1)\n" 1065425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f3, 88(r1)\n" "stfd f2, 80(r1)\n" 1075425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f1, 72(r1)\n" 1085425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Arguments to Compilation Callback: 1095425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // r3 - our lr (address of the call instruction in stub plus 4) 1105425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // r4 - stub's lr (address of instruction that called the stub plus 4) 111e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner // r5 - is64Bit - always 0. 1125425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mr r3, r0\n" 1135425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r2, 208(r1)\n" // stub's frame 1145425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r4, 8(r2)\n" // stub's lr 11506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "li r5, 0\n" // 0 == 32 bit 11606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "bl _PPCCompilationCallbackC\n" 1175425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mtctr r3\n" 1185425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Restore all int arg registers 1195425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r10, 204(r1)\n" "lwz r9, 200(r1)\n" 1205425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r8, 196(r1)\n" "lwz r7, 192(r1)\n" 1215425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r6, 188(r1)\n" "lwz r5, 184(r1)\n" 1225425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r4, 180(r1)\n" "lwz r3, 176(r1)\n" 1235425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Restore all FP arg registers 1245425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f13, 168(r1)\n" "lfd f12, 160(r1)\n" 1255425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f11, 152(r1)\n" "lfd f10, 144(r1)\n" 1265425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f9, 136(r1)\n" "lfd f8, 128(r1)\n" 1275425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f7, 120(r1)\n" "lfd f6, 112(r1)\n" 1285425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f5, 104(r1)\n" "lfd f4, 96(r1)\n" 1295425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f3, 88(r1)\n" "lfd f2, 80(r1)\n" 1305425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f1, 72(r1)\n" 1315425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Pop 3 frames off the stack and branch to target 1325425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r1, 208(r1)\n" 1335425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r2, 8(r1)\n" 1345425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mtlr r2\n" 1355425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "bctr\n" 13673278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ); 137456bc87e78af18331b9579069a059c723da517d9Chris Lattner 138456bc87e78af18331b9579069a059c723da517d9Chris Lattner#elif defined(__PPC__) && !defined(__ppc64__) 139e7a83dfac62eb01a1dcc71b98363d3bf3a893a6cChris Lattner// Linux & FreeBSD / PPC 32 support 140456bc87e78af18331b9579069a059c723da517d9Chris Lattner 141456bc87e78af18331b9579069a059c723da517d9Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in 142456bc87e78af18331b9579069a059c723da517d9Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 143456bc87e78af18331b9579069a059c723da517d9Chris Lattner// write our own wrapper, which does things our way, so we have complete control 144456bc87e78af18331b9579069a059c723da517d9Chris Lattner// over register saving and restoring. 145456bc87e78af18331b9579069a059c723da517d9Chris Lattnerasm( 146456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".text\n" 147456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".align 2\n" 148456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".globl PPC32CompilationCallback\n" 149456bc87e78af18331b9579069a059c723da517d9Chris Lattner"PPC32CompilationCallback:\n" 1502fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray // Make space for 8 ints r[3-10] and 8 doubles f[1-8] and the 151456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME: need to save v[0-19] for altivec? 152456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME: could shrink frame 153456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Set up a proper stack frame 154456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME Layout 1552fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray // 8 double registers - 64 bytes 156456bc87e78af18331b9579069a059c723da517d9Chris Lattner // 8 int registers - 32 bytes 157456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mflr 0\n" 158456bc87e78af18331b9579069a059c723da517d9Chris Lattner "stw 0, 4(1)\n" 1592fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stwu 1, -104(1)\n" 160456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Save all int arg registers 1612fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 10, 100(1)\n" "stw 9, 96(1)\n" 1622fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 8, 92(1)\n" "stw 7, 88(1)\n" 1632fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 6, 84(1)\n" "stw 5, 80(1)\n" 1642fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 4, 76(1)\n" "stw 3, 72(1)\n" 165456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Save all call-clobbered FP regs. 1662fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 8, 64(1)\n" 1672fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 7, 56(1)\n" "stfd 6, 48(1)\n" 1682fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 5, 40(1)\n" "stfd 4, 32(1)\n" 1692fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 3, 24(1)\n" "stfd 2, 16(1)\n" 1702fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 1, 8(1)\n" 171456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Arguments to Compilation Callback: 172456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r3 - our lr (address of the call instruction in stub plus 4) 173456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r4 - stub's lr (address of instruction that called the stub plus 4) 174456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r5 - is64Bit - always 0. 175456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mr 3, 0\n" 1762fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 5, 104(1)\n" // stub's frame 1772fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 4, 4(5)\n" // stub's lr 178456bc87e78af18331b9579069a059c723da517d9Chris Lattner "li 5, 0\n" // 0 == 32 bit 179456bc87e78af18331b9579069a059c723da517d9Chris Lattner "bl PPCCompilationCallbackC\n" 180456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mtctr 3\n" 181456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Restore all int arg registers 1822fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 10, 100(1)\n" "lwz 9, 96(1)\n" 1832fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 8, 92(1)\n" "lwz 7, 88(1)\n" 1842fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 6, 84(1)\n" "lwz 5, 80(1)\n" 1852fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 4, 76(1)\n" "lwz 3, 72(1)\n" 186456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Restore all FP arg registers 1872fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 8, 64(1)\n" 1882fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 7, 56(1)\n" "lfd 6, 48(1)\n" 1892fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 5, 40(1)\n" "lfd 4, 32(1)\n" 1902fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 3, 24(1)\n" "lfd 2, 16(1)\n" 1912fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 1, 8(1)\n" 192456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Pop 3 frames off the stack and branch to target 1932fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 1, 104(1)\n" 1942fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 0, 4(1)\n" 1952fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "mtlr 0\n" 196456bc87e78af18331b9579069a059c723da517d9Chris Lattner "bctr\n" 197456bc87e78af18331b9579069a059c723da517d9Chris Lattner ); 198fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattner#else 199fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattnervoid PPC32CompilationCallback() { 200fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattner assert(0 && "This is not a power pc, you can't execute this!"); 201fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattner abort(); 202fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattner} 203ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman#endif 204ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman 2057be164c0eaa6c1ab2e69262036e54870176c10a4Chris Lattner#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 2067be164c0eaa6c1ab2e69262036e54870176c10a4Chris Lattner defined(__ppc64__) 20706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanasm( 20806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".text\n" 20906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".align 2\n" 21006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".globl _PPC64CompilationCallback\n" 21106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman"_PPC64CompilationCallback:\n" 21206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 21306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // FIXME: need to save v[0-19] for altivec? 21406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Set up a proper stack frame 21518e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // Layout 21618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // PowerPC64 ABI linkage - 48 bytes 21718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // parameters - 64 bytes 21818e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 13 double registers - 104 bytes 21918e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 8 int registers - 64 bytes 22006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "mflr r0\n" 22118e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "std r0, 16(r1)\n" 22218e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stdu r1, -280(r1)\n" 22306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Save all int arg registers 22418e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "std r10, 272(r1)\n" "std r9, 264(r1)\n" 22518e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "std r8, 256(r1)\n" "std r7, 248(r1)\n" 22618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "std r6, 240(r1)\n" "std r5, 232(r1)\n" 22718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "std r4, 224(r1)\n" "std r3, 216(r1)\n" 22806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Save all call-clobbered FP regs. 22918e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stfd f13, 208(r1)\n" "stfd f12, 200(r1)\n" 23018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stfd f11, 192(r1)\n" "stfd f10, 184(r1)\n" 23118e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stfd f9, 176(r1)\n" "stfd f8, 168(r1)\n" 23218e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stfd f7, 160(r1)\n" "stfd f6, 152(r1)\n" 23318e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stfd f5, 144(r1)\n" "stfd f4, 136(r1)\n" 23418e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stfd f3, 128(r1)\n" "stfd f2, 120(r1)\n" 23518e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stfd f1, 112(r1)\n" 23606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Arguments to Compilation Callback: 23706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // r3 - our lr (address of the call instruction in stub plus 4) 23806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // r4 - stub's lr (address of instruction that called the stub plus 4) 239e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner // r5 - is64Bit - always 1. 24006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "mr r3, r0\n" 24118e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "ld r2, 280(r1)\n" // stub's frame 24206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "ld r4, 16(r2)\n" // stub's lr 24306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "li r5, 1\n" // 1 == 64 bit 24406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "bl _PPCCompilationCallbackC\n" 24506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "mtctr r3\n" 24606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Restore all int arg registers 24718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "ld r10, 272(r1)\n" "ld r9, 264(r1)\n" 24818e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "ld r8, 256(r1)\n" "ld r7, 248(r1)\n" 24918e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "ld r6, 240(r1)\n" "ld r5, 232(r1)\n" 25018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "ld r4, 224(r1)\n" "ld r3, 216(r1)\n" 25106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Restore all FP arg registers 25218e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "lfd f13, 208(r1)\n" "lfd f12, 200(r1)\n" 25318e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "lfd f11, 192(r1)\n" "lfd f10, 184(r1)\n" 25418e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "lfd f9, 176(r1)\n" "lfd f8, 168(r1)\n" 25518e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "lfd f7, 160(r1)\n" "lfd f6, 152(r1)\n" 25618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "lfd f5, 144(r1)\n" "lfd f4, 136(r1)\n" 25718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "lfd f3, 128(r1)\n" "lfd f2, 120(r1)\n" 25818e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "lfd f1, 112(r1)\n" 25906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Pop 3 frames off the stack and branch to target 26018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "ld r1, 280(r1)\n" 26106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "ld r2, 16(r1)\n" 26206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "mtlr r2\n" 26306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "bctr\n" 26406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ); 26506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#else 26606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanvoid PPC64CompilationCallback() { 26706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman assert(0 && "This is not a power pc, you can't execute this!"); 26806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman abort(); 26906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman} 27006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#endif 27106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman 27206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanextern "C" void *PPCCompilationCallbackC(unsigned *StubCallAddrPlus4, 27306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman unsigned *OrigCallAddrPlus4, 27406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman bool is64Bit) { 275b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Adjust the pointer to the address of the call instruction in the stub 276b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // emitted by emitFunctionStub, rather than the instruction after it. 277b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned *StubCallAddr = StubCallAddrPlus4 - 1; 278b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned *OrigCallAddr = OrigCallAddrPlus4 - 1; 279b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 280b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman void *Target = JITCompilerFunction(StubCallAddr); 281b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 282b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Check to see if *OrigCallAddr is a 'bl' instruction, and if we can rewrite 283b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // it to branch directly to the destination. If so, rewrite it so it does not 284b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // need to go through the stub anymore. 285b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned OrigCallInst = *OrigCallAddr; 286b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman if ((OrigCallInst >> 26) == 18) { // Direct call. 287b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman intptr_t Offset = ((intptr_t)Target - (intptr_t)OrigCallAddr) >> 2; 288b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 289e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 290892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Clear the original target out. 291b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman OrigCallInst &= (63 << 26) | 3; 292892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Fill in the new target. 293b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman OrigCallInst |= (Offset & ((1 << 24)-1)) << 2; 294892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Replace the call. 295b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman *OrigCallAddr = OrigCallInst; 296e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner } 297e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner } 298b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman 299b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Assert that we are coming from a stub that was created with our 300b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // emitFunctionStub. 30106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if ((*StubCallAddr >> 26) == 18) 30206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman StubCallAddr -= 3; 30306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman else { 304b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman assert((*StubCallAddr >> 26) == 19 && "Call in stub is not indirect!"); 30506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman StubCallAddr -= is64Bit ? 9 : 6; 30606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 307e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 308e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner // Rewrite the stub with an unconditional branch to the target, for any users 309e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner // who took the address of the stub. 31006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit); 311e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 312b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Put the address of the target function to call and the address to return to 313b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // after calling the target function in a place that is easy to get on the 314b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // stack after we restore all regs. 31506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman return Target; 316e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner} 317e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 318e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 319e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 320b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha BrukmanTargetJITInfo::LazyResolverFn 32121e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) { 322e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner JITCompilerFunction = Fn; 32306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback; 324e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner} 325e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 3261910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 3271910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerdefined(__APPLE__) 3281910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerextern "C" void sys_icache_invalidate(const void *Addr, size_t len); 3291910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#endif 3301910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner 33151cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffrayvoid *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn, 332a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JITCodeEmitter &JCE) { 3339b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // If this is just a call to an external function, emit a branch instead of a 3349b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // call. The code is the same except for one bit of the last instruction. 33506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (Fn != (void*)(intptr_t)PPC32CompilationCallback && 33606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman Fn != (void*)(intptr_t)PPC64CompilationCallback) { 337a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.startGVStub(F, 7*4); 338a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); 339a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 340a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 341a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 342a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 343a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 344a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 345a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 34606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman EmitBranchToAt(Addr, (intptr_t)Fn, false, is64Bit); 347bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner sys::Memory::InvalidateInstructionCache((void*)Addr, 7*4); 348a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes return JCE.finishGVStub(F); 3499b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 3509b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 351a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.startGVStub(F, 10*4); 352a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); 35306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (is64Bit) { 354a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1) 355a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 356a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0xf9610060); // std r11, 96(r1) 3572a9ddfb903ae3baede7282348afae1f750905248Tilmann Scheller } else if (TM.getSubtargetImpl()->isDarwinABI()){ 358a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 359a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 360a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x91610028); // stw r11, 40(r1) 3612fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray } else { 362a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 363a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 364a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x91610024); // stw r11, 36(r1) 36506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 366a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes intptr_t BranchAddr = (intptr_t)JCE.getCurrentPCValue(); 367a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 368a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 369a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 370a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 371a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 372a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 373a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 3741910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit); 375bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner sys::Memory::InvalidateInstructionCache((void*)Addr, 10*4); 376a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes return JCE.finishGVStub(F); 3779b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 3789b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 3799b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 38021e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::relocate(void *Function, MachineRelocation *MR, 38121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman unsigned NumRelocs, unsigned char* GOTBase) { 3829b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { 3839b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; 3849b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); 3859b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner switch ((PPC::RelocationType)MR->getRelocationType()) { 3869b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner default: assert(0 && "Unknown relocation type!"); 3879b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner case PPC::reloc_pcrel_bx: 3889b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // PC-relative relocation for b and bl instructions. 3899b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 3909b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) && 3919b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner "Relocation out of range!"); 3929b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner *RelocPos |= (ResultPtr & ((1 << 24)-1)) << 2; 3939b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner break; 394f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng case PPC::reloc_pcrel_bcx: 395f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng // PC-relative relocation for BLT,BLE,BEQ,BGE,BGT,BNE, or other 396f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng // bcx instructions. 397f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 398f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng assert(ResultPtr >= -(1 << 13) && ResultPtr < (1 << 13) && 399f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng "Relocation out of range!"); 400f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng *RelocPos |= (ResultPtr & ((1 << 14)-1)) << 2; 401f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng break; 4025efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner case PPC::reloc_absolute_high: // high bits of ref -> low 16 of instr 4033bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner case PPC::reloc_absolute_low: { // low bits of ref -> low 16 of instr 4049b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr += MR->getConstantVal(); 4059b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4065efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner // If this is a high-part access, get the high-part. 40794be248dbb2d2a44e8f4d47f161b93704d33d279Nate Begeman if (MR->getRelocationType() == PPC::reloc_absolute_high) { 4089b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // If the low part will have a carry (really a borrow) from the low 4099b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // 16-bits into the high 16, add a bit to borrow from. 4109b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner if (((int)ResultPtr << 16) < 0) 4119b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr += 1 << 16; 4129b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr >>= 16; 4139b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4149b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4159b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // Do the addition then mask, so the addition does not overflow the 16-bit 4169b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // immediate section of the instruction. 4179b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned LowBits = (*RelocPos + ResultPtr) & 65535; 4189b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned HighBits = *RelocPos & ~65535; 4199b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner *RelocPos = LowBits | HighBits; // Slam into low 16-bits 4209b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner break; 4219b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4223bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner case PPC::reloc_absolute_low_ix: { // low bits of ref -> low 14 of instr 4233bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner ResultPtr += MR->getConstantVal(); 4243bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner // Do the addition then mask, so the addition does not overflow the 16-bit 4253bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner // immediate section of the instruction. 4263bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner unsigned LowBits = (*RelocPos + ResultPtr) & 0xFFFC; 4273bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner unsigned HighBits = *RelocPos & 0xFFFF0003; 4283bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner *RelocPos = LowBits | HighBits; // Slam into low 14-bits. 4293bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner break; 4303bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner } 4313bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner } 4329b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4339b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 4349b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 43521e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { 43606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit); 4379b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 438