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