PPCJITInfo.cpp revision d04a8d4b33ff316ca4cf961e06c9e312eff8e64f
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"
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
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"
213d9b41b339d3a8b35fac73e63ad665140b5bc7bdcRoman Divacky    ".section \".opd\",\"aw\",@progbits\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
2949cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikovextern "C" {
2959cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikovstatic void* LLVM_ATTRIBUTE_USED PPCCompilationCallbackC(unsigned *StubCallAddrPlus4,
2969cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikov                                                         unsigned *OrigCallAddrPlus4,
2979cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikov                                                         bool is64Bit) {
298b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Adjust the pointer to the address of the call instruction in the stub
299b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // emitted by emitFunctionStub, rather than the instruction after it.
300b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  unsigned *StubCallAddr = StubCallAddrPlus4 - 1;
301b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  unsigned *OrigCallAddr = OrigCallAddrPlus4 - 1;
302b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman
303b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  void *Target = JITCompilerFunction(StubCallAddr);
304b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman
305b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Check to see if *OrigCallAddr is a 'bl' instruction, and if we can rewrite
306b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // it to branch directly to the destination.  If so, rewrite it so it does not
307b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // need to go through the stub anymore.
308b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  unsigned OrigCallInst = *OrigCallAddr;
309b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  if ((OrigCallInst >> 26) == 18) {     // Direct call.
310b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman    intptr_t Offset = ((intptr_t)Target - (intptr_t)OrigCallAddr) >> 2;
311b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman
312e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner    if (Offset >= -(1 << 23) && Offset < (1 << 23)) {   // In range?
313892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner      // Clear the original target out.
314b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman      OrigCallInst &= (63 << 26) | 3;
315892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner      // Fill in the new target.
316b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman      OrigCallInst |= (Offset & ((1 << 24)-1)) << 2;
317892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner      // Replace the call.
318b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman      *OrigCallAddr = OrigCallInst;
319e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner    }
320e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  }
321b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
322b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Assert that we are coming from a stub that was created with our
323b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // emitFunctionStub.
32406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  if ((*StubCallAddr >> 26) == 18)
32506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    StubCallAddr -= 3;
32606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  else {
327b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  assert((*StubCallAddr >> 26) == 19 && "Call in stub is not indirect!");
32806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    StubCallAddr -= is64Bit ? 9 : 6;
32906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  }
330e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
331e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  // Rewrite the stub with an unconditional branch to the target, for any users
332e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  // who took the address of the stub.
33306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit);
33413c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin  sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4);
335e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
336b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Put the address of the target function to call and the address to return to
337b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // after calling the target function in a place that is easy to get on the
338b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // stack after we restore all regs.
33906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  return Target;
340e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner}
3419cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikov}
342e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
343e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
344e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
345b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha BrukmanTargetJITInfo::LazyResolverFn
34621e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) {
347e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  JITCompilerFunction = Fn;
34806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback;
349e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner}
350e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
351108c838093704650378b194fe9afc5ebb9e91455Jeffrey YasskinTargetJITInfo::StubLayout PPCJITInfo::getStubLayout() {
352108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // The stub contains up to 10 4-byte instructions, aligned at 4 bytes: 3
353108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // instructions to save the caller's address if this is a lazy-compilation
354108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // stub, plus a 1-, 4-, or 7-instruction sequence to load an arbitrary address
355108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // into a register and jump through it.
356108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  StubLayout Result = {10*4, 4};
357108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  return Result;
358108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin}
359108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin
3601910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
3611910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerdefined(__APPLE__)
3621910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerextern "C" void sys_icache_invalidate(const void *Addr, size_t len);
3631910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#endif
3641910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner
36551cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffrayvoid *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
366a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes                                   JITCodeEmitter &JCE) {
3679b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  // If this is just a call to an external function, emit a branch instead of a
3689b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  // call.  The code is the same except for one bit of the last instruction.
36906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  if (Fn != (void*)(intptr_t)PPC32CompilationCallback &&
37006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman      Fn != (void*)(intptr_t)PPC64CompilationCallback) {
371108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    void *Addr = (void*)JCE.getCurrentPCValue();
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);
377a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
378a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
379108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    EmitBranchToAt((intptr_t)Addr, (intptr_t)Fn, false, is64Bit);
380108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    sys::Memory::InvalidateInstructionCache(Addr, 7*4);
381108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    return Addr;
3829b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  }
3839b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
384108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  void *Addr = (void*)JCE.getCurrentPCValue();
38506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  if (is64Bit) {
386a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0xf821ffb1);     // stdu r1,-80(r1)
387a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x7d6802a6);     // mflr r11
388a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0xf9610060);     // std r11, 96(r1)
3892a9ddfb903ae3baede7282348afae1f750905248Tilmann Scheller  } else if (TM.getSubtargetImpl()->isDarwinABI()){
390a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x9421ffe0);     // stwu r1,-32(r1)
391a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x7d6802a6);     // mflr r11
392a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x91610028);     // stw r11, 40(r1)
3932fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray  } else {
394a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x9421ffe0);     // stwu r1,-32(r1)
395a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x7d6802a6);     // mflr r11
396a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x91610024);     // stw r11, 36(r1)
39706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  }
398a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  intptr_t BranchAddr = (intptr_t)JCE.getCurrentPCValue();
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);
404a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
405a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
4061910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner  EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit);
407108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  sys::Memory::InvalidateInstructionCache(Addr, 10*4);
408108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  return Addr;
4099b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner}
4109b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
4119b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
41221e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::relocate(void *Function, MachineRelocation *MR,
41321e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                          unsigned NumRelocs, unsigned char* GOTBase) {
4149b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  for (unsigned i = 0; i != NumRelocs; ++i, ++MR) {
4159b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4;
4169b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    intptr_t ResultPtr = (intptr_t)MR->getResultPointer();
4179b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    switch ((PPC::RelocationType)MR->getRelocationType()) {
418c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown relocation type!");
4199b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    case PPC::reloc_pcrel_bx:
4209b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      // PC-relative relocation for b and bl instructions.
4219b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2;
4229b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) &&
4239b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner             "Relocation out of range!");
4249b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      *RelocPos |= (ResultPtr & ((1 << 24)-1))  << 2;
4259b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      break;
426f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng    case PPC::reloc_pcrel_bcx:
427f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      // PC-relative relocation for BLT,BLE,BEQ,BGE,BGT,BNE, or other
428f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      // bcx instructions.
429f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2;
430f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      assert(ResultPtr >= -(1 << 13) && ResultPtr < (1 << 13) &&
431f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng             "Relocation out of range!");
432f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      *RelocPos |= (ResultPtr & ((1 << 14)-1))  << 2;
433f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      break;
4345efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner    case PPC::reloc_absolute_high:     // high bits of ref -> low 16 of instr
4353bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    case PPC::reloc_absolute_low: {    // low bits of ref  -> low 16 of instr
4369b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      ResultPtr += MR->getConstantVal();
4379b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
4385efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner      // If this is a high-part access, get the high-part.
43994be248dbb2d2a44e8f4d47f161b93704d33d279Nate Begeman      if (MR->getRelocationType() == PPC::reloc_absolute_high) {
4409b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        // If the low part will have a carry (really a borrow) from the low
4419b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        // 16-bits into the high 16, add a bit to borrow from.
4429b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        if (((int)ResultPtr << 16) < 0)
4439b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner          ResultPtr += 1 << 16;
4449b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        ResultPtr >>= 16;
4459b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      }
4469b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
4479b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      // Do the addition then mask, so the addition does not overflow the 16-bit
4489b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      // immediate section of the instruction.
4499b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      unsigned LowBits  = (*RelocPos + ResultPtr) & 65535;
4509b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      unsigned HighBits = *RelocPos & ~65535;
4519b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      *RelocPos = LowBits | HighBits;  // Slam into low 16-bits
4529b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      break;
4539b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    }
4543bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    case PPC::reloc_absolute_low_ix: {  // low bits of ref  -> low 14 of instr
4553bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      ResultPtr += MR->getConstantVal();
4563bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      // Do the addition then mask, so the addition does not overflow the 16-bit
4573bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      // immediate section of the instruction.
4583bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      unsigned LowBits  = (*RelocPos + ResultPtr) & 0xFFFC;
4593bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      unsigned HighBits = *RelocPos & 0xFFFF0003;
4603bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      *RelocPos = LowBits | HighBits;  // Slam into low 14-bits.
4613bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      break;
4623bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    }
4633bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    }
4649b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  }
4659b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner}
4669b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
46721e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
46806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit);
46913c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin  sys::Memory::InvalidateInstructionCache(Old, 7*4);
4709b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner}
471