1259698Sdim//===-- Sparc/SparcCodeEmitter.cpp - Convert Sparc Code to Machine Code ---===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===---------------------------------------------------------------------===//
9259698Sdim//
10259698Sdim// This file contains the pass that transforms the Sparc machine instructions
11259698Sdim// into relocatable machine code.
12259698Sdim//
13259698Sdim//===---------------------------------------------------------------------===//
14259698Sdim
15259698Sdim#define DEBUG_TYPE "jit"
16259698Sdim#include "Sparc.h"
17263763Sdim#include "MCTargetDesc/SparcMCExpr.h"
18259698Sdim#include "SparcRelocations.h"
19259698Sdim#include "SparcTargetMachine.h"
20259698Sdim#include "llvm/ADT/Statistic.h"
21259698Sdim#include "llvm/CodeGen/JITCodeEmitter.h"
22259698Sdim#include "llvm/CodeGen/MachineFunctionPass.h"
23259698Sdim#include "llvm/CodeGen/MachineModuleInfo.h"
24259698Sdim#include "llvm/Support/Debug.h"
25259698Sdim
26259698Sdimusing namespace llvm;
27259698Sdim
28259698SdimSTATISTIC(NumEmitted, "Number of machine instructions emitted");
29259698Sdim
30259698Sdimnamespace {
31259698Sdim
32259698Sdimclass SparcCodeEmitter : public MachineFunctionPass {
33259698Sdim  SparcJITInfo *JTI;
34259698Sdim  const SparcInstrInfo *II;
35259698Sdim  const DataLayout *TD;
36259698Sdim  const SparcSubtarget *Subtarget;
37259698Sdim  TargetMachine &TM;
38259698Sdim  JITCodeEmitter &MCE;
39259698Sdim  const std::vector<MachineConstantPoolEntry> *MCPEs;
40259698Sdim  bool IsPIC;
41259698Sdim
42259698Sdim  void getAnalysisUsage(AnalysisUsage &AU) const {
43259698Sdim    AU.addRequired<MachineModuleInfo> ();
44259698Sdim    MachineFunctionPass::getAnalysisUsage(AU);
45259698Sdim  }
46259698Sdim
47259698Sdim  static char ID;
48259698Sdim
49259698Sdimpublic:
50259698Sdim  SparcCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
51259698Sdim    : MachineFunctionPass(ID), JTI(0), II(0), TD(0),
52259698Sdim      TM(tm), MCE(mce), MCPEs(0),
53259698Sdim      IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
54259698Sdim
55259698Sdim  bool runOnMachineFunction(MachineFunction &MF);
56259698Sdim
57259698Sdim  virtual const char *getPassName() const {
58259698Sdim    return "Sparc Machine Code Emitter";
59259698Sdim  }
60259698Sdim
61259698Sdim  /// getBinaryCodeForInstr - This function, generated by the
62259698Sdim  /// CodeEmitterGenerator using TableGen, produces the binary encoding for
63259698Sdim  /// machine instructions.
64259698Sdim  uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
65259698Sdim
66259698Sdim  void emitInstruction(MachineBasicBlock::instr_iterator MI,
67259698Sdim                       MachineBasicBlock &MBB);
68259698Sdim
69259698Sdimprivate:
70259698Sdim  /// getMachineOpValue - Return binary encoding of operand. If the machine
71259698Sdim  /// operand requires relocation, record the relocation and return zero.
72259698Sdim  unsigned getMachineOpValue(const MachineInstr &MI,
73259698Sdim                             const MachineOperand &MO) const;
74259698Sdim
75263763Sdim  unsigned getCallTargetOpValue(const MachineInstr &MI,
76263763Sdim                                unsigned) const;
77263763Sdim  unsigned getBranchTargetOpValue(const MachineInstr &MI,
78263763Sdim                                  unsigned) const;
79263763Sdim
80259698Sdim  void emitWord(unsigned Word);
81259698Sdim
82259698Sdim  unsigned getRelocation(const MachineInstr &MI,
83259698Sdim                         const MachineOperand &MO) const;
84259698Sdim
85259698Sdim  void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc) const;
86259698Sdim  void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
87259698Sdim  void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
88259698Sdim  void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const;
89259698Sdim};
90259698Sdim}  // end anonymous namespace.
91259698Sdim
92259698Sdimchar SparcCodeEmitter::ID = 0;
93259698Sdim
94259698Sdimbool SparcCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
95259698Sdim  SparcTargetMachine &Target = static_cast<SparcTargetMachine &>(
96259698Sdim                                const_cast<TargetMachine &>(MF.getTarget()));
97259698Sdim
98259698Sdim  JTI = Target.getJITInfo();
99259698Sdim  II = Target.getInstrInfo();
100259698Sdim  TD = Target.getDataLayout();
101259698Sdim  Subtarget = &TM.getSubtarget<SparcSubtarget> ();
102259698Sdim  MCPEs = &MF.getConstantPool()->getConstants();
103259698Sdim  JTI->Initialize(MF, IsPIC);
104259698Sdim  MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
105259698Sdim
106259698Sdim  do {
107259698Sdim    DEBUG(errs() << "JITTing function '"
108259698Sdim        << MF.getName() << "'\n");
109259698Sdim    MCE.startFunction(MF);
110259698Sdim
111259698Sdim    for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
112259698Sdim        MBB != E; ++MBB){
113259698Sdim      MCE.StartMachineBasicBlock(MBB);
114259698Sdim      for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(),
115259698Sdim           E = MBB->instr_end(); I != E;)
116259698Sdim        emitInstruction(*I++, *MBB);
117259698Sdim    }
118259698Sdim  } while (MCE.finishFunction(MF));
119259698Sdim
120259698Sdim  return false;
121259698Sdim}
122259698Sdim
123259698Sdimvoid SparcCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI,
124259698Sdim                                      MachineBasicBlock &MBB) {
125259698Sdim  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI);
126259698Sdim
127259698Sdim  MCE.processDebugLoc(MI->getDebugLoc(), true);
128259698Sdim
129259698Sdim  ++NumEmitted;
130259698Sdim
131259698Sdim  switch (MI->getOpcode()) {
132259698Sdim  default: {
133259698Sdim    emitWord(getBinaryCodeForInstr(*MI));
134259698Sdim    break;
135259698Sdim  }
136259698Sdim  case TargetOpcode::INLINEASM: {
137259698Sdim    // We allow inline assembler nodes with empty bodies - they can
138259698Sdim    // implicitly define registers, which is ok for JIT.
139259698Sdim    if (MI->getOperand(0).getSymbolName()[0]) {
140259698Sdim      report_fatal_error("JIT does not support inline asm!");
141259698Sdim    }
142259698Sdim    break;
143259698Sdim  }
144259698Sdim  case TargetOpcode::PROLOG_LABEL:
145259698Sdim  case TargetOpcode::EH_LABEL: {
146259698Sdim    MCE.emitLabel(MI->getOperand(0).getMCSymbol());
147259698Sdim    break;
148259698Sdim  }
149259698Sdim  case TargetOpcode::IMPLICIT_DEF:
150259698Sdim  case TargetOpcode::KILL: {
151259698Sdim    // Do nothing.
152259698Sdim    break;
153259698Sdim  }
154259698Sdim  case SP::GETPCX: {
155259698Sdim    report_fatal_error("JIT does not support pseudo instruction GETPCX yet!");
156259698Sdim    break;
157259698Sdim  }
158259698Sdim  }
159259698Sdim
160259698Sdim  MCE.processDebugLoc(MI->getDebugLoc(), false);
161259698Sdim}
162259698Sdim
163259698Sdimvoid SparcCodeEmitter::emitWord(unsigned Word) {
164259698Sdim  DEBUG(errs() << "  0x";
165259698Sdim        errs().write_hex(Word) << "\n");
166259698Sdim  MCE.emitWordBE(Word);
167259698Sdim}
168259698Sdim
169259698Sdim/// getMachineOpValue - Return binary encoding of operand. If the machine
170259698Sdim/// operand requires relocation, record the relocation and return zero.
171259698Sdimunsigned SparcCodeEmitter::getMachineOpValue(const MachineInstr &MI,
172259698Sdim                                             const MachineOperand &MO) const {
173259698Sdim  if (MO.isReg())
174259698Sdim    return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
175259698Sdim  else if (MO.isImm())
176259698Sdim    return static_cast<unsigned>(MO.getImm());
177259698Sdim  else if (MO.isGlobal())
178259698Sdim    emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO));
179259698Sdim  else if (MO.isSymbol())
180259698Sdim    emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
181259698Sdim  else if (MO.isCPI())
182259698Sdim    emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
183259698Sdim  else if (MO.isMBB())
184259698Sdim    emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
185259698Sdim  else
186259698Sdim    llvm_unreachable("Unable to encode MachineOperand!");
187259698Sdim  return 0;
188259698Sdim}
189263763Sdimunsigned SparcCodeEmitter::getCallTargetOpValue(const MachineInstr &MI,
190263763Sdim                                                unsigned opIdx) const {
191263763Sdim  const MachineOperand MO = MI.getOperand(opIdx);
192263763Sdim  return getMachineOpValue(MI, MO);
193263763Sdim}
194263763Sdim
195263763Sdimunsigned SparcCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
196263763Sdim                                                  unsigned opIdx) const {
197263763Sdim  const MachineOperand MO = MI.getOperand(opIdx);
198263763Sdim  return getMachineOpValue(MI, MO);
199263763Sdim}
200263763Sdim
201259698Sdimunsigned SparcCodeEmitter::getRelocation(const MachineInstr &MI,
202259698Sdim                                         const MachineOperand &MO) const {
203259698Sdim
204259698Sdim  unsigned TF = MO.getTargetFlags();
205259698Sdim  switch (TF) {
206259698Sdim  default:
207263763Sdim  case SparcMCExpr::VK_Sparc_None:  break;
208263763Sdim  case SparcMCExpr::VK_Sparc_LO:    return SP::reloc_sparc_lo;
209263763Sdim  case SparcMCExpr::VK_Sparc_HI:    return SP::reloc_sparc_hi;
210263763Sdim  case SparcMCExpr::VK_Sparc_H44:   return SP::reloc_sparc_h44;
211263763Sdim  case SparcMCExpr::VK_Sparc_M44:   return SP::reloc_sparc_m44;
212263763Sdim  case SparcMCExpr::VK_Sparc_L44:   return SP::reloc_sparc_l44;
213263763Sdim  case SparcMCExpr::VK_Sparc_HH:    return SP::reloc_sparc_hh;
214263763Sdim  case SparcMCExpr::VK_Sparc_HM:    return SP::reloc_sparc_hm;
215259698Sdim  }
216259698Sdim
217259698Sdim  unsigned Opc = MI.getOpcode();
218259698Sdim  switch (Opc) {
219259698Sdim  default: break;
220259698Sdim  case SP::CALL:    return SP::reloc_sparc_pc30;
221259698Sdim  case SP::BA:
222259698Sdim  case SP::BCOND:
223259698Sdim  case SP::FBCOND:  return SP::reloc_sparc_pc22;
224259698Sdim  case SP::BPXCC:   return SP::reloc_sparc_pc19;
225259698Sdim  }
226259698Sdim  llvm_unreachable("unknown reloc!");
227259698Sdim}
228259698Sdim
229259698Sdimvoid SparcCodeEmitter::emitGlobalAddress(const GlobalValue *GV,
230259698Sdim                                        unsigned Reloc) const {
231259698Sdim  MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
232259698Sdim                                             const_cast<GlobalValue *>(GV), 0,
233259698Sdim                                             true));
234259698Sdim}
235259698Sdim
236259698Sdimvoid SparcCodeEmitter::
237259698SdimemitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
238259698Sdim  MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
239259698Sdim                                                 Reloc, ES, 0, 0));
240259698Sdim}
241259698Sdim
242259698Sdimvoid SparcCodeEmitter::
243259698SdimemitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
244259698Sdim  MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
245259698Sdim                                                    Reloc, CPI, 0, false));
246259698Sdim}
247259698Sdim
248259698Sdimvoid SparcCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
249259698Sdim                                            unsigned Reloc) const {
250259698Sdim  MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
251259698Sdim                                             Reloc, BB));
252259698Sdim}
253259698Sdim
254259698Sdim
255259698Sdim/// createSparcJITCodeEmitterPass - Return a pass that emits the collected Sparc
256259698Sdim/// code to the specified MCE object.
257259698SdimFunctionPass *llvm::createSparcJITCodeEmitterPass(SparcTargetMachine &TM,
258259698Sdim                                                 JITCodeEmitter &JCE) {
259259698Sdim  return new SparcCodeEmitter(TM, JCE);
260259698Sdim}
261259698Sdim
262259698Sdim#include "SparcGenCodeEmitter.inc"
263