summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-11-04 00:50:32 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-11-04 00:50:32 +0000
commit25e04788bfddc54dde7bed65302146b46089a166 (patch)
tree078176efdcd15d4eec35030cc86f27fa6abd71ed
parentf6503a031e2459be63ebc688d32577d9f70da354 (diff)
downloadllvm-25e04788bfddc54dde7bed65302146b46089a166.tar.gz
llvm-25e04788bfddc54dde7bed65302146b46089a166.tar.bz2
llvm-25e04788bfddc54dde7bed65302146b46089a166.tar.xz
Handle ARM machine constantpool entries.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58671 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp16
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.cpp6
-rw-r--r--lib/Target/ARM/ARMJITInfo.cpp33
-rw-r--r--lib/Target/ARM/ARMJITInfo.h38
-rw-r--r--lib/Target/ARM/ARMRelocations.h4
5 files changed, 77 insertions, 20 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 53385d945e..68a36aee16 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -158,7 +158,7 @@ bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData();
JTI = ((ARMTargetMachine&)MF.getTarget()).getJITInfo();
MCPEs = &MF.getConstantPool()->getConstants();
- JTI->ResizeConstPoolMap(MCPEs->size());
+ JTI->Initialize(MCPEs);
do {
DOUT << "JITTing function '" << MF.getFunction()->getName() << "'\n";
@@ -257,7 +257,7 @@ void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB) {
}
void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
- DOUT << "JIT: " << "0x" << MCE.getCurrentPCValue() << ":\t" << MI;
+ DOUT << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI;
NumEmitted++; // Keep track of the # of mi's emitted
if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo)
@@ -286,8 +286,10 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
GlobalValue *GV = ACPV->getGV();
if (GV) {
assert(!ACPV->isStub() && "Don't know how to deal this yet!");
- emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
- } else {
+ MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
+ ARM::reloc_arm_machine_cp_entry,
+ GV, CPIndex, false));
+ } else {
assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
}
@@ -320,6 +322,12 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
emitConstPoolInstruction(MI);
break;
case ARM::PICADD: {
+ // Remember of the address of the PC label for relocation later.
+ const MachineOperand &MO2 = MI.getOperand(2);
+ DOUT << "\t** LPC" << MO2.getImm() << " @ "
+ << (void*)MCE.getCurrentPCValue() << '\n';
+ JTI->addPCLabelAddr(MO2.getImm(), MCE.getCurrentPCValue());
+
// PICADD is just an add instruction that implicitly read pc.
unsigned Binary = getBinaryCodeForInstr(MI);
const TargetInstrDesc &TID = MI.getDesc();
diff --git a/lib/Target/ARM/ARMConstantPoolValue.cpp b/lib/Target/ARM/ARMConstantPoolValue.cpp
index 002ebf109f..c95a6e6b47 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.cpp
+++ b/lib/Target/ARM/ARMConstantPoolValue.cpp
@@ -93,10 +93,8 @@ void ARMConstantPoolValue::print(raw_ostream &O) const {
else if (isStub()) O << "$stub";
if (Modifier) O << "(" << Modifier << ")";
if (PCAdjust != 0) {
- O << "-(LPIC" << LabelId << "+"
- << (unsigned)PCAdjust;
- if (AddCurrentAddress)
- O << "-.";
+ O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
+ if (AddCurrentAddress) O << "-.";
O << ")";
}
}
diff --git a/lib/Target/ARM/ARMJITInfo.cpp b/lib/Target/ARM/ARMJITInfo.cpp
index 6a2c253ff1..2f04d0b4e8 100644
--- a/lib/Target/ARM/ARMJITInfo.cpp
+++ b/lib/Target/ARM/ARMJITInfo.cpp
@@ -13,6 +13,7 @@
#define DEBUG_TYPE "jit"
#include "ARMJITInfo.h"
+#include "ARMConstantPoolValue.h"
#include "ARMRelocations.h"
#include "ARMSubtarget.h"
#include "llvm/Function.h"
@@ -167,6 +168,25 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
return MCE.finishFunctionStub(F);
}
+intptr_t ARMJITInfo::resolveRelocationAddr(MachineRelocation *MR) const {
+ ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType();
+ if (RT == ARM::reloc_arm_cp_entry)
+ return getConstantPoolEntryAddr(MR->getConstantPoolIndex());
+ else if (RT == ARM::reloc_arm_machine_cp_entry) {
+ const MachineConstantPoolEntry &MCPE = (*MCPEs)[MR->getConstantVal()];
+ assert(MCPE.isMachineConstantPoolEntry() &&
+ "Expecting a machine constant pool entry!");
+ ARMConstantPoolValue *ACPV =
+ static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
+ assert((!ACPV->hasModifier() && !ACPV->mustAddCurrentAddress()) &&
+ "Can't handle this machine constant pool entry yet!");
+ intptr_t Addr = (intptr_t)(MR->getResultPointer());
+ Addr -= getPCLabelAddr(ACPV->getLabelId()) + ACPV->getPCAdjustment();
+ return Addr;
+ }
+ return (intptr_t)(MR->getResultPointer());
+}
+
/// relocate - Before the JIT can run a block of code that has been emitted,
/// it must rewrite the code to contain the actual addresses of any
/// referenced global symbols.
@@ -174,12 +194,9 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
unsigned NumRelocs, unsigned char* GOTBase) {
for (unsigned i = 0; i != NumRelocs; ++i, ++MR) {
void *RelocPos = (char*)Function + MR->getMachineCodeOffset();
- ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType();
// If this is a constpool relocation, get the address of the
// constpool_entry instruction.
- intptr_t ResultPtr = (RT == ARM::reloc_arm_cp_entry)
- ? getConstantPoolEntryAddr(MR->getConstantPoolIndex())
- : (intptr_t)MR->getResultPointer();
+ intptr_t ResultPtr = resolveRelocationAddr(MR);
switch ((ARM::RelocationType)MR->getRelocationType()) {
case ARM::reloc_arm_cp_entry:
case ARM::reloc_arm_relative: {
@@ -190,18 +207,20 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
if (ResultPtr >= 0)
*((unsigned*)RelocPos) |= 1 << 23;
else {
- // otherwise, obtain the absolute value and set
+ // Otherwise, obtain the absolute value and set
// bit U(23) to 0.
ResultPtr *= -1;
*((unsigned*)RelocPos) &= 0xFF7FFFFF;
}
- // set the immed value calculated
+ // Set the immed value calculated.
*((unsigned*)RelocPos) |= (unsigned)ResultPtr;
- // set register Rn to PC
+ // Set register Rn to PC.
*((unsigned*)RelocPos) |= 0xF << 16;
break;
}
+ case ARM::reloc_arm_machine_cp_entry:
case ARM::reloc_arm_absolute: {
+ // These addresses have already been resolved.
*((unsigned*)RelocPos) += (unsigned)ResultPtr;
break;
}
diff --git a/lib/Target/ARM/ARMJITInfo.h b/lib/Target/ARM/ARMJITInfo.h
index cdcd1ad1d6..ba8768aec4 100644
--- a/lib/Target/ARM/ARMJITInfo.h
+++ b/lib/Target/ARM/ARMJITInfo.h
@@ -15,6 +15,8 @@
#define ARMJITINFO_H
#include "llvm/Target/TargetJITInfo.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
@@ -23,10 +25,17 @@ namespace llvm {
class ARMJITInfo : public TargetJITInfo {
ARMTargetMachine &TM;
+ // MCPEs - List of the constant pool entries for the current machine
+ // function that's being processed.
+ const std::vector<MachineConstantPoolEntry> *MCPEs;
+
// ConstPoolId2AddrMap - A map from constant pool ids to the corresponding
// CONSTPOOL_ENTRY addresses.
SmallVector<intptr_t, 32> ConstPoolId2AddrMap;
+ // PCLabelMap - A map from PC labels to addresses.
+ DenseMap<unsigned, intptr_t> PCLabelMap;
+
public:
explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; }
@@ -51,15 +60,16 @@ namespace llvm {
/// referenced global symbols.
virtual void relocate(void *Function, MachineRelocation *MR,
unsigned NumRelocs, unsigned char* GOTBase);
-
+
/// hasCustomConstantPool - Allows a target to specify that constant
/// pool address resolution is handled by the target.
virtual bool hasCustomConstantPool() const { return true; }
- /// ResizeConstPoolMap - Resize constant pool ids to CONSTPOOL_ENTRY
- /// addresses map.
- void ResizeConstPoolMap(unsigned Size) {
- ConstPoolId2AddrMap.resize(Size);
+ /// Initialize - Initialize internal stage. Get the list of constant pool
+ /// Resize constant pool ids to CONSTPOOL_ENTRY addresses map.
+ void Initialize(const std::vector<MachineConstantPoolEntry> *mcpes) {
+ MCPEs = mcpes;
+ ConstPoolId2AddrMap.resize(MCPEs->size());
}
/// getConstantPoolEntryAddr - The ARM target puts all constant
@@ -77,6 +87,24 @@ namespace llvm {
assert(CPI < ConstPoolId2AddrMap.size());
ConstPoolId2AddrMap[CPI] = Addr;
}
+
+ /// getPCLabelAddr - Retrieve the address of the PC label of the specified id.
+ intptr_t getPCLabelAddr(unsigned Id) const {
+ DenseMap<unsigned, intptr_t>::const_iterator I = PCLabelMap.find(Id);
+ assert(I != PCLabelMap.end());
+ return I->second;
+ }
+
+ /// addPCLabelAddr - Remember the address of the specified PC label.
+ void addPCLabelAddr(unsigned Id, intptr_t Addr) {
+ PCLabelMap.insert(std::make_pair(Id, Addr));
+ }
+
+ private:
+ /// resolveRelocationAddr - Resolve the resulting address of the relocation
+ /// if it's not already solved. Constantpool entries must be resolved by
+ /// ARM target.
+ intptr_t resolveRelocationAddr(MachineRelocation *MR) const;
};
}
diff --git a/lib/Target/ARM/ARMRelocations.h b/lib/Target/ARM/ARMRelocations.h
index 93101a6179..2c1a98990a 100644
--- a/lib/Target/ARM/ARMRelocations.h
+++ b/lib/Target/ARM/ARMRelocations.h
@@ -31,6 +31,10 @@ namespace llvm {
// addresses are kept locally in a map.
reloc_arm_cp_entry,
+ // reloc_arm_machine_cp_entry - Relocation of a ARM machine constantpool
+ // entry.
+ reloc_arm_machine_cp_entry,
+
// reloc_arm_branch - Branch address relocation.
reloc_arm_branch
};