4 * Copyright (c) 2005 Samuel Tardieu
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define SH4_DEBUG_DISAS
29 //#define SH4_SINGLE_STEP
36 #include "qemu-common.h"
38 typedef struct DisasContext {
39 struct TranslationBlock *tb;
48 int singlestep_enabled;
52 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
55 BS_STOP = 1, /* We want to stop translation for any reason */
56 BS_BRANCH = 2, /* We reached a branch condition */
57 BS_EXCP = 3, /* We reached an exception condition */
60 /* global register indexes */
62 static TCGv cpu_gregs[24];
63 static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65 static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
67 /* internal register indexes */
68 static TCGv cpu_flags, cpu_delayed_pc;
70 /* dyngen register indexes */
73 #include "gen-icount.h"
75 static void sh4_translate_init(void)
78 static int done_init = 0;
79 static const char * const gregnames[24] = {
80 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
81 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
82 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
83 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
84 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
90 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
91 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
92 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
94 for (i = 0; i < 24; i++)
95 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
96 offsetof(CPUState, gregs[i]),
99 cpu_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
100 offsetof(CPUState, pc), "PC");
101 cpu_sr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
102 offsetof(CPUState, sr), "SR");
103 cpu_ssr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
104 offsetof(CPUState, ssr), "SSR");
105 cpu_spc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
106 offsetof(CPUState, spc), "SPC");
107 cpu_gbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
108 offsetof(CPUState, gbr), "GBR");
109 cpu_vbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
110 offsetof(CPUState, vbr), "VBR");
111 cpu_sgr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
112 offsetof(CPUState, sgr), "SGR");
113 cpu_dbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
114 offsetof(CPUState, dbr), "DBR");
115 cpu_mach = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
116 offsetof(CPUState, mach), "MACH");
117 cpu_macl = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
118 offsetof(CPUState, macl), "MACL");
119 cpu_pr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
120 offsetof(CPUState, pr), "PR");
121 cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
122 offsetof(CPUState, fpscr), "FPSCR");
123 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
124 offsetof(CPUState, fpul), "FPUL");
126 cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
127 offsetof(CPUState, flags), "_flags_");
128 cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
129 offsetof(CPUState, delayed_pc),
132 /* register helpers */
134 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
140 #ifdef CONFIG_USER_ONLY
142 #define GEN_OP_LD(width, reg) \
143 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
144 gen_op_ld##width##_T0_##reg##_raw(); \
146 #define GEN_OP_ST(width, reg) \
147 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
148 gen_op_st##width##_##reg##_T1_raw(); \
153 #define GEN_OP_LD(width, reg) \
154 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
155 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
156 else gen_op_ld##width##_T0_##reg##_user();\
158 #define GEN_OP_ST(width, reg) \
159 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
160 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
161 else gen_op_st##width##_##reg##_T1_user();\
171 void cpu_dump_state(CPUState * env, FILE * f,
172 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
176 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
177 env->pc, env->sr, env->pr, env->fpscr);
178 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
179 env->spc, env->ssr, env->gbr, env->vbr);
180 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
181 env->sgr, env->dbr, env->delayed_pc, env->fpul);
182 for (i = 0; i < 24; i += 4) {
183 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
184 i, env->gregs[i], i + 1, env->gregs[i + 1],
185 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
187 if (env->flags & DELAY_SLOT) {
188 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
190 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
191 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
196 void cpu_sh4_reset(CPUSH4State * env)
198 #if defined(CONFIG_USER_ONLY)
199 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
201 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
204 env->pc = 0xA0000000;
205 #if defined(CONFIG_USER_ONLY)
206 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
207 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
209 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
210 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
215 CPUSH4State *cpu_sh4_init(const char *cpu_model)
219 env = qemu_mallocz(sizeof(CPUSH4State));
223 sh4_translate_init();
229 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
231 TranslationBlock *tb;
234 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
235 !ctx->singlestep_enabled) {
236 /* Use a direct jump if in same page and singlestep not enabled */
238 tcg_gen_movi_i32(cpu_pc, dest);
239 tcg_gen_exit_tb((long) tb + n);
241 tcg_gen_movi_i32(cpu_pc, dest);
242 if (ctx->singlestep_enabled)
243 tcg_gen_helper_0_0(helper_debug);
248 static void gen_jump(DisasContext * ctx)
250 if (ctx->delayed_pc == (uint32_t) - 1) {
251 /* Target is not statically known, it comes necessarily from a
252 delayed jump as immediate jump are conditinal jumps */
253 tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
254 if (ctx->singlestep_enabled)
255 tcg_gen_helper_0_0(helper_debug);
258 gen_goto_tb(ctx, 0, ctx->delayed_pc);
262 static inline void gen_branch_slot(uint32_t delayed_pc, int t)
264 int label = gen_new_label();
265 tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
266 tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
267 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], t ? SR_T : 0, label);
268 tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
269 gen_set_label(label);
272 /* Immediate conditional jump (bt or bf) */
273 static void gen_conditional_jump(DisasContext * ctx,
274 target_ulong ift, target_ulong ifnott)
278 l1 = gen_new_label();
279 tcg_gen_andi_i32(cpu_T[0], cpu_sr, SR_T);
280 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], SR_T, l1);
281 gen_goto_tb(ctx, 0, ifnott);
283 gen_goto_tb(ctx, 1, ift);
286 /* Delayed conditional jump (bt or bf) */
287 static void gen_delayed_conditional_jump(DisasContext * ctx)
291 l1 = gen_new_label();
292 tcg_gen_andi_i32(cpu_T[0], cpu_flags, DELAY_SLOT_TRUE);
293 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], DELAY_SLOT_TRUE, l1);
294 gen_goto_tb(ctx, 1, ctx->pc + 2);
296 tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
300 static inline void gen_set_t(void)
302 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
305 static inline void gen_clr_t(void)
307 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
310 static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
312 int label1 = gen_new_label();
313 int label2 = gen_new_label();
314 tcg_gen_brcond_i32(cond, t1, t0, label1);
317 gen_set_label(label1);
319 gen_set_label(label2);
322 static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
324 int label1 = gen_new_label();
325 int label2 = gen_new_label();
326 tcg_gen_brcondi_i32(cond, t0, imm, label1);
329 gen_set_label(label1);
331 gen_set_label(label2);
334 static inline void gen_store_flags(uint32_t flags)
336 tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
337 tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
340 static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
342 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
347 tcg_gen_andi_i32(tmp, t1, (1 << p1));
348 tcg_gen_andi_i32(t0, t0, ~(1 << p0));
350 tcg_gen_shri_i32(tmp, tmp, p1 - p0);
352 tcg_gen_shli_i32(tmp, tmp, p0 - p1);
353 tcg_gen_or_i32(t0, t0, tmp);
358 #define B3_0 (ctx->opcode & 0xf)
359 #define B6_4 ((ctx->opcode >> 4) & 0x7)
360 #define B7_4 ((ctx->opcode >> 4) & 0xf)
361 #define B7_0 (ctx->opcode & 0xff)
362 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
363 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
364 (ctx->opcode & 0xfff))
365 #define B11_8 ((ctx->opcode >> 8) & 0xf)
366 #define B15_12 ((ctx->opcode >> 12) & 0xf)
368 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
371 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
374 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
375 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
376 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
377 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
379 #define CHECK_NOT_DELAY_SLOT \
380 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
381 {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
384 void _decode_opc(DisasContext * ctx)
387 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
389 switch (ctx->opcode) {
390 case 0x0019: /* div0u */
391 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
393 case 0x000b: /* rts */
395 tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
396 ctx->flags |= DELAY_SLOT;
397 ctx->delayed_pc = (uint32_t) - 1;
399 case 0x0028: /* clrmac */
400 tcg_gen_movi_i32(cpu_mach, 0);
401 tcg_gen_movi_i32(cpu_macl, 0);
403 case 0x0048: /* clrs */
404 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
406 case 0x0008: /* clrt */
409 case 0x0038: /* ldtlb */
410 #if defined(CONFIG_USER_ONLY)
411 assert(0); /* XXXXX */
413 tcg_gen_helper_0_0(helper_ldtlb);
416 case 0x002b: /* rte */
418 tcg_gen_mov_i32(cpu_sr, cpu_ssr);
419 tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
420 ctx->flags |= DELAY_SLOT;
421 ctx->delayed_pc = (uint32_t) - 1;
423 case 0x0058: /* sets */
424 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
426 case 0x0018: /* sett */
429 case 0xfbfd: /* frchg */
430 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
431 ctx->bstate = BS_STOP;
433 case 0xf3fd: /* fschg */
434 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
435 ctx->bstate = BS_STOP;
437 case 0x0009: /* nop */
439 case 0x001b: /* sleep */
441 tcg_gen_helper_0_0(helper_sleep);
443 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
444 ctx->bstate = BS_EXCP;
449 switch (ctx->opcode & 0xf000) {
450 case 0x1000: /* mov.l Rm,@(disp,Rn) */
451 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
452 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
453 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 4);
454 tcg_gen_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
456 case 0x5000: /* mov.l @(disp,Rm),Rn */
457 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
458 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 4);
459 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
460 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
462 case 0xe000: /* mov #imm,Rn */
463 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
465 case 0x9000: /* mov.w @(disp,PC),Rn */
466 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
467 tcg_gen_qemu_ld16s(cpu_T[0], cpu_T[0], ctx->memidx);
468 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
470 case 0xd000: /* mov.l @(disp,PC),Rn */
471 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
472 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
473 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
475 case 0x7000: /* add #imm,Rn */
476 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], B7_0s);
478 case 0xa000: /* bra disp */
480 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
481 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
482 ctx->flags |= DELAY_SLOT;
484 case 0xb000: /* bsr disp */
486 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
487 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
488 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
489 ctx->flags |= DELAY_SLOT;
493 switch (ctx->opcode & 0xf00f) {
494 case 0x6003: /* mov Rm,Rn */
495 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
496 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
498 case 0x2000: /* mov.b Rm,@Rn */
499 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
500 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
501 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
503 case 0x2001: /* mov.w Rm,@Rn */
504 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
505 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
506 tcg_gen_qemu_st16(cpu_T[0], cpu_T[1], ctx->memidx);
508 case 0x2002: /* mov.l Rm,@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_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
513 case 0x6000: /* mov.b @Rm,Rn */
514 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
515 tcg_gen_qemu_ld8s(cpu_T[0], cpu_T[0], ctx->memidx);
516 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
518 case 0x6001: /* mov.w @Rm,Rn */
519 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
520 tcg_gen_qemu_ld16s(cpu_T[0], cpu_T[0], ctx->memidx);
521 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
523 case 0x6002: /* mov.l @Rm,Rn */
524 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
525 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
526 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
528 case 0x2004: /* mov.b Rm,@-Rn */
529 tcg_gen_subi_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 1);
530 tcg_gen_qemu_st8(cpu_gregs[REG(B7_4)], cpu_T[1], ctx->memidx); /* might cause re-execution */
531 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
532 cpu_gregs[REG(B11_8)], 1); /* modify register status */
534 case 0x2005: /* mov.w Rm,@-Rn */
535 tcg_gen_subi_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 2);
536 tcg_gen_qemu_st16(cpu_gregs[REG(B7_4)], cpu_T[1], ctx->memidx);
537 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
538 cpu_gregs[REG(B11_8)], 2);
540 case 0x2006: /* mov.l Rm,@-Rn */
541 tcg_gen_subi_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 4);
542 tcg_gen_qemu_st32(cpu_gregs[REG(B7_4)], cpu_T[1], ctx->memidx);
543 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
544 cpu_gregs[REG(B11_8)], 4);
546 case 0x6004: /* mov.b @Rm+,Rn */
547 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
548 tcg_gen_qemu_ld8s(cpu_T[0], cpu_T[0], ctx->memidx);
549 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
551 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
552 cpu_gregs[REG(B7_4)], 1);
554 case 0x6005: /* mov.w @Rm+,Rn */
555 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
556 tcg_gen_qemu_ld16s(cpu_T[0], cpu_T[0], ctx->memidx);
557 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
559 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
560 cpu_gregs[REG(B7_4)], 2);
562 case 0x6006: /* mov.l @Rm+,Rn */
563 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
564 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
565 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
567 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
568 cpu_gregs[REG(B7_4)], 4);
570 case 0x0004: /* mov.b Rm,@(R0,Rn) */
571 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
572 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
573 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
574 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
576 case 0x0005: /* mov.w Rm,@(R0,Rn) */
577 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
578 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
579 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
580 tcg_gen_qemu_st16(cpu_T[0], cpu_T[1], ctx->memidx);
582 case 0x0006: /* mov.l Rm,@(R0,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 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
586 tcg_gen_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
588 case 0x000c: /* mov.b @(R0,Rm),Rn */
589 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
590 tcg_gen_qemu_ld8s(cpu_T[0], cpu_T[0], ctx->memidx);
591 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
593 case 0x000d: /* mov.w @(R0,Rm),Rn */
594 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
595 tcg_gen_qemu_ld16s(cpu_T[0], cpu_T[0], ctx->memidx);
596 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
598 case 0x000e: /* mov.l @(R0,Rm),Rn */
599 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
600 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
601 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
603 case 0x6008: /* swap.b Rm,Rn */
604 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], 0xffff0000);
605 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xff);
606 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
607 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
608 tcg_gen_shri_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 8);
609 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
610 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
612 case 0x6009: /* swap.w Rm,Rn */
613 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
614 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
615 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B7_4)], 16);
616 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
617 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
619 case 0x200d: /* xtrct Rm,Rn */
620 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
621 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
622 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 16);
623 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
624 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
626 case 0x300c: /* add Rm,Rn */
627 tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
629 case 0x300e: /* addc Rm,Rn */
630 tcg_gen_helper_1_2(helper_addc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
632 case 0x300f: /* addv Rm,Rn */
633 tcg_gen_helper_1_2(helper_addv, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
635 case 0x2009: /* and Rm,Rn */
636 tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
638 case 0x3000: /* cmp/eq Rm,Rn */
639 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
640 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
641 gen_cmp(TCG_COND_EQ, cpu_T[0], cpu_T[1]);
643 case 0x3003: /* cmp/ge Rm,Rn */
644 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
645 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
646 gen_cmp(TCG_COND_GE, cpu_T[0], cpu_T[1]);
648 case 0x3007: /* cmp/gt Rm,Rn */
649 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
650 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
651 gen_cmp(TCG_COND_GT, cpu_T[0], cpu_T[1]);
653 case 0x3006: /* cmp/hi Rm,Rn */
654 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
655 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
656 gen_cmp(TCG_COND_GTU, cpu_T[0], cpu_T[1]);
658 case 0x3002: /* cmp/hs Rm,Rn */
659 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
660 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
661 gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]);
663 case 0x200c: /* cmp/str Rm,Rn */
665 int label1 = gen_new_label();
666 int label2 = gen_new_label();
667 tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
668 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff000000);
669 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
670 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x00ff0000);
671 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
672 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x0000ff00);
673 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
674 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x000000ff);
675 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label1);
676 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
678 gen_set_label(label1);
679 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
680 gen_set_label(label2);
683 case 0x2007: /* div0s Rm,Rn */
684 gen_copy_bit_i32(cpu_sr, 8, cpu_gregs[REG(B11_8)], 31); /* SR_Q */
685 gen_copy_bit_i32(cpu_sr, 9, cpu_gregs[REG(B7_4)], 31); /* SR_M */
686 tcg_gen_xor_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
687 gen_copy_bit_i32(cpu_sr, 0, cpu_T[0], 31); /* SR_T */
689 case 0x3004: /* div1 Rm,Rn */
690 tcg_gen_helper_1_2(helper_div1, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
692 case 0x300d: /* dmuls.l Rm,Rn */
694 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
695 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
697 tcg_gen_ext_i32_i64(tmp1, cpu_gregs[REG(B7_4)]);
698 tcg_gen_ext_i32_i64(tmp2, cpu_gregs[REG(B11_8)]);
699 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
700 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
701 tcg_gen_shri_i64(tmp1, tmp1, 32);
702 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
708 case 0x3005: /* dmulu.l Rm,Rn */
710 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
711 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
713 tcg_gen_extu_i32_i64(tmp1, cpu_gregs[REG(B7_4)]);
714 tcg_gen_extu_i32_i64(tmp2, cpu_gregs[REG(B11_8)]);
715 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
716 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
717 tcg_gen_shri_i64(tmp1, tmp1, 32);
718 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
724 case 0x600e: /* exts.b Rm,Rn */
725 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
726 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
727 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
728 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
730 case 0x600f: /* exts.w Rm,Rn */
731 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
732 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
733 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
734 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
736 case 0x600c: /* extu.b Rm,Rn */
737 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
738 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
739 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
741 case 0x600d: /* extu.w Rm,Rn */
742 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
743 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
744 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
746 case 0x000f: /* mac.l @Rm+,@Rn+ */
747 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
748 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
749 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
750 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
751 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
752 tcg_gen_helper_0_2(helper_macl, cpu_T[0], cpu_T[1]);
753 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
754 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
756 case 0x400f: /* mac.w @Rm+,@Rn+ */
757 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
758 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
759 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
760 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
761 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
762 tcg_gen_helper_0_2(helper_macw, cpu_T[0], cpu_T[1]);
763 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
764 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
766 case 0x0007: /* mul.l Rm,Rn */
767 tcg_gen_mul_i32(cpu_macl, cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
769 case 0x200f: /* muls.w Rm,Rn */
770 tcg_gen_ext16s_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
771 tcg_gen_ext16s_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
772 tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]);
774 case 0x200e: /* mulu.w Rm,Rn */
775 tcg_gen_ext16u_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
776 tcg_gen_ext16u_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
777 tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]);
779 case 0x600b: /* neg Rm,Rn */
780 tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
782 case 0x600a: /* negc Rm,Rn */
783 tcg_gen_helper_1_1(helper_negc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
785 case 0x6007: /* not Rm,Rn */
786 tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
788 case 0x200b: /* or Rm,Rn */
789 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
791 case 0x400c: /* shad Rm,Rn */
793 int label1 = gen_new_label();
794 int label2 = gen_new_label();
795 int label3 = gen_new_label();
796 int label4 = gen_new_label();
797 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1);
798 /* Rm positive, shift to the left */
799 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
800 tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
802 /* Rm negative, shift to the right */
803 gen_set_label(label1);
804 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
805 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2);
806 tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
807 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f);
808 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1);
809 tcg_gen_sar_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
812 gen_set_label(label2);
813 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B11_8)], 0, label3);
814 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0);
816 gen_set_label(label3);
817 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0xffffffff);
818 gen_set_label(label4);
821 case 0x400d: /* shld Rm,Rn */
823 int label1 = gen_new_label();
824 int label2 = gen_new_label();
825 int label3 = gen_new_label();
826 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_gregs[REG(B7_4)], 0, label1);
827 /* Rm positive, shift to the left */
828 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
829 tcg_gen_shl_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
831 /* Rm negative, shift to the right */
832 gen_set_label(label1);
833 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0x1f);
834 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_T[0], 0, label2);
835 tcg_gen_not_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
836 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0x1f);
837 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], 1);
838 tcg_gen_shr_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
841 gen_set_label(label2);
842 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], 0);
843 gen_set_label(label3);
846 case 0x3008: /* sub Rm,Rn */
847 tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
849 case 0x300a: /* subc Rm,Rn */
850 tcg_gen_helper_1_2(helper_subc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
852 case 0x300b: /* subv Rm,Rn */
853 tcg_gen_helper_1_2(helper_subv, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]);
855 case 0x2008: /* tst Rm,Rn */
856 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
857 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
858 tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
859 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
861 case 0x200a: /* xor Rm,Rn */
862 tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
864 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
865 if (ctx->fpscr & FPSCR_SZ) {
866 gen_op_fmov_drN_DT0(XREG(B7_4));
867 gen_op_fmov_DT0_drN(XREG(B11_8));
869 gen_op_fmov_frN_FT0(FREG(B7_4));
870 gen_op_fmov_FT0_frN(FREG(B11_8));
873 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
874 if (ctx->fpscr & FPSCR_SZ) {
875 gen_op_fmov_drN_DT0(XREG(B7_4));
876 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
877 gen_op_stfq_DT0_T1(ctx);
879 gen_op_fmov_frN_FT0(FREG(B7_4));
880 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
881 gen_op_stfl_FT0_T1(ctx);
884 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
885 if (ctx->fpscr & FPSCR_SZ) {
886 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
887 gen_op_ldfq_T0_DT0(ctx);
888 gen_op_fmov_DT0_drN(XREG(B11_8));
890 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
891 gen_op_ldfl_T0_FT0(ctx);
892 gen_op_fmov_FT0_frN(FREG(B11_8));
895 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
896 if (ctx->fpscr & FPSCR_SZ) {
897 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
898 gen_op_ldfq_T0_DT0(ctx);
899 gen_op_fmov_DT0_drN(XREG(B11_8));
900 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
901 cpu_gregs[REG(B7_4)], 8);
903 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
904 gen_op_ldfl_T0_FT0(ctx);
905 gen_op_fmov_FT0_frN(FREG(B11_8));
906 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
907 cpu_gregs[REG(B7_4)], 4);
910 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
911 if (ctx->fpscr & FPSCR_SZ) {
912 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
913 gen_op_fmov_drN_DT0(XREG(B7_4));
914 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
915 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
916 gen_op_stfq_DT0_T1(ctx);
917 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
919 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
920 gen_op_fmov_frN_FT0(FREG(B7_4));
921 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
922 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
923 gen_op_stfl_FT0_T1(ctx);
924 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
927 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
928 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
929 if (ctx->fpscr & FPSCR_SZ) {
930 gen_op_ldfq_T0_DT0(ctx);
931 gen_op_fmov_DT0_drN(XREG(B11_8));
933 gen_op_ldfl_T0_FT0(ctx);
934 gen_op_fmov_FT0_frN(FREG(B11_8));
937 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
938 if (ctx->fpscr & FPSCR_SZ) {
939 gen_op_fmov_drN_DT0(XREG(B7_4));
940 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
941 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
942 gen_op_stfq_DT0_T1(ctx);
944 gen_op_fmov_frN_FT0(FREG(B7_4));
945 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
946 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
947 gen_op_stfl_FT0_T1(ctx);
950 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
951 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
952 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
953 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
954 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
955 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
956 if (ctx->fpscr & FPSCR_PR) {
957 if (ctx->opcode & 0x0110)
958 break; /* illegal instruction */
959 gen_op_fmov_drN_DT1(DREG(B7_4));
960 gen_op_fmov_drN_DT0(DREG(B11_8));
963 gen_op_fmov_frN_FT1(FREG(B7_4));
964 gen_op_fmov_frN_FT0(FREG(B11_8));
967 switch (ctx->opcode & 0xf00f) {
968 case 0xf000: /* fadd Rm,Rn */
969 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
971 case 0xf001: /* fsub Rm,Rn */
972 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
974 case 0xf002: /* fmul Rm,Rn */
975 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
977 case 0xf003: /* fdiv Rm,Rn */
978 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
980 case 0xf004: /* fcmp/eq Rm,Rn */
981 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
983 case 0xf005: /* fcmp/gt Rm,Rn */
984 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
988 if (ctx->fpscr & FPSCR_PR) {
989 gen_op_fmov_DT0_drN(DREG(B11_8));
992 gen_op_fmov_FT0_frN(FREG(B11_8));
997 switch (ctx->opcode & 0xff00) {
998 case 0xc900: /* and #imm,R0 */
999 tcg_gen_andi_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1001 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1002 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1003 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1004 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1005 tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[0], ctx->memidx);
1006 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
1007 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1009 case 0x8b00: /* bf label */
1010 CHECK_NOT_DELAY_SLOT
1011 gen_conditional_jump(ctx, ctx->pc + 2,
1012 ctx->pc + 4 + B7_0s * 2);
1013 ctx->bstate = BS_BRANCH;
1015 case 0x8f00: /* bf/s label */
1016 CHECK_NOT_DELAY_SLOT
1017 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1018 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1020 case 0x8900: /* bt label */
1021 CHECK_NOT_DELAY_SLOT
1022 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1024 ctx->bstate = BS_BRANCH;
1026 case 0x8d00: /* bt/s label */
1027 CHECK_NOT_DELAY_SLOT
1028 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1029 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1031 case 0x8800: /* cmp/eq #imm,R0 */
1032 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1033 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], B7_0s);
1035 case 0xc400: /* mov.b @(disp,GBR),R0 */
1036 tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0);
1037 tcg_gen_qemu_ld8s(cpu_T[0], cpu_T[0], ctx->memidx);
1038 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1040 case 0xc500: /* mov.w @(disp,GBR),R0 */
1041 tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 2);
1042 tcg_gen_qemu_ld16s(cpu_T[0], cpu_T[0], ctx->memidx);
1043 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1045 case 0xc600: /* mov.l @(disp,GBR),R0 */
1046 tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 4);
1047 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
1048 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1050 case 0xc000: /* mov.b R0,@(disp,GBR) */
1051 tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0);
1052 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1053 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1054 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1056 case 0xc100: /* mov.w R0,@(disp,GBR) */
1057 tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 2);
1058 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1059 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1060 tcg_gen_qemu_st16(cpu_T[0], cpu_T[1], ctx->memidx);
1062 case 0xc200: /* mov.l R0,@(disp,GBR) */
1063 tcg_gen_addi_i32(cpu_T[0], cpu_gbr, B7_0 * 4);
1064 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1065 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1066 tcg_gen_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
1068 case 0x8000: /* mov.b R0,@(disp,Rn) */
1069 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1070 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
1071 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0);
1072 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1074 case 0x8100: /* mov.w R0,@(disp,Rn) */
1075 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1076 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
1077 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 2);
1078 tcg_gen_qemu_st16(cpu_T[0], cpu_T[1], ctx->memidx);
1080 case 0x8400: /* mov.b @(disp,Rn),R0 */
1081 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
1082 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0);
1083 tcg_gen_qemu_ld8s(cpu_T[0], cpu_T[0], ctx->memidx);
1084 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1086 case 0x8500: /* mov.w @(disp,Rn),R0 */
1087 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
1088 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 2);
1089 tcg_gen_qemu_ld16s(cpu_T[0], cpu_T[0], ctx->memidx);
1090 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
1092 case 0xc700: /* mova @(disp,PC),R0 */
1093 tcg_gen_movi_i32(cpu_gregs[REG(0)],
1094 ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1096 case 0xcb00: /* or #imm,R0 */
1097 tcg_gen_ori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1099 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1100 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1101 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1102 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
1103 tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[0], ctx->memidx);
1104 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
1105 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1107 case 0xc300: /* trapa #imm */
1108 CHECK_NOT_DELAY_SLOT
1109 tcg_gen_movi_i32(cpu_pc, ctx->pc);
1110 tcg_gen_movi_i32(cpu_T[0], B7_0);
1111 tcg_gen_helper_0_1(helper_trapa, cpu_T[0]);
1112 ctx->bstate = BS_BRANCH;
1114 case 0xc800: /* tst #imm,R0 */
1115 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(0)], B7_0);
1116 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1118 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1119 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1120 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1121 tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[0], ctx->memidx);
1122 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
1123 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1125 case 0xca00: /* xor #imm,R0 */
1126 tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
1128 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1129 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1130 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
1131 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1132 tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[0], ctx->memidx);
1133 tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
1134 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1138 switch (ctx->opcode & 0xf08f) {
1139 case 0x408e: /* ldc Rm,Rn_BANK */
1140 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1141 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1143 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1144 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1145 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
1146 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
1147 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1149 case 0x0082: /* stc Rm_BANK,Rn */
1150 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1151 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
1153 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1154 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1155 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1156 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1157 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1158 tcg_gen_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
1159 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1163 switch (ctx->opcode & 0xf0ff) {
1164 case 0x0023: /* braf Rn */
1165 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1166 tcg_gen_addi_i32(cpu_delayed_pc, cpu_T[0], ctx->pc + 4);
1167 ctx->flags |= DELAY_SLOT;
1168 ctx->delayed_pc = (uint32_t) - 1;
1170 case 0x0003: /* bsrf Rn */
1171 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1172 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1173 tcg_gen_add_i32(cpu_delayed_pc, cpu_T[0], cpu_pr);
1174 ctx->flags |= DELAY_SLOT;
1175 ctx->delayed_pc = (uint32_t) - 1;
1177 case 0x4015: /* cmp/pl Rn */
1178 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1179 gen_cmp_imm(TCG_COND_GT, cpu_T[0], 0);
1181 case 0x4011: /* cmp/pz Rn */
1182 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1183 gen_cmp_imm(TCG_COND_GE, cpu_T[0], 0);
1185 case 0x4010: /* dt Rn */
1186 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1187 gen_cmp_imm(TCG_COND_EQ, cpu_gregs[REG(B11_8)], 0);
1189 case 0x402b: /* jmp @Rn */
1190 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1191 tcg_gen_mov_i32(cpu_delayed_pc, cpu_T[0]);
1192 ctx->flags |= DELAY_SLOT;
1193 ctx->delayed_pc = (uint32_t) - 1;
1195 case 0x400b: /* jsr @Rn */
1196 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1197 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1198 tcg_gen_mov_i32(cpu_delayed_pc, cpu_T[0]);
1199 ctx->flags |= DELAY_SLOT;
1200 ctx->delayed_pc = (uint32_t) - 1;
1202 case 0x400e: /* lds Rm,SR */
1203 tcg_gen_andi_i32(cpu_sr, cpu_gregs[REG(B11_8)], 0x700083f3);
1204 ctx->bstate = BS_STOP;
1206 case 0x4007: /* lds.l @Rm+,SR */
1207 tcg_gen_qemu_ld32s(cpu_T[0], cpu_gregs[REG(B11_8)], ctx->memidx);
1208 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1209 tcg_gen_andi_i32(cpu_sr, cpu_T[0], 0x700083f3);
1210 ctx->bstate = BS_STOP;
1212 case 0x0002: /* sts SR,Rn */
1213 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_sr);
1215 case 0x4003: /* sts SR,@-Rn */
1216 tcg_gen_subi_i32(cpu_T[0], cpu_gregs[REG(B11_8)], 4);
1217 tcg_gen_qemu_st32(cpu_sr, cpu_T[0], ctx->memidx);
1218 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1220 #define LDST(reg,ldnum,ldpnum,stnum,stpnum) \
1222 tcg_gen_mov_i32 (cpu_##reg, cpu_gregs[REG(B11_8)]); \
1225 tcg_gen_qemu_ld32s (cpu_##reg, cpu_gregs[REG(B11_8)], ctx->memidx); \
1226 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1227 cpu_gregs[REG(B11_8)], 4); \
1230 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_##reg); \
1233 tcg_gen_subi_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 4); \
1234 tcg_gen_qemu_st32 (cpu_##reg, cpu_T[1], ctx->memidx); \
1235 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1236 cpu_gregs[REG(B11_8)], 4); \
1238 LDST(gbr, 0x401e, 0x4017, 0x0012, 0x4013)
1239 LDST(vbr, 0x402e, 0x4027, 0x0022, 0x4023)
1240 LDST(ssr, 0x403e, 0x4037, 0x0032, 0x4033)
1241 LDST(spc, 0x404e, 0x4047, 0x0042, 0x4043)
1242 LDST(dbr, 0x40fa, 0x40f6, 0x00fa, 0x40f2)
1243 LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002)
1244 LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012)
1245 LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022)
1246 LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052)
1247 case 0x406a: /* lds Rm,FPSCR */
1248 tcg_gen_helper_0_1(helper_ld_fpscr, cpu_gregs[REG(B11_8)]);
1249 ctx->bstate = BS_STOP;
1251 case 0x4066: /* lds.l @Rm+,FPSCR */
1252 tcg_gen_qemu_ld32s(cpu_T[0], cpu_gregs[REG(B11_8)], ctx->memidx);
1253 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1254 tcg_gen_helper_0_1(helper_ld_fpscr, cpu_T[0]);
1255 ctx->bstate = BS_STOP;
1257 case 0x006a: /* sts FPSCR,Rn */
1258 tcg_gen_andi_i32(cpu_T[0], cpu_fpscr, 0x003fffff);
1259 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
1261 case 0x4062: /* sts FPSCR,@-Rn */
1262 tcg_gen_andi_i32(cpu_T[0], cpu_fpscr, 0x003fffff);
1263 tcg_gen_subi_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 4);
1264 tcg_gen_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
1265 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1267 case 0x00c3: /* movca.l R0,@Rm */
1268 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1269 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1270 tcg_gen_qemu_st32(cpu_T[0], cpu_T[1], ctx->memidx);
1272 case 0x0029: /* movt Rn */
1273 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_sr, SR_T);
1275 case 0x0093: /* ocbi @Rn */
1276 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1277 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
1279 case 0x00a3: /* ocbp @Rn */
1280 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1281 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
1283 case 0x00b3: /* ocbwb @Rn */
1284 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1285 tcg_gen_qemu_ld32s(cpu_T[0], cpu_T[0], ctx->memidx);
1287 case 0x0083: /* pref @Rn */
1289 case 0x4024: /* rotcl Rn */
1290 tcg_gen_mov_i32(cpu_T[0], cpu_sr);
1291 gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31);
1292 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1293 gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_T[0], 0);
1295 case 0x4025: /* rotcr Rn */
1296 tcg_gen_mov_i32(cpu_T[0], cpu_sr);
1297 gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
1298 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1299 gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_T[0], 0);
1301 case 0x4004: /* rotl Rn */
1302 gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31);
1303 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1304 gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 0, cpu_sr, 0);
1306 case 0x4005: /* rotr Rn */
1307 gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
1308 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1309 gen_copy_bit_i32(cpu_gregs[REG(B11_8)], 31, cpu_sr, 0);
1311 case 0x4000: /* shll Rn */
1312 case 0x4020: /* shal Rn */
1313 gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 31);
1314 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1316 case 0x4021: /* shar Rn */
1317 gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
1318 tcg_gen_sari_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1320 case 0x4001: /* shlr Rn */
1321 gen_copy_bit_i32(cpu_sr, 0, cpu_gregs[REG(B11_8)], 0);
1322 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1324 case 0x4008: /* shll2 Rn */
1325 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1327 case 0x4018: /* shll8 Rn */
1328 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1330 case 0x4028: /* shll16 Rn */
1331 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1333 case 0x4009: /* shlr2 Rn */
1334 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1336 case 0x4019: /* shlr8 Rn */
1337 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1339 case 0x4029: /* shlr16 Rn */
1340 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1342 case 0x401b: /* tas.b @Rn */
1343 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1344 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1345 tcg_gen_qemu_ld8u(cpu_T[0], cpu_T[0], ctx->memidx);
1346 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
1347 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
1348 tcg_gen_qemu_st8(cpu_T[0], cpu_T[1], ctx->memidx);
1350 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1351 gen_op_movl_fpul_FT0();
1352 gen_op_fmov_FT0_frN(FREG(B11_8));
1354 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1355 gen_op_fmov_frN_FT0(FREG(B11_8));
1356 gen_op_movl_FT0_fpul();
1358 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1359 if (ctx->fpscr & FPSCR_PR) {
1360 if (ctx->opcode & 0x0100)
1361 break; /* illegal instruction */
1363 gen_op_fmov_DT0_drN(DREG(B11_8));
1367 gen_op_fmov_FT0_frN(FREG(B11_8));
1370 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1371 if (ctx->fpscr & FPSCR_PR) {
1372 if (ctx->opcode & 0x0100)
1373 break; /* illegal instruction */
1374 gen_op_fmov_drN_DT0(DREG(B11_8));
1378 gen_op_fmov_frN_FT0(FREG(B11_8));
1382 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1383 gen_op_fneg_frN(FREG(B11_8));
1385 case 0xf05d: /* fabs FRn/DRn */
1386 if (ctx->fpscr & FPSCR_PR) {
1387 if (ctx->opcode & 0x0100)
1388 break; /* illegal instruction */
1389 gen_op_fmov_drN_DT0(DREG(B11_8));
1391 gen_op_fmov_DT0_drN(DREG(B11_8));
1393 gen_op_fmov_frN_FT0(FREG(B11_8));
1395 gen_op_fmov_FT0_frN(FREG(B11_8));
1398 case 0xf06d: /* fsqrt FRn */
1399 if (ctx->fpscr & FPSCR_PR) {
1400 if (ctx->opcode & 0x0100)
1401 break; /* illegal instruction */
1402 gen_op_fmov_drN_DT0(FREG(B11_8));
1404 gen_op_fmov_DT0_drN(FREG(B11_8));
1406 gen_op_fmov_frN_FT0(FREG(B11_8));
1408 gen_op_fmov_FT0_frN(FREG(B11_8));
1411 case 0xf07d: /* fsrra FRn */
1413 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1414 if (!(ctx->fpscr & FPSCR_PR)) {
1415 tcg_gen_movi_i32(cpu_T[0], 0);
1416 gen_op_fmov_T0_frN(FREG(B11_8));
1420 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1421 if (!(ctx->fpscr & FPSCR_PR)) {
1422 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1423 gen_op_fmov_T0_frN(FREG(B11_8));
1427 case 0xf0ad: /* fcnvsd FPUL,DRn */
1428 gen_op_movl_fpul_FT0();
1429 gen_op_fcnvsd_FT_DT();
1430 gen_op_fmov_DT0_drN(DREG(B11_8));
1432 case 0xf0bd: /* fcnvds DRn,FPUL */
1433 gen_op_fmov_drN_DT0(DREG(B11_8));
1434 gen_op_fcnvds_DT_FT();
1435 gen_op_movl_FT0_fpul();
1439 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1440 ctx->opcode, ctx->pc);
1441 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
1442 ctx->bstate = BS_EXCP;
1445 void decode_opc(DisasContext * ctx)
1447 uint32_t old_flags = ctx->flags;
1451 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1452 if (ctx->flags & DELAY_SLOT_CLEARME) {
1455 /* go out of the delay slot */
1456 uint32_t new_flags = ctx->flags;
1457 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1458 gen_store_flags(new_flags);
1461 ctx->bstate = BS_BRANCH;
1462 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1463 gen_delayed_conditional_jump(ctx);
1464 } else if (old_flags & DELAY_SLOT) {
1470 /* go into a delay slot */
1471 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1472 gen_store_flags(ctx->flags);
1476 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1480 target_ulong pc_start;
1481 static uint16_t *gen_opc_end;
1487 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1489 ctx.flags = (uint32_t)tb->flags;
1490 ctx.bstate = BS_NONE;
1492 ctx.fpscr = env->fpscr;
1493 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1494 /* We don't know if the delayed pc came from a dynamic or static branch,
1495 so assume it is a dynamic branch. */
1496 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1498 ctx.singlestep_enabled = env->singlestep_enabled;
1501 if (loglevel & CPU_LOG_TB_CPU) {
1503 "------------------------------------------------\n");
1504 cpu_dump_state(env, logfile, fprintf, 0);
1510 max_insns = tb->cflags & CF_COUNT_MASK;
1512 max_insns = CF_COUNT_MASK;
1514 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1515 if (env->nb_breakpoints > 0) {
1516 for (i = 0; i < env->nb_breakpoints; i++) {
1517 if (ctx.pc == env->breakpoints[i]) {
1518 /* We have hit a breakpoint - make sure PC is up-to-date */
1519 tcg_gen_movi_i32(cpu_pc, ctx.pc);
1520 tcg_gen_helper_0_0(helper_debug);
1521 ctx.bstate = BS_EXCP;
1527 i = gen_opc_ptr - gen_opc_buf;
1531 gen_opc_instr_start[ii++] = 0;
1533 gen_opc_pc[ii] = ctx.pc;
1534 gen_opc_hflags[ii] = ctx.flags;
1535 gen_opc_instr_start[ii] = 1;
1536 gen_opc_icount[ii] = num_insns;
1538 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1541 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1544 ctx.opcode = lduw_code(ctx.pc);
1548 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1550 if (env->singlestep_enabled)
1552 if (num_insns >= max_insns)
1554 #ifdef SH4_SINGLE_STEP
1558 if (tb->cflags & CF_LAST_IO)
1560 if (env->singlestep_enabled) {
1561 tcg_gen_helper_0_0(helper_debug);
1563 switch (ctx.bstate) {
1565 /* gen_op_interrupt_restart(); */
1569 gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1571 gen_goto_tb(&ctx, 0, ctx.pc);
1574 /* gen_op_interrupt_restart(); */
1583 gen_icount_end(tb, num_insns);
1584 *gen_opc_ptr = INDEX_op_end;
1586 i = gen_opc_ptr - gen_opc_buf;
1589 gen_opc_instr_start[ii++] = 0;
1591 tb->size = ctx.pc - pc_start;
1592 tb->icount = num_insns;
1596 #ifdef SH4_DEBUG_DISAS
1597 if (loglevel & CPU_LOG_TB_IN_ASM)
1598 fprintf(logfile, "\n");
1600 if (loglevel & CPU_LOG_TB_IN_ASM) {
1601 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1602 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1603 fprintf(logfile, "\n");
1608 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1610 gen_intermediate_code_internal(env, tb, 0);
1613 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1615 gen_intermediate_code_internal(env, tb, 1);
1618 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1619 unsigned long searched_pc, int pc_pos, void *puc)
1621 env->pc = gen_opc_pc[pc_pos];
1622 env->flags = gen_opc_hflags[pc_pos];