aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC/PPCJITInfo.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-11-23 06:02:06 +0000
committerChris Lattner <sabre@nondot.org>2004-11-23 06:02:06 +0000
commit9b3d989cb7b3473fbb7f268dbc02ae32052a9cbb (patch)
tree9002f809474e7f4592c4947e883c43a033819120 /lib/Target/PowerPC/PPCJITInfo.cpp
parente94c517bb52095f1ad070bb029617d532af405b8 (diff)
downloadexternal_llvm-9b3d989cb7b3473fbb7f268dbc02ae32052a9cbb.zip
external_llvm-9b3d989cb7b3473fbb7f268dbc02ae32052a9cbb.tar.gz
external_llvm-9b3d989cb7b3473fbb7f268dbc02ae32052a9cbb.tar.bz2
Initial implementation of the JIT interfaces. Relocation is done and stubs
for external functions work. CompilationCallback has not been written, and stubs for internal functions are not generated yet. This means you can call printf and exit, and use global variables, but cannot call functions local to a module yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18145 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCJITInfo.cpp')
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp
new file mode 100644
index 0000000..b86ff16
--- /dev/null
+++ b/lib/Target/PowerPC/PPCJITInfo.cpp
@@ -0,0 +1,117 @@
+//===-- PPC32JITInfo.cpp - Implement the JIT interfaces for the PowerPC ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the JIT interfaces for the 32-bit PowerPC target.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "jit"
+#include "PPC32JITInfo.h"
+#include "PPC32Relocations.h"
+#include "llvm/CodeGen/MachineCodeEmitter.h"
+#include "llvm/Config/alloca.h"
+using namespace llvm;
+
+static TargetJITInfo::JITCompilerFn JITCompilerFunction;
+
+#define BUILD_ADDIS(RD,RS,IMM16) \
+ ((15 << 26) | ((RD) << 21) | ((RS) << 16) | ((IMM16) & 65535))
+#define BUILD_ORI(RD,RS,UIMM16) \
+ ((24 << 26) | ((RS) << 21) | ((RD) << 16) | ((UIMM16) & 65535))
+#define BUILD_MTSPR(RS,SPR) \
+ ((31 << 26) | ((RS) << 21) | ((SPR) << 16) | (467 << 1))
+#define BUILD_BCCTRx(BO,BI,LINK) \
+ ((19 << 26) | ((BO) << 21) | ((BI) << 16) | (528 << 1) | ((LINK) & 1))
+
+// Pseudo-ops
+#define BUILD_LIS(RD,IMM16) BUILD_ADDIS(RD,0,IMM16)
+#define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9)
+#define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK)
+
+static void CompilationCallback() {
+ //JITCompilerFunction
+ assert(0 && "CompilationCallback not implemented yet!");
+}
+
+
+TargetJITInfo::LazyResolverFn
+PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) {
+ return CompilationCallback;
+}
+
+static void EmitBranchToAt(void *At, void *To) {
+ intptr_t Addr = (intptr_t)To;
+
+ // FIXME: should special case the short branch case.
+ unsigned *AtI = (unsigned*)At;
+
+ AtI[0] = BUILD_LIS(12, Addr >> 16); // lis r12, hi16(address)
+ AtI[1] = BUILD_ORI(12, 12, Addr); // ori r12, r12, low16(address)
+ AtI[2] = BUILD_MTCTR(12); // mtctr r12
+ AtI[3] = BUILD_BCTR(0); // bctr
+}
+
+void *PPC32JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+ // If this is just a call to an external function, emit a branch instead of a
+ // call. The code is the same except for one bit of the last instruction.
+ if (Fn != CompilationCallback) {
+ MCE.startFunctionStub(4*4);
+ void *Addr = (void*)(intptr_t)MCE.getCurrentPCValue();
+ MCE.emitWord(0);
+ MCE.emitWord(0);
+ MCE.emitWord(0);
+ MCE.emitWord(0);
+ EmitBranchToAt(Addr, Fn);
+ return MCE.finishFunctionStub(0);
+ }
+
+ MCE.startFunctionStub(4*4);
+ return MCE.finishFunctionStub(0);
+}
+
+
+void PPC32JITInfo::relocate(void *Function, MachineRelocation *MR,
+ unsigned NumRelocs) {
+ for (unsigned i = 0; i != NumRelocs; ++i, ++MR) {
+ unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4;
+ intptr_t ResultPtr = (intptr_t)MR->getResultPointer();
+ switch ((PPC::RelocationType)MR->getRelocationType()) {
+ default: assert(0 && "Unknown relocation type!");
+ case PPC::reloc_pcrel_bx:
+ // PC-relative relocation for b and bl instructions.
+ ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2;
+ assert(ResultPtr >= -(1 << 23) && ResultPtr < (1 << 23) &&
+ "Relocation out of range!");
+ *RelocPos |= (ResultPtr & ((1 << 24)-1)) << 2;
+ break;
+ case PPC::reloc_absolute_loadhi: // Relocate high bits into addis
+ case PPC::reloc_absolute_la: // Relocate low bits into addi
+ ResultPtr += MR->getConstantVal();
+
+ if (MR->getRelocationType() == PPC::reloc_absolute_loadhi) {
+ // If the low part will have a carry (really a borrow) from the low
+ // 16-bits into the high 16, add a bit to borrow from.
+ if (((int)ResultPtr << 16) < 0)
+ ResultPtr += 1 << 16;
+ ResultPtr >>= 16;
+ }
+
+ // Do the addition then mask, so the addition does not overflow the 16-bit
+ // immediate section of the instruction.
+ unsigned LowBits = (*RelocPos + ResultPtr) & 65535;
+ unsigned HighBits = *RelocPos & ~65535;
+ *RelocPos = LowBits | HighBits; // Slam into low 16-bits
+ break;
+ }
+ }
+}
+
+void PPC32JITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
+ EmitBranchToAt(Old, New);
+}