blob: a3b260fa364ecfa98b2adce12eb8d29aff1919ef [file] [log] [blame]
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +00001//===-- Mips/MipsCodeEmitter.cpp - Convert Mips 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 Mips machine instructions
11// into relocatable machine code.
12//
13//===---------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "jit"
16#include "Mips.h"
17#include "MipsInstrInfo.h"
18#include "MipsRelocations.h"
19#include "MipsSubtarget.h"
20#include "MipsTargetMachine.h"
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +000021#include "MCTargetDesc/MipsBaseInfo.h"
22#include "llvm/ADT/Statistic.h"
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000023#include "llvm/CodeGen/JITCodeEmitter.h"
24#include "llvm/CodeGen/MachineConstantPool.h"
25#include "llvm/CodeGen/MachineFunctionPass.h"
26#include "llvm/CodeGen/MachineInstr.h"
27#include "llvm/CodeGen/MachineJumpTableInfo.h"
28#include "llvm/CodeGen/MachineModuleInfo.h"
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +000029#include "llvm/CodeGen/MachineOperand.h"
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000030#include "llvm/CodeGen/Passes.h"
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +000031#include "llvm/Constants.h"
32#include "llvm/DerivedTypes.h"
33#include "llvm/Function.h"
34#include "llvm/PassManager.h"
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000035#include "llvm/Support/Debug.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/raw_ostream.h"
38#ifndef NDEBUG
39#include <iomanip>
40#endif
41
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000042using namespace llvm;
43
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +000044STATISTIC(NumEmitted, "Number of machine instructions emitted");
45
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000046namespace {
47
48class MipsCodeEmitter : public MachineFunctionPass {
49 MipsJITInfo *JTI;
50 const MipsInstrInfo *II;
51 const TargetData *TD;
52 const MipsSubtarget *Subtarget;
53 TargetMachine &TM;
54 JITCodeEmitter &MCE;
55 const std::vector<MachineConstantPoolEntry> *MCPEs;
56 const std::vector<MachineJumpTableEntry> *MJTEs;
57 bool IsPIC;
58
59 void getAnalysisUsage(AnalysisUsage &AU) const {
60 AU.addRequired<MachineModuleInfo> ();
61 MachineFunctionPass::getAnalysisUsage(AU);
62 }
63
64 static char ID;
65
66 public:
67 MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
68 MachineFunctionPass(ID), JTI(0),
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +000069 II((const MipsInstrInfo *) tm.getInstrInfo()),
70 TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
71 IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000072 }
73
74 bool runOnMachineFunction(MachineFunction &MF);
75
76 virtual const char *getPassName() const {
77 return "Mips Machine Code Emitter";
78 }
79
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +000080 /// getBinaryCodeForInstr - This function, generated by the
81 /// CodeEmitterGenerator using TableGen, produces the binary encoding for
82 /// machine instructions.
83 unsigned getBinaryCodeForInstr(const MachineInstr &MI) const;
84
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000085 void emitInstruction(const MachineInstr &MI);
86
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +000087 private:
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000088
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +000089 void emitWordLE(unsigned Word);
90
91 /// Routines that handle operands which add machine relocations which are
92 /// fixed up by the relocation stage.
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000093 void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +000094 bool MayNeedFarStub) const;
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +000095 void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
96 void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +000097 void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +000098 void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const;
99
100 /// getMachineOpValue - Return binary encoding of operand. If the machine
101 /// operand requires relocation, record the relocation and return zero.
102 unsigned getMachineOpValue(const MachineInstr &MI,
103 const MachineOperand &MO) const;
104
105 unsigned getRelocation(const MachineInstr &MI,
106 const MachineOperand &MO) const;
107
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000108 unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
109
Akira Hatanaka82099682011-12-19 19:52:25 +0000110 unsigned getBranchTargetOpValue(const MachineInstr &MI,
111 unsigned OpNo) const;
Bruno Cardoso Lopesc3f16b32011-10-18 17:50:36 +0000112 unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
113 unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
114 unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
Bruno Cardoso Lopesad6eef42011-11-08 12:47:11 +0000115
116 int emitULW(const MachineInstr &MI);
117 int emitUSW(const MachineInstr &MI);
118 int emitULH(const MachineInstr &MI);
119 int emitULHu(const MachineInstr &MI);
120 int emitUSH(const MachineInstr &MI);
121
122 void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc,
Akira Hatanaka82099682011-12-19 19:52:25 +0000123 int Offset) const;
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000124 };
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +0000125}
126
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000127char MipsCodeEmitter::ID = 0;
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +0000128
129bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
130 JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
131 II = ((const MipsTargetMachine&) MF.getTarget()).getInstrInfo();
132 TD = ((const MipsTargetMachine&) MF.getTarget()).getTargetData();
133 Subtarget = &TM.getSubtarget<MipsSubtarget> ();
134 MCPEs = &MF.getConstantPool()->getConstants();
135 MJTEs = 0;
136 if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
137 JTI->Initialize(MF, IsPIC);
138 MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
139
140 do {
141 DEBUG(errs() << "JITTing function '"
142 << MF.getFunction()->getName() << "'\n");
143 MCE.startFunction(MF);
144
145 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
146 MBB != E; ++MBB){
147 MCE.StartMachineBasicBlock(MBB);
Evan Cheng7c2a4a32011-12-06 22:12:01 +0000148 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +0000149 I != E; ++I)
150 emitInstruction(*I);
151 }
152 } while (MCE.finishFunction(MF));
153
154 return false;
155}
156
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000157unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
158 const MachineOperand &MO) const {
159 // NOTE: This relocations are for static.
160 uint64_t TSFlags = MI.getDesc().TSFlags;
161 uint64_t Form = TSFlags & MipsII::FormMask;
162 if (Form == MipsII::FrmJ)
163 return Mips::reloc_mips_26;
164 if ((Form == MipsII::FrmI || Form == MipsII::FrmFI)
Evan Cheng5a96b3d2011-12-07 07:15:52 +0000165 && MI.isBranch())
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000166 return Mips::reloc_mips_branch;
167 if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi)
168 return Mips::reloc_mips_hi;
169 return Mips::reloc_mips_lo;
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +0000170}
171
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000172unsigned MipsCodeEmitter::getJumpTargetOpValue(const MachineInstr &MI,
173 unsigned OpNo) const {
174 // FIXME: implement
175 return 0;
176}
177
178unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
179 unsigned OpNo) const {
180 // FIXME: implement
181 return 0;
182}
183
Bruno Cardoso Lopesc3f16b32011-10-18 17:50:36 +0000184unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000185 unsigned OpNo) const {
Bruno Cardoso Lopesc3f16b32011-10-18 17:50:36 +0000186 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
187 assert(MI.getOperand(OpNo).isReg());
188 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000189 return (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
Bruno Cardoso Lopesc3f16b32011-10-18 17:50:36 +0000190}
191
192unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000193 unsigned OpNo) const {
Bruno Cardoso Lopesc3f16b32011-10-18 17:50:36 +0000194 // size is encoded as size-1.
195 return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
196}
197
198unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000199 unsigned OpNo) const {
Bruno Cardoso Lopesc3f16b32011-10-18 17:50:36 +0000200 // size is encoded as pos+size-1.
201 return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
202 getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
203}
204
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000205/// getMachineOpValue - Return binary encoding of operand. If the machine
206/// operand requires relocation, record the relocation and return zero.
207unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000208 const MachineOperand &MO) const {
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000209 if (MO.isReg())
210 return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
211 else if (MO.isImm())
212 return static_cast<unsigned>(MO.getImm());
Bruno Cardoso Lopesad6eef42011-11-08 12:47:11 +0000213 else if (MO.isGlobal()) {
214 if (MI.getOpcode() == Mips::ULW || MI.getOpcode() == Mips::USW ||
215 MI.getOpcode() == Mips::ULH || MI.getOpcode() == Mips::ULHu)
216 emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 4);
217 else if (MI.getOpcode() == Mips::USH)
218 emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 8);
219 else
220 emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
221 } else if (MO.isSymbol())
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000222 emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
223 else if (MO.isCPI())
224 emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
225 else if (MO.isJTI())
226 emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
227 else if (MO.isMBB())
228 emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
229 else
230 llvm_unreachable("Unable to encode MachineOperand!");
231 return 0;
232}
233
234void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000235 bool MayNeedFarStub) const {
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000236 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000237 const_cast<GlobalValue *>(GV), 0,
238 MayNeedFarStub));
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000239}
240
Bruno Cardoso Lopesad6eef42011-11-08 12:47:11 +0000241void MipsCodeEmitter::emitGlobalAddressUnaligned(const GlobalValue *GV,
242 unsigned Reloc, int Offset) const {
243 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
244 const_cast<GlobalValue *>(GV), 0, false));
245 MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset() + Offset,
246 Reloc, const_cast<GlobalValue *>(GV), 0, false));
247}
248
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000249void MipsCodeEmitter::
250emitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
251 MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
252 Reloc, ES, 0, 0, false));
253}
254
255void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
256 MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
257 Reloc, CPI, 0, false));
258}
259
260void MipsCodeEmitter::
261emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
262 MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
263 Reloc, JTIndex, 0, false));
264}
265
266void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000267 unsigned Reloc) const {
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000268 MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
269 Reloc, BB));
270}
271
Bruno Cardoso Lopesad6eef42011-11-08 12:47:11 +0000272int MipsCodeEmitter::emitUSW(const MachineInstr &MI) {
273 unsigned src = getMachineOpValue(MI, MI.getOperand(0));
274 unsigned base = getMachineOpValue(MI, MI.getOperand(1));
275 unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
276 // swr src, offset(base)
277 // swl src, offset+3(base)
278 MCE.emitWordLE(
279 (0x2e << 26) | (base << 21) | (src << 16) | (offset & 0xffff));
280 MCE.emitWordLE(
281 (0x2a << 26) | (base << 21) | (src << 16) | ((offset+3) & 0xffff));
282 return 2;
283}
284
285int MipsCodeEmitter::emitULW(const MachineInstr &MI) {
286 unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
287 unsigned base = getMachineOpValue(MI, MI.getOperand(1));
288 unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
289 unsigned at = 1;
290 if (dst != base) {
291 // lwr dst, offset(base)
292 // lwl dst, offset+3(base)
293 MCE.emitWordLE(
294 (0x26 << 26) | (base << 21) | (dst << 16) | (offset & 0xffff));
295 MCE.emitWordLE(
296 (0x22 << 26) | (base << 21) | (dst << 16) | ((offset+3) & 0xffff));
297 return 2;
298 } else {
299 // lwr at, offset(base)
300 // lwl at, offset+3(base)
301 // addu dst, at, $zero
302 MCE.emitWordLE(
303 (0x26 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
304 MCE.emitWordLE(
305 (0x22 << 26) | (base << 21) | (at << 16) | ((offset+3) & 0xffff));
306 MCE.emitWordLE(
307 (0x0 << 26) | (at << 21) | (0x0 << 16) | (dst << 11) | (0x0 << 6) | 0x21);
308 return 3;
309 }
310}
311
312int MipsCodeEmitter::emitUSH(const MachineInstr &MI) {
313 unsigned src = getMachineOpValue(MI, MI.getOperand(0));
314 unsigned base = getMachineOpValue(MI, MI.getOperand(1));
315 unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
316 unsigned at = 1;
317 // sb src, offset(base)
318 // srl at,src,8
319 // sb at, offset+1(base)
320 MCE.emitWordLE(
321 (0x28 << 26) | (base << 21) | (src << 16) | (offset & 0xffff));
322 MCE.emitWordLE(
323 (0x0 << 26) | (0x0 << 21) | (src << 16) | (at << 11) | (0x8 << 6) | 0x2);
324 MCE.emitWordLE(
325 (0x28 << 26) | (base << 21) | (at << 16) | ((offset+1) & 0xffff));
326 return 3;
327}
328
329int MipsCodeEmitter::emitULH(const MachineInstr &MI) {
330 unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
331 unsigned base = getMachineOpValue(MI, MI.getOperand(1));
332 unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
333 unsigned at = 1;
334 // lbu at, offset(base)
335 // lb dst, offset+1(base)
336 // sll dst,dst,8
337 // or dst,dst,at
338 MCE.emitWordLE(
339 (0x24 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
340 MCE.emitWordLE(
341 (0x20 << 26) | (base << 21) | (dst << 16) | ((offset+1) & 0xffff));
342 MCE.emitWordLE(
343 (0x0 << 26) | (0x0 << 21) | (dst << 16) | (dst << 11) | (0x8 << 6) | 0x0);
344 MCE.emitWordLE(
345 (0x0 << 26) | (dst << 21) | (at << 16) | (dst << 11) | (0x0 << 6) | 0x25);
346 return 4;
347}
348
349int MipsCodeEmitter::emitULHu(const MachineInstr &MI) {
350 unsigned dst = getMachineOpValue(MI, MI.getOperand(0));
351 unsigned base = getMachineOpValue(MI, MI.getOperand(1));
352 unsigned offset = getMachineOpValue(MI, MI.getOperand(2));
353 unsigned at = 1;
354 // lbu at, offset(base)
355 // lbu dst, offset+1(base)
356 // sll dst,dst,8
357 // or dst,dst,at
358 MCE.emitWordLE(
359 (0x24 << 26) | (base << 21) | (at << 16) | (offset & 0xffff));
360 MCE.emitWordLE(
361 (0x24 << 26) | (base << 21) | (dst << 16) | ((offset+1) & 0xffff));
362 MCE.emitWordLE(
363 (0x0 << 26) | (0x0 << 21) | (dst << 16) | (dst << 11) | (0x8 << 6) | 0x0);
364 MCE.emitWordLE(
365 (0x0 << 26) | (dst << 21) | (at << 16) | (dst << 11) | (0x0 << 6) | 0x25);
366 return 4;
367}
368
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000369void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
370 DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
371
372 MCE.processDebugLoc(MI.getDebugLoc(), true);
373
374 // Skip pseudo instructions.
375 if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
376 return;
377
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000378
379 switch (MI.getOpcode()) {
Bruno Cardoso Lopesad6eef42011-11-08 12:47:11 +0000380 case Mips::USW:
381 NumEmitted += emitUSW(MI);
382 break;
383 case Mips::ULW:
384 NumEmitted += emitULW(MI);
385 break;
386 case Mips::ULH:
387 NumEmitted += emitULH(MI);
388 break;
389 case Mips::ULHu:
390 NumEmitted += emitULHu(MI);
391 break;
392 case Mips::USH:
393 NumEmitted += emitUSH(MI);
394 break;
395
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000396 default:
397 emitWordLE(getBinaryCodeForInstr(MI));
Bruno Cardoso Lopesad6eef42011-11-08 12:47:11 +0000398 ++NumEmitted; // Keep track of the # of mi's emitted
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000399 break;
400 }
401
402 MCE.processDebugLoc(MI.getDebugLoc(), false);
403}
404
405void MipsCodeEmitter::emitWordLE(unsigned Word) {
406 DEBUG(errs() << " 0x";
407 errs().write_hex(Word) << "\n");
408 MCE.emitWordLE(Word);
409}
410
411/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
412/// code to the specified MCE object.
413FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
Bruno Cardoso Lopes47b92f32011-11-11 22:58:42 +0000414 JITCodeEmitter &JCE) {
Bruno Cardoso Lopesc4cc40c2011-09-14 03:00:41 +0000415 return new MipsCodeEmitter(TM, JCE);
416}
417
Bruno Cardoso Lopesc3f16b32011-10-18 17:50:36 +0000418#include "MipsGenCodeEmitter.inc"