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;
67 /* dyngen register indexes */
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");
88 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
89 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
91 for (i = 0; i < 24; i++)
92 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
93 offsetof(CPUState, gregs[i]),
96 cpu_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
97 offsetof(CPUState, pc), "PC");
98 cpu_sr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
99 offsetof(CPUState, sr), "SR");
100 cpu_ssr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
101 offsetof(CPUState, ssr), "SSR");
102 cpu_spc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
103 offsetof(CPUState, spc), "SPC");
104 cpu_gbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
105 offsetof(CPUState, gbr), "GBR");
106 cpu_vbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
107 offsetof(CPUState, vbr), "VBR");
108 cpu_sgr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
109 offsetof(CPUState, sgr), "SGR");
110 cpu_dbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
111 offsetof(CPUState, dbr), "DBR");
112 cpu_mach = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
113 offsetof(CPUState, mach), "MACH");
114 cpu_macl = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
115 offsetof(CPUState, macl), "MACL");
116 cpu_pr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
117 offsetof(CPUState, pr), "PR");
118 cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
119 offsetof(CPUState, fpscr), "FPSCR");
120 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
121 offsetof(CPUState, fpul), "FPUL");
123 /* register helpers */
125 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
131 #ifdef CONFIG_USER_ONLY
133 #define GEN_OP_LD(width, reg) \
134 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
135 gen_op_ld##width##_T0_##reg##_raw(); \
137 #define GEN_OP_ST(width, reg) \
138 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
139 gen_op_st##width##_##reg##_T1_raw(); \
144 #define GEN_OP_LD(width, reg) \
145 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
146 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
147 else gen_op_ld##width##_T0_##reg##_user();\
149 #define GEN_OP_ST(width, reg) \
150 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
151 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
152 else gen_op_st##width##_##reg##_T1_user();\
170 void cpu_dump_state(CPUState * env, FILE * f,
171 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
175 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
176 env->pc, env->sr, env->pr, env->fpscr);
177 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
178 env->spc, env->ssr, env->gbr, env->vbr);
179 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
180 env->sgr, env->dbr, env->delayed_pc, env->fpul);
181 for (i = 0; i < 24; i += 4) {
182 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
183 i, env->gregs[i], i + 1, env->gregs[i + 1],
184 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
186 if (env->flags & DELAY_SLOT) {
187 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
189 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
190 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
195 void cpu_sh4_reset(CPUSH4State * env)
197 #if defined(CONFIG_USER_ONLY)
198 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
200 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
203 env->pc = 0xA0000000;
204 #if defined(CONFIG_USER_ONLY)
205 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
206 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
208 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
209 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
214 CPUSH4State *cpu_sh4_init(const char *cpu_model)
218 env = qemu_mallocz(sizeof(CPUSH4State));
222 sh4_translate_init();
228 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
230 TranslationBlock *tb;
233 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
234 !ctx->singlestep_enabled) {
235 /* Use a direct jump if in same page and singlestep not enabled */
237 tcg_gen_movi_i32(cpu_pc, dest);
238 tcg_gen_exit_tb((long) tb + n);
240 tcg_gen_movi_i32(cpu_pc, dest);
241 if (ctx->singlestep_enabled)
247 static void gen_jump(DisasContext * ctx)
249 if (ctx->delayed_pc == (uint32_t) - 1) {
250 /* Target is not statically known, it comes necessarily from a
251 delayed jump as immediate jump are conditinal jumps */
252 gen_op_movl_delayed_pc_PC();
253 if (ctx->singlestep_enabled)
257 gen_goto_tb(ctx, 0, ctx->delayed_pc);
261 /* Immediate conditional jump (bt or bf) */
262 static void gen_conditional_jump(DisasContext * ctx,
263 target_ulong ift, target_ulong ifnott)
267 l1 = gen_new_label();
269 gen_goto_tb(ctx, 0, ifnott);
271 gen_goto_tb(ctx, 1, ift);
274 /* Delayed conditional jump (bt or bf) */
275 static void gen_delayed_conditional_jump(DisasContext * ctx)
279 l1 = gen_new_label();
281 gen_goto_tb(ctx, 1, ctx->pc + 2);
286 static inline void gen_set_t(void)
288 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
291 static inline void gen_clr_t(void)
293 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
296 static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
298 int label1 = gen_new_label();
299 int label2 = gen_new_label();
300 tcg_gen_brcond_i32(cond, t1, t0, label1);
303 gen_set_label(label1);
305 gen_set_label(label2);
308 static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
310 int label1 = gen_new_label();
311 int label2 = gen_new_label();
312 tcg_gen_brcondi_i32(cond, t0, imm, label1);
315 gen_set_label(label1);
317 gen_set_label(label2);
320 #define B3_0 (ctx->opcode & 0xf)
321 #define B6_4 ((ctx->opcode >> 4) & 0x7)
322 #define B7_4 ((ctx->opcode >> 4) & 0xf)
323 #define B7_0 (ctx->opcode & 0xff)
324 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
325 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
326 (ctx->opcode & 0xfff))
327 #define B11_8 ((ctx->opcode >> 8) & 0xf)
328 #define B15_12 ((ctx->opcode >> 12) & 0xf)
330 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
333 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
336 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
337 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
338 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
339 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
341 #define CHECK_NOT_DELAY_SLOT \
342 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
343 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
346 void _decode_opc(DisasContext * ctx)
349 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
351 switch (ctx->opcode) {
352 case 0x0019: /* div0u */
353 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
355 case 0x000b: /* rts */
356 CHECK_NOT_DELAY_SLOT gen_op_rts();
357 ctx->flags |= DELAY_SLOT;
358 ctx->delayed_pc = (uint32_t) - 1;
360 case 0x0028: /* clrmac */
361 tcg_gen_movi_i32(cpu_mach, 0);
362 tcg_gen_movi_i32(cpu_macl, 0);
364 case 0x0048: /* clrs */
365 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
367 case 0x0008: /* clrt */
370 case 0x0038: /* ldtlb */
371 #if defined(CONFIG_USER_ONLY)
372 assert(0); /* XXXXX */
377 case 0x002b: /* rte */
378 CHECK_NOT_DELAY_SLOT gen_op_rte();
379 ctx->flags |= DELAY_SLOT;
380 ctx->delayed_pc = (uint32_t) - 1;
382 case 0x0058: /* sets */
383 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
385 case 0x0018: /* sett */
388 case 0xfbfd: /* frchg */
390 ctx->bstate = BS_STOP;
392 case 0xf3fd: /* fschg */
394 ctx->bstate = BS_STOP;
396 case 0x0009: /* nop */
398 case 0x001b: /* sleep */
402 gen_op_raise_illegal_instruction();
403 ctx->bstate = BS_EXCP;
408 switch (ctx->opcode & 0xf000) {
409 case 0x1000: /* mov.l Rm,@(disp,Rn) */
410 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
411 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
412 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 4);
413 gen_op_stl_T0_T1(ctx);
415 case 0x5000: /* mov.l @(disp,Rm),Rn */
416 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
417 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 4);
418 gen_op_ldl_T0_T0(ctx);
419 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
421 case 0xe000: /* mov #imm,Rn */
422 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
424 case 0x9000: /* mov.w @(disp,PC),Rn */
425 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
426 gen_op_ldw_T0_T0(ctx);
427 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
429 case 0xd000: /* mov.l @(disp,PC),Rn */
430 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
431 gen_op_ldl_T0_T0(ctx);
432 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
434 case 0x7000: /* add #imm,Rn */
435 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], B7_0s);
437 case 0xa000: /* bra disp */
439 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
440 ctx->flags |= DELAY_SLOT;
442 case 0xb000: /* bsr disp */
444 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
445 ctx->pc + 4 + B11_0s * 2);
446 ctx->flags |= DELAY_SLOT;
450 switch (ctx->opcode & 0xf00f) {
451 case 0x6003: /* mov Rm,Rn */
452 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
453 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
455 case 0x2000: /* mov.b Rm,@Rn */
456 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
457 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
458 gen_op_stb_T0_T1(ctx);
460 case 0x2001: /* mov.w Rm,@Rn */
461 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
462 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
463 gen_op_stw_T0_T1(ctx);
465 case 0x2002: /* mov.l Rm,@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_stl_T0_T1(ctx);
470 case 0x6000: /* mov.b @Rm,Rn */
471 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
472 gen_op_ldb_T0_T0(ctx);
473 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
475 case 0x6001: /* mov.w @Rm,Rn */
476 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
477 gen_op_ldw_T0_T0(ctx);
478 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
480 case 0x6002: /* mov.l @Rm,Rn */
481 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
482 gen_op_ldl_T0_T0(ctx);
483 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
485 case 0x2004: /* mov.b Rm,@-Rn */
486 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
487 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
488 cpu_gregs[REG(B11_8)], 1); /* modify register status */
489 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
490 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
491 cpu_gregs[REG(B11_8)], 1); /* recover register status */
492 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
493 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
494 cpu_gregs[REG(B11_8)], 1); /* modify register status */
496 case 0x2005: /* mov.w Rm,@-Rn */
497 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
498 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
499 cpu_gregs[REG(B11_8)], 2);
500 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
501 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
502 cpu_gregs[REG(B11_8)], 2);
503 gen_op_stw_T0_T1(ctx);
504 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
505 cpu_gregs[REG(B11_8)], 2);
507 case 0x2006: /* mov.l Rm,@-Rn */
508 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
509 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
510 cpu_gregs[REG(B11_8)], 4);
511 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
512 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
513 cpu_gregs[REG(B11_8)], 4);
514 gen_op_stl_T0_T1(ctx);
515 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
516 cpu_gregs[REG(B11_8)], 4);
518 case 0x6004: /* mov.b @Rm+,Rn */
519 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
520 gen_op_ldb_T0_T0(ctx);
521 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
523 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
524 cpu_gregs[REG(B7_4)], 1);
526 case 0x6005: /* mov.w @Rm+,Rn */
527 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
528 gen_op_ldw_T0_T0(ctx);
529 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
531 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
532 cpu_gregs[REG(B7_4)], 2);
534 case 0x6006: /* mov.l @Rm+,Rn */
535 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
536 gen_op_ldl_T0_T0(ctx);
537 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
539 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
540 cpu_gregs[REG(B7_4)], 4);
542 case 0x0004: /* mov.b Rm,@(R0,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 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
546 gen_op_stb_T0_T1(ctx);
548 case 0x0005: /* mov.w Rm,@(R0,Rn) */
549 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
550 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
551 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
552 gen_op_stw_T0_T1(ctx);
554 case 0x0006: /* mov.l Rm,@(R0,Rn) */
555 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
556 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
557 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
558 gen_op_stl_T0_T1(ctx);
560 case 0x000c: /* mov.b @(R0,Rm),Rn */
561 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
562 gen_op_ldb_T0_T0(ctx);
563 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
565 case 0x000d: /* mov.w @(R0,Rm),Rn */
566 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
567 gen_op_ldw_T0_T0(ctx);
568 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
570 case 0x000e: /* mov.l @(R0,Rm),Rn */
571 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
572 gen_op_ldl_T0_T0(ctx);
573 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
575 case 0x6008: /* swap.b Rm,Rn */
576 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], 0xffff0000);
577 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xff);
578 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
579 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
580 tcg_gen_shri_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 8);
581 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
582 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
584 case 0x6009: /* swap.w Rm,Rn */
585 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
586 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
587 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B7_4)], 16);
588 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
589 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
591 case 0x200d: /* xtrct Rm,Rn */
592 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
593 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
594 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 16);
595 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
596 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
598 case 0x300c: /* add Rm,Rn */
599 tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
601 case 0x300e: /* addc Rm,Rn */
602 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
603 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
605 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
607 case 0x300f: /* addv Rm,Rn */
608 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
609 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
611 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
613 case 0x2009: /* and Rm,Rn */
614 tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
616 case 0x3000: /* cmp/eq Rm,Rn */
617 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
618 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
619 gen_cmp(TCG_COND_EQ, cpu_T[0], cpu_T[1]);
621 case 0x3003: /* cmp/ge Rm,Rn */
622 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
623 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
624 gen_cmp(TCG_COND_GE, cpu_T[0], cpu_T[1]);
626 case 0x3007: /* cmp/gt Rm,Rn */
627 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
628 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
629 gen_cmp(TCG_COND_GT, cpu_T[0], cpu_T[1]);
631 case 0x3006: /* cmp/hi Rm,Rn */
632 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
633 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
634 gen_cmp(TCG_COND_GTU, cpu_T[0], cpu_T[1]);
636 case 0x3002: /* cmp/hs Rm,Rn */
637 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
638 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
639 gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]);
641 case 0x200c: /* cmp/str Rm,Rn */
642 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
643 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
644 gen_op_cmp_str_T0_T1();
646 case 0x2007: /* div0s Rm,Rn */
647 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
648 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
649 gen_op_div0s_T0_T1();
651 case 0x3004: /* div1 Rm,Rn */
652 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
653 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
655 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
657 case 0x300d: /* dmuls.l Rm,Rn */
658 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
659 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
660 gen_op_dmulsl_T0_T1();
662 case 0x3005: /* dmulu.l Rm,Rn */
663 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
664 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
665 gen_op_dmulul_T0_T1();
667 case 0x600e: /* exts.b Rm,Rn */
668 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
669 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
670 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
671 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
673 case 0x600f: /* exts.w Rm,Rn */
674 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
675 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
676 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
677 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
679 case 0x600c: /* extu.b Rm,Rn */
680 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
681 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
682 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
684 case 0x600d: /* extu.w Rm,Rn */
685 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
686 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
687 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
689 case 0x000f: /* mac.l @Rm+,@Rn+ */
690 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
691 gen_op_ldl_T0_T0(ctx);
692 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
693 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
694 gen_op_ldl_T0_T0(ctx);
696 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
697 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
699 case 0x400f: /* mac.w @Rm+,@Rn+ */
700 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
701 gen_op_ldl_T0_T0(ctx);
702 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
703 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
704 gen_op_ldl_T0_T0(ctx);
706 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
707 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
709 case 0x0007: /* mul.l Rm,Rn */
710 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
711 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
714 case 0x200f: /* muls.w Rm,Rn */
715 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
716 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
717 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
718 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
719 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
720 tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
721 gen_op_mulsw_T0_T1();
723 case 0x200e: /* mulu.w Rm,Rn */
724 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
725 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
726 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
727 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
728 gen_op_muluw_T0_T1();
730 case 0x600b: /* neg Rm,Rn */
731 tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
733 case 0x600a: /* negc Rm,Rn */
734 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
736 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
738 case 0x6007: /* not Rm,Rn */
739 tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
741 case 0x200b: /* or Rm,Rn */
742 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
744 case 0x400c: /* shad Rm,Rn */
745 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
746 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
748 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
750 case 0x400d: /* shld Rm,Rn */
751 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
752 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
754 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
756 case 0x3008: /* sub Rm,Rn */
757 tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
759 case 0x300a: /* subc Rm,Rn */
760 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
761 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
763 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
765 case 0x300b: /* subv Rm,Rn */
766 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
767 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
769 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
771 case 0x2008: /* tst Rm,Rn */
772 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
773 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
774 tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
775 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
777 case 0x200a: /* xor Rm,Rn */
778 tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
780 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
781 if (ctx->fpscr & FPSCR_SZ) {
782 gen_op_fmov_drN_DT0(XREG(B7_4));
783 gen_op_fmov_DT0_drN(XREG(B11_8));
785 gen_op_fmov_frN_FT0(FREG(B7_4));
786 gen_op_fmov_FT0_frN(FREG(B11_8));
789 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
790 if (ctx->fpscr & FPSCR_SZ) {
791 gen_op_fmov_drN_DT0(XREG(B7_4));
792 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
793 gen_op_stfq_DT0_T1(ctx);
795 gen_op_fmov_frN_FT0(FREG(B7_4));
796 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
797 gen_op_stfl_FT0_T1(ctx);
800 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
801 if (ctx->fpscr & FPSCR_SZ) {
802 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
803 gen_op_ldfq_T0_DT0(ctx);
804 gen_op_fmov_DT0_drN(XREG(B11_8));
806 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
807 gen_op_ldfl_T0_FT0(ctx);
808 gen_op_fmov_FT0_frN(FREG(B11_8));
811 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
812 if (ctx->fpscr & FPSCR_SZ) {
813 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
814 gen_op_ldfq_T0_DT0(ctx);
815 gen_op_fmov_DT0_drN(XREG(B11_8));
816 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
817 cpu_gregs[REG(B7_4)], 8);
819 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
820 gen_op_ldfl_T0_FT0(ctx);
821 gen_op_fmov_FT0_frN(FREG(B11_8));
822 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
823 cpu_gregs[REG(B7_4)], 4);
826 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
827 if (ctx->fpscr & FPSCR_SZ) {
828 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
829 gen_op_fmov_drN_DT0(XREG(B7_4));
830 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
831 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
832 gen_op_stfq_DT0_T1(ctx);
833 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
835 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
836 gen_op_fmov_frN_FT0(FREG(B7_4));
837 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
838 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
839 gen_op_stfl_FT0_T1(ctx);
840 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
843 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
844 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
845 if (ctx->fpscr & FPSCR_SZ) {
846 gen_op_ldfq_T0_DT0(ctx);
847 gen_op_fmov_DT0_drN(XREG(B11_8));
849 gen_op_ldfl_T0_FT0(ctx);
850 gen_op_fmov_FT0_frN(FREG(B11_8));
853 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
854 if (ctx->fpscr & FPSCR_SZ) {
855 gen_op_fmov_drN_DT0(XREG(B7_4));
856 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
857 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
858 gen_op_stfq_DT0_T1(ctx);
860 gen_op_fmov_frN_FT0(FREG(B7_4));
861 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
862 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
863 gen_op_stfl_FT0_T1(ctx);
866 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
867 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
868 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
869 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
870 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
871 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
872 if (ctx->fpscr & FPSCR_PR) {
873 if (ctx->opcode & 0x0110)
874 break; /* illegal instruction */
875 gen_op_fmov_drN_DT1(DREG(B7_4));
876 gen_op_fmov_drN_DT0(DREG(B11_8));
879 gen_op_fmov_frN_FT1(FREG(B7_4));
880 gen_op_fmov_frN_FT0(FREG(B11_8));
883 switch (ctx->opcode & 0xf00f) {
884 case 0xf000: /* fadd Rm,Rn */
885 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
887 case 0xf001: /* fsub Rm,Rn */
888 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
890 case 0xf002: /* fmul Rm,Rn */
891 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
893 case 0xf003: /* fdiv Rm,Rn */
894 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
896 case 0xf004: /* fcmp/eq Rm,Rn */
897 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
899 case 0xf005: /* fcmp/gt Rm,Rn */
900 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
904 if (ctx->fpscr & FPSCR_PR) {
905 gen_op_fmov_DT0_drN(DREG(B11_8));
908 gen_op_fmov_FT0_frN(FREG(B11_8));
913 switch (ctx->opcode & 0xff00) {
914 case 0xc900: /* and #imm,R0 */
915 tcg_gen_andi_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
917 case 0xcd00: /* and.b #imm,@(R0,GBR) */
918 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
919 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
920 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
921 gen_op_ldub_T0_T0(ctx);
922 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
923 gen_op_stb_T0_T1(ctx);
925 case 0x8b00: /* bf label */
927 gen_conditional_jump(ctx, ctx->pc + 2,
928 ctx->pc + 4 + B7_0s * 2);
929 ctx->bstate = BS_BRANCH;
931 case 0x8f00: /* bf/s label */
933 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
934 ctx->flags |= DELAY_SLOT_CONDITIONAL;
936 case 0x8900: /* bt label */
938 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
940 ctx->bstate = BS_BRANCH;
942 case 0x8d00: /* bt/s label */
944 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
945 ctx->flags |= DELAY_SLOT_CONDITIONAL;
947 case 0x8800: /* cmp/eq #imm,R0 */
948 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
949 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], B7_0s);
951 case 0xc400: /* mov.b @(disp,GBR),R0 */
953 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
954 gen_op_ldb_T0_T0(ctx);
955 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
957 case 0xc500: /* mov.w @(disp,GBR),R0 */
959 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
960 gen_op_ldw_T0_T0(ctx);
961 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
963 case 0xc600: /* mov.l @(disp,GBR),R0 */
965 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
966 gen_op_ldl_T0_T0(ctx);
967 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
969 case 0xc000: /* mov.b R0,@(disp,GBR) */
971 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
972 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
973 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
974 gen_op_stb_T0_T1(ctx);
976 case 0xc100: /* mov.w R0,@(disp,GBR) */
978 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
979 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
980 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
981 gen_op_stw_T0_T1(ctx);
983 case 0xc200: /* mov.l R0,@(disp,GBR) */
985 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
986 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
987 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
988 gen_op_stl_T0_T1(ctx);
990 case 0x8000: /* mov.b R0,@(disp,Rn) */
991 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
992 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
993 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0);
994 gen_op_stb_T0_T1(ctx);
996 case 0x8100: /* mov.w R0,@(disp,Rn) */
997 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
998 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
999 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 2);
1000 gen_op_stw_T0_T1(ctx);
1002 case 0x8400: /* mov.b @(disp,Rn),R0 */
1003 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
1004 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0);
1005 gen_op_ldb_T0_T0(ctx);
1006 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1008 case 0x8500: /* mov.w @(disp,Rn),R0 */
1009 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
1010 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 2);
1011 gen_op_ldw_T0_T0(ctx);
1012 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1014 case 0xc700: /* mova @(disp,PC),R0 */
1015 tcg_gen_movi_i32(cpu_gregs[REG(0)],
1016 ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1018 case 0xcb00: /* or #imm,R0 */
1019 tcg_gen_ori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1021 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1022 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1023 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1024 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
1025 gen_op_ldub_T0_T0(ctx);
1026 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
1027 gen_op_stb_T0_T1(ctx);
1029 case 0xc300: /* trapa #imm */
1030 CHECK_NOT_DELAY_SLOT tcg_gen_movi_i32(cpu_pc, ctx->pc);
1032 ctx->bstate = BS_BRANCH;
1034 case 0xc800: /* tst #imm,R0 */
1035 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(0)], B7_0);
1036 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1038 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1039 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1040 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1041 gen_op_ldub_T0_T0(ctx);
1042 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
1043 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1045 case 0xca00: /* xor #imm,R0 */
1046 tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1048 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1049 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1050 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1051 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1052 gen_op_ldub_T0_T0(ctx);
1053 tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
1054 gen_op_stb_T0_T1(ctx);
1058 switch (ctx->opcode & 0xf08f) {
1059 case 0x408e: /* ldc Rm,Rn_BANK */
1060 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1061 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1063 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1064 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1065 gen_op_ldl_T0_T0(ctx);
1066 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1067 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1069 case 0x0082: /* stc Rm_BANK,Rn */
1070 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1071 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
1073 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1074 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1075 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1076 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1077 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1078 gen_op_stl_T0_T1(ctx);
1079 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1083 switch (ctx->opcode & 0xf0ff) {
1084 case 0x0023: /* braf Rn */
1085 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1086 gen_op_braf_T0(ctx->pc + 4);
1087 ctx->flags |= DELAY_SLOT;
1088 ctx->delayed_pc = (uint32_t) - 1;
1090 case 0x0003: /* bsrf Rn */
1091 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1092 gen_op_bsrf_T0(ctx->pc + 4);
1093 ctx->flags |= DELAY_SLOT;
1094 ctx->delayed_pc = (uint32_t) - 1;
1096 case 0x4015: /* cmp/pl Rn */
1097 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1098 gen_cmp_imm(TCG_COND_GT, cpu_T[0], 0);
1100 case 0x4011: /* cmp/pz Rn */
1101 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1102 gen_cmp_imm(TCG_COND_GE, cpu_T[0], 0);
1104 case 0x4010: /* dt Rn */
1105 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1106 gen_cmp_imm(TCG_COND_EQ, cpu_gregs[REG(B11_8)], 0);
1108 case 0x402b: /* jmp @Rn */
1109 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1111 ctx->flags |= DELAY_SLOT;
1112 ctx->delayed_pc = (uint32_t) - 1;
1114 case 0x400b: /* jsr @Rn */
1115 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1116 gen_op_jsr_T0(ctx->pc + 4);
1117 ctx->flags |= DELAY_SLOT;
1118 ctx->delayed_pc = (uint32_t) - 1;
1120 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1122 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1123 gen_op_##ldop##_T0_##reg (); \
1127 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1128 gen_op_ldl_T0_T0 (ctx); \
1129 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1130 cpu_gregs[REG(B11_8)], 4); \
1131 gen_op_##ldop##_T0_##reg (); \
1135 gen_op_##stop##_##reg##_T0 (); \
1136 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]); \
1139 gen_op_##stop##_##reg##_T0 (); \
1140 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1141 cpu_gregs[REG(B11_8)], 4); \
1142 tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]); \
1143 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1144 cpu_gregs[REG(B11_8)], 4); \
1145 gen_op_stl_T0_T1 (ctx); \
1146 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1147 cpu_gregs[REG(B11_8)], 4); \
1149 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1151 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1152 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1153 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1154 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1155 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1156 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1157 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1158 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1159 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1160 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1162 case 0x00c3: /* movca.l R0,@Rm */
1163 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1164 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1165 gen_op_stl_T0_T1(ctx);
1167 case 0x0029: /* movt Rn */
1168 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_sr, SR_T);
1170 case 0x0093: /* ocbi @Rn */
1171 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1172 gen_op_ldl_T0_T0(ctx);
1174 case 0x00a3: /* ocbp @Rn */
1175 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1176 gen_op_ldl_T0_T0(ctx);
1178 case 0x00b3: /* ocbwb @Rn */
1179 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1180 gen_op_ldl_T0_T0(ctx);
1182 case 0x0083: /* pref @Rn */
1184 case 0x4024: /* rotcl Rn */
1185 gen_op_rotcl_Rn(REG(B11_8));
1187 case 0x4025: /* rotcr Rn */
1188 gen_op_rotcr_Rn(REG(B11_8));
1190 case 0x4004: /* rotl Rn */
1191 gen_op_rotl_Rn(REG(B11_8));
1193 case 0x4005: /* rotr Rn */
1194 gen_op_rotr_Rn(REG(B11_8));
1196 case 0x4000: /* shll Rn */
1197 case 0x4020: /* shal Rn */
1198 gen_op_shal_Rn(REG(B11_8));
1200 case 0x4021: /* shar Rn */
1201 gen_op_shar_Rn(REG(B11_8));
1203 case 0x4001: /* shlr Rn */
1204 gen_op_shlr_Rn(REG(B11_8));
1206 case 0x4008: /* shll2 Rn */
1207 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1209 case 0x4018: /* shll8 Rn */
1210 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1212 case 0x4028: /* shll16 Rn */
1213 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1215 case 0x4009: /* shlr2 Rn */
1216 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1218 case 0x4019: /* shlr8 Rn */
1219 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1221 case 0x4029: /* shlr16 Rn */
1222 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1224 case 0x401b: /* tas.b @Rn */
1225 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1226 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1227 gen_op_ldub_T0_T0(ctx);
1228 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1229 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
1230 gen_op_stb_T0_T1(ctx);
1232 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1233 gen_op_movl_fpul_FT0();
1234 gen_op_fmov_FT0_frN(FREG(B11_8));
1236 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1237 gen_op_fmov_frN_FT0(FREG(B11_8));
1238 gen_op_movl_FT0_fpul();
1240 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1241 if (ctx->fpscr & FPSCR_PR) {
1242 if (ctx->opcode & 0x0100)
1243 break; /* illegal instruction */
1245 gen_op_fmov_DT0_drN(DREG(B11_8));
1249 gen_op_fmov_FT0_frN(FREG(B11_8));
1252 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1253 if (ctx->fpscr & FPSCR_PR) {
1254 if (ctx->opcode & 0x0100)
1255 break; /* illegal instruction */
1256 gen_op_fmov_drN_DT0(DREG(B11_8));
1260 gen_op_fmov_frN_FT0(FREG(B11_8));
1264 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1265 gen_op_fneg_frN(FREG(B11_8));
1267 case 0xf05d: /* fabs FRn/DRn */
1268 if (ctx->fpscr & FPSCR_PR) {
1269 if (ctx->opcode & 0x0100)
1270 break; /* illegal instruction */
1271 gen_op_fmov_drN_DT0(DREG(B11_8));
1273 gen_op_fmov_DT0_drN(DREG(B11_8));
1275 gen_op_fmov_frN_FT0(FREG(B11_8));
1277 gen_op_fmov_FT0_frN(FREG(B11_8));
1280 case 0xf06d: /* fsqrt FRn */
1281 if (ctx->fpscr & FPSCR_PR) {
1282 if (ctx->opcode & 0x0100)
1283 break; /* illegal instruction */
1284 gen_op_fmov_drN_DT0(FREG(B11_8));
1286 gen_op_fmov_DT0_drN(FREG(B11_8));
1288 gen_op_fmov_frN_FT0(FREG(B11_8));
1290 gen_op_fmov_FT0_frN(FREG(B11_8));
1293 case 0xf07d: /* fsrra FRn */
1295 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1296 if (!(ctx->fpscr & FPSCR_PR)) {
1297 tcg_gen_movi_i32(cpu_T[0], 0);
1298 gen_op_fmov_T0_frN(FREG(B11_8));
1302 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1303 if (!(ctx->fpscr & FPSCR_PR)) {
1304 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1305 gen_op_fmov_T0_frN(FREG(B11_8));
1309 case 0xf0ad: /* fcnvsd FPUL,DRn */
1310 gen_op_movl_fpul_FT0();
1311 gen_op_fcnvsd_FT_DT();
1312 gen_op_fmov_DT0_drN(DREG(B11_8));
1314 case 0xf0bd: /* fcnvds DRn,FPUL */
1315 gen_op_fmov_drN_DT0(DREG(B11_8));
1316 gen_op_fcnvds_DT_FT();
1317 gen_op_movl_FT0_fpul();
1321 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1322 ctx->opcode, ctx->pc);
1323 gen_op_raise_illegal_instruction();
1324 ctx->bstate = BS_EXCP;
1327 void decode_opc(DisasContext * ctx)
1329 uint32_t old_flags = ctx->flags;
1333 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1334 if (ctx->flags & DELAY_SLOT_CLEARME) {
1335 gen_op_store_flags(0);
1337 /* go out of the delay slot */
1338 uint32_t new_flags = ctx->flags;
1339 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1340 gen_op_store_flags(new_flags);
1343 ctx->bstate = BS_BRANCH;
1344 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1345 gen_delayed_conditional_jump(ctx);
1346 } else if (old_flags & DELAY_SLOT) {
1352 /* go into a delay slot */
1353 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1354 gen_op_store_flags(ctx->flags);
1358 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1362 target_ulong pc_start;
1363 static uint16_t *gen_opc_end;
1369 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1371 ctx.flags = (uint32_t)tb->flags;
1372 ctx.bstate = BS_NONE;
1374 ctx.fpscr = env->fpscr;
1375 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1376 /* We don't know if the delayed pc came from a dynamic or static branch,
1377 so assume it is a dynamic branch. */
1378 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1380 ctx.singlestep_enabled = env->singlestep_enabled;
1383 if (loglevel & CPU_LOG_TB_CPU) {
1385 "------------------------------------------------\n");
1386 cpu_dump_state(env, logfile, fprintf, 0);
1392 max_insns = tb->cflags & CF_COUNT_MASK;
1394 max_insns = CF_COUNT_MASK;
1396 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1397 if (env->nb_breakpoints > 0) {
1398 for (i = 0; i < env->nb_breakpoints; i++) {
1399 if (ctx.pc == env->breakpoints[i]) {
1400 /* We have hit a breakpoint - make sure PC is up-to-date */
1401 tcg_gen_movi_i32(cpu_pc, ctx.pc);
1403 ctx.bstate = BS_EXCP;
1409 i = gen_opc_ptr - gen_opc_buf;
1413 gen_opc_instr_start[ii++] = 0;
1415 gen_opc_pc[ii] = ctx.pc;
1416 gen_opc_hflags[ii] = ctx.flags;
1417 gen_opc_instr_start[ii] = 1;
1418 gen_opc_icount[ii] = num_insns;
1420 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1423 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1426 ctx.opcode = lduw_code(ctx.pc);
1430 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1432 if (env->singlestep_enabled)
1434 if (num_insns >= max_insns)
1436 #ifdef SH4_SINGLE_STEP
1440 if (tb->cflags & CF_LAST_IO)
1442 if (env->singlestep_enabled) {
1445 switch (ctx.bstate) {
1447 /* gen_op_interrupt_restart(); */
1451 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1453 gen_goto_tb(&ctx, 0, ctx.pc);
1456 /* gen_op_interrupt_restart(); */
1465 gen_icount_end(tb, num_insns);
1466 *gen_opc_ptr = INDEX_op_end;
1468 i = gen_opc_ptr - gen_opc_buf;
1471 gen_opc_instr_start[ii++] = 0;
1473 tb->size = ctx.pc - pc_start;
1474 tb->icount = num_insns;
1478 #ifdef SH4_DEBUG_DISAS
1479 if (loglevel & CPU_LOG_TB_IN_ASM)
1480 fprintf(logfile, "\n");
1482 if (loglevel & CPU_LOG_TB_IN_ASM) {
1483 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1484 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1485 fprintf(logfile, "\n");
1490 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1492 gen_intermediate_code_internal(env, tb, 0);
1495 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1497 gen_intermediate_code_internal(env, tb, 1);
1500 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1501 unsigned long searched_pc, int pc_pos, void *puc)
1503 env->pc = gen_opc_pc[pc_pos];
1504 env->flags = gen_opc_hflags[pc_pos];