]>
git.proxmox.com Git - mirror_qemu.git/blob - target-sh4/translate.c
4 * Copyright (c) 2005 Samuel Tardieu
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define SH4_DEBUG_DISAS
29 //#define SH4_SINGLE_STEP
36 #include "qemu-common.h"
38 typedef struct DisasContext
{
39 struct TranslationBlock
*tb
;
48 int singlestep_enabled
;
52 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
55 BS_STOP
= 1, /* We want to stop translation for any reason */
56 BS_BRANCH
= 2, /* We reached a branch condition */
57 BS_EXCP
= 3, /* We reached an exception condition */
60 /* global register indexes */
62 static TCGv cpu_gregs
[24];
64 /* dyngen register indexes */
67 #include "gen-icount.h"
69 static void sh4_translate_init(void)
72 static int done_init
= 0;
73 static const char * const gregnames
[24] = {
74 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
75 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
76 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
77 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
78 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
84 cpu_env
= tcg_global_reg_new(TCG_TYPE_PTR
, TCG_AREG0
, "env");
85 cpu_T
[0] = tcg_global_reg_new(TCG_TYPE_I32
, TCG_AREG1
, "T0");
86 cpu_T
[1] = tcg_global_reg_new(TCG_TYPE_I32
, TCG_AREG2
, "T1");
88 for (i
= 0; i
< 24; i
++)
89 cpu_gregs
[i
] = tcg_global_mem_new(TCG_TYPE_I32
, TCG_AREG0
,
90 offsetof(CPUState
, gregs
[i
]),
93 /* register helpers */
95 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
101 #ifdef CONFIG_USER_ONLY
103 #define GEN_OP_LD(width, reg) \
104 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
105 gen_op_ld##width##_T0_##reg##_raw(); \
107 #define GEN_OP_ST(width, reg) \
108 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
109 gen_op_st##width##_##reg##_T1_raw(); \
114 #define GEN_OP_LD(width, reg) \
115 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
116 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
117 else gen_op_ld##width##_T0_##reg##_user();\
119 #define GEN_OP_ST(width, reg) \
120 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
121 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
122 else gen_op_st##width##_##reg##_T1_user();\
140 void cpu_dump_state(CPUState
* env
, FILE * f
,
141 int (*cpu_fprintf
) (FILE * f
, const char *fmt
, ...),
145 cpu_fprintf(f
, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
146 env
->pc
, env
->sr
, env
->pr
, env
->fpscr
);
147 cpu_fprintf(f
, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
148 env
->spc
, env
->ssr
, env
->gbr
, env
->vbr
);
149 cpu_fprintf(f
, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
150 env
->sgr
, env
->dbr
, env
->delayed_pc
, env
->fpul
);
151 for (i
= 0; i
< 24; i
+= 4) {
152 cpu_fprintf(f
, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
153 i
, env
->gregs
[i
], i
+ 1, env
->gregs
[i
+ 1],
154 i
+ 2, env
->gregs
[i
+ 2], i
+ 3, env
->gregs
[i
+ 3]);
156 if (env
->flags
& DELAY_SLOT
) {
157 cpu_fprintf(f
, "in delay slot (delayed_pc=0x%08x)\n",
159 } else if (env
->flags
& DELAY_SLOT_CONDITIONAL
) {
160 cpu_fprintf(f
, "in conditional delay slot (delayed_pc=0x%08x)\n",
165 void cpu_sh4_reset(CPUSH4State
* env
)
167 #if defined(CONFIG_USER_ONLY)
168 env
->sr
= SR_FD
; /* FD - kernel does lazy fpu context switch */
170 env
->sr
= 0x700000F0; /* MD, RB, BL, I3-I0 */
173 env
->pc
= 0xA0000000;
174 #if defined(CONFIG_USER_ONLY)
175 env
->fpscr
= FPSCR_PR
; /* value for userspace according to the kernel */
176 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
); /* ?! */
178 env
->fpscr
= 0x00040001; /* CPU reset value according to SH4 manual */
179 set_float_rounding_mode(float_round_to_zero
, &env
->fp_status
);
184 CPUSH4State
*cpu_sh4_init(const char *cpu_model
)
188 env
= qemu_mallocz(sizeof(CPUSH4State
));
192 sh4_translate_init();
198 static void gen_goto_tb(DisasContext
* ctx
, int n
, target_ulong dest
)
200 TranslationBlock
*tb
;
203 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
204 !ctx
->singlestep_enabled
) {
205 /* Use a direct jump if in same page and singlestep not enabled */
207 gen_op_movl_imm_PC(dest
);
208 tcg_gen_exit_tb((long) tb
+ n
);
210 gen_op_movl_imm_PC(dest
);
211 if (ctx
->singlestep_enabled
)
217 static void gen_jump(DisasContext
* ctx
)
219 if (ctx
->delayed_pc
== (uint32_t) - 1) {
220 /* Target is not statically known, it comes necessarily from a
221 delayed jump as immediate jump are conditinal jumps */
222 gen_op_movl_delayed_pc_PC();
223 if (ctx
->singlestep_enabled
)
227 gen_goto_tb(ctx
, 0, ctx
->delayed_pc
);
231 /* Immediate conditional jump (bt or bf) */
232 static void gen_conditional_jump(DisasContext
* ctx
,
233 target_ulong ift
, target_ulong ifnott
)
237 l1
= gen_new_label();
239 gen_goto_tb(ctx
, 0, ifnott
);
241 gen_goto_tb(ctx
, 1, ift
);
244 /* Delayed conditional jump (bt or bf) */
245 static void gen_delayed_conditional_jump(DisasContext
* ctx
)
249 l1
= gen_new_label();
251 gen_goto_tb(ctx
, 1, ctx
->pc
+ 2);
256 #define B3_0 (ctx->opcode & 0xf)
257 #define B6_4 ((ctx->opcode >> 4) & 0x7)
258 #define B7_4 ((ctx->opcode >> 4) & 0xf)
259 #define B7_0 (ctx->opcode & 0xff)
260 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
261 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
262 (ctx->opcode & 0xfff))
263 #define B11_8 ((ctx->opcode >> 8) & 0xf)
264 #define B15_12 ((ctx->opcode >> 12) & 0xf)
266 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
269 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
272 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
273 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
274 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
275 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
277 #define CHECK_NOT_DELAY_SLOT \
278 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
279 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
282 void _decode_opc(DisasContext
* ctx
)
285 fprintf(stderr
, "Translating opcode 0x%04x\n", ctx
->opcode
);
287 switch (ctx
->opcode
) {
288 case 0x0019: /* div0u */
291 case 0x000b: /* rts */
292 CHECK_NOT_DELAY_SLOT
gen_op_rts();
293 ctx
->flags
|= DELAY_SLOT
;
294 ctx
->delayed_pc
= (uint32_t) - 1;
296 case 0x0028: /* clrmac */
299 case 0x0048: /* clrs */
302 case 0x0008: /* clrt */
305 case 0x0038: /* ldtlb */
306 #if defined(CONFIG_USER_ONLY)
307 assert(0); /* XXXXX */
312 case 0x002b: /* rte */
313 CHECK_NOT_DELAY_SLOT
gen_op_rte();
314 ctx
->flags
|= DELAY_SLOT
;
315 ctx
->delayed_pc
= (uint32_t) - 1;
317 case 0x0058: /* sets */
320 case 0x0018: /* sett */
323 case 0xfbfd: /* frchg */
325 ctx
->bstate
= BS_STOP
;
327 case 0xf3fd: /* fschg */
329 ctx
->bstate
= BS_STOP
;
331 case 0x0009: /* nop */
333 case 0x001b: /* sleep */
337 gen_op_raise_illegal_instruction();
338 ctx
->bstate
= BS_EXCP
;
343 switch (ctx
->opcode
& 0xf000) {
344 case 0x1000: /* mov.l Rm,@(disp,Rn) */
345 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
346 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
347 tcg_gen_addi_i32(cpu_T
[1], cpu_T
[1], B3_0
* 4);
348 gen_op_stl_T0_T1(ctx
);
350 case 0x5000: /* mov.l @(disp,Rm),Rn */
351 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
352 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B3_0
* 4);
353 gen_op_ldl_T0_T0(ctx
);
354 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
356 case 0xe000: /* mov #imm,Rn */
357 tcg_gen_movi_i32(cpu_gregs
[REG(B11_8
)], B7_0s
);
359 case 0x9000: /* mov.w @(disp,PC),Rn */
360 tcg_gen_movi_i32(cpu_T
[0], ctx
->pc
+ 4 + B7_0
* 2);
361 gen_op_ldw_T0_T0(ctx
);
362 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
364 case 0xd000: /* mov.l @(disp,PC),Rn */
365 tcg_gen_movi_i32(cpu_T
[0], (ctx
->pc
+ 4 + B7_0
* 4) & ~3);
366 gen_op_ldl_T0_T0(ctx
);
367 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
369 case 0x7000: /* add #imm,Rn */
370 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], B7_0s
);
372 case 0xa000: /* bra disp */
374 gen_op_bra(ctx
->delayed_pc
= ctx
->pc
+ 4 + B11_0s
* 2);
375 ctx
->flags
|= DELAY_SLOT
;
377 case 0xb000: /* bsr disp */
379 gen_op_bsr(ctx
->pc
+ 4, ctx
->delayed_pc
=
380 ctx
->pc
+ 4 + B11_0s
* 2);
381 ctx
->flags
|= DELAY_SLOT
;
385 switch (ctx
->opcode
& 0xf00f) {
386 case 0x6003: /* mov Rm,Rn */
387 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
388 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
390 case 0x2000: /* mov.b Rm,@Rn */
391 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
392 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
393 gen_op_stb_T0_T1(ctx
);
395 case 0x2001: /* mov.w Rm,@Rn */
396 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
397 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
398 gen_op_stw_T0_T1(ctx
);
400 case 0x2002: /* mov.l Rm,@Rn */
401 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
402 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
403 gen_op_stl_T0_T1(ctx
);
405 case 0x6000: /* mov.b @Rm,Rn */
406 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
407 gen_op_ldb_T0_T0(ctx
);
408 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
410 case 0x6001: /* mov.w @Rm,Rn */
411 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
412 gen_op_ldw_T0_T0(ctx
);
413 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
415 case 0x6002: /* mov.l @Rm,Rn */
416 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
417 gen_op_ldl_T0_T0(ctx
);
418 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
420 case 0x2004: /* mov.b Rm,@-Rn */
421 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
422 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)],
423 cpu_gregs
[REG(B11_8
)], 1); /* modify register status */
424 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
425 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)],
426 cpu_gregs
[REG(B11_8
)], 1); /* recover register status */
427 gen_op_stb_T0_T1(ctx
); /* might cause re-execution */
428 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)],
429 cpu_gregs
[REG(B11_8
)], 1); /* modify register status */
431 case 0x2005: /* mov.w Rm,@-Rn */
432 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
433 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)],
434 cpu_gregs
[REG(B11_8
)], 2);
435 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
436 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)],
437 cpu_gregs
[REG(B11_8
)], 2);
438 gen_op_stw_T0_T1(ctx
);
439 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)],
440 cpu_gregs
[REG(B11_8
)], 2);
442 case 0x2006: /* mov.l Rm,@-Rn */
443 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
444 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)],
445 cpu_gregs
[REG(B11_8
)], 4);
446 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
447 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)],
448 cpu_gregs
[REG(B11_8
)], 4);
449 gen_op_stl_T0_T1(ctx
);
450 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)],
451 cpu_gregs
[REG(B11_8
)], 4);
453 case 0x6004: /* mov.b @Rm+,Rn */
454 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
455 gen_op_ldb_T0_T0(ctx
);
456 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
458 tcg_gen_addi_i32(cpu_gregs
[REG(B7_4
)],
459 cpu_gregs
[REG(B7_4
)], 1);
461 case 0x6005: /* mov.w @Rm+,Rn */
462 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
463 gen_op_ldw_T0_T0(ctx
);
464 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
466 tcg_gen_addi_i32(cpu_gregs
[REG(B7_4
)],
467 cpu_gregs
[REG(B7_4
)], 2);
469 case 0x6006: /* mov.l @Rm+,Rn */
470 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
471 gen_op_ldl_T0_T0(ctx
);
472 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
474 tcg_gen_addi_i32(cpu_gregs
[REG(B7_4
)],
475 cpu_gregs
[REG(B7_4
)], 4);
477 case 0x0004: /* mov.b Rm,@(R0,Rn) */
478 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
479 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
480 tcg_gen_add_i32(cpu_T
[1], cpu_T
[1], cpu_gregs
[REG(0)]);
481 gen_op_stb_T0_T1(ctx
);
483 case 0x0005: /* mov.w Rm,@(R0,Rn) */
484 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
485 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
486 tcg_gen_add_i32(cpu_T
[1], cpu_T
[1], cpu_gregs
[REG(0)]);
487 gen_op_stw_T0_T1(ctx
);
489 case 0x0006: /* mov.l Rm,@(R0,Rn) */
490 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
491 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
492 tcg_gen_add_i32(cpu_T
[1], cpu_T
[1], cpu_gregs
[REG(0)]);
493 gen_op_stl_T0_T1(ctx
);
495 case 0x000c: /* mov.b @(R0,Rm),Rn */
496 tcg_gen_add_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], cpu_gregs
[REG(0)]);
497 gen_op_ldb_T0_T0(ctx
);
498 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
500 case 0x000d: /* mov.w @(R0,Rm),Rn */
501 tcg_gen_add_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], cpu_gregs
[REG(0)]);
502 gen_op_ldw_T0_T0(ctx
);
503 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
505 case 0x000e: /* mov.l @(R0,Rm),Rn */
506 tcg_gen_add_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], cpu_gregs
[REG(0)]);
507 gen_op_ldl_T0_T0(ctx
);
508 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
510 case 0x6008: /* swap.b Rm,Rn */
511 tcg_gen_andi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)], 0xffff0000);
512 tcg_gen_andi_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], 0xff);
513 tcg_gen_shli_i32(cpu_T
[0], cpu_T
[0], 8);
514 tcg_gen_or_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
515 tcg_gen_shri_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], 8);
516 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], 0xff);
517 tcg_gen_or_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
519 case 0x6009: /* swap.w Rm,Rn */
520 tcg_gen_andi_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], 0xffff);
521 tcg_gen_shli_i32(cpu_T
[0], cpu_T
[0], 16);
522 tcg_gen_shri_i32(cpu_T
[1], cpu_gregs
[REG(B7_4
)], 16);
523 tcg_gen_andi_i32(cpu_T
[1], cpu_T
[1], 0xffff);
524 tcg_gen_or_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0], cpu_T
[1]);
526 case 0x200d: /* xtrct Rm,Rn */
527 tcg_gen_andi_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], 0xffff);
528 tcg_gen_shli_i32(cpu_T
[0], cpu_T
[0], 16);
529 tcg_gen_shri_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)], 16);
530 tcg_gen_andi_i32(cpu_T
[1], cpu_T
[1], 0xffff);
531 tcg_gen_or_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0], cpu_T
[1]);
533 case 0x300c: /* add Rm,Rn */
534 tcg_gen_add_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)]);
536 case 0x300e: /* addc Rm,Rn */
537 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
538 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
540 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[1]);
542 case 0x300f: /* addv Rm,Rn */
543 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
544 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
546 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[1]);
548 case 0x2009: /* and Rm,Rn */
549 tcg_gen_and_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)]);
551 case 0x3000: /* cmp/eq Rm,Rn */
552 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
553 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
554 gen_op_cmp_eq_T0_T1();
556 case 0x3003: /* cmp/ge Rm,Rn */
557 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
558 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
559 gen_op_cmp_ge_T0_T1();
561 case 0x3007: /* cmp/gt Rm,Rn */
562 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
563 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
564 gen_op_cmp_gt_T0_T1();
566 case 0x3006: /* cmp/hi Rm,Rn */
567 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
568 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
569 gen_op_cmp_hi_T0_T1();
571 case 0x3002: /* cmp/hs Rm,Rn */
572 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
573 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
574 gen_op_cmp_hs_T0_T1();
576 case 0x200c: /* cmp/str Rm,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 gen_op_cmp_str_T0_T1();
581 case 0x2007: /* div0s Rm,Rn */
582 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
583 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
584 gen_op_div0s_T0_T1();
586 case 0x3004: /* div1 Rm,Rn */
587 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
588 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
590 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[1]);
592 case 0x300d: /* dmuls.l 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_dmulsl_T0_T1();
597 case 0x3005: /* dmulu.l 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_dmulul_T0_T1();
602 case 0x600e: /* exts.b Rm,Rn */
603 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
604 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], 0xff);
605 tcg_gen_ext8s_i32(cpu_T
[0], cpu_T
[0]);
606 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
608 case 0x600f: /* exts.w Rm,Rn */
609 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
610 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], 0xffff);
611 tcg_gen_ext16s_i32(cpu_T
[0], cpu_T
[0]);
612 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
614 case 0x600c: /* extu.b Rm,Rn */
615 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
616 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], 0xff);
617 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
619 case 0x600d: /* extu.w Rm,Rn */
620 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
621 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], 0xffff);
622 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
624 case 0x000f: /* mac.l @Rm+,@Rn+ */
625 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
626 gen_op_ldl_T0_T0(ctx
);
627 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
628 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
629 gen_op_ldl_T0_T0(ctx
);
631 tcg_gen_addi_i32(cpu_gregs
[REG(B7_4
)], cpu_gregs
[REG(B7_4
)], 4);
632 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
634 case 0x400f: /* mac.w @Rm+,@Rn+ */
635 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
636 gen_op_ldl_T0_T0(ctx
);
637 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
638 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
639 gen_op_ldl_T0_T0(ctx
);
641 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 2);
642 tcg_gen_addi_i32(cpu_gregs
[REG(B7_4
)], cpu_gregs
[REG(B7_4
)], 2);
644 case 0x0007: /* mul.l Rm,Rn */
645 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
646 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
649 case 0x200f: /* muls.w Rm,Rn */
650 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
651 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], 0xffff);
652 tcg_gen_ext16s_i32(cpu_T
[0], cpu_T
[0]);
653 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
654 tcg_gen_andi_i32(cpu_T
[1], cpu_T
[1], 0xffff);
655 tcg_gen_ext16s_i32(cpu_T
[1], cpu_T
[1]);
656 gen_op_mulsw_T0_T1();
658 case 0x200e: /* mulu.w Rm,Rn */
659 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
660 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], 0xffff);
661 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
662 tcg_gen_andi_i32(cpu_T
[1], cpu_T
[1], 0xffff);
663 gen_op_muluw_T0_T1();
665 case 0x600b: /* neg Rm,Rn */
666 tcg_gen_neg_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)]);
668 case 0x600a: /* negc Rm,Rn */
669 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
671 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
673 case 0x6007: /* not Rm,Rn */
674 tcg_gen_not_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)]);
676 case 0x200b: /* or Rm,Rn */
677 tcg_gen_or_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)]);
679 case 0x400c: /* shad Rm,Rn */
680 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
681 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
683 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[1]);
685 case 0x400d: /* shld Rm,Rn */
686 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
687 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
689 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[1]);
691 case 0x3008: /* sub Rm,Rn */
692 tcg_gen_sub_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)]);
694 case 0x300a: /* subc Rm,Rn */
695 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
696 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
698 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[1]);
700 case 0x300b: /* subv Rm,Rn */
701 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
702 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
704 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[1]);
706 case 0x2008: /* tst Rm,Rn */
707 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
708 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
711 case 0x200a: /* xor Rm,Rn */
712 tcg_gen_xor_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B7_4
)]);
714 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
715 if (ctx
->fpscr
& FPSCR_SZ
) {
716 gen_op_fmov_drN_DT0(XREG(B7_4
));
717 gen_op_fmov_DT0_drN(XREG(B11_8
));
719 gen_op_fmov_frN_FT0(FREG(B7_4
));
720 gen_op_fmov_FT0_frN(FREG(B11_8
));
723 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
724 if (ctx
->fpscr
& FPSCR_SZ
) {
725 gen_op_fmov_drN_DT0(XREG(B7_4
));
726 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
727 gen_op_stfq_DT0_T1(ctx
);
729 gen_op_fmov_frN_FT0(FREG(B7_4
));
730 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
731 gen_op_stfl_FT0_T1(ctx
);
734 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
735 if (ctx
->fpscr
& FPSCR_SZ
) {
736 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
737 gen_op_ldfq_T0_DT0(ctx
);
738 gen_op_fmov_DT0_drN(XREG(B11_8
));
740 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
741 gen_op_ldfl_T0_FT0(ctx
);
742 gen_op_fmov_FT0_frN(FREG(B11_8
));
745 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
746 if (ctx
->fpscr
& FPSCR_SZ
) {
747 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
748 gen_op_ldfq_T0_DT0(ctx
);
749 gen_op_fmov_DT0_drN(XREG(B11_8
));
750 tcg_gen_addi_i32(cpu_gregs
[REG(B7_4
)],
751 cpu_gregs
[REG(B7_4
)], 8);
753 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
754 gen_op_ldfl_T0_FT0(ctx
);
755 gen_op_fmov_FT0_frN(FREG(B11_8
));
756 tcg_gen_addi_i32(cpu_gregs
[REG(B7_4
)],
757 cpu_gregs
[REG(B7_4
)], 4);
760 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
761 if (ctx
->fpscr
& FPSCR_SZ
) {
762 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 8);
763 gen_op_fmov_drN_DT0(XREG(B7_4
));
764 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
765 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 8);
766 gen_op_stfq_DT0_T1(ctx
);
767 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 8);
769 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
770 gen_op_fmov_frN_FT0(FREG(B7_4
));
771 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
772 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
773 gen_op_stfl_FT0_T1(ctx
);
774 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
777 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
778 tcg_gen_add_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)], cpu_gregs
[REG(0)]);
779 if (ctx
->fpscr
& FPSCR_SZ
) {
780 gen_op_ldfq_T0_DT0(ctx
);
781 gen_op_fmov_DT0_drN(XREG(B11_8
));
783 gen_op_ldfl_T0_FT0(ctx
);
784 gen_op_fmov_FT0_frN(FREG(B11_8
));
787 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
788 if (ctx
->fpscr
& FPSCR_SZ
) {
789 gen_op_fmov_drN_DT0(XREG(B7_4
));
790 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
791 tcg_gen_add_i32(cpu_T
[1], cpu_T
[1], cpu_gregs
[REG(0)]);
792 gen_op_stfq_DT0_T1(ctx
);
794 gen_op_fmov_frN_FT0(FREG(B7_4
));
795 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
796 tcg_gen_add_i32(cpu_T
[1], cpu_T
[1], cpu_gregs
[REG(0)]);
797 gen_op_stfl_FT0_T1(ctx
);
800 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
801 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
802 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
803 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
804 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
805 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
806 if (ctx
->fpscr
& FPSCR_PR
) {
807 if (ctx
->opcode
& 0x0110)
808 break; /* illegal instruction */
809 gen_op_fmov_drN_DT1(DREG(B7_4
));
810 gen_op_fmov_drN_DT0(DREG(B11_8
));
813 gen_op_fmov_frN_FT1(FREG(B7_4
));
814 gen_op_fmov_frN_FT0(FREG(B11_8
));
817 switch (ctx
->opcode
& 0xf00f) {
818 case 0xf000: /* fadd Rm,Rn */
819 ctx
->fpscr
& FPSCR_PR
? gen_op_fadd_DT() : gen_op_fadd_FT();
821 case 0xf001: /* fsub Rm,Rn */
822 ctx
->fpscr
& FPSCR_PR
? gen_op_fsub_DT() : gen_op_fsub_FT();
824 case 0xf002: /* fmul Rm,Rn */
825 ctx
->fpscr
& FPSCR_PR
? gen_op_fmul_DT() : gen_op_fmul_FT();
827 case 0xf003: /* fdiv Rm,Rn */
828 ctx
->fpscr
& FPSCR_PR
? gen_op_fdiv_DT() : gen_op_fdiv_FT();
830 case 0xf004: /* fcmp/eq Rm,Rn */
831 ctx
->fpscr
& FPSCR_PR
? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
833 case 0xf005: /* fcmp/gt Rm,Rn */
834 ctx
->fpscr
& FPSCR_PR
? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
838 if (ctx
->fpscr
& FPSCR_PR
) {
839 gen_op_fmov_DT0_drN(DREG(B11_8
));
842 gen_op_fmov_FT0_frN(FREG(B11_8
));
847 switch (ctx
->opcode
& 0xff00) {
848 case 0xc900: /* and #imm,R0 */
849 tcg_gen_andi_i32(cpu_gregs
[REG(0)], cpu_gregs
[REG(0)], B7_0
);
851 case 0xcd00: /* and.b #imm,@(R0,GBR) */
852 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
853 gen_op_addl_GBR_T0();
854 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
855 gen_op_ldub_T0_T0(ctx
);
856 tcg_gen_andi_i32(cpu_T
[0], cpu_T
[0], B7_0
);
857 gen_op_stb_T0_T1(ctx
);
859 case 0x8b00: /* bf label */
861 gen_conditional_jump(ctx
, ctx
->pc
+ 2,
862 ctx
->pc
+ 4 + B7_0s
* 2);
863 ctx
->bstate
= BS_BRANCH
;
865 case 0x8f00: /* bf/s label */
867 gen_op_bf_s(ctx
->delayed_pc
= ctx
->pc
+ 4 + B7_0s
* 2);
868 ctx
->flags
|= DELAY_SLOT_CONDITIONAL
;
870 case 0x8900: /* bt label */
872 gen_conditional_jump(ctx
, ctx
->pc
+ 4 + B7_0s
* 2,
874 ctx
->bstate
= BS_BRANCH
;
876 case 0x8d00: /* bt/s label */
878 gen_op_bt_s(ctx
->delayed_pc
= ctx
->pc
+ 4 + B7_0s
* 2);
879 ctx
->flags
|= DELAY_SLOT_CONDITIONAL
;
881 case 0x8800: /* cmp/eq #imm,R0 */
882 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
883 gen_op_cmp_eq_imm_T0(B7_0s
);
885 case 0xc400: /* mov.b @(disp,GBR),R0 */
887 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B7_0
);
888 gen_op_ldb_T0_T0(ctx
);
889 tcg_gen_mov_i32(cpu_gregs
[REG(0)], cpu_T
[0]);
891 case 0xc500: /* mov.w @(disp,GBR),R0 */
893 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B7_0
* 2);
894 gen_op_ldw_T0_T0(ctx
);
895 tcg_gen_mov_i32(cpu_gregs
[REG(0)], cpu_T
[0]);
897 case 0xc600: /* mov.l @(disp,GBR),R0 */
899 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B7_0
* 4);
900 gen_op_ldl_T0_T0(ctx
);
901 tcg_gen_mov_i32(cpu_gregs
[REG(0)], cpu_T
[0]);
903 case 0xc000: /* mov.b R0,@(disp,GBR) */
905 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B7_0
);
906 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
907 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
908 gen_op_stb_T0_T1(ctx
);
910 case 0xc100: /* mov.w R0,@(disp,GBR) */
912 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B7_0
* 2);
913 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
914 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
915 gen_op_stw_T0_T1(ctx
);
917 case 0xc200: /* mov.l R0,@(disp,GBR) */
919 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B7_0
* 4);
920 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
921 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
922 gen_op_stl_T0_T1(ctx
);
924 case 0x8000: /* mov.b R0,@(disp,Rn) */
925 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
926 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B7_4
)]);
927 tcg_gen_addi_i32(cpu_T
[1], cpu_T
[1], B3_0
);
928 gen_op_stb_T0_T1(ctx
);
930 case 0x8100: /* mov.w R0,@(disp,Rn) */
931 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
932 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B7_4
)]);
933 tcg_gen_addi_i32(cpu_T
[1], cpu_T
[1], B3_0
* 2);
934 gen_op_stw_T0_T1(ctx
);
936 case 0x8400: /* mov.b @(disp,Rn),R0 */
937 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
938 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B3_0
);
939 gen_op_ldb_T0_T0(ctx
);
940 tcg_gen_mov_i32(cpu_gregs
[REG(0)], cpu_T
[0]);
942 case 0x8500: /* mov.w @(disp,Rn),R0 */
943 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B7_4
)]);
944 tcg_gen_addi_i32(cpu_T
[0], cpu_T
[0], B3_0
* 2);
945 gen_op_ldw_T0_T0(ctx
);
946 tcg_gen_mov_i32(cpu_gregs
[REG(0)], cpu_T
[0]);
948 case 0xc700: /* mova @(disp,PC),R0 */
949 tcg_gen_movi_i32(cpu_gregs
[REG(0)],
950 ((ctx
->pc
& 0xfffffffc) + 4 + B7_0
* 4) & ~3);
952 case 0xcb00: /* or #imm,R0 */
953 tcg_gen_ori_i32(cpu_gregs
[REG(0)], cpu_gregs
[REG(0)], B7_0
);
955 case 0xcf00: /* or.b #imm,@(R0,GBR) */
956 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
957 gen_op_addl_GBR_T0();
958 tcg_gen_mov_i32(cpu_T
[0], cpu_T
[1]);
959 gen_op_ldub_T0_T0(ctx
);
960 tcg_gen_ori_i32(cpu_T
[0], cpu_T
[0], B7_0
);
961 gen_op_stb_T0_T1(ctx
);
963 case 0xc300: /* trapa #imm */
964 CHECK_NOT_DELAY_SLOT
gen_op_movl_imm_PC(ctx
->pc
);
966 ctx
->bstate
= BS_BRANCH
;
968 case 0xc800: /* tst #imm,R0 */
969 gen_op_tst_imm_rN(B7_0
, REG(0));
971 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
972 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
973 gen_op_addl_GBR_T0();
974 gen_op_ldub_T0_T0(ctx
);
975 gen_op_tst_imm_T0(B7_0
);
977 case 0xca00: /* xor #imm,R0 */
978 tcg_gen_xori_i32(cpu_gregs
[REG(0)], cpu_gregs
[REG(0)], B7_0
);
980 case 0xce00: /* xor.b #imm,@(R0,GBR) */
981 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
982 gen_op_addl_GBR_T0();
983 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
984 gen_op_ldub_T0_T0(ctx
);
985 tcg_gen_xori_i32(cpu_T
[0], cpu_T
[0], B7_0
);
986 gen_op_stb_T0_T1(ctx
);
990 switch (ctx
->opcode
& 0xf08f) {
991 case 0x408e: /* ldc Rm,Rn_BANK */
992 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
993 tcg_gen_mov_i32(cpu_gregs
[ALTREG(B6_4
)], cpu_T
[0]);
995 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
996 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
997 gen_op_ldl_T0_T0(ctx
);
998 tcg_gen_mov_i32(cpu_gregs
[ALTREG(B6_4
)], cpu_T
[0]);
999 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
1001 case 0x0082: /* stc Rm_BANK,Rn */
1002 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[ALTREG(B6_4
)]);
1003 tcg_gen_mov_i32(cpu_gregs
[REG(B11_8
)], cpu_T
[0]);
1005 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1006 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
1007 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
1008 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[ALTREG(B6_4
)]);
1009 tcg_gen_addi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
1010 gen_op_stl_T0_T1(ctx
);
1011 tcg_gen_subi_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 4);
1015 switch (ctx
->opcode
& 0xf0ff) {
1016 case 0x0023: /* braf Rn */
1017 CHECK_NOT_DELAY_SLOT
tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1018 gen_op_braf_T0(ctx
->pc
+ 4);
1019 ctx
->flags
|= DELAY_SLOT
;
1020 ctx
->delayed_pc
= (uint32_t) - 1;
1022 case 0x0003: /* bsrf Rn */
1023 CHECK_NOT_DELAY_SLOT
tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1024 gen_op_bsrf_T0(ctx
->pc
+ 4);
1025 ctx
->flags
|= DELAY_SLOT
;
1026 ctx
->delayed_pc
= (uint32_t) - 1;
1028 case 0x4015: /* cmp/pl Rn */
1029 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1032 case 0x4011: /* cmp/pz Rn */
1033 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1036 case 0x4010: /* dt Rn */
1037 gen_op_dt_rN(REG(B11_8
));
1039 case 0x402b: /* jmp @Rn */
1040 CHECK_NOT_DELAY_SLOT
tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1042 ctx
->flags
|= DELAY_SLOT
;
1043 ctx
->delayed_pc
= (uint32_t) - 1;
1045 case 0x400b: /* jsr @Rn */
1046 CHECK_NOT_DELAY_SLOT
tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1047 gen_op_jsr_T0(ctx
->pc
+ 4);
1048 ctx
->flags
|= DELAY_SLOT
;
1049 ctx
->delayed_pc
= (uint32_t) - 1;
1051 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1053 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1054 gen_op_##ldop##_T0_##reg (); \
1058 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1059 gen_op_ldl_T0_T0 (ctx); \
1060 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1061 cpu_gregs[REG(B11_8)], 4); \
1062 gen_op_##ldop##_T0_##reg (); \
1066 gen_op_##stop##_##reg##_T0 (); \
1067 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]); \
1070 gen_op_##stop##_##reg##_T0 (); \
1071 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1072 cpu_gregs[REG(B11_8)], 4); \
1073 tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]); \
1074 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1075 cpu_gregs[REG(B11_8)], 4); \
1076 gen_op_stl_T0_T1 (ctx); \
1077 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1078 cpu_gregs[REG(B11_8)], 4); \
1080 LDST(sr
, 0x400e, 0x4007, ldc
, 0x0002, 0x4003, stc
, ctx
->bstate
=
1082 LDST(gbr
, 0x401e, 0x4017, ldc
, 0x0012, 0x4013, stc
,)
1083 LDST(vbr
, 0x402e, 0x4027, ldc
, 0x0022, 0x4023, stc
,)
1084 LDST(ssr
, 0x403e, 0x4037, ldc
, 0x0032, 0x4033, stc
,)
1085 LDST(spc
, 0x404e, 0x4047, ldc
, 0x0042, 0x4043, stc
,)
1086 LDST(dbr
, 0x40fa, 0x40f6, ldc
, 0x00fa, 0x40f2, stc
,)
1087 LDST(mach
, 0x400a, 0x4006, lds
, 0x000a, 0x4002, sts
,)
1088 LDST(macl
, 0x401a, 0x4016, lds
, 0x001a, 0x4012, sts
,)
1089 LDST(pr
, 0x402a, 0x4026, lds
, 0x002a, 0x4022, sts
,)
1090 LDST(fpul
, 0x405a, 0x4056, lds
, 0x005a, 0x4052, sts
,)
1091 LDST(fpscr
, 0x406a, 0x4066, lds
, 0x006a, 0x4062, sts
, ctx
->bstate
=
1093 case 0x00c3: /* movca.l R0,@Rm */
1094 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(0)]);
1095 tcg_gen_mov_i32(cpu_T
[1], cpu_gregs
[REG(B11_8
)]);
1096 gen_op_stl_T0_T1(ctx
);
1098 case 0x0029: /* movt Rn */
1099 gen_op_movt_rN(REG(B11_8
));
1101 case 0x0093: /* ocbi @Rn */
1102 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1103 gen_op_ldl_T0_T0(ctx
);
1105 case 0x00a3: /* ocbp @Rn */
1106 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1107 gen_op_ldl_T0_T0(ctx
);
1109 case 0x00b3: /* ocbwb @Rn */
1110 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1111 gen_op_ldl_T0_T0(ctx
);
1113 case 0x0083: /* pref @Rn */
1115 case 0x4024: /* rotcl Rn */
1116 gen_op_rotcl_Rn(REG(B11_8
));
1118 case 0x4025: /* rotcr Rn */
1119 gen_op_rotcr_Rn(REG(B11_8
));
1121 case 0x4004: /* rotl Rn */
1122 gen_op_rotl_Rn(REG(B11_8
));
1124 case 0x4005: /* rotr Rn */
1125 gen_op_rotr_Rn(REG(B11_8
));
1127 case 0x4000: /* shll Rn */
1128 case 0x4020: /* shal Rn */
1129 gen_op_shal_Rn(REG(B11_8
));
1131 case 0x4021: /* shar Rn */
1132 gen_op_shar_Rn(REG(B11_8
));
1134 case 0x4001: /* shlr Rn */
1135 gen_op_shlr_Rn(REG(B11_8
));
1137 case 0x4008: /* shll2 Rn */
1138 tcg_gen_shli_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 2);
1140 case 0x4018: /* shll8 Rn */
1141 tcg_gen_shli_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 8);
1143 case 0x4028: /* shll16 Rn */
1144 tcg_gen_shli_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 16);
1146 case 0x4009: /* shlr2 Rn */
1147 tcg_gen_shri_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 2);
1149 case 0x4019: /* shlr8 Rn */
1150 tcg_gen_shri_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 8);
1152 case 0x4029: /* shlr16 Rn */
1153 tcg_gen_shri_i32(cpu_gregs
[REG(B11_8
)], cpu_gregs
[REG(B11_8
)], 16);
1155 case 0x401b: /* tas.b @Rn */
1156 tcg_gen_mov_i32(cpu_T
[0], cpu_gregs
[REG(B11_8
)]);
1157 tcg_gen_mov_i32(cpu_T
[1], cpu_T
[0]);
1158 gen_op_ldub_T0_T0(ctx
);
1159 gen_op_cmp_eq_imm_T0(0);
1160 tcg_gen_ori_i32(cpu_T
[0], cpu_T
[0], 0x80);
1161 gen_op_stb_T0_T1(ctx
);
1163 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1164 gen_op_movl_fpul_FT0();
1165 gen_op_fmov_FT0_frN(FREG(B11_8
));
1167 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1168 gen_op_fmov_frN_FT0(FREG(B11_8
));
1169 gen_op_movl_FT0_fpul();
1171 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1172 if (ctx
->fpscr
& FPSCR_PR
) {
1173 if (ctx
->opcode
& 0x0100)
1174 break; /* illegal instruction */
1176 gen_op_fmov_DT0_drN(DREG(B11_8
));
1180 gen_op_fmov_FT0_frN(FREG(B11_8
));
1183 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1184 if (ctx
->fpscr
& FPSCR_PR
) {
1185 if (ctx
->opcode
& 0x0100)
1186 break; /* illegal instruction */
1187 gen_op_fmov_drN_DT0(DREG(B11_8
));
1191 gen_op_fmov_frN_FT0(FREG(B11_8
));
1195 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1196 gen_op_fneg_frN(FREG(B11_8
));
1198 case 0xf05d: /* fabs FRn/DRn */
1199 if (ctx
->fpscr
& FPSCR_PR
) {
1200 if (ctx
->opcode
& 0x0100)
1201 break; /* illegal instruction */
1202 gen_op_fmov_drN_DT0(DREG(B11_8
));
1204 gen_op_fmov_DT0_drN(DREG(B11_8
));
1206 gen_op_fmov_frN_FT0(FREG(B11_8
));
1208 gen_op_fmov_FT0_frN(FREG(B11_8
));
1211 case 0xf06d: /* fsqrt FRn */
1212 if (ctx
->fpscr
& FPSCR_PR
) {
1213 if (ctx
->opcode
& 0x0100)
1214 break; /* illegal instruction */
1215 gen_op_fmov_drN_DT0(FREG(B11_8
));
1217 gen_op_fmov_DT0_drN(FREG(B11_8
));
1219 gen_op_fmov_frN_FT0(FREG(B11_8
));
1221 gen_op_fmov_FT0_frN(FREG(B11_8
));
1224 case 0xf07d: /* fsrra FRn */
1226 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1227 if (!(ctx
->fpscr
& FPSCR_PR
)) {
1228 tcg_gen_movi_i32(cpu_T
[0], 0);
1229 gen_op_fmov_T0_frN(FREG(B11_8
));
1233 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1234 if (!(ctx
->fpscr
& FPSCR_PR
)) {
1235 tcg_gen_movi_i32(cpu_T
[0], 0x3f800000);
1236 gen_op_fmov_T0_frN(FREG(B11_8
));
1240 case 0xf0ad: /* fcnvsd FPUL,DRn */
1241 gen_op_movl_fpul_FT0();
1242 gen_op_fcnvsd_FT_DT();
1243 gen_op_fmov_DT0_drN(DREG(B11_8
));
1245 case 0xf0bd: /* fcnvds DRn,FPUL */
1246 gen_op_fmov_drN_DT0(DREG(B11_8
));
1247 gen_op_fcnvds_DT_FT();
1248 gen_op_movl_FT0_fpul();
1252 fprintf(stderr
, "unknown instruction 0x%04x at pc 0x%08x\n",
1253 ctx
->opcode
, ctx
->pc
);
1254 gen_op_raise_illegal_instruction();
1255 ctx
->bstate
= BS_EXCP
;
1258 void decode_opc(DisasContext
* ctx
)
1260 uint32_t old_flags
= ctx
->flags
;
1264 if (old_flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
)) {
1265 if (ctx
->flags
& DELAY_SLOT_CLEARME
) {
1266 gen_op_store_flags(0);
1268 /* go out of the delay slot */
1269 uint32_t new_flags
= ctx
->flags
;
1270 new_flags
&= ~(DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
);
1271 gen_op_store_flags(new_flags
);
1274 ctx
->bstate
= BS_BRANCH
;
1275 if (old_flags
& DELAY_SLOT_CONDITIONAL
) {
1276 gen_delayed_conditional_jump(ctx
);
1277 } else if (old_flags
& DELAY_SLOT
) {
1283 /* go into a delay slot */
1284 if (ctx
->flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
))
1285 gen_op_store_flags(ctx
->flags
);
1289 gen_intermediate_code_internal(CPUState
* env
, TranslationBlock
* tb
,
1293 target_ulong pc_start
;
1294 static uint16_t *gen_opc_end
;
1300 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
1302 ctx
.flags
= (uint32_t)tb
->flags
;
1303 ctx
.bstate
= BS_NONE
;
1305 ctx
.fpscr
= env
->fpscr
;
1306 ctx
.memidx
= (env
->sr
& SR_MD
) ? 1 : 0;
1307 /* We don't know if the delayed pc came from a dynamic or static branch,
1308 so assume it is a dynamic branch. */
1309 ctx
.delayed_pc
= -1; /* use delayed pc from env pointer */
1311 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
1314 if (loglevel
& CPU_LOG_TB_CPU
) {
1316 "------------------------------------------------\n");
1317 cpu_dump_state(env
, logfile
, fprintf
, 0);
1323 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
1325 max_insns
= CF_COUNT_MASK
;
1327 while (ctx
.bstate
== BS_NONE
&& gen_opc_ptr
< gen_opc_end
) {
1328 if (env
->nb_breakpoints
> 0) {
1329 for (i
= 0; i
< env
->nb_breakpoints
; i
++) {
1330 if (ctx
.pc
== env
->breakpoints
[i
]) {
1331 /* We have hit a breakpoint - make sure PC is up-to-date */
1332 gen_op_movl_imm_PC(ctx
.pc
);
1334 ctx
.bstate
= BS_EXCP
;
1340 i
= gen_opc_ptr
- gen_opc_buf
;
1344 gen_opc_instr_start
[ii
++] = 0;
1346 gen_opc_pc
[ii
] = ctx
.pc
;
1347 gen_opc_hflags
[ii
] = ctx
.flags
;
1348 gen_opc_instr_start
[ii
] = 1;
1349 gen_opc_icount
[ii
] = num_insns
;
1351 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
1354 fprintf(stderr
, "Loading opcode at address 0x%08x\n", ctx
.pc
);
1357 ctx
.opcode
= lduw_code(ctx
.pc
);
1361 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
1363 if (env
->singlestep_enabled
)
1365 if (num_insns
>= max_insns
)
1367 #ifdef SH4_SINGLE_STEP
1371 if (tb
->cflags
& CF_LAST_IO
)
1373 if (env
->singlestep_enabled
) {
1376 switch (ctx
.bstate
) {
1378 /* gen_op_interrupt_restart(); */
1382 gen_op_store_flags(ctx
.flags
| DELAY_SLOT_CLEARME
);
1384 gen_goto_tb(&ctx
, 0, ctx
.pc
);
1387 /* gen_op_interrupt_restart(); */
1396 gen_icount_end(tb
, num_insns
);
1397 *gen_opc_ptr
= INDEX_op_end
;
1399 i
= gen_opc_ptr
- gen_opc_buf
;
1402 gen_opc_instr_start
[ii
++] = 0;
1404 tb
->size
= ctx
.pc
- pc_start
;
1405 tb
->icount
= num_insns
;
1409 #ifdef SH4_DEBUG_DISAS
1410 if (loglevel
& CPU_LOG_TB_IN_ASM
)
1411 fprintf(logfile
, "\n");
1413 if (loglevel
& CPU_LOG_TB_IN_ASM
) {
1414 fprintf(logfile
, "IN:\n"); /* , lookup_symbol(pc_start)); */
1415 target_disas(logfile
, pc_start
, ctx
.pc
- pc_start
, 0);
1416 fprintf(logfile
, "\n");
1421 void gen_intermediate_code(CPUState
* env
, struct TranslationBlock
*tb
)
1423 gen_intermediate_code_internal(env
, tb
, 0);
1426 void gen_intermediate_code_pc(CPUState
* env
, struct TranslationBlock
*tb
)
1428 gen_intermediate_code_internal(env
, tb
, 1);
1431 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
1432 unsigned long searched_pc
, int pc_pos
, void *puc
)
1434 env
->pc
= gen_opc_pc
[pc_pos
];
1435 env
->flags
= gen_opc_hflags
[pc_pos
];