summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MipsCodeEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips/MipsCodeEmitter.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsCodeEmitter.cpp198
1 files changed, 125 insertions, 73 deletions
diff --git a/llvm/lib/Target/Mips/MipsCodeEmitter.cpp b/llvm/lib/Target/Mips/MipsCodeEmitter.cpp
index eb8f7e0870e..9220d9c7ab4 100644
--- a/llvm/lib/Target/Mips/MipsCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MipsCodeEmitter.cpp
@@ -41,6 +41,8 @@
using namespace llvm;
+STATISTIC(NumEmitted, "Number of machine instructions emitted");
+
namespace {
class MipsCodeEmitter : public MachineFunctionPass {
@@ -75,65 +77,38 @@ class MipsCodeEmitter : public MachineFunctionPass {
return "Mips Machine Code Emitter";
}
- void emitInstruction(const MachineInstr &MI);
+ /// getBinaryCodeForInstr - This function, generated by the
+ /// CodeEmitterGenerator using TableGen, produces the binary encoding for
+ /// machine instructions.
+ unsigned getBinaryCodeForInstr(const MachineInstr &MI) const;
- unsigned getOperandValue(const MachineOperand &MO,
- unsigned relocType = -1);
+ void emitInstruction(const MachineInstr &MI);
- void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
- bool MayNeedFarStub = true);
+ private:
- void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
- intptr_t JTBase = 0);
+ void emitWordLE(unsigned Word);
- void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
+ /// Routines that handle operands which add machine relocations which are
+ /// fixed up by the relocation stage.
+ void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
+ bool MayNeedFarStub) const;
+ void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
+ void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
- void emitConstPoolAddress(unsigned CPI, unsigned Reloc);
-};
-}
-
-void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
- bool mayNeedFarStub) {
- MachineRelocation MR = MachineRelocation::getGV(MCE.getCurrentPCOffset(),
- Reloc, const_cast<GlobalValue *> (GV), 0, mayNeedFarStub);
- MCE.addRelocation(MR);
-}
-
-/// emitMachineBasicBlock - Emit the specified address basic block.
-void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
- unsigned Reloc, intptr_t JTBase) {
- MCE.addRelocation(
- MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, BB, JTBase));
-}
-
-void MipsCodeEmitter::emitExternalSymbolAddress(const char *ES,
- unsigned Reloc) {
- MCE.addRelocation(
- MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, ES, 0, 0,
- false));
-}
+ void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const;
-void MipsCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc)
- const {
- MCE.addRelocation(
- MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, JTIndex,
- 0, false));
-}
+ /// getMachineOpValue - Return binary encoding of operand. If the machine
+ /// operand requires relocation, record the relocation and return zero.
+ unsigned getMachineOpValue(const MachineInstr &MI,
+ const MachineOperand &MO) const;
-void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
- MCE.addRelocation(
- MachineRelocation::getConstPool
- (MCE.getCurrentPCOffset(), Reloc, CPI, 0));
-}
+ unsigned getRelocation(const MachineInstr &MI,
+ const MachineOperand &MO) const;
-/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
-/// code to the specified MCE object.
-FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
- JITCodeEmitter &JCE) {
- return new MipsCodeEmitter(TM, JCE);
+ };
}
-char MipsCodeEmitter::ID = 10;
+char MipsCodeEmitter::ID = 0;
bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
@@ -163,31 +138,108 @@ bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
-void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {}
-
-unsigned MipsCodeEmitter::getOperandValue(const MachineOperand &MO,
- unsigned relocType) {
- switch (MO.getType()) {
- case MachineOperand::MO_Immediate:
- return MO.getImm();
- case MachineOperand::MO_GlobalAddress:
- emitGlobalAddress(MO.getGlobal(), relocType, false);
- return 0;
- case MachineOperand::MO_ExternalSymbol:
- emitExternalSymbolAddress(MO.getSymbolName(), relocType);
- return 0;
- case MachineOperand::MO_MachineBasicBlock:
- emitMachineBasicBlock(MO.getMBB(), relocType, MCE.getCurrentPCValue());
- return 0;
- case MachineOperand::MO_Register:
+unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
+ const MachineOperand &MO) const {
+ // NOTE: This relocations are for static.
+ uint64_t TSFlags = MI.getDesc().TSFlags;
+ uint64_t Form = TSFlags & MipsII::FormMask;
+ if (Form == MipsII::FrmJ)
+ return Mips::reloc_mips_26;
+ if ((Form == MipsII::FrmI || Form == MipsII::FrmFI)
+ && MI.getDesc().isBranch())
+ return Mips::reloc_mips_branch;
+ if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi)
+ return Mips::reloc_mips_hi;
+ return Mips::reloc_mips_lo;
+}
+
+/// getMachineOpValue - Return binary encoding of operand. If the machine
+/// operand requires relocation, record the relocation and return zero.
+unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
+ const MachineOperand &MO) const {
+ if (MO.isReg())
return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
- case MachineOperand::MO_JumpTableIndex:
- emitJumpTableAddress(MO.getIndex(), relocType);
- return 0;
- case MachineOperand::MO_ConstantPoolIndex:
- emitConstPoolAddress(MO.getIndex(), relocType);
- return 0;
- default: return 0;
+ else if (MO.isImm())
+ return static_cast<unsigned>(MO.getImm());
+ else if (MO.isGlobal())
+ emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
+ else if (MO.isSymbol())
+ emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
+ else if (MO.isCPI())
+ emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
+ else if (MO.isJTI())
+ emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
+ else if (MO.isMBB())
+ emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
+ else
+ llvm_unreachable("Unable to encode MachineOperand!");
+ return 0;
+}
+
+void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
+ bool MayNeedFarStub) const {
+ MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
+ const_cast<GlobalValue *>(GV), 0, MayNeedFarStub));
+}
+
+void MipsCodeEmitter::
+emitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
+ Reloc, ES, 0, 0, false));
+}
+
+void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
+ Reloc, CPI, 0, false));
+}
+
+void MipsCodeEmitter::
+emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
+ Reloc, JTIndex, 0, false));
+}
+
+void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
+ unsigned Reloc) const {
+ MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
+ Reloc, BB));
+}
+
+void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
+ DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
+
+ MCE.processDebugLoc(MI.getDebugLoc(), true);
+
+ // Skip pseudo instructions.
+ if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
+ return;
+
+ ++NumEmitted; // Keep track of the # of mi's emitted
+
+ switch (MI.getOpcode()) {
+ default:
+ emitWordLE(getBinaryCodeForInstr(MI));
+ break;
}
+
+ MCE.processDebugLoc(MI.getDebugLoc(), false);
}
+void MipsCodeEmitter::emitWordLE(unsigned Word) {
+ DEBUG(errs() << " 0x";
+ errs().write_hex(Word) << "\n");
+ MCE.emitWordLE(Word);
+}
+
+/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
+/// code to the specified MCE object.
+FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
+ JITCodeEmitter &JCE) {
+ return new MipsCodeEmitter(TM, JCE);
+}
+
+unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {
+ // this function will be automatically generated by the CodeEmitterGenerator
+ // using TableGen
+ return 0;
+}
OpenPOWER on IntegriCloud