Home | History | Annotate | Download | only in Sparc
      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