diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsCodeEmitter.cpp')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsCodeEmitter.cpp | 198 |
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; +} |

