1235633Sdim//===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC -----------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines the PowerPC 32-bit CodeEmitter and associated machinery to 11193323Sed// JIT-compile bitcode to native PowerPC. 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15252723Sdim#include "PPC.h" 16252723Sdim#include "PPCRelocations.h" 17193323Sed#include "PPCTargetMachine.h" 18193323Sed#include "llvm/CodeGen/JITCodeEmitter.h" 19193323Sed#include "llvm/CodeGen/MachineFunctionPass.h" 20193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 21193323Sed#include "llvm/CodeGen/MachineModuleInfo.h" 22252723Sdim#include "llvm/IR/Module.h" 23252723Sdim#include "llvm/PassManager.h" 24198090Srdivacky#include "llvm/Support/ErrorHandling.h" 25198090Srdivacky#include "llvm/Support/raw_ostream.h" 26193323Sed#include "llvm/Target/TargetOptions.h" 27193323Sedusing namespace llvm; 28193323Sed 29193323Sednamespace { 30203954Srdivacky class PPCCodeEmitter : public MachineFunctionPass { 31193323Sed TargetMachine &TM; 32203954Srdivacky JITCodeEmitter &MCE; 33205218Srdivacky MachineModuleInfo *MMI; 34203954Srdivacky 35203954Srdivacky void getAnalysisUsage(AnalysisUsage &AU) const { 36203954Srdivacky AU.addRequired<MachineModuleInfo>(); 37203954Srdivacky MachineFunctionPass::getAnalysisUsage(AU); 38203954Srdivacky } 39203954Srdivacky 40203954Srdivacky static char ID; 41203954Srdivacky 42203954Srdivacky /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record 43203954Srdivacky /// its address in the function into this pointer. 44203954Srdivacky void *MovePCtoLROffset; 45193323Sed public: 46203954Srdivacky 47203954Srdivacky PPCCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) 48212904Sdim : MachineFunctionPass(ID), TM(tm), MCE(mce) {} 49193323Sed 50193323Sed /// getBinaryCodeForInstr - This function, generated by the 51193323Sed /// CodeEmitterGenerator using TableGen, produces the binary encoding for 52193323Sed /// machine instructions. 53235633Sdim uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const; 54193323Sed 55218893Sdim 56218893Sdim MachineRelocation GetRelocation(const MachineOperand &MO, 57218893Sdim unsigned RelocID) const; 58218893Sdim 59193323Sed /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr 60193323Sed unsigned getMachineOpValue(const MachineInstr &MI, 61218893Sdim const MachineOperand &MO) const; 62193323Sed 63218893Sdim unsigned get_crbitm_encoding(const MachineInstr &MI, unsigned OpNo) const; 64218893Sdim unsigned getDirectBrEncoding(const MachineInstr &MI, unsigned OpNo) const; 65218893Sdim unsigned getCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const; 66263509Sdim unsigned getAbsDirectBrEncoding(const MachineInstr &MI, 67263509Sdim unsigned OpNo) const; 68263509Sdim unsigned getAbsCondBrEncoding(const MachineInstr &MI, unsigned OpNo) const; 69218893Sdim 70263509Sdim unsigned getImm16Encoding(const MachineInstr &MI, unsigned OpNo) const; 71218893Sdim unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const; 72218893Sdim unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const; 73252723Sdim unsigned getTLSRegEncoding(const MachineInstr &MI, unsigned OpNo) const; 74263509Sdim unsigned getTLSCallEncoding(const MachineInstr &MI, unsigned OpNo) const; 75218893Sdim 76193323Sed const char *getPassName() const { return "PowerPC Machine Code Emitter"; } 77193323Sed 78193323Sed /// runOnMachineFunction - emits the given MachineFunction to memory 79193323Sed /// 80193323Sed bool runOnMachineFunction(MachineFunction &MF); 81193323Sed 82193323Sed /// emitBasicBlock - emits the given MachineBasicBlock to memory 83193323Sed /// 84193323Sed void emitBasicBlock(MachineBasicBlock &MBB); 85193323Sed }; 86193323Sed} 87198090Srdivacky 88203954Srdivackychar PPCCodeEmitter::ID = 0; 89203954Srdivacky 90193323Sed/// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code 91193323Sed/// to the specified MCE object. 92193323SedFunctionPass *llvm::createPPCJITCodeEmitterPass(PPCTargetMachine &TM, 93193323Sed JITCodeEmitter &JCE) { 94203954Srdivacky return new PPCCodeEmitter(TM, JCE); 95193323Sed} 96193323Sed 97203954Srdivackybool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 98193323Sed assert((MF.getTarget().getRelocationModel() != Reloc::Default || 99193323Sed MF.getTarget().getRelocationModel() != Reloc::Static) && 100193323Sed "JIT relocation model must be set to static or default!"); 101193323Sed 102205218Srdivacky MMI = &getAnalysis<MachineModuleInfo>(); 103205218Srdivacky MCE.setModuleInfo(MMI); 104193323Sed do { 105193323Sed MovePCtoLROffset = 0; 106193323Sed MCE.startFunction(MF); 107193323Sed for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) 108193323Sed emitBasicBlock(*BB); 109193323Sed } while (MCE.finishFunction(MF)); 110193323Sed 111193323Sed return false; 112193323Sed} 113193323Sed 114203954Srdivackyvoid PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { 115193323Sed MCE.StartMachineBasicBlock(&MBB); 116198090Srdivacky 117193323Sed for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ 118193323Sed const MachineInstr &MI = *I; 119198090Srdivacky MCE.processDebugLoc(MI.getDebugLoc(), true); 120193323Sed switch (MI.getOpcode()) { 121193323Sed default: 122193323Sed MCE.emitWordBE(getBinaryCodeForInstr(MI)); 123193323Sed break; 124212904Sdim case TargetOpcode::PROLOG_LABEL: 125203954Srdivacky case TargetOpcode::EH_LABEL: 126205218Srdivacky MCE.emitLabel(MI.getOperand(0).getMCSymbol()); 127193323Sed break; 128203954Srdivacky case TargetOpcode::IMPLICIT_DEF: 129203954Srdivacky case TargetOpcode::KILL: 130193323Sed break; // pseudo opcode, no side effects 131193323Sed case PPC::MovePCtoLR: 132193323Sed case PPC::MovePCtoLR8: 133193323Sed assert(TM.getRelocationModel() == Reloc::PIC_); 134193323Sed MovePCtoLROffset = (void*)MCE.getCurrentPCValue(); 135193323Sed MCE.emitWordBE(0x48000005); // bl 1 136193323Sed break; 137193323Sed } 138198090Srdivacky MCE.processDebugLoc(MI.getDebugLoc(), false); 139193323Sed } 140193323Sed} 141193323Sed 142218893Sdimunsigned PPCCodeEmitter::get_crbitm_encoding(const MachineInstr &MI, 143218893Sdim unsigned OpNo) const { 144218893Sdim const MachineOperand &MO = MI.getOperand(OpNo); 145263509Sdim assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 || 146263509Sdim MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) && 147218893Sdim (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)); 148252723Sdim return 0x80 >> TM.getRegisterInfo()->getEncodingValue(MO.getReg()); 149218893Sdim} 150193323Sed 151218893SdimMachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO, 152218893Sdim unsigned RelocID) const { 153218893Sdim // If in PIC mode, we need to encode the negated address of the 154218893Sdim // 'movepctolr' into the unrelocated field. After relocation, we'll have 155218893Sdim // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm 156218893Sdim // field, we get &gv. This doesn't happen for branch relocations, which are 157218893Sdim // always implicitly pc relative. 158218893Sdim intptr_t Cst = 0; 159218893Sdim if (TM.getRelocationModel() == Reloc::PIC_) { 160218893Sdim assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); 161218893Sdim Cst = -(intptr_t)MovePCtoLROffset - 4; 162218893Sdim } 163218893Sdim 164218893Sdim if (MO.isGlobal()) 165218893Sdim return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID, 166218893Sdim const_cast<GlobalValue *>(MO.getGlobal()), 167218893Sdim Cst, isa<Function>(MO.getGlobal())); 168218893Sdim if (MO.isSymbol()) 169218893Sdim return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 170218893Sdim RelocID, MO.getSymbolName(), Cst); 171218893Sdim if (MO.isCPI()) 172218893Sdim return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 173218893Sdim RelocID, MO.getIndex(), Cst); 174193323Sed 175218893Sdim if (MO.isMBB()) 176218893Sdim return MachineRelocation::getBB(MCE.getCurrentPCOffset(), 177218893Sdim RelocID, MO.getMBB()); 178218893Sdim 179218893Sdim assert(MO.isJTI()); 180218893Sdim return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 181218893Sdim RelocID, MO.getIndex(), Cst); 182218893Sdim} 183198090Srdivacky 184218893Sdimunsigned PPCCodeEmitter::getDirectBrEncoding(const MachineInstr &MI, 185218893Sdim unsigned OpNo) const { 186218893Sdim const MachineOperand &MO = MI.getOperand(OpNo); 187218893Sdim if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO); 188218893Sdim 189218893Sdim MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bx)); 190218893Sdim return 0; 191218893Sdim} 192193323Sed 193218893Sdimunsigned PPCCodeEmitter::getCondBrEncoding(const MachineInstr &MI, 194218893Sdim unsigned OpNo) const { 195218893Sdim const MachineOperand &MO = MI.getOperand(OpNo); 196218893Sdim MCE.addRelocation(GetRelocation(MO, PPC::reloc_pcrel_bcx)); 197218893Sdim return 0; 198218893Sdim} 199198090Srdivacky 200263509Sdimunsigned PPCCodeEmitter::getAbsDirectBrEncoding(const MachineInstr &MI, 201263509Sdim unsigned OpNo) const { 202218893Sdim const MachineOperand &MO = MI.getOperand(OpNo); 203218893Sdim if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO); 204198090Srdivacky 205263509Sdim llvm_unreachable("Absolute branch relocations unsupported on the old JIT."); 206218893Sdim} 207198090Srdivacky 208263509Sdimunsigned PPCCodeEmitter::getAbsCondBrEncoding(const MachineInstr &MI, 209263509Sdim unsigned OpNo) const { 210263509Sdim llvm_unreachable("Absolute branch relocations unsupported on the old JIT."); 211263509Sdim} 212263509Sdim 213263509Sdimunsigned PPCCodeEmitter::getImm16Encoding(const MachineInstr &MI, 214263509Sdim unsigned OpNo) const { 215218893Sdim const MachineOperand &MO = MI.getOperand(OpNo); 216218893Sdim if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO); 217263509Sdim 218263509Sdim unsigned RelocID; 219263509Sdim switch (MO.getTargetFlags() & PPCII::MO_ACCESS_MASK) { 220263509Sdim default: llvm_unreachable("Unsupported target operand flags!"); 221263509Sdim case PPCII::MO_LO: RelocID = PPC::reloc_absolute_low; break; 222263509Sdim case PPCII::MO_HA: RelocID = PPC::reloc_absolute_high; break; 223263509Sdim } 224263509Sdim 225263509Sdim MCE.addRelocation(GetRelocation(MO, RelocID)); 226218893Sdim return 0; 227218893Sdim} 228198090Srdivacky 229218893Sdimunsigned PPCCodeEmitter::getMemRIEncoding(const MachineInstr &MI, 230218893Sdim unsigned OpNo) const { 231218893Sdim // Encode (imm, reg) as a memri, which has the low 16-bits as the 232218893Sdim // displacement and the next 5 bits as the register #. 233218893Sdim assert(MI.getOperand(OpNo+1).isReg()); 234218893Sdim unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 16; 235218893Sdim 236218893Sdim const MachineOperand &MO = MI.getOperand(OpNo); 237218893Sdim if (MO.isImm()) 238218893Sdim return (getMachineOpValue(MI, MO) & 0xFFFF) | RegBits; 239218893Sdim 240218893Sdim // Add a fixup for the displacement field. 241218893Sdim MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low)); 242218893Sdim return RegBits; 243218893Sdim} 244193323Sed 245218893Sdimunsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI, 246218893Sdim unsigned OpNo) const { 247218893Sdim // Encode (imm, reg) as a memrix, which has the low 14-bits as the 248218893Sdim // displacement and the next 5 bits as the register #. 249218893Sdim assert(MI.getOperand(OpNo+1).isReg()); 250218893Sdim unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 14; 251218893Sdim 252218893Sdim const MachineOperand &MO = MI.getOperand(OpNo); 253218893Sdim if (MO.isImm()) 254263509Sdim return ((getMachineOpValue(MI, MO) >> 2) & 0x3FFF) | RegBits; 255218893Sdim 256218893Sdim MCE.addRelocation(GetRelocation(MO, PPC::reloc_absolute_low_ix)); 257218893Sdim return RegBits; 258193323Sed} 259193323Sed 260218893Sdim 261252723Sdimunsigned PPCCodeEmitter::getTLSRegEncoding(const MachineInstr &MI, 262252723Sdim unsigned OpNo) const { 263252723Sdim llvm_unreachable("TLS not supported on the old JIT."); 264252723Sdim return 0; 265252723Sdim} 266252723Sdim 267263509Sdimunsigned PPCCodeEmitter::getTLSCallEncoding(const MachineInstr &MI, 268263509Sdim unsigned OpNo) const { 269263509Sdim llvm_unreachable("TLS not supported on the old JIT."); 270263509Sdim return 0; 271263509Sdim} 272252723Sdim 273218893Sdimunsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, 274218893Sdim const MachineOperand &MO) const { 275218893Sdim 276218893Sdim if (MO.isReg()) { 277263509Sdim // MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand. 278218893Sdim // The GPR operand should come through here though. 279263509Sdim assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 && 280263509Sdim MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) || 281218893Sdim MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7); 282252723Sdim return TM.getRegisterInfo()->getEncodingValue(MO.getReg()); 283218893Sdim } 284218893Sdim 285218893Sdim assert(MO.isImm() && 286218893Sdim "Relocation required in an instruction that we cannot encode!"); 287218893Sdim return MO.getImm(); 288218893Sdim} 289218893Sdim 290193323Sed#include "PPCGenCodeEmitter.inc" 291