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/Support/Visibility.h"
00026 #include "llvm/Target/TargetOptions.h"
00027 #include <iostream>
00028 using namespace llvm;
00029 
00030 namespace {
00031   class VISIBILITY_HIDDEN PPCCodeEmitter : public MachineFunctionPass {
00032     TargetMachine &TM;
00033     MachineCodeEmitter &MCE;
00034 
00035     /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
00036     ///
00037     int getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
00038 
00039   public:
00040     PPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M)
00041       : TM(T), MCE(M) {}
00042 
00043     const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
00044 
00045     /// runOnMachineFunction - emits the given MachineFunction to memory
00046     ///
00047     bool runOnMachineFunction(MachineFunction &MF);
00048 
00049     /// emitBasicBlock - emits the given MachineBasicBlock to memory
00050     ///
00051     void emitBasicBlock(MachineBasicBlock &MBB);
00052 
00053     /// getValueBit - return the particular bit of Val
00054     ///
00055     unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
00056 
00057     /// getBinaryCodeForInstr - This function, generated by the
00058     /// CodeEmitterGenerator using TableGen, produces the binary encoding for
00059     /// machine instructions.
00060     ///
00061     unsigned getBinaryCodeForInstr(MachineInstr &MI);
00062   };
00063 }
00064 
00065 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
00066 /// machine code emitted.  This uses a MachineCodeEmitter object to handle
00067 /// actually outputting the machine code and resolving things like the address
00068 /// of functions.  This method should returns true if machine code emission is
00069 /// not supported.
00070 ///
00071 bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
00072                                                   MachineCodeEmitter &MCE) {
00073   // Machine code emitter pass for PowerPC
00074   PM.add(new PPCCodeEmitter(*this, MCE));
00075   // Delete machine code for this function after emitting it
00076   PM.add(createMachineCodeDeleter());
00077   return false;
00078 }
00079 
00080 #ifdef __APPLE__ 
00081 extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
00082 #endif
00083 
00084 bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
00085   assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
00086           MF.getTarget().getRelocationModel() != Reloc::Static) &&
00087          "JIT relocation model must be set to static or default!");
00088   do {
00089     MCE.startFunction(MF);
00090     for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
00091       emitBasicBlock(*BB);
00092   } while (MCE.finishFunction(MF));
00093 
00094   return false;
00095 }
00096 
00097 void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
00098   MCE.StartMachineBasicBlock(&MBB);
00099   
00100   for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
00101     MachineInstr &MI = *I;
00102     unsigned Opcode = MI.getOpcode();
00103     switch (MI.getOpcode()) {
00104     default:
00105       MCE.emitWordBE(getBinaryCodeForInstr(*I));
00106       break;
00107     case PPC::IMPLICIT_DEF_GPRC:
00108     case PPC::IMPLICIT_DEF_G8RC:
00109     case PPC::IMPLICIT_DEF_F8:
00110     case PPC::IMPLICIT_DEF_F4:
00111     case PPC::IMPLICIT_DEF_VRRC:
00112       break; // pseudo opcode, no side effects
00113     case PPC::MovePCtoLR:
00114       assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
00115       break;
00116     }
00117   }
00118 }
00119 
00120 int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
00121 
00122   intptr_t rv = 0; // Return value; defaults to 0 for unhandled cases
00123                    // or things that get fixed up later by the JIT.
00124   if (MO.isRegister()) {
00125     rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg());
00126 
00127     // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
00128     // register, not the register number directly.
00129     if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
00130         (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) {
00131       rv = 0x80 >> rv;
00132     }
00133   } else if (MO.isImmediate()) {
00134     rv = MO.getImmedValue();
00135   } else if (MO.isGlobalAddress() || MO.isExternalSymbol()) {
00136     unsigned Reloc = 0;
00137     if (MI.getOpcode() == PPC::BL)
00138       Reloc = PPC::reloc_pcrel_bx;
00139     else {
00140       switch (MI.getOpcode()) {
00141       default: DEBUG(MI.dump()); assert(0 && "Unknown instruction for relocation!");
00142       case PPC::LIS:
00143       case PPC::LIS8:
00144       case PPC::ADDIS8:
00145         Reloc = PPC::reloc_absolute_high;       // Pointer to symbol
00146         break;
00147       case PPC::LI:
00148       case PPC::LI8:
00149       case PPC::LA:
00150       // Loads.
00151       case PPC::LBZ:
00152       case PPC::LHA:
00153       case PPC::LHZ:
00154       case PPC::LWZ:
00155       case PPC::LFS:
00156       case PPC::LFD:
00157       case PPC::LWZ8:
00158       
00159       // Stores.
00160       case PPC::STB:
00161       case PPC::STH:
00162       case PPC::STW:
00163       case PPC::STFS:
00164       case PPC::STFD:
00165         Reloc = PPC::reloc_absolute_low;
00166         break;
00167 
00168       case PPC::LWA:
00169       case PPC::LD:
00170       case PPC::STD:
00171       case PPC::STD_32:
00172         Reloc = PPC::reloc_absolute_low_ix;
00173         break;
00174       }
00175     }
00176     if (MO.isGlobalAddress())
00177       MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(),
00178                                           Reloc, MO.getGlobal(), 0));
00179     else
00180       MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
00181                                           Reloc, MO.getSymbolName(), 0));
00182   } else if (MO.isMachineBasicBlock()) {
00183     unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue();
00184     TM.getJITInfo()->addBBRef(MO.getMachineBasicBlock(), (intptr_t)CurrPC);
00185   } else if (MO.isConstantPoolIndex() || MO.isJumpTableIndex()) {
00186     if (MO.isConstantPoolIndex())
00187       rv = MCE.getConstantPoolEntryAddress(MO.getConstantPoolIndex());
00188     else
00189       rv = MCE.getJumpTableEntryAddress(MO.getJumpTableIndex());
00190 
00191     unsigned Opcode = MI.getOpcode();
00192     if (Opcode == PPC::LIS || Opcode == PPC::LIS8 ||
00193         Opcode == PPC::ADDIS || Opcode == PPC::ADDIS8) {
00194       // lis wants hi16(addr)
00195       if ((short)rv < 0) rv += 1 << 16;
00196       rv >>= 16;
00197     } else if (Opcode == PPC::LWZ || Opcode == PPC::LWZ8 ||
00198                Opcode == PPC::LA ||
00199                Opcode == PPC::LI  || Opcode == PPC::LI8 ||
00200                Opcode == PPC::LFS || Opcode == PPC::LFD) {
00201       // These load opcodes want lo16(addr)
00202       rv &= 0xffff;
00203     } else {
00204       MI.dump();
00205       assert(0 && "Unknown constant pool or jump table using instruction!");
00206     }
00207   } else {
00208     std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
00209     abort();
00210   }
00211 
00212   return rv;
00213 }
00214 
00215 #include "PPCGenCodeEmitter.inc"
00216