aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetJITInfo.h9
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp9
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp26
-rw-r--r--lib/Target/ARM/ARMJITInfo.h25
4 files changed, 67 insertions, 2 deletions
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
index 142f0efbd3..f7c9b0d0ab 100644
--- a/include/llvm/Target/TargetJITInfo.h
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -107,6 +107,15 @@ namespace llvm {
// JIT to manage a GOT for it.
bool needsGOT() const { return useGOT; }
+ /// hasCustomConstantPool - Allows a target to specify that constant
+ /// pool address resolution is handled by the target.
+ virtual bool hasCustomConstantPool() const { return false; }
+
+ /// getCustomConstantPoolEntryAddress - When using a custom constant
+ /// pool, resolve a constant pool index to the address of where the
+ /// entry is stored.
+ virtual intptr_t getCustomConstantPoolEntryAddress(unsigned CPI) const
+ {return 0;}
protected:
bool useGOT;
};
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index 688d4984c2..44e6638562 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -1011,6 +1011,11 @@ void* JITEmitter::allocateSpace(intptr_t Size, unsigned Alignment) {
}
void JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
+ if (TheJIT->getJITInfo().hasCustomConstantPool()) {
+ DOUT << "JIT: Target has custom constant pool handling. Omitting standard "
+ "constant pool\n";
+ return;
+ }
const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
if (Constants.empty()) return;
@@ -1124,6 +1129,10 @@ void *JITEmitter::finishFunctionStub(const GlobalValue* F) {
// method.
//
intptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const {
+ if (TheJIT->getJITInfo().hasCustomConstantPool()) {
+ return TheJIT->getJITInfo().getCustomConstantPoolEntryAddress(ConstantNum);
+ }
+
assert(ConstantNum < ConstantPool->getConstants().size() &&
"Invalid ConstantPoolIndex!");
return (intptr_t)ConstantPoolBase +
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 574c14e00c..641e1a1205 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -19,6 +19,8 @@
#include "ARMRelocations.h"
#include "ARMSubtarget.h"
#include "ARMTargetMachine.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/PassManager.h"
#include "llvm/CodeGen/MachineCodeEmitter.h"
@@ -358,7 +360,29 @@ unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI,
}
void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
- // FIXME
+ unsigned CPID = MI.getOperand(0).getImm();
+ unsigned CPIndex = MI.getOperand(1).getIndex();
+ const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex];
+
+ //FIXME: Can we get these here?
+ assert (!MCPE.isMachineConstantPoolEntry());
+
+ const Constant *CV = MCPE.Val.ConstVal;
+ // FIXME: We can get other types here. Need to handle them.
+ // According to the constant island pass, everything is multiples,
+ // of 4-bytes in size, though, so that helps.
+ assert (CV->getType()->isInteger());
+ assert (cast<IntegerType>(CV->getType())->getBitWidth() == 32);
+
+ const ConstantInt *CI = dyn_cast<ConstantInt>(CV);
+ uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
+
+ DOUT << "Constant pool #" << CPID << ", value '" << Val << "' @ " <<
+ (void*)MCE.getCurrentPCValue() << "\n";
+
+ if (JTI)
+ JTI->mapCPIDtoAddress(CPID, MCE.getCurrentPCValue());
+ MCE.emitWordLE(Val);
}
void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
diff --git a/lib/Target/ARM/ARMJITInfo.h b/lib/Target/ARM/ARMJITInfo.h
index de3ff08ad2..62b8303010 100644
--- a/lib/Target/ARM/ARMJITInfo.h
+++ b/lib/Target/ARM/ARMJITInfo.h
@@ -15,14 +15,16 @@
#define ARMJITINFO_H
#include "llvm/Target/TargetJITInfo.h"
+#include <map>
namespace llvm {
class ARMTargetMachine;
class ARMJITInfo : public TargetJITInfo {
ARMTargetMachine &TM;
+ std::map<unsigned, intptr_t> CPIDtoAddressMap;
public:
- explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) {useGOT = 0;}
+ explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; }
/// replaceMachineCodeForFunction - Make it so that calling the function
/// whose machine code is at OLD turns into a call to NEW, perhaps by
@@ -45,6 +47,27 @@ 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; }
+
+ /// getCustomConstantPoolEntryAddress - The ARM target puts all constant
+ /// pool entries into constant islands. Resolve the constant pool index
+ /// into the address where the constant is stored.
+ virtual intptr_t getCustomConstantPoolEntryAddress(unsigned CPID) const
+ {
+ std::map<unsigned, intptr_t>::const_iterator elem;
+ elem = CPIDtoAddressMap.find(CPID);
+ assert (elem != CPIDtoAddressMap.end());
+ return elem->second;
+ }
+
+ /// mapCPIDtoAddress - Map a Constant Pool Index (CPID) to the address
+ /// where its associated value is stored. When relocations are processed,
+ /// this value will be used to resolve references to the constant.
+ void mapCPIDtoAddress(unsigned CPID, intptr_t address)
+ { CPIDtoAddressMap[CPID] = address; }
};
}