PPCCodeEmitter.cpp revision 193323
1193323Sed//===-- PPCCodeEmitter.cpp - JIT Code Emitter for PowerPC32 -------*- C++ -*-=//
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
15193323Sed#include "PPCTargetMachine.h"
16193323Sed#include "PPCRelocations.h"
17193323Sed#include "PPC.h"
18193323Sed#include "llvm/Module.h"
19193323Sed#include "llvm/PassManager.h"
20193323Sed#include "llvm/CodeGen/MachineCodeEmitter.h"
21193323Sed#include "llvm/CodeGen/JITCodeEmitter.h"
22193323Sed#include "llvm/CodeGen/MachineFunctionPass.h"
23193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
24193323Sed#include "llvm/CodeGen/MachineModuleInfo.h"
25193323Sed#include "llvm/CodeGen/Passes.h"
26193323Sed#include "llvm/Support/Debug.h"
27193323Sed#include "llvm/Support/Compiler.h"
28193323Sed#include "llvm/Target/TargetOptions.h"
29193323Sedusing namespace llvm;
30193323Sed
31193323Sednamespace {
32193323Sed  class PPCCodeEmitter {
33193323Sed    TargetMachine &TM;
34193323Sed    MachineCodeEmitter &MCE;
35193323Sed  public:
36193323Sed    PPCCodeEmitter(TargetMachine &tm, MachineCodeEmitter &mce):
37193323Sed        TM(tm), MCE(mce) {}
38193323Sed
39193323Sed    /// getBinaryCodeForInstr - This function, generated by the
40193323Sed    /// CodeEmitterGenerator using TableGen, produces the binary encoding for
41193323Sed    /// machine instructions.
42193323Sed
43193323Sed    unsigned getBinaryCodeForInstr(const MachineInstr &MI);
44193323Sed
45193323Sed    /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
46193323Sed
47193323Sed    unsigned getMachineOpValue(const MachineInstr &MI,
48193323Sed                               const MachineOperand &MO);
49193323Sed
50193323Sed    /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record
51193323Sed    /// its address in the function into this pointer.
52193323Sed
53193323Sed    void *MovePCtoLROffset;
54193323Sed  };
55193323Sed
56193323Sed  template <class CodeEmitter>
57193323Sed  class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass,
58193323Sed      public PPCCodeEmitter
59193323Sed  {
60193323Sed    TargetMachine &TM;
61193323Sed    CodeEmitter &MCE;
62193323Sed
63193323Sed    void getAnalysisUsage(AnalysisUsage &AU) const {
64193323Sed      AU.addRequired<MachineModuleInfo>();
65193323Sed      MachineFunctionPass::getAnalysisUsage(AU);
66193323Sed    }
67193323Sed
68193323Sed  public:
69193323Sed    static char ID;
70193323Sed    Emitter(TargetMachine &tm, CodeEmitter &mce)
71193323Sed      : MachineFunctionPass(&ID), PPCCodeEmitter(tm, mce), TM(tm), MCE(mce) {}
72193323Sed
73193323Sed    const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
74193323Sed
75193323Sed    /// runOnMachineFunction - emits the given MachineFunction to memory
76193323Sed    ///
77193323Sed    bool runOnMachineFunction(MachineFunction &MF);
78193323Sed
79193323Sed    /// emitBasicBlock - emits the given MachineBasicBlock to memory
80193323Sed    ///
81193323Sed    void emitBasicBlock(MachineBasicBlock &MBB);
82193323Sed
83193323Sed    /// getValueBit - return the particular bit of Val
84193323Sed    ///
85193323Sed    unsigned getValueBit(int64_t Val, unsigned bit) { return (Val >> bit) & 1; }
86193323Sed  };
87193323Sed
88193323Sed  template <class CodeEmitter>
89193323Sed    char Emitter<CodeEmitter>::ID = 0;
90193323Sed}
91193323Sed
92193323Sed/// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code
93193323Sed/// to the specified MCE object.
94193323SedFunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM,
95193323Sed                                             MachineCodeEmitter &MCE) {
96193323Sed  return new Emitter<MachineCodeEmitter>(TM, MCE);
97193323Sed}
98193323Sed
99193323SedFunctionPass *llvm::createPPCJITCodeEmitterPass(PPCTargetMachine &TM,
100193323Sed                                                JITCodeEmitter &JCE) {
101193323Sed  return new Emitter<JITCodeEmitter>(TM, JCE);
102193323Sed}
103193323Sed
104193323Sedtemplate <class CodeEmitter>
105193323Sedbool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) {
106193323Sed  assert((MF.getTarget().getRelocationModel() != Reloc::Default ||
107193323Sed          MF.getTarget().getRelocationModel() != Reloc::Static) &&
108193323Sed         "JIT relocation model must be set to static or default!");
109193323Sed
110193323Sed  MCE.setModuleInfo(&getAnalysis<MachineModuleInfo>());
111193323Sed  do {
112193323Sed    MovePCtoLROffset = 0;
113193323Sed    MCE.startFunction(MF);
114193323Sed    for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
115193323Sed      emitBasicBlock(*BB);
116193323Sed  } while (MCE.finishFunction(MF));
117193323Sed
118193323Sed  return false;
119193323Sed}
120193323Sed
121193323Sedtemplate <class CodeEmitter>
122193323Sedvoid Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) {
123193323Sed  MCE.StartMachineBasicBlock(&MBB);
124193323Sed
125193323Sed  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
126193323Sed    const MachineInstr &MI = *I;
127193323Sed    switch (MI.getOpcode()) {
128193323Sed    default:
129193323Sed      MCE.emitWordBE(getBinaryCodeForInstr(MI));
130193323Sed      break;
131193323Sed    case TargetInstrInfo::DBG_LABEL:
132193323Sed    case TargetInstrInfo::EH_LABEL:
133193323Sed      MCE.emitLabel(MI.getOperand(0).getImm());
134193323Sed      break;
135193323Sed    case TargetInstrInfo::IMPLICIT_DEF:
136193323Sed      break; // pseudo opcode, no side effects
137193323Sed    case PPC::MovePCtoLR:
138193323Sed    case PPC::MovePCtoLR8:
139193323Sed      assert(TM.getRelocationModel() == Reloc::PIC_);
140193323Sed      MovePCtoLROffset = (void*)MCE.getCurrentPCValue();
141193323Sed      MCE.emitWordBE(0x48000005);   // bl 1
142193323Sed      break;
143193323Sed    }
144193323Sed  }
145193323Sed}
146193323Sed
147193323Sedunsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
148193323Sed                                           const MachineOperand &MO) {
149193323Sed
150193323Sed  unsigned rv = 0; // Return value; defaults to 0 for unhandled cases
151193323Sed                   // or things that get fixed up later by the JIT.
152193323Sed  if (MO.isReg()) {
153193323Sed    rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg());
154193323Sed
155193323Sed    // Special encoding for MTCRF and MFOCRF, which uses a bit mask for the
156193323Sed    // register, not the register number directly.
157193323Sed    if ((MI.getOpcode() == PPC::MTCRF || MI.getOpcode() == PPC::MFOCRF) &&
158193323Sed        (MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7)) {
159193323Sed      rv = 0x80 >> rv;
160193323Sed    }
161193323Sed  } else if (MO.isImm()) {
162193323Sed    rv = MO.getImm();
163193323Sed  } else if (MO.isGlobal() || MO.isSymbol() ||
164193323Sed             MO.isCPI() || MO.isJTI()) {
165193323Sed    unsigned Reloc = 0;
166193323Sed    if (MI.getOpcode() == PPC::BL_Macho || MI.getOpcode() == PPC::BL8_Macho ||
167193323Sed        MI.getOpcode() == PPC::BL_ELF || MI.getOpcode() == PPC::BL8_ELF ||
168193323Sed        MI.getOpcode() == PPC::TAILB || MI.getOpcode() == PPC::TAILB8)
169193323Sed      Reloc = PPC::reloc_pcrel_bx;
170193323Sed    else {
171193323Sed      if (TM.getRelocationModel() == Reloc::PIC_) {
172193323Sed        assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
173193323Sed      }
174193323Sed      switch (MI.getOpcode()) {
175193323Sed      default: MI.dump(); assert(0 && "Unknown instruction for relocation!");
176193323Sed      case PPC::LIS:
177193323Sed      case PPC::LIS8:
178193323Sed      case PPC::ADDIS:
179193323Sed      case PPC::ADDIS8:
180193323Sed        Reloc = PPC::reloc_absolute_high;       // Pointer to symbol
181193323Sed        break;
182193323Sed      case PPC::LI:
183193323Sed      case PPC::LI8:
184193323Sed      case PPC::LA:
185193323Sed      // Loads.
186193323Sed      case PPC::LBZ:
187193323Sed      case PPC::LBZ8:
188193323Sed      case PPC::LHA:
189193323Sed      case PPC::LHA8:
190193323Sed      case PPC::LHZ:
191193323Sed      case PPC::LHZ8:
192193323Sed      case PPC::LWZ:
193193323Sed      case PPC::LWZ8:
194193323Sed      case PPC::LFS:
195193323Sed      case PPC::LFD:
196193323Sed
197193323Sed      // Stores.
198193323Sed      case PPC::STB:
199193323Sed      case PPC::STB8:
200193323Sed      case PPC::STH:
201193323Sed      case PPC::STH8:
202193323Sed      case PPC::STW:
203193323Sed      case PPC::STW8:
204193323Sed      case PPC::STFS:
205193323Sed      case PPC::STFD:
206193323Sed        Reloc = PPC::reloc_absolute_low;
207193323Sed        break;
208193323Sed
209193323Sed      case PPC::LWA:
210193323Sed      case PPC::LD:
211193323Sed      case PPC::STD:
212193323Sed      case PPC::STD_32:
213193323Sed        Reloc = PPC::reloc_absolute_low_ix;
214193323Sed        break;
215193323Sed      }
216193323Sed    }
217193323Sed
218193323Sed    MachineRelocation R;
219193323Sed    if (MO.isGlobal()) {
220193323Sed      R = MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
221193323Sed                                   MO.getGlobal(), 0,
222193323Sed                                   isa<Function>(MO.getGlobal()));
223193323Sed    } else if (MO.isSymbol()) {
224193323Sed      R = MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
225193323Sed                                       Reloc, MO.getSymbolName(), 0);
226193323Sed    } else if (MO.isCPI()) {
227193323Sed      R = MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
228193323Sed                                          Reloc, MO.getIndex(), 0);
229193323Sed    } else {
230193323Sed      assert(MO.isJTI());
231193323Sed      R = MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
232193323Sed                                          Reloc, MO.getIndex(), 0);
233193323Sed    }
234193323Sed
235193323Sed    // If in PIC mode, we need to encode the negated address of the
236193323Sed    // 'movepctolr' into the unrelocated field.  After relocation, we'll have
237193323Sed    // &gv-&movepctolr-4 in the imm field.  Once &movepctolr is added to the imm
238193323Sed    // field, we get &gv.  This doesn't happen for branch relocations, which are
239193323Sed    // always implicitly pc relative.
240193323Sed    if (TM.getRelocationModel() == Reloc::PIC_ && Reloc != PPC::reloc_pcrel_bx){
241193323Sed      assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
242193323Sed      R.setConstantVal(-(intptr_t)MovePCtoLROffset - 4);
243193323Sed    }
244193323Sed    MCE.addRelocation(R);
245193323Sed
246193323Sed  } else if (MO.isMBB()) {
247193323Sed    unsigned Reloc = 0;
248193323Sed    unsigned Opcode = MI.getOpcode();
249193323Sed    if (Opcode == PPC::B || Opcode == PPC::BL_Macho ||
250193323Sed        Opcode == PPC::BLA_Macho || Opcode == PPC::BL_ELF ||
251193323Sed        Opcode == PPC::BLA_ELF)
252193323Sed      Reloc = PPC::reloc_pcrel_bx;
253193323Sed    else // BCC instruction
254193323Sed      Reloc = PPC::reloc_pcrel_bcx;
255193323Sed    MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
256193323Sed                                               Reloc, MO.getMBB()));
257193323Sed  } else {
258193323Sed    cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n";
259193323Sed    abort();
260193323Sed  }
261193323Sed
262193323Sed  return rv;
263193323Sed}
264193323Sed
265193323Sed#include "PPCGenCodeEmitter.inc"
266193323Sed
267