Correct way to handle CONSTPOOL_ENTRY instructions.

llvm-svn: 58409
This commit is contained in:
Evan Cheng 2008-10-29 23:55:43 +00:00
parent 5e8fa6ef36
commit 69c2588244
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 "ARMAddressingModes.h"
#include "ARMConstantPoolValue.h"
#include "ARMInstrInfo.h"
#include "ARMRelocations.h"
#include "ARMSubtarget.h"
@ -192,7 +193,7 @@ unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
else if (MO.isSymbol())
emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_relative);
else if (MO.isCPI())
emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_relative);
emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
else if (MO.isJTI())
emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
else if (MO.isMBB())
@ -226,8 +227,9 @@ void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
int Disp /* = 0 */,
unsigned PCAdj /* = 0 */) {
// Tell JIT emitter we'll resolve the address.
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
Reloc, CPI, PCAdj));
Reloc, CPI, PCAdj, true));
}
/// 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) {
DOUT << MI;
DOUT << "JIT: " << "0x" << MCE.getCurrentPCValue() << ":\t" << MI;
NumEmitted++; // Keep track of the # of mi's emitted
if ((MI.getDesc().TSFlags & ARMII::FormMask) == ARMII::Pseudo)
@ -360,29 +362,47 @@ unsigned ARMCodeEmitter::getAddrMode1SBit(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();
const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIndex];
//FIXME: Can we get these here?
assert (!MCPE.isMachineConstantPoolEntry());
// Remember the CONSTPOOL_ENTRY address for later relocation.
JTI->addConstantPoolEntryAddr(CPI, MCE.getCurrentPCValue());
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);
// Emit constpool island entry. In most cases, the actual values will be
// resolved and relocated after code emission.
if (MCPE.isMachineConstantPoolEntry()) {
ARMConstantPoolValue *ACPV =
static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
const ConstantInt *CI = dyn_cast<ConstantInt>(CV);
uint32_t Val = *(uint32_t*)CI->getValue().getRawData();
DOUT << "\t** ARM constant pool #" << CPI << ", ' @ "
<< (void*)MCE.getCurrentPCValue() << *ACPV << '\n';
DOUT << "Constant pool #" << CPID << ", value '" << Val << "' @ " <<
(void*)MCE.getCurrentPCValue() << "\n";
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 {
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)
JTI->mapCPIDtoAddress(CPID, MCE.getCurrentPCValue());
MCE.emitWordLE(Val);
DOUT << "\t** Constant pool #" << CPI << ", ' @ "
<< (void*)MCE.getCurrentPCValue() << *CV << '\n';
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) {

View File

@ -174,8 +174,14 @@ 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();
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()) {
case ARM::reloc_arm_cp_entry:
case ARM::reloc_arm_relative: {
// It is necessary to calculate the correct PC relative value. We
// 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;
break;
}
case ARM::reloc_arm_absolute: {
*((unsigned*)RelocPos) += (unsigned)ResultPtr;
break;
}
case ARM::reloc_arm_branch: {
// 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

View File

@ -22,7 +22,11 @@ namespace llvm {
class ARMJITInfo : public TargetJITInfo {
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:
explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; }
@ -52,22 +56,22 @@ namespace llvm {
/// pool address resolution is handled by the target.
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
/// 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;
}
virtual intptr_t getConstantPoolEntryAddr(unsigned CPID) const {
std::map<unsigned, intptr_t>::const_iterator I
= ConstPoolId2AddrMap.find(CPID);
assert(I != ConstPoolId2AddrMap.end() && "Missing constpool_entry?");
return I->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,
/// this value will be used to resolve references to the constant.
void mapCPIDtoAddress(unsigned CPID, intptr_t address)
{ CPIDtoAddressMap[CPID] = address; }
void addConstantPoolEntryAddr(unsigned CPID, intptr_t Addr) {
ConstPoolId2AddrMap[CPID] = Addr;
}
};
}

View File

@ -19,8 +19,19 @@
namespace llvm {
namespace ARM {
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_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
};
}