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" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 1955fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng#include "llvm/Support/Debug.h" 20dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Memory.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 74f5b9110ce1e0d5bc6f96b1e74d110f0cc576324aBill Schmidt// The first clause of the preprocessor directive looks wrong, but it is 75f5b9110ce1e0d5bc6f96b1e74d110f0cc576324aBill Schmidt// necessary when compiling this code on non-PowerPC hosts. 76eec21735b36ec7f79e6f925b192430bd39e8cd29Bill Schmidt#if (!defined(__ppc__) && !defined(__powerpc__)) || defined(__powerpc64__) || defined(__ppc64__) 770a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenbergervoid PPC32CompilationCallback() { 780a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger llvm_unreachable("This is not a 32bit PowerPC, you can't execute this!"); 790a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger} 800a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#elif !defined(__ELF__) 8173278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in 8273278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 8373278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// write our own wrapper, which does things our way, so we have complete control 8473278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// over register saving and restoring. 8573278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattnerasm( 8673278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".text\n" 8773278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".align 2\n" 8873278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ".globl _PPC32CompilationCallback\n" 8973278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner"_PPC32CompilationCallback:\n" 905425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 915425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // FIXME: need to save v[0-19] for altivec? 9206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // FIXME: could shrink frame 935425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Set up a proper stack frame 9418e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // FIXME Layout 95e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky // PowerPC32 ABI linkage - 24 bytes 9618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // parameters - 32 bytes 9718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 13 double registers - 104 bytes 9818e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 8 int registers - 32 bytes 990eadd73bd78b00379e9f78d1a372bcd28efe855cJim Laskey "mflr r0\n" 10018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stw r0, 8(r1)\n" 10118e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey "stwu r1, -208(r1)\n" 1025425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Save all int arg registers 1035425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r10, 204(r1)\n" "stw r9, 200(r1)\n" 1045425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r8, 196(r1)\n" "stw r7, 192(r1)\n" 1055425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r6, 188(r1)\n" "stw r5, 184(r1)\n" 1065425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stw r4, 180(r1)\n" "stw r3, 176(r1)\n" 10773278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner // Save all call-clobbered FP regs. 1085425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f13, 168(r1)\n" "stfd f12, 160(r1)\n" 1095425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f11, 152(r1)\n" "stfd f10, 144(r1)\n" 1105425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f9, 136(r1)\n" "stfd f8, 128(r1)\n" 1115425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f7, 120(r1)\n" "stfd f6, 112(r1)\n" 1125425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f5, 104(r1)\n" "stfd f4, 96(r1)\n" 1135425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f3, 88(r1)\n" "stfd f2, 80(r1)\n" 1145425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "stfd f1, 72(r1)\n" 1155425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Arguments to Compilation Callback: 1165425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // r3 - our lr (address of the call instruction in stub plus 4) 1175425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // r4 - stub's lr (address of instruction that called the stub plus 4) 118e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner // r5 - is64Bit - always 0. 1195425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mr r3, r0\n" 1205425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r2, 208(r1)\n" // stub's frame 1215425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r4, 8(r2)\n" // stub's lr 12206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "li r5, 0\n" // 0 == 32 bit 1239fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola "bl _LLVMPPCCompilationCallback\n" 1245425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mtctr r3\n" 1255425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Restore all int arg registers 1265425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r10, 204(r1)\n" "lwz r9, 200(r1)\n" 1275425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r8, 196(r1)\n" "lwz r7, 192(r1)\n" 1285425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r6, 188(r1)\n" "lwz r5, 184(r1)\n" 1295425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r4, 180(r1)\n" "lwz r3, 176(r1)\n" 1305425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Restore all FP arg registers 1315425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f13, 168(r1)\n" "lfd f12, 160(r1)\n" 1325425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f11, 152(r1)\n" "lfd f10, 144(r1)\n" 1335425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f9, 136(r1)\n" "lfd f8, 128(r1)\n" 1345425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f7, 120(r1)\n" "lfd f6, 112(r1)\n" 1355425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f5, 104(r1)\n" "lfd f4, 96(r1)\n" 1365425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f3, 88(r1)\n" "lfd f2, 80(r1)\n" 1375425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lfd f1, 72(r1)\n" 1385425267e84946676f1e7424ee056f71b23497ee7Nate Begeman // Pop 3 frames off the stack and branch to target 1395425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r1, 208(r1)\n" 1405425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "lwz r2, 8(r1)\n" 1415425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "mtlr r2\n" 1425425267e84946676f1e7424ee056f71b23497ee7Nate Begeman "bctr\n" 14373278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner ); 144456bc87e78af18331b9579069a059c723da517d9Chris Lattner 1450a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#else 1460a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger// ELF PPC 32 support 147456bc87e78af18331b9579069a059c723da517d9Chris Lattner 148456bc87e78af18331b9579069a059c723da517d9Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in 149456bc87e78af18331b9579069a059c723da517d9Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us. Instead, 150456bc87e78af18331b9579069a059c723da517d9Chris Lattner// write our own wrapper, which does things our way, so we have complete control 151456bc87e78af18331b9579069a059c723da517d9Chris Lattner// over register saving and restoring. 152456bc87e78af18331b9579069a059c723da517d9Chris Lattnerasm( 153456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".text\n" 154456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".align 2\n" 155456bc87e78af18331b9579069a059c723da517d9Chris Lattner ".globl PPC32CompilationCallback\n" 156456bc87e78af18331b9579069a059c723da517d9Chris Lattner"PPC32CompilationCallback:\n" 1572fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray // Make space for 8 ints r[3-10] and 8 doubles f[1-8] and the 158456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME: need to save v[0-19] for altivec? 159456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME: could shrink frame 160456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Set up a proper stack frame 161456bc87e78af18331b9579069a059c723da517d9Chris Lattner // FIXME Layout 1622fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray // 8 double registers - 64 bytes 163456bc87e78af18331b9579069a059c723da517d9Chris Lattner // 8 int registers - 32 bytes 164456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mflr 0\n" 165456bc87e78af18331b9579069a059c723da517d9Chris Lattner "stw 0, 4(1)\n" 1662fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stwu 1, -104(1)\n" 167456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Save all int arg registers 1682fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 10, 100(1)\n" "stw 9, 96(1)\n" 1692fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 8, 92(1)\n" "stw 7, 88(1)\n" 1702fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 6, 84(1)\n" "stw 5, 80(1)\n" 1712fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stw 4, 76(1)\n" "stw 3, 72(1)\n" 172456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Save all call-clobbered FP regs. 1732fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 8, 64(1)\n" 1742fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 7, 56(1)\n" "stfd 6, 48(1)\n" 1752fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 5, 40(1)\n" "stfd 4, 32(1)\n" 1762fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 3, 24(1)\n" "stfd 2, 16(1)\n" 1772fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "stfd 1, 8(1)\n" 178456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Arguments to Compilation Callback: 179456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r3 - our lr (address of the call instruction in stub plus 4) 180456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r4 - stub's lr (address of instruction that called the stub plus 4) 181456bc87e78af18331b9579069a059c723da517d9Chris Lattner // r5 - is64Bit - always 0. 182456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mr 3, 0\n" 1832fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 5, 104(1)\n" // stub's frame 1842fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 4, 4(5)\n" // stub's lr 185456bc87e78af18331b9579069a059c723da517d9Chris Lattner "li 5, 0\n" // 0 == 32 bit 1869fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola "bl LLVMPPCCompilationCallback\n" 187456bc87e78af18331b9579069a059c723da517d9Chris Lattner "mtctr 3\n" 188456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Restore all int arg registers 1892fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 10, 100(1)\n" "lwz 9, 96(1)\n" 1902fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 8, 92(1)\n" "lwz 7, 88(1)\n" 1912fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 6, 84(1)\n" "lwz 5, 80(1)\n" 1922fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 4, 76(1)\n" "lwz 3, 72(1)\n" 193456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Restore all FP arg registers 1942fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 8, 64(1)\n" 1952fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 7, 56(1)\n" "lfd 6, 48(1)\n" 1962fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 5, 40(1)\n" "lfd 4, 32(1)\n" 1972fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 3, 24(1)\n" "lfd 2, 16(1)\n" 1982fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lfd 1, 8(1)\n" 199456bc87e78af18331b9579069a059c723da517d9Chris Lattner // Pop 3 frames off the stack and branch to target 2002fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 1, 104(1)\n" 2012fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "lwz 0, 4(1)\n" 2022fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray "mtlr 0\n" 203456bc87e78af18331b9579069a059c723da517d9Chris Lattner "bctr\n" 204456bc87e78af18331b9579069a059c723da517d9Chris Lattner ); 205ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman#endif 206ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman 207ef540b194f8ae1ff994ccdcb10dcc36f60e419c2David Fang#if !defined(__powerpc64__) && !defined(__ppc64__) 2080a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenbergervoid PPC64CompilationCallback() { 2090a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger llvm_unreachable("This is not a 64bit PowerPC, you can't execute this!"); 2100a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger} 2110a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#else 2120a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger# ifdef __ELF__ 213e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divackyasm( 214e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".text\n" 215e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".align 2\n" 216e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".globl PPC64CompilationCallback\n" 217d9b41b339d3a8b35fac73e63ad665140b5bc7bdcRoman Divacky ".section \".opd\",\"aw\",@progbits\n" 218e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".align 3\n" 219e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky"PPC64CompilationCallback:\n" 220e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".quad .L.PPC64CompilationCallback,.TOC.@tocbase,0\n" 221e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".size PPC64CompilationCallback,24\n" 222e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".previous\n" 223e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".align 4\n" 224e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky ".type PPC64CompilationCallback,@function\n" 225e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky".L.PPC64CompilationCallback:\n" 2260a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger# else 22706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanasm( 22806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".text\n" 22906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".align 2\n" 23006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ".globl _PPC64CompilationCallback\n" 23106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman"_PPC64CompilationCallback:\n" 2320a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger# endif 23306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the 23406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // FIXME: need to save v[0-19] for altivec? 23506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Set up a proper stack frame 23618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // Layout 23718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // PowerPC64 ABI linkage - 48 bytes 23818e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // parameters - 64 bytes 23918e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 13 double registers - 104 bytes 24018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey // 8 int registers - 64 bytes 241e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mflr 0\n" 242e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 0, 16(1)\n" 243e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stdu 1, -280(1)\n" 24406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Save all int arg registers 245e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 10, 272(1)\n" "std 9, 264(1)\n" 246e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 8, 256(1)\n" "std 7, 248(1)\n" 247e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 6, 240(1)\n" "std 5, 232(1)\n" 248e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "std 4, 224(1)\n" "std 3, 216(1)\n" 24906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Save all call-clobbered FP regs. 250e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 13, 208(1)\n" "stfd 12, 200(1)\n" 251e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 11, 192(1)\n" "stfd 10, 184(1)\n" 252e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 9, 176(1)\n" "stfd 8, 168(1)\n" 253e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 7, 160(1)\n" "stfd 6, 152(1)\n" 254e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 5, 144(1)\n" "stfd 4, 136(1)\n" 255e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 3, 128(1)\n" "stfd 2, 120(1)\n" 256e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "stfd 1, 112(1)\n" 25706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Arguments to Compilation Callback: 25806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // r3 - our lr (address of the call instruction in stub plus 4) 25906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // r4 - stub's lr (address of instruction that called the stub plus 4) 260e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner // r5 - is64Bit - always 1. 261e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mr 3, 0\n" // return address (still in r0) 262e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 5, 280(1)\n" // stub's frame 263e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 4, 16(5)\n" // stub's lr 264e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "li 5, 1\n" // 1 == 64 bit 2650a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger# ifdef __ELF__ 2669fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola "bl LLVMPPCCompilationCallback\n" 267e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "nop\n" 2680a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger# else 2699fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola "bl _LLVMPPCCompilationCallback\n" 2700a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger# endif 271e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mtctr 3\n" 27206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Restore all int arg registers 273e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 10, 272(1)\n" "ld 9, 264(1)\n" 274e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 8, 256(1)\n" "ld 7, 248(1)\n" 275e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 6, 240(1)\n" "ld 5, 232(1)\n" 276e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 4, 224(1)\n" "ld 3, 216(1)\n" 27706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Restore all FP arg registers 278e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 13, 208(1)\n" "lfd 12, 200(1)\n" 279e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 11, 192(1)\n" "lfd 10, 184(1)\n" 280e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 9, 176(1)\n" "lfd 8, 168(1)\n" 281e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 7, 160(1)\n" "lfd 6, 152(1)\n" 282e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 5, 144(1)\n" "lfd 4, 136(1)\n" 283e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 3, 128(1)\n" "lfd 2, 120(1)\n" 284e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "lfd 1, 112(1)\n" 28506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman // Pop 3 frames off the stack and branch to target 286e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 1, 280(1)\n" 287e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "ld 0, 16(1)\n" 288e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky "mtlr 0\n" 289e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky // XXX: any special TOC handling in the ELF case for JIT? 29006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman "bctr\n" 29106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman ); 29206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#endif 29306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman 2949cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikovextern "C" { 295a79cbb12324db93236e06cc820f0e36ea1f7e4c4Benjamin KramerLLVM_LIBRARY_VISIBILITY void * 2968a8a2dcae054a7b4dfea360b9b88e6be53fda40fRafael EspindolaLLVMPPCCompilationCallback(unsigned *StubCallAddrPlus4, 2978a8a2dcae054a7b4dfea360b9b88e6be53fda40fRafael Espindola unsigned *OrigCallAddrPlus4, 2988a8a2dcae054a7b4dfea360b9b88e6be53fda40fRafael Espindola bool is64Bit) { 299b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Adjust the pointer to the address of the call instruction in the stub 300b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // emitted by emitFunctionStub, rather than the instruction after it. 301b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned *StubCallAddr = StubCallAddrPlus4 - 1; 302b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned *OrigCallAddr = OrigCallAddrPlus4 - 1; 303b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 304b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman void *Target = JITCompilerFunction(StubCallAddr); 305b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 306b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Check to see if *OrigCallAddr is a 'bl' instruction, and if we can rewrite 307b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // it to branch directly to the destination. If so, rewrite it so it does not 308b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // need to go through the stub anymore. 309b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman unsigned OrigCallInst = *OrigCallAddr; 310b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman if ((OrigCallInst >> 26) == 18) { // Direct call. 311b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman intptr_t Offset = ((intptr_t)Target - (intptr_t)OrigCallAddr) >> 2; 312b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman 313e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range? 314892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Clear the original target out. 315b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman OrigCallInst &= (63 << 26) | 3; 316892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Fill in the new target. 317b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman OrigCallInst |= (Offset & ((1 << 24)-1)) << 2; 318892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner // Replace the call. 319b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman *OrigCallAddr = OrigCallInst; 320e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner } 321e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner } 322b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman 323b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Assert that we are coming from a stub that was created with our 324b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // emitFunctionStub. 32506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if ((*StubCallAddr >> 26) == 18) 32606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman StubCallAddr -= 3; 32706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman else { 328b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman assert((*StubCallAddr >> 26) == 19 && "Call in stub is not indirect!"); 32906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman StubCallAddr -= is64Bit ? 9 : 6; 33006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 331e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 332e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner // Rewrite the stub with an unconditional branch to the target, for any users 333e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner // who took the address of the stub. 33406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit); 33513c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4); 336e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 337b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // Put the address of the target function to call and the address to return to 338b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // after calling the target function in a place that is easy to get on the 339b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman // stack after we restore all regs. 34006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman return Target; 341e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner} 3429cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikov} 343e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 344e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 345e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 346b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha BrukmanTargetJITInfo::LazyResolverFn 34721e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) { 348e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner JITCompilerFunction = Fn; 34906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback; 350e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner} 351e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner 352108c838093704650378b194fe9afc5ebb9e91455Jeffrey YasskinTargetJITInfo::StubLayout PPCJITInfo::getStubLayout() { 353108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // The stub contains up to 10 4-byte instructions, aligned at 4 bytes: 3 354108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // instructions to save the caller's address if this is a lazy-compilation 355108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // stub, plus a 1-, 4-, or 7-instruction sequence to load an arbitrary address 356108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // into a register and jump through it. 357108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin StubLayout Result = {10*4, 4}; 358108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return Result; 359108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin} 360108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin 361496cf2308acf4bb719a015517f27dff10db7de49Rafael Espindola#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \ 362496cf2308acf4bb719a015517f27dff10db7de49Rafael Espindoladefined(__APPLE__) 3631910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerextern "C" void sys_icache_invalidate(const void *Addr, size_t len); 3641910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#endif 3651910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner 36651cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffrayvoid *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn, 367a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JITCodeEmitter &JCE) { 3689b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // If this is just a call to an external function, emit a branch instead of a 3699b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // call. The code is the same except for one bit of the last instruction. 37006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (Fn != (void*)(intptr_t)PPC32CompilationCallback && 37106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman Fn != (void*)(intptr_t)PPC64CompilationCallback) { 372108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *Addr = (void*)JCE.getCurrentPCValue(); 373a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 374a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 375a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 376a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 377a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 378a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 379a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 380108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin EmitBranchToAt((intptr_t)Addr, (intptr_t)Fn, false, is64Bit); 381108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin sys::Memory::InvalidateInstructionCache(Addr, 7*4); 382108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return Addr; 3839b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 3849b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 385108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *Addr = (void*)JCE.getCurrentPCValue(); 38606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman if (is64Bit) { 387a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0xf821ffb1); // stdu r1,-80(r1) 388a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 389a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0xf9610060); // std r11, 96(r1) 3902a9ddfb903ae3baede7282348afae1f750905248Tilmann Scheller } else if (TM.getSubtargetImpl()->isDarwinABI()){ 391a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 392a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 393a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x91610028); // stw r11, 40(r1) 3942fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray } else { 395a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x9421ffe0); // stwu r1,-32(r1) 396a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x7d6802a6); // mflr r11 397a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0x91610024); // stw r11, 36(r1) 39806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman } 399a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes intptr_t BranchAddr = (intptr_t)JCE.getCurrentPCValue(); 400a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 401a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 402a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 403a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 404a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 405a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 406a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JCE.emitWordBE(0); 4071910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit); 408108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin sys::Memory::InvalidateInstructionCache(Addr, 10*4); 409108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return Addr; 4109b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 4119b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4129b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 41321e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::relocate(void *Function, MachineRelocation *MR, 41421e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman unsigned NumRelocs, unsigned char* GOTBase) { 4159b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { 4169b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; 4179b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); 4189b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner switch ((PPC::RelocationType)MR->getRelocationType()) { 419c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown relocation type!"); 4209b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner case PPC::reloc_pcrel_bx: 4219b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // PC-relative relocation for b and bl instructions. 4229b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 4239b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) && 4249b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner "Relocation out of range!"); 4259b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner *RelocPos |= (ResultPtr & ((1 << 24)-1)) << 2; 4269b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner break; 427f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng case PPC::reloc_pcrel_bcx: 428f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng // PC-relative relocation for BLT,BLE,BEQ,BGE,BGT,BNE, or other 429f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng // bcx instructions. 430f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 431f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng assert(ResultPtr >= -(1 << 13) && ResultPtr < (1 << 13) && 432f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng "Relocation out of range!"); 433f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng *RelocPos |= (ResultPtr & ((1 << 14)-1)) << 2; 434f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng break; 4355efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner case PPC::reloc_absolute_high: // high bits of ref -> low 16 of instr 4363bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner case PPC::reloc_absolute_low: { // low bits of ref -> low 16 of instr 4379b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr += MR->getConstantVal(); 4389b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4395efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner // If this is a high-part access, get the high-part. 44094be248dbb2d2a44e8f4d47f161b93704d33d279Nate Begeman if (MR->getRelocationType() == PPC::reloc_absolute_high) { 4419b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // If the low part will have a carry (really a borrow) from the low 4429b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // 16-bits into the high 16, add a bit to borrow from. 4439b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner if (((int)ResultPtr << 16) < 0) 4449b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr += 1 << 16; 4459b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner ResultPtr >>= 16; 4469b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4479b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 4489b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // Do the addition then mask, so the addition does not overflow the 16-bit 4499b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner // immediate section of the instruction. 4509b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned LowBits = (*RelocPos + ResultPtr) & 65535; 4519b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner unsigned HighBits = *RelocPos & ~65535; 4529b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner *RelocPos = LowBits | HighBits; // Slam into low 16-bits 4539b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner break; 4549b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4553bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner case PPC::reloc_absolute_low_ix: { // low bits of ref -> low 14 of instr 4563bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner ResultPtr += MR->getConstantVal(); 4573bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner // Do the addition then mask, so the addition does not overflow the 16-bit 4583bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner // immediate section of the instruction. 4593bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner unsigned LowBits = (*RelocPos + ResultPtr) & 0xFFFC; 4603bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner unsigned HighBits = *RelocPos & 0xFFFF0003; 4613bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner *RelocPos = LowBits | HighBits; // Slam into low 14-bits. 4623bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner break; 4633bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner } 4643bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner } 4659b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner } 4669b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 4679b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner 46821e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) { 46906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit); 47013c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin sys::Memory::InvalidateInstructionCache(Old, 7*4); 4719b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner} 472