1259698Sdim//===-- Sparc/SparcCodeEmitter.cpp - Convert Sparc Code to Machine Code ---===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===---------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// This file contains the pass that transforms the Sparc machine instructions 11259698Sdim// into relocatable machine code. 12259698Sdim// 13259698Sdim//===---------------------------------------------------------------------===// 14259698Sdim 15259698Sdim#define DEBUG_TYPE "jit" 16259698Sdim#include "Sparc.h" 17263763Sdim#include "MCTargetDesc/SparcMCExpr.h" 18259698Sdim#include "SparcRelocations.h" 19259698Sdim#include "SparcTargetMachine.h" 20259698Sdim#include "llvm/ADT/Statistic.h" 21259698Sdim#include "llvm/CodeGen/JITCodeEmitter.h" 22259698Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 23259698Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 24259698Sdim#include "llvm/Support/Debug.h" 25259698Sdim 26259698Sdimusing namespace llvm; 27259698Sdim 28259698SdimSTATISTIC(NumEmitted, "Number of machine instructions emitted"); 29259698Sdim 30259698Sdimnamespace { 31259698Sdim 32259698Sdimclass SparcCodeEmitter : public MachineFunctionPass { 33259698Sdim SparcJITInfo *JTI; 34259698Sdim const SparcInstrInfo *II; 35259698Sdim const DataLayout *TD; 36259698Sdim const SparcSubtarget *Subtarget; 37259698Sdim TargetMachine &TM; 38259698Sdim JITCodeEmitter &MCE; 39259698Sdim const std::vector<MachineConstantPoolEntry> *MCPEs; 40259698Sdim bool IsPIC; 41259698Sdim 42259698Sdim void getAnalysisUsage(AnalysisUsage &AU) const { 43259698Sdim AU.addRequired<MachineModuleInfo> (); 44259698Sdim MachineFunctionPass::getAnalysisUsage(AU); 45259698Sdim } 46259698Sdim 47259698Sdim static char ID; 48259698Sdim 49259698Sdimpublic: 50259698Sdim SparcCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) 51259698Sdim : MachineFunctionPass(ID), JTI(0), II(0), TD(0), 52259698Sdim TM(tm), MCE(mce), MCPEs(0), 53259698Sdim IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} 54259698Sdim 55259698Sdim bool runOnMachineFunction(MachineFunction &MF); 56259698Sdim 57259698Sdim virtual const char *getPassName() const { 58259698Sdim return "Sparc Machine Code Emitter"; 59259698Sdim } 60259698Sdim 61259698Sdim /// getBinaryCodeForInstr - This function, generated by the 62259698Sdim /// CodeEmitterGenerator using TableGen, produces the binary encoding for 63259698Sdim /// machine instructions. 64259698Sdim uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const; 65259698Sdim 66259698Sdim void emitInstruction(MachineBasicBlock::instr_iterator MI, 67259698Sdim MachineBasicBlock &MBB); 68259698Sdim 69259698Sdimprivate: 70259698Sdim /// getMachineOpValue - Return binary encoding of operand. If the machine 71259698Sdim /// operand requires relocation, record the relocation and return zero. 72259698Sdim unsigned getMachineOpValue(const MachineInstr &MI, 73259698Sdim const MachineOperand &MO) const; 74259698Sdim 75263763Sdim unsigned getCallTargetOpValue(const MachineInstr &MI, 76263763Sdim unsigned) const; 77263763Sdim unsigned getBranchTargetOpValue(const MachineInstr &MI, 78263763Sdim unsigned) const; 79263763Sdim 80259698Sdim void emitWord(unsigned Word); 81259698Sdim 82259698Sdim unsigned getRelocation(const MachineInstr &MI, 83259698Sdim const MachineOperand &MO) const; 84259698Sdim 85259698Sdim void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc) const; 86259698Sdim void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const; 87259698Sdim void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const; 88259698Sdim void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const; 89259698Sdim}; 90259698Sdim} // end anonymous namespace. 91259698Sdim 92259698Sdimchar SparcCodeEmitter::ID = 0; 93259698Sdim 94259698Sdimbool SparcCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 95259698Sdim SparcTargetMachine &Target = static_cast<SparcTargetMachine &>( 96259698Sdim const_cast<TargetMachine &>(MF.getTarget())); 97259698Sdim 98259698Sdim JTI = Target.getJITInfo(); 99259698Sdim II = Target.getInstrInfo(); 100259698Sdim TD = Target.getDataLayout(); 101259698Sdim Subtarget = &TM.getSubtarget<SparcSubtarget> (); 102259698Sdim MCPEs = &MF.getConstantPool()->getConstants(); 103259698Sdim JTI->Initialize(MF, IsPIC); 104259698Sdim MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ()); 105259698Sdim 106259698Sdim do { 107259698Sdim DEBUG(errs() << "JITTing function '" 108259698Sdim << MF.getName() << "'\n"); 109259698Sdim MCE.startFunction(MF); 110259698Sdim 111259698Sdim for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 112259698Sdim MBB != E; ++MBB){ 113259698Sdim MCE.StartMachineBasicBlock(MBB); 114259698Sdim for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(), 115259698Sdim E = MBB->instr_end(); I != E;) 116259698Sdim emitInstruction(*I++, *MBB); 117259698Sdim } 118259698Sdim } while (MCE.finishFunction(MF)); 119259698Sdim 120259698Sdim return false; 121259698Sdim} 122259698Sdim 123259698Sdimvoid SparcCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, 124259698Sdim MachineBasicBlock &MBB) { 125259698Sdim DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI); 126259698Sdim 127259698Sdim MCE.processDebugLoc(MI->getDebugLoc(), true); 128259698Sdim 129259698Sdim ++NumEmitted; 130259698Sdim 131259698Sdim switch (MI->getOpcode()) { 132259698Sdim default: { 133259698Sdim emitWord(getBinaryCodeForInstr(*MI)); 134259698Sdim break; 135259698Sdim } 136259698Sdim case TargetOpcode::INLINEASM: { 137259698Sdim // We allow inline assembler nodes with empty bodies - they can 138259698Sdim // implicitly define registers, which is ok for JIT. 139259698Sdim if (MI->getOperand(0).getSymbolName()[0]) { 140259698Sdim report_fatal_error("JIT does not support inline asm!"); 141259698Sdim } 142259698Sdim break; 143259698Sdim } 144259698Sdim case TargetOpcode::PROLOG_LABEL: 145259698Sdim case TargetOpcode::EH_LABEL: { 146259698Sdim MCE.emitLabel(MI->getOperand(0).getMCSymbol()); 147259698Sdim break; 148259698Sdim } 149259698Sdim case TargetOpcode::IMPLICIT_DEF: 150259698Sdim case TargetOpcode::KILL: { 151259698Sdim // Do nothing. 152259698Sdim break; 153259698Sdim } 154259698Sdim case SP::GETPCX: { 155259698Sdim report_fatal_error("JIT does not support pseudo instruction GETPCX yet!"); 156259698Sdim break; 157259698Sdim } 158259698Sdim } 159259698Sdim 160259698Sdim MCE.processDebugLoc(MI->getDebugLoc(), false); 161259698Sdim} 162259698Sdim 163259698Sdimvoid SparcCodeEmitter::emitWord(unsigned Word) { 164259698Sdim DEBUG(errs() << " 0x"; 165259698Sdim errs().write_hex(Word) << "\n"); 166259698Sdim MCE.emitWordBE(Word); 167259698Sdim} 168259698Sdim 169259698Sdim/// getMachineOpValue - Return binary encoding of operand. If the machine 170259698Sdim/// operand requires relocation, record the relocation and return zero. 171259698Sdimunsigned SparcCodeEmitter::getMachineOpValue(const MachineInstr &MI, 172259698Sdim const MachineOperand &MO) const { 173259698Sdim if (MO.isReg()) 174259698Sdim return TM.getRegisterInfo()->getEncodingValue(MO.getReg()); 175259698Sdim else if (MO.isImm()) 176259698Sdim return static_cast<unsigned>(MO.getImm()); 177259698Sdim else if (MO.isGlobal()) 178259698Sdim emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO)); 179259698Sdim else if (MO.isSymbol()) 180259698Sdim emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 181259698Sdim else if (MO.isCPI()) 182259698Sdim emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); 183259698Sdim else if (MO.isMBB()) 184259698Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 185259698Sdim else 186259698Sdim llvm_unreachable("Unable to encode MachineOperand!"); 187259698Sdim return 0; 188259698Sdim} 189263763Sdimunsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI, 190263763Sdim unsigned opIdx) const { 191263763Sdim const MachineOperand MO = MI.getOperand(opIdx); 192263763Sdim return getMachineOpValue(MI, MO); 193263763Sdim} 194263763Sdim 195263763Sdimunsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, 196263763Sdim unsigned opIdx) const { 197263763Sdim const MachineOperand MO = MI.getOperand(opIdx); 198263763Sdim return getMachineOpValue(MI, MO); 199263763Sdim} 200263763Sdim 201259698Sdimunsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI, 202259698Sdim const MachineOperand &MO) const { 203259698Sdim 204259698Sdim unsigned TF = MO.getTargetFlags(); 205259698Sdim switch (TF) { 206259698Sdim default: 207263763Sdim case SparcMCExpr::VK_Sparc_None: break; 208263763Sdim case SparcMCExpr::VK_Sparc_LO: return SP::reloc_sparc_lo; 209263763Sdim case SparcMCExpr::VK_Sparc_HI: return SP::reloc_sparc_hi; 210263763Sdim case SparcMCExpr::VK_Sparc_H44: return SP::reloc_sparc_h44; 211263763Sdim case SparcMCExpr::VK_Sparc_M44: return SP::reloc_sparc_m44; 212263763Sdim case SparcMCExpr::VK_Sparc_L44: return SP::reloc_sparc_l44; 213263763Sdim case SparcMCExpr::VK_Sparc_HH: return SP::reloc_sparc_hh; 214263763Sdim case SparcMCExpr::VK_Sparc_HM: return SP::reloc_sparc_hm; 215259698Sdim } 216259698Sdim 217259698Sdim unsigned Opc = MI.getOpcode(); 218259698Sdim switch (Opc) { 219259698Sdim default: break; 220259698Sdim case SP::CALL: return SP::reloc_sparc_pc30; 221259698Sdim case SP::BA: 222259698Sdim case SP::BCOND: 223259698Sdim case SP::FBCOND: return SP::reloc_sparc_pc22; 224259698Sdim case SP::BPXCC: return SP::reloc_sparc_pc19; 225259698Sdim } 226259698Sdim llvm_unreachable("unknown reloc!"); 227259698Sdim} 228259698Sdim 229259698Sdimvoid SparcCodeEmitter::emitGlobalAddress(const GlobalValue *GV, 230259698Sdim unsigned Reloc) const { 231259698Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 232259698Sdim const_cast<GlobalValue *>(GV), 0, 233259698Sdim true)); 234259698Sdim} 235259698Sdim 236259698Sdimvoid SparcCodeEmitter:: 237259698SdimemitExternalSymbolAddress(const char *ES, unsigned Reloc) const { 238259698Sdim MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 239259698Sdim Reloc, ES, 0, 0)); 240259698Sdim} 241259698Sdim 242259698Sdimvoid SparcCodeEmitter:: 243259698SdimemitConstPoolAddress(unsigned CPI, unsigned Reloc) const { 244259698Sdim MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 245259698Sdim Reloc, CPI, 0, false)); 246259698Sdim} 247259698Sdim 248259698Sdimvoid SparcCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, 249259698Sdim unsigned Reloc) const { 250259698Sdim MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 251259698Sdim Reloc, BB)); 252259698Sdim} 253259698Sdim 254259698Sdim 255259698Sdim/// createSparcJITCodeEmitterPass - Return a pass that emits the collected Sparc 256259698Sdim/// code to the specified MCE object. 257259698SdimFunctionPass *llvm::createSparcJITCodeEmitterPass(SparcTargetMachine &TM, 258259698Sdim JITCodeEmitter &JCE) { 259259698Sdim return new SparcCodeEmitter(TM, JCE); 260259698Sdim} 261259698Sdim 262259698Sdim#include "SparcGenCodeEmitter.inc" 263