PPCJITInfo.cpp revision 9b3d989cb7b3473fbb7f268dbc02ae32052a9cbb
1//===-- PPC32JITInfo.cpp - Implement the JIT interfaces for the PowerPC ---===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the JIT interfaces for the 32-bit PowerPC target. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "jit" 15#include "PPC32JITInfo.h" 16#include "PPC32Relocations.h" 17#include "llvm/CodeGen/MachineCodeEmitter.h" 18#include "llvm/Config/alloca.h" 19using namespace llvm; 20 21static TargetJITInfo::JITCompilerFn JITCompilerFunction; 22 23#define BUILD_ADDIS(RD,RS,IMM16) \ 24 ((15 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535)) 25#define BUILD_ORI(RD,RS,UIMM16) \ 26 ((24 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535)) 27#define BUILD_MTSPR(RS,SPR) \ 28 ((31 << 26) | ((RS) << 21) | ((SPR) << 16) | (467 << 1)) 29#define BUILD_BCCTRx(BO,BI,LINK) \ 30 ((19 << 26) | ((BO) << 21) | ((BI) << 16) | (528 << 1) | ((LINK) & 1)) 31 32// Pseudo-ops 33#define BUILD_LIS(RD,IMM16) BUILD_ADDIS(RD,0,IMM16) 34#define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9) 35#define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK) 36 37static void CompilationCallback() { 38 //JITCompilerFunction 39 assert(0 && "CompilationCallback not implemented yet!"); 40} 41 42 43TargetJITInfo::LazyResolverFn 44PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) { 45 return CompilationCallback; 46} 47 48static void EmitBranchToAt(void *At, void *To) { 49 intptr_t Addr = (intptr_t)To; 50 51 // FIXME: should special case the short branch case. 52 unsigned *AtI = (unsigned*)At; 53 54 AtI[0] = BUILD_LIS(12, Addr >> 16); // lis r12, hi16(address) 55 AtI[1] = BUILD_ORI(12, 12, Addr); // ori r12, r12, low16(address) 56 AtI[2] = BUILD_MTCTR(12); // mtctr r12 57 AtI[3] = BUILD_BCTR(0); // bctr 58} 59 60void *PPC32JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { 61 // If this is just a call to an external function, emit a branch instead of a 62 // call. The code is the same except for one bit of the last instruction. 63 if (Fn != CompilationCallback) { 64 MCE.startFunctionStub(4*4); 65 void *Addr = (void*)(intptr_t)MCE.getCurrentPCValue(); 66 MCE.emitWord(0); 67 MCE.emitWord(0); 68 MCE.emitWord(0); 69 MCE.emitWord(0); 70 EmitBranchToAt(Addr, Fn); 71 return MCE.finishFunctionStub(0); 72 } 73 74 MCE.startFunctionStub(4*4); 75 return MCE.finishFunctionStub(0); 76} 77 78 79void PPC32JITInfo::relocate(void *Function, MachineRelocation *MR, 80 unsigned NumRelocs) { 81 for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { 82 unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; 83 intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); 84 switch ((PPC::RelocationType)MR->getRelocationType()) { 85 default: assert(0 && "Unknown relocation type!"); 86 case PPC::reloc_pcrel_bx: 87 // PC-relative relocation for b and bl instructions. 88 ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; 89 assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) && 90 "Relocation out of range!"); 91 *RelocPos |= (ResultPtr & ((1 << 24)-1)) << 2; 92 break; 93 case PPC::reloc_absolute_loadhi: // Relocate high bits into addis 94 case PPC::reloc_absolute_la: // Relocate low bits into addi 95 ResultPtr += MR->getConstantVal(); 96 97 if (MR->getRelocationType() == PPC::reloc_absolute_loadhi) { 98 // If the low part will have a carry (really a borrow) from the low 99 // 16-bits into the high 16, add a bit to borrow from. 100 if (((int)ResultPtr << 16) < 0) 101 ResultPtr += 1 << 16; 102 ResultPtr >>= 16; 103 } 104 105 // Do the addition then mask, so the addition does not overflow the 16-bit 106 // immediate section of the instruction. 107 unsigned LowBits = (*RelocPos + ResultPtr) & 65535; 108 unsigned HighBits = *RelocPos & ~65535; 109 *RelocPos = LowBits | HighBits; // Slam into low 16-bits 110 break; 111 } 112 } 113} 114 115void PPC32JITInfo::replaceMachineCodeForFunction(void *Old, void *New) { 116 EmitBranchToAt(Old, New); 117} 118