Home | History | Annotate | Download | only in PowerPC
      1 //===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC -----------------===//
      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 defines the PowerPC 32-bit CodeEmitter and associated machinery to
     11 // JIT-compile bitcode to native PowerPC.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "PPC.h"
     16 #include "PPCRelocations.h"
     17 #include "PPCTargetMachine.h"
     18 #include "llvm/CodeGen/JITCodeEmitter.h"
     19 #include "llvm/CodeGen/MachineFunctionPass.h"
     20 #include "llvm/CodeGen/MachineInstrBuilder.h"
     21 #include "llvm/CodeGen/MachineModuleInfo.h"
     22 #include "llvm/IR/Module.h"
     23 #include "llvm/PassManager.h"
     24 #include "llvm/Support/ErrorHandling.h"
     25 #include "llvm/Support/raw_ostream.h"
     26 #include "llvm/Target/TargetOptions.h"
     27 using namespace llvm;
     28 
     29 namespace {
     30   class PPCCodeEmitter : public MachineFunctionPass {
     31     TargetMachine &TM;
     32     JITCodeEmitter &MCE;
     33     MachineModuleInfo *MMI;
     34 
     35     void getAnalysisUsage(AnalysisUsage &AU) const {
     36       AU.addRequired<MachineModuleInfo>();
     37       MachineFunctionPass::getAnalysisUsage(AU);
     38     }
     39 
     40     static char ID;
     41 
     42     /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
     43     /// its address in the function into this pointer.
     44     void *MovePCtoLROffset;
     45   public:
     46 
     47     PPCCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
     48       : MachineFunctionPass(ID), TM(tm), MCE(mce) {}
     49 
     50     /// getBinaryCodeForInstr - This function, generated by the
     51     /// CodeEmitterGenerator using TableGen, produces the binary encoding for
     52     /// machine instructions.
     53     uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
     54 
     55 
     56     MachineRelocation GetRelocation(const MachineOperand &MO,
     57                                     unsigned RelocID) const;
     58 
     59     /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
     60     unsigned getMachineOpValue(const MachineInstr &MI,
     61                                const MachineOperand &MO) const;
     62 
     63     unsigned get_crbitm_encoding(const MachineInstr &MI, unsigned OpNo) const;
     64     unsigned getDirectBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
     65     unsigned getCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
     66     unsigned getAbsDirectBrEncoding(const MachineInstr &MI,
     67                                     unsigned OpNo) const;
     68     unsigned getAbsCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const;
     69 
     70     unsigned getImm16Encoding(const MachineInstr &MI, unsigned OpNo) const;
     71     unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const;
     72     unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
     73     unsigned getTLSRegEncoding(const MachineInstr &MI, unsigned OpNo) const;
     74     unsigned getTLSCallEncoding(const MachineInstr &MI, unsigned OpNo) const;
     75 
     76     const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
     77 
     78     /// runOnMachineFunction - emits the given MachineFunction to memory
     79     ///
     80     bool runOnMachineFunction(MachineFunction &MF);
     81 
     82     /// emitBasicBlock - emits the given MachineBasicBlock to memory
     83     ///
     84     void emitBasicBlock(MachineBasicBlock &MBB);
     85   };
     86 }
     87 
     88 char PPCCodeEmitter::ID = 0;
     89 
     90 /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
     91 /// to the specified MCE object.
     92 FunctionPass *llvm::createPPCJITCodeEmitterPass(PPCTargetMachine &TM,
     93                                                 JITCodeEmitter &JCE) {
     94   return new PPCCodeEmitter(TM, JCE);
     95 }
     96 
     97 bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
     98   assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
     99           MF.getTarget().getRelocationModel() != Reloc::Static) &&
    100          "JIT relocation model must be set to static or default!");
    101 
    102   MMI = &getAnalysis<MachineModuleInfo>();
    103   MCE.setModuleInfo(MMI);
    104   do {
    105     MovePCtoLROffset = 0;
    106     MCE.startFunction(MF);
    107     for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
    108       emitBasicBlock(*BB);
    109   } while (MCE.finishFunction(MF));
    110 
    111   return false;
    112 }
    113 
    114 void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
    115   MCE.StartMachineBasicBlock(&MBB);
    116 
    117   for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
    118     const MachineInstr &MI = *I;
    119     MCE.processDebugLoc(MI.getDebugLoc(), true);
    120     switch (MI.getOpcode()) {
    121     default:
    122       MCE.emitWordBE(getBinaryCodeForInstr(MI));
    123       break;
    124     case TargetOpcode::PROLOG_LABEL:
    125     case TargetOpcode::EH_LABEL:
    126       MCE.emitLabel(MI.getOperand(0).getMCSymbol());
    127       break;
    128     case TargetOpcode::IMPLICIT_DEF:
    129     case TargetOpcode::KILL:
    130       break; // pseudo opcode, no side effects
    131     case PPC::MovePCtoLR:
    132     case PPC::MovePCtoLR8:
    133       assert(TM.getRelocationModel() == Reloc::PIC_);
    134       MovePCtoLROffset = (void*)MCE.getCurrentPCValue();
    135       MCE.emitWordBE(0x48000005);   // bl 1
    136       break;
    137     }
    138     MCE.processDebugLoc(MI.getDebugLoc(), false);
    139   }
    140 }
    141 
    142 unsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI,
    143                                              unsigned OpNo) const {
    144   const MachineOperand &MO = MI.getOperand(OpNo);
    145   assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
    146           MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
    147          (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
    148   return 0x80 >> TM.getRegisterInfo()->getEncodingValue(MO.getReg());
    149 }
    150 
    151 MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO,
    152                                                 unsigned RelocID) const {
    153   // If in PIC mode, we need to encode the negated address of the
    154   // 'movepctolr' into the unrelocated field.  After relocation, we'll have
    155   // &gv-&movepctolr-4 in the imm field.  Once &movepctolr is added to the imm
    156   // field, we get &gv.  This doesn't happen for branch relocations, which are
    157   // always implicitly pc relative.
    158   intptr_t Cst = 0;
    159   if (TM.getRelocationModel() == Reloc::PIC_) {
    160     assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
    161     Cst = -(intptr_t)MovePCtoLROffset - 4;
    162   }
    163 
    164   if (MO.isGlobal())
    165     return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID,
    166                                     const_cast<GlobalValue *>(MO.getGlobal()),
    167                                     Cst, isa<Function>(MO.getGlobal()));
    168   if (MO.isSymbol())
    169     return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
    170                                         RelocID, MO.getSymbolName(), Cst);
    171   if (MO.isCPI())
    172     return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
    173                                            RelocID, MO.getIndex(), Cst);
    174 
    175   if (MO.isMBB())
    176     return MachineRelocation::getBB(MCE.getCurrentPCOffset(),
    177                                     RelocID, MO.getMBB());
    178 
    179   assert(MO.isJTI());
    180   return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
    181                                          RelocID, MO.getIndex(), Cst);
    182 }
    183 
    184 unsigned PPCCodeEmitter::getDirectBrEncoding(const MachineInstr &MI,
    185                                              unsigned OpNo) const {
    186   const MachineOperand &MO = MI.getOperand(OpNo);
    187   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
    188 
    189   MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bx));
    190   return 0;
    191 }
    192 
    193 unsigned PPCCodeEmitter::getCondBrEncoding(const MachineInstr &MI,
    194                                            unsigned OpNo) const {
    195   const MachineOperand &MO = MI.getOperand(OpNo);
    196   MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bcx));
    197   return 0;
    198 }
    199 
    200 unsigned PPCCodeEmitter::getAbsDirectBrEncoding(const MachineInstr &MI,
    201                                                 unsigned OpNo) const {
    202   const MachineOperand &MO = MI.getOperand(OpNo);
    203   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
    204 
    205   llvm_unreachable("Absolute branch relocations unsupported on the old JIT.");
    206 }
    207 
    208 unsigned PPCCodeEmitter::getAbsCondBrEncoding(const MachineInstr &MI,
    209                                               unsigned OpNo) const {
    210   llvm_unreachable("Absolute branch relocations unsupported on the old JIT.");
    211 }
    212 
    213 unsigned PPCCodeEmitter::getImm16Encoding(const MachineInstr &MI,
    214                                           unsigned OpNo) const {
    215   const MachineOperand &MO = MI.getOperand(OpNo);
    216   if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO);
    217 
    218   unsigned RelocID;
    219   switch (MO.getTargetFlags() & PPCII::MO_ACCESS_MASK) {
    220     default: llvm_unreachable("Unsupported target operand flags!");
    221     case PPCII::MO_LO: RelocID = PPC::reloc_absolute_low; break;
    222     case PPCII::MO_HA: RelocID = PPC::reloc_absolute_high; break;
    223   }
    224 
    225   MCE.addRelocation(GetRelocation(MO, RelocID));
    226   return 0;
    227 }
    228 
    229 unsigned PPCCodeEmitter::getMemRIEncoding(const MachineInstr &MI,
    230                                           unsigned OpNo) const {
    231   // Encode (imm, reg) as a memri, which has the low 16-bits as the
    232   // displacement and the next 5 bits as the register #.
    233   assert(MI.getOperand(OpNo+1).isReg());
    234   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 16;
    235 
    236   const MachineOperand &MO = MI.getOperand(OpNo);
    237   if (MO.isImm())
    238     return (getMachineOpValue(MI, MO) & 0xFFFF) | RegBits;
    239 
    240   // Add a fixup for the displacement field.
    241   MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low));
    242   return RegBits;
    243 }
    244 
    245 unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI,
    246                                            unsigned OpNo) const {
    247   // Encode (imm, reg) as a memrix, which has the low 14-bits as the
    248   // displacement and the next 5 bits as the register #.
    249   assert(MI.getOperand(OpNo+1).isReg());
    250   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 14;
    251 
    252   const MachineOperand &MO = MI.getOperand(OpNo);
    253   if (MO.isImm())
    254     return ((getMachineOpValue(MI, MO) >> 2) & 0x3FFF) | RegBits;
    255 
    256   MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low_ix));
    257   return RegBits;
    258 }
    259 
    260 
    261 unsigned PPCCodeEmitter::getTLSRegEncoding(const MachineInstr &MI,
    262                                            unsigned OpNo) const {
    263   llvm_unreachable("TLS not supported on the old JIT.");
    264   return 0;
    265 }
    266 
    267 unsigned PPCCodeEmitter::getTLSCallEncoding(const MachineInstr &MI,
    268                                             unsigned OpNo) const {
    269   llvm_unreachable("TLS not supported on the old JIT.");
    270   return 0;
    271 }
    272 
    273 unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
    274                                            const MachineOperand &MO) const {
    275 
    276   if (MO.isReg()) {
    277     // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
    278     // The GPR operand should come through here though.
    279     assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
    280             MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
    281            MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
    282     return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
    283   }
    284 
    285   assert(MO.isImm() &&
    286          "Relocation required in an instruction that we cannot encode!");
    287   return MO.getImm();
    288 }
    289 
    290 #include "PPCGenCodeEmitter.inc"
    291