PPCJITInfo.cpp revision e355b80194ac5c908cecbecd6f3c137b2c9802cb
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" 193cc52ea33c0b96d1682f14fc45c45b57df0f39b6Michael J. Spencer#include "llvm/Support/Memory.h" 2055fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng#include "llvm/Support/Debug.h" 21dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h" 22dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h" 239b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattnerusing namespace llvm; 249b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 259b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattnerstatic TargetJITInfo::JITCompilerFn JITCompilerFunction; 269b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 279b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_ADDIS(RD,RS,IMM16) \ 289b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((15 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535)) 299b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_ORI(RD,RS,UIMM16) \ 309b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((24 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 3106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_ORIS(RD,RS,UIMM16) \ 3206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ((25 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 3306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_RLDICR(RD,RS,SH,ME) \ 3406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ((30 << 26) | ((RS) << 21) | ((RD) << 16) | (((SH) & 31) << 11) | \ 35eb63b0a9d5089dd3119ba9c3cad9cf9ad79df0f7Chris Lattner (((ME) & 63) << 6) | (1 << 2) | ((((SH) >> 5) & 1) << 1)) 369b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_MTSPR(RS,SPR) \ 379b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((31 << 26) | ((RS) << 21) | ((SPR) << 16) | (467 << 1)) 389b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_BCCTRx(BO,BI,LINK) \ 399b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ((19 << 26) | ((BO) << 21) | ((BI) << 16) | (528 << 1) | ((LINK) & 1)) 4006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_B(TARGET, LINK) \ 4106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ((18 << 26) | (((TARGET) & 0x00FFFFFF) << 2) | ((LINK) & 1)) 429b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 439b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// Pseudo-ops 449b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_LIS(RD,IMM16) BUILD_ADDIS(RD,0,IMM16) 4506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_SLDI(RD,RS,IMM6) BUILD_RLDICR(RD,RS,IMM6,63-IMM6) 469b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9) 479b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK) 489b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanstatic void EmitBranchToAt(uint64_t At, uint64_t To, bool isCall, bool is64Bit){ 5006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman intptr_t Offset = ((intptr_t)To - (intptr_t)At) >> 2; 5106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman unsigned *AtI = (unsigned*)(intptr_t)At; 529b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 5306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 5406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[0] = BUILD_B(Offset, isCall); // b/bl target 5506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } else if (!is64Bit) { 5606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[0] = BUILD_LIS(12, To >> 16); // lis r12, hi16(address) 5706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[1] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 5806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[2] = BUILD_MTCTR(12); // mtctr r12 5906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl 6006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } else { 6106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[0] = BUILD_LIS(12, To >> 48); // lis r12, hi16(address) 6206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[1] = BUILD_ORI(12, 12, To >> 32); // ori r12, r12, lo16(address) 6306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[2] = BUILD_SLDI(12, 12, 32); // sldi r12, r12, 32 6406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[3] = BUILD_ORIS(12, 12, To >> 16); // oris r12, r12, hi16(address) 6506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[4] = BUILD_ORI(12, 12, To); // ori r12, r12, lo16(address) 6606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[5] = BUILD_MTCTR(12); // mtctr r12 6706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman AtI[6] = BUILD_BCTR(isCall); // bctr/bctrl 6806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 699b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 709b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 7173278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattnerextern "C" void PPC32CompilationCallback(); 7206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanextern "C" void PPC64CompilationCallback(); 7373278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner 747be164c0eaa6c1ab2e69262036e54870176c10a4Chris Lattner#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 75e7a83dfac62eb01a1dcc71b98363d3bf3a893a6cChris Lattner !(defined(__ppc64__) || defined(__FreeBSD__)) 7673278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in 7773278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 7873278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// write our own wrapper, which does things our way, so we have complete control 7973278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// over register saving and restoring. 8073278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattnerasm( 8173278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".text\n" 8273278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".align 2\n" 8373278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".globl _PPC32CompilationCallback\n" 8473278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner"_PPC32CompilationCallback:\n" 855425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 865425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // FIXME: need to save v[0-19] for altivec? 8706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // FIXME: could shrink frame 885425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Set up a proper stack frame 8918e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // FIXME Layout 90e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky // PowerPC32 ABI linkage - 24 bytes 9118e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // parameters - 32 bytes 9218e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 13 double registers - 104 bytes 9318e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 8 int registers - 32 bytes 940eadd73bd78b00379e9f78d1a372bcd28efe855cJim Laskey "mflr r0\n" 9518e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stw r0, 8(r1)\n" 9618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stwu r1, -208(r1)\n" 975425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Save all int arg registers 985425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r10, 204(r1)\n" "stw r9, 200(r1)\n" 995425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r8, 196(r1)\n" "stw r7, 192(r1)\n" 1005425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r6, 188(r1)\n" "stw r5, 184(r1)\n" 1015425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r4, 180(r1)\n" "stw r3, 176(r1)\n" 10273278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner // Save all call-clobbered FP regs. 1035425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f13, 168(r1)\n" "stfd f12, 160(r1)\n" 1045425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f11, 152(r1)\n" "stfd f10, 144(r1)\n" 1055425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f9, 136(r1)\n" "stfd f8, 128(r1)\n" 1065425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f7, 120(r1)\n" "stfd f6, 112(r1)\n" 1075425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f5, 104(r1)\n" "stfd f4, 96(r1)\n" 1085425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f3, 88(r1)\n" "stfd f2, 80(r1)\n" 1095425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f1, 72(r1)\n" 1105425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Arguments to Compilation Callback: 1115425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // r3 - our lr (address of the call instruction in stub plus 4) 1125425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // r4 - stub's lr (address of instruction that called the stub plus 4) 113e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner // r5 - is64Bit - always 0. 1145425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mr r3, r0\n" 1155425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r2, 208(r1)\n" // stub's frame 1165425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r4, 8(r2)\n" // stub's lr 11706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "li r5, 0\n" // 0 == 32 bit 11806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "bl _PPCCompilationCallbackC\n" 1195425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mtctr r3\n" 1205425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Restore all int arg registers 1215425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r10, 204(r1)\n" "lwz r9, 200(r1)\n" 1225425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r8, 196(r1)\n" "lwz r7, 192(r1)\n" 1235425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r6, 188(r1)\n" "lwz r5, 184(r1)\n" 1245425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r4, 180(r1)\n" "lwz r3, 176(r1)\n" 1255425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Restore all FP arg registers 1265425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f13, 168(r1)\n" "lfd f12, 160(r1)\n" 1275425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f11, 152(r1)\n" "lfd f10, 144(r1)\n" 1285425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f9, 136(r1)\n" "lfd f8, 128(r1)\n" 1295425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f7, 120(r1)\n" "lfd f6, 112(r1)\n" 1305425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f5, 104(r1)\n" "lfd f4, 96(r1)\n" 1315425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f3, 88(r1)\n" "lfd f2, 80(r1)\n" 1325425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f1, 72(r1)\n" 1335425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Pop 3 frames off the stack and branch to target 1345425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r1, 208(r1)\n" 1355425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r2, 8(r1)\n" 1365425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mtlr r2\n" 1375425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "bctr\n" 13873278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ); 139456bc87e78af18331b9579069a059c723da517d9Chris Lattner 140456bc87e78af18331b9579069a059c723da517d9Chris Lattner#elif defined(__PPC__) && !defined(__ppc64__) 141e7a83dfac62eb01a1dcc71b98363d3bf3a893a6cChris Lattner// Linux & FreeBSD / PPC 32 support 142456bc87e78af18331b9579069a059c723da517d9Chris Lattner 143456bc87e78af18331b9579069a059c723da517d9Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in 144456bc87e78af18331b9579069a059c723da517d9Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 145456bc87e78af18331b9579069a059c723da517d9Chris Lattner// write our own wrapper, which does things our way, so we have complete control 146456bc87e78af18331b9579069a059c723da517d9Chris Lattner// over register saving and restoring. 147456bc87e78af18331b9579069a059c723da517d9Chris Lattnerasm( 148456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".text\n" 149456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".align 2\n" 150456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".globl PPC32CompilationCallback\n" 151456bc87e78af18331b9579069a059c723da517d9Chris Lattner"PPC32CompilationCallback:\n" 1522fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray // Make space for 8 ints r[3-10] and 8 doubles f[1-8] and the 153456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME: need to save v[0-19] for altivec? 154456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME: could shrink frame 155456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Set up a proper stack frame 156456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME Layout 1572fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray // 8 double registers - 64 bytes 158456bc87e78af18331b9579069a059c723da517d9Chris Lattner // 8 int registers - 32 bytes 159456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mflr 0\n" 160456bc87e78af18331b9579069a059c723da517d9Chris Lattner "stw 0, 4(1)\n" 1612fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stwu 1, -104(1)\n" 162456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Save all int arg registers 1632fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 10, 100(1)\n" "stw 9, 96(1)\n" 1642fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 8, 92(1)\n" "stw 7, 88(1)\n" 1652fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 6, 84(1)\n" "stw 5, 80(1)\n" 1662fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 4, 76(1)\n" "stw 3, 72(1)\n" 167456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Save all call-clobbered FP regs. 1682fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 8, 64(1)\n" 1692fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 7, 56(1)\n" "stfd 6, 48(1)\n" 1702fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 5, 40(1)\n" "stfd 4, 32(1)\n" 1712fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 3, 24(1)\n" "stfd 2, 16(1)\n" 1722fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 1, 8(1)\n" 173456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Arguments to Compilation Callback: 174456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r3 - our lr (address of the call instruction in stub plus 4) 175456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r4 - stub's lr (address of instruction that called the stub plus 4) 176456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r5 - is64Bit - always 0. 177456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mr 3, 0\n" 1782fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 5, 104(1)\n" // stub's frame 1792fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 4, 4(5)\n" // stub's lr 180456bc87e78af18331b9579069a059c723da517d9Chris Lattner "li 5, 0\n" // 0 == 32 bit 181456bc87e78af18331b9579069a059c723da517d9Chris Lattner "bl PPCCompilationCallbackC\n" 182456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mtctr 3\n" 183456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Restore all int arg registers 1842fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 10, 100(1)\n" "lwz 9, 96(1)\n" 1852fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 8, 92(1)\n" "lwz 7, 88(1)\n" 1862fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 6, 84(1)\n" "lwz 5, 80(1)\n" 1872fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 4, 76(1)\n" "lwz 3, 72(1)\n" 188456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Restore all FP arg registers 1892fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 8, 64(1)\n" 1902fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 7, 56(1)\n" "lfd 6, 48(1)\n" 1912fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 5, 40(1)\n" "lfd 4, 32(1)\n" 1922fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 3, 24(1)\n" "lfd 2, 16(1)\n" 1932fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 1, 8(1)\n" 194456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Pop 3 frames off the stack and branch to target 1952fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 1, 104(1)\n" 1962fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 0, 4(1)\n" 1972fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "mtlr 0\n" 198456bc87e78af18331b9579069a059c723da517d9Chris Lattner "bctr\n" 199456bc87e78af18331b9579069a059c723da517d9Chris Lattner ); 200fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattner#else 201fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattnervoid PPC32CompilationCallback() { 202c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("This is not a power pc, you can't execute this!"); 203fde839b4ff3c2c3f3658d45b2f7e9806f1d14032Chris Lattner} 204ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman#endif 205ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman 2067be164c0eaa6c1ab2e69262036e54870176c10a4Chris Lattner#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 2077be164c0eaa6c1ab2e69262036e54870176c10a4Chris Lattner defined(__ppc64__) 208e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky#ifdef __ELF__ 209e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divackyasm( 210e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".text\n" 211e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".align 2\n" 212e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".globl PPC64CompilationCallback\n" 213e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".section \".opd\",\"aw\"\n" 214e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".align 3\n" 215e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky"PPC64CompilationCallback:\n" 216e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".quad .L.PPC64CompilationCallback,.TOC.@tocbase,0\n" 217e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".size PPC64CompilationCallback,24\n" 218e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".previous\n" 219e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".align 4\n" 220e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".type PPC64CompilationCallback,@function\n" 221e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky".L.PPC64CompilationCallback:\n" 222e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky#else 22306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanasm( 22406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".text\n" 22506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".align 2\n" 22606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".globl _PPC64CompilationCallback\n" 22706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman"_PPC64CompilationCallback:\n" 228e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky#endif 22906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 23006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // FIXME: need to save v[0-19] for altivec? 23106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Set up a proper stack frame 23218e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // Layout 23318e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // PowerPC64 ABI linkage - 48 bytes 23418e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // parameters - 64 bytes 23518e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 13 double registers - 104 bytes 23618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 8 int registers - 64 bytes 237e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mflr 0\n" 238e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 0, 16(1)\n" 239e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stdu 1, -280(1)\n" 24006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Save all int arg registers 241e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 10, 272(1)\n" "std 9, 264(1)\n" 242e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 8, 256(1)\n" "std 7, 248(1)\n" 243e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 6, 240(1)\n" "std 5, 232(1)\n" 244e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 4, 224(1)\n" "std 3, 216(1)\n" 24506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Save all call-clobbered FP regs. 246e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 13, 208(1)\n" "stfd 12, 200(1)\n" 247e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 11, 192(1)\n" "stfd 10, 184(1)\n" 248e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 9, 176(1)\n" "stfd 8, 168(1)\n" 249e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 7, 160(1)\n" "stfd 6, 152(1)\n" 250e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 5, 144(1)\n" "stfd 4, 136(1)\n" 251e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 3, 128(1)\n" "stfd 2, 120(1)\n" 252e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 1, 112(1)\n" 25306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Arguments to Compilation Callback: 25406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // r3 - our lr (address of the call instruction in stub plus 4) 25506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // r4 - stub's lr (address of instruction that called the stub plus 4) 256e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner // r5 - is64Bit - always 1. 257e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mr 3, 0\n" // return address (still in r0) 258e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 5, 280(1)\n" // stub's frame 259e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 4, 16(5)\n" // stub's lr 260e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "li 5, 1\n" // 1 == 64 bit 261e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky#ifdef __ELF__ 262e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "bl PPCCompilationCallbackC\n" 263e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "nop\n" 264e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky#else 26506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "bl _PPCCompilationCallbackC\n" 266e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky#endif 267e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mtctr 3\n" 26806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Restore all int arg registers 269e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 10, 272(1)\n" "ld 9, 264(1)\n" 270e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 8, 256(1)\n" "ld 7, 248(1)\n" 271e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 6, 240(1)\n" "ld 5, 232(1)\n" 272e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 4, 224(1)\n" "ld 3, 216(1)\n" 27306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Restore all FP arg registers 274e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 13, 208(1)\n" "lfd 12, 200(1)\n" 275e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 11, 192(1)\n" "lfd 10, 184(1)\n" 276e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 9, 176(1)\n" "lfd 8, 168(1)\n" 277e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 7, 160(1)\n" "lfd 6, 152(1)\n" 278e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 5, 144(1)\n" "lfd 4, 136(1)\n" 279e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 3, 128(1)\n" "lfd 2, 120(1)\n" 280e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 1, 112(1)\n" 28106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Pop 3 frames off the stack and branch to target 282e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 1, 280(1)\n" 283e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 0, 16(1)\n" 284e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mtlr 0\n" 285e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky // XXX: any special TOC handling in the ELF case for JIT? 28606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "bctr\n" 28706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ); 28806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#else 28906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanvoid PPC64CompilationCallback() { 290c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("This is not a power pc, you can't execute this!"); 29106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman} 29206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#endif 29306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman 29406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanextern "C" void *PPCCompilationCallbackC(unsigned *StubCallAddrPlus4, 29506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman unsigned *OrigCallAddrPlus4, 29606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman bool is64Bit) { 297b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Adjust the pointer to the address of the call instruction in the stub 298b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // emitted by emitFunctionStub, rather than the instruction after it. 299b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned *StubCallAddr = StubCallAddrPlus4 - 1; 300b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned *OrigCallAddr = OrigCallAddrPlus4 - 1; 301b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 302b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman void *Target = JITCompilerFunction(StubCallAddr); 303b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 304b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Check to see if *OrigCallAddr is a 'bl' instruction, and if we can rewrite 305b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // it to branch directly to the destination. If so, rewrite it so it does not 306b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // need to go through the stub anymore. 307b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned OrigCallInst = *OrigCallAddr; 308b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman if ((OrigCallInst >> 26) == 18) { // Direct call. 309b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman intptr_t Offset = ((intptr_t)Target - (intptr_t)OrigCallAddr) >> 2; 310b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 311e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 312892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Clear the original target out. 313b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman OrigCallInst &= (63 << 26) | 3; 314892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Fill in the new target. 315b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman OrigCallInst |= (Offset & ((1 << 24)-1)) << 2; 316892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Replace the call. 317b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman *OrigCallAddr = OrigCallInst; 318e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner } 319e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner } 320b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman 321b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Assert that we are coming from a stub that was created with our 322b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // emitFunctionStub. 32306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if ((*StubCallAddr >> 26) == 18) 32406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman StubCallAddr -= 3; 32506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman else { 326b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman assert((*StubCallAddr >> 26) == 19 && "Call in stub is not indirect!"); 32706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman StubCallAddr -= is64Bit ? 9 : 6; 32806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 329e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 330e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner // Rewrite the stub with an unconditional branch to the target, for any users 331e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner // who took the address of the stub. 33206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit); 33313c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4); 334e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 335b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Put the address of the target function to call and the address to return to 336b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // after calling the target function in a place that is easy to get on the 337b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // stack after we restore all regs. 33806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman return Target; 339e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner} 340e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 341e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 342e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 343b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha BrukmanTargetJITInfo::LazyResolverFn 34421e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) { 345e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner JITCompilerFunction = Fn; 34606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback; 347e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner} 348e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 349108c838093704650378b194fe9afc5ebb9e91455Jeffrey YasskinTargetJITInfo::StubLayout PPCJITInfo::getStubLayout() { 350108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // The stub contains up to 10 4-byte instructions, aligned at 4 bytes: 3 351108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // instructions to save the caller's address if this is a lazy-compilation 352108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // stub, plus a 1-, 4-, or 7-instruction sequence to load an arbitrary address 353108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // into a register and jump through it. 354108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin StubLayout Result = {10*4, 4}; 355108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return Result; 356108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin} 357108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin 3581910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 3591910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerdefined(__APPLE__) 3601910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerextern "C" void sys_icache_invalidate(const void *Addr, size_t len); 3611910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#endif 3621910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner 36351cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffrayvoid *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn, 364a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JITCodeEmitter &JCE) { 3659b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // If this is just a call to an external function, emit a branch instead of a 3669b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // call. The code is the same except for one bit of the last instruction. 36706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (Fn != (void*)(intptr_t)PPC32CompilationCallback && 36806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman Fn != (void*)(intptr_t)PPC64CompilationCallback) { 369108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *Addr = (void*)JCE.getCurrentPCValue(); 370a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 371a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 372a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 373a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 374a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 375a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 376a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 377108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin EmitBranchToAt((intptr_t)Addr, (intptr_t)Fn, false, is64Bit); 378108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin sys::Memory::InvalidateInstructionCache(Addr, 7*4); 379108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return Addr; 3809b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 3819b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 382108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *Addr = (void*)JCE.getCurrentPCValue(); 38306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (is64Bit) { 384a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1) 385a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 386a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0xf9610060); // std r11, 96(r1) 3872a9ddfb903ae3baede7282348afae1f750905248Tilmann Scheller } else if (TM.getSubtargetImpl()->isDarwinABI()){ 388a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 389a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 390a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x91610028); // stw r11, 40(r1) 3912fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray } else { 392a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 393a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 394a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x91610024); // stw r11, 36(r1) 39506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 396a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes intptr_t BranchAddr = (intptr_t)JCE.getCurrentPCValue(); 397a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 398a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 399a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 400a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 401a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 402a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 403a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 4041910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit); 405108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin sys::Memory::InvalidateInstructionCache(Addr, 10*4); 406108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return Addr; 4079b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 4089b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4099b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 41021e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::relocate(void *Function, MachineRelocation *MR, 41121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman unsigned NumRelocs, unsigned char* GOTBase) { 4129b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { 4139b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; 4149b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); 4159b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner switch ((PPC::RelocationType)MR->getRelocationType()) { 416c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown relocation type!"); 4179b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner case PPC::reloc_pcrel_bx: 4189b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // PC-relative relocation for b and bl instructions. 4199b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 4209b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) && 4219b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner "Relocation out of range!"); 4229b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner *RelocPos |= (ResultPtr & ((1 << 24)-1)) << 2; 4239b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner break; 424f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng case PPC::reloc_pcrel_bcx: 425f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng // PC-relative relocation for BLT,BLE,BEQ,BGE,BGT,BNE, or other 426f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng // bcx instructions. 427f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 428f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng assert(ResultPtr >= -(1 << 13) && ResultPtr < (1 << 13) && 429f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng "Relocation out of range!"); 430f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng *RelocPos |= (ResultPtr & ((1 << 14)-1)) << 2; 431f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng break; 4325efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner case PPC::reloc_absolute_high: // high bits of ref -> low 16 of instr 4333bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner case PPC::reloc_absolute_low: { // low bits of ref -> low 16 of instr 4349b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr += MR->getConstantVal(); 4359b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4365efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner // If this is a high-part access, get the high-part. 43794be248dbb2d2a44e8f4d47f161b93704d33d279Nate Begeman if (MR->getRelocationType() == PPC::reloc_absolute_high) { 4389b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // If the low part will have a carry (really a borrow) from the low 4399b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // 16-bits into the high 16, add a bit to borrow from. 4409b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner if (((int)ResultPtr << 16) < 0) 4419b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr += 1 << 16; 4429b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr >>= 16; 4439b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4449b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4459b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // Do the addition then mask, so the addition does not overflow the 16-bit 4469b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // immediate section of the instruction. 4479b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned LowBits = (*RelocPos + ResultPtr) & 65535; 4489b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned HighBits = *RelocPos & ~65535; 4499b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner *RelocPos = LowBits | HighBits; // Slam into low 16-bits 4509b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner break; 4519b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4523bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner case PPC::reloc_absolute_low_ix: { // low bits of ref -> low 14 of instr 4533bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner ResultPtr += MR->getConstantVal(); 4543bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner // Do the addition then mask, so the addition does not overflow the 16-bit 4553bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner // immediate section of the instruction. 4563bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner unsigned LowBits = (*RelocPos + ResultPtr) & 0xFFFC; 4573bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner unsigned HighBits = *RelocPos & 0xFFFF0003; 4583bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner *RelocPos = LowBits | HighBits; // Slam into low 14-bits. 4593bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner break; 4603bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner } 4613bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner } 4629b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4639b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 4649b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 46521e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { 46606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit); 46713c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin sys::Memory::InvalidateInstructionCache(Old, 7*4); 4689b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 469