1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
7 // FIXME: lb/sb/sh/lh need not be word aligned
8 // FIXME: memory accesses aren't handling sign-extending properly
9 // FIXME: probably have to implement nonaligned access
10 // FIXME: implement malloc()
12 // FIXME: implement an ELF parser based on RandomAccessFile
14 // FEATURE: progress indicator
15 // FEATURE: support n32 abi (passes more arguments in registers)
16 // FEATURE: trap on arithmetic overflows
18 // FEATURE: we always know the value of the pc register; we should emit it as a literal when it appears in computations
19 // FEATURE: emit bytecode rather than .java code (for on-the-fly classloading without javac present in "real" JVMs)
21 /** reads a fully linked MIPS ELF binary image on stdin; writes a .java file on stdout */
24 static String runs = "";
25 static int last_emit = -1;
26 static DataInputStream dis;
27 public static void main(String[] s) throws IOException {
30 System.err.println("usage: java " + MIPS.class.getName() + " <classname> <binary.mips>");
34 String packageName = null;
35 String className = s[0];
36 if (s[0].indexOf('.') != -1) {
37 packageName = s[0].substring(0, s[0].lastIndexOf('.'));
38 className = s[0].substring(s[0].lastIndexOf('.') + 1);
41 System.out.println(prefix + "// This file was generated by MipsToJava");
42 if (packageName != null) System.out.println(prefix + "package " + packageName + ";");
43 System.out.println(prefix + "public class " + className + " {");
44 System.out.println(prefix + "");
45 System.out.println(prefix + " public " + className + "() { }");
46 System.out.println(prefix + "");
47 System.out.println(prefix + " // memory");
48 System.out.println(prefix + " public int mem_read[][] = new int[65535][];");
49 System.out.println(prefix + "");
50 System.out.println(prefix + " // same as mem_read unless a page is write-protected");
51 System.out.println(prefix + " public int mem_write[][] = new int[65535][];");
52 System.out.println(prefix + "");
53 System.out.println(prefix + " // program counter");
54 System.out.println(prefix + " int pc = 0;");
55 System.out.println(prefix + "");
56 System.out.println(prefix + " // temporary");
57 System.out.println(prefix + " int tmp = 0;");
58 System.out.println(prefix + "");
59 System.out.println(prefix + " // MIPS multiply/divide subsystem; 64-bit result");
60 System.out.println(prefix + " long hilo = 0;");
61 System.out.println(prefix + "");
62 System.out.println(prefix + " // General Purpose registers");
63 System.out.println(prefix + " final int r0 = 0;");
64 System.out.println(prefix + " int r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0, r7 = 0,");
65 System.out.println(prefix + " r8 = 0, r9 = 0, r10 = 0, r11 = 0, r12 = 0, r13 = 0, r14 = 0, r15 = 0,");
66 System.out.println(prefix + " r16 = 0, r17 = 0, r18 = 0, r19 = 0, r20 = 0, r21 = 0, r22 = 0, r23 = 0,");
67 System.out.println(prefix + " r24 = 0, r25 = 0, r26 = 0, r27 = 0, r28 = 0, r29 = 0, r30 = 0, r31 = 0;");
68 System.out.println(prefix + "");
70 dis = new DataInputStream(new FileInputStream(s[1]));
72 // read the ELF header
73 if (dis.readByte() != 0x7f || dis.readByte() != 'E' || dis.readByte() != 'L' || dis.readByte() != 'F')
74 throw new RuntimeException("input file is not an ELF binary");
77 if (dis.readShort() != 2)
78 throw new RuntimeException("binary is not a linked executable");
80 if (dis.readShort() != 8)
81 throw new RuntimeException("binary is not a MIPS R3000 binary");
85 int entry_point = dis.readInt();
86 String entry_point_string = Long.toString(entry_point & 0xffffffffL, 16);
88 int ph_offset = dis.readInt();
89 int sh_offset = dis.readInt();
90 if (ph_offset == 0) throw new RuntimeException("binary is not statically linked");
94 int ph_entry_size = dis.readShort();
95 int ph_num_entries = dis.readShort();
96 int sh_entry_size = dis.readShort();
97 int sh_num_entries = dis.readShort();
98 int string_table_section_number = dis.readShort();
100 int skipamount = sh_offset - (4 + 12 + 2 + 2 + 4 + 4 + 4 + 4 + 4 + 2 + 2 + 2 + 2 + 2 + 2);
101 while (skipamount>0) skipamount -= (int)dis.skip(skipamount);
103 int[] p_type = new int[sh_num_entries];
104 int[] p_ofs = new int[sh_num_entries];
105 int[] addr = new int[sh_num_entries];
106 int[] p_size = new int[sh_num_entries];
107 int[] p_name = new int[sh_num_entries];
108 for(int i=0; i<sh_num_entries; i++) {
109 p_name[i] = dis.readInt();
110 p_type[i] = dis.readInt();
112 addr[i] = dis.readInt();
113 p_ofs[i] = dis.readInt();
114 p_size[i] = dis.readInt();
115 dis.skip(sh_entry_size - 4 * 6);
119 dis = new DataInputStream(new FileInputStream(s[1]));
121 int seek = p_ofs[string_table_section_number];
122 while (seek > 0) seek -= dis.skip(seek);
123 char[] stringTable = new char[p_size[string_table_section_number]];
124 for(int i=0; i<p_size[string_table_section_number]; i++)
125 stringTable[i] = (char)dis.readByte();
128 dis = new DataInputStream(new FileInputStream(s[1]));
131 for(int i=0; i<sh_num_entries; i++) {
134 for(int j=p_name[i]; j<stringTable.length && stringTable[j] != 0; j++) name += stringTable[j];
135 System.out.println();
136 System.out.println(prefix + "// section \"" + name +
137 "\" #" + i + "; file offset 0x" + Long.toString(p_ofs[i] & 0xffffffffL, 16) +
138 ", vma 0x" + Long.toString(addr[i] & 0xffffffffL, 16) +
139 ", size 0x" + Long.toString(p_size[i] & 0xffffffff, 16));
141 if (name.equals(".sdata")) {
142 if (last_emit != -1) {
143 System.out.println(prefix + " case 0x" + Long.toString((last_emit & 0xffffffffL) + 0x1000, 16) + ": return;");
144 System.out.println(prefix + " default: throw new Error(\"invalid address 0x\" + Long.toString(pc&0xffffffffL,16));");
145 System.out.println(prefix + " }");
146 System.out.println(prefix + " }");
149 pos = 0; dis.close(); dis = new DataInputStream(new FileInputStream(s[1]));
150 while(pos < p_ofs[i]) pos += dis.skip(p_ofs[i] - pos);
151 String base = "0x" + Long.toString((addr[i] & 0xffff0000L) >> 16, 16);
152 System.out.println(prefix + " private void initData() {");
153 System.out.println(prefix + " r28 = 0x" + Long.toString((addr[i] - Short.MIN_VALUE - 12) & 0xffffffffL, 16) + ";");
154 System.out.println(prefix + " mem_read[" + base + "] = mem_write[" + base + "] = new int[65535];");
155 for(long k=addr[i] & 0xffffffffL; k<((addr[i] + p_size[i]) & 0xffffffffL); k += 4)
156 System.out.println(prefix + " mem_write[" + base + "][0x" + Long.toString(k & 0xffff, 16) + "] = 0x" +
157 Long.toString(dis.readInt() & 0xffffffffL, 16) + ";");
158 System.out.println(prefix + " }");
160 } else if (name.equals(".text") /*|| name.equals(".init")*/) {
161 if (pos > p_ofs[i]) { pos = 0; dis.close(); dis = new DataInputStream(new FileInputStream(s[1])); }
162 while(pos < p_ofs[i]) pos += dis.skip(p_ofs[i] - pos);
163 int remaining = p_size[i];
164 for(int ofs = addr[i]; ofs < addr[i] + p_size[i];) {
165 String base = Long.toString(ofs & 0xffffff00L, 16);
166 int len = Math.min(((ofs + 0x100) & 0xffffff00) - ofs, remaining);
175 if (last_emit != -1) {
176 System.out.println(prefix + " case 0x" + Long.toString((last_emit & 0xffffffffL) + 0x1000, 16) + ": return;");
177 System.out.println(prefix + " default: throw new Error(\"invalid address 0x\" + Long.toString(pc&0xffffffffL,16));");
178 System.out.println(prefix + " }");
179 System.out.println(prefix + " }");
183 System.out.println();
184 System.out.println(prefix + " public static void main(String[] s) { new " + className + "().main(); }");
185 System.out.println();
186 System.out.println(prefix + " public void main() {");
187 System.out.println();
188 System.out.println(prefix + " // allocate the stack");
189 System.out.println(prefix + " mem_read[1] = mem_write[1] = new int[65535];");
190 System.out.println();
191 System.out.println(prefix + " // set the stack pointer");
192 System.out.println(prefix + " r29 = 0x0001ff00;");
193 System.out.println();
194 System.out.println(prefix + " // set the \"return address\" from _start to point at the \"magic exit address\" (0xdeadbeef)");
195 System.out.println(prefix + " r31 = 0xdeadbeef;");
196 System.out.println();
197 System.out.println(prefix + " // read in the .data segment");
198 System.out.println(prefix + " initData();");
199 System.out.println();
200 System.out.println(prefix + " trampoline(0x" + entry_point_string + ");");
201 System.out.println();
202 System.out.println(prefix + " }");
204 System.out.println();
205 System.out.println(prefix + " public void trampoline(int pc) {");
206 System.out.println(prefix + " this.pc = pc;");
207 System.out.println(prefix + " while(true) {");
208 System.out.println(prefix + " switch(this.pc & 0xffffff00) {");
209 System.out.println(prefix + " case 0xdeadbe00: System.out.println(\"exiting with return value \" + r2); System.exit(r2); continue;");
210 System.out.print(runs);
211 System.out.println(prefix + " default: throw new Error(\"invalid address 0x\" + Long.toString(this.pc&0xffffffffL,16));");
212 System.out.println(prefix + " }");
213 System.out.println(prefix + " }");
214 System.out.println(prefix + " }");
215 System.out.println(prefix + "}");
218 static int _instruction;
219 static boolean readnext = true;
221 /** reads <tt>numbytes</tt> from the stream, emitting <tt>case</tt> blocks starting at vaddr <tt>ofs</tt> */
222 static void emit(int vaddr, int numbytes, DataInputStream dis) throws IOException {
223 if (last_emit != -1 && ((last_emit & 0xffffff00) != (vaddr & 0xffffff00))) {
224 System.out.println(prefix + " case 0x" + Long.toString((last_emit & 0xffffffffL) + 0x1000, 16) + ": return;");
225 System.out.println(prefix + " default: throw new Error(\"invalid address 0x\" + Long.toString(pc&0xffffffffL,16));");
226 System.out.println(prefix + " }");
227 System.out.println(prefix + " }");
229 if (last_emit == -1 || ((last_emit & 0xffffff00) != (vaddr & 0xffffff00))) {
230 System.out.println("");
231 System.out.println(prefix + " private void run_" + Long.toString(vaddr & 0xffffff00L,16) + "() {");
232 runs += " case 0x" + Long.toString(vaddr & 0xffffff00L,16) +
233 ": run_" + Long.toString(vaddr & 0xffffff00L,16) + "(); continue;\n";
234 System.out.println(prefix + " switch(pc) {");
238 OUTER: for(ofs = vaddr; ofs < vaddr + numbytes; ofs+=4) {
239 if (readnext) _instruction = dis.readInt();
242 String istring = Long.toString(_instruction & 0xffffffffL, 16);
243 while(istring.length() < 8) istring = "0" + istring;
244 String ostring = Long.toString(ofs & 0xffffffffL, 16);
245 while(ostring.length() < 8) ostring = "0" + ostring;
246 System.out.print(prefix + " /* " + istring + " */ case 0x" + ostring + ": System.out.println(\"pc=0x\" + Long.toString(pc&0xffffffffL,16));");
248 emit_instruction(ofs, _instruction);
250 } catch (EOFException e) {
251 emit(ofs, " // warning, reached EOF before section end");
257 private static void emit_instruction(int ofs, int instruction) throws IOException {
258 int op = (instruction >>> 26) & 0xff; // bits 26-31
259 int rs = (instruction >> 21) & 0x1f; // bits 21-25
260 int rt = (instruction >> 16) & 0x1f; // bits 16-20
261 int rd = (instruction >> 11) & 0x1f; // bits 11-15
262 int shamt = (instruction >> 6) & 0x1f; // bits 6-10
263 int subcode = instruction & 0x3f; // bits 0-5
265 int branch_offset = (((instruction & 0x8000) << 16) | ((instruction & 0x7fff))) * 4;
266 int jump_target = (instruction & 0x03ffffff) * 4;
267 int signed_immediate = (int)((short)(instruction & 0xffff));
268 int unsigned_immediate = instruction & 0xffff;
276 if (instruction == 0) emit(ofs, " /* NOP */;"); // NOP
277 else emit(ofs, " r" + rd + " = r" + rt + " << " + shamt + ";"); // SLL
280 case 1: throw new Error("opcode 0, subcode 1 is not part of the MIPS I instruction set");
283 emit(ofs, " r" + rd + " = r" + rt + " >>> " + shamt + ";"); // SRL
287 emit(ofs, " r" + rd + " = r" + rt + " >> " + shamt + ";"); // SRA
291 emit(ofs, " r" + rd + " = r" + rt + " << (r" + rs + " % 32);"); // SLLV
294 case 5: throw new Error("opcode 0, subcode 5 is not part of the MIPS I instruction set");
297 emit(ofs, " r" + rd + " = r" + rs + " >>> (r" + rt + " % 32);"); // SRLV
301 emit(ofs, " r" + rd + " = r" + rs + " >> (r" + rt + " % 32);"); // SRAV
305 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
306 emit(ofs, " pc = r" + rs + "; return;"); // JR
310 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
311 emit(ofs, " r" + rd + " = pc + 8; pc = r" + rs + "; return;"); // JALR
314 case 10: throw new Error("opcode 0, subcode 10 is not part of the MIPS I instruction set");
315 case 11: throw new Error("opcode 0, subcode 11 is not part of the MIPS I instruction set");
318 emit(ofs, " syscall(" + ((instruction & 0x07ffffc0) >> 6) + ");"); // SYSCALL
322 emit(ofs, " /* BREAKPOINT */");
325 case 14: throw new Error("opcode 0, subcode 14 is not part of the MIPS I instruction set");
326 case 15: throw new Error("opcode 0, subcode 15 is not part of the MIPS I instruction set");
329 emit(ofs, " r" + rd + " = (int)(hilo >>> 32);"); // MFHI
333 emit(ofs, " hilo = (hilo & 0x00000000ffffffffL) | ((r" + rs + " & 0xffffffffL) << 32);"); // MTHI
337 emit(ofs, " r" + rd + " = (int)hilo;"); // MFLO
341 emit(ofs, " hilo = (hilo & 0xffffffff00000000L) | (r" + rs + " & 0xffffffffL);"); // MTLO
344 case 20: throw new Error("opcode 0, subcode 20 is not part of the MIPS I instruction set");
345 case 22: throw new Error("opcode 0, subcode 22 is not part of the MIPS I instruction set");
346 case 23: throw new Error("opcode 0, subcode 23 is not part of the MIPS I instruction set");
349 emit(ofs, " hilo = ((long)r" + rs + ") * ((long)r" + rt + ");"); // MULT
353 emit(ofs, " hilo = (r" + rs + " & 0xffffffffL) * (r" + rt + " & 0xffffffffL);"); // MULTU
357 emit(ofs, " hilo = (((r" + rs + " % r" + rt +") & 0xffffffffL) << 32) | ((r" + rs + " / r" + rt +") & 0xffffffffL);"); // DIV
361 emit(ofs, " hilo = (((r" + rs + " & 0xffffffffL) % (r" + rt +" & 0xffffffffL)) << 32) | " + // DIVU
362 "((r" + rs + " & 0xffffffffL) / (r" + rt +" & 0xffffffffL));");
365 case 28: throw new Error("opcode 0, subcode 28 is not part of the MIPS I instruction set");
366 case 29: throw new Error("opcode 0, subcode 29 is not part of the MIPS I instruction set");
367 case 30: throw new Error("opcode 0, subcode 30 is not part of the MIPS I instruction set");
368 case 31: throw new Error("opcode 0, subcode 31 is not part of the MIPS I instruction set");
371 emit(ofs, " r" + rd + " = r" + rs + " + r" + rt + ";"); // ADD
375 emit(ofs, " r" + rd + " = (int)(((r" + rs + " & 0xffffffffL) + (r" + rt + " & 0xffffffffL)));"); // ADDU
379 emit(ofs, " r" + rd + " = r" + rs + " - r" + rt + ";"); // SUB
383 emit(ofs, " r" + rd + " = (int)(((r" + rs + " & 0xffffffffL) - (r" + rt + " & 0xffffffffL)));"); // SUBU
387 emit(ofs, " r" + rd + " = r" + rs + " & r" + rt + ";"); // AND
391 emit(ofs, " r" + rd + " = r" + rs + " | r" + rt + ";"); // OR
395 emit(ofs, " r" + rd + " = r" + rs + " ^ r" + rt + ";"); // XOR
399 emit(ofs, " r" + rd + " = ~(r" + rs + " | r" + rt + ");"); // NOR
402 case 40: throw new Error("opcode 0, subcode 40 is not part of the MIPS I instruction set");
403 case 41: throw new Error("opcode 0, subcode 41 is not part of the MIPS I instruction set");
406 emit(ofs, " r" + rd + " = (r" + rs + " < r" + rt + ") ? 1 : 0;"); // SLT
410 emit(ofs, " r" + rd + " = ((r" + rs + " & 0xffffffffL) < (r" + rt + " & 0xffffffffL)) ? 1 : 0;"); // SLTU
413 case 44: case 45: case 46: case 47: case 48: case 49: case 50: case 51: case 52: case 53: case 54:
414 case 55: case 56: case 57: case 58: case 59: case 60: case 61: case 62: case 63:
415 throw new Error("opcode 0, subcode " + subcode + " is not part of the MIPS I instruction set");
417 throw new Error("opcode 0, subcode " + subcode + " is not a valid MIPS instruction");
425 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
426 emit(ofs, " if (r" + rs + " < 0) { pc += " + (branch_offset + 4) + "; return; }; "); // BLTZ
430 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
431 emit(ofs, " if (r" + rs + " >= 0) { pc += " + (branch_offset + 4) + "; return; }; "); // BGEZ
435 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
436 emit(ofs, " r31 = pc + 4; if (r" + rs + " < 0) { pc += " + (branch_offset + 4) + "; return; }; "); // BLTZAL
440 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
441 emit(ofs, " r31 = pc + 4; if (r" + rs + " >= 0) { pc += " + (branch_offset + 4) + "; return; }; "); // BGEZAL
444 default: throw new Error("opcode 1, subcode " + rt + " is not part of the MIPS I instruction set");
450 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
451 emit(ofs, " pc &= 0xf0000000; pc |= 0x" + Long.toString(jump_target & 0xffffffffL, 16) + "; return;"); // J
455 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
456 emit(ofs, " r31 = pc + 4; pc &= 0xf0000000; pc |= 0x" + Long.toString(jump_target & 0xffffffffL, 16) + "; return;"); // JAL
460 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
461 emit(ofs, " if (r" + rs + " == r" + rt + ") { pc += 0x" + Long.toString((branch_offset + 4) & 0xffffffffL, 16) + "; return; }; "); // BEQ
465 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
466 emit(ofs, " if (r" + rs + " != r" + rt + ") { pc += 0x" + Long.toString((branch_offset + 4) & 0xffffffffL, 16) + "; return; }; "); // BNE
470 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
471 emit(ofs, " if (r" + rs + " <= 0) { pc += 0x" + Long.toString((branch_offset + 4) & 0xffffffffL, 16) + "; return; }; "); // BLEZ
475 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
476 emit(ofs, " if (r" + rs + " > 0) { pc += 0x" + Long.toString((branch_offset + 4) & 0xffffffffL, 16) + "; return; }; "); // BGTZ
480 emit(ofs, " r" + rt + " = r" + rs + " + " + signed_immediate + ";"); // ADDI[U]
484 emit(ofs, " r" + rt + " = (r" + rs + " < " + signed_immediate + ") ? 1 : 0;"); // SLTI
488 emit(ofs, " r" + rt + " = ((r" + rs + " & 0xffffffffL) < (" + signed_immediate + " & 0xffffffffL)) ? 1 : 0;"); // SLTIU
492 emit(ofs, " r" + rt + " = r" + rs + " & " + unsigned_immediate + ";"); // ANDI
496 emit(ofs, " r" + rt + " = r" + rs + " | " + unsigned_immediate + ";"); // ORI
500 emit(ofs, " r" + rt + " = r" + rs + " ^ " + unsigned_immediate + ";"); // XORI
504 emit(ofs, " r" + rt + " = " + unsigned_immediate + " << 16;"); // LUI
507 case 16: /* throw new Error("coprocessor instructions (opcode 16) are not implemented"); */
508 emit(ofs, " throw new Error(\"coprocessor instructions (opcode 16) are not implemented\");");
510 case 17: throw new Error("coprocessor instructions (opcode 17) are not implemented");
511 case 18: throw new Error("coprocessor instructions (opcode 18) are not implemented");
513 case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28:
514 throw new Error("opcode " + op + " is not part of the MIPS I instruction set @" + Long.toString(ofs & 0xffffffffL, 16));
517 String dest = "(r" + rs + " + " + signed_immediate + ")";
518 emit(ofs, " tmp = mem_read[" + dest + ">>>16][" + dest + " & 0xffff]; r" + rt + " = ((tmp & 0x80) << 24) | (tmp & 0x7f);"); // LB
523 String dest = "(r" + rs + " + " + signed_immediate + ")";
524 emit(ofs, " tmp = mem_read[" + dest + ">>>16][" + dest + " & 0xffff]; r" + rt + " = ((tmp & 0x8000) << 16) | (tmp & 0x7fff);"); // LH
529 emit(ofs, " throw new Error(\"LWL (opcode 34) is not supported; are you sure you used -mstrict-align?\");");
533 String dest = "(r" + rs + " + " + signed_immediate + ")";
534 emit(ofs, " r" + rt + " = mem_read[" + dest + ">>>16][" + dest + " & 0xffff];"); // LW
539 String dest = "(r" + rs + " + " + signed_immediate + ")";
540 emit(ofs, " r" + rt + " = mem_read[" + dest + ">>>16][" + dest + " & 0xffff] & 0xff;"); // LBU
545 String dest = "(r" + rs + " + " + signed_immediate + ")";
546 emit(ofs, " r" + rt + " = mem_read[" + dest + ">>>16][" + dest + " & 0xffff] & 0xffff;"); // LHU
551 emit(ofs, " throw new Error(\"LWR (opcode 38) is not supported; are you sure you used -mstrict-align?\");");
554 case 39: throw new Error("opcode 39 is not part of the MIPS I instruction set");
557 String dest = "(r" + rs + " + " + signed_immediate + ")";
558 emit(ofs, " tmp = mem_read[" + dest + ">>>16][" + dest + " & 0xffff]; " +
559 "mem_write[" + dest + ">>>16][" + dest + " & 0xffff] = (tmp & 0xffffff00) | (r" + rt + " & 0xff);"); // SB
564 String dest = "(r" + rs + " + " + signed_immediate + ")";
565 emit(ofs, " tmp = mem_read[" + dest + ">>>16][" + dest + " & 0xffff]; " +
566 "mem_write[" + dest + ">>>16][" + dest + " & 0xffff] = (tmp & 0xffff0000) | (r" + rt + " & 0xffff);"); // SH
571 emit(ofs, " throw new Error(\"SWL (opcode 42) is not supported; are you sure you used -mstrict-align?\");");
575 String dest = "(r" + rs + " + " + signed_immediate + ")";
576 emit(ofs, " mem_write[" + dest + ">>>16][" + dest + " & 0xffff] = r" + rt + ";"); // SW
580 case 44: throw new Error("opcode 44 is not part of the MIPS I instruction set");
581 case 45: throw new Error("opcode 45 is not part of the MIPS I instruction set");
584 emit(ofs, " throw new Error(\"SWR (opcode 46) is not supported; are you sure you used -mstrict-align?\");");
587 case 47: throw new Error("opcode 47 is not part of the MIPS I instruction set");
588 case 48: throw new Error("opcode 48 is not part of the MIPS I instruction set");
591 emit(ofs, " throw new Error(\"floating point operations (opcode 49) are not yet supported\");");
595 emit(ofs, " throw new Error(\"floating point operations (opcode 50) are not yet supported\");");
598 case 51: case 52: case 53: case 54: case 55: case 56:
599 throw new Error("opcode " + op + " is not part of the MIPS I instruction set");
602 emit(ofs, " throw new Error(\"floating point operations (opcode 57) are not yet supported\");");
606 emit(ofs, " throw new Error(\"floating point operations (opcode 58) are not yet supported\");");
609 case 60: case 61: case 62: case 63:
610 throw new Error("opcode " + op + " is not part of the MIPS I instruction set");
613 throw new Error("unknown opcode " + op);
619 static String prefix = "";
620 static void emit(int vaddr, String s) {
621 if (s.indexOf("r0 = ") != -1) s = " /* NOP */";
622 if (!s.trim().endsWith("return;") && s.indexOf("throw") == -1) s += " pc = 0x" + Long.toString((vaddr + 4) & 0xffffffffL,16) + ";";
623 System.out.println(s);