[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp PPC32Relocations.h PPC32JITInfo.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Nov 24 14:30:23 PST 2004
Changes in directory llvm/lib/Target/PowerPC:
PPC32CodeEmitter.cpp updated: 1.24 -> 1.25
PPC32Relocations.h updated: 1.1 -> 1.2
PPC32JITInfo.cpp updated: 1.9 -> 1.10
---
Log message:
* 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 :)
---
Diffs of the changes: (+65 -18)
Index: llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp
diff -u llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp:1.24 llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp:1.25
--- llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp:1.24 Tue Nov 23 20:03:44 2004
+++ llvm/lib/Target/PowerPC/PPC32CodeEmitter.cpp Wed Nov 24 16:30:08 2004
@@ -189,21 +189,36 @@
} else if (MO.isImmediate()) {
rv = MO.getImmedValue();
} else if (MO.isGlobalAddress()) {
+ GlobalValue *GV = MO.getGlobal();
unsigned Reloc = 0;
int Offset = 0;
if (MI.getOpcode() == PPC::CALLpcrel)
Reloc = PPC::reloc_pcrel_bx;
- else if (MI.getOpcode() == PPC::LOADHiAddr) {
+ else {
assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
- Reloc = PPC::reloc_absolute_loadhi;
Offset = -((intptr_t)MovePCtoLROffset+4);
- } else if (MI.getOpcode() == PPC::LA || MI.getOpcode() == PPC::LWZ ||
- MI.getOpcode() == PPC::LFS || MI.getOpcode() == PPC::LFD) {
- assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
- Reloc = PPC::reloc_absolute_la;
- Offset = -((intptr_t)MovePCtoLROffset+4);
- } else {
- assert(0 && "Unknown instruction for relocation!");
+
+ if (MI.getOpcode() == PPC::LOADHiAddr) {
+ if (GV->hasWeakLinkage() || GV->isExternal() || isa<Function>(GV))
+ Reloc = PPC::reloc_absolute_ptr_high; // Pointer to stub
+ else
+ Reloc = PPC::reloc_absolute_high; // Pointer to symbol
+
+ } else if (MI.getOpcode() == PPC::LA) {
+ assert(!(GV->hasWeakLinkage() || GV->isExternal() || isa<Function>(GV))
+ && "Something in the ISEL changed\n");
+
+ Reloc = PPC::reloc_absolute_low;
+ } else if (MI.getOpcode() == PPC::LWZ) {
+ Reloc = PPC::reloc_absolute_ptr_low;
+
+ assert((GV->hasWeakLinkage() || GV->isExternal() || isa<Function>(GV))&&
+ "Something in the ISEL changed\n");
+ } else {
+ // These don't show up for global value references AFAIK, only for
+ // constant pool refs: PPC::LFS, PPC::LFD
+ assert(0 && "Unknown instruction for relocation!");
+ }
}
MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
Reloc, MO.getGlobal(), Offset));
Index: llvm/lib/Target/PowerPC/PPC32Relocations.h
diff -u llvm/lib/Target/PowerPC/PPC32Relocations.h:1.1 llvm/lib/Target/PowerPC/PPC32Relocations.h:1.2
--- llvm/lib/Target/PowerPC/PPC32Relocations.h:1.1 Mon Nov 22 23:57:38 2004
+++ llvm/lib/Target/PowerPC/PPC32Relocations.h Wed Nov 24 16:30:08 2004
@@ -22,15 +22,29 @@
// reloc_pcrel_bx - PC relative relocation, for the b or bl instructions.
reloc_pcrel_bx,
- // reloc_absolute_loadhi - Absolute relocation, for the loadhi instruction
+ // reloc_absolute_high - Absolute relocation, for the loadhi instruction
// (which is really addis). Add the high 16-bits of the specified global
- // address into the immediate field of the addis.
- reloc_absolute_loadhi,
+ // address into the low 16-bits of the instruction.
+ reloc_absolute_high,
- // reloc_absolute_la - Absolute relocation, for the la instruction (which
+ // reloc_absolute_low - Absolute relocation, for the la instruction (which
// is really an addi). Add the low 16-bits of teh specified global
- // address into the immediate field of the addi.
- reloc_absolute_la,
+ // address into the low 16-bits of the instruction.
+ reloc_absolute_low,
+
+ // reloc_absolute_ptr_high - Absolute relocation for references to lazy
+ // pointer stubs. In this case, the relocated instruction should be
+ // relocated to point to a POINTER to the indicated global. The low-16
+ // bits of the instruction are rewritten with the high 16-bits of the
+ // address of the pointer.
+ reloc_absolute_ptr_high,
+
+ // reloc_absolute_ptr_low - Absolute relocation for references to lazy
+ // pointer stubs. In this case, the relocated instruction should be
+ // relocated to point to a POINTER to the indicated global. The low-16
+ // bits of the instruction are rewritten with the low 16-bits of the
+ // address of the pointer.
+ reloc_absolute_ptr_low,
};
}
}
Index: llvm/lib/Target/PowerPC/PPC32JITInfo.cpp
diff -u llvm/lib/Target/PowerPC/PPC32JITInfo.cpp:1.9 llvm/lib/Target/PowerPC/PPC32JITInfo.cpp:1.10
--- llvm/lib/Target/PowerPC/PPC32JITInfo.cpp:1.9 Wed Nov 24 15:01:46 2004
+++ llvm/lib/Target/PowerPC/PPC32JITInfo.cpp Wed Nov 24 16:30:08 2004
@@ -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 @@
"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)
More information about the llvm-commits
mailing list