mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Handle ARM machine constantpool entries.
llvm-svn: 58671
This commit is contained in:
parent
0ba8aad1af
commit
f117632c3f
@ -158,7 +158,7 @@ bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData();
|
TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData();
|
||||||
JTI = ((ARMTargetMachine&)MF.getTarget()).getJITInfo();
|
JTI = ((ARMTargetMachine&)MF.getTarget()).getJITInfo();
|
||||||
MCPEs = &MF.getConstantPool()->getConstants();
|
MCPEs = &MF.getConstantPool()->getConstants();
|
||||||
JTI->ResizeConstPoolMap(MCPEs->size());
|
JTI->Initialize(MCPEs);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
DOUT << "JITTing function '" << MF.getFunction()->getName() << "'\n";
|
DOUT << "JITTing function '" << MF.getFunction()->getName() << "'\n";
|
||||||
@ -257,7 +257,7 @@ void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
|
||||||
DOUT << "JIT: " << "0x" << MCE.getCurrentPCValue() << ":\t" << MI;
|
DOUT << "JIT: " << (void*)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)
|
||||||
@ -286,8 +286,10 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
|
|||||||
GlobalValue *GV = ACPV->getGV();
|
GlobalValue *GV = ACPV->getGV();
|
||||||
if (GV) {
|
if (GV) {
|
||||||
assert(!ACPV->isStub() && "Don't know how to deal this yet!");
|
assert(!ACPV->isStub() && "Don't know how to deal this yet!");
|
||||||
emitGlobalAddress(GV, ARM::reloc_arm_absolute, false);
|
MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
|
||||||
} else {
|
ARM::reloc_arm_machine_cp_entry,
|
||||||
|
GV, CPIndex, false));
|
||||||
|
} else {
|
||||||
assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
|
assert(!ACPV->isNonLazyPointer() && "Don't know how to deal this yet!");
|
||||||
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
|
emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute);
|
||||||
}
|
}
|
||||||
@ -320,6 +322,12 @@ void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
|
|||||||
emitConstPoolInstruction(MI);
|
emitConstPoolInstruction(MI);
|
||||||
break;
|
break;
|
||||||
case ARM::PICADD: {
|
case ARM::PICADD: {
|
||||||
|
// Remember of the address of the PC label for relocation later.
|
||||||
|
const MachineOperand &MO2 = MI.getOperand(2);
|
||||||
|
DOUT << "\t** LPC" << MO2.getImm() << " @ "
|
||||||
|
<< (void*)MCE.getCurrentPCValue() << '\n';
|
||||||
|
JTI->addPCLabelAddr(MO2.getImm(), MCE.getCurrentPCValue());
|
||||||
|
|
||||||
// PICADD is just an add instruction that implicitly read pc.
|
// PICADD is just an add instruction that implicitly read pc.
|
||||||
unsigned Binary = getBinaryCodeForInstr(MI);
|
unsigned Binary = getBinaryCodeForInstr(MI);
|
||||||
const TargetInstrDesc &TID = MI.getDesc();
|
const TargetInstrDesc &TID = MI.getDesc();
|
||||||
|
@ -93,10 +93,8 @@ void ARMConstantPoolValue::print(raw_ostream &O) const {
|
|||||||
else if (isStub()) O << "$stub";
|
else if (isStub()) O << "$stub";
|
||||||
if (Modifier) O << "(" << Modifier << ")";
|
if (Modifier) O << "(" << Modifier << ")";
|
||||||
if (PCAdjust != 0) {
|
if (PCAdjust != 0) {
|
||||||
O << "-(LPIC" << LabelId << "+"
|
O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
|
||||||
<< (unsigned)PCAdjust;
|
if (AddCurrentAddress) O << "-.";
|
||||||
if (AddCurrentAddress)
|
|
||||||
O << "-.";
|
|
||||||
O << ")";
|
O << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#define DEBUG_TYPE "jit"
|
#define DEBUG_TYPE "jit"
|
||||||
#include "ARMJITInfo.h"
|
#include "ARMJITInfo.h"
|
||||||
|
#include "ARMConstantPoolValue.h"
|
||||||
#include "ARMRelocations.h"
|
#include "ARMRelocations.h"
|
||||||
#include "ARMSubtarget.h"
|
#include "ARMSubtarget.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
@ -167,6 +168,25 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
|
|||||||
return MCE.finishFunctionStub(F);
|
return MCE.finishFunctionStub(F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intptr_t ARMJITInfo::resolveRelocationAddr(MachineRelocation *MR) const {
|
||||||
|
ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType();
|
||||||
|
if (RT == ARM::reloc_arm_cp_entry)
|
||||||
|
return getConstantPoolEntryAddr(MR->getConstantPoolIndex());
|
||||||
|
else if (RT == ARM::reloc_arm_machine_cp_entry) {
|
||||||
|
const MachineConstantPoolEntry &MCPE = (*MCPEs)[MR->getConstantVal()];
|
||||||
|
assert(MCPE.isMachineConstantPoolEntry() &&
|
||||||
|
"Expecting a machine constant pool entry!");
|
||||||
|
ARMConstantPoolValue *ACPV =
|
||||||
|
static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
|
||||||
|
assert((!ACPV->hasModifier() && !ACPV->mustAddCurrentAddress()) &&
|
||||||
|
"Can't handle this machine constant pool entry yet!");
|
||||||
|
intptr_t Addr = (intptr_t)(MR->getResultPointer());
|
||||||
|
Addr -= getPCLabelAddr(ACPV->getLabelId()) + ACPV->getPCAdjustment();
|
||||||
|
return Addr;
|
||||||
|
}
|
||||||
|
return (intptr_t)(MR->getResultPointer());
|
||||||
|
}
|
||||||
|
|
||||||
/// relocate - Before the JIT can run a block of code that has been emitted,
|
/// relocate - Before the JIT can run a block of code that has been emitted,
|
||||||
/// it must rewrite the code to contain the actual addresses of any
|
/// it must rewrite the code to contain the actual addresses of any
|
||||||
/// referenced global symbols.
|
/// referenced global symbols.
|
||||||
@ -174,12 +194,9 @@ 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();
|
||||||
ARM::RelocationType RT = (ARM::RelocationType)MR->getRelocationType();
|
|
||||||
// If this is a constpool relocation, get the address of the
|
// If this is a constpool relocation, get the address of the
|
||||||
// constpool_entry instruction.
|
// constpool_entry instruction.
|
||||||
intptr_t ResultPtr = (RT == ARM::reloc_arm_cp_entry)
|
intptr_t ResultPtr = resolveRelocationAddr(MR);
|
||||||
? 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_cp_entry:
|
||||||
case ARM::reloc_arm_relative: {
|
case ARM::reloc_arm_relative: {
|
||||||
@ -190,18 +207,20 @@ void ARMJITInfo::relocate(void *Function, MachineRelocation *MR,
|
|||||||
if (ResultPtr >= 0)
|
if (ResultPtr >= 0)
|
||||||
*((unsigned*)RelocPos) |= 1 << 23;
|
*((unsigned*)RelocPos) |= 1 << 23;
|
||||||
else {
|
else {
|
||||||
// otherwise, obtain the absolute value and set
|
// Otherwise, obtain the absolute value and set
|
||||||
// bit U(23) to 0.
|
// bit U(23) to 0.
|
||||||
ResultPtr *= -1;
|
ResultPtr *= -1;
|
||||||
*((unsigned*)RelocPos) &= 0xFF7FFFFF;
|
*((unsigned*)RelocPos) &= 0xFF7FFFFF;
|
||||||
}
|
}
|
||||||
// set the immed value calculated
|
// Set the immed value calculated.
|
||||||
*((unsigned*)RelocPos) |= (unsigned)ResultPtr;
|
*((unsigned*)RelocPos) |= (unsigned)ResultPtr;
|
||||||
// set register Rn to PC
|
// Set register Rn to PC.
|
||||||
*((unsigned*)RelocPos) |= 0xF << 16;
|
*((unsigned*)RelocPos) |= 0xF << 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ARM::reloc_arm_machine_cp_entry:
|
||||||
case ARM::reloc_arm_absolute: {
|
case ARM::reloc_arm_absolute: {
|
||||||
|
// These addresses have already been resolved.
|
||||||
*((unsigned*)RelocPos) += (unsigned)ResultPtr;
|
*((unsigned*)RelocPos) += (unsigned)ResultPtr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#define ARMJITINFO_H
|
#define ARMJITINFO_H
|
||||||
|
|
||||||
#include "llvm/Target/TargetJITInfo.h"
|
#include "llvm/Target/TargetJITInfo.h"
|
||||||
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -23,10 +25,17 @@ namespace llvm {
|
|||||||
class ARMJITInfo : public TargetJITInfo {
|
class ARMJITInfo : public TargetJITInfo {
|
||||||
ARMTargetMachine &TM;
|
ARMTargetMachine &TM;
|
||||||
|
|
||||||
|
// MCPEs - List of the constant pool entries for the current machine
|
||||||
|
// function that's being processed.
|
||||||
|
const std::vector<MachineConstantPoolEntry> *MCPEs;
|
||||||
|
|
||||||
// ConstPoolId2AddrMap - A map from constant pool ids to the corresponding
|
// ConstPoolId2AddrMap - A map from constant pool ids to the corresponding
|
||||||
// CONSTPOOL_ENTRY addresses.
|
// CONSTPOOL_ENTRY addresses.
|
||||||
SmallVector<intptr_t, 32> ConstPoolId2AddrMap;
|
SmallVector<intptr_t, 32> ConstPoolId2AddrMap;
|
||||||
|
|
||||||
|
// PCLabelMap - A map from PC labels to addresses.
|
||||||
|
DenseMap<unsigned, intptr_t> PCLabelMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; }
|
explicit ARMJITInfo(ARMTargetMachine &tm) : TM(tm) { useGOT = false; }
|
||||||
|
|
||||||
@ -51,15 +60,16 @@ namespace llvm {
|
|||||||
/// referenced global symbols.
|
/// referenced global symbols.
|
||||||
virtual void relocate(void *Function, MachineRelocation *MR,
|
virtual void relocate(void *Function, MachineRelocation *MR,
|
||||||
unsigned NumRelocs, unsigned char* GOTBase);
|
unsigned NumRelocs, unsigned char* GOTBase);
|
||||||
|
|
||||||
/// hasCustomConstantPool - Allows a target to specify that constant
|
/// hasCustomConstantPool - Allows a target to specify that constant
|
||||||
/// 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; }
|
||||||
|
|
||||||
/// ResizeConstPoolMap - Resize constant pool ids to CONSTPOOL_ENTRY
|
/// Initialize - Initialize internal stage. Get the list of constant pool
|
||||||
/// addresses map.
|
/// Resize constant pool ids to CONSTPOOL_ENTRY addresses map.
|
||||||
void ResizeConstPoolMap(unsigned Size) {
|
void Initialize(const std::vector<MachineConstantPoolEntry> *mcpes) {
|
||||||
ConstPoolId2AddrMap.resize(Size);
|
MCPEs = mcpes;
|
||||||
|
ConstPoolId2AddrMap.resize(MCPEs->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getConstantPoolEntryAddr - The ARM target puts all constant
|
/// getConstantPoolEntryAddr - The ARM target puts all constant
|
||||||
@ -77,6 +87,24 @@ namespace llvm {
|
|||||||
assert(CPI < ConstPoolId2AddrMap.size());
|
assert(CPI < ConstPoolId2AddrMap.size());
|
||||||
ConstPoolId2AddrMap[CPI] = Addr;
|
ConstPoolId2AddrMap[CPI] = Addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getPCLabelAddr - Retrieve the address of the PC label of the specified id.
|
||||||
|
intptr_t getPCLabelAddr(unsigned Id) const {
|
||||||
|
DenseMap<unsigned, intptr_t>::const_iterator I = PCLabelMap.find(Id);
|
||||||
|
assert(I != PCLabelMap.end());
|
||||||
|
return I->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// addPCLabelAddr - Remember the address of the specified PC label.
|
||||||
|
void addPCLabelAddr(unsigned Id, intptr_t Addr) {
|
||||||
|
PCLabelMap.insert(std::make_pair(Id, Addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// resolveRelocationAddr - Resolve the resulting address of the relocation
|
||||||
|
/// if it's not already solved. Constantpool entries must be resolved by
|
||||||
|
/// ARM target.
|
||||||
|
intptr_t resolveRelocationAddr(MachineRelocation *MR) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,10 @@ namespace llvm {
|
|||||||
// addresses are kept locally in a map.
|
// addresses are kept locally in a map.
|
||||||
reloc_arm_cp_entry,
|
reloc_arm_cp_entry,
|
||||||
|
|
||||||
|
// reloc_arm_machine_cp_entry - Relocation of a ARM machine constantpool
|
||||||
|
// entry.
|
||||||
|
reloc_arm_machine_cp_entry,
|
||||||
|
|
||||||
// reloc_arm_branch - Branch address relocation.
|
// reloc_arm_branch - Branch address relocation.
|
||||||
reloc_arm_branch
|
reloc_arm_branch
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user