]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/m32r-gx/gx-translate.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / sim / m32r-gx / gx-translate.c
1 /* GX M32R implementation.
2 Copyright (C) 1998 Cygnus Solutions.
3 */
4
5 #include <stdio.h>
6 #include <time.h>
7 #include <stdlib.h>
8
9 /* common simulator framework */
10 #include "sim-main.h"
11 #include "sim-base.h"
12 #include "sim-core.h"
13 #include "sim-inline.c"
14 #include "sim-gx.h"
15 #include "sim-assert.h"
16 #include "targ-vals.h"
17
18
19 /* internal functions */
20 void m32r_emit_long_insn(sim_gx_block* block, PCADDR pc, unsigned insn, int optimized);
21 void m32r_emit_short_insn(sim_gx_block* block, PCADDR pc, unsigned insn, int optimized);
22
23 /* callback functions */
24 unsigned m32r_gx_load(tgx_info* info, unsigned pc, unsigned addr);
25 void m32r_gx_store(tgx_info* info, unsigned pc, unsigned addr, unsigned data);
26 signed char m32r_gx_load1(tgx_info* info, unsigned pc, unsigned addr);
27 void m32r_gx_store1(tgx_info* info, unsigned pc, unsigned addr, signed char data);
28 signed short m32r_gx_load2(tgx_info* info, unsigned pc, unsigned addr);
29 void m32r_gx_store2(tgx_info* info, unsigned pc, unsigned addr, signed short data);
30 void m32r_gx_syscall(tgx_info* info, tgx_syscall_data* data);
31
32
33
34 /* external functions */
35
36 void
37 tgx_block_ctor(sim_gx_block* block, sim_cia cia)
38 {
39 /* pick translation boundaries */
40 unsigned_4 origin, length, divisor;
41
42 #define GX_PAGE_SIZE 4096
43 origin = (cia / GX_PAGE_SIZE) * GX_PAGE_SIZE;
44 length = GX_PAGE_SIZE;
45
46 /* fill in general target-dependent fields */
47 divisor = 4; /* m32r instruction-pairs occur on word boundaries */
48
49 tgx_block_ctor2(block, origin, length, divisor);
50 }
51
52
53 void
54 tgx_block_ctor2(sim_gx_block* block, unsigned_4 origin,
55 unsigned_4 length, unsigned_4 divisor)
56 {
57 block->origin = origin;
58 block->length = length;
59 block->divisor = divisor;
60
61 /* allocate pc_flags array */
62 block->pc_flags = zalloc(block->length / block->divisor);
63
64 /* allocate tgx_callbacks */
65 block->callbacks = zalloc(sizeof(tgx_callbacks));
66 block->callbacks->load = m32r_gx_load;
67 block->callbacks->store = m32r_gx_store;
68 block->callbacks->load1 = m32r_gx_load1;
69 block->callbacks->store1 = m32r_gx_store1;
70 block->callbacks->load2 = m32r_gx_load2;
71 block->callbacks->store2 = m32r_gx_store2;
72 block->callbacks->syscall = m32r_gx_syscall;
73 }
74
75
76
77 void
78 tgx_emit_pre_function(sim_gx_block* gx, int optimized)
79 {
80 sim_gx_compiled_block* block = optimized ? gx->optimized_block : gx->learning_block;
81 ASSERT(block->source_file != NULL);
82
83 fprintf(block->source_file, "\n");
84 fprintf(block->source_file, "#include <stdio.h>\n");
85 fprintf(block->source_file, "\n");
86 fprintf(block->source_file, /* match with definition in sim-main.h! */
87 "typedef struct tgx_cpu_regs\n"
88 "{\n"
89 " unsigned int h_pc; /* program counter */\n"
90 " signed int h_gr[16]; /* general registers */\n"
91 " unsigned int h_cr[16]; /* control registers */\n"
92 " long long h_accum; /* accumulator */\n"
93 " unsigned h_lock; /* lock */\n"
94 "} tgx_cpu_regs;\n");
95
96 fprintf(block->source_file, /* match with definition in sim-main.h! */
97 "typedef struct tgx_syscall_data\n"
98 "{\n"
99 " unsigned pc;\n"
100 " unsigned func;\n"
101 " unsigned arg1;\n"
102 " unsigned arg2;\n"
103 " unsigned arg3;\n"
104 " unsigned errcode;\n"
105 " unsigned result;\n"
106 " unsigned result2;\n"
107 "} tgx_syscall_data;\n");
108
109 fprintf(block->source_file, /* match with definition in sim-main.h! */
110 "struct tgx_info;\n"
111 "typedef struct tgx_callbacks\n"
112 "{\n"
113 " unsigned (*load)(struct tgx_info* info, unsigned pc, unsigned addr);\n"
114 " void (*store)(struct tgx_info* info, unsigned pc, unsigned addr, unsigned data);\n"
115 " signed char (*load1)(struct tgx_info* info, unsigned pc, unsigned addr);\n"
116 " void (*store1)(struct tgx_info* info, unsigned pc, unsigned addr, signed char data);\n"
117 " signed short (*load2)(struct tgx_info* info, unsigned pc, unsigned addr);\n"
118 " void (*store2)(struct tgx_info* info, unsigned pc, unsigned addr, signed short data);\n"
119 " void (*syscall)(struct tgx_info* info, tgx_syscall_data* data);\n"
120 "} tgx_callbacks;\n");
121
122 fprintf(block->source_file, /* match with definition in sim-main.h! */
123 "typedef struct tgx_mapping_cache\n"
124 "{\n"
125 " unsigned base;\n"
126 " unsigned bound;\n"
127 " void* buffer;\n"
128 "} tgx_mapping_cache;\n");
129
130 fprintf(block->source_file, /* match with definition in sim-main.h! */
131 "typedef struct tgx_info\n"
132 "{\n"
133 " struct tgx_cpu_regs* regs;\n"
134 " char* pc_flags;\n"
135 " struct tgx_callbacks* callbacks;\n"
136 "} tgx_info;\n");
137 }
138
139
140 void
141 tgx_emit_load_block(sim_gx_block* gx, int optimized)
142 {
143 sim_gx_compiled_block* block =
144 optimized ? gx->optimized_block : gx->learning_block;
145
146 ASSERT(block->source_file != NULL);
147 fprintf(block->source_file, /* match with definition above */
148 " tgx_cpu_regs* regs = info->regs;\n"
149 " tgx_callbacks* callbacks = info->callbacks;\n"
150 " char* pc_flags = info->pc_flags;\n"
151 "\n"
152 " unsigned int pc = regs->h_pc;\n"
153 " unsigned int npc = pc;\n"
154 " signed int temp;\n"
155 " signed int gr0 = regs->h_gr[0], gr1 = regs->h_gr[1];\n"
156 " signed int gr2 = regs->h_gr[2], gr3 = regs->h_gr[3];\n"
157 " signed int gr4 = regs->h_gr[4], gr5 = regs->h_gr[5];\n"
158 " signed int gr6 = regs->h_gr[6], gr7 = regs->h_gr[7];\n"
159 " signed int gr8 = regs->h_gr[8], gr9 = regs->h_gr[9];\n"
160 " signed int gr10 = regs->h_gr[10], gr11 = regs->h_gr[11];\n"
161 " signed int gr12 = regs->h_gr[12], gr13 = regs->h_gr[13];\n"
162 " signed int gr14 = regs->h_gr[14];\n"
163 " unsigned int cr0 = regs->h_cr[0], cr1 = regs->h_cr[1];\n"
164 " unsigned int cr2 = regs->h_cr[2], cr3 = regs->h_cr[3];\n"
165 " unsigned int cr4 = regs->h_cr[4], cr5 = regs->h_cr[5];\n"
166 " unsigned int cr6 = regs->h_cr[6], cr7 = regs->h_cr[7];\n"
167 " unsigned int cr8 = regs->h_cr[8], cr9 = regs->h_cr[9];\n"
168 " unsigned int cr10 = regs->h_cr[10], cr11 = regs->h_cr[11];\n"
169 " unsigned int cr12 = regs->h_cr[12], cr13 = regs->h_cr[13];\n"
170 " unsigned int cr14 = regs->h_cr[14], cr15 = regs->h_cr[15];\n"
171 " long long accum = regs->h_accum;\n"
172 " unsigned cond = cr0 & 0x01;\n"
173 " unsigned sm = cr0 & 0x80;\n"
174 " unsigned int gr15 = sm ? cr3 : cr2;\n"
175 " unsigned lock = regs->h_lock;\n");
176 }
177
178
179
180 sim_cia
181 tgx_emit_insn(sim_gx_block* gx, sim_cia cia, int optimized)
182 {
183 PCADDR pc = cia;
184 SIM_DESC sd = CURRENT_STATE;
185 sim_cpu* cpu = STATE_CPU (sd, 0);
186 USI insn = sim_core_read_unaligned_4 (cpu, NULL_CIA, exec_map, cia);
187 USI insn1 = (insn >> 16) & 0xffff;
188 USI insn2 = insn & 0xffff;
189 sim_gx_compiled_block* block =
190 optimized ? gx->optimized_block : gx->learning_block;
191
192 ASSERT(block->source_file != NULL);
193
194 /* classify instruction word */
195 if (insn & 0x80000000) /* single long word */
196 m32r_emit_long_insn(gx, pc, insn, optimized);
197 else /* two sequential half words */
198 {
199 /* translate first instruction */
200 m32r_emit_short_insn(gx, pc, insn1, optimized);
201
202 if(insn2 & 0x8000) /* parallel? */
203 {
204 fprintf(block->source_file, " /* || */\n");
205 insn2 &= 0x7fff;
206 /* XXX: genuine parallelism handling */
207 }
208 else
209 fprintf(block->source_file, " /* -> */\n");
210
211 /* translate second instruction */
212 m32r_emit_short_insn(gx, pc + 2, insn2, optimized);
213 }
214
215 return cia + 4; /* next instruction pair */
216 }
217
218
219 void
220 tgx_emit_save_block(sim_gx_block* gx, int optimized)
221 {
222 sim_gx_compiled_block* block =
223 optimized ? gx->optimized_block : gx->learning_block;
224
225 ASSERT(block->source_file != NULL);
226 fprintf(block->source_file, /* match with definition above */
227 " cr0 = (cr0 & 0x00c140) | (sm ? 0x80 : 0 ) | (cond ? 1 : 0);\n"
228 " cr1 = cond ? 1 : 0;\n"
229 " cr2 = sm ? cr2 : gr15;\n"
230 " cr3 = sm ? gr15 : cr3;\n"
231 " regs->h_pc = npc;\n"
232 " regs->h_gr[0] = gr0, regs->h_gr[1] = gr1;\n"
233 " regs->h_gr[2] = gr2, regs->h_gr[3] = gr3;\n"
234 " regs->h_gr[4] = gr4, regs->h_gr[5] = gr5;\n"
235 " regs->h_gr[6] = gr6, regs->h_gr[7] = gr7;\n"
236 " regs->h_gr[8] = gr8, regs->h_gr[9] = gr9;\n"
237 " regs->h_gr[10] = gr10, regs->h_gr[11] = gr11;\n"
238 " regs->h_gr[12] = gr12, regs->h_gr[13] = gr13;\n"
239 " regs->h_gr[14] = gr14, regs->h_gr[15] = gr15;\n"
240 " regs->h_cr[0] = cr0, regs->h_cr[1] = cr1;\n"
241 " regs->h_cr[2] = cr2, regs->h_cr[3] = cr3;\n"
242 " regs->h_cr[4] = cr4, regs->h_cr[5] = cr5;\n"
243 " regs->h_cr[6] = cr6, regs->h_cr[7] = cr7;\n"
244 " regs->h_cr[8] = cr8, regs->h_cr[9] = cr9;\n"
245 " regs->h_cr[10] = cr10, regs->h_cr[11] = cr11;\n"
246 " regs->h_cr[12] = cr12, regs->h_cr[13] = cr13;\n"
247 " regs->h_cr[14] = cr14, regs->h_cr[15] = cr15;\n"
248 " regs->h_accum = accum;\n"
249 " regs->h_lock = lock;\n");
250 }
251
252
253 void
254 tgx_emit_post_function(sim_gx_block* gx, int optimized)
255 {
256 sim_gx_compiled_block* block =
257 optimized ? gx->optimized_block : gx->learning_block;
258
259 ASSERT(block->source_file != NULL);
260 fprintf(block->source_file, "\n/* end of file */\n");
261 }
262
263
264 void
265 tgx_block_dtor(sim_gx_block* block)
266 {
267 }
268
269
270
271 int
272 tgx_optimize_test(sim_gx_block* block)
273 {
274 unsigned_4 current_time = time(NULL);
275 unsigned_4 constant_time = current_time - block->learn_last_change;
276 int opt;
277 char* env;
278
279 /* try another optimize run if the system has settled down */
280 opt = (block->compile_time != 0
281 && block->learn_last_change != 0
282 && constant_time > block->compile_time);
283
284 /* allow override by environment variable */
285 #ifdef HAVE_GETENV
286 env = getenv("GX_OPTIMIZE");
287 if(env)
288 opt = atoi(env);
289 #endif
290
291 /*
292 if(opt)
293 printf("optimize_test: now: %d, chg: %d, comp: %d, count: %d => opt %d\n",
294 current_time, block->learn_last_change, block->compile_time,
295 block->opt_compile_count, opt);
296
297 */
298
299 return opt;
300 }
301
302
303 unsigned
304 m32r_gx_load(struct tgx_info* info, unsigned pc, unsigned addr)
305 {
306 SIM_DESC sd = CURRENT_STATE;
307 sim_cpu* cpu = STATE_CPU (sd, 0);
308
309 USI data = sim_core_read_unaligned_4 (cpu, pc, read_map, addr);
310 return data;
311 }
312
313
314 void
315 m32r_gx_store(struct tgx_info* info, unsigned pc, unsigned addr, unsigned data)
316 {
317 SIM_DESC sd = CURRENT_STATE;
318 sim_cpu* cpu = STATE_CPU (sd, 0);
319
320 sim_core_write_unaligned_4 (cpu, pc, write_map, addr, data);
321 }
322
323
324 signed char
325 m32r_gx_load1(struct tgx_info* info, unsigned pc, unsigned addr)
326 {
327 SIM_DESC sd = CURRENT_STATE;
328 sim_cpu* cpu = STATE_CPU (sd, 0);
329 signed char data = 0;
330
331 data = sim_core_read_unaligned_1 (cpu, pc, read_map, addr);
332 return data;
333 }
334
335
336 void
337 m32r_gx_store1(struct tgx_info* info, unsigned pc, unsigned addr, signed char data)
338 {
339 SIM_DESC sd = CURRENT_STATE;
340 sim_cpu* cpu = STATE_CPU (sd, 0);
341
342 sim_core_write_unaligned_1 (cpu, pc, write_map, addr, data);
343 }
344
345
346 signed short
347 m32r_gx_load2(struct tgx_info* info, unsigned pc, unsigned addr)
348 {
349 SIM_DESC sd = CURRENT_STATE;
350 sim_cpu* cpu = STATE_CPU (sd, 0);
351
352 signed short data = sim_core_read_unaligned_2 (cpu, pc, read_map, addr);
353 return data;
354 }
355
356
357 void
358 m32r_gx_store2(struct tgx_info* info, unsigned pc, unsigned addr, signed short data)
359 {
360 SIM_DESC sd = CURRENT_STATE;
361 sim_cpu* cpu = STATE_CPU (sd, 0);
362
363 sim_core_write_unaligned_2 (cpu, pc, write_map, addr, data);
364 }
365
366
367 static int
368 syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
369 unsigned long taddr, char *buf, int bytes)
370 {
371 SIM_DESC sd = (SIM_DESC) sc->p1;
372 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
373
374 return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
375 }
376
377
378 static int
379 syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
380 unsigned long taddr, const char *buf, int bytes)
381 {
382 SIM_DESC sd = (SIM_DESC) sc->p1;
383 SIM_CPU *cpu = (SIM_CPU *) sc->p2;
384
385 return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
386 }
387
388
389 void
390 m32r_gx_syscall(struct tgx_info* info, tgx_syscall_data* data)
391 {
392 SIM_DESC sd = CURRENT_STATE;
393 sim_cpu* cpu = STATE_CPU (sd, 0);
394 host_callback *cb = STATE_CALLBACK (sd);
395 CB_SYSCALL s;
396
397 CB_SYSCALL_INIT (&s);
398 s.func = data->func;
399 s.arg1 = data->arg1;
400 s.arg2 = data->arg2;
401 s.arg3 = data->arg3;
402
403 if (s.func == TARGET_SYS_exit)
404 {
405 sim_engine_halt (sd, cpu, NULL, data->pc, sim_exited, s.arg1);
406 exit(s.arg1);
407 }
408
409 s.p1 = (PTR) sd;
410 s.p2 = (PTR) cpu;
411 s.read_mem = syscall_read_mem;
412 s.write_mem = syscall_write_mem;
413 cb_syscall (cb, &s);
414
415 data->errcode = s.errcode;
416 data->result = s.result;
417 data->result2 = s.result2;
418
419 /* XXX: clear read/write cache in info */
420 }
421
422
423
424 void
425 m32r_emit_long_insn(sim_gx_block* gx, PCADDR pc, unsigned insn, int optimized)
426 {
427 int op1 = (insn & 0xf0000000) >> 28;
428 int r1 = (insn & 0x0f000000) >> 24;
429 int op2 = (insn & 0x00f00000) >> 20;
430 int r2 = (insn & 0x000f0000) >> 16;
431 short lit2 = (insn & 0x0000ffff);
432 int lit3 = (insn & 0x00ffffff);
433 sim_gx_compiled_block* block = optimized ? gx->optimized_block : gx->learning_block;
434 FILE* f = block->source_file;
435
436 ASSERT(f != NULL);
437
438 /* force PC trace by environment variable */
439 #ifdef HAVE_GETENV
440 if(getenv("GX_TRACE"))
441 fprintf(f, " printf(\"0x%06x\\n\");\n", pc);
442 #endif
443
444 if(op1 == 0x8 && op2 == 0x4 && r1 == 0)
445 {
446 fprintf(f, " /* CMPI R%d,#%d */\n", r2, lit2);
447 fprintf(f, " cond = (gr%d < %d);\n", r2, lit2);
448 }
449 else if(op1 == 0x8 && op2 == 0x5 && r1 == 0)
450 {
451 fprintf(f, " /* CMPUI R%d,#%d */\n", r2, lit2);
452 fprintf(f, " cond = ((unsigned) gr%d < %u);\n", r2, (unsigned)((int) lit2));
453 }
454 else if(op1 == 0x8 && op2 == 0x8)
455 {
456 fprintf(f, " /* ADDV3 R%d,R%d,#%d */\n", r1, r2, lit2);
457 fprintf(f, " temp = gr%d + %d;\n", r2, lit2);
458 fprintf(f, " cond = (~(gr%d & %d) & (gr%d ^ temp)) & (1<<31);\n", r2, lit2, r2);
459 fprintf(f, " gr%d = temp;\n", r1);
460 }
461 else if(op1 == 0x8 && op2 == 0xa)
462 {
463 fprintf(f, " /* ADD3 R%d,R%d,#%d */\n", r1, r2, lit2);
464 fprintf(f, " gr%d = gr%d + %d;\n", r1, r2, lit2);
465 }
466 else if(op1 == 0x8 && op2 == 0xc)
467 {
468 fprintf(f, " /* AND3 R%d,R%d,#%u */\n", r1, r2, (unsigned short) lit2);
469 fprintf(f, " gr%d = gr%d & %u;\n", r1, r2, (unsigned short) lit2);
470 }
471 else if(op1 == 0x8 && op2 == 0xd)
472 {
473 fprintf(f, " /* XOR3 R%d,R%d,#%d */\n", r1, r2, lit2);
474 fprintf(f, " gr%d = gr%d ^ %d;\n", r1, r2, lit2);
475 }
476 else if(op1 == 0x8 && op2 == 0xe)
477 {
478 fprintf(f, " /* OR3 R%d,R%d,#%u */\n", r1, r2, (unsigned short) lit2);
479 fprintf(f, " gr%d = gr%d | %u;\n", r1, r2, (unsigned short) lit2);
480 }
481
482 else if(op1 == 0x9 && op2 == 0x0 && lit2 == 0)
483 {
484 fprintf(f, " /* DIV R%d,R%d */\n", r1, r2);
485 fprintf(f, " if(gr%d != 0)\n", r2);
486 fprintf(f, " gr%d = gr%d / gr%d;\n", r1, r1, r2);
487 }
488 else if(op1 == 0x9 && op2 == 0x1 && lit2 == 0)
489 {
490 fprintf(f, " /* DIVU R%d,R%d */\n", r1, r2);
491 fprintf(f, " if(gr%d != 0)\n", r2);
492 fprintf(f, " gr%d = (unsigned) gr%d / (unsigned) gr%d;\n", r1, r1, r2);
493 }
494 else if(op1 == 0x9 && op2 == 0x2 && lit2 == 0)
495 {
496 fprintf(f, " /* REM R%d,R%d */\n", r1, r2);
497 fprintf(f, " if(gr%d != 0)\n", r2);
498 fprintf(f, " gr%d = gr%d %% gr%d;\n", r1, r1, r2);
499 }
500 else if(op1 == 0x9 && op2 == 0x3 && lit2 == 0)
501 {
502 fprintf(f, " /* REMU R%d,R%d */\n", r1, r2);
503 fprintf(f, " if(gr%d != 0)\n", r2);
504 fprintf(f, " gr%d = (unsigned) gr%d %% (unsigned) gr%d;\n", r1, r1, r2);
505 }
506 else if(op1 == 0x9 && op2 == 0x8)
507 {
508 fprintf(f, " /* SRL3 R%d,R%d,#%d */\n", r1, r2, lit2);
509 fprintf(f, " gr%d = (unsigned) gr%d >> %d;\n", r1, r2, (lit2 & 0x1f));
510 }
511 else if(op1 == 0x9 && op2 == 0xa)
512 {
513 fprintf(f, " /* SRA3 R%d,R%d,#%d */\n", r1, r2, lit2);
514 fprintf(f, " gr%d = gr%d >> %d;\n", r1, r2, (lit2 & 0x1f));
515 }
516 else if(op1 == 0x9 && op2 == 0xc)
517 {
518 fprintf(f, " /* SLL3 R%d,R%d,#%d */\n", r1, r2, lit2);
519 fprintf(f, " gr%d = gr%d << %d;\n", r1, r2, (lit2 & 0x1f));
520 }
521 else if(op1 == 0x9 && op2 == 0xf && r2 == 0)
522 {
523 fprintf(f, " /* LDI R%d,#%d */\n", r1, lit2);
524 fprintf(f, " gr%d = %d;\n", r1, lit2);
525 }
526
527 else if(op1 == 0xa && op2 == 0x0)
528 {
529 fprintf(f, " /* STB R%d,@(%d,R%d) */\n", r1, lit2, r2);
530 fprintf(f, " (*(callbacks->store1))(info, 0x%08x, gr%d + %d, gr%d & 0xff);\n", (unsigned)pc, r2, lit2, r1);
531 }
532 else if(op1 == 0xa && op2 == 0x2)
533 {
534 fprintf(f, " /* STH R%d,@(%d,R%d) */\n", r1, lit2, r2);
535 fprintf(f, " (*(callbacks->store2))(info, 0x%08x, gr%d + %d, gr%d & 0xffff);\n", (unsigned)pc, r2, lit2, r1);
536 }
537 else if(op1 == 0xa && op2 == 0x4)
538 {
539 fprintf(f, " /* ST R%d,@(%d,R%d) */\n", r1, lit2, r2);
540 fprintf(f, " (*(callbacks->store))(info, 0x%08x, gr%d + %d, gr%d);\n", (unsigned)pc, r2, lit2, r1);
541 }
542 else if(op1 == 0xa && op2 == 0x8)
543 {
544 fprintf(f, " /* LDB R%d,@(%d,R%d) */\n", r1, lit2, r2);
545 fprintf(f, " gr%d = (*(callbacks->load1))(info, 0x%08x, gr%d + %d);\n", r1, (unsigned)pc, r2, lit2);
546 }
547 else if(op1 == 0xa && op2 == 0x9)
548 {
549 fprintf(f, " /* LDUB R%d,@(%d,R%d) */\n", r1, lit2, r2);
550 fprintf(f, " gr%d = (unsigned char)(*(callbacks->load1))(info, 0x%08x, gr%d + %d);\n", r1, (unsigned)pc, r2, lit2);
551 }
552 else if(op1 == 0xa && op2 == 0xa)
553 {
554 fprintf(f, " /* LDH R%d,@(%d,R%d) */\n", r1, lit2, r2);
555 fprintf(f, " gr%d = (*(callbacks->load2))(info, 0x%08x, gr%d + %d);\n", r1, (unsigned)pc, r2, lit2);
556 }
557 else if(op1 == 0xa && op2 == 0xb)
558 {
559 fprintf(f, " /* LDUH R%d,@(%d,R%d) */\n", r1, lit2, r2);
560 fprintf(f, " gr%d = (unsigned short)(*(callbacks->load2))(info, 0x%08x, gr%d + %d);\n", r1, (unsigned)pc, r2, lit2);
561 }
562 else if(op1 == 0xa && op2 == 0xc)
563 {
564 fprintf(f, " /* LD R%d,@(%d,R%d) */\n", r1, lit2, r2);
565 fprintf(f, " gr%d = (*(callbacks->load))(info, 0x%08x, gr%d + %d);\n", r1, (unsigned)pc, r2, lit2);
566 }
567
568 else if(op1 == 0xb && op2 == 0x0)
569 {
570 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
571 fprintf(f, " /* BEQ R%d,R%d,%d */\n", r1, r2, lit2);
572 fprintf(f, " if (gr%d == gr%d)\n", r1, r2);
573 fprintf(f, " {\n");
574 if (optimized &&
575 (GX_PC_INCLUDES(gx,newpc)) &&
576 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
577 {
578 fprintf(f, " goto gx_label_%ld;\n",
579 ((newpc - gx->origin) / gx->divisor));
580 }
581 else
582 {
583 fprintf(f, " npc = 0x%08x;\n", newpc);
584 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
585 }
586 fprintf(f, " }\n");
587 }
588 else if(op1 == 0xb && op2 == 0x1)
589 {
590 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
591 fprintf(f, " /* BNE R%d,R%d,%d */\n", r1, r2, lit2);
592 fprintf(f, " if (gr%d != gr%d)\n", r1, r2);
593 fprintf(f, " {\n");
594 if (optimized &&
595 (GX_PC_INCLUDES(gx,newpc)) &&
596 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
597 {
598 fprintf(f, " goto gx_label_%ld;\n",
599 ((newpc - gx->origin) / gx->divisor));
600 }
601 else
602 {
603 fprintf(f, " npc = 0x%08x;\n", newpc);
604 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
605 }
606 fprintf(f, " }\n");
607 }
608 else if(op1 == 0xb && op2 == 0x8 && r1 == 0)
609 {
610 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
611 fprintf(f, " /* BEQZ R%d,%d */\n", r2, lit2);
612 fprintf(f, " if (gr%d == 0)\n", r2);
613 fprintf(f, " {\n");
614 if (optimized &&
615 (GX_PC_INCLUDES(gx,newpc)) &&
616 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
617 {
618 fprintf(f, " goto gx_label_%ld;\n",
619 ((newpc - gx->origin) / gx->divisor));
620 }
621 else
622 {
623 fprintf(f, " npc = 0x%08x;\n", newpc);
624 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
625 }
626 fprintf(f, " }\n");
627 }
628 else if(op1 == 0xb && op2 == 0x9 && r1 == 0)
629 {
630 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
631 fprintf(f, " /* BNEZ R%d,%d */\n", r2, lit2);
632 fprintf(f, " if (gr%d != 0)\n", r2);
633 fprintf(f, " {\n");
634 if (optimized &&
635 (GX_PC_INCLUDES(gx,newpc)) &&
636 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
637 {
638 fprintf(f, " goto gx_label_%ld;\n",
639 ((newpc - gx->origin) / gx->divisor));
640 }
641 else
642 {
643 fprintf(f, " npc = 0x%08x;\n", newpc);
644 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
645 }
646 fprintf(f, " }\n");
647 }
648 else if(op1 == 0xb && op2 == 0xa && r1 == 0x0)
649 {
650 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
651 fprintf(f, " /* BLTZ R%d,%d */\n", r2, lit2);
652 fprintf(f, " if (gr%d < 0)\n", r2);
653 fprintf(f, " {\n");
654 if (optimized &&
655 (GX_PC_INCLUDES(gx,newpc)) &&
656 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
657 {
658 fprintf(f, " goto gx_label_%ld;\n",
659 ((newpc - gx->origin) / gx->divisor));
660 }
661 else
662 {
663 fprintf(f, " npc = 0x%08x;\n", newpc);
664 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
665 }
666 fprintf(f, " }\n");
667 }
668 else if(op1 == 0xb && op2 == 0xb && r1 == 0x0)
669 {
670 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
671 fprintf(f, " /* BGEZ R%d,%d */\n", r2, lit2);
672 fprintf(f, " if (gr%d >= 0)\n", r2);
673 fprintf(f, " {\n");
674 if (optimized &&
675 (GX_PC_INCLUDES(gx,newpc)) &&
676 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
677 {
678 fprintf(f, " goto gx_label_%ld;\n",
679 ((newpc - gx->origin) / gx->divisor));
680 }
681 else
682 {
683 fprintf(f, " npc = 0x%08x;\n", newpc);
684 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
685 }
686 fprintf(f, " }\n");
687 }
688 else if(op1 == 0xb && op2 == 0xc && r1 == 0x0)
689 {
690 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
691 fprintf(f, " /* BLEZ R%d,%d */\n", r2, lit2);
692 fprintf(f, " if (gr%d <= 0)\n", r2);
693 fprintf(f, " {\n");
694 if (optimized &&
695 (GX_PC_INCLUDES(gx,newpc)) &&
696 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
697 {
698 fprintf(f, " goto gx_label_%ld;\n",
699 ((newpc - gx->origin) / gx->divisor));
700 }
701 else
702 {
703 fprintf(f, " npc = 0x%08x;\n", newpc);
704 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
705 }
706 fprintf(f, " }\n");
707 }
708 else if(op1 == 0xb && op2 == 0xd && r1 == 0x0)
709 {
710 unsigned newpc = (pc & 0xfffffffc) + (((int) lit2) << 2);
711 fprintf(f, " /* BGTZ R%d,%d */\n", r2, lit2);
712 fprintf(f, " if (gr%d > 0)\n", r2);
713 fprintf(f, " {\n");
714 if (optimized &&
715 (GX_PC_INCLUDES(gx,newpc)) &&
716 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
717 {
718 fprintf(f, " goto gx_label_%ld;\n",
719 ((newpc - gx->origin) / gx->divisor));
720 }
721 else
722 {
723 fprintf(f, " npc = 0x%08x;\n", newpc);
724 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
725 }
726 fprintf(f, " }\n");
727 }
728
729 else if(op1 == 0xd && op2 == 0xc && r2 == 0)
730 {
731 fprintf(f, " /* SETH R%d,#%d */\n", r1, lit2);
732 fprintf(f, " gr%d = 0x%08x;\n", r1, (lit2 << 16));
733 }
734
735 else if(op1 == 0xe)
736 {
737 fprintf(f, " /* LD24 R%d,#%d */\n", r1, lit3);
738 fprintf(f, " gr%d = 0x%08x;\n", r1, lit3);
739 }
740
741 else if(op1 == 0xf && r1 == 0xc)
742 {
743 unsigned newpc = (pc & 0xfffffffc) + (((lit3 << 8) >> 8) << 2);
744 fprintf(f, " /* BC %d */\n", lit3);
745 fprintf(f, " if (cond)\n");
746 fprintf(f, " {\n");
747 if (optimized &&
748 (GX_PC_INCLUDES(gx,newpc)) &&
749 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
750 {
751 fprintf(f, " goto gx_label_%ld;\n",
752 ((newpc - gx->origin) / gx->divisor));
753 }
754 else
755 {
756 fprintf(f, " npc = 0x%08x;\n", newpc);
757 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
758 }
759 fprintf(f, " }\n");
760 }
761 else if(op1 == 0xf && r1 == 0xd)
762 {
763 unsigned newpc = (pc & 0xfffffffc) + (((lit3 << 8) >> 8) << 2);
764 fprintf(f, " /* BNC %d */\n", lit3);
765 fprintf(f, " if (! cond)\n");
766 fprintf(f, " {\n");
767 if (optimized &&
768 (GX_PC_INCLUDES(gx,newpc)) &&
769 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
770 {
771 fprintf(f, " goto gx_label_%ld;\n",
772 ((newpc - gx->origin) / gx->divisor));
773 }
774 else
775 {
776 fprintf(f, " npc = 0x%08x;\n", newpc);
777 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
778 }
779 fprintf(f, " }\n");
780 }
781 else if(op1 == 0xf && r1 == 0xe)
782 {
783 unsigned newpc = (pc & 0xfffffffc) + (((lit3 << 8) >> 8) << 2);
784 unsigned retpc = (pc & 0xfffffffc) + 4;
785 fprintf(f, " /* BL %d */\n", lit3);
786 fprintf(f, " gr14 = 0x%08x;\n", retpc);
787 if (optimized &&
788 (GX_PC_INCLUDES(gx,newpc)) &&
789 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
790 {
791 fprintf(f, " goto gx_label_%ld;\n",
792 ((newpc - gx->origin) / gx->divisor));
793 }
794 else
795 {
796 fprintf(f, " npc = 0x%08x;\n", newpc);
797 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
798 }
799 }
800 else if(op1 == 0xf && r1 == 0xf)
801 {
802 unsigned newpc = (pc & 0xfffffffc) + (((lit3 << 8) >> 8) << 2);
803 fprintf(f, " /* BRA %d */\n", lit3);
804 if (optimized &&
805 (GX_PC_INCLUDES(gx,newpc)) &&
806 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
807 {
808 fprintf(f, " goto gx_label_%ld;\n",
809 ((newpc - gx->origin) / gx->divisor));
810 }
811 else
812 {
813 fprintf(f, " npc = 0x%08x;\n", newpc);
814 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
815 }
816 }
817
818 else
819 {
820 /* illegal instruction */
821 /* XXX */
822 fprintf(f, " printf(\"ILLEGAL INSN 0x%08x @ PC 0x%08x\\n\");\n", insn, (unsigned)pc);
823 fprintf(f, " abort();\n");
824 }
825 }
826
827
828 void
829 m32r_emit_short_insn(sim_gx_block* gx, PCADDR pc, unsigned insn, int optimized)
830 {
831 int op1 = (insn & 0xf000) >> 12;
832 int r1 = (insn & 0x0f00) >> 8;
833 int op2 = (insn & 0x00f0) >> 4;
834 int op2part = (insn & 0x00e0) >> 5;
835 int r2 = (insn & 0x000f);
836 signed char c = (insn & 0x00ff);
837 signed char c5 = (insn & 0x001f);
838 sim_gx_compiled_block* block = optimized ? gx->optimized_block : gx->learning_block;
839 FILE* f = block->source_file;
840
841 ASSERT(f != NULL);
842
843 /* force PC trace by environment variable */
844 #ifdef HAVE_GETENV
845 if(getenv("GX_TRACE"))
846 fprintf(f, " printf(\"0x%06x\\n\");\n", pc);
847 #endif
848
849 if(0)
850 ; /* place holder */
851 else if(op1 == 0x0 && op2 == 0x0)
852 {
853 fprintf(f, " /* SUBV R%d,R%d */\n", r1, r2);
854 fprintf(f, " temp = gr%d - gr%d;\n", r1, r2);
855 fprintf(f, " cond = (unsigned) gr%d < (unsigned) gr%d;\n", r1, r2);
856 fprintf(f, " gr%d = temp;\n", r1);
857 }
858 else if(op1 == 0x0 && op2 == 0x1)
859 {
860 fprintf(f, " /* SUBX R%d,R%d */\n", r1, r2);
861 fprintf(f, " temp = gr%d - gr%d - (cond ? 1:0);\n", r1, r2);
862 fprintf(f, " cond = (unsigned) gr%d < (unsigned) gr%d;\n", r1, r2);
863 fprintf(f, " gr%d = temp;\n", r1);
864 }
865 else if(op1 == 0x0 && op2 == 0x2)
866 {
867 fprintf(f, " /* SUB R%d,R%d */\n", r1, r2);
868 fprintf(f, " gr%d = gr%d - gr%d;\n", r1, r1, r2);
869 }
870 else if(op1 == 0x0 && op2 == 0x3)
871 {
872 fprintf(f, " /* NEG R%d,R%d */\n", r1, r2);
873 fprintf(f, " gr%d = 0 - gr%d;\n", r1, r2);
874 }
875 else if(op1 == 0x0 && op2 == 0x4)
876 {
877 fprintf(f, " /* CMP R%d,R%d */\n", r1, r2);
878 fprintf(f, " cond = (gr%d < gr%d);\n", r1, r2);
879 }
880 else if(op1 == 0x0 && op2 == 0x5)
881 {
882 fprintf(f, " /* CMPU R%d,R%d */\n", r1, r2);
883 fprintf(f, " cond = ((unsigned) gr%d < (unsigned) gr%d);\n", r1, r2);
884 }
885 else if(op1 == 0x0 && op2 == 0x8)
886 {
887 fprintf(f, " /* ADDV R%d,R%d */\n", r1, r2);
888 fprintf(f, " temp = gr%d + gr%d;\n", r1, r2);
889 fprintf(f, " cond = ((gr%d & gr%d) | (gr%d & ~temp) | (gr%d & ~temp)) & (1<<31);\n", r1, r2, r1, r2);
890 fprintf(f, " cond = (gr%d ^ gr%d ^ temp ^ cond) & (1<<31);\n", r1, r2);
891 fprintf(f, " gr%d = temp;\n", r1);
892 }
893 else if(op1 == 0x0 && op2 == 0x9)
894 {
895 fprintf(f, " /* ADDX R%d,R%d */\n", r1, r2);
896 fprintf(f, " temp = gr%d + gr%d + (cond ? 1:0);\n", r1, r2);
897 fprintf(f, " cond = ((gr%d & gr%d) | (gr%d & ~temp) | (gr%d & ~temp)) & (1<<31);\n", r1, r2, r1, r2);
898 fprintf(f, " gr%d = temp;\n", r1);
899 }
900 else if(op1 == 0x0 && op2 == 0xa)
901 {
902 fprintf(f, " /* ADD R%d,R%d */\n", r1, r2);
903 fprintf(f, " gr%d = gr%d + gr%d;\n", r1, r1, r2);
904 }
905 else if(op1 == 0x0 && op2 == 0xb)
906 {
907 fprintf(f, " /* NOT R%d,R%d */\n", r1, r2);
908 fprintf(f, " gr%d = ~ gr%d;\n", r1, r2);
909 }
910 else if(op1 == 0x0 && op2 == 0xc)
911 {
912 fprintf(f, " /* AND R%d,R%d */\n", r1, r2);
913 fprintf(f, " gr%d = gr%d & gr%d;\n", r1, r1, r2);
914 }
915 else if(op1 == 0x0 && op2 == 0xd)
916 {
917 fprintf(f, " /* XOR R%d,R%d */\n", r1, r2);
918 fprintf(f, " gr%d = gr%d ^ gr%d;\n", r1, r1, r2);
919 }
920 else if(op1 == 0x0 && op2 == 0xe)
921 {
922 fprintf(f, " /* OR R%d,R%d */\n", r1, r2);
923 fprintf(f, " gr%d = gr%d | gr%d;\n", r1, r1, r2);
924 }
925
926 else if(op1 == 0x1 && op2 == 0x0)
927 {
928 fprintf(f, " /* SRL R%d,R%d */\n", r1, r2);
929 fprintf(f, " gr%d = (unsigned) gr%d >> (gr%d & 0x1f);\n", r1, r1, r2);
930 }
931 else if(op1 == 0x1 && op2 == 0x2)
932 {
933 fprintf(f, " /* SRA R%d,R%d */\n", r1, r2);
934 fprintf(f, " gr%d = gr%d >> (gr%d & 0x1f);\n", r1, r1, r2);
935 }
936 else if(op1 == 0x1 && op2 == 0x4)
937 {
938 fprintf(f, " /* SLL R%d,R%d */\n", r1, r2);
939 fprintf(f, " gr%d = gr%d << (gr%d & 0x1f);\n", r1, r1, r2);
940 }
941 else if(op1 == 0x1 && op2 == 0x6)
942 {
943 fprintf(f, " /* MUL R%d,R%d */\n", r1, r2);
944 fprintf(f, " gr%d = gr%d * gr%d;\n", r1, r1, r2);
945 }
946 else if(op1 == 0x1 && op2 == 0x8)
947 {
948 fprintf(f, " /* MV R%d,R%d */\n", r1, r2);
949 fprintf(f, " gr%d = gr%d;\n", r1, r2);
950 }
951 else if(op1 == 0x1 && op2 == 0x9)
952 {
953 fprintf(f, " /* MVFC R%d,CR%d */\n", r1, r2);
954 if(r2 == 0) /* psw */
955 fprintf(f, " gr%d = (cr0 & 0x00c140) | (sm ? 0x80 : 0 ) | (cond ? 1 : 0);\n", r1);
956 else if(r2 == 1) /* cbr */
957 fprintf(f, " gr%d = (cond ? 1 : 0);\n", r1);
958 else if(r2 == 2) /* spi */
959 {
960 fprintf(f, " if (sm) gr%d = cr2;\n", r1);
961 fprintf(f, " else gr%d = gr15;\n", r1);
962 }
963 else if(r2 == 3) /* spu */
964 {
965 fprintf(f, " if (!sm) gr%d = cr3;\n", r1);
966 fprintf(f, " else gr%d = gr15;\n", r1);
967 }
968 else
969 fprintf(f, " gr%d = cr%d;\n", r1, r2);
970 }
971 else if(op1 == 0x1 && op2 == 0xa)
972 {
973 fprintf(f, " /* MVTC R%d,CR%d */\n", r1, r2);
974 if(r2 == 0) /* psw */
975 {
976 fprintf(f, " cr0 = gr%d & 0x0000c1c1;\n", r1);
977 fprintf(f, " cond = cr0 & 1;\n");
978 fprintf(f, " cr2 = sm ? cr2 : gr15;\n");
979 fprintf(f, " cr3 = sm ? gr15 : cr3;\n");
980 fprintf(f, " sm = cr0 & 80;\n");
981 fprintf(f, " gr15 = sm ? cr3 : cr2;\n");
982 }
983 else if(r2 == 1) /* cbr */
984 ; /* no effect */
985 else if(r2 == 2) /* spi */
986 {
987 fprintf(f, " if (sm) cr2 = gr%d;\n", r1);
988 fprintf(f, " else gr15 = gr%d;\n", r1);
989 }
990 else if(r2 == 3) /* spu */
991 {
992 fprintf(f, " if (!sm) cr3 = gr%d;\n", r1);
993 fprintf(f, " else gr15 = gr%d;\n", r1);
994 }
995 else if(r2 == 6) /* bpc */
996 fprintf(f, " cr6 = gr%d & 0xfffffffe;\n", r1);
997 else
998 fprintf(f, " cr%d = gr%d;\n", r1, r2);
999 }
1000 else if(op1 == 0x1 && op2 == 0xc && r1 == 0xe)
1001 {
1002 fprintf(f, " /* JL R%d */\n", r2);
1003 fprintf(f, " gr14 = (0x%08x & 0xfffffffc) + 4;\n", (unsigned)pc);
1004 fprintf(f, " npc = gr%d & 0xfffffffc;\n", r2);
1005 fprintf(f, " goto unknownjump;\n");
1006 }
1007 else if(op1 == 0x1 && op2 == 0xc && r1 == 0xf)
1008 {
1009 fprintf(f, " /* JMP R%d */\n", r2);
1010 fprintf(f, " npc = gr%d & 0xfffffffc;\n", r2);
1011 fprintf(f, " goto unknownjump;\n");
1012 }
1013 else if(op1 == 0x1 && op2 == 0xd && r1 == 0x0 && r2 == 0x6)
1014 {
1015 fprintf(f, " /* RTE */\n");
1016 fprintf(f, " cr0 = (cr0 & 0xff00) | (cr0 >> 8);\n");
1017 fprintf(f, " cond = cr0 & 0x01;\n");
1018 fprintf(f, " sm = cr0 & 0x80;\n");
1019 fprintf(f, " gr15 = sm ? cr3 : cr2;\n");
1020 fprintf(f, " npc = cr6 & 0xfffffffc;\n");
1021 fprintf(f, " goto unknownjump;\n");
1022 }
1023 else if(op1 == 0x1 && op2 == 0xf)
1024 {
1025 fprintf(f, " /* TRAP #%d */\n", r2);
1026 if (r2 == TRAP_SYSCALL) /* general syscall ABI */
1027 {
1028 fprintf(f, " {\n");
1029 fprintf(f, " tgx_syscall_data d = { 0x%08x, gr0, gr1, gr2, gr3 };\n", (unsigned) pc);
1030 fprintf(f, " (*(callbacks->syscall))(info, &d);\n");
1031 fprintf(f, " gr2 = d.errcode;\n");
1032 fprintf(f, " gr0 = d.result;\n");
1033 fprintf(f, " gr1 = d.result2;\n");
1034 fprintf(f, " }\n");
1035 }
1036 else if (r2 == 1) /* gdb breakpoint */
1037 {
1038 fprintf(f, " rc = %d;\n", GX_F_HALT);
1039 fprintf(f, " goto save;\n");
1040 }
1041 else
1042 {
1043 fprintf(f, " cr6 = 0x%08x;\n", (unsigned)(pc + 4));
1044 fprintf(f, " cr0 = (cr0 & 0x000040) | (sm ? 0x80 : 0 ) | (cond ? 1 : 0);\n");
1045 fprintf(f, " cr0 = (cr0 & 0x0000ff) << 8 | (cr0 & 0x0000ff);\n");
1046 fprintf(f, " npc = 0x%08x;\n", 0x40 + (r2 * 4)); /* EIT_TRAP_BASE_ADDR */
1047 fprintf(f, " goto unknownjump;\n");
1048 }
1049 }
1050
1051 else if(op1 == 0x2 && op2 == 0x0)
1052 {
1053 fprintf(f, " /* STB R%d,@R%d */\n", r1, r2);
1054 fprintf(f, " (*(callbacks->store1))(info, 0x%08x, gr%d, gr%d & 0xff);\n", (unsigned)pc, r2, r1);
1055 }
1056 else if(op1 == 0x2 && op2 == 0x2)
1057 {
1058 fprintf(f, " /* STH R%d,@R%d */\n", r1, r2);
1059 fprintf(f, " (*(callbacks->store2))(info, 0x%08x, gr%d, gr%d & 0x0000ffff);\n", (unsigned)pc, r2, r1);
1060 }
1061 else if(op1 == 0x2 && op2 == 0x4)
1062 {
1063 fprintf(f, " /* ST R%d,@R%d */\n", r1, r2);
1064 fprintf(f, " (*(callbacks->store))(info, 0x%08x, gr%d, gr%d);\n", (unsigned)pc, r2, r1);
1065 }
1066 else if(op1 == 0x2 && op2 == 0x5)
1067 {
1068 fprintf(f, " /* UNLOCK R%d,@R%d */\n", r1, r2);
1069 fprintf(f, " if(lock)\n");
1070 fprintf(f, " {\n");
1071 fprintf(f, " lock = 0;\n");
1072 fprintf(f, " (*(callbacks->store))(info, 0x%08x, gr%d, gr%d);\n", (unsigned)pc, r2, r1);
1073 fprintf(f, " }\n");
1074 }
1075 else if(op1 == 0x2 && op2 == 0x6)
1076 {
1077 fprintf(f, " /* ST R%d,@+R%d */\n", r1, r2);
1078 fprintf(f, " gr%d = gr%d + 4;\n", r2, r2);
1079 fprintf(f, " (*(callbacks->store))(info, 0x%08x, gr%d, gr%d);\n", (unsigned)pc, r2, r1);
1080 }
1081 else if(op1 == 0x2 && op2 == 0x7)
1082 {
1083 fprintf(f, " /* ST R%d,@-R%d */\n", r1, r2);
1084 fprintf(f, " gr%d = gr%d - 4;\n", r2, r2);
1085 fprintf(f, " (*(callbacks->store))(info, 0x%08x, gr%d, gr%d);\n", (unsigned)pc, r2, r1);
1086 }
1087 else if(op1 == 0x2 && op2 == 0x8)
1088 {
1089 fprintf(f, " /* LDB R%d,@R%d */\n", r1, r2);
1090 fprintf(f, " gr%d = (*(callbacks->load1))(info, 0x%08x, gr%d);\n", r1, (unsigned)pc, r2);
1091 }
1092 else if(op1 == 0x2 && op2 == 0x9)
1093 {
1094 fprintf(f, " /* LDUB R%d,@R%d */\n", r1, r2);
1095 fprintf(f, " gr%d = (unsigned char)(*(callbacks->load1))(info, 0x%08x, gr%d);\n", r1, (unsigned)pc, r2);
1096 }
1097 else if(op1 == 0x2 && op2 == 0xa)
1098 {
1099 fprintf(f, " /* LDH R%d,@R%d */\n", r1, r2);
1100 fprintf(f, " gr%d = (*(callbacks->load2))(info, 0x%08x, gr%d);\n", r1, (unsigned)pc, r2);
1101 }
1102 else if(op1 == 0x2 && op2 == 0xb)
1103 {
1104 fprintf(f, " /* LDUH R%d,@R%d */\n", r1, r2);
1105 fprintf(f, " gr%d = (unsigned short)(*(callbacks->load2))(info, 0x%08x, gr%d);\n", r1, (unsigned)pc, r2);
1106 }
1107 else if(op1 == 0x2 && op2 == 0xc)
1108 {
1109 fprintf(f, " /* LD R%d,@R%d */\n", r1, r2);
1110 fprintf(f, " gr%d = (*(callbacks->load))(info, 0x%08x, gr%d);\n", r1, (unsigned)pc, r2);
1111 }
1112 else if(op1 == 0x2 && op2 == 0xd)
1113 {
1114 fprintf(f, " /* LOCK R%d,@R%d */\n", r1, r2);
1115 fprintf(f, " lock = 1;\n");
1116 fprintf(f, " gr%d = (*(callbacks->load))(info, 0x%08x, gr%d);\n", r1, (unsigned)pc, r2);
1117 }
1118 else if(op1 == 0x2 && op2 == 0xe)
1119 {
1120 fprintf(f, " /* LD R%d,@R%d+ */\n", r1, r2);
1121 fprintf(f, " gr%d = (*(callbacks->load))(info, 0x%08x, gr%d);\n", r1, (unsigned)pc, r2);
1122 fprintf(f, " gr%d = gr%d + 4;\n", r2, r2);
1123 }
1124
1125 else if(op1 == 0x4)
1126 {
1127 fprintf(f, " /* ADDI R%d,#%d */\n", r1, c);
1128 fprintf(f, " gr%d = gr%d + %d;\n", r1, r1, c);
1129 }
1130
1131 else if(op1 == 0x5 && op2part == 0x0)
1132 {
1133 fprintf(f, " /* SRLI R%d,#%d */\n", r1, c5);
1134 fprintf(f, " gr%d = ((unsigned) gr%d) >> %d;\n", r1, r1, c5);
1135 }
1136 else if(op1 == 0x5 && op2part == 0x1)
1137 {
1138 fprintf(f, " /* SRAI R%d,#%d */\n", r1, c5);
1139 fprintf(f, " gr%d = gr%d >> %d;\n", r1, r1, c5);
1140 }
1141 else if(op1 == 0x5 && op2part == 0x2)
1142 {
1143 fprintf(f, " /* SRLI R%d,#%d */\n", r1, c5);
1144 fprintf(f, " gr%d = gr%d << %d;\n", r1, r1, c5);
1145 }
1146
1147 else if(op1 == 0x6)
1148 {
1149 fprintf(f, " /* LDI R%d,#%d */\n", r1, c);
1150 fprintf(f, " gr%d = 0x%08x;\n", r1, c);
1151 }
1152
1153 else if(op1 == 0x7 && r1 == 0xc)
1154 {
1155 unsigned newpc = (pc & 0xfffffffc) + (((int) c) << 2);
1156 fprintf(f, " /* BC %d */\n", c);
1157 fprintf(f, " if (cond)\n");
1158 fprintf(f, " {\n");
1159 if (optimized &&
1160 (GX_PC_INCLUDES(gx,newpc)) &&
1161 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
1162 {
1163 fprintf(f, " goto gx_label_%ld;\n",
1164 ((newpc - gx->origin) / gx->divisor));
1165 }
1166 else
1167 {
1168 fprintf(f, " npc = 0x%08x;\n", newpc);
1169 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
1170 }
1171 fprintf(f, " }\n");
1172 }
1173 else if(op1 == 0x7 && r1 == 0xd)
1174 {
1175 unsigned newpc = (pc & 0xfffffffc) + (((int) c) << 2);
1176 fprintf(f, " /* BNC %d */\n", c);
1177 fprintf(f, " if (! cond)\n");
1178 fprintf(f, " {\n");
1179 if (optimized &&
1180 (GX_PC_INCLUDES(gx,newpc)) &&
1181 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
1182 {
1183 fprintf(f, " goto gx_label_%ld;\n",
1184 ((newpc - gx->origin) / gx->divisor));
1185 }
1186 else
1187 {
1188 fprintf(f, " npc = 0x%08x;\n", newpc);
1189 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
1190 }
1191 fprintf(f, " }\n");
1192 }
1193 else if(op1 == 0x7 && r1 == 0xe)
1194 {
1195 unsigned newpc = (pc & 0xfffffffc) + (((int) c) << 2);
1196 unsigned retpc = (pc & 0xfffffffc) + 4;
1197 fprintf(f, " /* BL %d */\n", c);
1198 fprintf(f, " gr14 = 0x%08x;\n", retpc);
1199 if (optimized &&
1200 (GX_PC_INCLUDES(gx,newpc)) &&
1201 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
1202 {
1203 fprintf(f, " goto gx_label_%ld;\n",
1204 ((newpc - gx->origin) / gx->divisor));
1205 }
1206 else
1207 {
1208 fprintf(f, " npc = 0x%08x;\n", newpc);
1209 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
1210 }
1211 }
1212 else if(op1 == 0x7 && r1 == 0xf)
1213 {
1214 unsigned newpc = (pc & 0xfffffffc) + (((int) c) << 2);
1215 fprintf(f, " /* BRA %d */\n", c);
1216 if (optimized &&
1217 (GX_PC_INCLUDES(gx,newpc)) &&
1218 (GX_PC_FLAGS(gx, newpc) & GX_PCF_JUMPTARGET))
1219 {
1220 fprintf(f, " goto gx_label_%ld;\n",
1221 ((newpc - gx->origin) / gx->divisor));
1222 }
1223 else
1224 {
1225 fprintf(f, " npc = 0x%08x;\n", newpc);
1226 fprintf(f, " goto %s;\n", (GX_PC_INCLUDES(gx,newpc)) ? "shortjump" : "longjump");
1227 }
1228 }
1229
1230 else if(op1 == 0x7 && op2 == 0x0 && r1 == 0x0 && r1 == 0x0)
1231 {
1232 fprintf(f, " /* NOP */\n");
1233 }
1234
1235 else
1236 {
1237 /* illegal instruction */
1238 /* XXX */
1239 fprintf(f, " printf(\"ILLEGAL INSN 0x%04x @ PC 0x%08x\\n\");\n", insn, (unsigned) pc);
1240 fprintf(f, " abort();\n");
1241 }
1242 }
1243