summaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCJITInfo.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-11-24 22:30:08 +0000
committerChris Lattner <sabre@nondot.org>2004-11-24 22:30:08 +0000
commit5efb75daed48edfeb03ba62f3f0afe81b86f5d7f (patch)
tree7c99314e1f98ec1f73650c060d51ed9cf85133fd /lib/Target/PowerPC/PPCJITInfo.cpp
parent53e4aa57c6bdc9bc99d7d8843e1b2b693a16fbfa (diff)
downloadllvm-5efb75daed48edfeb03ba62f3f0afe81b86f5d7f.tar.gz
llvm-5efb75daed48edfeb03ba62f3f0afe81b86f5d7f.tar.bz2
llvm-5efb75daed48edfeb03ba62f3f0afe81b86f5d7f.tar.xz
* Rename existing relocations to be more specific
* Add relocations for refernces to non-lazy darwin stubs and implement them correctly. With this change, we can correctly references external globals, and now all but two UnitTests and all but 1 Regression/C tests pass. More importantly, bugpoint-jit will start giving us useful testcases, instead of always telling us that references to external globals don't work :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18222 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCJITInfo.cpp')
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp
index 5ee16178c6..15b2aa1bdd 100644
--- a/lib/Target/PowerPC/PPCJITInfo.cpp
+++ b/lib/Target/PowerPC/PPCJITInfo.cpp
@@ -16,6 +16,7 @@
#include "PPC32Relocations.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/Config/alloca.h"
+#include <map>
using namespace llvm;
static TargetJITInfo::JITCompilerFn JITCompilerFunction;
@@ -195,11 +196,28 @@ void PPC32JITInfo::relocate(void *Function, MachineRelocation *MR,
"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
+
+ case PPC::reloc_absolute_ptr_high: // Pointer relocations.
+ case PPC::reloc_absolute_ptr_low: {
+ // Pointer relocations are used for the PPC external stubs and lazy
+ // resolver pointers that the Darwin ABI likes to use. Basically, the
+ // address of the global is actually stored in memory, and the address of
+ // the pointer is relocated into instructions instead of the pointer
+ // itself. Because we have to keep the mapping anyway, we just return
+ // pointers to the values in the map as our new location.
+ static std::map<void*,void*> Pointers;
+ void *&Ptr = Pointers[(void*)ResultPtr];
+ Ptr = (void*)ResultPtr;
+ ResultPtr = (intptr_t)&Ptr;
+ }
+ // FALL THROUGH
+ case PPC::reloc_absolute_high: // high bits of ref -> low 16 of instr
+ case PPC::reloc_absolute_low: // low bits of ref -> low 16 of instr
ResultPtr += MR->getConstantVal();
- if (MR->getRelocationType() == PPC::reloc_absolute_loadhi) {
+ // If this is a high-part access, get the high-part.
+ if (MR->getRelocationType() == PPC::reloc_absolute_high ||
+ MR->getRelocationType() == PPC::reloc_absolute_ptr_high) {
// 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)