SparcCodeEmitter.cpp revision 263763
1//===-- Sparc/SparcCodeEmitter.cpp - Convert Sparc Code to Machine Code ---===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===---------------------------------------------------------------------===// 9// 10// This file contains the pass that transforms the Sparc machine instructions 11// into relocatable machine code. 12// 13//===---------------------------------------------------------------------===// 14 15#define DEBUG_TYPE "jit" 16#include "Sparc.h" 17#include "MCTargetDesc/SparcMCExpr.h" 18#include "SparcRelocations.h" 19#include "SparcTargetMachine.h" 20#include "llvm/ADT/Statistic.h" 21#include "llvm/CodeGen/JITCodeEmitter.h" 22#include "llvm/CodeGen/MachineFunctionPass.h" 23#include "llvm/CodeGen/MachineModuleInfo.h" 24#include "llvm/Support/Debug.h" 25 26using namespace llvm; 27 28STATISTIC(NumEmitted, "Number of machine instructions emitted"); 29 30namespace { 31 32class SparcCodeEmitter : public MachineFunctionPass { 33 SparcJITInfo *JTI; 34 const SparcInstrInfo *II; 35 const DataLayout *TD; 36 const SparcSubtarget *Subtarget; 37 TargetMachine &TM; 38 JITCodeEmitter &MCE; 39 const std::vector<MachineConstantPoolEntry> *MCPEs; 40 bool IsPIC; 41 42 void getAnalysisUsage(AnalysisUsage &AU) const { 43 AU.addRequired<MachineModuleInfo> (); 44 MachineFunctionPass::getAnalysisUsage(AU); 45 } 46 47 static char ID; 48 49public: 50 SparcCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) 51 : MachineFunctionPass(ID), JTI(0), II(0), TD(0), 52 TM(tm), MCE(mce), MCPEs(0), 53 IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} 54 55 bool runOnMachineFunction(MachineFunction &MF); 56 57 virtual const char *getPassName() const { 58 return "Sparc Machine Code Emitter"; 59 } 60 61 /// getBinaryCodeForInstr - This function, generated by the 62 /// CodeEmitterGenerator using TableGen, produces the binary encoding for 63 /// machine instructions. 64 uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const; 65 66 void emitInstruction(MachineBasicBlock::instr_iterator MI, 67 MachineBasicBlock &MBB); 68 69private: 70 /// getMachineOpValue - Return binary encoding of operand. If the machine 71 /// operand requires relocation, record the relocation and return zero. 72 unsigned getMachineOpValue(const MachineInstr &MI, 73 const MachineOperand &MO) const; 74 75 unsigned getCallTargetOpValue(const MachineInstr &MI, 76 unsigned) const; 77 unsigned getBranchTargetOpValue(const MachineInstr &MI, 78 unsigned) const; 79 80 void emitWord(unsigned Word); 81 82 unsigned getRelocation(const MachineInstr &MI, 83 const MachineOperand &MO) const; 84 85 void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc) const; 86 void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const; 87 void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const; 88 void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const; 89}; 90} // end anonymous namespace. 91 92char SparcCodeEmitter::ID = 0; 93 94bool SparcCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 95 SparcTargetMachine &Target = static_cast<SparcTargetMachine &>( 96 const_cast<TargetMachine &>(MF.getTarget())); 97 98 JTI = Target.getJITInfo(); 99 II = Target.getInstrInfo(); 100 TD = Target.getDataLayout(); 101 Subtarget = &TM.getSubtarget<SparcSubtarget> (); 102 MCPEs = &MF.getConstantPool()->getConstants(); 103 JTI->Initialize(MF, IsPIC); 104 MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ()); 105 106 do { 107 DEBUG(errs() << "JITTing function '" 108 << MF.getName() << "'\n"); 109 MCE.startFunction(MF); 110 111 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 112 MBB != E; ++MBB){ 113 MCE.StartMachineBasicBlock(MBB); 114 for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(), 115 E = MBB->instr_end(); I != E;) 116 emitInstruction(*I++, *MBB); 117 } 118 } while (MCE.finishFunction(MF)); 119 120 return false; 121} 122 123void SparcCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, 124 MachineBasicBlock &MBB) { 125 DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI); 126 127 MCE.processDebugLoc(MI->getDebugLoc(), true); 128 129 ++NumEmitted; 130 131 switch (MI->getOpcode()) { 132 default: { 133 emitWord(getBinaryCodeForInstr(*MI)); 134 break; 135 } 136 case TargetOpcode::INLINEASM: { 137 // We allow inline assembler nodes with empty bodies - they can 138 // implicitly define registers, which is ok for JIT. 139 if (MI->getOperand(0).getSymbolName()[0]) { 140 report_fatal_error("JIT does not support inline asm!"); 141 } 142 break; 143 } 144 case TargetOpcode::PROLOG_LABEL: 145 case TargetOpcode::EH_LABEL: { 146 MCE.emitLabel(MI->getOperand(0).getMCSymbol()); 147 break; 148 } 149 case TargetOpcode::IMPLICIT_DEF: 150 case TargetOpcode::KILL: { 151 // Do nothing. 152 break; 153 } 154 case SP::GETPCX: { 155 report_fatal_error("JIT does not support pseudo instruction GETPCX yet!"); 156 break; 157 } 158 } 159 160 MCE.processDebugLoc(MI->getDebugLoc(), false); 161} 162 163void SparcCodeEmitter::emitWord(unsigned Word) { 164 DEBUG(errs() << " 0x"; 165 errs().write_hex(Word) << "\n"); 166 MCE.emitWordBE(Word); 167} 168 169/// getMachineOpValue - Return binary encoding of operand. If the machine 170/// operand requires relocation, record the relocation and return zero. 171unsigned SparcCodeEmitter::getMachineOpValue(const MachineInstr &MI, 172 const MachineOperand &MO) const { 173 if (MO.isReg()) 174 return TM.getRegisterInfo()->getEncodingValue(MO.getReg()); 175 else if (MO.isImm()) 176 return static_cast<unsigned>(MO.getImm()); 177 else if (MO.isGlobal()) 178 emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO)); 179 else if (MO.isSymbol()) 180 emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 181 else if (MO.isCPI()) 182 emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); 183 else if (MO.isMBB()) 184 emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 185 else 186 llvm_unreachable("Unable to encode MachineOperand!"); 187 return 0; 188} 189unsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI, 190 unsigned opIdx) const { 191 const MachineOperand MO = MI.getOperand(opIdx); 192 return getMachineOpValue(MI, MO); 193} 194 195unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, 196 unsigned opIdx) const { 197 const MachineOperand MO = MI.getOperand(opIdx); 198 return getMachineOpValue(MI, MO); 199} 200 201unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI, 202 const MachineOperand &MO) const { 203 204 unsigned TF = MO.getTargetFlags(); 205 switch (TF) { 206 default: 207 case SparcMCExpr::VK_Sparc_None: break; 208 case SparcMCExpr::VK_Sparc_LO: return SP::reloc_sparc_lo; 209 case SparcMCExpr::VK_Sparc_HI: return SP::reloc_sparc_hi; 210 case SparcMCExpr::VK_Sparc_H44: return SP::reloc_sparc_h44; 211 case SparcMCExpr::VK_Sparc_M44: return SP::reloc_sparc_m44; 212 case SparcMCExpr::VK_Sparc_L44: return SP::reloc_sparc_l44; 213 case SparcMCExpr::VK_Sparc_HH: return SP::reloc_sparc_hh; 214 case SparcMCExpr::VK_Sparc_HM: return SP::reloc_sparc_hm; 215 } 216 217 unsigned Opc = MI.getOpcode(); 218 switch (Opc) { 219 default: break; 220 case SP::CALL: return SP::reloc_sparc_pc30; 221 case SP::BA: 222 case SP::BCOND: 223 case SP::FBCOND: return SP::reloc_sparc_pc22; 224 case SP::BPXCC: return SP::reloc_sparc_pc19; 225 } 226 llvm_unreachable("unknown reloc!"); 227} 228 229void SparcCodeEmitter::emitGlobalAddress(const GlobalValue *GV, 230 unsigned Reloc) const { 231 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 232 const_cast<GlobalValue *>(GV), 0, 233 true)); 234} 235 236void SparcCodeEmitter:: 237emitExternalSymbolAddress(const char *ES, unsigned Reloc) const { 238 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 239 Reloc, ES, 0, 0)); 240} 241 242void SparcCodeEmitter:: 243emitConstPoolAddress(unsigned CPI, unsigned Reloc) const { 244 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 245 Reloc, CPI, 0, false)); 246} 247 248void SparcCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, 249 unsigned Reloc) const { 250 MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 251 Reloc, BB)); 252} 253 254 255/// createSparcJITCodeEmitterPass - Return a pass that emits the collected Sparc 256/// code to the specified MCE object. 257FunctionPass *llvm::createSparcJITCodeEmitterPass(SparcTargetMachine &TM, 258 JITCodeEmitter &JCE) { 259 return new SparcCodeEmitter(TM, JCE); 260} 261 262#include "SparcGenCodeEmitter.inc" 263