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