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];
64 /* dyngen register indexes */
67 #include "gen-icount.h"
69 static void sh4_translate_init(void)
72 static int done_init = 0;
73 static const char * const gregnames[24] = {
74 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
75 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
76 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
77 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
78 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
84 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
85 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
86 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
88 for (i = 0; i < 24; i++)
89 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
90 offsetof(CPUState, gregs[i]),
93 /* register helpers */
95 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
101 #ifdef CONFIG_USER_ONLY
103 #define GEN_OP_LD(width, reg) \
104 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
105 gen_op_ld##width##_T0_##reg##_raw(); \
107 #define GEN_OP_ST(width, reg) \
108 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
109 gen_op_st##width##_##reg##_T1_raw(); \
114 #define GEN_OP_LD(width, reg) \
115 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
116 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
117 else gen_op_ld##width##_T0_##reg##_user();\
119 #define GEN_OP_ST(width, reg) \
120 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
121 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
122 else gen_op_st##width##_##reg##_T1_user();\
140 void cpu_dump_state(CPUState * env, FILE * f,
141 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
145 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
146 env->pc, env->sr, env->pr, env->fpscr);
147 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
148 env->spc, env->ssr, env->gbr, env->vbr);
149 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
150 env->sgr, env->dbr, env->delayed_pc, env->fpul);
151 for (i = 0; i < 24; i += 4) {
152 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
153 i, env->gregs[i], i + 1, env->gregs[i + 1],
154 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
156 if (env->flags & DELAY_SLOT) {
157 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
159 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
160 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
165 void cpu_sh4_reset(CPUSH4State * env)
167 #if defined(CONFIG_USER_ONLY)
168 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
170 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
173 env->pc = 0xA0000000;
174 #if defined(CONFIG_USER_ONLY)
175 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
176 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
178 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
179 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
184 CPUSH4State *cpu_sh4_init(const char *cpu_model)
188 env = qemu_mallocz(sizeof(CPUSH4State));
192 sh4_translate_init();
198 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
200 TranslationBlock *tb;
203 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
204 !ctx->singlestep_enabled) {
205 /* Use a direct jump if in same page and singlestep not enabled */
207 gen_op_movl_imm_PC(dest);
208 tcg_gen_exit_tb((long) tb + n);
210 gen_op_movl_imm_PC(dest);
211 if (ctx->singlestep_enabled)
217 static void gen_jump(DisasContext * ctx)
219 if (ctx->delayed_pc == (uint32_t) - 1) {
220 /* Target is not statically known, it comes necessarily from a
221 delayed jump as immediate jump are conditinal jumps */
222 gen_op_movl_delayed_pc_PC();
223 if (ctx->singlestep_enabled)
227 gen_goto_tb(ctx, 0, ctx->delayed_pc);
231 /* Immediate conditional jump (bt or bf) */
232 static void gen_conditional_jump(DisasContext * ctx,
233 target_ulong ift, target_ulong ifnott)
237 l1 = gen_new_label();
239 gen_goto_tb(ctx, 0, ifnott);
241 gen_goto_tb(ctx, 1, ift);
244 /* Delayed conditional jump (bt or bf) */
245 static void gen_delayed_conditional_jump(DisasContext * ctx)
249 l1 = gen_new_label();
251 gen_goto_tb(ctx, 1, ctx->pc + 2);
256 #define B3_0 (ctx->opcode & 0xf)
257 #define B6_4 ((ctx->opcode >> 4) & 0x7)
258 #define B7_4 ((ctx->opcode >> 4) & 0xf)
259 #define B7_0 (ctx->opcode & 0xff)
260 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
261 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
262 (ctx->opcode & 0xfff))
263 #define B11_8 ((ctx->opcode >> 8) & 0xf)
264 #define B15_12 ((ctx->opcode >> 12) & 0xf)
266 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
269 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
272 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
273 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
274 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
275 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
277 #define CHECK_NOT_DELAY_SLOT \
278 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
279 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
282 void _decode_opc(DisasContext * ctx)
285 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
287 switch (ctx->opcode) {
288 case 0x0019: /* div0u */
291 case 0x000b: /* rts */
292 CHECK_NOT_DELAY_SLOT gen_op_rts();
293 ctx->flags |= DELAY_SLOT;
294 ctx->delayed_pc = (uint32_t) - 1;
296 case 0x0028: /* clrmac */
299 case 0x0048: /* clrs */
302 case 0x0008: /* clrt */
305 case 0x0038: /* ldtlb */
306 #if defined(CONFIG_USER_ONLY)
307 assert(0); /* XXXXX */
312 case 0x002b: /* rte */
313 CHECK_NOT_DELAY_SLOT gen_op_rte();
314 ctx->flags |= DELAY_SLOT;
315 ctx->delayed_pc = (uint32_t) - 1;
317 case 0x0058: /* sets */
320 case 0x0018: /* sett */
323 case 0xfbfd: /* frchg */
325 ctx->bstate = BS_STOP;
327 case 0xf3fd: /* fschg */
329 ctx->bstate = BS_STOP;
331 case 0x0009: /* nop */
333 case 0x001b: /* sleep */
337 gen_op_raise_illegal_instruction();
338 ctx->bstate = BS_EXCP;
343 switch (ctx->opcode & 0xf000) {
344 case 0x1000: /* mov.l Rm,@(disp,Rn) */
345 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
346 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
347 gen_op_addl_imm_T1(B3_0 * 4);
348 gen_op_stl_T0_T1(ctx);
350 case 0x5000: /* mov.l @(disp,Rm),Rn */
351 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
352 gen_op_addl_imm_T0(B3_0 * 4);
353 gen_op_ldl_T0_T0(ctx);
354 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
356 case 0xe000: /* mov #imm,Rn */
357 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
359 case 0x9000: /* mov.w @(disp,PC),Rn */
360 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
361 gen_op_ldw_T0_T0(ctx);
362 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
364 case 0xd000: /* mov.l @(disp,PC),Rn */
365 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
366 gen_op_ldl_T0_T0(ctx);
367 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
369 case 0x7000: /* add #imm,Rn */
370 gen_op_add_imm_rN(B7_0s, REG(B11_8));
372 case 0xa000: /* bra disp */
374 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
375 ctx->flags |= DELAY_SLOT;
377 case 0xb000: /* bsr disp */
379 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
380 ctx->pc + 4 + B11_0s * 2);
381 ctx->flags |= DELAY_SLOT;
385 switch (ctx->opcode & 0xf00f) {
386 case 0x6003: /* mov Rm,Rn */
387 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
388 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
390 case 0x2000: /* mov.b Rm,@Rn */
391 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
392 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
393 gen_op_stb_T0_T1(ctx);
395 case 0x2001: /* mov.w Rm,@Rn */
396 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
397 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
398 gen_op_stw_T0_T1(ctx);
400 case 0x2002: /* mov.l Rm,@Rn */
401 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
402 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
403 gen_op_stl_T0_T1(ctx);
405 case 0x6000: /* mov.b @Rm,Rn */
406 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
407 gen_op_ldb_T0_T0(ctx);
408 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
410 case 0x6001: /* mov.w @Rm,Rn */
411 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
412 gen_op_ldw_T0_T0(ctx);
413 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
415 case 0x6002: /* mov.l @Rm,Rn */
416 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
417 gen_op_ldl_T0_T0(ctx);
418 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
420 case 0x2004: /* mov.b Rm,@-Rn */
421 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
422 gen_op_dec1_rN(REG(B11_8)); /* modify register status */
423 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
424 gen_op_inc1_rN(REG(B11_8)); /* recover register status */
425 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
426 gen_op_dec1_rN(REG(B11_8)); /* modify register status */
428 case 0x2005: /* mov.w Rm,@-Rn */
429 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
430 gen_op_dec2_rN(REG(B11_8));
431 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
432 gen_op_inc2_rN(REG(B11_8));
433 gen_op_stw_T0_T1(ctx);
434 gen_op_dec2_rN(REG(B11_8));
436 case 0x2006: /* mov.l Rm,@-Rn */
437 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
438 gen_op_dec4_rN(REG(B11_8));
439 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
440 gen_op_inc4_rN(REG(B11_8));
441 gen_op_stl_T0_T1(ctx);
442 gen_op_dec4_rN(REG(B11_8));
444 case 0x6004: /* mov.b @Rm+,Rn */
445 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
446 gen_op_ldb_T0_T0(ctx);
447 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
449 gen_op_inc1_rN(REG(B7_4));
451 case 0x6005: /* mov.w @Rm+,Rn */
452 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
453 gen_op_ldw_T0_T0(ctx);
454 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
456 gen_op_inc2_rN(REG(B7_4));
458 case 0x6006: /* mov.l @Rm+,Rn */
459 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
460 gen_op_ldl_T0_T0(ctx);
461 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
463 gen_op_inc4_rN(REG(B7_4));
465 case 0x0004: /* mov.b Rm,@(R0,Rn) */
466 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
467 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
468 gen_op_add_rN_T1(REG(0));
469 gen_op_stb_T0_T1(ctx);
471 case 0x0005: /* mov.w Rm,@(R0,Rn) */
472 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
473 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
474 gen_op_add_rN_T1(REG(0));
475 gen_op_stw_T0_T1(ctx);
477 case 0x0006: /* mov.l Rm,@(R0,Rn) */
478 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
479 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
480 gen_op_add_rN_T1(REG(0));
481 gen_op_stl_T0_T1(ctx);
483 case 0x000c: /* mov.b @(R0,Rm),Rn */
484 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
485 gen_op_add_rN_T0(REG(0));
486 gen_op_ldb_T0_T0(ctx);
487 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
489 case 0x000d: /* mov.w @(R0,Rm),Rn */
490 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
491 gen_op_add_rN_T0(REG(0));
492 gen_op_ldw_T0_T0(ctx);
493 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
495 case 0x000e: /* mov.l @(R0,Rm),Rn */
496 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
497 gen_op_add_rN_T0(REG(0));
498 gen_op_ldl_T0_T0(ctx);
499 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
501 case 0x6008: /* swap.b Rm,Rn */
502 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
504 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
506 case 0x6009: /* swap.w Rm,Rn */
507 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
509 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
511 case 0x200d: /* xtrct Rm,Rn */
512 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
513 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
514 gen_op_xtrct_T0_T1();
515 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
517 case 0x300c: /* add Rm,Rn */
518 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
519 gen_op_add_T0_rN(REG(B11_8));
521 case 0x300e: /* addc Rm,Rn */
522 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
523 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
525 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
527 case 0x300f: /* addv Rm,Rn */
528 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
529 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
531 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
533 case 0x2009: /* and Rm,Rn */
534 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
535 gen_op_and_T0_rN(REG(B11_8));
537 case 0x3000: /* cmp/eq Rm,Rn */
538 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
539 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
540 gen_op_cmp_eq_T0_T1();
542 case 0x3003: /* cmp/ge Rm,Rn */
543 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
544 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
545 gen_op_cmp_ge_T0_T1();
547 case 0x3007: /* cmp/gt Rm,Rn */
548 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
549 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
550 gen_op_cmp_gt_T0_T1();
552 case 0x3006: /* cmp/hi Rm,Rn */
553 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
554 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
555 gen_op_cmp_hi_T0_T1();
557 case 0x3002: /* cmp/hs Rm,Rn */
558 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
560 gen_op_cmp_hs_T0_T1();
562 case 0x200c: /* cmp/str Rm,Rn */
563 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
564 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
565 gen_op_cmp_str_T0_T1();
567 case 0x2007: /* div0s Rm,Rn */
568 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
569 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
570 gen_op_div0s_T0_T1();
572 case 0x3004: /* div1 Rm,Rn */
573 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
574 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
576 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
578 case 0x300d: /* dmuls.l Rm,Rn */
579 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
580 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
581 gen_op_dmulsl_T0_T1();
583 case 0x3005: /* dmulu.l Rm,Rn */
584 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
585 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
586 gen_op_dmulul_T0_T1();
588 case 0x600e: /* exts.b Rm,Rn */
589 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
590 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
591 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
592 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
594 case 0x600f: /* exts.w Rm,Rn */
595 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
596 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
597 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
598 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
600 case 0x600c: /* extu.b Rm,Rn */
601 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
602 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
603 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
605 case 0x600d: /* extu.w Rm,Rn */
606 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
607 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
608 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
610 case 0x000f: /* mac.l @Rm+,@Rn+ */
611 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
612 gen_op_ldl_T0_T0(ctx);
613 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
614 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
615 gen_op_ldl_T0_T0(ctx);
617 gen_op_inc4_rN(REG(B11_8));
618 gen_op_inc4_rN(REG(B7_4));
620 case 0x400f: /* mac.w @Rm+,@Rn+ */
621 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
622 gen_op_ldl_T0_T0(ctx);
623 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
624 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
625 gen_op_ldl_T0_T0(ctx);
627 gen_op_inc2_rN(REG(B11_8));
628 gen_op_inc2_rN(REG(B7_4));
630 case 0x0007: /* mul.l Rm,Rn */
631 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
632 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
635 case 0x200f: /* muls.w Rm,Rn */
636 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
637 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
638 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
639 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
640 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
641 tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
642 gen_op_mulsw_T0_T1();
644 case 0x200e: /* mulu.w Rm,Rn */
645 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
646 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
647 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
648 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
649 gen_op_muluw_T0_T1();
651 case 0x600b: /* neg Rm,Rn */
652 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
654 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
656 case 0x600a: /* negc Rm,Rn */
657 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
659 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
661 case 0x6007: /* not Rm,Rn */
662 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
664 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
666 case 0x200b: /* or Rm,Rn */
667 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
668 gen_op_or_T0_rN(REG(B11_8));
670 case 0x400c: /* shad Rm,Rn */
671 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
672 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
674 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
676 case 0x400d: /* shld Rm,Rn */
677 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
678 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
680 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
682 case 0x3008: /* sub Rm,Rn */
683 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
684 gen_op_sub_T0_rN(REG(B11_8));
686 case 0x300a: /* subc Rm,Rn */
687 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
688 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
690 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
692 case 0x300b: /* subv Rm,Rn */
693 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
694 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
696 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
698 case 0x2008: /* tst Rm,Rn */
699 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
700 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
703 case 0x200a: /* xor Rm,Rn */
704 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
705 gen_op_xor_T0_rN(REG(B11_8));
707 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
708 if (ctx->fpscr & FPSCR_SZ) {
709 gen_op_fmov_drN_DT0(XREG(B7_4));
710 gen_op_fmov_DT0_drN(XREG(B11_8));
712 gen_op_fmov_frN_FT0(FREG(B7_4));
713 gen_op_fmov_FT0_frN(FREG(B11_8));
716 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
717 if (ctx->fpscr & FPSCR_SZ) {
718 gen_op_fmov_drN_DT0(XREG(B7_4));
719 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
720 gen_op_stfq_DT0_T1(ctx);
722 gen_op_fmov_frN_FT0(FREG(B7_4));
723 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
724 gen_op_stfl_FT0_T1(ctx);
727 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
728 if (ctx->fpscr & FPSCR_SZ) {
729 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
730 gen_op_ldfq_T0_DT0(ctx);
731 gen_op_fmov_DT0_drN(XREG(B11_8));
733 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
734 gen_op_ldfl_T0_FT0(ctx);
735 gen_op_fmov_FT0_frN(FREG(B11_8));
738 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
739 if (ctx->fpscr & FPSCR_SZ) {
740 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
741 gen_op_ldfq_T0_DT0(ctx);
742 gen_op_fmov_DT0_drN(XREG(B11_8));
743 gen_op_inc8_rN(REG(B7_4));
745 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
746 gen_op_ldfl_T0_FT0(ctx);
747 gen_op_fmov_FT0_frN(FREG(B11_8));
748 gen_op_inc4_rN(REG(B7_4));
751 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
752 if (ctx->fpscr & FPSCR_SZ) {
753 gen_op_dec8_rN(REG(B11_8));
754 gen_op_fmov_drN_DT0(XREG(B7_4));
755 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
756 gen_op_inc8_rN(REG(B11_8));
757 gen_op_stfq_DT0_T1(ctx);
758 gen_op_dec8_rN(REG(B11_8));
760 gen_op_dec4_rN(REG(B11_8));
761 gen_op_fmov_frN_FT0(FREG(B7_4));
762 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
763 gen_op_inc4_rN(REG(B11_8));
764 gen_op_stfl_FT0_T1(ctx);
765 gen_op_dec4_rN(REG(B11_8));
768 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
769 if (ctx->fpscr & FPSCR_SZ) {
770 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
771 gen_op_add_rN_T0(REG(0));
772 gen_op_ldfq_T0_DT0(ctx);
773 gen_op_fmov_DT0_drN(XREG(B11_8));
775 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
776 gen_op_add_rN_T0(REG(0));
777 gen_op_ldfl_T0_FT0(ctx);
778 gen_op_fmov_FT0_frN(FREG(B11_8));
781 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
782 if (ctx->fpscr & FPSCR_SZ) {
783 gen_op_fmov_drN_DT0(XREG(B7_4));
784 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
785 gen_op_add_rN_T1(REG(0));
786 gen_op_stfq_DT0_T1(ctx);
788 gen_op_fmov_frN_FT0(FREG(B7_4));
789 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
790 gen_op_add_rN_T1(REG(0));
791 gen_op_stfl_FT0_T1(ctx);
794 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
795 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
796 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
797 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
798 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
799 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
800 if (ctx->fpscr & FPSCR_PR) {
801 if (ctx->opcode & 0x0110)
802 break; /* illegal instruction */
803 gen_op_fmov_drN_DT1(DREG(B7_4));
804 gen_op_fmov_drN_DT0(DREG(B11_8));
807 gen_op_fmov_frN_FT1(FREG(B7_4));
808 gen_op_fmov_frN_FT0(FREG(B11_8));
811 switch (ctx->opcode & 0xf00f) {
812 case 0xf000: /* fadd Rm,Rn */
813 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
815 case 0xf001: /* fsub Rm,Rn */
816 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
818 case 0xf002: /* fmul Rm,Rn */
819 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
821 case 0xf003: /* fdiv Rm,Rn */
822 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
824 case 0xf004: /* fcmp/eq Rm,Rn */
825 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
827 case 0xf005: /* fcmp/gt Rm,Rn */
828 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
832 if (ctx->fpscr & FPSCR_PR) {
833 gen_op_fmov_DT0_drN(DREG(B11_8));
836 gen_op_fmov_FT0_frN(FREG(B11_8));
841 switch (ctx->opcode & 0xff00) {
842 case 0xc900: /* and #imm,R0 */
843 gen_op_and_imm_rN(B7_0, REG(0));
845 case 0xcd00: /* and.b #imm,@(R0,GBR) */
846 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
847 gen_op_addl_GBR_T0();
848 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
849 gen_op_ldub_T0_T0(ctx);
850 gen_op_and_imm_T0(B7_0);
851 gen_op_stb_T0_T1(ctx);
853 case 0x8b00: /* bf label */
855 gen_conditional_jump(ctx, ctx->pc + 2,
856 ctx->pc + 4 + B7_0s * 2);
857 ctx->bstate = BS_BRANCH;
859 case 0x8f00: /* bf/s label */
861 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
862 ctx->flags |= DELAY_SLOT_CONDITIONAL;
864 case 0x8900: /* bt label */
866 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
868 ctx->bstate = BS_BRANCH;
870 case 0x8d00: /* bt/s label */
872 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
873 ctx->flags |= DELAY_SLOT_CONDITIONAL;
875 case 0x8800: /* cmp/eq #imm,R0 */
876 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
877 gen_op_cmp_eq_imm_T0(B7_0s);
879 case 0xc400: /* mov.b @(disp,GBR),R0 */
881 gen_op_addl_imm_T0(B7_0);
882 gen_op_ldb_T0_T0(ctx);
883 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
885 case 0xc500: /* mov.w @(disp,GBR),R0 */
887 gen_op_addl_imm_T0(B7_0 * 2);
888 gen_op_ldw_T0_T0(ctx);
889 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
891 case 0xc600: /* mov.l @(disp,GBR),R0 */
893 gen_op_addl_imm_T0(B7_0 * 4);
894 gen_op_ldl_T0_T0(ctx);
895 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
897 case 0xc000: /* mov.b R0,@(disp,GBR) */
899 gen_op_addl_imm_T0(B7_0);
900 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
901 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
902 gen_op_stb_T0_T1(ctx);
904 case 0xc100: /* mov.w R0,@(disp,GBR) */
906 gen_op_addl_imm_T0(B7_0 * 2);
907 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
908 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
909 gen_op_stw_T0_T1(ctx);
911 case 0xc200: /* mov.l R0,@(disp,GBR) */
913 gen_op_addl_imm_T0(B7_0 * 4);
914 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
915 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
916 gen_op_stl_T0_T1(ctx);
918 case 0x8000: /* mov.b R0,@(disp,Rn) */
919 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
920 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
921 gen_op_addl_imm_T1(B3_0);
922 gen_op_stb_T0_T1(ctx);
924 case 0x8100: /* mov.w R0,@(disp,Rn) */
925 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
926 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
927 gen_op_addl_imm_T1(B3_0 * 2);
928 gen_op_stw_T0_T1(ctx);
930 case 0x8400: /* mov.b @(disp,Rn),R0 */
931 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
932 gen_op_addl_imm_T0(B3_0);
933 gen_op_ldb_T0_T0(ctx);
934 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
936 case 0x8500: /* mov.w @(disp,Rn),R0 */
937 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
938 gen_op_addl_imm_T0(B3_0 * 2);
939 gen_op_ldw_T0_T0(ctx);
940 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
942 case 0xc700: /* mova @(disp,PC),R0 */
943 tcg_gen_movi_i32(cpu_gregs[REG(0)],
944 ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
946 case 0xcb00: /* or #imm,R0 */
947 gen_op_or_imm_rN(B7_0, REG(0));
949 case 0xcf00: /* or.b #imm,@(R0,GBR) */
950 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
951 gen_op_addl_GBR_T0();
952 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
953 gen_op_ldub_T0_T0(ctx);
954 gen_op_or_imm_T0(B7_0);
955 gen_op_stb_T0_T1(ctx);
957 case 0xc300: /* trapa #imm */
958 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
960 ctx->bstate = BS_BRANCH;
962 case 0xc800: /* tst #imm,R0 */
963 gen_op_tst_imm_rN(B7_0, REG(0));
965 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
966 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
967 gen_op_addl_GBR_T0();
968 gen_op_ldub_T0_T0(ctx);
969 gen_op_tst_imm_T0(B7_0);
971 case 0xca00: /* xor #imm,R0 */
972 gen_op_xor_imm_rN(B7_0, REG(0));
974 case 0xce00: /* xor.b #imm,@(R0,GBR) */
975 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
976 gen_op_addl_GBR_T0();
977 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
978 gen_op_ldub_T0_T0(ctx);
979 gen_op_xor_imm_T0(B7_0);
980 gen_op_stb_T0_T1(ctx);
984 switch (ctx->opcode & 0xf08f) {
985 case 0x408e: /* ldc Rm,Rn_BANK */
986 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
987 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
989 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
990 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
991 gen_op_ldl_T0_T0(ctx);
992 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
993 gen_op_inc4_rN(REG(B11_8));
995 case 0x0082: /* stc Rm_BANK,Rn */
996 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
997 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
999 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1000 gen_op_dec4_rN(REG(B11_8));
1001 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1002 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1003 gen_op_inc4_rN(REG(B11_8));
1004 gen_op_stl_T0_T1(ctx);
1005 gen_op_dec4_rN(REG(B11_8));
1009 switch (ctx->opcode & 0xf0ff) {
1010 case 0x0023: /* braf Rn */
1011 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1012 gen_op_braf_T0(ctx->pc + 4);
1013 ctx->flags |= DELAY_SLOT;
1014 ctx->delayed_pc = (uint32_t) - 1;
1016 case 0x0003: /* bsrf Rn */
1017 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1018 gen_op_bsrf_T0(ctx->pc + 4);
1019 ctx->flags |= DELAY_SLOT;
1020 ctx->delayed_pc = (uint32_t) - 1;
1022 case 0x4015: /* cmp/pl Rn */
1023 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1026 case 0x4011: /* cmp/pz Rn */
1027 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1030 case 0x4010: /* dt Rn */
1031 gen_op_dt_rN(REG(B11_8));
1033 case 0x402b: /* jmp @Rn */
1034 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1036 ctx->flags |= DELAY_SLOT;
1037 ctx->delayed_pc = (uint32_t) - 1;
1039 case 0x400b: /* jsr @Rn */
1040 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1041 gen_op_jsr_T0(ctx->pc + 4);
1042 ctx->flags |= DELAY_SLOT;
1043 ctx->delayed_pc = (uint32_t) - 1;
1045 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1047 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1048 gen_op_##ldop##_T0_##reg (); \
1052 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1053 gen_op_ldl_T0_T0 (ctx); \
1054 gen_op_inc4_rN (REG(B11_8)); \
1055 gen_op_##ldop##_T0_##reg (); \
1059 gen_op_##stop##_##reg##_T0 (); \
1060 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]); \
1063 gen_op_##stop##_##reg##_T0 (); \
1064 gen_op_dec4_rN (REG(B11_8)); \
1065 tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]); \
1066 gen_op_inc4_rN (REG(B11_8)); \
1067 gen_op_stl_T0_T1 (ctx); \
1068 gen_op_dec4_rN (REG(B11_8)); \
1070 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1072 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1073 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1074 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1075 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1076 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1077 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1078 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1079 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1080 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1081 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1083 case 0x00c3: /* movca.l R0,@Rm */
1084 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1085 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1086 gen_op_stl_T0_T1(ctx);
1088 case 0x0029: /* movt Rn */
1089 gen_op_movt_rN(REG(B11_8));
1091 case 0x0093: /* ocbi @Rn */
1092 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1093 gen_op_ldl_T0_T0(ctx);
1095 case 0x00a3: /* ocbp @Rn */
1096 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1097 gen_op_ldl_T0_T0(ctx);
1099 case 0x00b3: /* ocbwb @Rn */
1100 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1101 gen_op_ldl_T0_T0(ctx);
1103 case 0x0083: /* pref @Rn */
1105 case 0x4024: /* rotcl Rn */
1106 gen_op_rotcl_Rn(REG(B11_8));
1108 case 0x4025: /* rotcr Rn */
1109 gen_op_rotcr_Rn(REG(B11_8));
1111 case 0x4004: /* rotl Rn */
1112 gen_op_rotl_Rn(REG(B11_8));
1114 case 0x4005: /* rotr Rn */
1115 gen_op_rotr_Rn(REG(B11_8));
1117 case 0x4000: /* shll Rn */
1118 case 0x4020: /* shal Rn */
1119 gen_op_shal_Rn(REG(B11_8));
1121 case 0x4021: /* shar Rn */
1122 gen_op_shar_Rn(REG(B11_8));
1124 case 0x4001: /* shlr Rn */
1125 gen_op_shlr_Rn(REG(B11_8));
1127 case 0x4008: /* shll2 Rn */
1128 gen_op_shll2_Rn(REG(B11_8));
1130 case 0x4018: /* shll8 Rn */
1131 gen_op_shll8_Rn(REG(B11_8));
1133 case 0x4028: /* shll16 Rn */
1134 gen_op_shll16_Rn(REG(B11_8));
1136 case 0x4009: /* shlr2 Rn */
1137 gen_op_shlr2_Rn(REG(B11_8));
1139 case 0x4019: /* shlr8 Rn */
1140 gen_op_shlr8_Rn(REG(B11_8));
1142 case 0x4029: /* shlr16 Rn */
1143 gen_op_shlr16_Rn(REG(B11_8));
1145 case 0x401b: /* tas.b @Rn */
1146 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1147 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
1148 gen_op_ldub_T0_T0(ctx);
1149 gen_op_cmp_eq_imm_T0(0);
1150 gen_op_or_imm_T0(0x80);
1151 gen_op_stb_T0_T1(ctx);
1153 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1154 gen_op_movl_fpul_FT0();
1155 gen_op_fmov_FT0_frN(FREG(B11_8));
1157 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1158 gen_op_fmov_frN_FT0(FREG(B11_8));
1159 gen_op_movl_FT0_fpul();
1161 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1162 if (ctx->fpscr & FPSCR_PR) {
1163 if (ctx->opcode & 0x0100)
1164 break; /* illegal instruction */
1166 gen_op_fmov_DT0_drN(DREG(B11_8));
1170 gen_op_fmov_FT0_frN(FREG(B11_8));
1173 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1174 if (ctx->fpscr & FPSCR_PR) {
1175 if (ctx->opcode & 0x0100)
1176 break; /* illegal instruction */
1177 gen_op_fmov_drN_DT0(DREG(B11_8));
1181 gen_op_fmov_frN_FT0(FREG(B11_8));
1185 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1186 gen_op_fneg_frN(FREG(B11_8));
1188 case 0xf05d: /* fabs FRn/DRn */
1189 if (ctx->fpscr & FPSCR_PR) {
1190 if (ctx->opcode & 0x0100)
1191 break; /* illegal instruction */
1192 gen_op_fmov_drN_DT0(DREG(B11_8));
1194 gen_op_fmov_DT0_drN(DREG(B11_8));
1196 gen_op_fmov_frN_FT0(FREG(B11_8));
1198 gen_op_fmov_FT0_frN(FREG(B11_8));
1201 case 0xf06d: /* fsqrt FRn */
1202 if (ctx->fpscr & FPSCR_PR) {
1203 if (ctx->opcode & 0x0100)
1204 break; /* illegal instruction */
1205 gen_op_fmov_drN_DT0(FREG(B11_8));
1207 gen_op_fmov_DT0_drN(FREG(B11_8));
1209 gen_op_fmov_frN_FT0(FREG(B11_8));
1211 gen_op_fmov_FT0_frN(FREG(B11_8));
1214 case 0xf07d: /* fsrra FRn */
1216 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1217 if (!(ctx->fpscr & FPSCR_PR)) {
1218 tcg_gen_movi_i32(cpu_T[0], 0);
1219 gen_op_fmov_T0_frN(FREG(B11_8));
1223 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1224 if (!(ctx->fpscr & FPSCR_PR)) {
1225 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1226 gen_op_fmov_T0_frN(FREG(B11_8));
1230 case 0xf0ad: /* fcnvsd FPUL,DRn */
1231 gen_op_movl_fpul_FT0();
1232 gen_op_fcnvsd_FT_DT();
1233 gen_op_fmov_DT0_drN(DREG(B11_8));
1235 case 0xf0bd: /* fcnvds DRn,FPUL */
1236 gen_op_fmov_drN_DT0(DREG(B11_8));
1237 gen_op_fcnvds_DT_FT();
1238 gen_op_movl_FT0_fpul();
1242 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1243 ctx->opcode, ctx->pc);
1244 gen_op_raise_illegal_instruction();
1245 ctx->bstate = BS_EXCP;
1248 void decode_opc(DisasContext * ctx)
1250 uint32_t old_flags = ctx->flags;
1254 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1255 if (ctx->flags & DELAY_SLOT_CLEARME) {
1256 gen_op_store_flags(0);
1258 /* go out of the delay slot */
1259 uint32_t new_flags = ctx->flags;
1260 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1261 gen_op_store_flags(new_flags);
1264 ctx->bstate = BS_BRANCH;
1265 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1266 gen_delayed_conditional_jump(ctx);
1267 } else if (old_flags & DELAY_SLOT) {
1273 /* go into a delay slot */
1274 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1275 gen_op_store_flags(ctx->flags);
1279 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1283 target_ulong pc_start;
1284 static uint16_t *gen_opc_end;
1290 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1292 ctx.flags = (uint32_t)tb->flags;
1293 ctx.bstate = BS_NONE;
1295 ctx.fpscr = env->fpscr;
1296 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1297 /* We don't know if the delayed pc came from a dynamic or static branch,
1298 so assume it is a dynamic branch. */
1299 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1301 ctx.singlestep_enabled = env->singlestep_enabled;
1304 if (loglevel & CPU_LOG_TB_CPU) {
1306 "------------------------------------------------\n");
1307 cpu_dump_state(env, logfile, fprintf, 0);
1313 max_insns = tb->cflags & CF_COUNT_MASK;
1315 max_insns = CF_COUNT_MASK;
1317 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1318 if (env->nb_breakpoints > 0) {
1319 for (i = 0; i < env->nb_breakpoints; i++) {
1320 if (ctx.pc == env->breakpoints[i]) {
1321 /* We have hit a breakpoint - make sure PC is up-to-date */
1322 gen_op_movl_imm_PC(ctx.pc);
1324 ctx.bstate = BS_EXCP;
1330 i = gen_opc_ptr - gen_opc_buf;
1334 gen_opc_instr_start[ii++] = 0;
1336 gen_opc_pc[ii] = ctx.pc;
1337 gen_opc_hflags[ii] = ctx.flags;
1338 gen_opc_instr_start[ii] = 1;
1339 gen_opc_icount[ii] = num_insns;
1341 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1344 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1347 ctx.opcode = lduw_code(ctx.pc);
1351 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1353 if (env->singlestep_enabled)
1355 if (num_insns >= max_insns)
1357 #ifdef SH4_SINGLE_STEP
1361 if (tb->cflags & CF_LAST_IO)
1363 if (env->singlestep_enabled) {
1366 switch (ctx.bstate) {
1368 /* gen_op_interrupt_restart(); */
1372 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1374 gen_goto_tb(&ctx, 0, ctx.pc);
1377 /* gen_op_interrupt_restart(); */
1386 gen_icount_end(tb, num_insns);
1387 *gen_opc_ptr = INDEX_op_end;
1389 i = gen_opc_ptr - gen_opc_buf;
1392 gen_opc_instr_start[ii++] = 0;
1394 tb->size = ctx.pc - pc_start;
1395 tb->icount = num_insns;
1399 #ifdef SH4_DEBUG_DISAS
1400 if (loglevel & CPU_LOG_TB_IN_ASM)
1401 fprintf(logfile, "\n");
1403 if (loglevel & CPU_LOG_TB_IN_ASM) {
1404 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1405 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1406 fprintf(logfile, "\n");
1411 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1413 gen_intermediate_code_internal(env, tb, 0);
1416 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1418 gen_intermediate_code_internal(env, tb, 1);
1421 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1422 unsigned long searched_pc, int pc_pos, void *puc)
1424 env->pc = gen_opc_pc[pc_pos];
1425 env->flags = gen_opc_hflags[pc_pos];