mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 08:26:29 +00:00
Correct way to handle CONSTPOOL_ENTRY instructions.
llvm-svn: 58409
This commit is contained in:
parent
5e8fa6ef36
commit
69c2588244
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user