| //===-- ARM/ARMCodeEmitter.cpp - Convert ARM code to machine code ---------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file was developed by the Raul Herbster and is distributed under the |
| // University of Illinois Open Source License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains the pass that transforms the ARM machine instructions into |
| // relocatable machine code. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #define DEBUG_TYPE "arm-emitter" |
| #include "ARMInstrInfo.h" |
| #include "ARMSubtarget.h" |
| #include "ARMTargetMachine.h" |
| #include "ARM.h" |
| #include "llvm/PassManager.h" |
| #include "llvm/CodeGen/MachineCodeEmitter.h" |
| #include "llvm/CodeGen/MachineFunctionPass.h" |
| #include "llvm/CodeGen/MachineInstr.h" |
| #include "llvm/CodeGen/Passes.h" |
| #include "llvm/Function.h" |
| #include "llvm/ADT/Statistic.h" |
| #include "llvm/Support/Compiler.h" |
| using namespace llvm; |
| |
| STATISTIC(NumEmitted, "Number of machine instructions emitted"); |
| |
| namespace { |
| class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass { |
| const ARMInstrInfo *II; |
| const TargetData *TD; |
| TargetMachine &TM; |
| MachineCodeEmitter &MCE; |
| public: |
| static char ID; |
| explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce) |
| : MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm), |
| MCE(mce) {} |
| Emitter(TargetMachine &tm, MachineCodeEmitter &mce, |
| const ARMInstrInfo &ii, const TargetData &td) |
| : MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm), |
| MCE(mce) {} |
| |
| bool runOnMachineFunction(MachineFunction &MF); |
| |
| virtual const char *getPassName() const { |
| return "ARM Machine Code Emitter"; |
| } |
| |
| void emitInstruction(const MachineInstr &MI); |
| |
| private: |
| |
| }; |
| char Emitter::ID = 0; |
| } |
| |
| /// createARMCodeEmitterPass - Return a pass that emits the collected ARM code |
| /// to the specified MCE object. |
| FunctionPass *llvm::createARMCodeEmitterPass(ARMTargetMachine &TM, |
| MachineCodeEmitter &MCE) { |
| return new Emitter(TM, MCE); |
| } |
| |
| bool Emitter::runOnMachineFunction(MachineFunction &MF) { |
| assert((MF.getTarget().getRelocationModel() != Reloc::Default || |
| MF.getTarget().getRelocationModel() != Reloc::Static) && |
| "JIT relocation model must be set to static or default!"); |
| II = ((ARMTargetMachine&)MF.getTarget()).getInstrInfo(); |
| TD = ((ARMTargetMachine&)MF.getTarget()).getTargetData(); |
| |
| do { |
| MCE.startFunction(MF); |
| for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); |
| MBB != E; ++MBB) { |
| MCE.StartMachineBasicBlock(MBB); |
| for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); |
| I != E; ++I) |
| emitInstruction(*I); |
| } |
| } while (MCE.finishFunction(MF)); |
| |
| return false; |
| } |
| |
| void Emitter::emitInstruction(const MachineInstr &MI) { |
| NumEmitted++; // Keep track of the # of mi's emitted |
| } |