SD card emulation (initial implementation by Andrzei Zaborowski).
[qemu/mini2440.git] / target-sh4 / translate.c
blob1c9fe40f5f538a1c7fc8cbee1f1fc8672109400a
1 /*
2 * SH4 translation
3 *
4 * Copyright (c) 2005 Samuel Tardieu
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <assert.h>
27 #define DEBUG_DISAS
28 #define SH4_DEBUG_DISAS
29 //#define SH4_SINGLE_STEP
31 #include "cpu.h"
32 #include "exec-all.h"
33 #include "disas.h"
35 enum {
36 #define DEF(s, n, copy_size) INDEX_op_ ## s,
37 #include "opc.h"
38 #undef DEF
39 NB_OPS,
42 #ifdef USE_DIRECT_JUMP
43 #define TBPARAM(x)
44 #else
45 #define TBPARAM(x) ((long)(x))
46 #endif
48 static uint16_t *gen_opc_ptr;
49 static uint32_t *gen_opparam_ptr;
51 #include "gen-op.h"
53 typedef struct DisasContext {
54 struct TranslationBlock *tb;
55 target_ulong pc;
56 uint32_t sr;
57 uint32_t fpscr;
58 uint16_t opcode;
59 uint32_t flags;
60 int memidx;
61 uint32_t delayed_pc;
62 int singlestep_enabled;
63 } DisasContext;
65 #ifdef CONFIG_USER_ONLY
67 #define GEN_OP_LD(width, reg) \
68 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
69 gen_op_ld##width##_T0_##reg##_raw(); \
71 #define GEN_OP_ST(width, reg) \
72 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
73 gen_op_st##width##_##reg##_T1_raw(); \
76 #else
78 #define GEN_OP_LD(width, reg) \
79 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
80 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
81 else gen_op_ld##width##_T0_##reg##_user();\
83 #define GEN_OP_ST(width, reg) \
84 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
85 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
86 else gen_op_st##width##_##reg##_T1_user();\
89 #endif
91 GEN_OP_LD(ub, T0)
92 GEN_OP_LD(b, T0)
93 GEN_OP_ST(b, T0)
94 GEN_OP_LD(uw, T0)
95 GEN_OP_LD(w, T0)
96 GEN_OP_ST(w, T0)
97 GEN_OP_LD(l, T0)
98 GEN_OP_ST(l, T0)
99 GEN_OP_LD(fl, FT0)
100 GEN_OP_ST(fl, FT0)
101 GEN_OP_LD(fq, DT0)
102 GEN_OP_ST(fq, DT0)
104 void cpu_dump_state(CPUState * env, FILE * f,
105 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
106 int flags)
108 int i;
109 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
110 env->pc, env->sr, env->pr, env->fpscr);
111 for (i = 0; i < 24; i += 4) {
112 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
113 i, env->gregs[i], i + 1, env->gregs[i + 1],
114 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
116 if (env->flags & DELAY_SLOT) {
117 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
118 env->delayed_pc);
119 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
120 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
121 env->delayed_pc);
125 void cpu_sh4_reset(CPUSH4State * env)
127 #if defined(CONFIG_USER_ONLY)
128 env->sr = 0x00000000;
129 #else
130 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
131 #endif
132 env->vbr = 0;
133 env->pc = 0xA0000000;
134 env->fpscr = 0x00040001;
135 env->mmucr = 0;
138 CPUSH4State *cpu_sh4_init(void)
140 CPUSH4State *env;
142 env = qemu_mallocz(sizeof(CPUSH4State));
143 if (!env)
144 return NULL;
145 cpu_exec_init(env);
146 cpu_sh4_reset(env);
147 tlb_flush(env, 1);
148 return env;
151 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
153 TranslationBlock *tb;
154 tb = ctx->tb;
156 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
157 !ctx->singlestep_enabled) {
158 /* Use a direct jump if in same page and singlestep not enabled */
159 if (n == 0)
160 gen_op_goto_tb0(TBPARAM(tb));
161 else
162 gen_op_goto_tb1(TBPARAM(tb));
163 gen_op_movl_imm_T0((long) tb + n);
164 } else {
165 gen_op_movl_imm_T0(0);
167 gen_op_movl_imm_PC(dest);
168 if (ctx->singlestep_enabled)
169 gen_op_debug();
170 gen_op_exit_tb();
173 /* Jump to pc after an exception */
174 static void gen_jump_exception(DisasContext * ctx)
176 gen_op_movl_imm_T0(0);
177 if (ctx->singlestep_enabled)
178 gen_op_debug();
179 gen_op_exit_tb();
182 static void gen_jump(DisasContext * ctx)
184 if (ctx->delayed_pc == (uint32_t) - 1) {
185 /* Target is not statically known, it comes necessarily from a
186 delayed jump as immediate jump are conditinal jumps */
187 gen_op_movl_delayed_pc_PC();
188 gen_op_movl_imm_T0(0);
189 if (ctx->singlestep_enabled)
190 gen_op_debug();
191 gen_op_exit_tb();
192 } else {
193 gen_goto_tb(ctx, 0, ctx->delayed_pc);
197 /* Immediate conditional jump (bt or bf) */
198 static void gen_conditional_jump(DisasContext * ctx,
199 target_ulong ift, target_ulong ifnott)
201 int l1;
203 l1 = gen_new_label();
204 gen_op_jT(l1);
205 gen_goto_tb(ctx, 0, ifnott);
206 gen_set_label(l1);
207 gen_goto_tb(ctx, 1, ift);
210 /* Delayed conditional jump (bt or bf) */
211 static void gen_delayed_conditional_jump(DisasContext * ctx)
213 int l1;
215 l1 = gen_new_label();
216 gen_op_jdelayed(l1);
217 gen_goto_tb(ctx, 1, ctx->pc);
218 gen_set_label(l1);
219 gen_jump(ctx);
222 #define B3_0 (ctx->opcode & 0xf)
223 #define B6_4 ((ctx->opcode >> 4) & 0x7)
224 #define B7_4 ((ctx->opcode >> 4) & 0xf)
225 #define B7_0 (ctx->opcode & 0xff)
226 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
227 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
228 (ctx->opcode & 0xfff))
229 #define B11_8 ((ctx->opcode >> 8) & 0xf)
230 #define B15_12 ((ctx->opcode >> 12) & 0xf)
232 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
233 (x) + 16 : (x))
235 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
236 ? (x) + 16 : (x))
238 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
239 #define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1)
240 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
242 #define CHECK_NOT_DELAY_SLOT \
243 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
244 {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
245 return;}
247 void decode_opc(DisasContext * ctx)
249 #if 0
250 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
251 #endif
252 switch (ctx->opcode) {
253 case 0x0019: /* div0u */
254 gen_op_div0u();
255 return;
256 case 0x000b: /* rts */
257 CHECK_NOT_DELAY_SLOT gen_op_rts();
258 ctx->flags |= DELAY_SLOT;
259 ctx->delayed_pc = (uint32_t) - 1;
260 return;
261 case 0x0028: /* clrmac */
262 gen_op_clrmac();
263 return;
264 case 0x0048: /* clrs */
265 gen_op_clrs();
266 return;
267 case 0x0008: /* clrt */
268 gen_op_clrt();
269 return;
270 case 0x0038: /* ldtlb */
271 assert(0); /* XXXXX */
272 return;
273 case 0x004b: /* rte */
274 CHECK_NOT_DELAY_SLOT gen_op_rte();
275 ctx->flags |= DELAY_SLOT;
276 ctx->delayed_pc = (uint32_t) - 1;
277 return;
278 case 0x0058: /* sets */
279 gen_op_sets();
280 return;
281 case 0x0018: /* sett */
282 gen_op_sett();
283 return;
284 case 0xfbfb: /* frchg */
285 gen_op_frchg();
286 ctx->flags |= MODE_CHANGE;
287 return;
288 case 0xf3fb: /* fschg */
289 gen_op_fschg();
290 ctx->flags |= MODE_CHANGE;
291 return;
292 case 0x0009: /* nop */
293 return;
294 case 0x001b: /* sleep */
295 assert(0); /* XXXXX */
296 return;
299 switch (ctx->opcode & 0xf000) {
300 case 0x1000: /* mov.l Rm,@(disp,Rn) */
301 gen_op_movl_rN_T0(REG(B7_4));
302 gen_op_movl_rN_T1(REG(B11_8));
303 gen_op_addl_imm_T1(B3_0 * 4);
304 gen_op_stl_T0_T1(ctx);
305 return;
306 case 0x5000: /* mov.l @(disp,Rm),Rn */
307 gen_op_movl_rN_T0(REG(B7_4));
308 gen_op_addl_imm_T0(B3_0 * 4);
309 gen_op_ldl_T0_T0(ctx);
310 gen_op_movl_T0_rN(REG(B11_8));
311 return;
312 case 0xe000: /* mov.l #imm,Rn */
313 gen_op_movl_imm_rN(B7_0s, REG(B11_8));
314 return;
315 case 0x9000: /* mov.w @(disp,PC),Rn */
316 gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
317 gen_op_ldw_T0_T0(ctx);
318 gen_op_movl_T0_rN(REG(B11_8));
319 return;
320 case 0xd000: /* mov.l @(disp,PC),Rn */
321 gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
322 gen_op_ldl_T0_T0(ctx);
323 gen_op_movl_T0_rN(REG(B11_8));
324 return;
325 case 0x7000: /* add.l #imm,Rn */
326 gen_op_add_imm_rN(B7_0s, REG(B11_8));
327 return;
328 case 0xa000: /* bra disp */
329 CHECK_NOT_DELAY_SLOT
330 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
331 ctx->flags |= DELAY_SLOT;
332 return;
333 case 0xb000: /* bsr disp */
334 CHECK_NOT_DELAY_SLOT
335 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
336 ctx->pc + 4 + B11_0s * 2);
337 ctx->flags |= DELAY_SLOT;
338 return;
341 switch (ctx->opcode & 0xf00f) {
342 case 0x6003: /* mov Rm,Rn */
343 gen_op_movl_rN_T0(REG(B7_4));
344 gen_op_movl_T0_rN(REG(B11_8));
345 return;
346 case 0x2000: /* mov.b Rm,@Rn */
347 gen_op_movl_rN_T0(REG(B7_4));
348 gen_op_movl_rN_T1(REG(B11_8));
349 gen_op_stb_T0_T1(ctx);
350 return;
351 case 0x2001: /* mov.w Rm,@Rn */
352 gen_op_movl_rN_T0(REG(B7_4));
353 gen_op_movl_rN_T1(REG(B11_8));
354 gen_op_stw_T0_T1(ctx);
355 return;
356 case 0x2002: /* mov.l Rm,@Rn */
357 gen_op_movl_rN_T0(REG(B7_4));
358 gen_op_movl_rN_T1(REG(B11_8));
359 gen_op_stl_T0_T1(ctx);
360 return;
361 case 0x6000: /* mov.b @Rm,Rn */
362 gen_op_movl_rN_T0(REG(B7_4));
363 gen_op_ldb_T0_T0(ctx);
364 gen_op_movl_T0_rN(REG(B11_8));
365 return;
366 case 0x6001: /* mov.w @Rm,Rn */
367 gen_op_movl_rN_T0(REG(B7_4));
368 gen_op_ldw_T0_T0(ctx);
369 gen_op_movl_T0_rN(REG(B11_8));
370 return;
371 case 0x6002: /* mov.l @Rm,Rn */
372 gen_op_movl_rN_T0(REG(B7_4));
373 gen_op_ldl_T0_T0(ctx);
374 gen_op_movl_T0_rN(REG(B11_8));
375 return;
376 case 0x2004: /* mov.b Rm,@-Rn */
377 gen_op_dec1_rN(REG(B11_8));
378 gen_op_movl_rN_T0(REG(B7_4));
379 gen_op_movl_rN_T1(REG(B11_8));
380 gen_op_stb_T0_T1(ctx);
381 return;
382 case 0x2005: /* mov.w Rm,@-Rn */
383 gen_op_dec2_rN(REG(B11_8));
384 gen_op_movl_rN_T0(REG(B7_4));
385 gen_op_movl_rN_T1(REG(B11_8));
386 gen_op_stw_T0_T1(ctx);
387 return;
388 case 0x2006: /* mov.l Rm,@-Rn */
389 gen_op_dec4_rN(REG(B11_8));
390 gen_op_movl_rN_T0(REG(B7_4));
391 gen_op_movl_rN_T1(REG(B11_8));
392 gen_op_stl_T0_T1(ctx);
393 return;
394 case 0x6004: /* mov.b @Rm+,Rn */
395 gen_op_movl_rN_T0(REG(B7_4));
396 gen_op_ldb_T0_T0(ctx);
397 gen_op_movl_T0_rN(REG(B11_8));
398 gen_op_inc1_rN(REG(B7_4));
399 return;
400 case 0x6005: /* mov.w @Rm+,Rn */
401 gen_op_movl_rN_T0(REG(B7_4));
402 gen_op_ldw_T0_T0(ctx);
403 gen_op_movl_T0_rN(REG(B11_8));
404 gen_op_inc2_rN(REG(B7_4));
405 return;
406 case 0x6006: /* mov.l @Rm+,Rn */
407 gen_op_movl_rN_T0(REG(B7_4));
408 gen_op_ldl_T0_T0(ctx);
409 gen_op_movl_T0_rN(REG(B11_8));
410 gen_op_inc4_rN(REG(B7_4));
411 return;
412 case 0x0004: /* mov.b Rm,@(R0,Rn) */
413 gen_op_movl_rN_T0(REG(B7_4));
414 gen_op_movl_rN_T1(REG(B11_8));
415 gen_op_add_rN_T1(REG(0));
416 gen_op_stb_T0_T1(ctx);
417 return;
418 case 0x0005: /* mov.w Rm,@(R0,Rn) */
419 gen_op_movl_rN_T0(REG(B7_4));
420 gen_op_movl_rN_T1(REG(B11_8));
421 gen_op_add_rN_T1(REG(0));
422 gen_op_stw_T0_T1(ctx);
423 return;
424 case 0x0006: /* mov.l Rm,@(R0,Rn) */
425 gen_op_movl_rN_T0(REG(B7_4));
426 gen_op_movl_rN_T1(REG(B11_8));
427 gen_op_add_rN_T1(REG(0));
428 gen_op_stl_T0_T1(ctx);
429 return;
430 case 0x000c: /* mov.b @(R0,Rm),Rn */
431 gen_op_movl_rN_T0(REG(B7_4));
432 gen_op_add_rN_T0(REG(0));
433 gen_op_ldb_T0_T0(ctx);
434 gen_op_movl_T0_rN(REG(B11_8));
435 return;
436 case 0x000d: /* mov.w @(R0,Rm),Rn */
437 gen_op_movl_rN_T0(REG(B7_4));
438 gen_op_add_rN_T0(REG(0));
439 gen_op_ldw_T0_T0(ctx);
440 gen_op_movl_T0_rN(REG(B11_8));
441 return;
442 case 0x000e: /* mov.l @(R0,Rm),Rn */
443 gen_op_movl_rN_T0(REG(B7_4));
444 gen_op_add_rN_T0(REG(0));
445 gen_op_ldl_T0_T0(ctx);
446 gen_op_movl_T0_rN(REG(B11_8));
447 return;
448 case 0x6008: /* swap.b Rm,Rn */
449 gen_op_movl_rN_T0(REG(B7_4));
450 gen_op_swapb_T0();
451 gen_op_movl_T0_rN(REG(B11_8));
452 return;
453 case 0x6009: /* swap.w Rm,Rn */
454 gen_op_movl_rN_T0(REG(B7_4));
455 gen_op_swapw_T0();
456 gen_op_movl_T0_rN(REG(B11_8));
457 return;
458 case 0x200d: /* xtrct Rm,Rn */
459 gen_op_movl_rN_T0(REG(B7_4));
460 gen_op_movl_rN_T1(REG(B11_8));
461 gen_op_xtrct_T0_T1();
462 gen_op_movl_T1_rN(REG(B11_8));
463 return;
464 case 0x300c: /* add Rm,Rn */
465 gen_op_movl_rN_T0(REG(B7_4));
466 gen_op_add_T0_rN(REG(B11_8));
467 return;
468 case 0x300e: /* addc Rm,Rn */
469 gen_op_movl_rN_T0(REG(B7_4));
470 gen_op_movl_rN_T1(REG(B11_8));
471 gen_op_addc_T0_T1();
472 gen_op_movl_T1_rN(REG(B11_8));
473 return;
474 case 0x300f: /* addv Rm,Rn */
475 gen_op_movl_rN_T0(REG(B7_4));
476 gen_op_movl_rN_T1(REG(B11_8));
477 gen_op_addv_T0_T1();
478 gen_op_movl_T1_rN(REG(B11_8));
479 return;
480 case 0x2009: /* and Rm,Rn */
481 gen_op_movl_rN_T0(REG(B7_4));
482 gen_op_and_T0_rN(REG(B11_8));
483 return;
484 case 0x3000: /* cmp/eq Rm,Rn */
485 gen_op_movl_rN_T0(REG(B7_4));
486 gen_op_movl_rN_T1(REG(B11_8));
487 gen_op_cmp_eq_T0_T1();
488 return;
489 case 0x3003: /* cmp/ge Rm,Rn */
490 gen_op_movl_rN_T0(REG(B7_4));
491 gen_op_movl_rN_T1(REG(B11_8));
492 gen_op_cmp_ge_T0_T1();
493 return;
494 case 0x3007: /* cmp/gt Rm,Rn */
495 gen_op_movl_rN_T0(REG(B7_4));
496 gen_op_movl_rN_T1(REG(B11_8));
497 gen_op_cmp_gt_T0_T1();
498 return;
499 case 0x3006: /* cmp/hi Rm,Rn */
500 gen_op_movl_rN_T0(REG(B7_4));
501 gen_op_movl_rN_T1(REG(B11_8));
502 gen_op_cmp_hi_T0_T1();
503 return;
504 case 0x3002: /* cmp/hs Rm,Rn */
505 gen_op_movl_rN_T0(REG(B7_4));
506 gen_op_movl_rN_T1(REG(B11_8));
507 gen_op_cmp_hs_T0_T1();
508 return;
509 case 0x200c: /* cmp/str Rm,Rn */
510 gen_op_movl_rN_T0(REG(B7_4));
511 gen_op_movl_rN_T1(REG(B11_8));
512 gen_op_cmp_str_T0_T1();
513 return;
514 case 0x2007: /* div0s Rm,Rn */
515 gen_op_movl_rN_T0(REG(B7_4));
516 gen_op_movl_rN_T1(REG(B11_8));
517 gen_op_div0s_T0_T1();
518 gen_op_movl_T1_rN(REG(B11_8));
519 return;
520 case 0x3004: /* div1 Rm,Rn */
521 gen_op_movl_rN_T0(REG(B7_4));
522 gen_op_movl_rN_T1(REG(B11_8));
523 gen_op_div1_T0_T1();
524 gen_op_movl_T1_rN(REG(B11_8));
525 return;
526 case 0x300d: /* dmuls.l Rm,Rn */
527 gen_op_movl_rN_T0(REG(B7_4));
528 gen_op_movl_rN_T1(REG(B11_8));
529 gen_op_dmulsl_T0_T1();
530 return;
531 case 0x3005: /* dmulu.l Rm,Rn */
532 gen_op_movl_rN_T0(REG(B7_4));
533 gen_op_movl_rN_T1(REG(B11_8));
534 gen_op_dmulul_T0_T1();
535 return;
536 case 0x600e: /* exts.b Rm,Rn */
537 gen_op_movb_rN_T0(REG(B7_4));
538 gen_op_movl_T0_rN(REG(B11_8));
539 return;
540 case 0x600f: /* exts.w Rm,Rn */
541 gen_op_movw_rN_T0(REG(B7_4));
542 gen_op_movl_T0_rN(REG(B11_8));
543 return;
544 case 0x600c: /* extu.b Rm,Rn */
545 gen_op_movub_rN_T0(REG(B7_4));
546 gen_op_movl_T0_rN(REG(B11_8));
547 return;
548 case 0x600d: /* extu.w Rm,Rn */
549 gen_op_movuw_rN_T0(REG(B7_4));
550 gen_op_movl_T0_rN(REG(B11_8));
551 return;
552 case 0x000f: /* mac.l @Rm+,@Rn- */
553 gen_op_movl_rN_T0(REG(B11_8));
554 gen_op_ldl_T0_T0(ctx);
555 gen_op_movl_T0_T1();
556 gen_op_movl_rN_T1(REG(B7_4));
557 gen_op_ldl_T0_T0(ctx);
558 gen_op_macl_T0_T1();
559 gen_op_inc4_rN(REG(B7_4));
560 gen_op_inc4_rN(REG(B11_8));
561 return;
562 case 0x400f: /* mac.w @Rm+,@Rn+ */
563 gen_op_movl_rN_T0(REG(B11_8));
564 gen_op_ldl_T0_T0(ctx);
565 gen_op_movl_T0_T1();
566 gen_op_movl_rN_T1(REG(B7_4));
567 gen_op_ldl_T0_T0(ctx);
568 gen_op_macw_T0_T1();
569 gen_op_inc2_rN(REG(B7_4));
570 gen_op_inc2_rN(REG(B11_8));
571 return;
572 case 0x0007: /* mul.l Rm,Rn */
573 gen_op_movl_rN_T0(REG(B7_4));
574 gen_op_movl_rN_T1(REG(B11_8));
575 gen_op_mull_T0_T1();
576 return;
577 case 0x200f: /* muls.w Rm,Rn */
578 gen_op_movw_rN_T0(REG(B7_4));
579 gen_op_movw_rN_T1(REG(B11_8));
580 gen_op_mulsw_T0_T1();
581 return;
582 case 0x200e: /* mulu.w Rm,Rn */
583 gen_op_movuw_rN_T0(REG(B7_4));
584 gen_op_movuw_rN_T1(REG(B11_8));
585 gen_op_muluw_T0_T1();
586 return;
587 case 0x600b: /* neg Rm,Rn */
588 gen_op_movl_rN_T0(REG(B7_4));
589 gen_op_neg_T0();
590 gen_op_movl_T0_rN(REG(B11_8));
591 return;
592 case 0x600a: /* negc Rm,Rn */
593 gen_op_movl_rN_T0(REG(B7_4));
594 gen_op_negc_T0();
595 gen_op_movl_T0_rN(REG(B11_8));
596 return;
597 case 0x6007: /* not Rm,Rn */
598 gen_op_movl_rN_T0(REG(B7_4));
599 gen_op_not_T0();
600 gen_op_movl_T0_rN(REG(B11_8));
601 return;
602 case 0x200b: /* or Rm,Rn */
603 gen_op_movl_rN_T0(REG(B7_4));
604 gen_op_or_T0_rN(REG(B11_8));
605 return;
606 case 0x400c: /* shad Rm,Rn */
607 gen_op_movl_rN_T0(REG(B7_4));
608 gen_op_movl_rN_T1(REG(B11_8));
609 gen_op_shad_T0_T1();
610 gen_op_movl_T1_rN(REG(B11_8));
611 return;
612 case 0x400d: /* shld Rm,Rn */
613 gen_op_movl_rN_T0(REG(B7_4));
614 gen_op_movl_rN_T1(REG(B11_8));
615 gen_op_shld_T0_T1();
616 gen_op_movl_T1_rN(REG(B11_8));
617 return;
618 case 0x3008: /* sub Rm,Rn */
619 gen_op_movl_rN_T0(REG(B7_4));
620 gen_op_sub_T0_rN(REG(B11_8));
621 return;
622 case 0x300a: /* subc Rm,Rn */
623 gen_op_movl_rN_T0(REG(B7_4));
624 gen_op_movl_rN_T1(REG(B11_8));
625 gen_op_subc_T0_T1();
626 gen_op_movl_T1_rN(REG(B11_8));
627 return;
628 case 0x300b: /* subv Rm,Rn */
629 gen_op_movl_rN_T0(REG(B7_4));
630 gen_op_movl_rN_T1(REG(B11_8));
631 gen_op_subv_T0_T1();
632 gen_op_movl_T1_rN(REG(B11_8));
633 return;
634 case 0x2008: /* tst Rm,Rn */
635 gen_op_movl_rN_T0(REG(B7_4));
636 gen_op_movl_rN_T1(REG(B11_8));
637 gen_op_tst_T0_T1();
638 return;
639 case 0x200a: /* xor Rm,Rn */
640 gen_op_movl_rN_T0(REG(B7_4));
641 gen_op_xor_T0_rN(REG(B11_8));
642 return;
643 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn */
644 if (ctx->fpscr & FPSCR_PR) {
645 gen_op_fmov_drN_DT0(XREG(B7_4));
646 gen_op_fmov_DT0_drN(XREG(B11_8));
647 } else if (ctx->fpscr & FPSCR_SZ) {
648 if (ctx->opcode & 0x0110)
649 break; /* illegal instruction */
650 gen_op_fmov_drN_DT0(XREG(B7_4));
651 gen_op_fmov_DT0_drN(XREG(B11_8));
652 } else {
653 gen_op_fmov_frN_FT0(FREG(B7_4));
654 gen_op_fmov_FT0_frN(FREG(B11_8));
656 return;
657 case 0xf00a: /* fmov {F,D,X}Rm,@Rn */
658 if (ctx->fpscr & FPSCR_PR) {
659 gen_op_fmov_drN_DT0(XREG(B7_4));
660 gen_op_movl_rN_T1(REG(B11_8));
661 gen_op_stfq_DT0_T1(ctx);
662 } else if (ctx->fpscr & FPSCR_SZ) {
663 if (ctx->opcode & 0x0010)
664 break; /* illegal instruction */
665 gen_op_fmov_drN_DT0(XREG(B7_4));
666 gen_op_movl_rN_T1(REG(B11_8));
667 gen_op_stfq_DT0_T1(ctx);
668 } else {
669 gen_op_fmov_frN_FT0(FREG(B7_4));
670 gen_op_movl_rN_T1(REG(B11_8));
671 gen_op_stfl_FT0_T1(ctx);
673 return;
674 case 0xf008: /* fmov @Rm,{F,D,X}Rn */
675 if (ctx->fpscr & FPSCR_PR) {
676 gen_op_movl_rN_T0(REG(B7_4));
677 gen_op_ldfq_T0_DT0(ctx);
678 gen_op_fmov_DT0_drN(XREG(B11_8));
679 } else if (ctx->fpscr & FPSCR_SZ) {
680 if (ctx->opcode & 0x0100)
681 break; /* illegal instruction */
682 gen_op_movl_rN_T0(REG(B7_4));
683 gen_op_ldfq_T0_DT0(ctx);
684 gen_op_fmov_DT0_drN(XREG(B11_8));
685 } else {
686 gen_op_movl_rN_T0(REG(B7_4));
687 gen_op_ldfl_T0_FT0(ctx);
688 gen_op_fmov_FT0_frN(XREG(B11_8));
690 return;
691 case 0xf009: /* fmov @Rm+,{F,D,X}Rn */
692 if (ctx->fpscr & FPSCR_PR) {
693 gen_op_movl_rN_T0(REG(B7_4));
694 gen_op_ldfq_T0_DT0(ctx);
695 gen_op_fmov_DT0_drN(XREG(B11_8));
696 gen_op_inc8_rN(REG(B7_4));
697 } else if (ctx->fpscr & FPSCR_SZ) {
698 if (ctx->opcode & 0x0100)
699 break; /* illegal instruction */
700 gen_op_movl_rN_T0(REG(B7_4));
701 gen_op_ldfq_T0_DT0(ctx);
702 gen_op_fmov_DT0_drN(XREG(B11_8));
703 gen_op_inc8_rN(REG(B7_4));
704 } else {
705 gen_op_movl_rN_T0(REG(B7_4));
706 gen_op_ldfl_T0_FT0(ctx);
707 gen_op_fmov_FT0_frN(XREG(B11_8));
708 gen_op_inc4_rN(REG(B7_4));
710 return;
711 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn */
712 if (ctx->fpscr & FPSCR_PR) {
713 gen_op_dec8_rN(REG(B11_8));
714 gen_op_fmov_drN_DT0(XREG(B7_4));
715 gen_op_movl_rN_T1(REG(B11_8));
716 gen_op_stfq_DT0_T1(ctx);
717 } else if (ctx->fpscr & FPSCR_SZ) {
718 if (ctx->opcode & 0x0100)
719 break; /* illegal instruction */
720 gen_op_dec8_rN(REG(B11_8));
721 gen_op_fmov_drN_DT0(XREG(B7_4));
722 gen_op_movl_rN_T1(REG(B11_8));
723 gen_op_stfq_DT0_T1(ctx);
724 } else {
725 gen_op_dec4_rN(REG(B11_8));
726 gen_op_fmov_frN_FT0(FREG(B7_4));
727 gen_op_movl_rN_T1(REG(B11_8));
728 gen_op_stfl_FT0_T1(ctx);
730 return;
731 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */
732 if (ctx->fpscr & FPSCR_PR) {
733 gen_op_movl_rN_T0(REG(B7_4));
734 gen_op_add_rN_T0(REG(0));
735 gen_op_ldfq_T0_DT0(ctx);
736 gen_op_fmov_DT0_drN(XREG(B11_8));
737 } else if (ctx->fpscr & FPSCR_SZ) {
738 if (ctx->opcode & 0x0100)
739 break; /* illegal instruction */
740 gen_op_movl_rN_T0(REG(B7_4));
741 gen_op_add_rN_T0(REG(0));
742 gen_op_ldfq_T0_DT0(ctx);
743 gen_op_fmov_DT0_drN(XREG(B11_8));
744 } else {
745 gen_op_movl_rN_T0(REG(B7_4));
746 gen_op_add_rN_T0(REG(0));
747 gen_op_ldfl_T0_FT0(ctx);
748 gen_op_fmov_FT0_frN(XREG(B11_8));
750 return;
751 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */
752 if (ctx->fpscr & FPSCR_PR) {
753 gen_op_fmov_drN_DT0(XREG(B7_4));
754 gen_op_movl_rN_T1(REG(B11_8));
755 gen_op_add_rN_T1(REG(0));
756 gen_op_stfq_DT0_T1(ctx);
757 } else if (ctx->fpscr & FPSCR_SZ) {
758 if (ctx->opcode & 0x0010)
759 break; /* illegal instruction */
760 gen_op_fmov_drN_DT0(XREG(B7_4));
761 gen_op_movl_rN_T1(REG(B11_8));
762 gen_op_add_rN_T1(REG(0));
763 gen_op_stfq_DT0_T1(ctx);
764 } else {
765 gen_op_fmov_frN_FT0(FREG(B7_4));
766 gen_op_movl_rN_T1(REG(B11_8));
767 gen_op_add_rN_T1(REG(0));
768 gen_op_stfl_FT0_T1(ctx);
770 return;
773 switch (ctx->opcode & 0xff00) {
774 case 0xc900: /* and #imm,R0 */
775 gen_op_and_imm_rN(B7_0, REG(0));
776 return;
777 case 0xcd00: /* and.b #imm,@(R0+GBR) */
778 gen_op_movl_rN_T0(REG(0));
779 gen_op_addl_GBR_T0();
780 gen_op_movl_T0_T1();
781 gen_op_ldb_T0_T0(ctx);
782 gen_op_and_imm_T0(B7_0);
783 gen_op_stb_T0_T1(ctx);
784 return;
785 case 0x8b00: /* bf label */
786 CHECK_NOT_DELAY_SLOT
787 gen_conditional_jump(ctx, ctx->pc + 2,
788 ctx->pc + 4 + B7_0s * 2);
789 ctx->flags |= BRANCH_CONDITIONAL;
790 return;
791 case 0x8f00: /* bf/s label */
792 CHECK_NOT_DELAY_SLOT
793 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
794 ctx->flags |= DELAY_SLOT_CONDITIONAL;
795 return;
796 case 0x8900: /* bt label */
797 CHECK_NOT_DELAY_SLOT
798 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
799 ctx->pc + 2);
800 ctx->flags |= BRANCH_CONDITIONAL;
801 return;
802 case 0x8d00: /* bt/s label */
803 CHECK_NOT_DELAY_SLOT
804 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
805 ctx->flags |= DELAY_SLOT_CONDITIONAL;
806 return;
807 case 0x8800: /* cmp/eq #imm,R0 */
808 gen_op_movl_rN_T0(REG(0));
809 gen_op_cmp_eq_imm_T0(B7_0s);
810 return;
811 case 0xc400: /* mov.b @(disp,GBR),R0 */
812 gen_op_stc_gbr_T0();
813 gen_op_addl_imm_T0(B7_0);
814 gen_op_ldb_T0_T0(ctx);
815 gen_op_movl_T0_rN(REG(0));
816 return;
817 case 0xc500: /* mov.w @(disp,GBR),R0 */
818 gen_op_stc_gbr_T0();
819 gen_op_addl_imm_T0(B7_0);
820 gen_op_ldw_T0_T0(ctx);
821 gen_op_movl_T0_rN(REG(0));
822 return;
823 case 0xc600: /* mov.l @(disp,GBR),R0 */
824 gen_op_stc_gbr_T0();
825 gen_op_addl_imm_T0(B7_0);
826 gen_op_ldl_T0_T0(ctx);
827 gen_op_movl_T0_rN(REG(0));
828 return;
829 case 0xc000: /* mov.b R0,@(disp,GBR) */
830 gen_op_stc_gbr_T0();
831 gen_op_addl_imm_T0(B7_0);
832 gen_op_movl_T0_T1();
833 gen_op_movl_rN_T0(REG(0));
834 gen_op_stb_T0_T1(ctx);
835 return;
836 case 0xc100: /* mov.w R0,@(disp,GBR) */
837 gen_op_stc_gbr_T0();
838 gen_op_addl_imm_T0(B7_0);
839 gen_op_movl_T0_T1();
840 gen_op_movl_rN_T0(REG(0));
841 gen_op_stw_T0_T1(ctx);
842 return;
843 case 0xc200: /* mov.l R0,@(disp,GBR) */
844 gen_op_stc_gbr_T0();
845 gen_op_addl_imm_T0(B7_0);
846 gen_op_movl_T0_T1();
847 gen_op_movl_rN_T0(REG(0));
848 gen_op_stl_T0_T1(ctx);
849 return;
850 case 0x8000: /* mov.b R0,@(disp,Rn) */
851 gen_op_movl_rN_T0(REG(0));
852 gen_op_movl_rN_T1(REG(B7_4));
853 gen_op_addl_imm_T1(B3_0);
854 gen_op_stb_T0_T1(ctx);
855 return;
856 case 0x8100: /* mov.w R0,@(disp,Rn) */
857 gen_op_movl_rN_T0(REG(0));
858 gen_op_movl_rN_T1(REG(B7_4));
859 gen_op_addl_imm_T1(B3_0 * 2);
860 gen_op_stw_T0_T1(ctx);
861 return;
862 case 0x8400: /* mov.b @(disp,Rn),R0 */
863 gen_op_movl_rN_T0(REG(0));
864 gen_op_movl_rN_T1(REG(B7_4));
865 gen_op_addl_imm_T1(B3_0);
866 gen_op_stb_T0_T1(ctx);
867 return;
868 case 0x8500: /* mov.w @(disp,Rn),R0 */
869 gen_op_movl_rN_T0(REG(B7_4));
870 gen_op_addl_imm_T0(B3_0 * 2);
871 gen_op_ldw_T0_T0(ctx);
872 gen_op_movl_T0_rN(REG(0));
873 return;
874 case 0xc700: /* mova @(disp,PC),R0 */
875 gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
876 REG(0));
877 return;
878 case 0xcb00: /* or #imm,R0 */
879 gen_op_or_imm_rN(B7_0, REG(0));
880 return;
881 case 0xcf00: /* or.b #imm,@(R0+GBR) */
882 gen_op_movl_rN_T0(REG(0));
883 gen_op_addl_GBR_T0();
884 gen_op_movl_T0_T1();
885 gen_op_ldb_T0_T0(ctx);
886 gen_op_or_imm_T0(B7_0);
887 gen_op_stb_T0_T1(ctx);
888 return;
889 case 0xc300: /* trapa #imm */
890 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
891 gen_op_trapa(B7_0);
892 ctx->flags |= BRANCH;
893 return;
894 case 0xc800: /* tst #imm,R0 */
895 gen_op_tst_imm_rN(B7_0, REG(0));
896 return;
897 case 0xcc00: /* tst #imm,@(R0+GBR) */
898 gen_op_movl_rN_T0(REG(0));
899 gen_op_addl_GBR_T0();
900 gen_op_ldb_T0_T0(ctx);
901 gen_op_tst_imm_T0(B7_0);
902 return;
903 case 0xca00: /* xor #imm,R0 */
904 gen_op_xor_imm_rN(B7_0, REG(0));
905 return;
906 case 0xce00: /* xor.b #imm,@(R0+GBR) */
907 gen_op_movl_rN_T0(REG(0));
908 gen_op_addl_GBR_T0();
909 gen_op_movl_T0_T1();
910 gen_op_ldb_T0_T0(ctx);
911 gen_op_xor_imm_T0(B7_0);
912 gen_op_stb_T0_T1(ctx);
913 return;
916 switch (ctx->opcode & 0xf08f) {
917 case 0x408e: /* ldc Rm,Rn_BANK */
918 gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
919 return;
920 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
921 gen_op_movl_rN_T0(REG(B11_8));
922 gen_op_ldl_T0_T0(ctx);
923 gen_op_movl_T0_rN(ALTREG(B6_4));
924 gen_op_inc4_rN(REG(B11_8));
925 return;
926 case 0x0082: /* stc Rm_BANK,Rn */
927 gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
928 return;
929 case 0x4083: /* stc.l Rm_BANK,@-Rn */
930 gen_op_dec4_rN(REG(B11_8));
931 gen_op_movl_rN_T1(REG(B11_8));
932 gen_op_movl_rN_T0(ALTREG(B6_4));
933 gen_op_stl_T0_T1(ctx);
934 return;
937 switch (ctx->opcode & 0xf0ff) {
938 case 0x0023: /* braf Rn */
939 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
940 gen_op_braf_T0(ctx->pc + 4);
941 ctx->flags |= DELAY_SLOT;
942 ctx->delayed_pc = (uint32_t) - 1;
943 return;
944 case 0x0003: /* bsrf Rn */
945 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
946 gen_op_bsrf_T0(ctx->pc + 4);
947 ctx->flags |= DELAY_SLOT;
948 ctx->delayed_pc = (uint32_t) - 1;
949 return;
950 case 0x4015: /* cmp/pl Rn */
951 gen_op_movl_rN_T0(REG(B11_8));
952 gen_op_cmp_pl_T0();
953 return;
954 case 0x4011: /* cmp/pz Rn */
955 gen_op_movl_rN_T0(REG(B11_8));
956 gen_op_cmp_pz_T0();
957 return;
958 case 0x4010: /* dt Rn */
959 gen_op_dt_rN(REG(B11_8));
960 return;
961 case 0x402b: /* jmp @Rn */
962 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
963 gen_op_jmp_T0();
964 ctx->flags |= DELAY_SLOT;
965 ctx->delayed_pc = (uint32_t) - 1;
966 return;
967 case 0x400b: /* jsr @Rn */
968 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
969 gen_op_jsr_T0(ctx->pc + 4);
970 ctx->flags |= DELAY_SLOT;
971 ctx->delayed_pc = (uint32_t) - 1;
972 return;
973 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
974 case ldnum: \
975 gen_op_movl_rN_T0 (REG(B11_8)); \
976 gen_op_##ldop##_T0_##reg (); \
977 extrald \
978 return; \
979 case ldpnum: \
980 gen_op_movl_rN_T0 (REG(B11_8)); \
981 gen_op_ldl_T0_T0 (ctx); \
982 gen_op_inc4_rN (REG(B11_8)); \
983 gen_op_##ldop##_T0_##reg (); \
984 extrald \
985 return; \
986 case stnum: \
987 gen_op_##stop##_##reg##_T0 (); \
988 gen_op_movl_T0_rN (REG(B11_8)); \
989 return; \
990 case stpnum: \
991 gen_op_##stop##_##reg##_T0 (); \
992 gen_op_dec4_rN (REG(B11_8)); \
993 gen_op_movl_rN_T1 (REG(B11_8)); \
994 gen_op_stl_T0_T1 (ctx); \
995 return;
996 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
997 MODE_CHANGE;)
998 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
999 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1000 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1001 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1002 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1003 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1004 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1005 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1006 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,)
1007 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |=
1008 MODE_CHANGE;)
1009 case 0x00c3: /* movca.l R0,@Rm */
1010 gen_op_movl_rN_T0(REG(0));
1011 gen_op_movl_rN_T1(REG(B11_8));
1012 gen_op_stl_T0_T1(ctx);
1013 return;
1014 case 0x0029: /* movt Rn */
1015 gen_op_movt_rN(REG(B11_8));
1016 return;
1017 case 0x0093: /* ocbi @Rn */
1018 gen_op_movl_rN_T0(REG(B11_8));
1019 gen_op_ldl_T0_T0(ctx);
1020 return;
1021 case 0x00a2: /* ocbp @Rn */
1022 gen_op_movl_rN_T0(REG(B11_8));
1023 gen_op_ldl_T0_T0(ctx);
1024 return;
1025 case 0x00b3: /* ocbwb @Rn */
1026 gen_op_movl_rN_T0(REG(B11_8));
1027 gen_op_ldl_T0_T0(ctx);
1028 return;
1029 case 0x0083: /* pref @Rn */
1030 return;
1031 case 0x4024: /* rotcl Rn */
1032 gen_op_rotcl_Rn(REG(B11_8));
1033 return;
1034 case 0x4025: /* rotcr Rn */
1035 gen_op_rotcr_Rn(REG(B11_8));
1036 return;
1037 case 0x4004: /* rotl Rn */
1038 gen_op_rotl_Rn(REG(B11_8));
1039 return;
1040 case 0x4005: /* rotr Rn */
1041 gen_op_rotr_Rn(REG(B11_8));
1042 return;
1043 case 0x4000: /* shll Rn */
1044 case 0x4020: /* shal Rn */
1045 gen_op_shal_Rn(REG(B11_8));
1046 return;
1047 case 0x4021: /* shar Rn */
1048 gen_op_shar_Rn(REG(B11_8));
1049 return;
1050 case 0x4001: /* shlr Rn */
1051 gen_op_shlr_Rn(REG(B11_8));
1052 return;
1053 case 0x4008: /* shll2 Rn */
1054 gen_op_shll2_Rn(REG(B11_8));
1055 return;
1056 case 0x4018: /* shll8 Rn */
1057 gen_op_shll8_Rn(REG(B11_8));
1058 return;
1059 case 0x4028: /* shll16 Rn */
1060 gen_op_shll16_Rn(REG(B11_8));
1061 return;
1062 case 0x4009: /* shlr2 Rn */
1063 gen_op_shlr2_Rn(REG(B11_8));
1064 return;
1065 case 0x4019: /* shlr8 Rn */
1066 gen_op_shlr8_Rn(REG(B11_8));
1067 return;
1068 case 0x4029: /* shlr16 Rn */
1069 gen_op_shlr16_Rn(REG(B11_8));
1070 return;
1071 case 0x401b: /* tas.b @Rn */
1072 gen_op_tasb_rN(REG(B11_8));
1073 return;
1074 case 0xf00d: /* fsts FPUL,FRn */
1075 gen_op_movl_fpul_FT0();
1076 gen_op_fmov_FT0_frN(FREG(B11_8));
1077 return;
1078 case 0xf01d: /* flds FRm.FPUL */
1079 gen_op_fmov_frN_FT0(FREG(B11_8));
1080 gen_op_movl_FT0_fpul();
1081 return;
1084 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1085 ctx->opcode, ctx->pc);
1086 gen_op_raise_illegal_instruction();
1087 ctx->flags |= BRANCH_EXCEPTION;
1090 static inline int
1091 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1092 int search_pc)
1094 DisasContext ctx;
1095 target_ulong pc_start;
1096 static uint16_t *gen_opc_end;
1097 uint32_t old_flags;
1098 int i, ii;
1100 pc_start = tb->pc;
1101 gen_opc_ptr = gen_opc_buf;
1102 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1103 gen_opparam_ptr = gen_opparam_buf;
1104 ctx.pc = pc_start;
1105 ctx.flags = env->flags;
1106 old_flags = 0;
1107 ctx.sr = env->sr;
1108 ctx.fpscr = env->fpscr;
1109 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1110 /* We don't know if the delayed pc came from a dynamic or static branch,
1111 so assume it is a dynamic branch. */
1112 ctx.delayed_pc = -1;
1113 ctx.tb = tb;
1114 ctx.singlestep_enabled = env->singlestep_enabled;
1115 nb_gen_labels = 0;
1117 #ifdef DEBUG_DISAS
1118 if (loglevel & CPU_LOG_TB_CPU) {
1119 fprintf(logfile,
1120 "------------------------------------------------\n");
1121 cpu_dump_state(env, logfile, fprintf, 0);
1123 #endif
1125 ii = -1;
1126 while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1127 (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1128 BRANCH_EXCEPTION)) == 0 &&
1129 gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1130 old_flags = ctx.flags;
1131 if (env->nb_breakpoints > 0) {
1132 for (i = 0; i < env->nb_breakpoints; i++) {
1133 if (ctx.pc == env->breakpoints[i]) {
1134 /* We have hit a breakpoint - make sure PC is up-to-date */
1135 gen_op_movl_imm_PC(ctx.pc);
1136 gen_op_debug();
1137 ctx.flags |= BRANCH_EXCEPTION;
1138 break;
1142 if (search_pc) {
1143 i = gen_opc_ptr - gen_opc_buf;
1144 if (ii < i) {
1145 ii++;
1146 while (ii < i)
1147 gen_opc_instr_start[ii++] = 0;
1149 gen_opc_pc[ii] = ctx.pc;
1150 gen_opc_instr_start[ii] = 1;
1152 #if 0
1153 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1154 fflush(stderr);
1155 #endif
1156 ctx.opcode = lduw_code(ctx.pc);
1157 decode_opc(&ctx);
1158 ctx.pc += 2;
1159 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1160 break;
1161 if (env->singlestep_enabled)
1162 break;
1163 #ifdef SH4_SINGLE_STEP
1164 break;
1165 #endif
1168 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1169 gen_delayed_conditional_jump(&ctx);
1170 } else if (old_flags & DELAY_SLOT) {
1171 gen_op_clr_delay_slot();
1172 gen_jump(&ctx);
1173 } else if (ctx.flags & BRANCH_EXCEPTION) {
1174 gen_jump_exception(&ctx);
1175 } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1176 gen_goto_tb(&ctx, 0, ctx.pc);
1179 if (env->singlestep_enabled) {
1180 gen_op_debug();
1182 *gen_opc_ptr = INDEX_op_end;
1183 if (search_pc) {
1184 i = gen_opc_ptr - gen_opc_buf;
1185 ii++;
1186 while (ii <= i)
1187 gen_opc_instr_start[ii++] = 0;
1188 tb->size = 0;
1189 } else {
1190 tb->size = ctx.pc - pc_start;
1193 #ifdef DEBUG_DISAS
1194 #ifdef SH4_DEBUG_DISAS
1195 if (loglevel & CPU_LOG_TB_IN_ASM)
1196 fprintf(logfile, "\n");
1197 #endif
1198 if (loglevel & CPU_LOG_TB_IN_ASM) {
1199 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1200 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1201 fprintf(logfile, "\n");
1203 if (loglevel & CPU_LOG_TB_OP) {
1204 fprintf(logfile, "OP:\n");
1205 dump_ops(gen_opc_buf, gen_opparam_buf);
1206 fprintf(logfile, "\n");
1208 #endif
1209 return 0;
1212 int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1214 return gen_intermediate_code_internal(env, tb, 0);
1217 int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1219 return gen_intermediate_code_internal(env, tb, 1);