Correct way to handle CONSTPOOL_ENTRY instructions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58409 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2008-10-29 23:55:43 +00:00
parent 5be59eace5
commit 0f282439be
4 changed files with 78 additions and 33 deletions

View File

@ -12,9 +12,10 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define DEBUG_TYPE "arm-emitter" #define DEBUG_TYPE "jit"
#include "ARM.h" #include "ARM.h"
#include "ARMAddressingModes.h" #include "ARMAddressingModes.h"
#include "ARMConstantPoolValue.h"
#include "ARMInstrInfo.h" #include "ARMInstrInfo.h"
#include "ARMRelocations.h" #include "ARMRelocations.h"
#include "ARMSubtarget.h" #include "ARMSubtarget.h"
@ -192,7 +193,7 @@ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
else if (MO.isSymbol()) else if (MO.isSymbol())
emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_relative); emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_relative);
else if (MO.isCPI()) else if (MO.isCPI())
emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_relative); emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
else if (MO.isJTI()) else if (MO.isJTI())
emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative); emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
else if (MO.isMBB()) else if (MO.isMBB())
@ -226,8 +227,9 @@ void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc, void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
int Disp /* = 0 */, int Disp /* = 0 */,
unsigned PCAdj /* = 0 */) { unsigned PCAdj /* = 0 */) {
// Tell JIT emitter we'll resolve the address.
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
Reloc, CPI, PCAdj)); Reloc, CPI, PCAdj, true));
} }
/// emitJumpTableAddress - Arrange for the address of a jump table to /// emitJumpTableAddress - Arrange for the address of a jump table to
@ -246,7 +248,7 @@ void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB) {
} }
void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
DOUT << MI; DOUT << "JIT: " << "0x" << MCE.getCurrentPCValue() << ":\t" << MI;
NumEmitted++; // Keep track of the # of mi's emitted NumEmitted++; // Keep track of the # of mi's emitted
if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo) if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo)
@ -360,29 +362,47 @@ unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI,
} }
void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
unsigned CPID = MI.getOperand(0).getImm(); unsigned CPI = MI.getOperand(0).getImm();
unsigned CPIndex = MI.getOperand(1).getIndex(); unsigned CPIndex = MI.getOperand(1).getIndex();
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex]; const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex];
//FIXME: Can we get these here? // Remember the CONSTPOOL_ENTRY address for later relocation.
assert (!MCPE.isMachineConstantPoolEntry()); JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());
const Constant *CV = MCPE.Val.ConstVal; // Emit constpool island entry. In most cases, the actual values will be
// FIXME: We can get other types here. Need to handle them. // resolved and relocated after code emission.
// According to the constant island pass, everything is multiples, if (MCPE.isMachineConstantPoolEntry()) {
// of 4-bytes in size, though, so that helps. ARMConstantPoolValue *ACPV =
assert (CV->getType()->isInteger()); static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
assert (cast<IntegerType>(CV->getType())->getBitWidth() == 32);
const ConstantInt *CI = dyn_cast<ConstantInt>(CV); DOUT << "\t** ARM constant pool #" << CPI << ", ' @ "
uint32_t Val = *(uint32_t*)CI->getValue().getRawData(); << (void*)MCE.getCurrentPCValue() << *ACPV << '\n';
DOUT << "Constant pool #" << CPID << ", value '" << Val << "' @ " << GlobalValue *GV = ACPV->getGV();
(void*)MCE.getCurrentPCValue() << "\n"; if (GV) {
assert(!ACPV->isStub() && "Don't know how to deal this yet!");
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
} else {
assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
}
MCE.emitWordLE(0);
} else {
Constant *CV = MCPE.Val.ConstVal;
if (JTI) DOUT << "\t** Constant pool #" << CPI << ", ' @ "
JTI->mapCPIDtoAddress(CPID, MCE.getCurrentPCValue()); << (void*)MCE.getCurrentPCValue() << *CV << '\n';
MCE.emitWordLE(Val);
if (GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
MCE.emitWordLE(0);
} else {
abort(); // FIXME: Is this right?
const ConstantInt *CI = dyn_cast<ConstantInt>(CV);
uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
MCE.emitWordLE(Val);
}
}
} }
void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) { void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {

View File

@ -174,8 +174,14 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
unsigned NumRelocs, unsigned char* GOTBase) { unsigned NumRelocs, unsigned char* GOTBase) {
for (unsigned i = 0; i != NumRelocs; ++i, ++MR) { for (unsigned i = 0; i != NumRelocs; ++i, ++MR) {
void *RelocPos = (char*)Function + MR->getMachineCodeOffset(); void *RelocPos = (char*)Function + MR->getMachineCodeOffset();
intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); 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();
switch ((ARM::RelocationType)MR->getRelocationType()) { switch ((ARM::RelocationType)MR->getRelocationType()) {
case ARM::reloc_arm_cp_entry:
case ARM::reloc_arm_relative: { case ARM::reloc_arm_relative: {
// It is necessary to calculate the correct PC relative value. We // It is necessary to calculate the correct PC relative value. We
// subtract the base addr from the target addr to form a byte offset. // subtract the base addr from the target addr to form a byte offset.
@ -195,6 +201,10 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
*((unsigned*)RelocPos) |= 0xF << 16; *((unsigned*)RelocPos) |= 0xF << 16;
break; break;
} }
case ARM::reloc_arm_absolute: {
*((unsigned*)RelocPos) += (unsigned)ResultPtr;
break;
}
case ARM::reloc_arm_branch: { case ARM::reloc_arm_branch: {
// It is necessary to calculate the correct value of signed_immed_24 // It is necessary to calculate the correct value of signed_immed_24
// field. We subtract the base addr from the target addr to form a // field. We subtract the base addr from the target addr to form a

View File

@ -22,7 +22,11 @@ namespace llvm {
class ARMJITInfo : public TargetJITInfo { class ARMJITInfo : public TargetJITInfo {
ARMTargetMachine &TM; ARMTargetMachine &TM;
std::map<unsigned, intptr_t> CPIDtoAddressMap;
// ConstPoolId2AddrMap - A map from constant pool ids to the corresponding
// CONSTPOOL_ENTRY addresses.
std::map<unsigned, intptr_t> ConstPoolId2AddrMap;
public: public:
explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; } explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; }
@ -52,22 +56,22 @@ namespace llvm {
/// pool address resolution is handled by the target. /// pool address resolution is handled by the target.
virtual bool hasCustomConstantPool() const { return true; } virtual bool hasCustomConstantPool() const { return true; }
/// getCustomConstantPoolEntryAddress - The ARM target puts all constant /// getConstantPoolEntryAddr - The ARM target puts all constant
/// pool entries into constant islands. Resolve the constant pool index /// pool entries into constant islands. Resolve the constant pool index
/// into the address where the constant is stored. /// into the address where the constant is stored.
virtual intptr_t getCustomConstantPoolEntryAddress(unsigned CPID) const virtual intptr_t getConstantPoolEntryAddr(unsigned CPID) const {
{ std::map<unsigned, intptr_t>::const_iterator I
std::map<unsigned, intptr_t>::const_iterator elem; = ConstPoolId2AddrMap.find(CPID);
elem = CPIDtoAddressMap.find(CPID); assert(I != ConstPoolId2AddrMap.end() && "Missing constpool_entry?");
assert (elem != CPIDtoAddressMap.end()); return I->second;
return elem->second; }
}
/// mapCPIDtoAddress - Map a Constant Pool Index (CPID) to the address /// addConstantPoolEntryAddr - Map a Constant Pool Index (CPID) to the address
/// where its associated value is stored. When relocations are processed, /// where its associated value is stored. When relocations are processed,
/// this value will be used to resolve references to the constant. /// this value will be used to resolve references to the constant.
void mapCPIDtoAddress(unsigned CPID, intptr_t address) void addConstantPoolEntryAddr(unsigned CPID, intptr_t Addr) {
{ CPIDtoAddressMap[CPID] = address; } ConstPoolId2AddrMap[CPID] = Addr;
}
}; };
} }

View File

@ -19,8 +19,19 @@
namespace llvm { namespace llvm {
namespace ARM { namespace ARM {
enum RelocationType { enum RelocationType {
// reloc_arm_absolute - Absolute relocation, just add the relocated value
// to the value already in memory.
reloc_arm_absolute,
// reloc_arm_relative - PC relative relocation, add the relocated value to
// the value already in memory, after we adjust it for where the PC is.
reloc_arm_relative, reloc_arm_relative,
// reloc_arm_cp_entry - PC relative relocation for constpool_entry's whose
// addresses are kept locally in a map.
reloc_arm_cp_entry,
// reloc_arm_branch - Branch address relocation.
reloc_arm_branch reloc_arm_branch
}; };
} }