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 #define B3_0 (ctx->opcode & 0xf)
287 #define B6_4 ((ctx->opcode >> 4) & 0x7)
288 #define B7_4 ((ctx->opcode >> 4) & 0xf)
289 #define B7_0 (ctx->opcode & 0xff)
290 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
291 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
292 (ctx->opcode & 0xfff))
293 #define B11_8 ((ctx->opcode >> 8) & 0xf)
294 #define B15_12 ((ctx->opcode >> 12) & 0xf)
296 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
299 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
302 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
303 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
304 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
305 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
307 #define CHECK_NOT_DELAY_SLOT \
308 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
309 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
312 void _decode_opc(DisasContext * ctx)
315 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
317 switch (ctx->opcode) {
318 case 0x0019: /* div0u */
319 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
321 case 0x000b: /* rts */
322 CHECK_NOT_DELAY_SLOT gen_op_rts();
323 ctx->flags |= DELAY_SLOT;
324 ctx->delayed_pc = (uint32_t) - 1;
326 case 0x0028: /* clrmac */
327 tcg_gen_movi_i32(cpu_mach, 0);
328 tcg_gen_movi_i32(cpu_macl, 0);
330 case 0x0048: /* clrs */
331 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
333 case 0x0008: /* clrt */
334 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
336 case 0x0038: /* ldtlb */
337 #if defined(CONFIG_USER_ONLY)
338 assert(0); /* XXXXX */
343 case 0x002b: /* rte */
344 CHECK_NOT_DELAY_SLOT gen_op_rte();
345 ctx->flags |= DELAY_SLOT;
346 ctx->delayed_pc = (uint32_t) - 1;
348 case 0x0058: /* sets */
349 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
351 case 0x0018: /* sett */
352 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
354 case 0xfbfd: /* frchg */
356 ctx->bstate = BS_STOP;
358 case 0xf3fd: /* fschg */
360 ctx->bstate = BS_STOP;
362 case 0x0009: /* nop */
364 case 0x001b: /* sleep */
368 gen_op_raise_illegal_instruction();
369 ctx->bstate = BS_EXCP;
374 switch (ctx->opcode & 0xf000) {
375 case 0x1000: /* mov.l Rm,@(disp,Rn) */
376 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
377 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
378 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 4);
379 gen_op_stl_T0_T1(ctx);
381 case 0x5000: /* mov.l @(disp,Rm),Rn */
382 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
383 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 4);
384 gen_op_ldl_T0_T0(ctx);
385 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
387 case 0xe000: /* mov #imm,Rn */
388 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
390 case 0x9000: /* mov.w @(disp,PC),Rn */
391 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
392 gen_op_ldw_T0_T0(ctx);
393 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
395 case 0xd000: /* mov.l @(disp,PC),Rn */
396 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
397 gen_op_ldl_T0_T0(ctx);
398 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
400 case 0x7000: /* add #imm,Rn */
401 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], B7_0s);
403 case 0xa000: /* bra disp */
405 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
406 ctx->flags |= DELAY_SLOT;
408 case 0xb000: /* bsr disp */
410 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
411 ctx->pc + 4 + B11_0s * 2);
412 ctx->flags |= DELAY_SLOT;
416 switch (ctx->opcode & 0xf00f) {
417 case 0x6003: /* mov Rm,Rn */
418 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
419 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
421 case 0x2000: /* mov.b Rm,@Rn */
422 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
423 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
424 gen_op_stb_T0_T1(ctx);
426 case 0x2001: /* mov.w Rm,@Rn */
427 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
428 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
429 gen_op_stw_T0_T1(ctx);
431 case 0x2002: /* mov.l Rm,@Rn */
432 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
433 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
434 gen_op_stl_T0_T1(ctx);
436 case 0x6000: /* mov.b @Rm,Rn */
437 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
438 gen_op_ldb_T0_T0(ctx);
439 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
441 case 0x6001: /* mov.w @Rm,Rn */
442 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
443 gen_op_ldw_T0_T0(ctx);
444 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
446 case 0x6002: /* mov.l @Rm,Rn */
447 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
448 gen_op_ldl_T0_T0(ctx);
449 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
451 case 0x2004: /* mov.b Rm,@-Rn */
452 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
453 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
454 cpu_gregs[REG(B11_8)], 1); /* modify register status */
455 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
456 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
457 cpu_gregs[REG(B11_8)], 1); /* recover register status */
458 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
459 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
460 cpu_gregs[REG(B11_8)], 1); /* modify register status */
462 case 0x2005: /* mov.w Rm,@-Rn */
463 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
464 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
465 cpu_gregs[REG(B11_8)], 2);
466 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
467 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
468 cpu_gregs[REG(B11_8)], 2);
469 gen_op_stw_T0_T1(ctx);
470 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
471 cpu_gregs[REG(B11_8)], 2);
473 case 0x2006: /* mov.l Rm,@-Rn */
474 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
475 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
476 cpu_gregs[REG(B11_8)], 4);
477 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
478 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
479 cpu_gregs[REG(B11_8)], 4);
480 gen_op_stl_T0_T1(ctx);
481 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
482 cpu_gregs[REG(B11_8)], 4);
484 case 0x6004: /* mov.b @Rm+,Rn */
485 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
486 gen_op_ldb_T0_T0(ctx);
487 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
489 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
490 cpu_gregs[REG(B7_4)], 1);
492 case 0x6005: /* mov.w @Rm+,Rn */
493 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
494 gen_op_ldw_T0_T0(ctx);
495 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
497 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
498 cpu_gregs[REG(B7_4)], 2);
500 case 0x6006: /* mov.l @Rm+,Rn */
501 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
502 gen_op_ldl_T0_T0(ctx);
503 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
505 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
506 cpu_gregs[REG(B7_4)], 4);
508 case 0x0004: /* mov.b Rm,@(R0,Rn) */
509 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
510 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
511 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
512 gen_op_stb_T0_T1(ctx);
514 case 0x0005: /* mov.w Rm,@(R0,Rn) */
515 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
516 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
517 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
518 gen_op_stw_T0_T1(ctx);
520 case 0x0006: /* mov.l Rm,@(R0,Rn) */
521 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
522 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
523 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
524 gen_op_stl_T0_T1(ctx);
526 case 0x000c: /* mov.b @(R0,Rm),Rn */
527 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
528 gen_op_ldb_T0_T0(ctx);
529 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
531 case 0x000d: /* mov.w @(R0,Rm),Rn */
532 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
533 gen_op_ldw_T0_T0(ctx);
534 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
536 case 0x000e: /* mov.l @(R0,Rm),Rn */
537 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
538 gen_op_ldl_T0_T0(ctx);
539 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
541 case 0x6008: /* swap.b Rm,Rn */
542 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], 0xffff0000);
543 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xff);
544 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
545 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
546 tcg_gen_shri_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 8);
547 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
548 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
550 case 0x6009: /* swap.w Rm,Rn */
551 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
552 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
553 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B7_4)], 16);
554 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
555 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
557 case 0x200d: /* xtrct Rm,Rn */
558 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
559 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
560 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 16);
561 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
562 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
564 case 0x300c: /* add Rm,Rn */
565 tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
567 case 0x300e: /* addc 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)]);
571 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
573 case 0x300f: /* addv Rm,Rn */
574 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
575 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
577 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
579 case 0x2009: /* and Rm,Rn */
580 tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
582 case 0x3000: /* cmp/eq Rm,Rn */
583 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
584 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
585 gen_op_cmp_eq_T0_T1();
587 case 0x3003: /* cmp/ge Rm,Rn */
588 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
589 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
590 gen_op_cmp_ge_T0_T1();
592 case 0x3007: /* cmp/gt Rm,Rn */
593 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
594 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
595 gen_op_cmp_gt_T0_T1();
597 case 0x3006: /* cmp/hi Rm,Rn */
598 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
599 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
600 gen_op_cmp_hi_T0_T1();
602 case 0x3002: /* cmp/hs Rm,Rn */
603 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
604 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
605 gen_op_cmp_hs_T0_T1();
607 case 0x200c: /* cmp/str 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)]);
610 gen_op_cmp_str_T0_T1();
612 case 0x2007: /* div0s Rm,Rn */
613 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
614 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
615 gen_op_div0s_T0_T1();
617 case 0x3004: /* div1 Rm,Rn */
618 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
619 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
621 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
623 case 0x300d: /* dmuls.l Rm,Rn */
624 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
625 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
626 gen_op_dmulsl_T0_T1();
628 case 0x3005: /* dmulu.l Rm,Rn */
629 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
630 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
631 gen_op_dmulul_T0_T1();
633 case 0x600e: /* exts.b Rm,Rn */
634 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
635 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
636 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
637 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
639 case 0x600f: /* exts.w Rm,Rn */
640 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
641 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
642 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
643 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
645 case 0x600c: /* extu.b Rm,Rn */
646 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
647 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
648 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
650 case 0x600d: /* extu.w Rm,Rn */
651 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
652 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
653 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
655 case 0x000f: /* mac.l @Rm+,@Rn+ */
656 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
657 gen_op_ldl_T0_T0(ctx);
658 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
659 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
660 gen_op_ldl_T0_T0(ctx);
662 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
663 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
665 case 0x400f: /* mac.w @Rm+,@Rn+ */
666 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
667 gen_op_ldl_T0_T0(ctx);
668 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
669 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
670 gen_op_ldl_T0_T0(ctx);
672 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
673 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
675 case 0x0007: /* mul.l Rm,Rn */
676 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
677 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
680 case 0x200f: /* muls.w Rm,Rn */
681 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
682 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
683 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
684 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
685 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
686 tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
687 gen_op_mulsw_T0_T1();
689 case 0x200e: /* mulu.w Rm,Rn */
690 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
691 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
692 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
693 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
694 gen_op_muluw_T0_T1();
696 case 0x600b: /* neg Rm,Rn */
697 tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
699 case 0x600a: /* negc Rm,Rn */
700 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
702 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
704 case 0x6007: /* not Rm,Rn */
705 tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
707 case 0x200b: /* or Rm,Rn */
708 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
710 case 0x400c: /* shad Rm,Rn */
711 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
712 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
714 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
716 case 0x400d: /* shld Rm,Rn */
717 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
718 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
720 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
722 case 0x3008: /* sub Rm,Rn */
723 tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
725 case 0x300a: /* subc Rm,Rn */
726 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
727 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
729 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
731 case 0x300b: /* subv Rm,Rn */
732 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
733 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
735 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
737 case 0x2008: /* tst Rm,Rn */
738 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
739 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
742 case 0x200a: /* xor Rm,Rn */
743 tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
745 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
746 if (ctx->fpscr & FPSCR_SZ) {
747 gen_op_fmov_drN_DT0(XREG(B7_4));
748 gen_op_fmov_DT0_drN(XREG(B11_8));
750 gen_op_fmov_frN_FT0(FREG(B7_4));
751 gen_op_fmov_FT0_frN(FREG(B11_8));
754 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
755 if (ctx->fpscr & FPSCR_SZ) {
756 gen_op_fmov_drN_DT0(XREG(B7_4));
757 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
758 gen_op_stfq_DT0_T1(ctx);
760 gen_op_fmov_frN_FT0(FREG(B7_4));
761 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
762 gen_op_stfl_FT0_T1(ctx);
765 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
766 if (ctx->fpscr & FPSCR_SZ) {
767 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
768 gen_op_ldfq_T0_DT0(ctx);
769 gen_op_fmov_DT0_drN(XREG(B11_8));
771 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
772 gen_op_ldfl_T0_FT0(ctx);
773 gen_op_fmov_FT0_frN(FREG(B11_8));
776 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
777 if (ctx->fpscr & FPSCR_SZ) {
778 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
779 gen_op_ldfq_T0_DT0(ctx);
780 gen_op_fmov_DT0_drN(XREG(B11_8));
781 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
782 cpu_gregs[REG(B7_4)], 8);
784 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
785 gen_op_ldfl_T0_FT0(ctx);
786 gen_op_fmov_FT0_frN(FREG(B11_8));
787 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
788 cpu_gregs[REG(B7_4)], 4);
791 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
792 if (ctx->fpscr & FPSCR_SZ) {
793 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
794 gen_op_fmov_drN_DT0(XREG(B7_4));
795 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
796 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
797 gen_op_stfq_DT0_T1(ctx);
798 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
800 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
801 gen_op_fmov_frN_FT0(FREG(B7_4));
802 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
803 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
804 gen_op_stfl_FT0_T1(ctx);
805 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
808 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
809 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
810 if (ctx->fpscr & FPSCR_SZ) {
811 gen_op_ldfq_T0_DT0(ctx);
812 gen_op_fmov_DT0_drN(XREG(B11_8));
814 gen_op_ldfl_T0_FT0(ctx);
815 gen_op_fmov_FT0_frN(FREG(B11_8));
818 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
819 if (ctx->fpscr & FPSCR_SZ) {
820 gen_op_fmov_drN_DT0(XREG(B7_4));
821 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
822 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
823 gen_op_stfq_DT0_T1(ctx);
825 gen_op_fmov_frN_FT0(FREG(B7_4));
826 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
827 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
828 gen_op_stfl_FT0_T1(ctx);
831 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
832 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
833 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
834 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
835 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
836 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
837 if (ctx->fpscr & FPSCR_PR) {
838 if (ctx->opcode & 0x0110)
839 break; /* illegal instruction */
840 gen_op_fmov_drN_DT1(DREG(B7_4));
841 gen_op_fmov_drN_DT0(DREG(B11_8));
844 gen_op_fmov_frN_FT1(FREG(B7_4));
845 gen_op_fmov_frN_FT0(FREG(B11_8));
848 switch (ctx->opcode & 0xf00f) {
849 case 0xf000: /* fadd Rm,Rn */
850 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
852 case 0xf001: /* fsub Rm,Rn */
853 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
855 case 0xf002: /* fmul Rm,Rn */
856 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
858 case 0xf003: /* fdiv Rm,Rn */
859 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
861 case 0xf004: /* fcmp/eq Rm,Rn */
862 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
864 case 0xf005: /* fcmp/gt Rm,Rn */
865 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
869 if (ctx->fpscr & FPSCR_PR) {
870 gen_op_fmov_DT0_drN(DREG(B11_8));
873 gen_op_fmov_FT0_frN(FREG(B11_8));
878 switch (ctx->opcode & 0xff00) {
879 case 0xc900: /* and #imm,R0 */
880 tcg_gen_andi_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
882 case 0xcd00: /* and.b #imm,@(R0,GBR) */
883 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
884 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
885 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
886 gen_op_ldub_T0_T0(ctx);
887 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
888 gen_op_stb_T0_T1(ctx);
890 case 0x8b00: /* bf label */
892 gen_conditional_jump(ctx, ctx->pc + 2,
893 ctx->pc + 4 + B7_0s * 2);
894 ctx->bstate = BS_BRANCH;
896 case 0x8f00: /* bf/s label */
898 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
899 ctx->flags |= DELAY_SLOT_CONDITIONAL;
901 case 0x8900: /* bt label */
903 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
905 ctx->bstate = BS_BRANCH;
907 case 0x8d00: /* bt/s label */
909 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
910 ctx->flags |= DELAY_SLOT_CONDITIONAL;
912 case 0x8800: /* cmp/eq #imm,R0 */
913 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
914 gen_op_cmp_eq_imm_T0(B7_0s);
916 case 0xc400: /* mov.b @(disp,GBR),R0 */
918 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
919 gen_op_ldb_T0_T0(ctx);
920 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
922 case 0xc500: /* mov.w @(disp,GBR),R0 */
924 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
925 gen_op_ldw_T0_T0(ctx);
926 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
928 case 0xc600: /* mov.l @(disp,GBR),R0 */
930 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
931 gen_op_ldl_T0_T0(ctx);
932 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
934 case 0xc000: /* mov.b R0,@(disp,GBR) */
936 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
937 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
938 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
939 gen_op_stb_T0_T1(ctx);
941 case 0xc100: /* mov.w R0,@(disp,GBR) */
943 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
944 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
945 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
946 gen_op_stw_T0_T1(ctx);
948 case 0xc200: /* mov.l R0,@(disp,GBR) */
950 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
951 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
952 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
953 gen_op_stl_T0_T1(ctx);
955 case 0x8000: /* mov.b R0,@(disp,Rn) */
956 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
957 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
958 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0);
959 gen_op_stb_T0_T1(ctx);
961 case 0x8100: /* mov.w R0,@(disp,Rn) */
962 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
963 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
964 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 2);
965 gen_op_stw_T0_T1(ctx);
967 case 0x8400: /* mov.b @(disp,Rn),R0 */
968 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
969 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0);
970 gen_op_ldb_T0_T0(ctx);
971 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
973 case 0x8500: /* mov.w @(disp,Rn),R0 */
974 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
975 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 2);
976 gen_op_ldw_T0_T0(ctx);
977 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
979 case 0xc700: /* mova @(disp,PC),R0 */
980 tcg_gen_movi_i32(cpu_gregs[REG(0)],
981 ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
983 case 0xcb00: /* or #imm,R0 */
984 tcg_gen_ori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
986 case 0xcf00: /* or.b #imm,@(R0,GBR) */
987 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
988 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
989 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
990 gen_op_ldub_T0_T0(ctx);
991 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
992 gen_op_stb_T0_T1(ctx);
994 case 0xc300: /* trapa #imm */
995 CHECK_NOT_DELAY_SLOT tcg_gen_movi_i32(cpu_pc, ctx->pc);
997 ctx->bstate = BS_BRANCH;
999 case 0xc800: /* tst #imm,R0 */
1000 gen_op_tst_imm_rN(B7_0, REG(0));
1002 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1003 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1004 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1005 gen_op_ldub_T0_T0(ctx);
1006 gen_op_tst_imm_T0(B7_0);
1008 case 0xca00: /* xor #imm,R0 */
1009 tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1011 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1012 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1013 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1014 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1015 gen_op_ldub_T0_T0(ctx);
1016 tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
1017 gen_op_stb_T0_T1(ctx);
1021 switch (ctx->opcode & 0xf08f) {
1022 case 0x408e: /* ldc Rm,Rn_BANK */
1023 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1024 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1026 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1027 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1028 gen_op_ldl_T0_T0(ctx);
1029 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1030 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1032 case 0x0082: /* stc Rm_BANK,Rn */
1033 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1034 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
1036 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1037 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1038 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1039 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1040 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1041 gen_op_stl_T0_T1(ctx);
1042 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1046 switch (ctx->opcode & 0xf0ff) {
1047 case 0x0023: /* braf Rn */
1048 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1049 gen_op_braf_T0(ctx->pc + 4);
1050 ctx->flags |= DELAY_SLOT;
1051 ctx->delayed_pc = (uint32_t) - 1;
1053 case 0x0003: /* bsrf Rn */
1054 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1055 gen_op_bsrf_T0(ctx->pc + 4);
1056 ctx->flags |= DELAY_SLOT;
1057 ctx->delayed_pc = (uint32_t) - 1;
1059 case 0x4015: /* cmp/pl Rn */
1060 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1063 case 0x4011: /* cmp/pz Rn */
1064 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1067 case 0x4010: /* dt Rn */
1068 gen_op_dt_rN(REG(B11_8));
1070 case 0x402b: /* jmp @Rn */
1071 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1073 ctx->flags |= DELAY_SLOT;
1074 ctx->delayed_pc = (uint32_t) - 1;
1076 case 0x400b: /* jsr @Rn */
1077 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1078 gen_op_jsr_T0(ctx->pc + 4);
1079 ctx->flags |= DELAY_SLOT;
1080 ctx->delayed_pc = (uint32_t) - 1;
1082 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1084 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1085 gen_op_##ldop##_T0_##reg (); \
1089 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1090 gen_op_ldl_T0_T0 (ctx); \
1091 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1092 cpu_gregs[REG(B11_8)], 4); \
1093 gen_op_##ldop##_T0_##reg (); \
1097 gen_op_##stop##_##reg##_T0 (); \
1098 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]); \
1101 gen_op_##stop##_##reg##_T0 (); \
1102 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1103 cpu_gregs[REG(B11_8)], 4); \
1104 tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]); \
1105 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1106 cpu_gregs[REG(B11_8)], 4); \
1107 gen_op_stl_T0_T1 (ctx); \
1108 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1109 cpu_gregs[REG(B11_8)], 4); \
1111 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1113 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1114 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1115 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1116 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1117 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1118 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1119 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1120 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1121 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1122 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1124 case 0x00c3: /* movca.l R0,@Rm */
1125 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1126 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1127 gen_op_stl_T0_T1(ctx);
1129 case 0x0029: /* movt Rn */
1130 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_sr, SR_T);
1132 case 0x0093: /* ocbi @Rn */
1133 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1134 gen_op_ldl_T0_T0(ctx);
1136 case 0x00a3: /* ocbp @Rn */
1137 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1138 gen_op_ldl_T0_T0(ctx);
1140 case 0x00b3: /* ocbwb @Rn */
1141 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1142 gen_op_ldl_T0_T0(ctx);
1144 case 0x0083: /* pref @Rn */
1146 case 0x4024: /* rotcl Rn */
1147 gen_op_rotcl_Rn(REG(B11_8));
1149 case 0x4025: /* rotcr Rn */
1150 gen_op_rotcr_Rn(REG(B11_8));
1152 case 0x4004: /* rotl Rn */
1153 gen_op_rotl_Rn(REG(B11_8));
1155 case 0x4005: /* rotr Rn */
1156 gen_op_rotr_Rn(REG(B11_8));
1158 case 0x4000: /* shll Rn */
1159 case 0x4020: /* shal Rn */
1160 gen_op_shal_Rn(REG(B11_8));
1162 case 0x4021: /* shar Rn */
1163 gen_op_shar_Rn(REG(B11_8));
1165 case 0x4001: /* shlr Rn */
1166 gen_op_shlr_Rn(REG(B11_8));
1168 case 0x4008: /* shll2 Rn */
1169 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1171 case 0x4018: /* shll8 Rn */
1172 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1174 case 0x4028: /* shll16 Rn */
1175 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1177 case 0x4009: /* shlr2 Rn */
1178 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1180 case 0x4019: /* shlr8 Rn */
1181 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1183 case 0x4029: /* shlr16 Rn */
1184 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1186 case 0x401b: /* tas.b @Rn */
1187 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1188 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1189 gen_op_ldub_T0_T0(ctx);
1190 gen_op_cmp_eq_imm_T0(0);
1191 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
1192 gen_op_stb_T0_T1(ctx);
1194 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1195 gen_op_movl_fpul_FT0();
1196 gen_op_fmov_FT0_frN(FREG(B11_8));
1198 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1199 gen_op_fmov_frN_FT0(FREG(B11_8));
1200 gen_op_movl_FT0_fpul();
1202 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1203 if (ctx->fpscr & FPSCR_PR) {
1204 if (ctx->opcode & 0x0100)
1205 break; /* illegal instruction */
1207 gen_op_fmov_DT0_drN(DREG(B11_8));
1211 gen_op_fmov_FT0_frN(FREG(B11_8));
1214 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1215 if (ctx->fpscr & FPSCR_PR) {
1216 if (ctx->opcode & 0x0100)
1217 break; /* illegal instruction */
1218 gen_op_fmov_drN_DT0(DREG(B11_8));
1222 gen_op_fmov_frN_FT0(FREG(B11_8));
1226 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1227 gen_op_fneg_frN(FREG(B11_8));
1229 case 0xf05d: /* fabs FRn/DRn */
1230 if (ctx->fpscr & FPSCR_PR) {
1231 if (ctx->opcode & 0x0100)
1232 break; /* illegal instruction */
1233 gen_op_fmov_drN_DT0(DREG(B11_8));
1235 gen_op_fmov_DT0_drN(DREG(B11_8));
1237 gen_op_fmov_frN_FT0(FREG(B11_8));
1239 gen_op_fmov_FT0_frN(FREG(B11_8));
1242 case 0xf06d: /* fsqrt FRn */
1243 if (ctx->fpscr & FPSCR_PR) {
1244 if (ctx->opcode & 0x0100)
1245 break; /* illegal instruction */
1246 gen_op_fmov_drN_DT0(FREG(B11_8));
1248 gen_op_fmov_DT0_drN(FREG(B11_8));
1250 gen_op_fmov_frN_FT0(FREG(B11_8));
1252 gen_op_fmov_FT0_frN(FREG(B11_8));
1255 case 0xf07d: /* fsrra FRn */
1257 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1258 if (!(ctx->fpscr & FPSCR_PR)) {
1259 tcg_gen_movi_i32(cpu_T[0], 0);
1260 gen_op_fmov_T0_frN(FREG(B11_8));
1264 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1265 if (!(ctx->fpscr & FPSCR_PR)) {
1266 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1267 gen_op_fmov_T0_frN(FREG(B11_8));
1271 case 0xf0ad: /* fcnvsd FPUL,DRn */
1272 gen_op_movl_fpul_FT0();
1273 gen_op_fcnvsd_FT_DT();
1274 gen_op_fmov_DT0_drN(DREG(B11_8));
1276 case 0xf0bd: /* fcnvds DRn,FPUL */
1277 gen_op_fmov_drN_DT0(DREG(B11_8));
1278 gen_op_fcnvds_DT_FT();
1279 gen_op_movl_FT0_fpul();
1283 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1284 ctx->opcode, ctx->pc);
1285 gen_op_raise_illegal_instruction();
1286 ctx->bstate = BS_EXCP;
1289 void decode_opc(DisasContext * ctx)
1291 uint32_t old_flags = ctx->flags;
1295 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1296 if (ctx->flags & DELAY_SLOT_CLEARME) {
1297 gen_op_store_flags(0);
1299 /* go out of the delay slot */
1300 uint32_t new_flags = ctx->flags;
1301 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1302 gen_op_store_flags(new_flags);
1305 ctx->bstate = BS_BRANCH;
1306 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1307 gen_delayed_conditional_jump(ctx);
1308 } else if (old_flags & DELAY_SLOT) {
1314 /* go into a delay slot */
1315 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1316 gen_op_store_flags(ctx->flags);
1320 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1324 target_ulong pc_start;
1325 static uint16_t *gen_opc_end;
1331 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1333 ctx.flags = (uint32_t)tb->flags;
1334 ctx.bstate = BS_NONE;
1336 ctx.fpscr = env->fpscr;
1337 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1338 /* We don't know if the delayed pc came from a dynamic or static branch,
1339 so assume it is a dynamic branch. */
1340 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1342 ctx.singlestep_enabled = env->singlestep_enabled;
1345 if (loglevel & CPU_LOG_TB_CPU) {
1347 "------------------------------------------------\n");
1348 cpu_dump_state(env, logfile, fprintf, 0);
1354 max_insns = tb->cflags & CF_COUNT_MASK;
1356 max_insns = CF_COUNT_MASK;
1358 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1359 if (env->nb_breakpoints > 0) {
1360 for (i = 0; i < env->nb_breakpoints; i++) {
1361 if (ctx.pc == env->breakpoints[i]) {
1362 /* We have hit a breakpoint - make sure PC is up-to-date */
1363 tcg_gen_movi_i32(cpu_pc, ctx.pc);
1365 ctx.bstate = BS_EXCP;
1371 i = gen_opc_ptr - gen_opc_buf;
1375 gen_opc_instr_start[ii++] = 0;
1377 gen_opc_pc[ii] = ctx.pc;
1378 gen_opc_hflags[ii] = ctx.flags;
1379 gen_opc_instr_start[ii] = 1;
1380 gen_opc_icount[ii] = num_insns;
1382 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1385 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1388 ctx.opcode = lduw_code(ctx.pc);
1392 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1394 if (env->singlestep_enabled)
1396 if (num_insns >= max_insns)
1398 #ifdef SH4_SINGLE_STEP
1402 if (tb->cflags & CF_LAST_IO)
1404 if (env->singlestep_enabled) {
1407 switch (ctx.bstate) {
1409 /* gen_op_interrupt_restart(); */
1413 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1415 gen_goto_tb(&ctx, 0, ctx.pc);
1418 /* gen_op_interrupt_restart(); */
1427 gen_icount_end(tb, num_insns);
1428 *gen_opc_ptr = INDEX_op_end;
1430 i = gen_opc_ptr - gen_opc_buf;
1433 gen_opc_instr_start[ii++] = 0;
1435 tb->size = ctx.pc - pc_start;
1436 tb->icount = num_insns;
1440 #ifdef SH4_DEBUG_DISAS
1441 if (loglevel & CPU_LOG_TB_IN_ASM)
1442 fprintf(logfile, "\n");
1444 if (loglevel & CPU_LOG_TB_IN_ASM) {
1445 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1446 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1447 fprintf(logfile, "\n");
1452 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1454 gen_intermediate_code_internal(env, tb, 0);
1457 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1459 gen_intermediate_code_internal(env, tb, 1);
1462 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1463 unsigned long searched_pc, int pc_pos, void *puc)
1465 env->pc = gen_opc_pc[pc_pos];
1466 env->flags = gen_opc_hflags[pc_pos];