detemplatize ARM code emitter.

llvm-svn: 95138
This commit is contained in:
Chris Lattner 2010-02-02 21:48:51 +00:00
parent 3184f22447
commit 8d806876c0
1 changed files with 57 additions and 111 deletions

View File

@ -46,42 +46,34 @@ STATISTIC(NumEmitted, "Number of machine instructions emitted");
namespace {
class ARMCodeEmitter {
public:
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
/// machine instructions.
unsigned getBinaryCodeForInstr(const MachineInstr &MI);
};
template<class CodeEmitter>
class Emitter : public MachineFunctionPass, public ARMCodeEmitter {
class ARMCodeEmitter : public MachineFunctionPass {
ARMJITInfo *JTI;
const ARMInstrInfo *II;
const TargetData *TD;
const ARMSubtarget *Subtarget;
TargetMachine &TM;
CodeEmitter &MCE;
JITCodeEmitter &MCE;
const std::vector<MachineConstantPoolEntry> *MCPEs;
const std::vector<MachineJumpTableEntry> *MJTEs;
bool IsPIC;
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineModuleInfo>();
MachineFunctionPass::getAnalysisUsage(AU);
}
public:
static char ID;
explicit Emitter(TargetMachine &tm, CodeEmitter &mce)
: MachineFunctionPass(&ID), JTI(0), II(0), TD(0), TM(tm),
MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
Emitter(TargetMachine &tm, CodeEmitter &mce,
const ARMInstrInfo &ii, const TargetData &td)
: MachineFunctionPass(&ID), JTI(0), II(&ii), TD(&td), TM(tm),
MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
public:
ARMCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
: MachineFunctionPass(&ID), JTI(0), II((ARMInstrInfo*)tm.getInstrInfo()),
TD(tm.getTargetData()), TM(tm),
MCE(mce), MCPEs(0), MJTEs(0),
IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
/// getBinaryCodeForInstr - This function, generated by the
/// CodeEmitterGenerator using TableGen, produces the binary encoding for
/// machine instructions.
unsigned getBinaryCodeForInstr(const MachineInstr &MI);
bool runOnMachineFunction(MachineFunction &MF);
@ -94,21 +86,13 @@ namespace {
private:
void emitWordLE(unsigned Binary);
void emitDWordLE(uint64_t Binary);
void emitConstPoolInstruction(const MachineInstr &MI);
void emitMOVi2piecesInstruction(const MachineInstr &MI);
void emitLEApcrelJTInstruction(const MachineInstr &MI);
void emitPseudoMoveInstruction(const MachineInstr &MI);
void addPCLabel(unsigned LabelID);
void emitPseudoInstruction(const MachineInstr &MI);
unsigned getMachineSoRegOpValue(const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
@ -176,19 +160,18 @@ namespace {
void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
intptr_t JTBase = 0);
};
template <class CodeEmitter>
char Emitter<CodeEmitter>::ID = 0;
}
char ARMCodeEmitter::ID = 0;
/// createARMJITCodeEmitterPass - Return a pass that emits the collected ARM
/// code to the specified MCE object.
FunctionPass *llvm::createARMJITCodeEmitterPass(ARMBaseTargetMachine &TM,
JITCodeEmitter &JCE) {
return new Emitter<JITCodeEmitter>(TM, JCE);
return new ARMCodeEmitter(TM, JCE);
}
template<class CodeEmitter>
bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
bool ARMCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
MF.getTarget().getRelocationModel() != Reloc::Static) &&
"JIT relocation model must be set to static or default!");
@ -221,8 +204,7 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
/// getShiftOp - Return the shift opcode (bit[6:5]) of the immediate value.
///
template<class CodeEmitter>
unsigned Emitter<CodeEmitter>::getShiftOp(unsigned Imm) const {
unsigned ARMCodeEmitter::getShiftOp(unsigned Imm) const {
switch (ARM_AM::getAM2ShiftOpc(Imm)) {
default: llvm_unreachable("Unknown shift opc!");
case ARM_AM::asr: return 2;
@ -236,9 +218,8 @@ unsigned Emitter<CodeEmitter>::getShiftOp(unsigned Imm) const {
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
template<class CodeEmitter>
unsigned Emitter<CodeEmitter>::getMachineOpValue(const MachineInstr &MI,
const MachineOperand &MO) {
unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
const MachineOperand &MO) {
if (MO.isReg())
return ARMRegisterInfo::getRegisterNumbering(MO.getReg());
else if (MO.isImm())
@ -268,10 +249,9 @@ unsigned Emitter<CodeEmitter>::getMachineOpValue(const MachineInstr &MI,
/// emitGlobalAddress - Emit the specified address to the code stream.
///
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
bool MayNeedFarStub, bool Indirect,
intptr_t ACPV) {
void ARMCodeEmitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
bool MayNeedFarStub, bool Indirect,
intptr_t ACPV) {
MachineRelocation MR = Indirect
? MachineRelocation::getIndirectSymbol(MCE.getCurrentPCOffset(), Reloc,
GV, ACPV, MayNeedFarStub)
@ -283,9 +263,7 @@ void Emitter<CodeEmitter>::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES,
unsigned Reloc) {
void ARMCodeEmitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
Reloc, ES));
}
@ -293,9 +271,7 @@ void Emitter<CodeEmitter>::emitExternalSymbolAddress(const char *ES,
/// emitConstPoolAddress - Arrange for the address of an constant pool
/// to be emitted to the current location in the function, and allow it to be PC
/// relative.
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitConstPoolAddress(unsigned CPI,
unsigned Reloc) {
void ARMCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
// Tell JIT emitter we'll resolve the address.
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
Reloc, CPI, 0, true));
@ -304,37 +280,31 @@ void Emitter<CodeEmitter>::emitConstPoolAddress(unsigned CPI,
/// emitJumpTableAddress - Arrange for the address of a jump table to
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitJumpTableAddress(unsigned JTIndex,
unsigned Reloc) {
void ARMCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) {
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
Reloc, JTIndex, 0, true));
}
/// emitMachineBasicBlock - Emit the specified address basic block.
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitMachineBasicBlock(MachineBasicBlock *BB,
unsigned Reloc, intptr_t JTBase) {
void ARMCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
unsigned Reloc, intptr_t JTBase) {
MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
Reloc, BB, JTBase));
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitWordLE(unsigned Binary) {
void ARMCodeEmitter::emitWordLE(unsigned Binary) {
DEBUG(errs() << " 0x";
errs().write_hex(Binary) << "\n");
MCE.emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitDWordLE(uint64_t Binary) {
void ARMCodeEmitter::emitDWordLE(uint64_t Binary) {
DEBUG(errs() << " 0x";
errs().write_hex(Binary) << "\n");
MCE.emitDWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) {
DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
MCE.processDebugLoc(MI.getDebugLoc(), true);
@ -403,8 +373,7 @@ void Emitter<CodeEmitter>::emitInstruction(const MachineInstr &MI) {
MCE.processDebugLoc(MI.getDebugLoc(), false);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitConstPoolInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) {
unsigned CPI = MI.getOperand(0).getImm(); // CP instruction index.
unsigned CPIndex = MI.getOperand(1).getIndex(); // Actual cp entry index.
const MachineConstantPoolEntry &MCPE = (*MCPEs)[CPIndex];
@ -466,8 +435,7 @@ void Emitter<CodeEmitter>::emitConstPoolInstruction(const MachineInstr &MI) {
}
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitMOVi2piecesInstruction(const MachineInstr &MI) {
const MachineOperand &MO0 = MI.getOperand(0);
const MachineOperand &MO1 = MI.getOperand(1);
assert(MO1.isImm() && ARM_AM::getSOImmVal(MO1.isImm()) != -1 &&
@ -509,8 +477,7 @@ void Emitter<CodeEmitter>::emitMOVi2piecesInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitLEApcrelJTInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitLEApcrelJTInstruction(const MachineInstr &MI) {
// It's basically add r, pc, (LJTI - $+8)
const TargetInstrDesc &TID = MI.getDesc();
@ -537,8 +504,7 @@ void Emitter<CodeEmitter>::emitLEApcrelJTInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitPseudoMoveInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitPseudoMoveInstruction(const MachineInstr &MI) {
unsigned Opcode = MI.getDesc().Opcode;
// Part of binary is determined by TableGn.
@ -577,15 +543,13 @@ void Emitter<CodeEmitter>::emitPseudoMoveInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::addPCLabel(unsigned LabelID) {
void ARMCodeEmitter::addPCLabel(unsigned LabelID) {
DEBUG(errs() << " ** LPC" << LabelID << " @ "
<< (void*)MCE.getCurrentPCValue() << '\n');
JTI->addPCLabelAddr(LabelID, MCE.getCurrentPCValue());
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitPseudoInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitPseudoInstruction(const MachineInstr &MI) {
unsigned Opcode = MI.getDesc().Opcode;
switch (Opcode) {
default:
@ -653,8 +617,7 @@ void Emitter<CodeEmitter>::emitPseudoInstruction(const MachineInstr &MI) {
}
}
template<class CodeEmitter>
unsigned Emitter<CodeEmitter>::getMachineSoRegOpValue(
unsigned ARMCodeEmitter::getMachineSoRegOpValue(
const MachineInstr &MI,
const TargetInstrDesc &TID,
const MachineOperand &MO,
@ -713,8 +676,7 @@ unsigned Emitter<CodeEmitter>::getMachineSoRegOpValue(
return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
}
template<class CodeEmitter>
unsigned Emitter<CodeEmitter>::getMachineSoImmOpValue(unsigned SoImm) {
unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) {
int SoImmVal = ARM_AM::getSOImmVal(SoImm);
assert(SoImmVal != -1 && "Not a valid so_imm value!");
@ -727,8 +689,7 @@ unsigned Emitter<CodeEmitter>::getMachineSoImmOpValue(unsigned SoImm) {
return Binary;
}
template<class CodeEmitter>
unsigned Emitter<CodeEmitter>::getAddrModeSBit(const MachineInstr &MI,
unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
const TargetInstrDesc &TID) const {
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
const MachineOperand &MO = MI.getOperand(i-1);
@ -738,8 +699,7 @@ unsigned Emitter<CodeEmitter>::getAddrModeSBit(const MachineInstr &MI,
return 0;
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitDataProcessingInstruction(
void ARMCodeEmitter::emitDataProcessingInstruction(
const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
@ -805,8 +765,7 @@ void Emitter<CodeEmitter>::emitDataProcessingInstruction(
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitLoadStoreInstruction(
void ARMCodeEmitter::emitLoadStoreInstruction(
const MachineInstr &MI,
unsigned ImplicitRd,
unsigned ImplicitRn) {
@ -881,8 +840,7 @@ void Emitter<CodeEmitter>::emitLoadStoreInstruction(
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitMiscLoadStoreInstruction(const MachineInstr &MI,
void ARMCodeEmitter::emitMiscLoadStoreInstruction(const MachineInstr &MI,
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
@ -969,8 +927,7 @@ static unsigned getAddrModeUPBits(unsigned Mode) {
return Binary;
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitLoadStoreMultipleInstruction(
void ARMCodeEmitter::emitLoadStoreMultipleInstruction(
const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@ -1003,8 +960,7 @@ void Emitter<CodeEmitter>::emitLoadStoreMultipleInstruction(
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitMulFrmInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@ -1041,8 +997,7 @@ void Emitter<CodeEmitter>::emitMulFrmInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitExtendInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitExtendInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@ -1079,8 +1034,7 @@ void Emitter<CodeEmitter>::emitExtendInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitMiscArithInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitMiscArithInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@ -1118,8 +1072,7 @@ void Emitter<CodeEmitter>::emitMiscArithInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitBranchInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitBranchInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
if (TID.Opcode == ARM::TPsoft) {
@ -1138,8 +1091,7 @@ void Emitter<CodeEmitter>::emitBranchInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitInlineJumpTable(unsigned JTIndex) {
void ARMCodeEmitter::emitInlineJumpTable(unsigned JTIndex) {
// Remember the base address of the inline jump table.
uintptr_t JTBase = MCE.getCurrentPCValue();
JTI->addJumpTableBaseAddr(JTIndex, JTBase);
@ -1159,8 +1111,7 @@ void Emitter<CodeEmitter>::emitInlineJumpTable(unsigned JTIndex) {
}
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitMiscBranchInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitMiscBranchInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Handle jump tables.
@ -1241,8 +1192,7 @@ static unsigned encodeVFPRm(const MachineInstr &MI, unsigned OpIdx) {
return Binary;
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitVFPArithInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitVFPArithInstruction(const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
// Part of binary is determined by TableGn.
@ -1281,8 +1231,7 @@ void Emitter<CodeEmitter>::emitVFPArithInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitVFPConversionInstruction(
void ARMCodeEmitter::emitVFPConversionInstruction(
const MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
unsigned Form = TID.TSFlags & ARMII::FormMask;
@ -1339,8 +1288,7 @@ void Emitter<CodeEmitter>::emitVFPConversionInstruction(
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@ -1374,8 +1322,7 @@ void Emitter<CodeEmitter>::emitVFPLoadStoreInstruction(const MachineInstr &MI) {
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitVFPLoadStoreMultipleInstruction(
void ARMCodeEmitter::emitVFPLoadStoreMultipleInstruction(
const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
@ -1410,8 +1357,7 @@ void Emitter<CodeEmitter>::emitVFPLoadStoreMultipleInstruction(
emitWordLE(Binary);
}
template<class CodeEmitter>
void Emitter<CodeEmitter>::emitMiscInstruction(const MachineInstr &MI) {
void ARMCodeEmitter::emitMiscInstruction(const MachineInstr &MI) {
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);