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
14b9459b731a0b6345d1e14083fcfa6508646ba81dChris Lattner#include "PPCJITInfo.h"
1516e71f2f70811c69c56052dd146324fe20e31db5Chris Lattner#include "PPCRelocations.h"
16cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "PPCSubtarget.h"
170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
1855fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng#include "llvm/Support/Debug.h"
19dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Memory.h"
21dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
229b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattnerusing namespace llvm;
239b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "jit"
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
269b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattnerstatic TargetJITInfo::JITCompilerFn JITCompilerFunction;
279b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesPPCJITInfo::PPCJITInfo(PPCSubtarget &STI)
29cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    : Subtarget(STI), is64Bit(STI.isPPC64()) {
30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  useGOT = 0;
31cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
339b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_ADDIS(RD,RS,IMM16) \
349b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  ((15 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535))
359b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_ORI(RD,RS,UIMM16) \
369b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  ((24 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535))
3706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_ORIS(RD,RS,UIMM16) \
3806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  ((25 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535))
3906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_RLDICR(RD,RS,SH,ME) \
4006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  ((30 << 26) | ((RS) << 21) | ((RD) << 16) | (((SH) & 31) << 11) | \
41eb63b0a9d5089dd3119ba9c3cad9cf9ad79df0f7Chris Lattner   (((ME) & 63) << 6) | (1 << 2) | ((((SH) >> 5) & 1) << 1))
429b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_MTSPR(RS,SPR)      \
439b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  ((31 << 26) | ((RS) << 21) | ((SPR) << 16) | (467 << 1))
449b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_BCCTRx(BO,BI,LINK) \
459b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  ((19 << 26) | ((BO) << 21) | ((BI) << 16) | (528 << 1) | ((LINK) & 1))
4606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_B(TARGET, LINK) \
4706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  ((18 << 26) | (((TARGET) & 0x00FFFFFF) << 2) | ((LINK) & 1))
489b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
499b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner// Pseudo-ops
509b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_LIS(RD,IMM16)    BUILD_ADDIS(RD,0,IMM16)
5106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#define BUILD_SLDI(RD,RS,IMM6) BUILD_RLDICR(RD,RS,IMM6,63-IMM6)
529b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_MTCTR(RS)        BUILD_MTSPR(RS,9)
539b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner#define BUILD_BCTR(LINK)       BUILD_BCCTRx(20,0,LINK)
549b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
5506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanstatic void EmitBranchToAt(uint64_t At, uint64_t To, bool isCall, bool is64Bit){
5606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  intptr_t Offset = ((intptr_t)To - (intptr_t)At) >> 2;
5706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  unsigned *AtI = (unsigned*)(intptr_t)At;
589b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
5906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  if (Offset >= -(1 << 23) && Offset < (1 << 23)) {   // In range?
6006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[0] = BUILD_B(Offset, isCall);     // b/bl target
6106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  } else if (!is64Bit) {
6206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[0] = BUILD_LIS(12, To >> 16);     // lis r12, hi16(address)
6306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[1] = BUILD_ORI(12, 12, To);       // ori r12, r12, lo16(address)
6406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[2] = BUILD_MTCTR(12);             // mtctr r12
6506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[3] = BUILD_BCTR(isCall);          // bctr/bctrl
6606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  } else {
6706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[0] = BUILD_LIS(12, To >> 48);      // lis r12, hi16(address)
6806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[1] = BUILD_ORI(12, 12, To >> 32);  // ori r12, r12, lo16(address)
6906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[2] = BUILD_SLDI(12, 12, 32);       // sldi r12, r12, 32
7006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[3] = BUILD_ORIS(12, 12, To >> 16); // oris r12, r12, hi16(address)
7106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[4] = BUILD_ORI(12, 12, To);        // ori r12, r12, lo16(address)
7206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[5] = BUILD_MTCTR(12);              // mtctr r12
7306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    AtI[6] = BUILD_BCTR(isCall);           // bctr/bctrl
7406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  }
759b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner}
769b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
7773278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattnerextern "C" void PPC32CompilationCallback();
7806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanextern "C" void PPC64CompilationCallback();
7973278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner
80f5b9110ce1e0d5bc6f96b1e74d110f0cc576324aBill Schmidt// The first clause of the preprocessor directive looks wrong, but it is
81f5b9110ce1e0d5bc6f96b1e74d110f0cc576324aBill Schmidt// necessary when compiling this code on non-PowerPC hosts.
82eec21735b36ec7f79e6f925b192430bd39e8cd29Bill Schmidt#if (!defined(__ppc__) && !defined(__powerpc__)) || defined(__powerpc64__) || defined(__ppc64__)
830a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenbergervoid PPC32CompilationCallback() {
840a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger  llvm_unreachable("This is not a 32bit PowerPC, you can't execute this!");
850a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger}
860a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#elif !defined(__ELF__)
8773278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in
8873278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us.  Instead,
8973278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// write our own wrapper, which does things our way, so we have complete control
9073278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner// over register saving and restoring.
9173278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattnerasm(
9273278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner    ".text\n"
9373278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner    ".align 2\n"
9473278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner    ".globl _PPC32CompilationCallback\n"
9573278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner"_PPC32CompilationCallback:\n"
965425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the
975425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // FIXME: need to save v[0-19] for altivec?
9806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // FIXME: could shrink frame
995425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // Set up a proper stack frame
10018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    // FIXME Layout
101e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    //   PowerPC32 ABI linkage    -  24 bytes
10218e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    //                 parameters -  32 bytes
10318e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    //   13 double registers      - 104 bytes
10418e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    //   8 int registers          -  32 bytes
1050eadd73bd78b00379e9f78d1a372bcd28efe855cJim Laskey    "mflr r0\n"
10618e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    "stw r0,  8(r1)\n"
10718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    "stwu r1, -208(r1)\n"
1085425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // Save all int arg registers
1095425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stw r10, 204(r1)\n"    "stw r9,  200(r1)\n"
1105425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stw r8,  196(r1)\n"    "stw r7,  192(r1)\n"
1115425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stw r6,  188(r1)\n"    "stw r5,  184(r1)\n"
1125425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stw r4,  180(r1)\n"    "stw r3,  176(r1)\n"
11373278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner    // Save all call-clobbered FP regs.
1145425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stfd f13, 168(r1)\n"   "stfd f12, 160(r1)\n"
1155425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stfd f11, 152(r1)\n"   "stfd f10, 144(r1)\n"
1165425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stfd f9,  136(r1)\n"   "stfd f8,  128(r1)\n"
1175425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stfd f7,  120(r1)\n"   "stfd f6,  112(r1)\n"
1185425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stfd f5,  104(r1)\n"   "stfd f4,   96(r1)\n"
1195425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stfd f3,   88(r1)\n"   "stfd f2,   80(r1)\n"
1205425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "stfd f1,   72(r1)\n"
1215425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // Arguments to Compilation Callback:
1225425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // r3 - our lr (address of the call instruction in stub plus 4)
1235425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // r4 - stub's lr (address of instruction that called the stub plus 4)
124e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner    // r5 - is64Bit - always 0.
1255425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "mr   r3, r0\n"
1265425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz  r2, 208(r1)\n" // stub's frame
1275425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz  r4, 8(r2)\n" // stub's lr
12806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    "li   r5, 0\n"       // 0 == 32 bit
1299fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola    "bl _LLVMPPCCompilationCallback\n"
1305425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "mtctr r3\n"
1315425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // Restore all int arg registers
1325425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz r10, 204(r1)\n"    "lwz r9,  200(r1)\n"
1335425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz r8,  196(r1)\n"    "lwz r7,  192(r1)\n"
1345425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz r6,  188(r1)\n"    "lwz r5,  184(r1)\n"
1355425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz r4,  180(r1)\n"    "lwz r3,  176(r1)\n"
1365425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // Restore all FP arg registers
1375425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lfd f13, 168(r1)\n"    "lfd f12, 160(r1)\n"
1385425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lfd f11, 152(r1)\n"    "lfd f10, 144(r1)\n"
1395425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lfd f9,  136(r1)\n"    "lfd f8,  128(r1)\n"
1405425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lfd f7,  120(r1)\n"    "lfd f6,  112(r1)\n"
1415425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lfd f5,  104(r1)\n"    "lfd f4,   96(r1)\n"
1425425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lfd f3,   88(r1)\n"    "lfd f2,   80(r1)\n"
1435425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lfd f1,   72(r1)\n"
1445425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    // Pop 3 frames off the stack and branch to target
1455425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz  r1, 208(r1)\n"
1465425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "lwz  r2, 8(r1)\n"
1475425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "mtlr r2\n"
1485425267e84946676f1e7424ee056f71b23497ee7Nate Begeman    "bctr\n"
14973278080c8078002beb4706d5b1592e9b9c5f9b3Chris Lattner    );
150456bc87e78af18331b9579069a059c723da517d9Chris Lattner
1510a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#else
1520a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger// ELF PPC 32 support
153456bc87e78af18331b9579069a059c723da517d9Chris Lattner
154456bc87e78af18331b9579069a059c723da517d9Chris Lattner// CompilationCallback stub - We can't use a C function with inline assembly in
155456bc87e78af18331b9579069a059c723da517d9Chris Lattner// it, because we the prolog/epilog inserted by GCC won't work for us.  Instead,
156456bc87e78af18331b9579069a059c723da517d9Chris Lattner// write our own wrapper, which does things our way, so we have complete control
157456bc87e78af18331b9579069a059c723da517d9Chris Lattner// over register saving and restoring.
158456bc87e78af18331b9579069a059c723da517d9Chris Lattnerasm(
159456bc87e78af18331b9579069a059c723da517d9Chris Lattner    ".text\n"
160456bc87e78af18331b9579069a059c723da517d9Chris Lattner    ".align 2\n"
161456bc87e78af18331b9579069a059c723da517d9Chris Lattner    ".globl PPC32CompilationCallback\n"
162456bc87e78af18331b9579069a059c723da517d9Chris Lattner"PPC32CompilationCallback:\n"
1632fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    // Make space for 8 ints r[3-10] and 8 doubles f[1-8] and the
164456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // FIXME: need to save v[0-19] for altivec?
165456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // FIXME: could shrink frame
166456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // Set up a proper stack frame
167456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // FIXME Layout
1682fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    //   8 double registers       -  64 bytes
169456bc87e78af18331b9579069a059c723da517d9Chris Lattner    //   8 int registers          -  32 bytes
170456bc87e78af18331b9579069a059c723da517d9Chris Lattner    "mflr 0\n"
171456bc87e78af18331b9579069a059c723da517d9Chris Lattner    "stw 0,  4(1)\n"
1722fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stwu 1, -104(1)\n"
173456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // Save all int arg registers
1742fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stw 10, 100(1)\n"   "stw 9,  96(1)\n"
1752fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stw 8,  92(1)\n"    "stw 7,  88(1)\n"
1762fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stw 6,  84(1)\n"    "stw 5,  80(1)\n"
1772fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stw 4,  76(1)\n"    "stw 3,  72(1)\n"
178456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // Save all call-clobbered FP regs.
1792fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stfd 8,  64(1)\n"
1802fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stfd 7,  56(1)\n"   "stfd 6,  48(1)\n"
1812fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stfd 5,  40(1)\n"   "stfd 4,  32(1)\n"
1822fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stfd 3,  24(1)\n"   "stfd 2,  16(1)\n"
1832fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "stfd 1,  8(1)\n"
184456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // Arguments to Compilation Callback:
185456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // r3 - our lr (address of the call instruction in stub plus 4)
186456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // r4 - stub's lr (address of instruction that called the stub plus 4)
187456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // r5 - is64Bit - always 0.
188456bc87e78af18331b9579069a059c723da517d9Chris Lattner    "mr   3, 0\n"
1892fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz  5, 104(1)\n" // stub's frame
1902fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz  4, 4(5)\n" // stub's lr
191456bc87e78af18331b9579069a059c723da517d9Chris Lattner    "li   5, 0\n"       // 0 == 32 bit
1929fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola    "bl LLVMPPCCompilationCallback\n"
193456bc87e78af18331b9579069a059c723da517d9Chris Lattner    "mtctr 3\n"
194456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // Restore all int arg registers
1952fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz 10, 100(1)\n"   "lwz 9,  96(1)\n"
1962fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz 8,  92(1)\n"    "lwz 7,  88(1)\n"
1972fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz 6,  84(1)\n"    "lwz 5,  80(1)\n"
1982fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz 4,  76(1)\n"    "lwz 3,  72(1)\n"
199456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // Restore all FP arg registers
2002fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lfd 8,  64(1)\n"
2012fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lfd 7,  56(1)\n"    "lfd 6,  48(1)\n"
2022fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lfd 5,  40(1)\n"    "lfd 4,  32(1)\n"
2032fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lfd 3,  24(1)\n"    "lfd 2,  16(1)\n"
2042fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lfd 1,  8(1)\n"
205456bc87e78af18331b9579069a059c723da517d9Chris Lattner    // Pop 3 frames off the stack and branch to target
2062fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz  1, 104(1)\n"
2072fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "lwz  0, 4(1)\n"
2082fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray    "mtlr 0\n"
209456bc87e78af18331b9579069a059c723da517d9Chris Lattner    "bctr\n"
210456bc87e78af18331b9579069a059c723da517d9Chris Lattner    );
211ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman#endif
212ca6d0f53ffb0a3112b55a665f7a446f86d5cd6dcNate Begeman
213ef540b194f8ae1ff994ccdcb10dcc36f60e419c2David Fang#if !defined(__powerpc64__) && !defined(__ppc64__)
2140a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenbergervoid PPC64CompilationCallback() {
2150a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger  llvm_unreachable("This is not a 64bit PowerPC, you can't execute this!");
2160a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger}
2170a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#else
2180a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#  ifdef __ELF__
219e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divackyasm(
220e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".text\n"
221e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".align 2\n"
222e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".globl PPC64CompilationCallback\n"
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#if _CALL_ELF == 2
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ".type PPC64CompilationCallback,@function\n"
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines"PPC64CompilationCallback:\n"
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#else
227d9b41b339d3a8b35fac73e63ad665140b5bc7bdcRoman Divacky    ".section \".opd\",\"aw\",@progbits\n"
228e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".align 3\n"
229e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky"PPC64CompilationCallback:\n"
230e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".quad .L.PPC64CompilationCallback,.TOC.@tocbase,0\n"
231e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".size PPC64CompilationCallback,24\n"
232e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".previous\n"
233e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".align 4\n"
234e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    ".type PPC64CompilationCallback,@function\n"
235e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky".L.PPC64CompilationCallback:\n"
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
2370a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#  else
23806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begemanasm(
23906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    ".text\n"
24006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    ".align 2\n"
24106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    ".globl _PPC64CompilationCallback\n"
24206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman"_PPC64CompilationCallback:\n"
2430a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#  endif
24406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Make space for 8 ints r[3-10] and 13 doubles f[1-13] and the
24506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // FIXME: need to save v[0-19] for altivec?
24606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Set up a proper stack frame
24718e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    // Layout
24818e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    //   PowerPC64 ABI linkage    -  48 bytes
24918e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    //                 parameters -  64 bytes
25018e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    //   13 double registers      - 104 bytes
25118e2f4433e3bc8b95e1bd0c9e5de7b384eb7db3bJim Laskey    //   8 int registers          -  64 bytes
252e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "mflr 0\n"
253e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "std  0,  16(1)\n"
254e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stdu 1, -280(1)\n"
25506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Save all int arg registers
256e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "std 10, 272(1)\n"    "std 9,  264(1)\n"
257e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "std 8,  256(1)\n"    "std 7,  248(1)\n"
258e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "std 6,  240(1)\n"    "std 5,  232(1)\n"
259e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "std 4,  224(1)\n"    "std 3,  216(1)\n"
26006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Save all call-clobbered FP regs.
261e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stfd 13, 208(1)\n"    "stfd 12, 200(1)\n"
262e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stfd 11, 192(1)\n"    "stfd 10, 184(1)\n"
263e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stfd 9,  176(1)\n"    "stfd 8,  168(1)\n"
264e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stfd 7,  160(1)\n"    "stfd 6,  152(1)\n"
265e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stfd 5,  144(1)\n"    "stfd 4,  136(1)\n"
266e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stfd 3,  128(1)\n"    "stfd 2,  120(1)\n"
267e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "stfd 1,  112(1)\n"
26806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Arguments to Compilation Callback:
26906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // r3 - our lr (address of the call instruction in stub plus 4)
27006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // r4 - stub's lr (address of instruction that called the stub plus 4)
271e150b8eb873fc1bdde17d8ecfd3c38168a5cdceeChris Lattner    // r5 - is64Bit - always 1.
272e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "mr   3, 0\n"      // return address (still in r0)
273e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld   5, 280(1)\n" // stub's frame
274e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld   4, 16(5)\n"  // stub's lr
275e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "li   5, 1\n"      // 1 == 64 bit
2760a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#  ifdef __ELF__
2779fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola    "bl LLVMPPCCompilationCallback\n"
278e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "nop\n"
2790a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#  else
2809fa05f98e0e8410bc8c5e4000e0d47880f8b37c4Rafael Espindola    "bl _LLVMPPCCompilationCallback\n"
2810a14e7123269ffc84b26d87676ddce1afc335f02Joerg Sonnenberger#  endif
282e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "mtctr 3\n"
28306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Restore all int arg registers
284e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld 10, 272(1)\n"    "ld 9,  264(1)\n"
285e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld 8,  256(1)\n"    "ld 7,  248(1)\n"
286e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld 6,  240(1)\n"    "ld 5,  232(1)\n"
287e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld 4,  224(1)\n"    "ld 3,  216(1)\n"
28806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Restore all FP arg registers
289e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "lfd 13, 208(1)\n"    "lfd 12, 200(1)\n"
290e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "lfd 11, 192(1)\n"    "lfd 10, 184(1)\n"
291e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "lfd 9,  176(1)\n"    "lfd 8,  168(1)\n"
292e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "lfd 7,  160(1)\n"    "lfd 6,  152(1)\n"
293e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "lfd 5,  144(1)\n"    "lfd 4,  136(1)\n"
294e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "lfd 3,  128(1)\n"    "lfd 2,  120(1)\n"
295e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "lfd 1,  112(1)\n"
29606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    // Pop 3 frames off the stack and branch to target
297e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld  1, 280(1)\n"
298e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "ld  0, 16(1)\n"
299e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    "mtlr 0\n"
300e355b80194ac5c908cecbecd6f3c137b2c9802cbRoman Divacky    // XXX: any special TOC handling in the ELF case for JIT?
30106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    "bctr\n"
30206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    );
30306abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman#endif
30406abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman
3059cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikovextern "C" {
306a79cbb12324db93236e06cc820f0e36ea1f7e4c4Benjamin KramerLLVM_LIBRARY_VISIBILITY void *
3078a8a2dcae054a7b4dfea360b9b88e6be53fda40fRafael EspindolaLLVMPPCCompilationCallback(unsigned *StubCallAddrPlus4,
3088a8a2dcae054a7b4dfea360b9b88e6be53fda40fRafael Espindola                           unsigned *OrigCallAddrPlus4,
3098a8a2dcae054a7b4dfea360b9b88e6be53fda40fRafael Espindola                           bool is64Bit) {
310b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Adjust the pointer to the address of the call instruction in the stub
311b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // emitted by emitFunctionStub, rather than the instruction after it.
312b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  unsigned *StubCallAddr = StubCallAddrPlus4 - 1;
313b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  unsigned *OrigCallAddr = OrigCallAddrPlus4 - 1;
314b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman
315b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  void *Target = JITCompilerFunction(StubCallAddr);
316b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman
317b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Check to see if *OrigCallAddr is a 'bl' instruction, and if we can rewrite
318b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // it to branch directly to the destination.  If so, rewrite it so it does not
319b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // need to go through the stub anymore.
320b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  unsigned OrigCallInst = *OrigCallAddr;
321b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  if ((OrigCallInst >> 26) == 18) {     // Direct call.
322b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman    intptr_t Offset = ((intptr_t)Target - (intptr_t)OrigCallAddr) >> 2;
323b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman
324e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner    if (Offset >= -(1 << 23) && Offset < (1 << 23)) {   // In range?
325892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner      // Clear the original target out.
326b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman      OrigCallInst &= (63 << 26) | 3;
327892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner      // Fill in the new target.
328b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman      OrigCallInst |= (Offset & ((1 << 24)-1)) << 2;
329892afa9556eabf358ef632f1be0bde1587b3d610Chris Lattner      // Replace the call.
330b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman      *OrigCallAddr = OrigCallInst;
331e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner    }
332e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  }
333b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman
334b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Assert that we are coming from a stub that was created with our
335b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // emitFunctionStub.
33606abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  if ((*StubCallAddr >> 26) == 18)
33706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    StubCallAddr -= 3;
33806abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  else {
339b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  assert((*StubCallAddr >> 26) == 19 && "Call in stub is not indirect!");
34006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman    StubCallAddr -= is64Bit ? 9 : 6;
34106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  }
342e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
343e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  // Rewrite the stub with an unconditional branch to the target, for any users
344e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  // who took the address of the stub.
34506abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit);
34613c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin  sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4);
347e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
348b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // Put the address of the target function to call and the address to return to
349b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // after calling the target function in a place that is easy to get on the
350b3f70d7d556913126e4066d61328b701ce59c55aNate Begeman  // stack after we restore all regs.
35106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  return Target;
352e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner}
3539cd5e7a47836a6be3d2c274a5b6b019aaad106ceAnton Korobeynikov}
354e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
355e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
356e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
357b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha BrukmanTargetJITInfo::LazyResolverFn
35821e463b2bf864671a87ebe386cb100ef9349a540Nate BegemanPPCJITInfo::getLazyResolverFunction(JITCompilerFn Fn) {
359e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner  JITCompilerFunction = Fn;
36006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  return is64Bit ? PPC64CompilationCallback : PPC32CompilationCallback;
361e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner}
362e61198b3233f0c46900ced6d856534b11bd3d9f2Chris Lattner
363108c838093704650378b194fe9afc5ebb9e91455Jeffrey YasskinTargetJITInfo::StubLayout PPCJITInfo::getStubLayout() {
364108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // The stub contains up to 10 4-byte instructions, aligned at 4 bytes: 3
365108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // instructions to save the caller's address if this is a lazy-compilation
366108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // stub, plus a 1-, 4-, or 7-instruction sequence to load an arbitrary address
367108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  // into a register and jump through it.
368108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  StubLayout Result = {10*4, 4};
369108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  return Result;
370108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin}
371108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin
372496cf2308acf4bb719a015517f27dff10db7de49Rafael Espindola#if (defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)) && \
373496cf2308acf4bb719a015517f27dff10db7de49Rafael Espindoladefined(__APPLE__)
3741910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattnerextern "C" void sys_icache_invalidate(const void *Addr, size_t len);
3751910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner#endif
3761910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner
37751cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffrayvoid *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
378a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes                                   JITCodeEmitter &JCE) {
3799b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  // If this is just a call to an external function, emit a branch instead of a
3809b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  // call.  The code is the same except for one bit of the last instruction.
38106abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  if (Fn != (void*)(intptr_t)PPC32CompilationCallback &&
38206abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman      Fn != (void*)(intptr_t)PPC64CompilationCallback) {
383108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    void *Addr = (void*)JCE.getCurrentPCValue();
384a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
385a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
386a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
387a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
388a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
389a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
390a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0);
391108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    EmitBranchToAt((intptr_t)Addr, (intptr_t)Fn, false, is64Bit);
392108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    sys::Memory::InvalidateInstructionCache(Addr, 7*4);
393108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    return Addr;
3949b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  }
3959b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
396108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  void *Addr = (void*)JCE.getCurrentPCValue();
39706abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  if (is64Bit) {
398a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0xf821ffb1);     // stdu r1,-80(r1)
399a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x7d6802a6);     // mflr r11
400a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0xf9610060);     // std r11, 96(r1)
401cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if (Subtarget.isDarwinABI()){
402a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x9421ffe0);     // stwu r1,-32(r1)
403a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x7d6802a6);     // mflr r11
404a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x91610028);     // stw r11, 40(r1)
4052fb813d70b8928f355b35f782889c55c1aa891efNicolas Geoffray  } else {
406a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x9421ffe0);     // stwu r1,-32(r1)
407a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x7d6802a6);     // mflr r11
408a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    JCE.emitWordBE(0x91610024);     // stw r11, 36(r1)
40906abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  }
410a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  intptr_t BranchAddr = (intptr_t)JCE.getCurrentPCValue();
411a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
412a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
413a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
414a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
415a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
416a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
417a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes  JCE.emitWordBE(0);
4181910e2f3ecec461d1eab8c44b16c977539080a6eChris Lattner  EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit);
419108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  sys::Memory::InvalidateInstructionCache(Addr, 10*4);
420108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin  return Addr;
4219b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner}
4229b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
4239b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
42421e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::relocate(void *Function, MachineRelocation *MR,
42521e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman                          unsigned NumRelocs, unsigned char* GOTBase) {
4269b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  for (unsigned i = 0; i != NumRelocs; ++i, ++MR) {
4279b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4;
4289b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    intptr_t ResultPtr = (intptr_t)MR->getResultPointer();
4299b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    switch ((PPC::RelocationType)MR->getRelocationType()) {
430c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown relocation type!");
4319b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    case PPC::reloc_pcrel_bx:
4329b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      // PC-relative relocation for b and bl instructions.
4339b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2;
4349b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) &&
4359b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner             "Relocation out of range!");
4369b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      *RelocPos |= (ResultPtr & ((1 << 24)-1))  << 2;
4379b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      break;
438f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng    case PPC::reloc_pcrel_bcx:
439f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      // PC-relative relocation for BLT,BLE,BEQ,BGE,BGT,BNE, or other
440f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      // bcx instructions.
441f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2;
442f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      assert(ResultPtr >= -(1 << 13) && ResultPtr < (1 << 13) &&
443f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng             "Relocation out of range!");
444f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      *RelocPos |= (ResultPtr & ((1 << 14)-1))  << 2;
445f141cc46faf6f0525f0baa10b6a6c976301874a5Evan Cheng      break;
4465efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner    case PPC::reloc_absolute_high:     // high bits of ref -> low 16 of instr
4473bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    case PPC::reloc_absolute_low: {    // low bits of ref  -> low 16 of instr
4489b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      ResultPtr += MR->getConstantVal();
4499b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
4505efb75daed48edfeb03ba62f3f0afe81b86f5d7fChris Lattner      // If this is a high-part access, get the high-part.
45194be248dbb2d2a44e8f4d47f161b93704d33d279Nate Begeman      if (MR->getRelocationType() == PPC::reloc_absolute_high) {
4529b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        // If the low part will have a carry (really a borrow) from the low
4539b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        // 16-bits into the high 16, add a bit to borrow from.
4549b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        if (((int)ResultPtr << 16) < 0)
4559b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner          ResultPtr += 1 << 16;
4569b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner        ResultPtr >>= 16;
4579b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      }
4589b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
4599b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      // Do the addition then mask, so the addition does not overflow the 16-bit
4609b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      // immediate section of the instruction.
4619b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      unsigned LowBits  = (*RelocPos + ResultPtr) & 65535;
4629b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      unsigned HighBits = *RelocPos & ~65535;
4639b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      *RelocPos = LowBits | HighBits;  // Slam into low 16-bits
4649b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner      break;
4659b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner    }
4663bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    case PPC::reloc_absolute_low_ix: {  // low bits of ref  -> low 14 of instr
4673bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      ResultPtr += MR->getConstantVal();
4683bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      // Do the addition then mask, so the addition does not overflow the 16-bit
4693bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      // immediate section of the instruction.
4703bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      unsigned LowBits  = (*RelocPos + ResultPtr) & 0xFFFC;
4713bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      unsigned HighBits = *RelocPos & 0xFFFF0003;
4723bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      *RelocPos = LowBits | HighBits;  // Slam into low 14-bits.
4733bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner      break;
4743bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    }
4753bc8a765a98015e6d55510b6ea6e387cbfd793cdChris Lattner    }
4769b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner  }
4779b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner}
4789b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner
47921e463b2bf864671a87ebe386cb100ef9349a540Nate Begemanvoid PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
48006abd22b1ad203103c1a07a030ebc5c1c4cfbb14Nate Begeman  EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit);
48113c10c4e49109054281a8e2c074f8c901ab0404aJeffrey Yasskin  sys::Memory::InvalidateInstructionCache(Old, 7*4);
4829b3d989cb7b3473fbb7f268dbc02ae32052a9cbbChris Lattner}
483