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 static TCGv cpu_env, cpu_T[2];
62 #include "gen-icount.h"
64 static void sh4_translate_init(void)
66 static int done_init = 0;
69 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
70 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
71 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
73 /* register helpers */
75 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
81 /* General purpose registers moves. */
82 static inline void gen_movl_imm_rN(uint32_t arg, int reg)
84 TCGv tmp = tcg_const_i32(arg);
85 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, gregs[reg]));
89 static always_inline void gen_movl_T_rN (TCGv t, int reg)
91 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, gregs[reg]));
94 static always_inline void gen_movl_rN_T (TCGv t, int reg)
96 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, gregs[reg]));
99 #ifdef CONFIG_USER_ONLY
101 #define GEN_OP_LD(width, reg) \
102 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
103 gen_op_ld##width##_T0_##reg##_raw(); \
105 #define GEN_OP_ST(width, reg) \
106 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
107 gen_op_st##width##_##reg##_T1_raw(); \
112 #define GEN_OP_LD(width, reg) \
113 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
114 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
115 else gen_op_ld##width##_T0_##reg##_user();\
117 #define GEN_OP_ST(width, reg) \
118 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
119 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
120 else gen_op_st##width##_##reg##_T1_user();\
138 void cpu_dump_state(CPUState * env, FILE * f,
139 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
143 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
144 env->pc, env->sr, env->pr, env->fpscr);
145 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
146 env->spc, env->ssr, env->gbr, env->vbr);
147 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
148 env->sgr, env->dbr, env->delayed_pc, env->fpul);
149 for (i = 0; i < 24; i += 4) {
150 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
151 i, env->gregs[i], i + 1, env->gregs[i + 1],
152 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
154 if (env->flags & DELAY_SLOT) {
155 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
157 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
158 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
163 void cpu_sh4_reset(CPUSH4State * env)
165 #if defined(CONFIG_USER_ONLY)
166 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
168 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
171 env->pc = 0xA0000000;
172 #if defined(CONFIG_USER_ONLY)
173 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
174 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
176 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
177 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
182 CPUSH4State *cpu_sh4_init(const char *cpu_model)
186 env = qemu_mallocz(sizeof(CPUSH4State));
190 sh4_translate_init();
196 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
198 TranslationBlock *tb;
201 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
202 !ctx->singlestep_enabled) {
203 /* Use a direct jump if in same page and singlestep not enabled */
205 gen_op_movl_imm_PC(dest);
206 tcg_gen_exit_tb((long) tb + n);
208 gen_op_movl_imm_PC(dest);
209 if (ctx->singlestep_enabled)
215 static void gen_jump(DisasContext * ctx)
217 if (ctx->delayed_pc == (uint32_t) - 1) {
218 /* Target is not statically known, it comes necessarily from a
219 delayed jump as immediate jump are conditinal jumps */
220 gen_op_movl_delayed_pc_PC();
221 if (ctx->singlestep_enabled)
225 gen_goto_tb(ctx, 0, ctx->delayed_pc);
229 /* Immediate conditional jump (bt or bf) */
230 static void gen_conditional_jump(DisasContext * ctx,
231 target_ulong ift, target_ulong ifnott)
235 l1 = gen_new_label();
237 gen_goto_tb(ctx, 0, ifnott);
239 gen_goto_tb(ctx, 1, ift);
242 /* Delayed conditional jump (bt or bf) */
243 static void gen_delayed_conditional_jump(DisasContext * ctx)
247 l1 = gen_new_label();
249 gen_goto_tb(ctx, 1, ctx->pc + 2);
254 #define B3_0 (ctx->opcode & 0xf)
255 #define B6_4 ((ctx->opcode >> 4) & 0x7)
256 #define B7_4 ((ctx->opcode >> 4) & 0xf)
257 #define B7_0 (ctx->opcode & 0xff)
258 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
259 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
260 (ctx->opcode & 0xfff))
261 #define B11_8 ((ctx->opcode >> 8) & 0xf)
262 #define B15_12 ((ctx->opcode >> 12) & 0xf)
264 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
267 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
270 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
271 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
272 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
273 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
275 #define CHECK_NOT_DELAY_SLOT \
276 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
277 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
280 void _decode_opc(DisasContext * ctx)
283 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
285 switch (ctx->opcode) {
286 case 0x0019: /* div0u */
289 case 0x000b: /* rts */
290 CHECK_NOT_DELAY_SLOT gen_op_rts();
291 ctx->flags |= DELAY_SLOT;
292 ctx->delayed_pc = (uint32_t) - 1;
294 case 0x0028: /* clrmac */
297 case 0x0048: /* clrs */
300 case 0x0008: /* clrt */
303 case 0x0038: /* ldtlb */
304 #if defined(CONFIG_USER_ONLY)
305 assert(0); /* XXXXX */
310 case 0x002b: /* rte */
311 CHECK_NOT_DELAY_SLOT gen_op_rte();
312 ctx->flags |= DELAY_SLOT;
313 ctx->delayed_pc = (uint32_t) - 1;
315 case 0x0058: /* sets */
318 case 0x0018: /* sett */
321 case 0xfbfd: /* frchg */
323 ctx->bstate = BS_STOP;
325 case 0xf3fd: /* fschg */
327 ctx->bstate = BS_STOP;
329 case 0x0009: /* nop */
331 case 0x001b: /* sleep */
335 gen_op_raise_illegal_instruction();
336 ctx->bstate = BS_EXCP;
341 switch (ctx->opcode & 0xf000) {
342 case 0x1000: /* mov.l Rm,@(disp,Rn) */
343 gen_movl_rN_T(cpu_T[0], REG(B7_4));
344 gen_movl_rN_T(cpu_T[1], REG(B11_8));
345 gen_op_addl_imm_T1(B3_0 * 4);
346 gen_op_stl_T0_T1(ctx);
348 case 0x5000: /* mov.l @(disp,Rm),Rn */
349 gen_movl_rN_T(cpu_T[0], REG(B7_4));
350 gen_op_addl_imm_T0(B3_0 * 4);
351 gen_op_ldl_T0_T0(ctx);
352 gen_movl_T_rN(cpu_T[0], REG(B11_8));
354 case 0xe000: /* mov #imm,Rn */
355 gen_movl_imm_rN(B7_0s, REG(B11_8));
357 case 0x9000: /* mov.w @(disp,PC),Rn */
358 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
359 gen_op_ldw_T0_T0(ctx);
360 gen_movl_T_rN(cpu_T[0], REG(B11_8));
362 case 0xd000: /* mov.l @(disp,PC),Rn */
363 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
364 gen_op_ldl_T0_T0(ctx);
365 gen_movl_T_rN(cpu_T[0], REG(B11_8));
367 case 0x7000: /* add #imm,Rn */
368 gen_op_add_imm_rN(B7_0s, REG(B11_8));
370 case 0xa000: /* bra disp */
372 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
373 ctx->flags |= DELAY_SLOT;
375 case 0xb000: /* bsr disp */
377 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
378 ctx->pc + 4 + B11_0s * 2);
379 ctx->flags |= DELAY_SLOT;
383 switch (ctx->opcode & 0xf00f) {
384 case 0x6003: /* mov Rm,Rn */
385 gen_movl_rN_T(cpu_T[0], REG(B7_4));
386 gen_movl_T_rN(cpu_T[0], REG(B11_8));
388 case 0x2000: /* mov.b Rm,@Rn */
389 gen_movl_rN_T(cpu_T[0], REG(B7_4));
390 gen_movl_rN_T(cpu_T[1], REG(B11_8));
391 gen_op_stb_T0_T1(ctx);
393 case 0x2001: /* mov.w Rm,@Rn */
394 gen_movl_rN_T(cpu_T[0], REG(B7_4));
395 gen_movl_rN_T(cpu_T[1], REG(B11_8));
396 gen_op_stw_T0_T1(ctx);
398 case 0x2002: /* mov.l Rm,@Rn */
399 gen_movl_rN_T(cpu_T[0], REG(B7_4));
400 gen_movl_rN_T(cpu_T[1], REG(B11_8));
401 gen_op_stl_T0_T1(ctx);
403 case 0x6000: /* mov.b @Rm,Rn */
404 gen_movl_rN_T(cpu_T[0], REG(B7_4));
405 gen_op_ldb_T0_T0(ctx);
406 gen_movl_T_rN(cpu_T[0], REG(B11_8));
408 case 0x6001: /* mov.w @Rm,Rn */
409 gen_movl_rN_T(cpu_T[0], REG(B7_4));
410 gen_op_ldw_T0_T0(ctx);
411 gen_movl_T_rN(cpu_T[0], REG(B11_8));
413 case 0x6002: /* mov.l @Rm,Rn */
414 gen_movl_rN_T(cpu_T[0], REG(B7_4));
415 gen_op_ldl_T0_T0(ctx);
416 gen_movl_T_rN(cpu_T[0], REG(B11_8));
418 case 0x2004: /* mov.b Rm,@-Rn */
419 gen_movl_rN_T(cpu_T[0], REG(B7_4));
420 gen_op_dec1_rN(REG(B11_8)); /* modify register status */
421 gen_movl_rN_T(cpu_T[1], REG(B11_8));
422 gen_op_inc1_rN(REG(B11_8)); /* recover register status */
423 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
424 gen_op_dec1_rN(REG(B11_8)); /* modify register status */
426 case 0x2005: /* mov.w Rm,@-Rn */
427 gen_movl_rN_T(cpu_T[0], REG(B7_4));
428 gen_op_dec2_rN(REG(B11_8));
429 gen_movl_rN_T(cpu_T[1], REG(B11_8));
430 gen_op_inc2_rN(REG(B11_8));
431 gen_op_stw_T0_T1(ctx);
432 gen_op_dec2_rN(REG(B11_8));
434 case 0x2006: /* mov.l Rm,@-Rn */
435 gen_movl_rN_T(cpu_T[0], REG(B7_4));
436 gen_op_dec4_rN(REG(B11_8));
437 gen_movl_rN_T(cpu_T[1], REG(B11_8));
438 gen_op_inc4_rN(REG(B11_8));
439 gen_op_stl_T0_T1(ctx);
440 gen_op_dec4_rN(REG(B11_8));
442 case 0x6004: /* mov.b @Rm+,Rn */
443 gen_movl_rN_T(cpu_T[0], REG(B7_4));
444 gen_op_ldb_T0_T0(ctx);
445 gen_movl_T_rN(cpu_T[0], REG(B11_8));
447 gen_op_inc1_rN(REG(B7_4));
449 case 0x6005: /* mov.w @Rm+,Rn */
450 gen_movl_rN_T(cpu_T[0], REG(B7_4));
451 gen_op_ldw_T0_T0(ctx);
452 gen_movl_T_rN(cpu_T[0], REG(B11_8));
454 gen_op_inc2_rN(REG(B7_4));
456 case 0x6006: /* mov.l @Rm+,Rn */
457 gen_movl_rN_T(cpu_T[0], REG(B7_4));
458 gen_op_ldl_T0_T0(ctx);
459 gen_movl_T_rN(cpu_T[0], REG(B11_8));
461 gen_op_inc4_rN(REG(B7_4));
463 case 0x0004: /* mov.b Rm,@(R0,Rn) */
464 gen_movl_rN_T(cpu_T[0], REG(B7_4));
465 gen_movl_rN_T(cpu_T[1], REG(B11_8));
466 gen_op_add_rN_T1(REG(0));
467 gen_op_stb_T0_T1(ctx);
469 case 0x0005: /* mov.w Rm,@(R0,Rn) */
470 gen_movl_rN_T(cpu_T[0], REG(B7_4));
471 gen_movl_rN_T(cpu_T[1], REG(B11_8));
472 gen_op_add_rN_T1(REG(0));
473 gen_op_stw_T0_T1(ctx);
475 case 0x0006: /* mov.l Rm,@(R0,Rn) */
476 gen_movl_rN_T(cpu_T[0], REG(B7_4));
477 gen_movl_rN_T(cpu_T[1], REG(B11_8));
478 gen_op_add_rN_T1(REG(0));
479 gen_op_stl_T0_T1(ctx);
481 case 0x000c: /* mov.b @(R0,Rm),Rn */
482 gen_movl_rN_T(cpu_T[0], REG(B7_4));
483 gen_op_add_rN_T0(REG(0));
484 gen_op_ldb_T0_T0(ctx);
485 gen_movl_T_rN(cpu_T[0], REG(B11_8));
487 case 0x000d: /* mov.w @(R0,Rm),Rn */
488 gen_movl_rN_T(cpu_T[0], REG(B7_4));
489 gen_op_add_rN_T0(REG(0));
490 gen_op_ldw_T0_T0(ctx);
491 gen_movl_T_rN(cpu_T[0], REG(B11_8));
493 case 0x000e: /* mov.l @(R0,Rm),Rn */
494 gen_movl_rN_T(cpu_T[0], REG(B7_4));
495 gen_op_add_rN_T0(REG(0));
496 gen_op_ldl_T0_T0(ctx);
497 gen_movl_T_rN(cpu_T[0], REG(B11_8));
499 case 0x6008: /* swap.b Rm,Rn */
500 gen_movl_rN_T(cpu_T[0], REG(B7_4));
502 gen_movl_T_rN(cpu_T[0], REG(B11_8));
504 case 0x6009: /* swap.w Rm,Rn */
505 gen_movl_rN_T(cpu_T[0], REG(B7_4));
507 gen_movl_T_rN(cpu_T[0], REG(B11_8));
509 case 0x200d: /* xtrct Rm,Rn */
510 gen_movl_rN_T(cpu_T[0], REG(B7_4));
511 gen_movl_rN_T(cpu_T[1], REG(B11_8));
512 gen_op_xtrct_T0_T1();
513 gen_movl_T_rN(cpu_T[1], REG(B11_8));
515 case 0x300c: /* add Rm,Rn */
516 gen_movl_rN_T(cpu_T[0], REG(B7_4));
517 gen_op_add_T0_rN(REG(B11_8));
519 case 0x300e: /* addc Rm,Rn */
520 gen_movl_rN_T(cpu_T[0], REG(B7_4));
521 gen_movl_rN_T(cpu_T[1], REG(B11_8));
523 gen_movl_T_rN(cpu_T[1], REG(B11_8));
525 case 0x300f: /* addv Rm,Rn */
526 gen_movl_rN_T(cpu_T[0], REG(B7_4));
527 gen_movl_rN_T(cpu_T[1], REG(B11_8));
529 gen_movl_T_rN(cpu_T[1], REG(B11_8));
531 case 0x2009: /* and Rm,Rn */
532 gen_movl_rN_T(cpu_T[0], REG(B7_4));
533 gen_op_and_T0_rN(REG(B11_8));
535 case 0x3000: /* cmp/eq Rm,Rn */
536 gen_movl_rN_T(cpu_T[0], REG(B7_4));
537 gen_movl_rN_T(cpu_T[1], REG(B11_8));
538 gen_op_cmp_eq_T0_T1();
540 case 0x3003: /* cmp/ge Rm,Rn */
541 gen_movl_rN_T(cpu_T[0], REG(B7_4));
542 gen_movl_rN_T(cpu_T[1], REG(B11_8));
543 gen_op_cmp_ge_T0_T1();
545 case 0x3007: /* cmp/gt Rm,Rn */
546 gen_movl_rN_T(cpu_T[0], REG(B7_4));
547 gen_movl_rN_T(cpu_T[1], REG(B11_8));
548 gen_op_cmp_gt_T0_T1();
550 case 0x3006: /* cmp/hi Rm,Rn */
551 gen_movl_rN_T(cpu_T[0], REG(B7_4));
552 gen_movl_rN_T(cpu_T[1], REG(B11_8));
553 gen_op_cmp_hi_T0_T1();
555 case 0x3002: /* cmp/hs Rm,Rn */
556 gen_movl_rN_T(cpu_T[0], REG(B7_4));
557 gen_movl_rN_T(cpu_T[1], REG(B11_8));
558 gen_op_cmp_hs_T0_T1();
560 case 0x200c: /* cmp/str Rm,Rn */
561 gen_movl_rN_T(cpu_T[0], REG(B7_4));
562 gen_movl_rN_T(cpu_T[1], REG(B11_8));
563 gen_op_cmp_str_T0_T1();
565 case 0x2007: /* div0s Rm,Rn */
566 gen_movl_rN_T(cpu_T[0], REG(B7_4));
567 gen_movl_rN_T(cpu_T[1], REG(B11_8));
568 gen_op_div0s_T0_T1();
570 case 0x3004: /* div1 Rm,Rn */
571 gen_movl_rN_T(cpu_T[0], REG(B7_4));
572 gen_movl_rN_T(cpu_T[1], REG(B11_8));
574 gen_movl_T_rN(cpu_T[1], REG(B11_8));
576 case 0x300d: /* dmuls.l Rm,Rn */
577 gen_movl_rN_T(cpu_T[0], REG(B7_4));
578 gen_movl_rN_T(cpu_T[1], REG(B11_8));
579 gen_op_dmulsl_T0_T1();
581 case 0x3005: /* dmulu.l Rm,Rn */
582 gen_movl_rN_T(cpu_T[0], REG(B7_4));
583 gen_movl_rN_T(cpu_T[1], REG(B11_8));
584 gen_op_dmulul_T0_T1();
586 case 0x600e: /* exts.b Rm,Rn */
587 gen_movl_rN_T(cpu_T[0], REG(B7_4));
588 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
589 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
590 gen_movl_T_rN(cpu_T[0], REG(B11_8));
592 case 0x600f: /* exts.w Rm,Rn */
593 gen_movl_rN_T(cpu_T[0], REG(B7_4));
594 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
595 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
596 gen_movl_T_rN(cpu_T[0], REG(B11_8));
598 case 0x600c: /* extu.b Rm,Rn */
599 gen_movl_rN_T(cpu_T[0], REG(B7_4));
600 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
601 gen_movl_T_rN(cpu_T[0], REG(B11_8));
603 case 0x600d: /* extu.w Rm,Rn */
604 gen_movl_rN_T(cpu_T[0], REG(B7_4));
605 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
606 gen_movl_T_rN(cpu_T[0], REG(B11_8));
608 case 0x000f: /* mac.l @Rm+,@Rn+ */
609 gen_movl_rN_T(cpu_T[0], REG(B11_8));
610 gen_op_ldl_T0_T0(ctx);
611 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
612 gen_movl_rN_T(cpu_T[0], REG(B7_4));
613 gen_op_ldl_T0_T0(ctx);
615 gen_op_inc4_rN(REG(B11_8));
616 gen_op_inc4_rN(REG(B7_4));
618 case 0x400f: /* mac.w @Rm+,@Rn+ */
619 gen_movl_rN_T(cpu_T[0], REG(B11_8));
620 gen_op_ldl_T0_T0(ctx);
621 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
622 gen_movl_rN_T(cpu_T[0], REG(B7_4));
623 gen_op_ldl_T0_T0(ctx);
625 gen_op_inc2_rN(REG(B11_8));
626 gen_op_inc2_rN(REG(B7_4));
628 case 0x0007: /* mul.l Rm,Rn */
629 gen_movl_rN_T(cpu_T[0], REG(B7_4));
630 gen_movl_rN_T(cpu_T[1], REG(B11_8));
633 case 0x200f: /* muls.w Rm,Rn */
634 gen_movl_rN_T(cpu_T[0], REG(B7_4));
635 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
636 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
637 gen_movl_rN_T(cpu_T[1], REG(B11_8));
638 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
639 tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
640 gen_op_mulsw_T0_T1();
642 case 0x200e: /* mulu.w Rm,Rn */
643 gen_movl_rN_T(cpu_T[0], REG(B7_4));
644 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
645 gen_movl_rN_T(cpu_T[1], REG(B11_8));
646 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
647 gen_op_muluw_T0_T1();
649 case 0x600b: /* neg Rm,Rn */
650 gen_movl_rN_T(cpu_T[0], REG(B7_4));
652 gen_movl_T_rN(cpu_T[0], REG(B11_8));
654 case 0x600a: /* negc Rm,Rn */
655 gen_movl_rN_T(cpu_T[0], REG(B7_4));
657 gen_movl_T_rN(cpu_T[0], REG(B11_8));
659 case 0x6007: /* not Rm,Rn */
660 gen_movl_rN_T(cpu_T[0], REG(B7_4));
662 gen_movl_T_rN(cpu_T[0], REG(B11_8));
664 case 0x200b: /* or Rm,Rn */
665 gen_movl_rN_T(cpu_T[0], REG(B7_4));
666 gen_op_or_T0_rN(REG(B11_8));
668 case 0x400c: /* shad Rm,Rn */
669 gen_movl_rN_T(cpu_T[0], REG(B7_4));
670 gen_movl_rN_T(cpu_T[1], REG(B11_8));
672 gen_movl_T_rN(cpu_T[1], REG(B11_8));
674 case 0x400d: /* shld Rm,Rn */
675 gen_movl_rN_T(cpu_T[0], REG(B7_4));
676 gen_movl_rN_T(cpu_T[1], REG(B11_8));
678 gen_movl_T_rN(cpu_T[1], REG(B11_8));
680 case 0x3008: /* sub Rm,Rn */
681 gen_movl_rN_T(cpu_T[0], REG(B7_4));
682 gen_op_sub_T0_rN(REG(B11_8));
684 case 0x300a: /* subc Rm,Rn */
685 gen_movl_rN_T(cpu_T[0], REG(B7_4));
686 gen_movl_rN_T(cpu_T[1], REG(B11_8));
688 gen_movl_T_rN(cpu_T[1], REG(B11_8));
690 case 0x300b: /* subv Rm,Rn */
691 gen_movl_rN_T(cpu_T[0], REG(B7_4));
692 gen_movl_rN_T(cpu_T[1], REG(B11_8));
694 gen_movl_T_rN(cpu_T[1], REG(B11_8));
696 case 0x2008: /* tst Rm,Rn */
697 gen_movl_rN_T(cpu_T[0], REG(B7_4));
698 gen_movl_rN_T(cpu_T[1], REG(B11_8));
701 case 0x200a: /* xor Rm,Rn */
702 gen_movl_rN_T(cpu_T[0], REG(B7_4));
703 gen_op_xor_T0_rN(REG(B11_8));
705 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
706 if (ctx->fpscr & FPSCR_SZ) {
707 gen_op_fmov_drN_DT0(XREG(B7_4));
708 gen_op_fmov_DT0_drN(XREG(B11_8));
710 gen_op_fmov_frN_FT0(FREG(B7_4));
711 gen_op_fmov_FT0_frN(FREG(B11_8));
714 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
715 if (ctx->fpscr & FPSCR_SZ) {
716 gen_op_fmov_drN_DT0(XREG(B7_4));
717 gen_movl_rN_T(cpu_T[1], REG(B11_8));
718 gen_op_stfq_DT0_T1(ctx);
720 gen_op_fmov_frN_FT0(FREG(B7_4));
721 gen_movl_rN_T(cpu_T[1], REG(B11_8));
722 gen_op_stfl_FT0_T1(ctx);
725 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
726 if (ctx->fpscr & FPSCR_SZ) {
727 gen_movl_rN_T(cpu_T[0], REG(B7_4));
728 gen_op_ldfq_T0_DT0(ctx);
729 gen_op_fmov_DT0_drN(XREG(B11_8));
731 gen_movl_rN_T(cpu_T[0], REG(B7_4));
732 gen_op_ldfl_T0_FT0(ctx);
733 gen_op_fmov_FT0_frN(FREG(B11_8));
736 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
737 if (ctx->fpscr & FPSCR_SZ) {
738 gen_movl_rN_T(cpu_T[0], REG(B7_4));
739 gen_op_ldfq_T0_DT0(ctx);
740 gen_op_fmov_DT0_drN(XREG(B11_8));
741 gen_op_inc8_rN(REG(B7_4));
743 gen_movl_rN_T(cpu_T[0], REG(B7_4));
744 gen_op_ldfl_T0_FT0(ctx);
745 gen_op_fmov_FT0_frN(FREG(B11_8));
746 gen_op_inc4_rN(REG(B7_4));
749 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
750 if (ctx->fpscr & FPSCR_SZ) {
751 gen_op_dec8_rN(REG(B11_8));
752 gen_op_fmov_drN_DT0(XREG(B7_4));
753 gen_movl_rN_T(cpu_T[1], REG(B11_8));
754 gen_op_inc8_rN(REG(B11_8));
755 gen_op_stfq_DT0_T1(ctx);
756 gen_op_dec8_rN(REG(B11_8));
758 gen_op_dec4_rN(REG(B11_8));
759 gen_op_fmov_frN_FT0(FREG(B7_4));
760 gen_movl_rN_T(cpu_T[1], REG(B11_8));
761 gen_op_inc4_rN(REG(B11_8));
762 gen_op_stfl_FT0_T1(ctx);
763 gen_op_dec4_rN(REG(B11_8));
766 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
767 if (ctx->fpscr & FPSCR_SZ) {
768 gen_movl_rN_T(cpu_T[0], REG(B7_4));
769 gen_op_add_rN_T0(REG(0));
770 gen_op_ldfq_T0_DT0(ctx);
771 gen_op_fmov_DT0_drN(XREG(B11_8));
773 gen_movl_rN_T(cpu_T[0], REG(B7_4));
774 gen_op_add_rN_T0(REG(0));
775 gen_op_ldfl_T0_FT0(ctx);
776 gen_op_fmov_FT0_frN(FREG(B11_8));
779 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
780 if (ctx->fpscr & FPSCR_SZ) {
781 gen_op_fmov_drN_DT0(XREG(B7_4));
782 gen_movl_rN_T(cpu_T[1], REG(B11_8));
783 gen_op_add_rN_T1(REG(0));
784 gen_op_stfq_DT0_T1(ctx);
786 gen_op_fmov_frN_FT0(FREG(B7_4));
787 gen_movl_rN_T(cpu_T[1], REG(B11_8));
788 gen_op_add_rN_T1(REG(0));
789 gen_op_stfl_FT0_T1(ctx);
792 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
793 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
794 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
795 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
796 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
797 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
798 if (ctx->fpscr & FPSCR_PR) {
799 if (ctx->opcode & 0x0110)
800 break; /* illegal instruction */
801 gen_op_fmov_drN_DT1(DREG(B7_4));
802 gen_op_fmov_drN_DT0(DREG(B11_8));
805 gen_op_fmov_frN_FT1(FREG(B7_4));
806 gen_op_fmov_frN_FT0(FREG(B11_8));
809 switch (ctx->opcode & 0xf00f) {
810 case 0xf000: /* fadd Rm,Rn */
811 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
813 case 0xf001: /* fsub Rm,Rn */
814 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
816 case 0xf002: /* fmul Rm,Rn */
817 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
819 case 0xf003: /* fdiv Rm,Rn */
820 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
822 case 0xf004: /* fcmp/eq Rm,Rn */
823 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
825 case 0xf005: /* fcmp/gt Rm,Rn */
826 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
830 if (ctx->fpscr & FPSCR_PR) {
831 gen_op_fmov_DT0_drN(DREG(B11_8));
834 gen_op_fmov_FT0_frN(FREG(B11_8));
839 switch (ctx->opcode & 0xff00) {
840 case 0xc900: /* and #imm,R0 */
841 gen_op_and_imm_rN(B7_0, REG(0));
843 case 0xcd00: /* and.b #imm,@(R0,GBR) */
844 gen_movl_rN_T(cpu_T[0], REG(0));
845 gen_op_addl_GBR_T0();
846 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
847 gen_op_ldub_T0_T0(ctx);
848 gen_op_and_imm_T0(B7_0);
849 gen_op_stb_T0_T1(ctx);
851 case 0x8b00: /* bf label */
853 gen_conditional_jump(ctx, ctx->pc + 2,
854 ctx->pc + 4 + B7_0s * 2);
855 ctx->bstate = BS_BRANCH;
857 case 0x8f00: /* bf/s label */
859 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
860 ctx->flags |= DELAY_SLOT_CONDITIONAL;
862 case 0x8900: /* bt label */
864 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
866 ctx->bstate = BS_BRANCH;
868 case 0x8d00: /* bt/s label */
870 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
871 ctx->flags |= DELAY_SLOT_CONDITIONAL;
873 case 0x8800: /* cmp/eq #imm,R0 */
874 gen_movl_rN_T(cpu_T[0], REG(0));
875 gen_op_cmp_eq_imm_T0(B7_0s);
877 case 0xc400: /* mov.b @(disp,GBR),R0 */
879 gen_op_addl_imm_T0(B7_0);
880 gen_op_ldb_T0_T0(ctx);
881 gen_movl_T_rN(cpu_T[0], REG(0));
883 case 0xc500: /* mov.w @(disp,GBR),R0 */
885 gen_op_addl_imm_T0(B7_0 * 2);
886 gen_op_ldw_T0_T0(ctx);
887 gen_movl_T_rN(cpu_T[0], REG(0));
889 case 0xc600: /* mov.l @(disp,GBR),R0 */
891 gen_op_addl_imm_T0(B7_0 * 4);
892 gen_op_ldl_T0_T0(ctx);
893 gen_movl_T_rN(cpu_T[0], REG(0));
895 case 0xc000: /* mov.b R0,@(disp,GBR) */
897 gen_op_addl_imm_T0(B7_0);
898 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
899 gen_movl_rN_T(cpu_T[0], REG(0));
900 gen_op_stb_T0_T1(ctx);
902 case 0xc100: /* mov.w R0,@(disp,GBR) */
904 gen_op_addl_imm_T0(B7_0 * 2);
905 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
906 gen_movl_rN_T(cpu_T[0], REG(0));
907 gen_op_stw_T0_T1(ctx);
909 case 0xc200: /* mov.l R0,@(disp,GBR) */
911 gen_op_addl_imm_T0(B7_0 * 4);
912 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
913 gen_movl_rN_T(cpu_T[0], REG(0));
914 gen_op_stl_T0_T1(ctx);
916 case 0x8000: /* mov.b R0,@(disp,Rn) */
917 gen_movl_rN_T(cpu_T[0], REG(0));
918 gen_movl_rN_T(cpu_T[1], REG(B7_4));
919 gen_op_addl_imm_T1(B3_0);
920 gen_op_stb_T0_T1(ctx);
922 case 0x8100: /* mov.w R0,@(disp,Rn) */
923 gen_movl_rN_T(cpu_T[0], REG(0));
924 gen_movl_rN_T(cpu_T[1], REG(B7_4));
925 gen_op_addl_imm_T1(B3_0 * 2);
926 gen_op_stw_T0_T1(ctx);
928 case 0x8400: /* mov.b @(disp,Rn),R0 */
929 gen_movl_rN_T(cpu_T[0], REG(B7_4));
930 gen_op_addl_imm_T0(B3_0);
931 gen_op_ldb_T0_T0(ctx);
932 gen_movl_T_rN(cpu_T[0], REG(0));
934 case 0x8500: /* mov.w @(disp,Rn),R0 */
935 gen_movl_rN_T(cpu_T[0], REG(B7_4));
936 gen_op_addl_imm_T0(B3_0 * 2);
937 gen_op_ldw_T0_T0(ctx);
938 gen_movl_T_rN(cpu_T[0], REG(0));
940 case 0xc700: /* mova @(disp,PC),R0 */
941 gen_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
944 case 0xcb00: /* or #imm,R0 */
945 gen_op_or_imm_rN(B7_0, REG(0));
947 case 0xcf00: /* or.b #imm,@(R0,GBR) */
948 gen_movl_rN_T(cpu_T[0], REG(0));
949 gen_op_addl_GBR_T0();
950 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
951 gen_op_ldub_T0_T0(ctx);
952 gen_op_or_imm_T0(B7_0);
953 gen_op_stb_T0_T1(ctx);
955 case 0xc300: /* trapa #imm */
956 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
958 ctx->bstate = BS_BRANCH;
960 case 0xc800: /* tst #imm,R0 */
961 gen_op_tst_imm_rN(B7_0, REG(0));
963 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
964 gen_movl_rN_T(cpu_T[0], REG(0));
965 gen_op_addl_GBR_T0();
966 gen_op_ldub_T0_T0(ctx);
967 gen_op_tst_imm_T0(B7_0);
969 case 0xca00: /* xor #imm,R0 */
970 gen_op_xor_imm_rN(B7_0, REG(0));
972 case 0xce00: /* xor.b #imm,@(R0,GBR) */
973 gen_movl_rN_T(cpu_T[0], REG(0));
974 gen_op_addl_GBR_T0();
975 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
976 gen_op_ldub_T0_T0(ctx);
977 gen_op_xor_imm_T0(B7_0);
978 gen_op_stb_T0_T1(ctx);
982 switch (ctx->opcode & 0xf08f) {
983 case 0x408e: /* ldc Rm,Rn_BANK */
984 gen_movl_rN_T(cpu_T[0], REG(B11_8));
985 gen_movl_T_rN(cpu_T[0], ALTREG(B6_4));
987 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
988 gen_movl_rN_T(cpu_T[0], REG(B11_8));
989 gen_op_ldl_T0_T0(ctx);
990 gen_movl_T_rN(cpu_T[0], ALTREG(B6_4));
991 gen_op_inc4_rN(REG(B11_8));
993 case 0x0082: /* stc Rm_BANK,Rn */
994 gen_movl_rN_T(cpu_T[0], ALTREG(B6_4));
995 gen_movl_T_rN(cpu_T[0], REG(B11_8));
997 case 0x4083: /* stc.l Rm_BANK,@-Rn */
998 gen_op_dec4_rN(REG(B11_8));
999 gen_movl_rN_T(cpu_T[1], REG(B11_8));
1000 gen_movl_rN_T(cpu_T[0], ALTREG(B6_4));
1001 gen_op_inc4_rN(REG(B11_8));
1002 gen_op_stl_T0_T1(ctx);
1003 gen_op_dec4_rN(REG(B11_8));
1007 switch (ctx->opcode & 0xf0ff) {
1008 case 0x0023: /* braf Rn */
1009 CHECK_NOT_DELAY_SLOT gen_movl_rN_T(cpu_T[0], REG(B11_8));
1010 gen_op_braf_T0(ctx->pc + 4);
1011 ctx->flags |= DELAY_SLOT;
1012 ctx->delayed_pc = (uint32_t) - 1;
1014 case 0x0003: /* bsrf Rn */
1015 CHECK_NOT_DELAY_SLOT gen_movl_rN_T(cpu_T[0], REG(B11_8));
1016 gen_op_bsrf_T0(ctx->pc + 4);
1017 ctx->flags |= DELAY_SLOT;
1018 ctx->delayed_pc = (uint32_t) - 1;
1020 case 0x4015: /* cmp/pl Rn */
1021 gen_movl_rN_T(cpu_T[0], REG(B11_8));
1024 case 0x4011: /* cmp/pz Rn */
1025 gen_movl_rN_T(cpu_T[0], REG(B11_8));
1028 case 0x4010: /* dt Rn */
1029 gen_op_dt_rN(REG(B11_8));
1031 case 0x402b: /* jmp @Rn */
1032 CHECK_NOT_DELAY_SLOT gen_movl_rN_T(cpu_T[0], REG(B11_8));
1034 ctx->flags |= DELAY_SLOT;
1035 ctx->delayed_pc = (uint32_t) - 1;
1037 case 0x400b: /* jsr @Rn */
1038 CHECK_NOT_DELAY_SLOT gen_movl_rN_T(cpu_T[0], REG(B11_8));
1039 gen_op_jsr_T0(ctx->pc + 4);
1040 ctx->flags |= DELAY_SLOT;
1041 ctx->delayed_pc = (uint32_t) - 1;
1043 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1045 gen_movl_rN_T (cpu_T[0], REG(B11_8)); \
1046 gen_op_##ldop##_T0_##reg (); \
1050 gen_movl_rN_T (cpu_T[0], REG(B11_8)); \
1051 gen_op_ldl_T0_T0 (ctx); \
1052 gen_op_inc4_rN (REG(B11_8)); \
1053 gen_op_##ldop##_T0_##reg (); \
1057 gen_op_##stop##_##reg##_T0 (); \
1058 gen_movl_T_rN (cpu_T[0], REG(B11_8)); \
1061 gen_op_##stop##_##reg##_T0 (); \
1062 gen_op_dec4_rN (REG(B11_8)); \
1063 gen_movl_rN_T (cpu_T[1], REG(B11_8)); \
1064 gen_op_inc4_rN (REG(B11_8)); \
1065 gen_op_stl_T0_T1 (ctx); \
1066 gen_op_dec4_rN (REG(B11_8)); \
1068 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1070 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1071 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1072 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1073 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1074 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1075 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1076 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1077 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1078 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1079 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1081 case 0x00c3: /* movca.l R0,@Rm */
1082 gen_movl_rN_T(cpu_T[0], REG(0));
1083 gen_movl_rN_T(cpu_T[1], REG(B11_8));
1084 gen_op_stl_T0_T1(ctx);
1086 case 0x0029: /* movt Rn */
1087 gen_op_movt_rN(REG(B11_8));
1089 case 0x0093: /* ocbi @Rn */
1090 gen_movl_rN_T(cpu_T[0], REG(B11_8));
1091 gen_op_ldl_T0_T0(ctx);
1093 case 0x00a3: /* ocbp @Rn */
1094 gen_movl_rN_T(cpu_T[0], REG(B11_8));
1095 gen_op_ldl_T0_T0(ctx);
1097 case 0x00b3: /* ocbwb @Rn */
1098 gen_movl_rN_T(cpu_T[0], REG(B11_8));
1099 gen_op_ldl_T0_T0(ctx);
1101 case 0x0083: /* pref @Rn */
1103 case 0x4024: /* rotcl Rn */
1104 gen_op_rotcl_Rn(REG(B11_8));
1106 case 0x4025: /* rotcr Rn */
1107 gen_op_rotcr_Rn(REG(B11_8));
1109 case 0x4004: /* rotl Rn */
1110 gen_op_rotl_Rn(REG(B11_8));
1112 case 0x4005: /* rotr Rn */
1113 gen_op_rotr_Rn(REG(B11_8));
1115 case 0x4000: /* shll Rn */
1116 case 0x4020: /* shal Rn */
1117 gen_op_shal_Rn(REG(B11_8));
1119 case 0x4021: /* shar Rn */
1120 gen_op_shar_Rn(REG(B11_8));
1122 case 0x4001: /* shlr Rn */
1123 gen_op_shlr_Rn(REG(B11_8));
1125 case 0x4008: /* shll2 Rn */
1126 gen_op_shll2_Rn(REG(B11_8));
1128 case 0x4018: /* shll8 Rn */
1129 gen_op_shll8_Rn(REG(B11_8));
1131 case 0x4028: /* shll16 Rn */
1132 gen_op_shll16_Rn(REG(B11_8));
1134 case 0x4009: /* shlr2 Rn */
1135 gen_op_shlr2_Rn(REG(B11_8));
1137 case 0x4019: /* shlr8 Rn */
1138 gen_op_shlr8_Rn(REG(B11_8));
1140 case 0x4029: /* shlr16 Rn */
1141 gen_op_shlr16_Rn(REG(B11_8));
1143 case 0x401b: /* tas.b @Rn */
1144 gen_movl_rN_T(cpu_T[0], REG(B11_8));
1145 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
1146 gen_op_ldub_T0_T0(ctx);
1147 gen_op_cmp_eq_imm_T0(0);
1148 gen_op_or_imm_T0(0x80);
1149 gen_op_stb_T0_T1(ctx);
1151 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1152 gen_op_movl_fpul_FT0();
1153 gen_op_fmov_FT0_frN(FREG(B11_8));
1155 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1156 gen_op_fmov_frN_FT0(FREG(B11_8));
1157 gen_op_movl_FT0_fpul();
1159 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1160 if (ctx->fpscr & FPSCR_PR) {
1161 if (ctx->opcode & 0x0100)
1162 break; /* illegal instruction */
1164 gen_op_fmov_DT0_drN(DREG(B11_8));
1168 gen_op_fmov_FT0_frN(FREG(B11_8));
1171 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1172 if (ctx->fpscr & FPSCR_PR) {
1173 if (ctx->opcode & 0x0100)
1174 break; /* illegal instruction */
1175 gen_op_fmov_drN_DT0(DREG(B11_8));
1179 gen_op_fmov_frN_FT0(FREG(B11_8));
1183 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1184 gen_op_fneg_frN(FREG(B11_8));
1186 case 0xf05d: /* fabs FRn/DRn */
1187 if (ctx->fpscr & FPSCR_PR) {
1188 if (ctx->opcode & 0x0100)
1189 break; /* illegal instruction */
1190 gen_op_fmov_drN_DT0(DREG(B11_8));
1192 gen_op_fmov_DT0_drN(DREG(B11_8));
1194 gen_op_fmov_frN_FT0(FREG(B11_8));
1196 gen_op_fmov_FT0_frN(FREG(B11_8));
1199 case 0xf06d: /* fsqrt FRn */
1200 if (ctx->fpscr & FPSCR_PR) {
1201 if (ctx->opcode & 0x0100)
1202 break; /* illegal instruction */
1203 gen_op_fmov_drN_DT0(FREG(B11_8));
1205 gen_op_fmov_DT0_drN(FREG(B11_8));
1207 gen_op_fmov_frN_FT0(FREG(B11_8));
1209 gen_op_fmov_FT0_frN(FREG(B11_8));
1212 case 0xf07d: /* fsrra FRn */
1214 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1215 if (!(ctx->fpscr & FPSCR_PR)) {
1216 tcg_gen_movi_i32(cpu_T[0], 0);
1217 gen_op_fmov_T0_frN(FREG(B11_8));
1221 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1222 if (!(ctx->fpscr & FPSCR_PR)) {
1223 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1224 gen_op_fmov_T0_frN(FREG(B11_8));
1228 case 0xf0ad: /* fcnvsd FPUL,DRn */
1229 gen_op_movl_fpul_FT0();
1230 gen_op_fcnvsd_FT_DT();
1231 gen_op_fmov_DT0_drN(DREG(B11_8));
1233 case 0xf0bd: /* fcnvds DRn,FPUL */
1234 gen_op_fmov_drN_DT0(DREG(B11_8));
1235 gen_op_fcnvds_DT_FT();
1236 gen_op_movl_FT0_fpul();
1240 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1241 ctx->opcode, ctx->pc);
1242 gen_op_raise_illegal_instruction();
1243 ctx->bstate = BS_EXCP;
1246 void decode_opc(DisasContext * ctx)
1248 uint32_t old_flags = ctx->flags;
1252 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1253 if (ctx->flags & DELAY_SLOT_CLEARME) {
1254 gen_op_store_flags(0);
1256 /* go out of the delay slot */
1257 uint32_t new_flags = ctx->flags;
1258 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1259 gen_op_store_flags(new_flags);
1262 ctx->bstate = BS_BRANCH;
1263 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1264 gen_delayed_conditional_jump(ctx);
1265 } else if (old_flags & DELAY_SLOT) {
1271 /* go into a delay slot */
1272 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1273 gen_op_store_flags(ctx->flags);
1277 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1281 target_ulong pc_start;
1282 static uint16_t *gen_opc_end;
1288 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1290 ctx.flags = (uint32_t)tb->flags;
1291 ctx.bstate = BS_NONE;
1293 ctx.fpscr = env->fpscr;
1294 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1295 /* We don't know if the delayed pc came from a dynamic or static branch,
1296 so assume it is a dynamic branch. */
1297 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1299 ctx.singlestep_enabled = env->singlestep_enabled;
1302 if (loglevel & CPU_LOG_TB_CPU) {
1304 "------------------------------------------------\n");
1305 cpu_dump_state(env, logfile, fprintf, 0);
1311 max_insns = tb->cflags & CF_COUNT_MASK;
1313 max_insns = CF_COUNT_MASK;
1315 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1316 if (env->nb_breakpoints > 0) {
1317 for (i = 0; i < env->nb_breakpoints; i++) {
1318 if (ctx.pc == env->breakpoints[i]) {
1319 /* We have hit a breakpoint - make sure PC is up-to-date */
1320 gen_op_movl_imm_PC(ctx.pc);
1322 ctx.bstate = BS_EXCP;
1328 i = gen_opc_ptr - gen_opc_buf;
1332 gen_opc_instr_start[ii++] = 0;
1334 gen_opc_pc[ii] = ctx.pc;
1335 gen_opc_hflags[ii] = ctx.flags;
1336 gen_opc_instr_start[ii] = 1;
1337 gen_opc_icount[ii] = num_insns;
1339 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1342 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1345 ctx.opcode = lduw_code(ctx.pc);
1349 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1351 if (env->singlestep_enabled)
1353 if (num_insns >= max_insns)
1355 #ifdef SH4_SINGLE_STEP
1359 if (tb->cflags & CF_LAST_IO)
1361 if (env->singlestep_enabled) {
1364 switch (ctx.bstate) {
1366 /* gen_op_interrupt_restart(); */
1370 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1372 gen_goto_tb(&ctx, 0, ctx.pc);
1375 /* gen_op_interrupt_restart(); */
1384 gen_icount_end(tb, num_insns);
1385 *gen_opc_ptr = INDEX_op_end;
1387 i = gen_opc_ptr - gen_opc_buf;
1390 gen_opc_instr_start[ii++] = 0;
1392 tb->size = ctx.pc - pc_start;
1393 tb->icount = num_insns;
1397 #ifdef SH4_DEBUG_DISAS
1398 if (loglevel & CPU_LOG_TB_IN_ASM)
1399 fprintf(logfile, "\n");
1401 if (loglevel & CPU_LOG_TB_IN_ASM) {
1402 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1403 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1404 fprintf(logfile, "\n");
1409 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1411 gen_intermediate_code_internal(env, tb, 0);
1414 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1416 gen_intermediate_code_internal(env, tb, 1);
1419 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1420 unsigned long searched_pc, int pc_pos, void *puc)
1422 env->pc = gen_opc_pc[pc_pos];
1423 env->flags = gen_opc_hflags[pc_pos];