LLVM API Documentation

PPCCodeEmitter.cpp

Go to the documentation of this file.
00001 //===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -------*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the PowerPC 32-bit CodeEmitter and associated machinery to
00011 // JIT-compile bytecode to native PowerPC.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "PPCTargetMachine.h"
00016 #include "PPCRelocations.h"
00017 #include "PPC.h"
00018 #include "llvm/Module.h"
00019 #include "llvm/PassManager.h"
00020 #include "llvm/CodeGen/MachineCodeEmitter.h"
00021 #include "llvm/CodeGen/MachineFunctionPass.h"
00022 #include "llvm/CodeGen/MachineInstrBuilder.h"
00023 #include "llvm/CodeGen/Passes.h"
00024 #include "llvm/Support/Debug.h"
00025 #include "llvm/Target/TargetOptions.h"
00026 #include <iostream>
00027 using namespace llvm;
00028 
00029 namespace {
00030   class PPCCodeEmitter : public MachineFunctionPass {
00031     TargetMachine &TM;
00032     MachineCodeEmitter &MCE;
00033 
00034     // Tracks which instruction references which BasicBlock
00035     std::vector<std::pair<MachineBasicBlock*, unsigned*> > BBRefs;
00036     // Tracks where each BasicBlock starts
00037     std::map<MachineBasicBlock*, long> BBLocations;
00038 
00039     /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
00040     ///
00041     int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
00042 
00043   public:
00044     PPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
00045       : TM(T), MCE(M) {}
00046 
00047     const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
00048 
00049     /// runOnMachineFunction - emits the given MachineFunction to memory
00050     ///
00051     bool runOnMachineFunction(MachineFunction &MF);
00052 
00053     /// emitBasicBlock - emits the given MachineBasicBlock to memory
00054     ///
00055     void emitBasicBlock(MachineBasicBlock &MBB);
00056 
00057     /// emitWord - write a 32-bit word to memory at the current PC
00058     ///
00059     void emitWord(unsigned w) { MCE.emitWord(w); }
00060 
00061     /// getValueBit - return the particular bit of Val
00062     ///
00063     unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
00064 
00065     /// getBinaryCodeForInstr - This function, generated by the
00066     /// CodeEmitterGenerator using TableGen, produces the binary encoding for
00067     /// machine instructions.
00068     ///
00069     unsigned getBinaryCodeForInstr(MachineInstr &MI);
00070   };
00071 }
00072 
00073 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
00074 /// machine code emitted.  This uses a MachineCodeEmitter object to handle
00075 /// actually outputting the machine code and resolving things like the address
00076 /// of functions.  This method should returns true if machine code emission is
00077 /// not supported.
00078 ///
00079 bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
00080                                                   MachineCodeEmitter &MCE) {
00081   // Machine code emitter pass for PowerPC
00082   PM.add(new PPCCodeEmitter(*this, MCE));
00083   // Delete machine code for this function after emitting it
00084   PM.add(createMachineCodeDeleter());
00085   return false;
00086 }
00087 
00088 bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
00089   assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
00090           MF.getTarget().getRelocationModel() != Reloc::Static) &&
00091          "JIT relocation model must be set to static or default!");
00092   MCE.startFunction(MF);
00093   MCE.emitConstantPool(MF.getConstantPool());
00094   for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
00095     emitBasicBlock(*BB);
00096   MCE.finishFunction(MF);
00097 
00098   // Resolve branches to BasicBlocks for the entire function
00099   for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
00100     intptr_t Location = BBLocations[BBRefs[i].first];
00101     unsigned *Ref = BBRefs[i].second;
00102     DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location
00103                     << "\n");
00104     unsigned Instr = *Ref;
00105     intptr_t BranchTargetDisp = (Location - (intptr_t)Ref) >> 2;
00106 
00107     switch (Instr >> 26) {
00108     default: assert(0 && "Unknown branch user!");
00109     case 18:  // This is B or BL
00110       *Ref |= (BranchTargetDisp & ((1 << 24)-1)) << 2;
00111       break;
00112     case 16:  // This is BLT,BLE,BEQ,BGE,BGT,BNE, or other bcx instruction
00113       *Ref |= (BranchTargetDisp & ((1 << 14)-1)) << 2;
00114       break;
00115     }
00116   }
00117   BBRefs.clear();
00118   BBLocations.clear();
00119 
00120   return false;
00121 }
00122 
00123 void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
00124   BBLocations[&MBB] = MCE.getCurrentPCValue();
00125   for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
00126     MachineInstr &MI = *I;
00127     unsigned Opcode = MI.getOpcode();
00128     switch (MI.getOpcode()) {
00129     default:
00130       emitWord(getBinaryCodeForInstr(*I));
00131       break;
00132     case PPC::IMPLICIT_DEF_GPR:
00133     case PPC::IMPLICIT_DEF_F8:
00134     case PPC::IMPLICIT_DEF_F4:
00135     case PPC::IMPLICIT_DEF_VRRC:
00136       break; // pseudo opcode, no side effects
00137     case PPC::MovePCtoLR:
00138       assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
00139       break;
00140     }
00141   }
00142 }
00143 
00144 static unsigned enumRegToMachineReg(unsigned enumReg) {
00145   switch (enumReg) {
00146   case PPC::R0 :  case PPC::F0 :  case PPC::V0 : case PPC::CR0:  return  0;
00147   case PPC::R1 :  case PPC::F1 :  case PPC::V1 : case PPC::CR1:  return  1;
00148   case PPC::R2 :  case PPC::F2 :  case PPC::V2 : case PPC::CR2:  return  2;
00149   case PPC::R3 :  case PPC::F3 :  case PPC::V3 : case PPC::CR3:  return  3;
00150   case PPC::R4 :  case PPC::F4 :  case PPC::V4 : case PPC::CR4:  return  4;
00151   case PPC::R5 :  case PPC::F5 :  case PPC::V5 : case PPC::CR5:  return  5;
00152   case PPC::R6 :  case PPC::F6 :  case PPC::V6 : case PPC::CR6:  return  6;
00153   case PPC::R7 :  case PPC::F7 :  case PPC::V7 : case PPC::CR7:  return  7;
00154   case PPC::R8 :  case PPC::F8 :  case PPC::V8 : return  8;
00155   case PPC::R9 :  case PPC::F9 :  case PPC::V9 : return  9;
00156   case PPC::R10:  case PPC::F10:  case PPC::V10: return 10;
00157   case PPC::R11:  case PPC::F11:  case PPC::V11: return 11;
00158   case PPC::R12:  case PPC::F12:  case PPC::V12: return 12;
00159   case PPC::R13:  case PPC::F13:  case PPC::V13: return 13;
00160   case PPC::R14:  case PPC::F14:  case PPC::V14: return 14;
00161   case PPC::R15:  case PPC::F15:  case PPC::V15: return 15;
00162   case PPC::R16:  case PPC::F16:  case PPC::V16: return 16;
00163   case PPC::R17:  case PPC::F17:  case PPC::V17: return 17;
00164   case PPC::R18:  case PPC::F18:  case PPC::V18: return 18;
00165   case PPC::R19:  case PPC::F19:  case PPC::V19: return 19;
00166   case PPC::R20:  case PPC::F20:  case PPC::V20: return 20;
00167   case PPC::R21:  case PPC::F21:  case PPC::V21: return 21;
00168   case PPC::R22:  case PPC::F22:  case PPC::V22: return 22;
00169   case PPC::R23:  case PPC::F23:  case PPC::V23: return 23;
00170   case PPC::R24:  case PPC::F24:  case PPC::V24: return 24;
00171   case PPC::R25:  case PPC::F25:  case PPC::V25: return 25;
00172   case PPC::R26:  case PPC::F26:  case PPC::V26: return 26;
00173   case PPC::R27:  case PPC::F27:  case PPC::V27: return 27;
00174   case PPC::R28:  case PPC::F28:  case PPC::V28: return 28;
00175   case PPC::R29:  case PPC::F29:  case PPC::V29: return 29;
00176   case PPC::R30:  case PPC::F30:  case PPC::V30: return 30;
00177   case PPC::R31:  case PPC::F31:  case PPC::V31: return 31;
00178   default:
00179     std::cerr << "Unhandled reg in enumRegToRealReg!\n";
00180     abort();
00181   }
00182 }
00183 
00184 int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
00185 
00186   int rv = 0; // Return value; defaults to 0 for unhandled cases
00187                   // or things that get fixed up later by the JIT.
00188   if (MO.isRegister()) {
00189     rv = enumRegToMachineReg(MO.getReg());
00190 
00191     // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
00192     // register, not the register number directly.
00193     if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
00194         (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) {
00195       rv = 0x80 >> rv;
00196     }
00197   } else if (MO.isImmediate()) {
00198     rv = MO.getImmedValue();
00199   } else if (MO.isGlobalAddress() || MO.isExternalSymbol()) {
00200     bool isExternal = MO.isExternalSymbol() ||
00201                       MO.getGlobal()->hasWeakLinkage() ||
00202                       MO.getGlobal()->hasLinkOnceLinkage() ||
00203                       (MO.getGlobal()->isExternal() &&
00204                        !MO.getGlobal()->hasNotBeenReadFromBytecode());
00205     unsigned Reloc = 0;
00206     if (MI.getOpcode() == PPC::BL)
00207       Reloc = PPC::reloc_pcrel_bx;
00208     else {
00209       switch (MI.getOpcode()) {
00210       default: MI.dump(); assert(0 && "Unknown instruction for relocation!");
00211       case PPC::LIS:
00212         if (isExternal)
00213           Reloc = PPC::reloc_absolute_ptr_high;   // Pointer to stub
00214         else
00215           Reloc = PPC::reloc_absolute_high;       // Pointer to symbol
00216         break;
00217       case PPC::LA:
00218         assert(!isExternal && "Something in the ISEL changed\n");
00219         Reloc = PPC::reloc_absolute_low;
00220         break;
00221       case PPC::LBZ:
00222       case PPC::LHA:
00223       case PPC::LHZ:
00224       case PPC::LWZ:
00225       case PPC::LFS:
00226       case PPC::LFD:
00227       case PPC::STB:
00228       case PPC::STH:
00229       case PPC::STW:
00230       case PPC::STFS:
00231       case PPC::STFD:
00232         if (isExternal)
00233           Reloc = PPC::reloc_absolute_ptr_low;
00234         else
00235           Reloc = PPC::reloc_absolute_low;
00236         break;
00237       }
00238     }
00239     if (MO.isGlobalAddress())
00240       MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
00241                                           Reloc, MO.getGlobal(), 0));
00242     else
00243       MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(),
00244                                           Reloc, MO.getSymbolName(), 0));
00245   } else if (MO.isMachineBasicBlock()) {
00246     unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
00247     BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC));
00248   } else if (MO.isConstantPoolIndex()) {
00249     unsigned index = MO.getConstantPoolIndex();
00250     unsigned Opcode = MI.getOpcode();
00251     rv = MCE.getConstantPoolEntryAddress(index);
00252     if (Opcode == PPC::LIS || Opcode == PPC::ADDIS) {
00253       // lis wants hi16(addr)
00254       if ((short)rv < 0) rv += 1 << 16;
00255       rv >>= 16;
00256     } else if (Opcode == PPC::LWZ || Opcode == PPC::LA ||
00257                Opcode == PPC::LI ||
00258                Opcode == PPC::LFS || Opcode == PPC::LFD) {
00259       // These load opcodes want lo16(addr)
00260       rv &= 0xffff;
00261     } else {
00262       assert(0 && "Unknown constant pool using instruction!");
00263     }
00264   } else {
00265     std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
00266     abort();
00267   }
00268 
00269   return rv;
00270 }
00271 
00272 #include "PPCGenCodeEmitter.inc"
00273