diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h index 142f0efbd3f..f7c9b0d0aba 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 688d4984c20..44e6638562c 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 &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 574c14e00c6..641e1a1205f 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(CV->getType())->getBitWidth() == 32); + + const ConstantInt *CI = dyn_cast(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 de3ff08ad2a..62b83030106 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 namespace llvm { class ARMTargetMachine; class ARMJITInfo : public TargetJITInfo { ARMTargetMachine &TM; + std::map 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::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; } }; }