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