SparcCodeEmitter.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===-- Sparc/SparcCodeEmitter.cpp - Convert Sparc Code to Machine Code ---===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9//
10// This file contains the pass that transforms the Sparc machine instructions
11// into relocatable machine code.
12//
13//===---------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "jit"
16#include "Sparc.h"
17#include "MCTargetDesc/SparcMCExpr.h"
18#include "SparcRelocations.h"
19#include "SparcTargetMachine.h"
20#include "llvm/ADT/Statistic.h"
21#include "llvm/CodeGen/JITCodeEmitter.h"
22#include "llvm/CodeGen/MachineFunctionPass.h"
23#include "llvm/CodeGen/MachineModuleInfo.h"
24#include "llvm/Support/Debug.h"
25
26using namespace llvm;
27
28STATISTIC(NumEmitted, "Number of machine instructions emitted");
29
30namespace {
31
32class SparcCodeEmitter : public MachineFunctionPass {
33  SparcJITInfo *JTI;
34  const SparcInstrInfo *II;
35  const DataLayout *TD;
36  const SparcSubtarget *Subtarget;
37  TargetMachine &TM;
38  JITCodeEmitter &MCE;
39  const std::vector<MachineConstantPoolEntry> *MCPEs;
40  bool IsPIC;
41
42  void getAnalysisUsage(AnalysisUsage &AU) const {
43    AU.addRequired<MachineModuleInfo> ();
44    MachineFunctionPass::getAnalysisUsage(AU);
45  }
46
47  static char ID;
48
49public:
50  SparcCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
51    : MachineFunctionPass(ID), JTI(0), II(0), TD(0),
52      TM(tm), MCE(mce), MCPEs(0),
53      IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
54
55  bool runOnMachineFunction(MachineFunction &MF);
56
57  virtual const char *getPassName() const {
58    return "Sparc Machine Code Emitter";
59  }
60
61  /// getBinaryCodeForInstr - This function, generated by the
62  /// CodeEmitterGenerator using TableGen, produces the binary encoding for
63  /// machine instructions.
64  uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
65
66  void emitInstruction(MachineBasicBlock::instr_iterator MI,
67                       MachineBasicBlock &MBB);
68
69private:
70  /// getMachineOpValue - Return binary encoding of operand. If the machine
71  /// operand requires relocation, record the relocation and return zero.
72  unsigned getMachineOpValue(const MachineInstr &MI,
73                             const MachineOperand &MO) const;
74
75  unsigned getCallTargetOpValue(const MachineInstr &MI,
76                                unsigned) const;
77  unsigned getBranchTargetOpValue(const MachineInstr &MI,
78                                  unsigned) const;
79  unsigned getBranchPredTargetOpValue(const MachineInstr &MI,
80                                      unsigned) const;
81  unsigned getBranchOnRegTargetOpValue(const MachineInstr &MI,
82                                       unsigned) const;
83
84  void emitWord(unsigned Word);
85
86  unsigned getRelocation(const MachineInstr &MI,
87                         const MachineOperand &MO) const;
88
89  void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc) const;
90  void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
91  void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
92  void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const;
93};
94}  // end anonymous namespace.
95
96char SparcCodeEmitter::ID = 0;
97
98bool SparcCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
99  SparcTargetMachine &Target = static_cast<SparcTargetMachine &>(
100                                const_cast<TargetMachine &>(MF.getTarget()));
101
102  JTI = Target.getJITInfo();
103  II = Target.getInstrInfo();
104  TD = Target.getDataLayout();
105  Subtarget = &TM.getSubtarget<SparcSubtarget> ();
106  MCPEs = &MF.getConstantPool()->getConstants();
107  JTI->Initialize(MF, IsPIC);
108  MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
109
110  do {
111    DEBUG(errs() << "JITTing function '"
112        << MF.getName() << "'\n");
113    MCE.startFunction(MF);
114
115    for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
116        MBB != E; ++MBB){
117      MCE.StartMachineBasicBlock(MBB);
118      for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(),
119           E = MBB->instr_end(); I != E;)
120        emitInstruction(*I++, *MBB);
121    }
122  } while (MCE.finishFunction(MF));
123
124  return false;
125}
126
127void SparcCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI,
128                                      MachineBasicBlock &MBB) {
129  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI);
130
131  MCE.processDebugLoc(MI->getDebugLoc(), true);
132
133  ++NumEmitted;
134
135  switch (MI->getOpcode()) {
136  default: {
137    emitWord(getBinaryCodeForInstr(*MI));
138    break;
139  }
140  case TargetOpcode::INLINEASM: {
141    // We allow inline assembler nodes with empty bodies - they can
142    // implicitly define registers, which is ok for JIT.
143    if (MI->getOperand(0).getSymbolName()[0]) {
144      report_fatal_error("JIT does not support inline asm!");
145    }
146    break;
147  }
148  case TargetOpcode::CFI_INSTRUCTION:
149    break;
150  case TargetOpcode::EH_LABEL: {
151    MCE.emitLabel(MI->getOperand(0).getMCSymbol());
152    break;
153  }
154  case TargetOpcode::IMPLICIT_DEF:
155  case TargetOpcode::KILL: {
156    // Do nothing.
157    break;
158  }
159  case SP::GETPCX: {
160    report_fatal_error("JIT does not support pseudo instruction GETPCX yet!");
161    break;
162  }
163  }
164
165  MCE.processDebugLoc(MI->getDebugLoc(), false);
166}
167
168void SparcCodeEmitter::emitWord(unsigned Word) {
169  DEBUG(errs() << "  0x";
170        errs().write_hex(Word) << "\n");
171  MCE.emitWordBE(Word);
172}
173
174/// getMachineOpValue - Return binary encoding of operand. If the machine
175/// operand requires relocation, record the relocation and return zero.
176unsigned SparcCodeEmitter::getMachineOpValue(const MachineInstr &MI,
177                                             const MachineOperand &MO) const {
178  if (MO.isReg())
179    return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
180  else if (MO.isImm())
181    return static_cast<unsigned>(MO.getImm());
182  else if (MO.isGlobal())
183    emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO));
184  else if (MO.isSymbol())
185    emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
186  else if (MO.isCPI())
187    emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
188  else if (MO.isMBB())
189    emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
190  else
191    llvm_unreachable("Unable to encode MachineOperand!");
192  return 0;
193}
194unsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI,
195                                                unsigned opIdx) const {
196  const MachineOperand MO = MI.getOperand(opIdx);
197  return getMachineOpValue(MI, MO);
198}
199
200unsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
201                                                  unsigned opIdx) const {
202  const MachineOperand MO = MI.getOperand(opIdx);
203  return getMachineOpValue(MI, MO);
204}
205
206unsigned SparcCodeEmitter::getBranchPredTargetOpValue(const MachineInstr &MI,
207                                                      unsigned opIdx) const {
208  const MachineOperand MO = MI.getOperand(opIdx);
209  return getMachineOpValue(MI, MO);
210}
211
212unsigned SparcCodeEmitter::getBranchOnRegTargetOpValue(const MachineInstr &MI,
213                                                       unsigned opIdx) const {
214  const MachineOperand MO = MI.getOperand(opIdx);
215  return getMachineOpValue(MI, MO);
216}
217
218unsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI,
219                                         const MachineOperand &MO) const {
220
221  unsigned TF = MO.getTargetFlags();
222  switch (TF) {
223  default:
224  case SparcMCExpr::VK_Sparc_None:  break;
225  case SparcMCExpr::VK_Sparc_LO:    return SP::reloc_sparc_lo;
226  case SparcMCExpr::VK_Sparc_HI:    return SP::reloc_sparc_hi;
227  case SparcMCExpr::VK_Sparc_H44:   return SP::reloc_sparc_h44;
228  case SparcMCExpr::VK_Sparc_M44:   return SP::reloc_sparc_m44;
229  case SparcMCExpr::VK_Sparc_L44:   return SP::reloc_sparc_l44;
230  case SparcMCExpr::VK_Sparc_HH:    return SP::reloc_sparc_hh;
231  case SparcMCExpr::VK_Sparc_HM:    return SP::reloc_sparc_hm;
232  }
233
234  unsigned Opc = MI.getOpcode();
235  switch (Opc) {
236  default: break;
237  case SP::CALL:    return SP::reloc_sparc_pc30;
238  case SP::BA:
239  case SP::BCOND:
240  case SP::FBCOND:  return SP::reloc_sparc_pc22;
241  case SP::BPXCC:   return SP::reloc_sparc_pc19;
242  }
243  llvm_unreachable("unknown reloc!");
244}
245
246void SparcCodeEmitter::emitGlobalAddress(const GlobalValue *GV,
247                                        unsigned Reloc) const {
248  MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
249                                             const_cast<GlobalValue *>(GV), 0,
250                                             true));
251}
252
253void SparcCodeEmitter::
254emitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
255  MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
256                                                 Reloc, ES, 0, 0));
257}
258
259void SparcCodeEmitter::
260emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
261  MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
262                                                    Reloc, CPI, 0, false));
263}
264
265void SparcCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
266                                            unsigned Reloc) const {
267  MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
268                                             Reloc, BB));
269}
270
271
272/// createSparcJITCodeEmitterPass - Return a pass that emits the collected Sparc
273/// code to the specified MCE object.
274FunctionPass *llvm::createSparcJITCodeEmitterPass(SparcTargetMachine &TM,
275                                                 JITCodeEmitter &JCE) {
276  return new SparcCodeEmitter(TM, JCE);
277}
278
279#include "SparcGenCodeEmitter.inc"
280