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
28 #define SH4_DEBUG_DISAS
29 //#define SH4_SINGLE_STEP
35 #include "qemu-common.h"
37 typedef struct DisasContext {
38 struct TranslationBlock *tb;
47 int singlestep_enabled;
51 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
54 BS_STOP = 1, /* We want to stop translation for any reason */
55 BS_BRANCH = 2, /* We reached a branch condition */
56 BS_EXCP = 3, /* We reached an exception condition */
59 static TCGv cpu_env, cpu_T[2];
61 #include "gen-icount.h"
63 static void sh4_translate_init(void)
65 static int done_init = 0;
68 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
69 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
70 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
74 #ifdef CONFIG_USER_ONLY
76 #define GEN_OP_LD(width, reg) \
77 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
78 gen_op_ld##width##_T0_##reg##_raw(); \
80 #define GEN_OP_ST(width, reg) \
81 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
82 gen_op_st##width##_##reg##_T1_raw(); \
87 #define GEN_OP_LD(width, reg) \
88 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
89 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
90 else gen_op_ld##width##_T0_##reg##_user();\
92 #define GEN_OP_ST(width, reg) \
93 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
94 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
95 else gen_op_st##width##_##reg##_T1_user();\
113 void cpu_dump_state(CPUState * env, FILE * f,
114 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
118 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
119 env->pc, env->sr, env->pr, env->fpscr);
120 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
121 env->spc, env->ssr, env->gbr, env->vbr);
122 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
123 env->sgr, env->dbr, env->delayed_pc, env->fpul);
124 for (i = 0; i < 24; i += 4) {
125 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
126 i, env->gregs[i], i + 1, env->gregs[i + 1],
127 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
129 if (env->flags & DELAY_SLOT) {
130 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
132 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
133 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
138 void cpu_sh4_reset(CPUSH4State * env)
140 #if defined(CONFIG_USER_ONLY)
141 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
143 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
146 env->pc = 0xA0000000;
147 #if defined(CONFIG_USER_ONLY)
148 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
149 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
151 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
152 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
157 CPUSH4State *cpu_sh4_init(const char *cpu_model)
161 env = qemu_mallocz(sizeof(CPUSH4State));
165 sh4_translate_init();
171 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
173 TranslationBlock *tb;
176 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
177 !ctx->singlestep_enabled) {
178 /* Use a direct jump if in same page and singlestep not enabled */
180 gen_op_movl_imm_PC(dest);
181 tcg_gen_exit_tb((long) tb + n);
183 gen_op_movl_imm_PC(dest);
184 if (ctx->singlestep_enabled)
190 static void gen_jump(DisasContext * ctx)
192 if (ctx->delayed_pc == (uint32_t) - 1) {
193 /* Target is not statically known, it comes necessarily from a
194 delayed jump as immediate jump are conditinal jumps */
195 gen_op_movl_delayed_pc_PC();
196 if (ctx->singlestep_enabled)
200 gen_goto_tb(ctx, 0, ctx->delayed_pc);
204 /* Immediate conditional jump (bt or bf) */
205 static void gen_conditional_jump(DisasContext * ctx,
206 target_ulong ift, target_ulong ifnott)
210 l1 = gen_new_label();
212 gen_goto_tb(ctx, 0, ifnott);
214 gen_goto_tb(ctx, 1, ift);
217 /* Delayed conditional jump (bt or bf) */
218 static void gen_delayed_conditional_jump(DisasContext * ctx)
222 l1 = gen_new_label();
224 gen_goto_tb(ctx, 1, ctx->pc + 2);
229 #define B3_0 (ctx->opcode & 0xf)
230 #define B6_4 ((ctx->opcode >> 4) & 0x7)
231 #define B7_4 ((ctx->opcode >> 4) & 0xf)
232 #define B7_0 (ctx->opcode & 0xff)
233 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
234 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
235 (ctx->opcode & 0xfff))
236 #define B11_8 ((ctx->opcode >> 8) & 0xf)
237 #define B15_12 ((ctx->opcode >> 12) & 0xf)
239 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
242 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
245 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
246 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
247 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
248 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
250 #define CHECK_NOT_DELAY_SLOT \
251 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
252 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
255 void _decode_opc(DisasContext * ctx)
258 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
260 switch (ctx->opcode) {
261 case 0x0019: /* div0u */
264 case 0x000b: /* rts */
265 CHECK_NOT_DELAY_SLOT gen_op_rts();
266 ctx->flags |= DELAY_SLOT;
267 ctx->delayed_pc = (uint32_t) - 1;
269 case 0x0028: /* clrmac */
272 case 0x0048: /* clrs */
275 case 0x0008: /* clrt */
278 case 0x0038: /* ldtlb */
279 #if defined(CONFIG_USER_ONLY)
280 assert(0); /* XXXXX */
285 case 0x002b: /* rte */
286 CHECK_NOT_DELAY_SLOT gen_op_rte();
287 ctx->flags |= DELAY_SLOT;
288 ctx->delayed_pc = (uint32_t) - 1;
290 case 0x0058: /* sets */
293 case 0x0018: /* sett */
296 case 0xfbfd: /* frchg */
298 ctx->bstate = BS_STOP;
300 case 0xf3fd: /* fschg */
302 ctx->bstate = BS_STOP;
304 case 0x0009: /* nop */
306 case 0x001b: /* sleep */
310 gen_op_raise_illegal_instruction();
311 ctx->bstate = BS_EXCP;
316 switch (ctx->opcode & 0xf000) {
317 case 0x1000: /* mov.l Rm,@(disp,Rn) */
318 gen_op_movl_rN_T0(REG(B7_4));
319 gen_op_movl_rN_T1(REG(B11_8));
320 gen_op_addl_imm_T1(B3_0 * 4);
321 gen_op_stl_T0_T1(ctx);
323 case 0x5000: /* mov.l @(disp,Rm),Rn */
324 gen_op_movl_rN_T0(REG(B7_4));
325 gen_op_addl_imm_T0(B3_0 * 4);
326 gen_op_ldl_T0_T0(ctx);
327 gen_op_movl_T0_rN(REG(B11_8));
329 case 0xe000: /* mov #imm,Rn */
330 gen_op_movl_imm_rN(B7_0s, REG(B11_8));
332 case 0x9000: /* mov.w @(disp,PC),Rn */
333 gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
334 gen_op_ldw_T0_T0(ctx);
335 gen_op_movl_T0_rN(REG(B11_8));
337 case 0xd000: /* mov.l @(disp,PC),Rn */
338 gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
339 gen_op_ldl_T0_T0(ctx);
340 gen_op_movl_T0_rN(REG(B11_8));
342 case 0x7000: /* add #imm,Rn */
343 gen_op_add_imm_rN(B7_0s, REG(B11_8));
345 case 0xa000: /* bra disp */
347 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
348 ctx->flags |= DELAY_SLOT;
350 case 0xb000: /* bsr disp */
352 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
353 ctx->pc + 4 + B11_0s * 2);
354 ctx->flags |= DELAY_SLOT;
358 switch (ctx->opcode & 0xf00f) {
359 case 0x6003: /* mov Rm,Rn */
360 gen_op_movl_rN_T0(REG(B7_4));
361 gen_op_movl_T0_rN(REG(B11_8));
363 case 0x2000: /* mov.b Rm,@Rn */
364 gen_op_movl_rN_T0(REG(B7_4));
365 gen_op_movl_rN_T1(REG(B11_8));
366 gen_op_stb_T0_T1(ctx);
368 case 0x2001: /* mov.w Rm,@Rn */
369 gen_op_movl_rN_T0(REG(B7_4));
370 gen_op_movl_rN_T1(REG(B11_8));
371 gen_op_stw_T0_T1(ctx);
373 case 0x2002: /* mov.l Rm,@Rn */
374 gen_op_movl_rN_T0(REG(B7_4));
375 gen_op_movl_rN_T1(REG(B11_8));
376 gen_op_stl_T0_T1(ctx);
378 case 0x6000: /* mov.b @Rm,Rn */
379 gen_op_movl_rN_T0(REG(B7_4));
380 gen_op_ldb_T0_T0(ctx);
381 gen_op_movl_T0_rN(REG(B11_8));
383 case 0x6001: /* mov.w @Rm,Rn */
384 gen_op_movl_rN_T0(REG(B7_4));
385 gen_op_ldw_T0_T0(ctx);
386 gen_op_movl_T0_rN(REG(B11_8));
388 case 0x6002: /* mov.l @Rm,Rn */
389 gen_op_movl_rN_T0(REG(B7_4));
390 gen_op_ldl_T0_T0(ctx);
391 gen_op_movl_T0_rN(REG(B11_8));
393 case 0x2004: /* mov.b Rm,@-Rn */
394 gen_op_movl_rN_T0(REG(B7_4));
395 gen_op_dec1_rN(REG(B11_8)); /* modify register status */
396 gen_op_movl_rN_T1(REG(B11_8));
397 gen_op_inc1_rN(REG(B11_8)); /* recover register status */
398 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
399 gen_op_dec1_rN(REG(B11_8)); /* modify register status */
401 case 0x2005: /* mov.w Rm,@-Rn */
402 gen_op_movl_rN_T0(REG(B7_4));
403 gen_op_dec2_rN(REG(B11_8));
404 gen_op_movl_rN_T1(REG(B11_8));
405 gen_op_inc2_rN(REG(B11_8));
406 gen_op_stw_T0_T1(ctx);
407 gen_op_dec2_rN(REG(B11_8));
409 case 0x2006: /* mov.l Rm,@-Rn */
410 gen_op_movl_rN_T0(REG(B7_4));
411 gen_op_dec4_rN(REG(B11_8));
412 gen_op_movl_rN_T1(REG(B11_8));
413 gen_op_inc4_rN(REG(B11_8));
414 gen_op_stl_T0_T1(ctx);
415 gen_op_dec4_rN(REG(B11_8));
417 case 0x6004: /* mov.b @Rm+,Rn */
418 gen_op_movl_rN_T0(REG(B7_4));
419 gen_op_ldb_T0_T0(ctx);
420 gen_op_movl_T0_rN(REG(B11_8));
422 gen_op_inc1_rN(REG(B7_4));
424 case 0x6005: /* mov.w @Rm+,Rn */
425 gen_op_movl_rN_T0(REG(B7_4));
426 gen_op_ldw_T0_T0(ctx);
427 gen_op_movl_T0_rN(REG(B11_8));
429 gen_op_inc2_rN(REG(B7_4));
431 case 0x6006: /* mov.l @Rm+,Rn */
432 gen_op_movl_rN_T0(REG(B7_4));
433 gen_op_ldl_T0_T0(ctx);
434 gen_op_movl_T0_rN(REG(B11_8));
436 gen_op_inc4_rN(REG(B7_4));
438 case 0x0004: /* mov.b Rm,@(R0,Rn) */
439 gen_op_movl_rN_T0(REG(B7_4));
440 gen_op_movl_rN_T1(REG(B11_8));
441 gen_op_add_rN_T1(REG(0));
442 gen_op_stb_T0_T1(ctx);
444 case 0x0005: /* mov.w Rm,@(R0,Rn) */
445 gen_op_movl_rN_T0(REG(B7_4));
446 gen_op_movl_rN_T1(REG(B11_8));
447 gen_op_add_rN_T1(REG(0));
448 gen_op_stw_T0_T1(ctx);
450 case 0x0006: /* mov.l Rm,@(R0,Rn) */
451 gen_op_movl_rN_T0(REG(B7_4));
452 gen_op_movl_rN_T1(REG(B11_8));
453 gen_op_add_rN_T1(REG(0));
454 gen_op_stl_T0_T1(ctx);
456 case 0x000c: /* mov.b @(R0,Rm),Rn */
457 gen_op_movl_rN_T0(REG(B7_4));
458 gen_op_add_rN_T0(REG(0));
459 gen_op_ldb_T0_T0(ctx);
460 gen_op_movl_T0_rN(REG(B11_8));
462 case 0x000d: /* mov.w @(R0,Rm),Rn */
463 gen_op_movl_rN_T0(REG(B7_4));
464 gen_op_add_rN_T0(REG(0));
465 gen_op_ldw_T0_T0(ctx);
466 gen_op_movl_T0_rN(REG(B11_8));
468 case 0x000e: /* mov.l @(R0,Rm),Rn */
469 gen_op_movl_rN_T0(REG(B7_4));
470 gen_op_add_rN_T0(REG(0));
471 gen_op_ldl_T0_T0(ctx);
472 gen_op_movl_T0_rN(REG(B11_8));
474 case 0x6008: /* swap.b Rm,Rn */
475 gen_op_movl_rN_T0(REG(B7_4));
477 gen_op_movl_T0_rN(REG(B11_8));
479 case 0x6009: /* swap.w Rm,Rn */
480 gen_op_movl_rN_T0(REG(B7_4));
482 gen_op_movl_T0_rN(REG(B11_8));
484 case 0x200d: /* xtrct Rm,Rn */
485 gen_op_movl_rN_T0(REG(B7_4));
486 gen_op_movl_rN_T1(REG(B11_8));
487 gen_op_xtrct_T0_T1();
488 gen_op_movl_T1_rN(REG(B11_8));
490 case 0x300c: /* add Rm,Rn */
491 gen_op_movl_rN_T0(REG(B7_4));
492 gen_op_add_T0_rN(REG(B11_8));
494 case 0x300e: /* addc Rm,Rn */
495 gen_op_movl_rN_T0(REG(B7_4));
496 gen_op_movl_rN_T1(REG(B11_8));
498 gen_op_movl_T1_rN(REG(B11_8));
500 case 0x300f: /* addv Rm,Rn */
501 gen_op_movl_rN_T0(REG(B7_4));
502 gen_op_movl_rN_T1(REG(B11_8));
504 gen_op_movl_T1_rN(REG(B11_8));
506 case 0x2009: /* and Rm,Rn */
507 gen_op_movl_rN_T0(REG(B7_4));
508 gen_op_and_T0_rN(REG(B11_8));
510 case 0x3000: /* cmp/eq Rm,Rn */
511 gen_op_movl_rN_T0(REG(B7_4));
512 gen_op_movl_rN_T1(REG(B11_8));
513 gen_op_cmp_eq_T0_T1();
515 case 0x3003: /* cmp/ge Rm,Rn */
516 gen_op_movl_rN_T0(REG(B7_4));
517 gen_op_movl_rN_T1(REG(B11_8));
518 gen_op_cmp_ge_T0_T1();
520 case 0x3007: /* cmp/gt Rm,Rn */
521 gen_op_movl_rN_T0(REG(B7_4));
522 gen_op_movl_rN_T1(REG(B11_8));
523 gen_op_cmp_gt_T0_T1();
525 case 0x3006: /* cmp/hi Rm,Rn */
526 gen_op_movl_rN_T0(REG(B7_4));
527 gen_op_movl_rN_T1(REG(B11_8));
528 gen_op_cmp_hi_T0_T1();
530 case 0x3002: /* cmp/hs Rm,Rn */
531 gen_op_movl_rN_T0(REG(B7_4));
532 gen_op_movl_rN_T1(REG(B11_8));
533 gen_op_cmp_hs_T0_T1();
535 case 0x200c: /* cmp/str Rm,Rn */
536 gen_op_movl_rN_T0(REG(B7_4));
537 gen_op_movl_rN_T1(REG(B11_8));
538 gen_op_cmp_str_T0_T1();
540 case 0x2007: /* div0s Rm,Rn */
541 gen_op_movl_rN_T0(REG(B7_4));
542 gen_op_movl_rN_T1(REG(B11_8));
543 gen_op_div0s_T0_T1();
545 case 0x3004: /* div1 Rm,Rn */
546 gen_op_movl_rN_T0(REG(B7_4));
547 gen_op_movl_rN_T1(REG(B11_8));
549 gen_op_movl_T1_rN(REG(B11_8));
551 case 0x300d: /* dmuls.l Rm,Rn */
552 gen_op_movl_rN_T0(REG(B7_4));
553 gen_op_movl_rN_T1(REG(B11_8));
554 gen_op_dmulsl_T0_T1();
556 case 0x3005: /* dmulu.l Rm,Rn */
557 gen_op_movl_rN_T0(REG(B7_4));
558 gen_op_movl_rN_T1(REG(B11_8));
559 gen_op_dmulul_T0_T1();
561 case 0x600e: /* exts.b Rm,Rn */
562 gen_op_movb_rN_T0(REG(B7_4));
563 gen_op_movl_T0_rN(REG(B11_8));
565 case 0x600f: /* exts.w Rm,Rn */
566 gen_op_movw_rN_T0(REG(B7_4));
567 gen_op_movl_T0_rN(REG(B11_8));
569 case 0x600c: /* extu.b Rm,Rn */
570 gen_op_movub_rN_T0(REG(B7_4));
571 gen_op_movl_T0_rN(REG(B11_8));
573 case 0x600d: /* extu.w Rm,Rn */
574 gen_op_movuw_rN_T0(REG(B7_4));
575 gen_op_movl_T0_rN(REG(B11_8));
577 case 0x000f: /* mac.l @Rm+,@Rn+ */
578 gen_op_movl_rN_T0(REG(B11_8));
579 gen_op_ldl_T0_T0(ctx);
581 gen_op_movl_rN_T0(REG(B7_4));
582 gen_op_ldl_T0_T0(ctx);
584 gen_op_inc4_rN(REG(B11_8));
585 gen_op_inc4_rN(REG(B7_4));
587 case 0x400f: /* mac.w @Rm+,@Rn+ */
588 gen_op_movl_rN_T0(REG(B11_8));
589 gen_op_ldl_T0_T0(ctx);
591 gen_op_movl_rN_T0(REG(B7_4));
592 gen_op_ldl_T0_T0(ctx);
594 gen_op_inc2_rN(REG(B11_8));
595 gen_op_inc2_rN(REG(B7_4));
597 case 0x0007: /* mul.l Rm,Rn */
598 gen_op_movl_rN_T0(REG(B7_4));
599 gen_op_movl_rN_T1(REG(B11_8));
602 case 0x200f: /* muls.w Rm,Rn */
603 gen_op_movw_rN_T0(REG(B7_4));
604 gen_op_movw_rN_T1(REG(B11_8));
605 gen_op_mulsw_T0_T1();
607 case 0x200e: /* mulu.w Rm,Rn */
608 gen_op_movuw_rN_T0(REG(B7_4));
609 gen_op_movuw_rN_T1(REG(B11_8));
610 gen_op_muluw_T0_T1();
612 case 0x600b: /* neg Rm,Rn */
613 gen_op_movl_rN_T0(REG(B7_4));
615 gen_op_movl_T0_rN(REG(B11_8));
617 case 0x600a: /* negc Rm,Rn */
618 gen_op_movl_rN_T0(REG(B7_4));
620 gen_op_movl_T0_rN(REG(B11_8));
622 case 0x6007: /* not Rm,Rn */
623 gen_op_movl_rN_T0(REG(B7_4));
625 gen_op_movl_T0_rN(REG(B11_8));
627 case 0x200b: /* or Rm,Rn */
628 gen_op_movl_rN_T0(REG(B7_4));
629 gen_op_or_T0_rN(REG(B11_8));
631 case 0x400c: /* shad Rm,Rn */
632 gen_op_movl_rN_T0(REG(B7_4));
633 gen_op_movl_rN_T1(REG(B11_8));
635 gen_op_movl_T1_rN(REG(B11_8));
637 case 0x400d: /* shld Rm,Rn */
638 gen_op_movl_rN_T0(REG(B7_4));
639 gen_op_movl_rN_T1(REG(B11_8));
641 gen_op_movl_T1_rN(REG(B11_8));
643 case 0x3008: /* sub Rm,Rn */
644 gen_op_movl_rN_T0(REG(B7_4));
645 gen_op_sub_T0_rN(REG(B11_8));
647 case 0x300a: /* subc Rm,Rn */
648 gen_op_movl_rN_T0(REG(B7_4));
649 gen_op_movl_rN_T1(REG(B11_8));
651 gen_op_movl_T1_rN(REG(B11_8));
653 case 0x300b: /* subv Rm,Rn */
654 gen_op_movl_rN_T0(REG(B7_4));
655 gen_op_movl_rN_T1(REG(B11_8));
657 gen_op_movl_T1_rN(REG(B11_8));
659 case 0x2008: /* tst Rm,Rn */
660 gen_op_movl_rN_T0(REG(B7_4));
661 gen_op_movl_rN_T1(REG(B11_8));
664 case 0x200a: /* xor Rm,Rn */
665 gen_op_movl_rN_T0(REG(B7_4));
666 gen_op_xor_T0_rN(REG(B11_8));
668 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
669 if (ctx->fpscr & FPSCR_SZ) {
670 gen_op_fmov_drN_DT0(XREG(B7_4));
671 gen_op_fmov_DT0_drN(XREG(B11_8));
673 gen_op_fmov_frN_FT0(FREG(B7_4));
674 gen_op_fmov_FT0_frN(FREG(B11_8));
677 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
678 if (ctx->fpscr & FPSCR_SZ) {
679 gen_op_fmov_drN_DT0(XREG(B7_4));
680 gen_op_movl_rN_T1(REG(B11_8));
681 gen_op_stfq_DT0_T1(ctx);
683 gen_op_fmov_frN_FT0(FREG(B7_4));
684 gen_op_movl_rN_T1(REG(B11_8));
685 gen_op_stfl_FT0_T1(ctx);
688 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
689 if (ctx->fpscr & FPSCR_SZ) {
690 gen_op_movl_rN_T0(REG(B7_4));
691 gen_op_ldfq_T0_DT0(ctx);
692 gen_op_fmov_DT0_drN(XREG(B11_8));
694 gen_op_movl_rN_T0(REG(B7_4));
695 gen_op_ldfl_T0_FT0(ctx);
696 gen_op_fmov_FT0_frN(FREG(B11_8));
699 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
700 if (ctx->fpscr & FPSCR_SZ) {
701 gen_op_movl_rN_T0(REG(B7_4));
702 gen_op_ldfq_T0_DT0(ctx);
703 gen_op_fmov_DT0_drN(XREG(B11_8));
704 gen_op_inc8_rN(REG(B7_4));
706 gen_op_movl_rN_T0(REG(B7_4));
707 gen_op_ldfl_T0_FT0(ctx);
708 gen_op_fmov_FT0_frN(FREG(B11_8));
709 gen_op_inc4_rN(REG(B7_4));
712 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
713 if (ctx->fpscr & FPSCR_SZ) {
714 gen_op_dec8_rN(REG(B11_8));
715 gen_op_fmov_drN_DT0(XREG(B7_4));
716 gen_op_movl_rN_T1(REG(B11_8));
717 gen_op_inc8_rN(REG(B11_8));
718 gen_op_stfq_DT0_T1(ctx);
719 gen_op_dec8_rN(REG(B11_8));
721 gen_op_dec4_rN(REG(B11_8));
722 gen_op_fmov_frN_FT0(FREG(B7_4));
723 gen_op_movl_rN_T1(REG(B11_8));
724 gen_op_inc4_rN(REG(B11_8));
725 gen_op_stfl_FT0_T1(ctx);
726 gen_op_dec4_rN(REG(B11_8));
729 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
730 if (ctx->fpscr & FPSCR_SZ) {
731 gen_op_movl_rN_T0(REG(B7_4));
732 gen_op_add_rN_T0(REG(0));
733 gen_op_ldfq_T0_DT0(ctx);
734 gen_op_fmov_DT0_drN(XREG(B11_8));
736 gen_op_movl_rN_T0(REG(B7_4));
737 gen_op_add_rN_T0(REG(0));
738 gen_op_ldfl_T0_FT0(ctx);
739 gen_op_fmov_FT0_frN(FREG(B11_8));
742 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
743 if (ctx->fpscr & FPSCR_SZ) {
744 gen_op_fmov_drN_DT0(XREG(B7_4));
745 gen_op_movl_rN_T1(REG(B11_8));
746 gen_op_add_rN_T1(REG(0));
747 gen_op_stfq_DT0_T1(ctx);
749 gen_op_fmov_frN_FT0(FREG(B7_4));
750 gen_op_movl_rN_T1(REG(B11_8));
751 gen_op_add_rN_T1(REG(0));
752 gen_op_stfl_FT0_T1(ctx);
755 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
756 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
757 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
758 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
759 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
760 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
761 if (ctx->fpscr & FPSCR_PR) {
762 if (ctx->opcode & 0x0110)
763 break; /* illegal instruction */
764 gen_op_fmov_drN_DT1(DREG(B7_4));
765 gen_op_fmov_drN_DT0(DREG(B11_8));
768 gen_op_fmov_frN_FT1(FREG(B7_4));
769 gen_op_fmov_frN_FT0(FREG(B11_8));
772 switch (ctx->opcode & 0xf00f) {
773 case 0xf000: /* fadd Rm,Rn */
774 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
776 case 0xf001: /* fsub Rm,Rn */
777 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
779 case 0xf002: /* fmul Rm,Rn */
780 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
782 case 0xf003: /* fdiv Rm,Rn */
783 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
785 case 0xf004: /* fcmp/eq Rm,Rn */
786 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
788 case 0xf005: /* fcmp/gt Rm,Rn */
789 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
793 if (ctx->fpscr & FPSCR_PR) {
794 gen_op_fmov_DT0_drN(DREG(B11_8));
797 gen_op_fmov_FT0_frN(FREG(B11_8));
802 switch (ctx->opcode & 0xff00) {
803 case 0xc900: /* and #imm,R0 */
804 gen_op_and_imm_rN(B7_0, REG(0));
806 case 0xcd00: /* and.b #imm,@(R0,GBR) */
807 gen_op_movl_rN_T0(REG(0));
808 gen_op_addl_GBR_T0();
810 gen_op_ldub_T0_T0(ctx);
811 gen_op_and_imm_T0(B7_0);
812 gen_op_stb_T0_T1(ctx);
814 case 0x8b00: /* bf label */
816 gen_conditional_jump(ctx, ctx->pc + 2,
817 ctx->pc + 4 + B7_0s * 2);
818 ctx->bstate = BS_BRANCH;
820 case 0x8f00: /* bf/s label */
822 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
823 ctx->flags |= DELAY_SLOT_CONDITIONAL;
825 case 0x8900: /* bt label */
827 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
829 ctx->bstate = BS_BRANCH;
831 case 0x8d00: /* bt/s label */
833 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
834 ctx->flags |= DELAY_SLOT_CONDITIONAL;
836 case 0x8800: /* cmp/eq #imm,R0 */
837 gen_op_movl_rN_T0(REG(0));
838 gen_op_cmp_eq_imm_T0(B7_0s);
840 case 0xc400: /* mov.b @(disp,GBR),R0 */
842 gen_op_addl_imm_T0(B7_0);
843 gen_op_ldb_T0_T0(ctx);
844 gen_op_movl_T0_rN(REG(0));
846 case 0xc500: /* mov.w @(disp,GBR),R0 */
848 gen_op_addl_imm_T0(B7_0 * 2);
849 gen_op_ldw_T0_T0(ctx);
850 gen_op_movl_T0_rN(REG(0));
852 case 0xc600: /* mov.l @(disp,GBR),R0 */
854 gen_op_addl_imm_T0(B7_0 * 4);
855 gen_op_ldl_T0_T0(ctx);
856 gen_op_movl_T0_rN(REG(0));
858 case 0xc000: /* mov.b R0,@(disp,GBR) */
860 gen_op_addl_imm_T0(B7_0);
862 gen_op_movl_rN_T0(REG(0));
863 gen_op_stb_T0_T1(ctx);
865 case 0xc100: /* mov.w R0,@(disp,GBR) */
867 gen_op_addl_imm_T0(B7_0 * 2);
869 gen_op_movl_rN_T0(REG(0));
870 gen_op_stw_T0_T1(ctx);
872 case 0xc200: /* mov.l R0,@(disp,GBR) */
874 gen_op_addl_imm_T0(B7_0 * 4);
876 gen_op_movl_rN_T0(REG(0));
877 gen_op_stl_T0_T1(ctx);
879 case 0x8000: /* mov.b R0,@(disp,Rn) */
880 gen_op_movl_rN_T0(REG(0));
881 gen_op_movl_rN_T1(REG(B7_4));
882 gen_op_addl_imm_T1(B3_0);
883 gen_op_stb_T0_T1(ctx);
885 case 0x8100: /* mov.w R0,@(disp,Rn) */
886 gen_op_movl_rN_T0(REG(0));
887 gen_op_movl_rN_T1(REG(B7_4));
888 gen_op_addl_imm_T1(B3_0 * 2);
889 gen_op_stw_T0_T1(ctx);
891 case 0x8400: /* mov.b @(disp,Rn),R0 */
892 gen_op_movl_rN_T0(REG(B7_4));
893 gen_op_addl_imm_T0(B3_0);
894 gen_op_ldb_T0_T0(ctx);
895 gen_op_movl_T0_rN(REG(0));
897 case 0x8500: /* mov.w @(disp,Rn),R0 */
898 gen_op_movl_rN_T0(REG(B7_4));
899 gen_op_addl_imm_T0(B3_0 * 2);
900 gen_op_ldw_T0_T0(ctx);
901 gen_op_movl_T0_rN(REG(0));
903 case 0xc700: /* mova @(disp,PC),R0 */
904 gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
907 case 0xcb00: /* or #imm,R0 */
908 gen_op_or_imm_rN(B7_0, REG(0));
910 case 0xcf00: /* or.b #imm,@(R0,GBR) */
911 gen_op_movl_rN_T0(REG(0));
912 gen_op_addl_GBR_T0();
914 gen_op_ldub_T0_T0(ctx);
915 gen_op_or_imm_T0(B7_0);
916 gen_op_stb_T0_T1(ctx);
918 case 0xc300: /* trapa #imm */
919 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
921 ctx->bstate = BS_BRANCH;
923 case 0xc800: /* tst #imm,R0 */
924 gen_op_tst_imm_rN(B7_0, REG(0));
926 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
927 gen_op_movl_rN_T0(REG(0));
928 gen_op_addl_GBR_T0();
929 gen_op_ldub_T0_T0(ctx);
930 gen_op_tst_imm_T0(B7_0);
932 case 0xca00: /* xor #imm,R0 */
933 gen_op_xor_imm_rN(B7_0, REG(0));
935 case 0xce00: /* xor.b #imm,@(R0,GBR) */
936 gen_op_movl_rN_T0(REG(0));
937 gen_op_addl_GBR_T0();
939 gen_op_ldub_T0_T0(ctx);
940 gen_op_xor_imm_T0(B7_0);
941 gen_op_stb_T0_T1(ctx);
945 switch (ctx->opcode & 0xf08f) {
946 case 0x408e: /* ldc Rm,Rn_BANK */
947 gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
949 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
950 gen_op_movl_rN_T0(REG(B11_8));
951 gen_op_ldl_T0_T0(ctx);
952 gen_op_movl_T0_rN(ALTREG(B6_4));
953 gen_op_inc4_rN(REG(B11_8));
955 case 0x0082: /* stc Rm_BANK,Rn */
956 gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
958 case 0x4083: /* stc.l Rm_BANK,@-Rn */
959 gen_op_dec4_rN(REG(B11_8));
960 gen_op_movl_rN_T1(REG(B11_8));
961 gen_op_movl_rN_T0(ALTREG(B6_4));
962 gen_op_inc4_rN(REG(B11_8));
963 gen_op_stl_T0_T1(ctx);
964 gen_op_dec4_rN(REG(B11_8));
968 switch (ctx->opcode & 0xf0ff) {
969 case 0x0023: /* braf Rn */
970 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
971 gen_op_braf_T0(ctx->pc + 4);
972 ctx->flags |= DELAY_SLOT;
973 ctx->delayed_pc = (uint32_t) - 1;
975 case 0x0003: /* bsrf Rn */
976 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
977 gen_op_bsrf_T0(ctx->pc + 4);
978 ctx->flags |= DELAY_SLOT;
979 ctx->delayed_pc = (uint32_t) - 1;
981 case 0x4015: /* cmp/pl Rn */
982 gen_op_movl_rN_T0(REG(B11_8));
985 case 0x4011: /* cmp/pz Rn */
986 gen_op_movl_rN_T0(REG(B11_8));
989 case 0x4010: /* dt Rn */
990 gen_op_dt_rN(REG(B11_8));
992 case 0x402b: /* jmp @Rn */
993 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
995 ctx->flags |= DELAY_SLOT;
996 ctx->delayed_pc = (uint32_t) - 1;
998 case 0x400b: /* jsr @Rn */
999 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
1000 gen_op_jsr_T0(ctx->pc + 4);
1001 ctx->flags |= DELAY_SLOT;
1002 ctx->delayed_pc = (uint32_t) - 1;
1004 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1006 gen_op_movl_rN_T0 (REG(B11_8)); \
1007 gen_op_##ldop##_T0_##reg (); \
1011 gen_op_movl_rN_T0 (REG(B11_8)); \
1012 gen_op_ldl_T0_T0 (ctx); \
1013 gen_op_inc4_rN (REG(B11_8)); \
1014 gen_op_##ldop##_T0_##reg (); \
1018 gen_op_##stop##_##reg##_T0 (); \
1019 gen_op_movl_T0_rN (REG(B11_8)); \
1022 gen_op_##stop##_##reg##_T0 (); \
1023 gen_op_dec4_rN (REG(B11_8)); \
1024 gen_op_movl_rN_T1 (REG(B11_8)); \
1025 gen_op_inc4_rN (REG(B11_8)); \
1026 gen_op_stl_T0_T1 (ctx); \
1027 gen_op_dec4_rN (REG(B11_8)); \
1029 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1031 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1032 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1033 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1034 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1035 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1036 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1037 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1038 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1039 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1040 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1042 case 0x00c3: /* movca.l R0,@Rm */
1043 gen_op_movl_rN_T0(REG(0));
1044 gen_op_movl_rN_T1(REG(B11_8));
1045 gen_op_stl_T0_T1(ctx);
1047 case 0x0029: /* movt Rn */
1048 gen_op_movt_rN(REG(B11_8));
1050 case 0x0093: /* ocbi @Rn */
1051 gen_op_movl_rN_T0(REG(B11_8));
1052 gen_op_ldl_T0_T0(ctx);
1054 case 0x00a3: /* ocbp @Rn */
1055 gen_op_movl_rN_T0(REG(B11_8));
1056 gen_op_ldl_T0_T0(ctx);
1058 case 0x00b3: /* ocbwb @Rn */
1059 gen_op_movl_rN_T0(REG(B11_8));
1060 gen_op_ldl_T0_T0(ctx);
1062 case 0x0083: /* pref @Rn */
1064 case 0x4024: /* rotcl Rn */
1065 gen_op_rotcl_Rn(REG(B11_8));
1067 case 0x4025: /* rotcr Rn */
1068 gen_op_rotcr_Rn(REG(B11_8));
1070 case 0x4004: /* rotl Rn */
1071 gen_op_rotl_Rn(REG(B11_8));
1073 case 0x4005: /* rotr Rn */
1074 gen_op_rotr_Rn(REG(B11_8));
1076 case 0x4000: /* shll Rn */
1077 case 0x4020: /* shal Rn */
1078 gen_op_shal_Rn(REG(B11_8));
1080 case 0x4021: /* shar Rn */
1081 gen_op_shar_Rn(REG(B11_8));
1083 case 0x4001: /* shlr Rn */
1084 gen_op_shlr_Rn(REG(B11_8));
1086 case 0x4008: /* shll2 Rn */
1087 gen_op_shll2_Rn(REG(B11_8));
1089 case 0x4018: /* shll8 Rn */
1090 gen_op_shll8_Rn(REG(B11_8));
1092 case 0x4028: /* shll16 Rn */
1093 gen_op_shll16_Rn(REG(B11_8));
1095 case 0x4009: /* shlr2 Rn */
1096 gen_op_shlr2_Rn(REG(B11_8));
1098 case 0x4019: /* shlr8 Rn */
1099 gen_op_shlr8_Rn(REG(B11_8));
1101 case 0x4029: /* shlr16 Rn */
1102 gen_op_shlr16_Rn(REG(B11_8));
1104 case 0x401b: /* tas.b @Rn */
1105 gen_op_movl_rN_T0(REG(B11_8));
1106 gen_op_movl_T0_T1();
1107 gen_op_ldub_T0_T0(ctx);
1108 gen_op_cmp_eq_imm_T0(0);
1109 gen_op_or_imm_T0(0x80);
1110 gen_op_stb_T0_T1(ctx);
1112 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1113 gen_op_movl_fpul_FT0();
1114 gen_op_fmov_FT0_frN(FREG(B11_8));
1116 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1117 gen_op_fmov_frN_FT0(FREG(B11_8));
1118 gen_op_movl_FT0_fpul();
1120 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1121 if (ctx->fpscr & FPSCR_PR) {
1122 if (ctx->opcode & 0x0100)
1123 break; /* illegal instruction */
1125 gen_op_fmov_DT0_drN(DREG(B11_8));
1129 gen_op_fmov_FT0_frN(FREG(B11_8));
1132 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1133 if (ctx->fpscr & FPSCR_PR) {
1134 if (ctx->opcode & 0x0100)
1135 break; /* illegal instruction */
1136 gen_op_fmov_drN_DT0(DREG(B11_8));
1140 gen_op_fmov_frN_FT0(FREG(B11_8));
1144 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1145 gen_op_fneg_frN(FREG(B11_8));
1147 case 0xf05d: /* fabs FRn/DRn */
1148 if (ctx->fpscr & FPSCR_PR) {
1149 if (ctx->opcode & 0x0100)
1150 break; /* illegal instruction */
1151 gen_op_fmov_drN_DT0(DREG(B11_8));
1153 gen_op_fmov_DT0_drN(DREG(B11_8));
1155 gen_op_fmov_frN_FT0(FREG(B11_8));
1157 gen_op_fmov_FT0_frN(FREG(B11_8));
1160 case 0xf06d: /* fsqrt FRn */
1161 if (ctx->fpscr & FPSCR_PR) {
1162 if (ctx->opcode & 0x0100)
1163 break; /* illegal instruction */
1164 gen_op_fmov_drN_DT0(FREG(B11_8));
1166 gen_op_fmov_DT0_drN(FREG(B11_8));
1168 gen_op_fmov_frN_FT0(FREG(B11_8));
1170 gen_op_fmov_FT0_frN(FREG(B11_8));
1173 case 0xf07d: /* fsrra FRn */
1175 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1176 if (!(ctx->fpscr & FPSCR_PR)) {
1177 gen_op_movl_imm_T0(0);
1178 gen_op_fmov_T0_frN(FREG(B11_8));
1182 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1183 if (!(ctx->fpscr & FPSCR_PR)) {
1184 gen_op_movl_imm_T0(0x3f800000);
1185 gen_op_fmov_T0_frN(FREG(B11_8));
1189 case 0xf0ad: /* fcnvsd FPUL,DRn */
1190 gen_op_movl_fpul_FT0();
1191 gen_op_fcnvsd_FT_DT();
1192 gen_op_fmov_DT0_drN(DREG(B11_8));
1194 case 0xf0bd: /* fcnvds DRn,FPUL */
1195 gen_op_fmov_drN_DT0(DREG(B11_8));
1196 gen_op_fcnvds_DT_FT();
1197 gen_op_movl_FT0_fpul();
1201 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1202 ctx->opcode, ctx->pc);
1203 gen_op_raise_illegal_instruction();
1204 ctx->bstate = BS_EXCP;
1207 void decode_opc(DisasContext * ctx)
1209 uint32_t old_flags = ctx->flags;
1213 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1214 if (ctx->flags & DELAY_SLOT_CLEARME) {
1215 gen_op_store_flags(0);
1217 /* go out of the delay slot */
1218 uint32_t new_flags = ctx->flags;
1219 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1220 gen_op_store_flags(new_flags);
1223 ctx->bstate = BS_BRANCH;
1224 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1225 gen_delayed_conditional_jump(ctx);
1226 } else if (old_flags & DELAY_SLOT) {
1232 /* go into a delay slot */
1233 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1234 gen_op_store_flags(ctx->flags);
1238 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1242 target_ulong pc_start;
1243 static uint16_t *gen_opc_end;
1249 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1251 ctx.flags = (uint32_t)tb->flags;
1252 ctx.bstate = BS_NONE;
1254 ctx.fpscr = env->fpscr;
1255 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1256 /* We don't know if the delayed pc came from a dynamic or static branch,
1257 so assume it is a dynamic branch. */
1258 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1260 ctx.singlestep_enabled = env->singlestep_enabled;
1263 if (loglevel & CPU_LOG_TB_CPU) {
1265 "------------------------------------------------\n");
1266 cpu_dump_state(env, logfile, fprintf, 0);
1272 max_insns = tb->cflags & CF_COUNT_MASK;
1274 max_insns = CF_COUNT_MASK;
1276 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1277 if (env->nb_breakpoints > 0) {
1278 for (i = 0; i < env->nb_breakpoints; i++) {
1279 if (ctx.pc == env->breakpoints[i]) {
1280 /* We have hit a breakpoint - make sure PC is up-to-date */
1281 gen_op_movl_imm_PC(ctx.pc);
1283 ctx.bstate = BS_EXCP;
1289 i = gen_opc_ptr - gen_opc_buf;
1293 gen_opc_instr_start[ii++] = 0;
1295 gen_opc_pc[ii] = ctx.pc;
1296 gen_opc_hflags[ii] = ctx.flags;
1297 gen_opc_instr_start[ii] = 1;
1298 gen_opc_icount[ii] = num_insns;
1300 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1303 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1306 ctx.opcode = lduw_code(ctx.pc);
1310 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1312 if (env->singlestep_enabled)
1314 if (num_insns >= max_insns)
1316 #ifdef SH4_SINGLE_STEP
1320 if (tb->cflags & CF_LAST_IO)
1322 if (env->singlestep_enabled) {
1325 switch (ctx.bstate) {
1327 /* gen_op_interrupt_restart(); */
1331 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1333 gen_goto_tb(&ctx, 0, ctx.pc);
1336 /* gen_op_interrupt_restart(); */
1345 gen_icount_end(tb, num_insns);
1346 *gen_opc_ptr = INDEX_op_end;
1348 i = gen_opc_ptr - gen_opc_buf;
1351 gen_opc_instr_start[ii++] = 0;
1353 tb->size = ctx.pc - pc_start;
1354 tb->icount = num_insns;
1358 #ifdef SH4_DEBUG_DISAS
1359 if (loglevel & CPU_LOG_TB_IN_ASM)
1360 fprintf(logfile, "\n");
1362 if (loglevel & CPU_LOG_TB_IN_ASM) {
1363 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1364 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1365 fprintf(logfile, "\n");
1370 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1372 gen_intermediate_code_internal(env, tb, 0);
1375 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1377 gen_intermediate_code_internal(env, tb, 1);
1380 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1381 unsigned long searched_pc, int pc_pos, void *puc)
1383 env->pc = gen_opc_pc[pc_pos];
1384 env->flags = gen_opc_hflags[pc_pos];