LLVM API Documentation
00001 //===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -------*- C++ -*-=// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // 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 bitcode 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/MachineModuleInfo.h" 00024 #include "llvm/CodeGen/Passes.h" 00025 #include "llvm/Support/Debug.h" 00026 #include "llvm/Support/Compiler.h" 00027 #include "llvm/Target/TargetOptions.h" 00028 using namespace llvm; 00029 00030 namespace { 00031 class VISIBILITY_HIDDEN PPCCodeEmitter : public MachineFunctionPass { 00032 TargetMachine &TM; 00033 MachineCodeEmitter &MCE; 00034 00035 /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record 00036 /// its address in the function into this pointer. 00037 void *MovePCtoLROffset; 00038 00039 /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr 00040 /// 00041 unsigned getMachineOpValue(const MachineInstr &MI, const MachineOperand &MO); 00042 00043 void getAnalysisUsage(AnalysisUsage &AU) const { 00044 AU.addRequired<MachineModuleInfo>(); 00045 MachineFunctionPass::getAnalysisUsage(AU); 00046 } 00047 00048 public: 00049 static char ID; 00050 PPCCodeEmitter(TargetMachine &T, MachineCodeEmitter &M) 00051 : MachineFunctionPass(&ID), TM(T), MCE(M) {} 00052 00053 const char *getPassName() const { return "PowerPC Machine Code Emitter"; } 00054 00055 /// runOnMachineFunction - emits the given MachineFunction to memory 00056 /// 00057 bool runOnMachineFunction(MachineFunction &MF); 00058 00059 /// emitBasicBlock - emits the given MachineBasicBlock to memory 00060 /// 00061 void emitBasicBlock(MachineBasicBlock &MBB); 00062 00063 /// getValueBit - return the particular bit of Val 00064 /// 00065 unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; } 00066 00067 /// getBinaryCodeForInstr - This function, generated by the 00068 /// CodeEmitterGenerator using TableGen, produces the binary encoding for 00069 /// machine instructions. 00070 /// 00071 unsigned getBinaryCodeForInstr(const MachineInstr &MI); 00072 }; 00073 char PPCCodeEmitter::ID = 0; 00074 } 00075 00076 /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code 00077 /// to the specified MCE object. 00078 FunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM, 00079 MachineCodeEmitter &MCE) { 00080 return new PPCCodeEmitter(TM, MCE); 00081 } 00082 00083 bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 00084 assert((MF.getTarget().getRelocationModel() != Reloc::Default || 00085 MF.getTarget().getRelocationModel() != Reloc::Static) && 00086 "JIT relocation model must be set to static or default!"); 00087 00088 MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>()); 00089 do { 00090 MovePCtoLROffset = 0; 00091 MCE.startFunction(MF); 00092 for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) 00093 emitBasicBlock(*BB); 00094 } while (MCE.finishFunction(MF)); 00095 00096 return false; 00097 } 00098 00099 void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { 00100 MCE.StartMachineBasicBlock(&MBB); 00101 00102 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ 00103 const MachineInstr &MI = *I; 00104 switch (MI.getOpcode()) { 00105 default: 00106 MCE.emitWordBE(getBinaryCodeForInstr(MI)); 00107 break; 00108 case TargetInstrInfo::DBG_LABEL: 00109 case TargetInstrInfo::EH_LABEL: 00110 MCE.emitLabel(MI.getOperand(0).getImm()); 00111 break; 00112 case TargetInstrInfo::IMPLICIT_DEF: 00113 break; // pseudo opcode, no side effects 00114 case PPC::MovePCtoLR: 00115 case PPC::MovePCtoLR8: 00116 assert(TM.getRelocationModel() == Reloc::PIC_); 00117 MovePCtoLROffset = (void*)MCE.getCurrentPCValue(); 00118 MCE.emitWordBE(0x48000005); // bl 1 00119 break; 00120 } 00121 } 00122 } 00123 00124 unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, 00125 const MachineOperand &MO) { 00126 00127 unsigned rv = 0; // Return value; defaults to 0 for unhandled cases 00128 // or things that get fixed up later by the JIT. 00129 if (MO.isReg()) { 00130 rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg()); 00131 00132 // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the 00133 // register, not the register number directly. 00134 if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) && 00135 (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) { 00136 rv = 0x80 >> rv; 00137 } 00138 } else if (MO.isImm()) { 00139 rv = MO.getImm(); 00140 } else if (MO.isGlobal() || MO.isSymbol() || 00141 MO.isCPI() || MO.isJTI()) { 00142 unsigned Reloc = 0; 00143 if (MI.getOpcode() == PPC::BL_Macho || MI.getOpcode() == PPC::BL8_Macho || 00144 MI.getOpcode() == PPC::BL_ELF || MI.getOpcode() == PPC::BL8_ELF || 00145 MI.getOpcode() == PPC::TAILB || MI.getOpcode() == PPC::TAILB8) 00146 Reloc = PPC::reloc_pcrel_bx; 00147 else { 00148 if (TM.getRelocationModel() == Reloc::PIC_) { 00149 assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); 00150 } 00151 switch (MI.getOpcode()) { 00152 default: MI.dump(); assert(0 && "Unknown instruction for relocation!"); 00153 case PPC::LIS: 00154 case PPC::LIS8: 00155 case PPC::ADDIS: 00156 case PPC::ADDIS8: 00157 Reloc = PPC::reloc_absolute_high; // Pointer to symbol 00158 break; 00159 case PPC::LI: 00160 case PPC::LI8: 00161 case PPC::LA: 00162 // Loads. 00163 case PPC::LBZ: 00164 case PPC::LBZ8: 00165 case PPC::LHA: 00166 case PPC::LHA8: 00167 case PPC::LHZ: 00168 case PPC::LHZ8: 00169 case PPC::LWZ: 00170 case PPC::LWZ8: 00171 case PPC::LFS: 00172 case PPC::LFD: 00173 00174 // Stores. 00175 case PPC::STB: 00176 case PPC::STB8: 00177 case PPC::STH: 00178 case PPC::STH8: 00179 case PPC::STW: 00180 case PPC::STW8: 00181 case PPC::STFS: 00182 case PPC::STFD: 00183 Reloc = PPC::reloc_absolute_low; 00184 break; 00185 00186 case PPC::LWA: 00187 case PPC::LD: 00188 case PPC::STD: 00189 case PPC::STD_32: 00190 Reloc = PPC::reloc_absolute_low_ix; 00191 break; 00192 } 00193 } 00194 00195 MachineRelocation R; 00196 if (MO.isGlobal()) { 00197 R = MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 00198 MO.getGlobal(), 0, 00199 isa<Function>(MO.getGlobal())); 00200 } else if (MO.isSymbol()) { 00201 R = MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 00202 Reloc, MO.getSymbolName(), 0); 00203 } else if (MO.isCPI()) { 00204 R = MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 00205 Reloc, MO.getIndex(), 0); 00206 } else { 00207 assert(MO.isJTI()); 00208 R = MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 00209 Reloc, MO.getIndex(), 0); 00210 } 00211 00212 // If in PIC mode, we need to encode the negated address of the 00213 // 'movepctolr' into the unrelocated field. After relocation, we'll have 00214 // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm 00215 // field, we get &gv. This doesn't happen for branch relocations, which are 00216 // always implicitly pc relative. 00217 if (TM.getRelocationModel() == Reloc::PIC_ && Reloc != PPC::reloc_pcrel_bx){ 00218 assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); 00219 R.setConstantVal(-(intptr_t)MovePCtoLROffset - 4); 00220 } 00221 MCE.addRelocation(R); 00222 00223 } else if (MO.isMBB()) { 00224 unsigned Reloc = 0; 00225 unsigned Opcode = MI.getOpcode(); 00226 if (Opcode == PPC::B || Opcode == PPC::BL_Macho || 00227 Opcode == PPC::BLA_Macho || Opcode == PPC::BL_ELF || 00228 Opcode == PPC::BLA_ELF) 00229 Reloc = PPC::reloc_pcrel_bx; 00230 else // BCC instruction 00231 Reloc = PPC::reloc_pcrel_bcx; 00232 MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 00233 Reloc, MO.getMBB())); 00234 } else { 00235 cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; 00236 abort(); 00237 } 00238 00239 return rv; 00240 } 00241 00242 #include "PPCGenCodeEmitter.inc" 00243