1
2 package org.xwt.imp;
3
4 import java.util.*;
5 import java.io.*;
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public class MIPS {
23
24 static String runs = "";
25 static int last_emit = -1;
26 static DataInputStream dis;
27 public static void main(String[] s) throws IOException {
28
29 if (s.length != 2) {
30 System.err.println("usage: java " + MIPS.class.getName() + " <classname> <binary.mips>");
31 System.exit(-1);
32 }
33
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);
39 }
40
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 + "");
69
70 dis = new DataInputStream(new FileInputStream(s[1]));
71
72
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");
75 dis.skip(12);
76
77 if (dis.readShort() != 2)
78 throw new RuntimeException("binary is not a linked executable");
79
80 if (dis.readShort() != 8)
81 throw new RuntimeException("binary is not a MIPS R3000 binary");
82
83 dis.skip(4);
84
85 int entry_point = dis.readInt();
86 String entry_point_string = Long.toString(entry_point & 0xffffffffL, 16);
87
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");
91 dis.skip(4);
92 dis.skip(2);
93
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();
99
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);
102
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();
111 dis.skip(4);
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);
116 }
117
118 dis.close();
119 dis = new DataInputStream(new FileInputStream(s[1]));
120
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();
126
127 dis.close();
128 dis = new DataInputStream(new FileInputStream(s[1]));
129
130 int pos = 0;
131 for(int i=0; i<sh_num_entries; i++) {
132
133 String name = "";
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));
140
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 + " }");
147 last_emit = -1;
148 }
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 + " }");
159
160 } else if (name.equals(".text") ) {
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);
167 emit(ofs, len, dis);
168 last_emit = ofs;
169 remaining -= len;
170 ofs += len;
171 }
172 }
173 }
174
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 + " }");
180 last_emit = -1;
181 }
182
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 + " }");
203
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 + "}");
216 }
217
218 static int _instruction;
219 static boolean readnext = true;
220
221
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 + " }");
228 }
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) {");
235 }
236 int ofs = vaddr;
237 try {
238 OUTER: for(ofs = vaddr; ofs < vaddr + numbytes; ofs+=4) {
239 if (readnext) _instruction = dis.readInt();
240 readnext = true;
241
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));");
247
248 emit_instruction(ofs, _instruction);
249 }
250 } catch (EOFException e) {
251 emit(ofs, " // warning, reached EOF before section end");
252 } finally {
253 last_emit = ofs;
254 }
255 }
256
257 private static void emit_instruction(int ofs, int instruction) throws IOException {
258 int op = (instruction >>> 26) & 0xff;
259 int rs = (instruction >> 21) & 0x1f;
260 int rt = (instruction >> 16) & 0x1f;
261 int rd = (instruction >> 11) & 0x1f;
262 int shamt = (instruction >> 6) & 0x1f;
263 int subcode = instruction & 0x3f;
264
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;
269
270 switch(op) {
271
272 case 0: {
273 switch(subcode) {
274
275 case 0:
276 if (instruction == 0) emit(ofs, " /* NOP */;");
277 else emit(ofs, " r" + rd + " = r" + rt + " << " + shamt + ";");
278 break;
279
280 case 1: throw new Error("opcode 0, subcode 1 is not part of the MIPS I instruction set");
281
282 case 2:
283 emit(ofs, " r" + rd + " = r" + rt + " >>> " + shamt + ";");
284 break;
285
286 case 3:
287 emit(ofs, " r" + rd + " = r" + rt + " >> " + shamt + ";");
288 break;
289
290 case 4:
291 emit(ofs, " r" + rd + " = r" + rt + " << (r" + rs + " % 32);");
292 break;
293
294 case 5: throw new Error("opcode 0, subcode 5 is not part of the MIPS I instruction set");
295
296 case 6:
297 emit(ofs, " r" + rd + " = r" + rs + " >>> (r" + rt + " % 32);");
298 break;
299
300 case 7:
301 emit(ofs, " r" + rd + " = r" + rs + " >> (r" + rt + " % 32);");
302 break;
303
304 case 8:
305 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
306 emit(ofs, " pc = r" + rs + "; return;");
307 break;
308
309 case 9:
310 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
311 emit(ofs, " r" + rd + " = pc + 8; pc = r" + rs + "; return;");
312 break;
313
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");
316
317 case 12:
318 emit(ofs, " syscall(" + ((instruction & 0x07ffffc0) >> 6) + ");");
319 break;
320
321 case 13:
322 emit(ofs, " /* BREAKPOINT */");
323 break;
324
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");
327
328 case 16:
329 emit(ofs, " r" + rd + " = (int)(hilo >>> 32);");
330 break;
331
332 case 17:
333 emit(ofs, " hilo = (hilo & 0x00000000ffffffffL) | ((r" + rs + " & 0xffffffffL) << 32);");
334 break;
335
336 case 18:
337 emit(ofs, " r" + rd + " = (int)hilo;");
338 break;
339
340 case 19:
341 emit(ofs, " hilo = (hilo & 0xffffffff00000000L) | (r" + rs + " & 0xffffffffL);");
342 break;
343
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");
347
348 case 24:
349 emit(ofs, " hilo = ((long)r" + rs + ") * ((long)r" + rt + ");");
350 break;
351
352 case 25:
353 emit(ofs, " hilo = (r" + rs + " & 0xffffffffL) * (r" + rt + " & 0xffffffffL);");
354 break;
355
356 case 26:
357 emit(ofs, " hilo = (((r" + rs + " % r" + rt +") & 0xffffffffL) << 32) | ((r" + rs + " / r" + rt +") & 0xffffffffL);");
358 break;
359
360 case 27:
361 emit(ofs, " hilo = (((r" + rs + " & 0xffffffffL) % (r" + rt +" & 0xffffffffL)) << 32) | " +
362 "((r" + rs + " & 0xffffffffL) / (r" + rt +" & 0xffffffffL));");
363 break;
364
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");
369
370 case 32:
371 emit(ofs, " r" + rd + " = r" + rs + " + r" + rt + ";");
372 break;
373
374 case 33:
375 emit(ofs, " r" + rd + " = (int)(((r" + rs + " & 0xffffffffL) + (r" + rt + " & 0xffffffffL)));");
376 break;
377
378 case 34:
379 emit(ofs, " r" + rd + " = r" + rs + " - r" + rt + ";");
380 break;
381
382 case 35:
383 emit(ofs, " r" + rd + " = (int)(((r" + rs + " & 0xffffffffL) - (r" + rt + " & 0xffffffffL)));");
384 break;
385
386 case 36:
387 emit(ofs, " r" + rd + " = r" + rs + " & r" + rt + ";");
388 break;
389
390 case 37:
391 emit(ofs, " r" + rd + " = r" + rs + " | r" + rt + ";");
392 break;
393
394 case 38:
395 emit(ofs, " r" + rd + " = r" + rs + " ^ r" + rt + ";");
396 break;
397
398 case 39:
399 emit(ofs, " r" + rd + " = ~(r" + rs + " | r" + rt + ");");
400 break;
401
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");
404
405 case 42:
406 emit(ofs, " r" + rd + " = (r" + rs + " < r" + rt + ") ? 1 : 0;");
407 break;
408
409 case 43:
410 emit(ofs, " r" + rd + " = ((r" + rs + " & 0xffffffffL) < (r" + rt + " & 0xffffffffL)) ? 1 : 0;");
411 break;
412
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");
416 default:
417 throw new Error("opcode 0, subcode " + subcode + " is not a valid MIPS instruction");
418 }
419 break;
420 }
421
422 case 1: {
423 switch(rt) {
424 case 0:
425 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
426 emit(ofs, " if (r" + rs + " < 0) { pc += " + (branch_offset + 4) + "; return; }; ");
427 break;
428
429 case 1:
430 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
431 emit(ofs, " if (r" + rs + " >= 0) { pc += " + (branch_offset + 4) + "; return; }; ");
432 break;
433
434 case 16:
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; }; ");
437 break;
438
439 case 17:
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; }; ");
442 break;
443
444 default: throw new Error("opcode 1, subcode " + rt + " is not part of the MIPS I instruction set");
445 }
446 break;
447 }
448
449 case 2:
450 _instruction = dis.readInt(); readnext = false; emit_instruction(ofs, _instruction);
451 emit(ofs, " pc &= 0xf0000000; pc |= 0x" + Long.toString(jump_target & 0xffffffffL, 16) + "; return;");
452 break;
453
454 case 3:
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;");
457 break;
458
459 case 4:
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; }; ");
462 break;
463
464 case 5:
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; }; ");
467 break;
468
469 case 6:
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; }; ");
472 break;
473
474 case 7:
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; }; ");
477 break;
478
479 case 8: case 9:
480 emit(ofs, " r" + rt + " = r" + rs + " + " + signed_immediate + ";");
481 break;
482
483 case 10:
484 emit(ofs, " r" + rt + " = (r" + rs + " < " + signed_immediate + ") ? 1 : 0;");
485 break;
486
487 case 11:
488 emit(ofs, " r" + rt + " = ((r" + rs + " & 0xffffffffL) < (" + signed_immediate + " & 0xffffffffL)) ? 1 : 0;");
489 break;
490
491 case 12:
492 emit(ofs, " r" + rt + " = r" + rs + " & " + unsigned_immediate + ";");
493 break;
494
495 case 13:
496 emit(ofs, " r" + rt + " = r" + rs + " | " + unsigned_immediate + ";");
497 break;
498
499 case 14:
500 emit(ofs, " r" + rt + " = r" + rs + " ^ " + unsigned_immediate + ";");
501 break;
502
503 case 15:
504 emit(ofs, " r" + rt + " = " + unsigned_immediate + " << 16;");
505 break;
506
507 case 16:
508 emit(ofs, " throw new Error(\"coprocessor instructions (opcode 16) are not implemented\");");
509 break;
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");
512
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));
515
516 case 32: {
517 String dest = "(r" + rs + " + " + signed_immediate + ")";
518 emit(ofs, " tmp = mem_read[" + dest + ">>>16][" + dest + " & 0xffff]; r" + rt + " = ((tmp & 0x80) << 24) | (tmp & 0x7f);");
519 break;
520 }
521
522 case 33: {
523 String dest = "(r" + rs + " + " + signed_immediate + ")";
524 emit(ofs, " tmp = mem_read[" + dest + ">>>16][" + dest + " & 0xffff]; r" + rt + " = ((tmp & 0x8000) << 16) | (tmp & 0x7fff);");
525 break;
526 }
527
528 case 34:
529 emit(ofs, " throw new Error(\"LWL (opcode 34) is not supported; are you sure you used -mstrict-align?\");");
530 break;
531
532 case 35: {
533 String dest = "(r" + rs + " + " + signed_immediate + ")";
534 emit(ofs, " r" + rt + " = mem_read[" + dest + ">>>16][" + dest + " & 0xffff];");
535 break;
536 }
537
538 case 36: {
539 String dest = "(r" + rs + " + " + signed_immediate + ")";
540 emit(ofs, " r" + rt + " = mem_read[" + dest + ">>>16][" + dest + " & 0xffff] & 0xff;");
541 break;
542 }
543
544 case 37: {
545 String dest = "(r" + rs + " + " + signed_immediate + ")";
546 emit(ofs, " r" + rt + " = mem_read[" + dest + ">>>16][" + dest + " & 0xffff] & 0xffff;");
547 break;
548 }
549
550 case 38:
551 emit(ofs, " throw new Error(\"LWR (opcode 38) is not supported; are you sure you used -mstrict-align?\");");
552 break;
553
554 case 39: throw new Error("opcode 39 is not part of the MIPS I instruction set");
555
556 case 40: {
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);");
560 break;
561 }
562
563 case 41: {
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);");
567 break;
568 }
569
570 case 42:
571 emit(ofs, " throw new Error(\"SWL (opcode 42) is not supported; are you sure you used -mstrict-align?\");");
572 break;
573
574 case 43: {
575 String dest = "(r" + rs + " + " + signed_immediate + ")";
576 emit(ofs, " mem_write[" + dest + ">>>16][" + dest + " & 0xffff] = r" + rt + ";");
577 break;
578 }
579
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");
582
583 case 46:
584 emit(ofs, " throw new Error(\"SWR (opcode 46) is not supported; are you sure you used -mstrict-align?\");");
585 break;
586
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");
589
590 case 49:
591 emit(ofs, " throw new Error(\"floating point operations (opcode 49) are not yet supported\");");
592 break;
593
594 case 50:
595 emit(ofs, " throw new Error(\"floating point operations (opcode 50) are not yet supported\");");
596 break;
597
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");
600
601 case 57:
602 emit(ofs, " throw new Error(\"floating point operations (opcode 57) are not yet supported\");");
603 break;
604
605 case 58:
606 emit(ofs, " throw new Error(\"floating point operations (opcode 58) are not yet supported\");");
607 break;
608
609 case 60: case 61: case 62: case 63:
610 throw new Error("opcode " + op + " is not part of the MIPS I instruction set");
611
612 default:
613 throw new Error("unknown opcode " + op);
614 }
615 }
616
617
618
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);
624 }
625 }
626
627