mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
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:
parent
5be59eace5
commit
0f282439be
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user