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
36 #include "qemu-common.h"
38 typedef struct DisasContext {
39 struct TranslationBlock *tb;
48 int singlestep_enabled;
52 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
55 BS_STOP = 1, /* We want to stop translation for any reason */
56 BS_BRANCH = 2, /* We reached a branch condition */
57 BS_EXCP = 3, /* We reached an exception condition */
60 /* global register indexes */
62 static TCGv cpu_gregs[24];
63 static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65 static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
67 /* internal register indexes */
68 static TCGv cpu_flags, cpu_delayed_pc;
70 #include "gen-icount.h"
72 static void sh4_translate_init(void)
75 static int done_init = 0;
76 static const char * const gregnames[24] = {
77 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
78 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
79 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
80 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
81 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
87 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
89 for (i = 0; i < 24; i++)
90 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
91 offsetof(CPUState, gregs[i]),
94 cpu_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
95 offsetof(CPUState, pc), "PC");
96 cpu_sr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
97 offsetof(CPUState, sr), "SR");
98 cpu_ssr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
99 offsetof(CPUState, ssr), "SSR");
100 cpu_spc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
101 offsetof(CPUState, spc), "SPC");
102 cpu_gbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
103 offsetof(CPUState, gbr), "GBR");
104 cpu_vbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
105 offsetof(CPUState, vbr), "VBR");
106 cpu_sgr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
107 offsetof(CPUState, sgr), "SGR");
108 cpu_dbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
109 offsetof(CPUState, dbr), "DBR");
110 cpu_mach = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
111 offsetof(CPUState, mach), "MACH");
112 cpu_macl = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
113 offsetof(CPUState, macl), "MACL");
114 cpu_pr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
115 offsetof(CPUState, pr), "PR");
116 cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
117 offsetof(CPUState, fpscr), "FPSCR");
118 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
119 offsetof(CPUState, fpul), "FPUL");
121 cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
122 offsetof(CPUState, flags), "_flags_");
123 cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
124 offsetof(CPUState, delayed_pc),
127 /* register helpers */
129 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
135 void cpu_dump_state(CPUState * env, FILE * f,
136 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
140 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
141 env->pc, env->sr, env->pr, env->fpscr);
142 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
143 env->spc, env->ssr, env->gbr, env->vbr);
144 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
145 env->sgr, env->dbr, env->delayed_pc, env->fpul);
146 for (i = 0; i < 24; i += 4) {
147 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
148 i, env->gregs[i], i + 1, env->gregs[i + 1],
149 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
151 if (env->flags & DELAY_SLOT) {
152 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
154 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
155 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
160 void cpu_sh4_reset(CPUSH4State * env)
162 #if defined(CONFIG_USER_ONLY)
163 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
165 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
168 env->pc = 0xA0000000;
169 #if defined(CONFIG_USER_ONLY)
170 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
171 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
173 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
174 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
180 const unsigned char *name;
187 static sh4_def_t sh4_defs[] = {
190 .id = SH_CPU_SH7750R,
196 .id = SH_CPU_SH7751R,
199 .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */
203 static const sh4_def_t *cpu_sh4_find_by_name(const unsigned char *name)
207 if (strcasecmp(name, "any") == 0)
210 for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
211 if (strcasecmp(name, sh4_defs[i].name) == 0)
217 void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
221 for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
222 (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
225 static int cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
233 CPUSH4State *cpu_sh4_init(const char *cpu_model)
236 const sh4_def_t *def;
238 def = cpu_sh4_find_by_name(cpu_model);
241 env = qemu_mallocz(sizeof(CPUSH4State));
245 sh4_translate_init();
246 env->cpu_model_str = cpu_model;
248 cpu_sh4_register(env, def);
253 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
255 TranslationBlock *tb;
258 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
259 !ctx->singlestep_enabled) {
260 /* Use a direct jump if in same page and singlestep not enabled */
262 tcg_gen_movi_i32(cpu_pc, dest);
263 tcg_gen_exit_tb((long) tb + n);
265 tcg_gen_movi_i32(cpu_pc, dest);
266 if (ctx->singlestep_enabled)
267 tcg_gen_helper_0_0(helper_debug);
272 static void gen_jump(DisasContext * ctx)
274 if (ctx->delayed_pc == (uint32_t) - 1) {
275 /* Target is not statically known, it comes necessarily from a
276 delayed jump as immediate jump are conditinal jumps */
277 tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
278 if (ctx->singlestep_enabled)
279 tcg_gen_helper_0_0(helper_debug);
282 gen_goto_tb(ctx, 0, ctx->delayed_pc);
286 static inline void gen_branch_slot(uint32_t delayed_pc, int t)
289 int label = gen_new_label();
290 tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
291 sr = tcg_temp_new(TCG_TYPE_I32);
292 tcg_gen_andi_i32(sr, cpu_sr, SR_T);
293 tcg_gen_brcondi_i32(TCG_COND_NE, sr, t ? SR_T : 0, label);
294 tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
295 gen_set_label(label);
298 /* Immediate conditional jump (bt or bf) */
299 static void gen_conditional_jump(DisasContext * ctx,
300 target_ulong ift, target_ulong ifnott)
305 l1 = gen_new_label();
306 sr = tcg_temp_new(TCG_TYPE_I32);
307 tcg_gen_andi_i32(sr, cpu_sr, SR_T);
308 tcg_gen_brcondi_i32(TCG_COND_EQ, sr, SR_T, l1);
309 gen_goto_tb(ctx, 0, ifnott);
311 gen_goto_tb(ctx, 1, ift);
314 /* Delayed conditional jump (bt or bf) */
315 static void gen_delayed_conditional_jump(DisasContext * ctx)
320 l1 = gen_new_label();
321 ds = tcg_temp_new(TCG_TYPE_I32);
322 tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
323 tcg_gen_brcondi_i32(TCG_COND_EQ, ds, DELAY_SLOT_TRUE, l1);
324 gen_goto_tb(ctx, 1, ctx->pc + 2);
326 tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
330 static inline void gen_set_t(void)
332 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
335 static inline void gen_clr_t(void)
337 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
340 static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
342 int label1 = gen_new_label();
343 int label2 = gen_new_label();
344 tcg_gen_brcond_i32(cond, t1, t0, label1);
347 gen_set_label(label1);
349 gen_set_label(label2);
352 static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
354 int label1 = gen_new_label();
355 int label2 = gen_new_label();
356 tcg_gen_brcondi_i32(cond, t0, imm, label1);
359 gen_set_label(label1);
361 gen_set_label(label2);
364 static inline void gen_store_flags(uint32_t flags)
366 tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
367 tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
370 static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
372 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
377 tcg_gen_andi_i32(tmp, t1, (1 << p1));
378 tcg_gen_andi_i32(t0, t0, ~(1 << p0));
380 tcg_gen_shri_i32(tmp, tmp, p1 - p0);
382 tcg_gen_shli_i32(tmp, tmp, p0 - p1);
383 tcg_gen_or_i32(t0, t0, tmp);
389 static inline void gen_load_fpr32(TCGv t, int reg)
391 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
394 static inline void gen_load_fpr64(TCGv t, int reg)
396 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
397 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
399 tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
400 tcg_gen_extu_i32_i64(t, tmp1);
401 tcg_gen_shli_i64(t, t, 32);
402 tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1]));
403 tcg_gen_extu_i32_i64(tmp2, tmp1);
405 tcg_gen_or_i64(t, t, tmp2);
409 static inline void gen_store_fpr32(TCGv t, int reg)
411 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
414 static inline void gen_store_fpr64 (TCGv t, int reg)
416 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
418 tcg_gen_trunc_i64_i32(tmp, t);
419 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg + 1]));
420 tcg_gen_shri_i64(t, t, 32);
421 tcg_gen_trunc_i64_i32(tmp, t);
422 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg]));
426 #define B3_0 (ctx->opcode & 0xf)
427 #define B6_4 ((ctx->opcode >> 4) & 0x7)
428 #define B7_4 ((ctx->opcode >> 4) & 0xf)
429 #define B7_0 (ctx->opcode & 0xff)
430 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
431 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
432 (ctx->opcode & 0xfff))
433 #define B11_8 ((ctx->opcode >> 8) & 0xf)
434 #define B15_12 ((ctx->opcode >> 12) & 0xf)
436 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
437 (cpu_gregs[x + 16]) : (cpu_gregs[x]))
439 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
440 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
442 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
443 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
444 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
445 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
447 #define CHECK_NOT_DELAY_SLOT \
448 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
449 {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
452 void _decode_opc(DisasContext * ctx)
455 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
457 switch (ctx->opcode) {
458 case 0x0019: /* div0u */
459 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
461 case 0x000b: /* rts */
463 tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
464 ctx->flags |= DELAY_SLOT;
465 ctx->delayed_pc = (uint32_t) - 1;
467 case 0x0028: /* clrmac */
468 tcg_gen_movi_i32(cpu_mach, 0);
469 tcg_gen_movi_i32(cpu_macl, 0);
471 case 0x0048: /* clrs */
472 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
474 case 0x0008: /* clrt */
477 case 0x0038: /* ldtlb */
478 #if defined(CONFIG_USER_ONLY)
479 assert(0); /* XXXXX */
481 tcg_gen_helper_0_0(helper_ldtlb);
484 case 0x002b: /* rte */
486 tcg_gen_mov_i32(cpu_sr, cpu_ssr);
487 tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
488 ctx->flags |= DELAY_SLOT;
489 ctx->delayed_pc = (uint32_t) - 1;
491 case 0x0058: /* sets */
492 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
494 case 0x0018: /* sett */
497 case 0xfbfd: /* frchg */
498 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
499 ctx->bstate = BS_STOP;
501 case 0xf3fd: /* fschg */
502 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
503 ctx->bstate = BS_STOP;
505 case 0x0009: /* nop */
507 case 0x001b: /* sleep */
509 tcg_gen_helper_0_1(helper_sleep, tcg_const_i32(ctx->pc + 2));
511 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
512 ctx->bstate = BS_EXCP;
517 switch (ctx->opcode & 0xf000) {
518 case 0x1000: /* mov.l Rm,@(disp,Rn) */
520 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
521 tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
522 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
526 case 0x5000: /* mov.l @(disp,Rm),Rn */
528 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
529 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
530 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
534 case 0xe000: /* mov #imm,Rn */
535 tcg_gen_movi_i32(REG(B11_8), B7_0s);
537 case 0x9000: /* mov.w @(disp,PC),Rn */
539 TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
540 tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
544 case 0xd000: /* mov.l @(disp,PC),Rn */
546 TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
547 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
551 case 0x7000: /* add #imm,Rn */
552 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
554 case 0xa000: /* bra disp */
556 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
557 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
558 ctx->flags |= DELAY_SLOT;
560 case 0xb000: /* bsr disp */
562 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
563 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
564 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
565 ctx->flags |= DELAY_SLOT;
569 switch (ctx->opcode & 0xf00f) {
570 case 0x6003: /* mov Rm,Rn */
571 tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
573 case 0x2000: /* mov.b Rm,@Rn */
574 tcg_gen_qemu_st8(REG(B7_4), REG(B11_8), ctx->memidx);
576 case 0x2001: /* mov.w Rm,@Rn */
577 tcg_gen_qemu_st16(REG(B7_4), REG(B11_8), ctx->memidx);
579 case 0x2002: /* mov.l Rm,@Rn */
580 tcg_gen_qemu_st32(REG(B7_4), REG(B11_8), ctx->memidx);
582 case 0x6000: /* mov.b @Rm,Rn */
583 tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
585 case 0x6001: /* mov.w @Rm,Rn */
586 tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
588 case 0x6002: /* mov.l @Rm,Rn */
589 tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
591 case 0x2004: /* mov.b Rm,@-Rn */
593 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
594 tcg_gen_subi_i32(addr, REG(B11_8), 1);
595 tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx); /* might cause re-execution */
596 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1); /* modify register status */
600 case 0x2005: /* mov.w Rm,@-Rn */
602 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
603 tcg_gen_subi_i32(addr, REG(B11_8), 2);
604 tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
605 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 2);
609 case 0x2006: /* mov.l Rm,@-Rn */
611 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
612 tcg_gen_subi_i32(addr, REG(B11_8), 4);
613 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
614 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
617 case 0x6004: /* mov.b @Rm+,Rn */
618 tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
620 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
622 case 0x6005: /* mov.w @Rm+,Rn */
623 tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
625 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
627 case 0x6006: /* mov.l @Rm+,Rn */
628 tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
630 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
632 case 0x0004: /* mov.b Rm,@(R0,Rn) */
634 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
635 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
636 tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);
640 case 0x0005: /* mov.w Rm,@(R0,Rn) */
642 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
643 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
644 tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
648 case 0x0006: /* mov.l Rm,@(R0,Rn) */
650 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
651 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
652 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
656 case 0x000c: /* mov.b @(R0,Rm),Rn */
658 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
659 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
660 tcg_gen_qemu_ld8s(REG(B11_8), addr, ctx->memidx);
664 case 0x000d: /* mov.w @(R0,Rm),Rn */
666 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
667 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
668 tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
672 case 0x000e: /* mov.l @(R0,Rm),Rn */
674 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
675 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
676 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
680 case 0x6008: /* swap.b Rm,Rn */
683 high = tcg_temp_new(TCG_TYPE_I32);
684 tcg_gen_ext8u_i32(high, REG(B7_4));
685 tcg_gen_shli_i32(high, high, 8);
686 low = tcg_temp_new(TCG_TYPE_I32);
687 tcg_gen_shri_i32(low, REG(B7_4), 8);
688 tcg_gen_ext8u_i32(low, low);
689 tcg_gen_or_i32(REG(B11_8), high, low);
694 case 0x6009: /* swap.w Rm,Rn */
697 high = tcg_temp_new(TCG_TYPE_I32);
698 tcg_gen_ext16u_i32(high, REG(B7_4));
699 tcg_gen_shli_i32(high, high, 16);
700 low = tcg_temp_new(TCG_TYPE_I32);
701 tcg_gen_shri_i32(low, REG(B7_4), 16);
702 tcg_gen_ext16u_i32(low, low);
703 tcg_gen_or_i32(REG(B11_8), high, low);
708 case 0x200d: /* xtrct Rm,Rn */
711 high = tcg_temp_new(TCG_TYPE_I32);
712 tcg_gen_ext16u_i32(high, REG(B7_4));
713 tcg_gen_shli_i32(high, high, 16);
714 low = tcg_temp_new(TCG_TYPE_I32);
715 tcg_gen_shri_i32(low, REG(B11_8), 16);
716 tcg_gen_ext16u_i32(low, low);
717 tcg_gen_or_i32(REG(B11_8), high, low);
722 case 0x300c: /* add Rm,Rn */
723 tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
725 case 0x300e: /* addc Rm,Rn */
726 tcg_gen_helper_1_2(helper_addc, REG(B11_8), REG(B7_4), REG(B11_8));
728 case 0x300f: /* addv Rm,Rn */
729 tcg_gen_helper_1_2(helper_addv, REG(B11_8), REG(B7_4), REG(B11_8));
731 case 0x2009: /* and Rm,Rn */
732 tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
734 case 0x3000: /* cmp/eq Rm,Rn */
735 gen_cmp(TCG_COND_EQ, REG(B7_4), REG(B11_8));
737 case 0x3003: /* cmp/ge Rm,Rn */
738 gen_cmp(TCG_COND_GE, REG(B7_4), REG(B11_8));
740 case 0x3007: /* cmp/gt Rm,Rn */
741 gen_cmp(TCG_COND_GT, REG(B7_4), REG(B11_8));
743 case 0x3006: /* cmp/hi Rm,Rn */
744 gen_cmp(TCG_COND_GTU, REG(B7_4), REG(B11_8));
746 case 0x3002: /* cmp/hs Rm,Rn */
747 gen_cmp(TCG_COND_GEU, REG(B7_4), REG(B11_8));
749 case 0x200c: /* cmp/str Rm,Rn */
751 int label1 = gen_new_label();
752 int label2 = gen_new_label();
753 TCGv cmp1 = tcg_temp_local_new(TCG_TYPE_I32);
754 TCGv cmp2 = tcg_temp_local_new(TCG_TYPE_I32);
755 tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8));
756 tcg_gen_andi_i32(cmp2, cmp1, 0xff000000);
757 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
758 tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000);
759 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
760 tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00);
761 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
762 tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff);
763 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
764 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
766 gen_set_label(label1);
767 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
768 gen_set_label(label2);
773 case 0x2007: /* div0s Rm,Rn */
775 gen_copy_bit_i32(cpu_sr, 8, REG(B11_8), 31); /* SR_Q */
776 gen_copy_bit_i32(cpu_sr, 9, REG(B7_4), 31); /* SR_M */
777 TCGv val = tcg_temp_new(TCG_TYPE_I32);
778 tcg_gen_xor_i32(val, REG(B7_4), REG(B11_8));
779 gen_copy_bit_i32(cpu_sr, 0, val, 31); /* SR_T */
783 case 0x3004: /* div1 Rm,Rn */
784 tcg_gen_helper_1_2(helper_div1, REG(B11_8), REG(B7_4), REG(B11_8));
786 case 0x300d: /* dmuls.l Rm,Rn */
788 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
789 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
791 tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
792 tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
793 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
794 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
795 tcg_gen_shri_i64(tmp1, tmp1, 32);
796 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
802 case 0x3005: /* dmulu.l Rm,Rn */
804 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
805 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
807 tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
808 tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
809 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
810 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
811 tcg_gen_shri_i64(tmp1, tmp1, 32);
812 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
818 case 0x600e: /* exts.b Rm,Rn */
819 tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
821 case 0x600f: /* exts.w Rm,Rn */
822 tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
824 case 0x600c: /* extu.b Rm,Rn */
825 tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
827 case 0x600d: /* extu.w Rm,Rn */
828 tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
830 case 0x000f: /* mac.l @Rm+,@Rn+ */
833 arg0 = tcg_temp_new(TCG_TYPE_I32);
834 tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
835 arg1 = tcg_temp_new(TCG_TYPE_I32);
836 tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
837 tcg_gen_helper_0_2(helper_macl, arg0, arg1);
840 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
841 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
844 case 0x400f: /* mac.w @Rm+,@Rn+ */
847 arg0 = tcg_temp_new(TCG_TYPE_I32);
848 tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
849 arg1 = tcg_temp_new(TCG_TYPE_I32);
850 tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
851 tcg_gen_helper_0_2(helper_macw, arg0, arg1);
854 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
855 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
858 case 0x0007: /* mul.l Rm,Rn */
859 tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
861 case 0x200f: /* muls.w Rm,Rn */
864 arg0 = tcg_temp_new(TCG_TYPE_I32);
865 tcg_gen_ext16s_i32(arg0, REG(B7_4));
866 arg1 = tcg_temp_new(TCG_TYPE_I32);
867 tcg_gen_ext16s_i32(arg1, REG(B11_8));
868 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
873 case 0x200e: /* mulu.w Rm,Rn */
876 arg0 = tcg_temp_new(TCG_TYPE_I32);
877 tcg_gen_ext16u_i32(arg0, REG(B7_4));
878 arg1 = tcg_temp_new(TCG_TYPE_I32);
879 tcg_gen_ext16u_i32(arg1, REG(B11_8));
880 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
885 case 0x600b: /* neg Rm,Rn */
886 tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
888 case 0x600a: /* negc Rm,Rn */
889 tcg_gen_helper_1_1(helper_negc, REG(B11_8), REG(B7_4));
891 case 0x6007: /* not Rm,Rn */
892 tcg_gen_not_i32(REG(B11_8), REG(B7_4));
894 case 0x200b: /* or Rm,Rn */
895 tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
897 case 0x400c: /* shad Rm,Rn */
899 int label1 = gen_new_label();
900 int label2 = gen_new_label();
901 int label3 = gen_new_label();
902 int label4 = gen_new_label();
903 TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
904 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
905 /* Rm positive, shift to the left */
906 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
907 tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
909 /* Rm negative, shift to the right */
910 gen_set_label(label1);
911 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
912 tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
913 tcg_gen_not_i32(shift, REG(B7_4));
914 tcg_gen_andi_i32(shift, shift, 0x1f);
915 tcg_gen_addi_i32(shift, shift, 1);
916 tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift);
919 gen_set_label(label2);
920 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);
921 tcg_gen_movi_i32(REG(B11_8), 0);
923 gen_set_label(label3);
924 tcg_gen_movi_i32(REG(B11_8), 0xffffffff);
925 gen_set_label(label4);
926 tcg_temp_free(shift);
929 case 0x400d: /* shld Rm,Rn */
931 int label1 = gen_new_label();
932 int label2 = gen_new_label();
933 int label3 = gen_new_label();
934 TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
935 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
936 /* Rm positive, shift to the left */
937 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
938 tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
940 /* Rm negative, shift to the right */
941 gen_set_label(label1);
942 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
943 tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
944 tcg_gen_not_i32(shift, REG(B7_4));
945 tcg_gen_andi_i32(shift, shift, 0x1f);
946 tcg_gen_addi_i32(shift, shift, 1);
947 tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift);
950 gen_set_label(label2);
951 tcg_gen_movi_i32(REG(B11_8), 0);
952 gen_set_label(label3);
953 tcg_temp_free(shift);
956 case 0x3008: /* sub Rm,Rn */
957 tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
959 case 0x300a: /* subc Rm,Rn */
960 tcg_gen_helper_1_2(helper_subc, REG(B11_8), REG(B7_4), REG(B11_8));
962 case 0x300b: /* subv Rm,Rn */
963 tcg_gen_helper_1_2(helper_subv, REG(B11_8), REG(B7_4), REG(B11_8));
965 case 0x2008: /* tst Rm,Rn */
967 TCGv val = tcg_temp_new(TCG_TYPE_I32);
968 tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
969 gen_cmp_imm(TCG_COND_EQ, val, 0);
973 case 0x200a: /* xor Rm,Rn */
974 tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
976 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
977 if (ctx->fpscr & FPSCR_SZ) {
978 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
979 gen_load_fpr64(fp, XREG(B7_4));
980 gen_store_fpr64(fp, XREG(B11_8));
983 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
984 gen_load_fpr32(fp, FREG(B7_4));
985 gen_store_fpr32(fp, FREG(B11_8));
989 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
990 if (ctx->fpscr & FPSCR_SZ) {
991 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
992 gen_load_fpr64(fp, XREG(B7_4));
993 tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx);
996 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
997 gen_load_fpr32(fp, FREG(B7_4));
998 tcg_gen_qemu_st32(fp, REG(B11_8), ctx->memidx);
1002 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
1003 if (ctx->fpscr & FPSCR_SZ) {
1004 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1005 tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
1006 gen_store_fpr64(fp, XREG(B11_8));
1009 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1010 tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
1011 gen_store_fpr32(fp, FREG(B11_8));
1015 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
1016 if (ctx->fpscr & FPSCR_SZ) {
1017 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1018 tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
1019 gen_store_fpr64(fp, XREG(B11_8));
1021 tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8);
1023 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1024 tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
1025 gen_store_fpr32(fp, FREG(B11_8));
1027 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
1030 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
1031 if (ctx->fpscr & FPSCR_SZ) {
1033 addr = tcg_temp_new(TCG_TYPE_I32);
1034 tcg_gen_subi_i32(addr, REG(B11_8), 8);
1035 fp = tcg_temp_new(TCG_TYPE_I64);
1036 gen_load_fpr64(fp, XREG(B7_4));
1037 tcg_gen_qemu_st64(fp, addr, ctx->memidx);
1039 tcg_temp_free(addr);
1040 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
1043 addr = tcg_temp_new(TCG_TYPE_I32);
1044 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1045 fp = tcg_temp_new(TCG_TYPE_I32);
1046 gen_load_fpr32(fp, FREG(B7_4));
1047 tcg_gen_qemu_st32(fp, addr, ctx->memidx);
1049 tcg_temp_free(addr);
1050 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1053 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1055 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1056 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1057 if (ctx->fpscr & FPSCR_SZ) {
1058 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1059 tcg_gen_qemu_ld64(fp, addr, ctx->memidx);
1060 gen_store_fpr64(fp, XREG(B11_8));
1063 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1064 tcg_gen_qemu_ld32u(fp, addr, ctx->memidx);
1065 gen_store_fpr32(fp, FREG(B11_8));
1068 tcg_temp_free(addr);
1071 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1073 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1074 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1075 if (ctx->fpscr & FPSCR_SZ) {
1076 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1077 gen_load_fpr64(fp, XREG(B7_4));
1078 tcg_gen_qemu_st64(fp, addr, ctx->memidx);
1081 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1082 gen_load_fpr32(fp, FREG(B7_4));
1083 tcg_gen_qemu_st32(fp, addr, ctx->memidx);
1086 tcg_temp_free(addr);
1089 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1090 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1091 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1092 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1093 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1094 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1098 if (ctx->fpscr & FPSCR_PR) {
1099 if (ctx->opcode & 0x0110)
1100 break; /* illegal instruction */
1101 fp0 = tcg_temp_new(TCG_TYPE_I64);
1102 fp1 = tcg_temp_new(TCG_TYPE_I64);
1103 gen_load_fpr64(fp0, DREG(B11_8));
1104 gen_load_fpr64(fp1, DREG(B7_4));
1107 fp0 = tcg_temp_new(TCG_TYPE_I32);
1108 fp1 = tcg_temp_new(TCG_TYPE_I32);
1109 gen_load_fpr32(fp0, FREG(B11_8));
1110 gen_load_fpr32(fp1, FREG(B7_4));
1113 switch (ctx->opcode & 0xf00f) {
1114 case 0xf000: /* fadd Rm,Rn */
1115 if (ctx->fpscr & FPSCR_PR)
1116 tcg_gen_helper_1_2(helper_fadd_DT, fp0, fp0, fp1);
1118 tcg_gen_helper_1_2(helper_fadd_FT, fp0, fp0, fp1);
1120 case 0xf001: /* fsub Rm,Rn */
1121 if (ctx->fpscr & FPSCR_PR)
1122 tcg_gen_helper_1_2(helper_fsub_DT, fp0, fp0, fp1);
1124 tcg_gen_helper_1_2(helper_fsub_FT, fp0, fp0, fp1);
1126 case 0xf002: /* fmul Rm,Rn */
1127 if (ctx->fpscr & FPSCR_PR)
1128 tcg_gen_helper_1_2(helper_fmul_DT, fp0, fp0, fp1);
1130 tcg_gen_helper_1_2(helper_fmul_FT, fp0, fp0, fp1);
1132 case 0xf003: /* fdiv Rm,Rn */
1133 if (ctx->fpscr & FPSCR_PR)
1134 tcg_gen_helper_1_2(helper_fdiv_DT, fp0, fp0, fp1);
1136 tcg_gen_helper_1_2(helper_fdiv_FT, fp0, fp0, fp1);
1138 case 0xf004: /* fcmp/eq Rm,Rn */
1139 if (ctx->fpscr & FPSCR_PR)
1140 tcg_gen_helper_0_2(helper_fcmp_eq_DT, fp0, fp1);
1142 tcg_gen_helper_0_2(helper_fcmp_eq_FT, fp0, fp1);
1144 case 0xf005: /* fcmp/gt Rm,Rn */
1145 if (ctx->fpscr & FPSCR_PR)
1146 tcg_gen_helper_0_2(helper_fcmp_gt_DT, fp0, fp1);
1148 tcg_gen_helper_0_2(helper_fcmp_gt_FT, fp0, fp1);
1152 if (ctx->fpscr & FPSCR_PR) {
1153 gen_store_fpr64(fp0, DREG(B11_8));
1156 gen_store_fpr32(fp0, FREG(B11_8));
1164 switch (ctx->opcode & 0xff00) {
1165 case 0xc900: /* and #imm,R0 */
1166 tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1168 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1171 addr = tcg_temp_new(TCG_TYPE_I32);
1172 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1173 val = tcg_temp_new(TCG_TYPE_I32);
1174 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1175 tcg_gen_andi_i32(val, val, B7_0);
1176 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1178 tcg_temp_free(addr);
1181 case 0x8b00: /* bf label */
1182 CHECK_NOT_DELAY_SLOT
1183 gen_conditional_jump(ctx, ctx->pc + 2,
1184 ctx->pc + 4 + B7_0s * 2);
1185 ctx->bstate = BS_BRANCH;
1187 case 0x8f00: /* bf/s label */
1188 CHECK_NOT_DELAY_SLOT
1189 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1190 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1192 case 0x8900: /* bt label */
1193 CHECK_NOT_DELAY_SLOT
1194 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1196 ctx->bstate = BS_BRANCH;
1198 case 0x8d00: /* bt/s label */
1199 CHECK_NOT_DELAY_SLOT
1200 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1201 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1203 case 0x8800: /* cmp/eq #imm,R0 */
1204 gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);
1206 case 0xc400: /* mov.b @(disp,GBR),R0 */
1208 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1209 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1210 tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1211 tcg_temp_free(addr);
1214 case 0xc500: /* mov.w @(disp,GBR),R0 */
1216 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1217 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1218 tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1219 tcg_temp_free(addr);
1222 case 0xc600: /* mov.l @(disp,GBR),R0 */
1224 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1225 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1226 tcg_gen_qemu_ld32s(REG(0), addr, ctx->memidx);
1227 tcg_temp_free(addr);
1230 case 0xc000: /* mov.b R0,@(disp,GBR) */
1232 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1233 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1234 tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1235 tcg_temp_free(addr);
1238 case 0xc100: /* mov.w R0,@(disp,GBR) */
1240 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1241 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1242 tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1243 tcg_temp_free(addr);
1246 case 0xc200: /* mov.l R0,@(disp,GBR) */
1248 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1249 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1250 tcg_gen_qemu_st32(REG(0), addr, ctx->memidx);
1251 tcg_temp_free(addr);
1254 case 0x8000: /* mov.b R0,@(disp,Rn) */
1256 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1257 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1258 tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1259 tcg_temp_free(addr);
1262 case 0x8100: /* mov.w R0,@(disp,Rn) */
1264 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1265 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1266 tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1267 tcg_temp_free(addr);
1270 case 0x8400: /* mov.b @(disp,Rn),R0 */
1272 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1273 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1274 tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1275 tcg_temp_free(addr);
1278 case 0x8500: /* mov.w @(disp,Rn),R0 */
1280 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1281 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1282 tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1283 tcg_temp_free(addr);
1286 case 0xc700: /* mova @(disp,PC),R0 */
1287 tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1289 case 0xcb00: /* or #imm,R0 */
1290 tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1292 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1295 addr = tcg_temp_new(TCG_TYPE_I32);
1296 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1297 val = tcg_temp_new(TCG_TYPE_I32);
1298 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1299 tcg_gen_ori_i32(val, val, B7_0);
1300 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1302 tcg_temp_free(addr);
1305 case 0xc300: /* trapa #imm */
1308 CHECK_NOT_DELAY_SLOT
1309 tcg_gen_movi_i32(cpu_pc, ctx->pc);
1310 imm = tcg_const_i32(B7_0);
1311 tcg_gen_helper_0_1(helper_trapa, imm);
1313 ctx->bstate = BS_BRANCH;
1316 case 0xc800: /* tst #imm,R0 */
1318 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1319 tcg_gen_andi_i32(val, REG(0), B7_0);
1320 gen_cmp_imm(TCG_COND_EQ, val, 0);
1324 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1326 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1327 tcg_gen_add_i32(val, REG(0), cpu_gbr);
1328 tcg_gen_qemu_ld8u(val, val, ctx->memidx);
1329 tcg_gen_andi_i32(val, val, B7_0);
1330 gen_cmp_imm(TCG_COND_EQ, val, 0);
1334 case 0xca00: /* xor #imm,R0 */
1335 tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1337 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1340 addr = tcg_temp_new(TCG_TYPE_I32);
1341 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1342 val = tcg_temp_new(TCG_TYPE_I32);
1343 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1344 tcg_gen_xori_i32(val, val, B7_0);
1345 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1347 tcg_temp_free(addr);
1352 switch (ctx->opcode & 0xf08f) {
1353 case 0x408e: /* ldc Rm,Rn_BANK */
1354 tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1356 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1357 tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);
1358 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1360 case 0x0082: /* stc Rm_BANK,Rn */
1361 tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1363 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1365 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1366 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1367 tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);
1368 tcg_temp_free(addr);
1369 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1374 switch (ctx->opcode & 0xf0ff) {
1375 case 0x0023: /* braf Rn */
1376 CHECK_NOT_DELAY_SLOT
1377 tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1378 ctx->flags |= DELAY_SLOT;
1379 ctx->delayed_pc = (uint32_t) - 1;
1381 case 0x0003: /* bsrf Rn */
1382 CHECK_NOT_DELAY_SLOT
1383 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1384 tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1385 ctx->flags |= DELAY_SLOT;
1386 ctx->delayed_pc = (uint32_t) - 1;
1388 case 0x4015: /* cmp/pl Rn */
1389 gen_cmp_imm(TCG_COND_GT, REG(B11_8), 0);
1391 case 0x4011: /* cmp/pz Rn */
1392 gen_cmp_imm(TCG_COND_GE, REG(B11_8), 0);
1394 case 0x4010: /* dt Rn */
1395 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1396 gen_cmp_imm(TCG_COND_EQ, REG(B11_8), 0);
1398 case 0x402b: /* jmp @Rn */
1399 CHECK_NOT_DELAY_SLOT
1400 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1401 ctx->flags |= DELAY_SLOT;
1402 ctx->delayed_pc = (uint32_t) - 1;
1404 case 0x400b: /* jsr @Rn */
1405 CHECK_NOT_DELAY_SLOT
1406 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1407 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1408 ctx->flags |= DELAY_SLOT;
1409 ctx->delayed_pc = (uint32_t) - 1;
1411 case 0x400e: /* lds Rm,SR */
1412 tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3);
1413 ctx->bstate = BS_STOP;
1415 case 0x4007: /* lds.l @Rm+,SR */
1417 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1418 tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx);
1419 tcg_gen_andi_i32(cpu_sr, val, 0x700083f3);
1421 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1422 ctx->bstate = BS_STOP;
1425 case 0x0002: /* sts SR,Rn */
1426 tcg_gen_mov_i32(REG(B11_8), cpu_sr);
1428 case 0x4003: /* sts SR,@-Rn */
1430 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1431 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1432 tcg_gen_qemu_st32(cpu_sr, addr, ctx->memidx);
1433 tcg_temp_free(addr);
1434 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1437 #define LDST(reg,ldnum,ldpnum,stnum,stpnum) \
1439 tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \
1442 tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx); \
1443 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \
1446 tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \
1450 TCGv addr = tcg_temp_new(TCG_TYPE_I32); \
1451 tcg_gen_subi_i32(addr, REG(B11_8), 4); \
1452 tcg_gen_qemu_st32 (cpu_##reg, addr, ctx->memidx); \
1453 tcg_temp_free(addr); \
1454 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4); \
1457 LDST(gbr, 0x401e, 0x4017, 0x0012, 0x4013)
1458 LDST(vbr, 0x402e, 0x4027, 0x0022, 0x4023)
1459 LDST(ssr, 0x403e, 0x4037, 0x0032, 0x4033)
1460 LDST(spc, 0x404e, 0x4047, 0x0042, 0x4043)
1461 LDST(dbr, 0x40fa, 0x40f6, 0x00fa, 0x40f2)
1462 LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002)
1463 LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012)
1464 LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022)
1465 LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052)
1466 case 0x406a: /* lds Rm,FPSCR */
1467 tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8));
1468 ctx->bstate = BS_STOP;
1470 case 0x4066: /* lds.l @Rm+,FPSCR */
1472 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1473 tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
1474 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1475 tcg_gen_helper_0_1(helper_ld_fpscr, addr);
1476 tcg_temp_free(addr);
1477 ctx->bstate = BS_STOP;
1480 case 0x006a: /* sts FPSCR,Rn */
1481 tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1483 case 0x4062: /* sts FPSCR,@-Rn */
1486 val = tcg_temp_new(TCG_TYPE_I32);
1487 tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1488 addr = tcg_temp_new(TCG_TYPE_I32);
1489 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1490 tcg_gen_qemu_st32(val, addr, ctx->memidx);
1491 tcg_temp_free(addr);
1493 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1496 case 0x00c3: /* movca.l R0,@Rm */
1497 tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
1499 case 0x0029: /* movt Rn */
1500 tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T);
1502 case 0x0093: /* ocbi @Rn */
1504 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1505 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1506 tcg_temp_free(dummy);
1509 case 0x00a3: /* ocbp @Rn */
1511 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1512 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1513 tcg_temp_free(dummy);
1516 case 0x00b3: /* ocbwb @Rn */
1518 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1519 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1520 tcg_temp_free(dummy);
1523 case 0x0083: /* pref @Rn */
1525 case 0x4024: /* rotcl Rn */
1527 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1528 tcg_gen_mov_i32(tmp, cpu_sr);
1529 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1530 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1531 gen_copy_bit_i32(REG(B11_8), 0, tmp, 0);
1535 case 0x4025: /* rotcr Rn */
1537 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1538 tcg_gen_mov_i32(tmp, cpu_sr);
1539 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1540 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1541 gen_copy_bit_i32(REG(B11_8), 31, tmp, 0);
1545 case 0x4004: /* rotl Rn */
1546 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1547 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1548 gen_copy_bit_i32(REG(B11_8), 0, cpu_sr, 0);
1550 case 0x4005: /* rotr Rn */
1551 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1552 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1553 gen_copy_bit_i32(REG(B11_8), 31, cpu_sr, 0);
1555 case 0x4000: /* shll Rn */
1556 case 0x4020: /* shal Rn */
1557 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1558 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1560 case 0x4021: /* shar Rn */
1561 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1562 tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1564 case 0x4001: /* shlr Rn */
1565 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1566 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1568 case 0x4008: /* shll2 Rn */
1569 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1571 case 0x4018: /* shll8 Rn */
1572 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1574 case 0x4028: /* shll16 Rn */
1575 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1577 case 0x4009: /* shlr2 Rn */
1578 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1580 case 0x4019: /* shlr8 Rn */
1581 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1583 case 0x4029: /* shlr16 Rn */
1584 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1586 case 0x401b: /* tas.b @Rn */
1589 addr = tcg_temp_local_new(TCG_TYPE_I32);
1590 tcg_gen_mov_i32(addr, REG(B11_8));
1591 val = tcg_temp_local_new(TCG_TYPE_I32);
1592 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1593 gen_cmp_imm(TCG_COND_EQ, val, 0);
1594 tcg_gen_ori_i32(val, val, 0x80);
1595 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1597 tcg_temp_free(addr);
1600 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1602 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1603 tcg_gen_mov_i32(fp, cpu_fpul);
1604 gen_store_fpr32(fp, FREG(B11_8));
1608 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1610 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1611 gen_load_fpr32(fp, FREG(B11_8));
1612 tcg_gen_mov_i32(cpu_fpul, fp);
1616 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1617 if (ctx->fpscr & FPSCR_PR) {
1619 if (ctx->opcode & 0x0100)
1620 break; /* illegal instruction */
1621 fp = tcg_temp_new(TCG_TYPE_I64);
1622 tcg_gen_helper_1_1(helper_float_DT, fp, cpu_fpul);
1623 gen_store_fpr64(fp, DREG(B11_8));
1627 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1628 tcg_gen_helper_1_1(helper_float_FT, fp, cpu_fpul);
1629 gen_store_fpr32(fp, FREG(B11_8));
1633 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1634 if (ctx->fpscr & FPSCR_PR) {
1636 if (ctx->opcode & 0x0100)
1637 break; /* illegal instruction */
1638 fp = tcg_temp_new(TCG_TYPE_I64);
1639 gen_load_fpr64(fp, DREG(B11_8));
1640 tcg_gen_helper_1_1(helper_ftrc_DT, cpu_fpul, fp);
1644 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1645 gen_load_fpr32(fp, FREG(B11_8));
1646 tcg_gen_helper_1_1(helper_ftrc_FT, cpu_fpul, fp);
1650 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1652 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1653 gen_load_fpr32(fp, FREG(B11_8));
1654 tcg_gen_helper_1_1(helper_fneg_T, fp, fp);
1655 gen_store_fpr32(fp, FREG(B11_8));
1659 case 0xf05d: /* fabs FRn/DRn */
1660 if (ctx->fpscr & FPSCR_PR) {
1661 if (ctx->opcode & 0x0100)
1662 break; /* illegal instruction */
1663 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1664 gen_load_fpr64(fp, DREG(B11_8));
1665 tcg_gen_helper_1_1(helper_fabs_DT, fp, fp);
1666 gen_store_fpr64(fp, DREG(B11_8));
1669 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1670 gen_load_fpr32(fp, FREG(B11_8));
1671 tcg_gen_helper_1_1(helper_fabs_FT, fp, fp);
1672 gen_store_fpr32(fp, FREG(B11_8));
1676 case 0xf06d: /* fsqrt FRn */
1677 if (ctx->fpscr & FPSCR_PR) {
1678 if (ctx->opcode & 0x0100)
1679 break; /* illegal instruction */
1680 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1681 gen_load_fpr64(fp, DREG(B11_8));
1682 tcg_gen_helper_1_1(helper_fsqrt_DT, fp, fp);
1683 gen_store_fpr64(fp, DREG(B11_8));
1686 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1687 gen_load_fpr32(fp, FREG(B11_8));
1688 tcg_gen_helper_1_1(helper_fsqrt_FT, fp, fp);
1689 gen_store_fpr32(fp, FREG(B11_8));
1693 case 0xf07d: /* fsrra FRn */
1695 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1696 if (!(ctx->fpscr & FPSCR_PR)) {
1697 TCGv val = tcg_const_i32(0);
1698 gen_load_fpr32(val, FREG(B11_8));
1703 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1704 if (!(ctx->fpscr & FPSCR_PR)) {
1705 TCGv val = tcg_const_i32(0x3f800000);
1706 gen_load_fpr32(val, FREG(B11_8));
1711 case 0xf0ad: /* fcnvsd FPUL,DRn */
1713 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1714 tcg_gen_helper_1_1(helper_fcnvsd_FT_DT, fp, cpu_fpul);
1715 gen_store_fpr64(fp, DREG(B11_8));
1719 case 0xf0bd: /* fcnvds DRn,FPUL */
1721 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1722 gen_load_fpr64(fp, DREG(B11_8));
1723 tcg_gen_helper_1_1(helper_fcnvds_DT_FT, cpu_fpul, fp);
1729 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1730 ctx->opcode, ctx->pc);
1731 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
1732 ctx->bstate = BS_EXCP;
1735 void decode_opc(DisasContext * ctx)
1737 uint32_t old_flags = ctx->flags;
1741 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1742 if (ctx->flags & DELAY_SLOT_CLEARME) {
1745 /* go out of the delay slot */
1746 uint32_t new_flags = ctx->flags;
1747 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1748 gen_store_flags(new_flags);
1751 ctx->bstate = BS_BRANCH;
1752 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1753 gen_delayed_conditional_jump(ctx);
1754 } else if (old_flags & DELAY_SLOT) {
1760 /* go into a delay slot */
1761 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1762 gen_store_flags(ctx->flags);
1766 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1770 target_ulong pc_start;
1771 static uint16_t *gen_opc_end;
1777 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1779 ctx.flags = (uint32_t)tb->flags;
1780 ctx.bstate = BS_NONE;
1782 ctx.fpscr = env->fpscr;
1783 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1784 /* We don't know if the delayed pc came from a dynamic or static branch,
1785 so assume it is a dynamic branch. */
1786 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1788 ctx.singlestep_enabled = env->singlestep_enabled;
1791 if (loglevel & CPU_LOG_TB_CPU) {
1793 "------------------------------------------------\n");
1794 cpu_dump_state(env, logfile, fprintf, 0);
1800 max_insns = tb->cflags & CF_COUNT_MASK;
1802 max_insns = CF_COUNT_MASK;
1804 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1805 if (env->nb_breakpoints > 0) {
1806 for (i = 0; i < env->nb_breakpoints; i++) {
1807 if (ctx.pc == env->breakpoints[i]) {
1808 /* We have hit a breakpoint - make sure PC is up-to-date */
1809 tcg_gen_movi_i32(cpu_pc, ctx.pc);
1810 tcg_gen_helper_0_0(helper_debug);
1811 ctx.bstate = BS_EXCP;
1817 i = gen_opc_ptr - gen_opc_buf;
1821 gen_opc_instr_start[ii++] = 0;
1823 gen_opc_pc[ii] = ctx.pc;
1824 gen_opc_hflags[ii] = ctx.flags;
1825 gen_opc_instr_start[ii] = 1;
1826 gen_opc_icount[ii] = num_insns;
1828 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1831 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1834 ctx.opcode = lduw_code(ctx.pc);
1838 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1840 if (env->singlestep_enabled)
1842 if (num_insns >= max_insns)
1844 #ifdef SH4_SINGLE_STEP
1848 if (tb->cflags & CF_LAST_IO)
1850 if (env->singlestep_enabled) {
1851 tcg_gen_helper_0_0(helper_debug);
1853 switch (ctx.bstate) {
1855 /* gen_op_interrupt_restart(); */
1859 gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1861 gen_goto_tb(&ctx, 0, ctx.pc);
1864 /* gen_op_interrupt_restart(); */
1873 gen_icount_end(tb, num_insns);
1874 *gen_opc_ptr = INDEX_op_end;
1876 i = gen_opc_ptr - gen_opc_buf;
1879 gen_opc_instr_start[ii++] = 0;
1881 tb->size = ctx.pc - pc_start;
1882 tb->icount = num_insns;
1886 #ifdef SH4_DEBUG_DISAS
1887 if (loglevel & CPU_LOG_TB_IN_ASM)
1888 fprintf(logfile, "\n");
1890 if (loglevel & CPU_LOG_TB_IN_ASM) {
1891 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1892 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1893 fprintf(logfile, "\n");
1898 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1900 gen_intermediate_code_internal(env, tb, 0);
1903 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1905 gen_intermediate_code_internal(env, tb, 1);
1908 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1909 unsigned long searched_pc, int pc_pos, void *puc)
1911 env->pc = gen_opc_pc[pc_pos];
1912 env->flags = gen_opc_hflags[pc_pos];