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, see <http://www.gnu.org/licenses/>.
26 #define SH4_DEBUG_DISAS
27 //#define SH4_SINGLE_STEP
33 #include "qemu-common.h"
39 typedef struct DisasContext
{
40 struct TranslationBlock
*tb
;
49 int singlestep_enabled
;
54 #if defined(CONFIG_USER_ONLY)
55 #define IS_USER(ctx) 1
57 #define IS_USER(ctx) (!(ctx->sr & SR_MD))
61 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
64 BS_STOP
= 1, /* We want to stop translation for any reason */
65 BS_BRANCH
= 2, /* We reached a branch condition */
66 BS_EXCP
= 3, /* We reached an exception condition */
69 /* global register indexes */
70 static TCGv_ptr cpu_env
;
71 static TCGv cpu_gregs
[24];
72 static TCGv cpu_pc
, cpu_sr
, cpu_ssr
, cpu_spc
, cpu_gbr
;
73 static TCGv cpu_vbr
, cpu_sgr
, cpu_dbr
, cpu_mach
, cpu_macl
;
74 static TCGv cpu_pr
, cpu_fpscr
, cpu_fpul
, cpu_ldst
;
75 static TCGv cpu_fregs
[32];
77 /* internal register indexes */
78 static TCGv cpu_flags
, cpu_delayed_pc
;
80 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
82 #include "gen-icount.h"
84 static void sh4_translate_init(void)
87 static int done_init
= 0;
88 static const char * const gregnames
[24] = {
89 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
90 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
91 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
92 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
93 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
95 static const char * const fregnames
[32] = {
96 "FPR0_BANK0", "FPR1_BANK0", "FPR2_BANK0", "FPR3_BANK0",
97 "FPR4_BANK0", "FPR5_BANK0", "FPR6_BANK0", "FPR7_BANK0",
98 "FPR8_BANK0", "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
99 "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
100 "FPR0_BANK1", "FPR1_BANK1", "FPR2_BANK1", "FPR3_BANK1",
101 "FPR4_BANK1", "FPR5_BANK1", "FPR6_BANK1", "FPR7_BANK1",
102 "FPR8_BANK1", "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
103 "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
109 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
111 for (i
= 0; i
< 24; i
++)
112 cpu_gregs
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
113 offsetof(CPUState
, gregs
[i
]),
116 cpu_pc
= tcg_global_mem_new_i32(TCG_AREG0
,
117 offsetof(CPUState
, pc
), "PC");
118 cpu_sr
= tcg_global_mem_new_i32(TCG_AREG0
,
119 offsetof(CPUState
, sr
), "SR");
120 cpu_ssr
= tcg_global_mem_new_i32(TCG_AREG0
,
121 offsetof(CPUState
, ssr
), "SSR");
122 cpu_spc
= tcg_global_mem_new_i32(TCG_AREG0
,
123 offsetof(CPUState
, spc
), "SPC");
124 cpu_gbr
= tcg_global_mem_new_i32(TCG_AREG0
,
125 offsetof(CPUState
, gbr
), "GBR");
126 cpu_vbr
= tcg_global_mem_new_i32(TCG_AREG0
,
127 offsetof(CPUState
, vbr
), "VBR");
128 cpu_sgr
= tcg_global_mem_new_i32(TCG_AREG0
,
129 offsetof(CPUState
, sgr
), "SGR");
130 cpu_dbr
= tcg_global_mem_new_i32(TCG_AREG0
,
131 offsetof(CPUState
, dbr
), "DBR");
132 cpu_mach
= tcg_global_mem_new_i32(TCG_AREG0
,
133 offsetof(CPUState
, mach
), "MACH");
134 cpu_macl
= tcg_global_mem_new_i32(TCG_AREG0
,
135 offsetof(CPUState
, macl
), "MACL");
136 cpu_pr
= tcg_global_mem_new_i32(TCG_AREG0
,
137 offsetof(CPUState
, pr
), "PR");
138 cpu_fpscr
= tcg_global_mem_new_i32(TCG_AREG0
,
139 offsetof(CPUState
, fpscr
), "FPSCR");
140 cpu_fpul
= tcg_global_mem_new_i32(TCG_AREG0
,
141 offsetof(CPUState
, fpul
), "FPUL");
143 cpu_flags
= tcg_global_mem_new_i32(TCG_AREG0
,
144 offsetof(CPUState
, flags
), "_flags_");
145 cpu_delayed_pc
= tcg_global_mem_new_i32(TCG_AREG0
,
146 offsetof(CPUState
, delayed_pc
),
148 cpu_ldst
= tcg_global_mem_new_i32(TCG_AREG0
,
149 offsetof(CPUState
, ldst
), "_ldst_");
151 for (i
= 0; i
< 32; i
++)
152 cpu_fregs
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
153 offsetof(CPUState
, fregs
[i
]),
156 /* register helpers */
163 void cpu_dump_state(CPUState
* env
, FILE * f
,
164 int (*cpu_fprintf
) (FILE * f
, const char *fmt
, ...),
168 cpu_fprintf(f
, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
169 env
->pc
, env
->sr
, env
->pr
, env
->fpscr
);
170 cpu_fprintf(f
, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
171 env
->spc
, env
->ssr
, env
->gbr
, env
->vbr
);
172 cpu_fprintf(f
, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
173 env
->sgr
, env
->dbr
, env
->delayed_pc
, env
->fpul
);
174 for (i
= 0; i
< 24; i
+= 4) {
175 cpu_fprintf(f
, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
176 i
, env
->gregs
[i
], i
+ 1, env
->gregs
[i
+ 1],
177 i
+ 2, env
->gregs
[i
+ 2], i
+ 3, env
->gregs
[i
+ 3]);
179 if (env
->flags
& DELAY_SLOT
) {
180 cpu_fprintf(f
, "in delay slot (delayed_pc=0x%08x)\n",
182 } else if (env
->flags
& DELAY_SLOT_CONDITIONAL
) {
183 cpu_fprintf(f
, "in conditional delay slot (delayed_pc=0x%08x)\n",
188 void cpu_reset(CPUSH4State
* env
)
190 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
191 qemu_log("CPU Reset (CPU %d)\n", env
->cpu_index
);
192 log_cpu_state(env
, 0);
195 memset(env
, 0, offsetof(CPUSH4State
, breakpoints
));
198 env
->pc
= 0xA0000000;
199 #if defined(CONFIG_USER_ONLY)
200 env
->fpscr
= FPSCR_PR
; /* value for userspace according to the kernel */
201 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
); /* ?! */
203 env
->sr
= SR_MD
| SR_RB
| SR_BL
| SR_I3
| SR_I2
| SR_I1
| SR_I0
;
204 env
->fpscr
= FPSCR_DN
| FPSCR_RM_ZERO
; /* CPU reset value according to SH4 manual */
205 set_float_rounding_mode(float_round_to_zero
, &env
->fp_status
);
206 set_flush_to_zero(1, &env
->fp_status
);
208 set_default_nan_mode(1, &env
->fp_status
);
220 static sh4_def_t sh4_defs
[] = {
223 .id
= SH_CPU_SH7750R
,
227 .features
= SH_FEATURE_BCR3_AND_BCR4
,
230 .id
= SH_CPU_SH7751R
,
233 .cvr
= 0x00110000, /* Neutered caches, should be 0x20480000 */
234 .features
= SH_FEATURE_BCR3_AND_BCR4
,
241 .features
= SH_FEATURE_SH4A
,
245 static const sh4_def_t
*cpu_sh4_find_by_name(const char *name
)
249 if (strcasecmp(name
, "any") == 0)
252 for (i
= 0; i
< ARRAY_SIZE(sh4_defs
); i
++)
253 if (strcasecmp(name
, sh4_defs
[i
].name
) == 0)
259 void sh4_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
263 for (i
= 0; i
< ARRAY_SIZE(sh4_defs
); i
++)
264 (*cpu_fprintf
)(f
, "%s\n", sh4_defs
[i
].name
);
267 static void cpu_register(CPUSH4State
*env
, const sh4_def_t
*def
)
275 CPUSH4State
*cpu_sh4_init(const char *cpu_model
)
278 const sh4_def_t
*def
;
280 def
= cpu_sh4_find_by_name(cpu_model
);
283 env
= qemu_mallocz(sizeof(CPUSH4State
));
284 env
->features
= def
->features
;
286 env
->movcal_backup_tail
= &(env
->movcal_backup
);
287 sh4_translate_init();
288 env
->cpu_model_str
= cpu_model
;
290 cpu_register(env
, def
);
295 static void gen_goto_tb(DisasContext
* ctx
, int n
, target_ulong dest
)
297 TranslationBlock
*tb
;
300 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
301 !ctx
->singlestep_enabled
) {
302 /* Use a direct jump if in same page and singlestep not enabled */
304 tcg_gen_movi_i32(cpu_pc
, dest
);
305 tcg_gen_exit_tb((long) tb
+ n
);
307 tcg_gen_movi_i32(cpu_pc
, dest
);
308 if (ctx
->singlestep_enabled
)
314 static void gen_jump(DisasContext
* ctx
)
316 if (ctx
->delayed_pc
== (uint32_t) - 1) {
317 /* Target is not statically known, it comes necessarily from a
318 delayed jump as immediate jump are conditinal jumps */
319 tcg_gen_mov_i32(cpu_pc
, cpu_delayed_pc
);
320 if (ctx
->singlestep_enabled
)
324 gen_goto_tb(ctx
, 0, ctx
->delayed_pc
);
328 static inline void gen_branch_slot(uint32_t delayed_pc
, int t
)
331 int label
= gen_new_label();
332 tcg_gen_movi_i32(cpu_delayed_pc
, delayed_pc
);
334 tcg_gen_andi_i32(sr
, cpu_sr
, SR_T
);
335 tcg_gen_brcondi_i32(t
? TCG_COND_EQ
:TCG_COND_NE
, sr
, 0, label
);
336 tcg_gen_ori_i32(cpu_flags
, cpu_flags
, DELAY_SLOT_TRUE
);
337 gen_set_label(label
);
340 /* Immediate conditional jump (bt or bf) */
341 static void gen_conditional_jump(DisasContext
* ctx
,
342 target_ulong ift
, target_ulong ifnott
)
347 l1
= gen_new_label();
349 tcg_gen_andi_i32(sr
, cpu_sr
, SR_T
);
350 tcg_gen_brcondi_i32(TCG_COND_NE
, sr
, 0, l1
);
351 gen_goto_tb(ctx
, 0, ifnott
);
353 gen_goto_tb(ctx
, 1, ift
);
356 /* Delayed conditional jump (bt or bf) */
357 static void gen_delayed_conditional_jump(DisasContext
* ctx
)
362 l1
= gen_new_label();
364 tcg_gen_andi_i32(ds
, cpu_flags
, DELAY_SLOT_TRUE
);
365 tcg_gen_brcondi_i32(TCG_COND_NE
, ds
, 0, l1
);
366 gen_goto_tb(ctx
, 1, ctx
->pc
+ 2);
368 tcg_gen_andi_i32(cpu_flags
, cpu_flags
, ~DELAY_SLOT_TRUE
);
372 static inline void gen_set_t(void)
374 tcg_gen_ori_i32(cpu_sr
, cpu_sr
, SR_T
);
377 static inline void gen_clr_t(void)
379 tcg_gen_andi_i32(cpu_sr
, cpu_sr
, ~SR_T
);
382 static inline void gen_cmp(int cond
, TCGv t0
, TCGv t1
)
384 int label1
= gen_new_label();
385 int label2
= gen_new_label();
386 tcg_gen_brcond_i32(cond
, t1
, t0
, label1
);
389 gen_set_label(label1
);
391 gen_set_label(label2
);
394 static inline void gen_cmp_imm(int cond
, TCGv t0
, int32_t imm
)
396 int label1
= gen_new_label();
397 int label2
= gen_new_label();
398 tcg_gen_brcondi_i32(cond
, t0
, imm
, label1
);
401 gen_set_label(label1
);
403 gen_set_label(label2
);
406 static inline void gen_store_flags(uint32_t flags
)
408 tcg_gen_andi_i32(cpu_flags
, cpu_flags
, DELAY_SLOT_TRUE
);
409 tcg_gen_ori_i32(cpu_flags
, cpu_flags
, flags
);
412 static inline void gen_copy_bit_i32(TCGv t0
, int p0
, TCGv t1
, int p1
)
414 TCGv tmp
= tcg_temp_new();
419 tcg_gen_andi_i32(tmp
, t1
, (1 << p1
));
420 tcg_gen_andi_i32(t0
, t0
, ~(1 << p0
));
422 tcg_gen_shri_i32(tmp
, tmp
, p1
- p0
);
424 tcg_gen_shli_i32(tmp
, tmp
, p0
- p1
);
425 tcg_gen_or_i32(t0
, t0
, tmp
);
430 static inline void gen_load_fpr64(TCGv_i64 t
, int reg
)
432 tcg_gen_concat_i32_i64(t
, cpu_fregs
[reg
+ 1], cpu_fregs
[reg
]);
435 static inline void gen_store_fpr64 (TCGv_i64 t
, int reg
)
437 TCGv_i32 tmp
= tcg_temp_new_i32();
438 tcg_gen_trunc_i64_i32(tmp
, t
);
439 tcg_gen_mov_i32(cpu_fregs
[reg
+ 1], tmp
);
440 tcg_gen_shri_i64(t
, t
, 32);
441 tcg_gen_trunc_i64_i32(tmp
, t
);
442 tcg_gen_mov_i32(cpu_fregs
[reg
], tmp
);
443 tcg_temp_free_i32(tmp
);
446 #define B3_0 (ctx->opcode & 0xf)
447 #define B6_4 ((ctx->opcode >> 4) & 0x7)
448 #define B7_4 ((ctx->opcode >> 4) & 0xf)
449 #define B7_0 (ctx->opcode & 0xff)
450 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
451 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
452 (ctx->opcode & 0xfff))
453 #define B11_8 ((ctx->opcode >> 8) & 0xf)
454 #define B15_12 ((ctx->opcode >> 12) & 0xf)
456 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
457 (cpu_gregs[x + 16]) : (cpu_gregs[x]))
459 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
460 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
462 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
463 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
464 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
465 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
467 #define CHECK_NOT_DELAY_SLOT \
468 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
470 gen_helper_raise_slot_illegal_instruction(); \
471 ctx->bstate = BS_EXCP; \
475 #define CHECK_PRIVILEGED \
476 if (IS_USER(ctx)) { \
477 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
478 gen_helper_raise_slot_illegal_instruction(); \
480 gen_helper_raise_illegal_instruction(); \
482 ctx->bstate = BS_EXCP; \
486 #define CHECK_FPU_ENABLED \
487 if (ctx->flags & SR_FD) { \
488 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
489 gen_helper_raise_slot_fpu_disable(); \
491 gen_helper_raise_fpu_disable(); \
493 ctx->bstate = BS_EXCP; \
497 static void _decode_opc(DisasContext
* ctx
)
499 /* This code tries to make movcal emulation sufficiently
500 accurate for Linux purposes. This instruction writes
501 memory, and prior to that, always allocates a cache line.
502 It is used in two contexts:
503 - in memcpy, where data is copied in blocks, the first write
504 of to a block uses movca.l for performance.
505 - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
506 to flush the cache. Here, the data written by movcal.l is never
507 written to memory, and the data written is just bogus.
509 To simulate this, we simulate movcal.l, we store the value to memory,
510 but we also remember the previous content. If we see ocbi, we check
511 if movcal.l for that address was done previously. If so, the write should
512 not have hit the memory, so we restore the previous content.
513 When we see an instruction that is neither movca.l
514 nor ocbi, the previous content is discarded.
516 To optimize, we only try to flush stores when we're at the start of
517 TB, or if we already saw movca.l in this TB and did not flush stores
521 int opcode
= ctx
->opcode
& 0xf0ff;
522 if (opcode
!= 0x0093 /* ocbi */
523 && opcode
!= 0x00c3 /* movca.l */)
525 gen_helper_discard_movcal_backup ();
531 fprintf(stderr
, "Translating opcode 0x%04x\n", ctx
->opcode
);
534 switch (ctx
->opcode
) {
535 case 0x0019: /* div0u */
536 tcg_gen_andi_i32(cpu_sr
, cpu_sr
, ~(SR_M
| SR_Q
| SR_T
));
538 case 0x000b: /* rts */
540 tcg_gen_mov_i32(cpu_delayed_pc
, cpu_pr
);
541 ctx
->flags
|= DELAY_SLOT
;
542 ctx
->delayed_pc
= (uint32_t) - 1;
544 case 0x0028: /* clrmac */
545 tcg_gen_movi_i32(cpu_mach
, 0);
546 tcg_gen_movi_i32(cpu_macl
, 0);
548 case 0x0048: /* clrs */
549 tcg_gen_andi_i32(cpu_sr
, cpu_sr
, ~SR_S
);
551 case 0x0008: /* clrt */
554 case 0x0038: /* ldtlb */
558 case 0x002b: /* rte */
561 tcg_gen_mov_i32(cpu_sr
, cpu_ssr
);
562 tcg_gen_mov_i32(cpu_delayed_pc
, cpu_spc
);
563 ctx
->flags
|= DELAY_SLOT
;
564 ctx
->delayed_pc
= (uint32_t) - 1;
566 case 0x0058: /* sets */
567 tcg_gen_ori_i32(cpu_sr
, cpu_sr
, SR_S
);
569 case 0x0018: /* sett */
572 case 0xfbfd: /* frchg */
573 tcg_gen_xori_i32(cpu_fpscr
, cpu_fpscr
, FPSCR_FR
);
574 ctx
->bstate
= BS_STOP
;
576 case 0xf3fd: /* fschg */
577 tcg_gen_xori_i32(cpu_fpscr
, cpu_fpscr
, FPSCR_SZ
);
578 ctx
->bstate
= BS_STOP
;
580 case 0x0009: /* nop */
582 case 0x001b: /* sleep */
584 gen_helper_sleep(tcg_const_i32(ctx
->pc
+ 2));
588 switch (ctx
->opcode
& 0xf000) {
589 case 0x1000: /* mov.l Rm,@(disp,Rn) */
591 TCGv addr
= tcg_temp_new();
592 tcg_gen_addi_i32(addr
, REG(B11_8
), B3_0
* 4);
593 tcg_gen_qemu_st32(REG(B7_4
), addr
, ctx
->memidx
);
597 case 0x5000: /* mov.l @(disp,Rm),Rn */
599 TCGv addr
= tcg_temp_new();
600 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 4);
601 tcg_gen_qemu_ld32s(REG(B11_8
), addr
, ctx
->memidx
);
605 case 0xe000: /* mov #imm,Rn */
606 tcg_gen_movi_i32(REG(B11_8
), B7_0s
);
608 case 0x9000: /* mov.w @(disp,PC),Rn */
610 TCGv addr
= tcg_const_i32(ctx
->pc
+ 4 + B7_0
* 2);
611 tcg_gen_qemu_ld16s(REG(B11_8
), addr
, ctx
->memidx
);
615 case 0xd000: /* mov.l @(disp,PC),Rn */
617 TCGv addr
= tcg_const_i32((ctx
->pc
+ 4 + B7_0
* 4) & ~3);
618 tcg_gen_qemu_ld32s(REG(B11_8
), addr
, ctx
->memidx
);
622 case 0x7000: /* add #imm,Rn */
623 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), B7_0s
);
625 case 0xa000: /* bra disp */
627 ctx
->delayed_pc
= ctx
->pc
+ 4 + B11_0s
* 2;
628 tcg_gen_movi_i32(cpu_delayed_pc
, ctx
->delayed_pc
);
629 ctx
->flags
|= DELAY_SLOT
;
631 case 0xb000: /* bsr disp */
633 tcg_gen_movi_i32(cpu_pr
, ctx
->pc
+ 4);
634 ctx
->delayed_pc
= ctx
->pc
+ 4 + B11_0s
* 2;
635 tcg_gen_movi_i32(cpu_delayed_pc
, ctx
->delayed_pc
);
636 ctx
->flags
|= DELAY_SLOT
;
640 switch (ctx
->opcode
& 0xf00f) {
641 case 0x6003: /* mov Rm,Rn */
642 tcg_gen_mov_i32(REG(B11_8
), REG(B7_4
));
644 case 0x2000: /* mov.b Rm,@Rn */
645 tcg_gen_qemu_st8(REG(B7_4
), REG(B11_8
), ctx
->memidx
);
647 case 0x2001: /* mov.w Rm,@Rn */
648 tcg_gen_qemu_st16(REG(B7_4
), REG(B11_8
), ctx
->memidx
);
650 case 0x2002: /* mov.l Rm,@Rn */
651 tcg_gen_qemu_st32(REG(B7_4
), REG(B11_8
), ctx
->memidx
);
653 case 0x6000: /* mov.b @Rm,Rn */
654 tcg_gen_qemu_ld8s(REG(B11_8
), REG(B7_4
), ctx
->memidx
);
656 case 0x6001: /* mov.w @Rm,Rn */
657 tcg_gen_qemu_ld16s(REG(B11_8
), REG(B7_4
), ctx
->memidx
);
659 case 0x6002: /* mov.l @Rm,Rn */
660 tcg_gen_qemu_ld32s(REG(B11_8
), REG(B7_4
), ctx
->memidx
);
662 case 0x2004: /* mov.b Rm,@-Rn */
664 TCGv addr
= tcg_temp_new();
665 tcg_gen_subi_i32(addr
, REG(B11_8
), 1);
666 tcg_gen_qemu_st8(REG(B7_4
), addr
, ctx
->memidx
); /* might cause re-execution */
667 tcg_gen_mov_i32(REG(B11_8
), addr
); /* modify register status */
671 case 0x2005: /* mov.w Rm,@-Rn */
673 TCGv addr
= tcg_temp_new();
674 tcg_gen_subi_i32(addr
, REG(B11_8
), 2);
675 tcg_gen_qemu_st16(REG(B7_4
), addr
, ctx
->memidx
);
676 tcg_gen_mov_i32(REG(B11_8
), addr
);
680 case 0x2006: /* mov.l Rm,@-Rn */
682 TCGv addr
= tcg_temp_new();
683 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
684 tcg_gen_qemu_st32(REG(B7_4
), addr
, ctx
->memidx
);
685 tcg_gen_mov_i32(REG(B11_8
), addr
);
688 case 0x6004: /* mov.b @Rm+,Rn */
689 tcg_gen_qemu_ld8s(REG(B11_8
), REG(B7_4
), ctx
->memidx
);
691 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 1);
693 case 0x6005: /* mov.w @Rm+,Rn */
694 tcg_gen_qemu_ld16s(REG(B11_8
), REG(B7_4
), ctx
->memidx
);
696 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 2);
698 case 0x6006: /* mov.l @Rm+,Rn */
699 tcg_gen_qemu_ld32s(REG(B11_8
), REG(B7_4
), ctx
->memidx
);
701 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
703 case 0x0004: /* mov.b Rm,@(R0,Rn) */
705 TCGv addr
= tcg_temp_new();
706 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
707 tcg_gen_qemu_st8(REG(B7_4
), addr
, ctx
->memidx
);
711 case 0x0005: /* mov.w Rm,@(R0,Rn) */
713 TCGv addr
= tcg_temp_new();
714 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
715 tcg_gen_qemu_st16(REG(B7_4
), addr
, ctx
->memidx
);
719 case 0x0006: /* mov.l Rm,@(R0,Rn) */
721 TCGv addr
= tcg_temp_new();
722 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
723 tcg_gen_qemu_st32(REG(B7_4
), addr
, ctx
->memidx
);
727 case 0x000c: /* mov.b @(R0,Rm),Rn */
729 TCGv addr
= tcg_temp_new();
730 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
731 tcg_gen_qemu_ld8s(REG(B11_8
), addr
, ctx
->memidx
);
735 case 0x000d: /* mov.w @(R0,Rm),Rn */
737 TCGv addr
= tcg_temp_new();
738 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
739 tcg_gen_qemu_ld16s(REG(B11_8
), addr
, ctx
->memidx
);
743 case 0x000e: /* mov.l @(R0,Rm),Rn */
745 TCGv addr
= tcg_temp_new();
746 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
747 tcg_gen_qemu_ld32s(REG(B11_8
), addr
, ctx
->memidx
);
751 case 0x6008: /* swap.b Rm,Rn */
754 high
= tcg_temp_new();
755 tcg_gen_andi_i32(high
, REG(B7_4
), 0xffff0000);
756 low
= tcg_temp_new();
757 tcg_gen_ext16u_i32(low
, REG(B7_4
));
758 tcg_gen_bswap16_i32(low
, low
);
759 tcg_gen_or_i32(REG(B11_8
), high
, low
);
764 case 0x6009: /* swap.w Rm,Rn */
767 high
= tcg_temp_new();
768 tcg_gen_shli_i32(high
, REG(B7_4
), 16);
769 low
= tcg_temp_new();
770 tcg_gen_shri_i32(low
, REG(B7_4
), 16);
771 tcg_gen_ext16u_i32(low
, low
);
772 tcg_gen_or_i32(REG(B11_8
), high
, low
);
777 case 0x200d: /* xtrct Rm,Rn */
780 high
= tcg_temp_new();
781 tcg_gen_shli_i32(high
, REG(B7_4
), 16);
782 low
= tcg_temp_new();
783 tcg_gen_shri_i32(low
, REG(B11_8
), 16);
784 tcg_gen_ext16u_i32(low
, low
);
785 tcg_gen_or_i32(REG(B11_8
), high
, low
);
790 case 0x300c: /* add Rm,Rn */
791 tcg_gen_add_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
793 case 0x300e: /* addc Rm,Rn */
794 gen_helper_addc(REG(B11_8
), REG(B7_4
), REG(B11_8
));
796 case 0x300f: /* addv Rm,Rn */
797 gen_helper_addv(REG(B11_8
), REG(B7_4
), REG(B11_8
));
799 case 0x2009: /* and Rm,Rn */
800 tcg_gen_and_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
802 case 0x3000: /* cmp/eq Rm,Rn */
803 gen_cmp(TCG_COND_EQ
, REG(B7_4
), REG(B11_8
));
805 case 0x3003: /* cmp/ge Rm,Rn */
806 gen_cmp(TCG_COND_GE
, REG(B7_4
), REG(B11_8
));
808 case 0x3007: /* cmp/gt Rm,Rn */
809 gen_cmp(TCG_COND_GT
, REG(B7_4
), REG(B11_8
));
811 case 0x3006: /* cmp/hi Rm,Rn */
812 gen_cmp(TCG_COND_GTU
, REG(B7_4
), REG(B11_8
));
814 case 0x3002: /* cmp/hs Rm,Rn */
815 gen_cmp(TCG_COND_GEU
, REG(B7_4
), REG(B11_8
));
817 case 0x200c: /* cmp/str Rm,Rn */
819 int label1
= gen_new_label();
820 int label2
= gen_new_label();
821 TCGv cmp1
= tcg_temp_local_new();
822 TCGv cmp2
= tcg_temp_local_new();
823 tcg_gen_xor_i32(cmp1
, REG(B7_4
), REG(B11_8
));
824 tcg_gen_andi_i32(cmp2
, cmp1
, 0xff000000);
825 tcg_gen_brcondi_i32(TCG_COND_EQ
, cmp2
, 0, label1
);
826 tcg_gen_andi_i32(cmp2
, cmp1
, 0x00ff0000);
827 tcg_gen_brcondi_i32(TCG_COND_EQ
, cmp2
, 0, label1
);
828 tcg_gen_andi_i32(cmp2
, cmp1
, 0x0000ff00);
829 tcg_gen_brcondi_i32(TCG_COND_EQ
, cmp2
, 0, label1
);
830 tcg_gen_andi_i32(cmp2
, cmp1
, 0x000000ff);
831 tcg_gen_brcondi_i32(TCG_COND_EQ
, cmp2
, 0, label1
);
832 tcg_gen_andi_i32(cpu_sr
, cpu_sr
, ~SR_T
);
834 gen_set_label(label1
);
835 tcg_gen_ori_i32(cpu_sr
, cpu_sr
, SR_T
);
836 gen_set_label(label2
);
841 case 0x2007: /* div0s Rm,Rn */
843 gen_copy_bit_i32(cpu_sr
, 8, REG(B11_8
), 31); /* SR_Q */
844 gen_copy_bit_i32(cpu_sr
, 9, REG(B7_4
), 31); /* SR_M */
845 TCGv val
= tcg_temp_new();
846 tcg_gen_xor_i32(val
, REG(B7_4
), REG(B11_8
));
847 gen_copy_bit_i32(cpu_sr
, 0, val
, 31); /* SR_T */
851 case 0x3004: /* div1 Rm,Rn */
852 gen_helper_div1(REG(B11_8
), REG(B7_4
), REG(B11_8
));
854 case 0x300d: /* dmuls.l Rm,Rn */
856 TCGv_i64 tmp1
= tcg_temp_new_i64();
857 TCGv_i64 tmp2
= tcg_temp_new_i64();
859 tcg_gen_ext_i32_i64(tmp1
, REG(B7_4
));
860 tcg_gen_ext_i32_i64(tmp2
, REG(B11_8
));
861 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
862 tcg_gen_trunc_i64_i32(cpu_macl
, tmp1
);
863 tcg_gen_shri_i64(tmp1
, tmp1
, 32);
864 tcg_gen_trunc_i64_i32(cpu_mach
, tmp1
);
866 tcg_temp_free_i64(tmp2
);
867 tcg_temp_free_i64(tmp1
);
870 case 0x3005: /* dmulu.l Rm,Rn */
872 TCGv_i64 tmp1
= tcg_temp_new_i64();
873 TCGv_i64 tmp2
= tcg_temp_new_i64();
875 tcg_gen_extu_i32_i64(tmp1
, REG(B7_4
));
876 tcg_gen_extu_i32_i64(tmp2
, REG(B11_8
));
877 tcg_gen_mul_i64(tmp1
, tmp1
, tmp2
);
878 tcg_gen_trunc_i64_i32(cpu_macl
, tmp1
);
879 tcg_gen_shri_i64(tmp1
, tmp1
, 32);
880 tcg_gen_trunc_i64_i32(cpu_mach
, tmp1
);
882 tcg_temp_free_i64(tmp2
);
883 tcg_temp_free_i64(tmp1
);
886 case 0x600e: /* exts.b Rm,Rn */
887 tcg_gen_ext8s_i32(REG(B11_8
), REG(B7_4
));
889 case 0x600f: /* exts.w Rm,Rn */
890 tcg_gen_ext16s_i32(REG(B11_8
), REG(B7_4
));
892 case 0x600c: /* extu.b Rm,Rn */
893 tcg_gen_ext8u_i32(REG(B11_8
), REG(B7_4
));
895 case 0x600d: /* extu.w Rm,Rn */
896 tcg_gen_ext16u_i32(REG(B11_8
), REG(B7_4
));
898 case 0x000f: /* mac.l @Rm+,@Rn+ */
901 arg0
= tcg_temp_new();
902 tcg_gen_qemu_ld32s(arg0
, REG(B7_4
), ctx
->memidx
);
903 arg1
= tcg_temp_new();
904 tcg_gen_qemu_ld32s(arg1
, REG(B11_8
), ctx
->memidx
);
905 gen_helper_macl(arg0
, arg1
);
908 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
909 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
912 case 0x400f: /* mac.w @Rm+,@Rn+ */
915 arg0
= tcg_temp_new();
916 tcg_gen_qemu_ld32s(arg0
, REG(B7_4
), ctx
->memidx
);
917 arg1
= tcg_temp_new();
918 tcg_gen_qemu_ld32s(arg1
, REG(B11_8
), ctx
->memidx
);
919 gen_helper_macw(arg0
, arg1
);
922 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 2);
923 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 2);
926 case 0x0007: /* mul.l Rm,Rn */
927 tcg_gen_mul_i32(cpu_macl
, REG(B7_4
), REG(B11_8
));
929 case 0x200f: /* muls.w Rm,Rn */
932 arg0
= tcg_temp_new();
933 tcg_gen_ext16s_i32(arg0
, REG(B7_4
));
934 arg1
= tcg_temp_new();
935 tcg_gen_ext16s_i32(arg1
, REG(B11_8
));
936 tcg_gen_mul_i32(cpu_macl
, arg0
, arg1
);
941 case 0x200e: /* mulu.w Rm,Rn */
944 arg0
= tcg_temp_new();
945 tcg_gen_ext16u_i32(arg0
, REG(B7_4
));
946 arg1
= tcg_temp_new();
947 tcg_gen_ext16u_i32(arg1
, REG(B11_8
));
948 tcg_gen_mul_i32(cpu_macl
, arg0
, arg1
);
953 case 0x600b: /* neg Rm,Rn */
954 tcg_gen_neg_i32(REG(B11_8
), REG(B7_4
));
956 case 0x600a: /* negc Rm,Rn */
957 gen_helper_negc(REG(B11_8
), REG(B7_4
));
959 case 0x6007: /* not Rm,Rn */
960 tcg_gen_not_i32(REG(B11_8
), REG(B7_4
));
962 case 0x200b: /* or Rm,Rn */
963 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
965 case 0x400c: /* shad Rm,Rn */
967 int label1
= gen_new_label();
968 int label2
= gen_new_label();
969 int label3
= gen_new_label();
970 int label4
= gen_new_label();
972 tcg_gen_brcondi_i32(TCG_COND_LT
, REG(B7_4
), 0, label1
);
973 /* Rm positive, shift to the left */
974 shift
= tcg_temp_new();
975 tcg_gen_andi_i32(shift
, REG(B7_4
), 0x1f);
976 tcg_gen_shl_i32(REG(B11_8
), REG(B11_8
), shift
);
977 tcg_temp_free(shift
);
979 /* Rm negative, shift to the right */
980 gen_set_label(label1
);
981 shift
= tcg_temp_new();
982 tcg_gen_andi_i32(shift
, REG(B7_4
), 0x1f);
983 tcg_gen_brcondi_i32(TCG_COND_EQ
, shift
, 0, label2
);
984 tcg_gen_not_i32(shift
, REG(B7_4
));
985 tcg_gen_andi_i32(shift
, shift
, 0x1f);
986 tcg_gen_addi_i32(shift
, shift
, 1);
987 tcg_gen_sar_i32(REG(B11_8
), REG(B11_8
), shift
);
988 tcg_temp_free(shift
);
991 gen_set_label(label2
);
992 tcg_gen_brcondi_i32(TCG_COND_LT
, REG(B11_8
), 0, label3
);
993 tcg_gen_movi_i32(REG(B11_8
), 0);
995 gen_set_label(label3
);
996 tcg_gen_movi_i32(REG(B11_8
), 0xffffffff);
997 gen_set_label(label4
);
1000 case 0x400d: /* shld Rm,Rn */
1002 int label1
= gen_new_label();
1003 int label2
= gen_new_label();
1004 int label3
= gen_new_label();
1006 tcg_gen_brcondi_i32(TCG_COND_LT
, REG(B7_4
), 0, label1
);
1007 /* Rm positive, shift to the left */
1008 shift
= tcg_temp_new();
1009 tcg_gen_andi_i32(shift
, REG(B7_4
), 0x1f);
1010 tcg_gen_shl_i32(REG(B11_8
), REG(B11_8
), shift
);
1011 tcg_temp_free(shift
);
1013 /* Rm negative, shift to the right */
1014 gen_set_label(label1
);
1015 shift
= tcg_temp_new();
1016 tcg_gen_andi_i32(shift
, REG(B7_4
), 0x1f);
1017 tcg_gen_brcondi_i32(TCG_COND_EQ
, shift
, 0, label2
);
1018 tcg_gen_not_i32(shift
, REG(B7_4
));
1019 tcg_gen_andi_i32(shift
, shift
, 0x1f);
1020 tcg_gen_addi_i32(shift
, shift
, 1);
1021 tcg_gen_shr_i32(REG(B11_8
), REG(B11_8
), shift
);
1022 tcg_temp_free(shift
);
1025 gen_set_label(label2
);
1026 tcg_gen_movi_i32(REG(B11_8
), 0);
1027 gen_set_label(label3
);
1030 case 0x3008: /* sub Rm,Rn */
1031 tcg_gen_sub_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
1033 case 0x300a: /* subc Rm,Rn */
1034 gen_helper_subc(REG(B11_8
), REG(B7_4
), REG(B11_8
));
1036 case 0x300b: /* subv Rm,Rn */
1037 gen_helper_subv(REG(B11_8
), REG(B7_4
), REG(B11_8
));
1039 case 0x2008: /* tst Rm,Rn */
1041 TCGv val
= tcg_temp_new();
1042 tcg_gen_and_i32(val
, REG(B7_4
), REG(B11_8
));
1043 gen_cmp_imm(TCG_COND_EQ
, val
, 0);
1047 case 0x200a: /* xor Rm,Rn */
1048 tcg_gen_xor_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
1050 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
1052 if (ctx
->fpscr
& FPSCR_SZ
) {
1053 TCGv_i64 fp
= tcg_temp_new_i64();
1054 gen_load_fpr64(fp
, XREG(B7_4
));
1055 gen_store_fpr64(fp
, XREG(B11_8
));
1056 tcg_temp_free_i64(fp
);
1058 tcg_gen_mov_i32(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
1061 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
1063 if (ctx
->fpscr
& FPSCR_SZ
) {
1064 TCGv addr_hi
= tcg_temp_new();
1065 int fr
= XREG(B7_4
);
1066 tcg_gen_addi_i32(addr_hi
, REG(B11_8
), 4);
1067 tcg_gen_qemu_st32(cpu_fregs
[fr
], REG(B11_8
), ctx
->memidx
);
1068 tcg_gen_qemu_st32(cpu_fregs
[fr
+1], addr_hi
, ctx
->memidx
);
1069 tcg_temp_free(addr_hi
);
1071 tcg_gen_qemu_st32(cpu_fregs
[FREG(B7_4
)], REG(B11_8
), ctx
->memidx
);
1074 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
1076 if (ctx
->fpscr
& FPSCR_SZ
) {
1077 TCGv addr_hi
= tcg_temp_new();
1078 int fr
= XREG(B11_8
);
1079 tcg_gen_addi_i32(addr_hi
, REG(B7_4
), 4);
1080 tcg_gen_qemu_ld32u(cpu_fregs
[fr
], REG(B7_4
), ctx
->memidx
);
1081 tcg_gen_qemu_ld32u(cpu_fregs
[fr
+1], addr_hi
, ctx
->memidx
);
1082 tcg_temp_free(addr_hi
);
1084 tcg_gen_qemu_ld32u(cpu_fregs
[FREG(B11_8
)], REG(B7_4
), ctx
->memidx
);
1087 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
1089 if (ctx
->fpscr
& FPSCR_SZ
) {
1090 TCGv addr_hi
= tcg_temp_new();
1091 int fr
= XREG(B11_8
);
1092 tcg_gen_addi_i32(addr_hi
, REG(B7_4
), 4);
1093 tcg_gen_qemu_ld32u(cpu_fregs
[fr
], REG(B7_4
), ctx
->memidx
);
1094 tcg_gen_qemu_ld32u(cpu_fregs
[fr
+1], addr_hi
, ctx
->memidx
);
1095 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 8);
1096 tcg_temp_free(addr_hi
);
1098 tcg_gen_qemu_ld32u(cpu_fregs
[FREG(B11_8
)], REG(B7_4
), ctx
->memidx
);
1099 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
1102 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
1104 if (ctx
->fpscr
& FPSCR_SZ
) {
1105 TCGv addr
= tcg_temp_new_i32();
1106 int fr
= XREG(B7_4
);
1107 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1108 tcg_gen_qemu_st32(cpu_fregs
[fr
+1], addr
, ctx
->memidx
);
1109 tcg_gen_subi_i32(addr
, addr
, 4);
1110 tcg_gen_qemu_st32(cpu_fregs
[fr
], addr
, ctx
->memidx
);
1111 tcg_gen_mov_i32(REG(B11_8
), addr
);
1112 tcg_temp_free(addr
);
1115 addr
= tcg_temp_new_i32();
1116 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1117 tcg_gen_qemu_st32(cpu_fregs
[FREG(B7_4
)], addr
, ctx
->memidx
);
1118 tcg_gen_mov_i32(REG(B11_8
), addr
);
1119 tcg_temp_free(addr
);
1122 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1125 TCGv addr
= tcg_temp_new_i32();
1126 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
1127 if (ctx
->fpscr
& FPSCR_SZ
) {
1128 int fr
= XREG(B11_8
);
1129 tcg_gen_qemu_ld32u(cpu_fregs
[fr
], addr
, ctx
->memidx
);
1130 tcg_gen_addi_i32(addr
, addr
, 4);
1131 tcg_gen_qemu_ld32u(cpu_fregs
[fr
+1], addr
, ctx
->memidx
);
1133 tcg_gen_qemu_ld32u(cpu_fregs
[FREG(B11_8
)], addr
, ctx
->memidx
);
1135 tcg_temp_free(addr
);
1138 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1141 TCGv addr
= tcg_temp_new();
1142 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
1143 if (ctx
->fpscr
& FPSCR_SZ
) {
1144 int fr
= XREG(B7_4
);
1145 tcg_gen_qemu_ld32u(cpu_fregs
[fr
], addr
, ctx
->memidx
);
1146 tcg_gen_addi_i32(addr
, addr
, 4);
1147 tcg_gen_qemu_ld32u(cpu_fregs
[fr
+1], addr
, ctx
->memidx
);
1149 tcg_gen_qemu_st32(cpu_fregs
[FREG(B7_4
)], addr
, ctx
->memidx
);
1151 tcg_temp_free(addr
);
1154 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1155 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1156 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1157 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1158 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1159 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1162 if (ctx
->fpscr
& FPSCR_PR
) {
1165 if (ctx
->opcode
& 0x0110)
1166 break; /* illegal instruction */
1167 fp0
= tcg_temp_new_i64();
1168 fp1
= tcg_temp_new_i64();
1169 gen_load_fpr64(fp0
, DREG(B11_8
));
1170 gen_load_fpr64(fp1
, DREG(B7_4
));
1171 switch (ctx
->opcode
& 0xf00f) {
1172 case 0xf000: /* fadd Rm,Rn */
1173 gen_helper_fadd_DT(fp0
, fp0
, fp1
);
1175 case 0xf001: /* fsub Rm,Rn */
1176 gen_helper_fsub_DT(fp0
, fp0
, fp1
);
1178 case 0xf002: /* fmul Rm,Rn */
1179 gen_helper_fmul_DT(fp0
, fp0
, fp1
);
1181 case 0xf003: /* fdiv Rm,Rn */
1182 gen_helper_fdiv_DT(fp0
, fp0
, fp1
);
1184 case 0xf004: /* fcmp/eq Rm,Rn */
1185 gen_helper_fcmp_eq_DT(fp0
, fp1
);
1187 case 0xf005: /* fcmp/gt Rm,Rn */
1188 gen_helper_fcmp_gt_DT(fp0
, fp1
);
1191 gen_store_fpr64(fp0
, DREG(B11_8
));
1192 tcg_temp_free_i64(fp0
);
1193 tcg_temp_free_i64(fp1
);
1195 switch (ctx
->opcode
& 0xf00f) {
1196 case 0xf000: /* fadd Rm,Rn */
1197 gen_helper_fadd_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
1199 case 0xf001: /* fsub Rm,Rn */
1200 gen_helper_fsub_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
1202 case 0xf002: /* fmul Rm,Rn */
1203 gen_helper_fmul_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
1205 case 0xf003: /* fdiv Rm,Rn */
1206 gen_helper_fdiv_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
1208 case 0xf004: /* fcmp/eq Rm,Rn */
1209 gen_helper_fcmp_eq_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
1211 case 0xf005: /* fcmp/gt Rm,Rn */
1212 gen_helper_fcmp_gt_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
1218 case 0xf00e: /* fmac FR0,RM,Rn */
1221 if (ctx
->fpscr
& FPSCR_PR
) {
1222 break; /* illegal instruction */
1224 gen_helper_fmac_FT(cpu_fregs
[FREG(B11_8
)],
1225 cpu_fregs
[FREG(0)], cpu_fregs
[FREG(B7_4
)], cpu_fregs
[FREG(B11_8
)]);
1231 switch (ctx
->opcode
& 0xff00) {
1232 case 0xc900: /* and #imm,R0 */
1233 tcg_gen_andi_i32(REG(0), REG(0), B7_0
);
1235 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1238 addr
= tcg_temp_new();
1239 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1240 val
= tcg_temp_new();
1241 tcg_gen_qemu_ld8u(val
, addr
, ctx
->memidx
);
1242 tcg_gen_andi_i32(val
, val
, B7_0
);
1243 tcg_gen_qemu_st8(val
, addr
, ctx
->memidx
);
1245 tcg_temp_free(addr
);
1248 case 0x8b00: /* bf label */
1249 CHECK_NOT_DELAY_SLOT
1250 gen_conditional_jump(ctx
, ctx
->pc
+ 2,
1251 ctx
->pc
+ 4 + B7_0s
* 2);
1252 ctx
->bstate
= BS_BRANCH
;
1254 case 0x8f00: /* bf/s label */
1255 CHECK_NOT_DELAY_SLOT
1256 gen_branch_slot(ctx
->delayed_pc
= ctx
->pc
+ 4 + B7_0s
* 2, 0);
1257 ctx
->flags
|= DELAY_SLOT_CONDITIONAL
;
1259 case 0x8900: /* bt label */
1260 CHECK_NOT_DELAY_SLOT
1261 gen_conditional_jump(ctx
, ctx
->pc
+ 4 + B7_0s
* 2,
1263 ctx
->bstate
= BS_BRANCH
;
1265 case 0x8d00: /* bt/s label */
1266 CHECK_NOT_DELAY_SLOT
1267 gen_branch_slot(ctx
->delayed_pc
= ctx
->pc
+ 4 + B7_0s
* 2, 1);
1268 ctx
->flags
|= DELAY_SLOT_CONDITIONAL
;
1270 case 0x8800: /* cmp/eq #imm,R0 */
1271 gen_cmp_imm(TCG_COND_EQ
, REG(0), B7_0s
);
1273 case 0xc400: /* mov.b @(disp,GBR),R0 */
1275 TCGv addr
= tcg_temp_new();
1276 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
);
1277 tcg_gen_qemu_ld8s(REG(0), addr
, ctx
->memidx
);
1278 tcg_temp_free(addr
);
1281 case 0xc500: /* mov.w @(disp,GBR),R0 */
1283 TCGv addr
= tcg_temp_new();
1284 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 2);
1285 tcg_gen_qemu_ld16s(REG(0), addr
, ctx
->memidx
);
1286 tcg_temp_free(addr
);
1289 case 0xc600: /* mov.l @(disp,GBR),R0 */
1291 TCGv addr
= tcg_temp_new();
1292 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 4);
1293 tcg_gen_qemu_ld32s(REG(0), addr
, ctx
->memidx
);
1294 tcg_temp_free(addr
);
1297 case 0xc000: /* mov.b R0,@(disp,GBR) */
1299 TCGv addr
= tcg_temp_new();
1300 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
);
1301 tcg_gen_qemu_st8(REG(0), addr
, ctx
->memidx
);
1302 tcg_temp_free(addr
);
1305 case 0xc100: /* mov.w R0,@(disp,GBR) */
1307 TCGv addr
= tcg_temp_new();
1308 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 2);
1309 tcg_gen_qemu_st16(REG(0), addr
, ctx
->memidx
);
1310 tcg_temp_free(addr
);
1313 case 0xc200: /* mov.l R0,@(disp,GBR) */
1315 TCGv addr
= tcg_temp_new();
1316 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 4);
1317 tcg_gen_qemu_st32(REG(0), addr
, ctx
->memidx
);
1318 tcg_temp_free(addr
);
1321 case 0x8000: /* mov.b R0,@(disp,Rn) */
1323 TCGv addr
= tcg_temp_new();
1324 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
);
1325 tcg_gen_qemu_st8(REG(0), addr
, ctx
->memidx
);
1326 tcg_temp_free(addr
);
1329 case 0x8100: /* mov.w R0,@(disp,Rn) */
1331 TCGv addr
= tcg_temp_new();
1332 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 2);
1333 tcg_gen_qemu_st16(REG(0), addr
, ctx
->memidx
);
1334 tcg_temp_free(addr
);
1337 case 0x8400: /* mov.b @(disp,Rn),R0 */
1339 TCGv addr
= tcg_temp_new();
1340 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
);
1341 tcg_gen_qemu_ld8s(REG(0), addr
, ctx
->memidx
);
1342 tcg_temp_free(addr
);
1345 case 0x8500: /* mov.w @(disp,Rn),R0 */
1347 TCGv addr
= tcg_temp_new();
1348 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 2);
1349 tcg_gen_qemu_ld16s(REG(0), addr
, ctx
->memidx
);
1350 tcg_temp_free(addr
);
1353 case 0xc700: /* mova @(disp,PC),R0 */
1354 tcg_gen_movi_i32(REG(0), ((ctx
->pc
& 0xfffffffc) + 4 + B7_0
* 4) & ~3);
1356 case 0xcb00: /* or #imm,R0 */
1357 tcg_gen_ori_i32(REG(0), REG(0), B7_0
);
1359 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1362 addr
= tcg_temp_new();
1363 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1364 val
= tcg_temp_new();
1365 tcg_gen_qemu_ld8u(val
, addr
, ctx
->memidx
);
1366 tcg_gen_ori_i32(val
, val
, B7_0
);
1367 tcg_gen_qemu_st8(val
, addr
, ctx
->memidx
);
1369 tcg_temp_free(addr
);
1372 case 0xc300: /* trapa #imm */
1375 CHECK_NOT_DELAY_SLOT
1376 imm
= tcg_const_i32(B7_0
);
1377 gen_helper_trapa(imm
);
1379 ctx
->bstate
= BS_BRANCH
;
1382 case 0xc800: /* tst #imm,R0 */
1384 TCGv val
= tcg_temp_new();
1385 tcg_gen_andi_i32(val
, REG(0), B7_0
);
1386 gen_cmp_imm(TCG_COND_EQ
, val
, 0);
1390 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1392 TCGv val
= tcg_temp_new();
1393 tcg_gen_add_i32(val
, REG(0), cpu_gbr
);
1394 tcg_gen_qemu_ld8u(val
, val
, ctx
->memidx
);
1395 tcg_gen_andi_i32(val
, val
, B7_0
);
1396 gen_cmp_imm(TCG_COND_EQ
, val
, 0);
1400 case 0xca00: /* xor #imm,R0 */
1401 tcg_gen_xori_i32(REG(0), REG(0), B7_0
);
1403 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1406 addr
= tcg_temp_new();
1407 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1408 val
= tcg_temp_new();
1409 tcg_gen_qemu_ld8u(val
, addr
, ctx
->memidx
);
1410 tcg_gen_xori_i32(val
, val
, B7_0
);
1411 tcg_gen_qemu_st8(val
, addr
, ctx
->memidx
);
1413 tcg_temp_free(addr
);
1418 switch (ctx
->opcode
& 0xf08f) {
1419 case 0x408e: /* ldc Rm,Rn_BANK */
1421 tcg_gen_mov_i32(ALTREG(B6_4
), REG(B11_8
));
1423 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1425 tcg_gen_qemu_ld32s(ALTREG(B6_4
), REG(B11_8
), ctx
->memidx
);
1426 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1428 case 0x0082: /* stc Rm_BANK,Rn */
1430 tcg_gen_mov_i32(REG(B11_8
), ALTREG(B6_4
));
1432 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1435 TCGv addr
= tcg_temp_new();
1436 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1437 tcg_gen_qemu_st32(ALTREG(B6_4
), addr
, ctx
->memidx
);
1438 tcg_gen_mov_i32(REG(B11_8
), addr
);
1439 tcg_temp_free(addr
);
1444 switch (ctx
->opcode
& 0xf0ff) {
1445 case 0x0023: /* braf Rn */
1446 CHECK_NOT_DELAY_SLOT
1447 tcg_gen_addi_i32(cpu_delayed_pc
, REG(B11_8
), ctx
->pc
+ 4);
1448 ctx
->flags
|= DELAY_SLOT
;
1449 ctx
->delayed_pc
= (uint32_t) - 1;
1451 case 0x0003: /* bsrf Rn */
1452 CHECK_NOT_DELAY_SLOT
1453 tcg_gen_movi_i32(cpu_pr
, ctx
->pc
+ 4);
1454 tcg_gen_add_i32(cpu_delayed_pc
, REG(B11_8
), cpu_pr
);
1455 ctx
->flags
|= DELAY_SLOT
;
1456 ctx
->delayed_pc
= (uint32_t) - 1;
1458 case 0x4015: /* cmp/pl Rn */
1459 gen_cmp_imm(TCG_COND_GT
, REG(B11_8
), 0);
1461 case 0x4011: /* cmp/pz Rn */
1462 gen_cmp_imm(TCG_COND_GE
, REG(B11_8
), 0);
1464 case 0x4010: /* dt Rn */
1465 tcg_gen_subi_i32(REG(B11_8
), REG(B11_8
), 1);
1466 gen_cmp_imm(TCG_COND_EQ
, REG(B11_8
), 0);
1468 case 0x402b: /* jmp @Rn */
1469 CHECK_NOT_DELAY_SLOT
1470 tcg_gen_mov_i32(cpu_delayed_pc
, REG(B11_8
));
1471 ctx
->flags
|= DELAY_SLOT
;
1472 ctx
->delayed_pc
= (uint32_t) - 1;
1474 case 0x400b: /* jsr @Rn */
1475 CHECK_NOT_DELAY_SLOT
1476 tcg_gen_movi_i32(cpu_pr
, ctx
->pc
+ 4);
1477 tcg_gen_mov_i32(cpu_delayed_pc
, REG(B11_8
));
1478 ctx
->flags
|= DELAY_SLOT
;
1479 ctx
->delayed_pc
= (uint32_t) - 1;
1481 case 0x400e: /* ldc Rm,SR */
1483 tcg_gen_andi_i32(cpu_sr
, REG(B11_8
), 0x700083f3);
1484 ctx
->bstate
= BS_STOP
;
1486 case 0x4007: /* ldc.l @Rm+,SR */
1489 TCGv val
= tcg_temp_new();
1490 tcg_gen_qemu_ld32s(val
, REG(B11_8
), ctx
->memidx
);
1491 tcg_gen_andi_i32(cpu_sr
, val
, 0x700083f3);
1493 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1494 ctx
->bstate
= BS_STOP
;
1497 case 0x0002: /* stc SR,Rn */
1499 tcg_gen_mov_i32(REG(B11_8
), cpu_sr
);
1501 case 0x4003: /* stc SR,@-Rn */
1504 TCGv addr
= tcg_temp_new();
1505 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1506 tcg_gen_qemu_st32(cpu_sr
, addr
, ctx
->memidx
);
1507 tcg_gen_mov_i32(REG(B11_8
), addr
);
1508 tcg_temp_free(addr
);
1511 #define LD(reg,ldnum,ldpnum,prechk) \
1514 tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \
1518 tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx); \
1519 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \
1521 #define ST(reg,stnum,stpnum,prechk) \
1524 tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \
1529 TCGv addr = tcg_temp_new(); \
1530 tcg_gen_subi_i32(addr, REG(B11_8), 4); \
1531 tcg_gen_qemu_st32 (cpu_##reg, addr, ctx->memidx); \
1532 tcg_gen_mov_i32(REG(B11_8), addr); \
1533 tcg_temp_free(addr); \
1536 #define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk) \
1537 LD(reg,ldnum,ldpnum,prechk) \
1538 ST(reg,stnum,stpnum,prechk)
1539 LDST(gbr
, 0x401e, 0x4017, 0x0012, 0x4013, {})
1540 LDST(vbr
, 0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED
)
1541 LDST(ssr
, 0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED
)
1542 LDST(spc
, 0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED
)
1543 ST(sgr
, 0x003a, 0x4032, CHECK_PRIVILEGED
)
1544 LD(sgr
, 0x403a, 0x4036, CHECK_PRIVILEGED
if (!(ctx
->features
& SH_FEATURE_SH4A
)) break;)
1545 LDST(dbr
, 0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED
)
1546 LDST(mach
, 0x400a, 0x4006, 0x000a, 0x4002, {})
1547 LDST(macl
, 0x401a, 0x4016, 0x001a, 0x4012, {})
1548 LDST(pr
, 0x402a, 0x4026, 0x002a, 0x4022, {})
1549 LDST(fpul
, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED
})
1550 case 0x406a: /* lds Rm,FPSCR */
1552 gen_helper_ld_fpscr(REG(B11_8
));
1553 ctx
->bstate
= BS_STOP
;
1555 case 0x4066: /* lds.l @Rm+,FPSCR */
1558 TCGv addr
= tcg_temp_new();
1559 tcg_gen_qemu_ld32s(addr
, REG(B11_8
), ctx
->memidx
);
1560 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1561 gen_helper_ld_fpscr(addr
);
1562 tcg_temp_free(addr
);
1563 ctx
->bstate
= BS_STOP
;
1566 case 0x006a: /* sts FPSCR,Rn */
1568 tcg_gen_andi_i32(REG(B11_8
), cpu_fpscr
, 0x003fffff);
1570 case 0x4062: /* sts FPSCR,@-Rn */
1574 val
= tcg_temp_new();
1575 tcg_gen_andi_i32(val
, cpu_fpscr
, 0x003fffff);
1576 addr
= tcg_temp_new();
1577 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1578 tcg_gen_qemu_st32(val
, addr
, ctx
->memidx
);
1579 tcg_gen_mov_i32(REG(B11_8
), addr
);
1580 tcg_temp_free(addr
);
1584 case 0x00c3: /* movca.l R0,@Rm */
1586 TCGv val
= tcg_temp_new();
1587 tcg_gen_qemu_ld32u(val
, REG(B11_8
), ctx
->memidx
);
1588 gen_helper_movcal (REG(B11_8
), val
);
1589 tcg_gen_qemu_st32(REG(0), REG(B11_8
), ctx
->memidx
);
1591 ctx
->has_movcal
= 1;
1594 /* MOVUA.L @Rm,R0 (Rm) -> R0
1595 Load non-boundary-aligned data */
1596 tcg_gen_qemu_ld32u(REG(0), REG(B11_8
), ctx
->memidx
);
1599 /* MOVUA.L @Rm+,R0 (Rm) -> R0, Rm + 4 -> Rm
1600 Load non-boundary-aligned data */
1601 tcg_gen_qemu_ld32u(REG(0), REG(B11_8
), ctx
->memidx
);
1602 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1604 case 0x0029: /* movt Rn */
1605 tcg_gen_andi_i32(REG(B11_8
), cpu_sr
, SR_T
);
1610 If (T == 1) R0 -> (Rn)
1613 if (ctx
->features
& SH_FEATURE_SH4A
) {
1614 int label
= gen_new_label();
1616 tcg_gen_or_i32(cpu_sr
, cpu_sr
, cpu_ldst
);
1617 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ldst
, 0, label
);
1618 tcg_gen_qemu_st32(REG(0), REG(B11_8
), ctx
->memidx
);
1619 gen_set_label(label
);
1620 tcg_gen_movi_i32(cpu_ldst
, 0);
1628 When interrupt/exception
1631 if (ctx
->features
& SH_FEATURE_SH4A
) {
1632 tcg_gen_movi_i32(cpu_ldst
, 0);
1633 tcg_gen_qemu_ld32s(REG(0), REG(B11_8
), ctx
->memidx
);
1634 tcg_gen_movi_i32(cpu_ldst
, 1);
1638 case 0x0093: /* ocbi @Rn */
1640 gen_helper_ocbi (REG(B11_8
));
1643 case 0x00a3: /* ocbp @Rn */
1645 TCGv dummy
= tcg_temp_new();
1646 tcg_gen_qemu_ld32s(dummy
, REG(B11_8
), ctx
->memidx
);
1647 tcg_temp_free(dummy
);
1650 case 0x00b3: /* ocbwb @Rn */
1652 TCGv dummy
= tcg_temp_new();
1653 tcg_gen_qemu_ld32s(dummy
, REG(B11_8
), ctx
->memidx
);
1654 tcg_temp_free(dummy
);
1657 case 0x0083: /* pref @Rn */
1659 case 0x00d3: /* prefi @Rn */
1660 if (ctx
->features
& SH_FEATURE_SH4A
)
1664 case 0x00e3: /* icbi @Rn */
1665 if (ctx
->features
& SH_FEATURE_SH4A
)
1669 case 0x00ab: /* synco */
1670 if (ctx
->features
& SH_FEATURE_SH4A
)
1674 case 0x4024: /* rotcl Rn */
1676 TCGv tmp
= tcg_temp_new();
1677 tcg_gen_mov_i32(tmp
, cpu_sr
);
1678 gen_copy_bit_i32(cpu_sr
, 0, REG(B11_8
), 31);
1679 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1680 gen_copy_bit_i32(REG(B11_8
), 0, tmp
, 0);
1684 case 0x4025: /* rotcr Rn */
1686 TCGv tmp
= tcg_temp_new();
1687 tcg_gen_mov_i32(tmp
, cpu_sr
);
1688 gen_copy_bit_i32(cpu_sr
, 0, REG(B11_8
), 0);
1689 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1690 gen_copy_bit_i32(REG(B11_8
), 31, tmp
, 0);
1694 case 0x4004: /* rotl Rn */
1695 gen_copy_bit_i32(cpu_sr
, 0, REG(B11_8
), 31);
1696 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1697 gen_copy_bit_i32(REG(B11_8
), 0, cpu_sr
, 0);
1699 case 0x4005: /* rotr Rn */
1700 gen_copy_bit_i32(cpu_sr
, 0, REG(B11_8
), 0);
1701 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1702 gen_copy_bit_i32(REG(B11_8
), 31, cpu_sr
, 0);
1704 case 0x4000: /* shll Rn */
1705 case 0x4020: /* shal Rn */
1706 gen_copy_bit_i32(cpu_sr
, 0, REG(B11_8
), 31);
1707 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1709 case 0x4021: /* shar Rn */
1710 gen_copy_bit_i32(cpu_sr
, 0, REG(B11_8
), 0);
1711 tcg_gen_sari_i32(REG(B11_8
), REG(B11_8
), 1);
1713 case 0x4001: /* shlr Rn */
1714 gen_copy_bit_i32(cpu_sr
, 0, REG(B11_8
), 0);
1715 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1717 case 0x4008: /* shll2 Rn */
1718 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 2);
1720 case 0x4018: /* shll8 Rn */
1721 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 8);
1723 case 0x4028: /* shll16 Rn */
1724 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 16);
1726 case 0x4009: /* shlr2 Rn */
1727 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 2);
1729 case 0x4019: /* shlr8 Rn */
1730 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 8);
1732 case 0x4029: /* shlr16 Rn */
1733 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 16);
1735 case 0x401b: /* tas.b @Rn */
1738 addr
= tcg_temp_local_new();
1739 tcg_gen_mov_i32(addr
, REG(B11_8
));
1740 val
= tcg_temp_local_new();
1741 tcg_gen_qemu_ld8u(val
, addr
, ctx
->memidx
);
1742 gen_cmp_imm(TCG_COND_EQ
, val
, 0);
1743 tcg_gen_ori_i32(val
, val
, 0x80);
1744 tcg_gen_qemu_st8(val
, addr
, ctx
->memidx
);
1746 tcg_temp_free(addr
);
1749 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1751 tcg_gen_mov_i32(cpu_fregs
[FREG(B11_8
)], cpu_fpul
);
1753 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1755 tcg_gen_mov_i32(cpu_fpul
, cpu_fregs
[FREG(B11_8
)]);
1757 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1759 if (ctx
->fpscr
& FPSCR_PR
) {
1761 if (ctx
->opcode
& 0x0100)
1762 break; /* illegal instruction */
1763 fp
= tcg_temp_new_i64();
1764 gen_helper_float_DT(fp
, cpu_fpul
);
1765 gen_store_fpr64(fp
, DREG(B11_8
));
1766 tcg_temp_free_i64(fp
);
1769 gen_helper_float_FT(cpu_fregs
[FREG(B11_8
)], cpu_fpul
);
1772 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1774 if (ctx
->fpscr
& FPSCR_PR
) {
1776 if (ctx
->opcode
& 0x0100)
1777 break; /* illegal instruction */
1778 fp
= tcg_temp_new_i64();
1779 gen_load_fpr64(fp
, DREG(B11_8
));
1780 gen_helper_ftrc_DT(cpu_fpul
, fp
);
1781 tcg_temp_free_i64(fp
);
1784 gen_helper_ftrc_FT(cpu_fpul
, cpu_fregs
[FREG(B11_8
)]);
1787 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1790 gen_helper_fneg_T(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)]);
1793 case 0xf05d: /* fabs FRn/DRn */
1795 if (ctx
->fpscr
& FPSCR_PR
) {
1796 if (ctx
->opcode
& 0x0100)
1797 break; /* illegal instruction */
1798 TCGv_i64 fp
= tcg_temp_new_i64();
1799 gen_load_fpr64(fp
, DREG(B11_8
));
1800 gen_helper_fabs_DT(fp
, fp
);
1801 gen_store_fpr64(fp
, DREG(B11_8
));
1802 tcg_temp_free_i64(fp
);
1804 gen_helper_fabs_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)]);
1807 case 0xf06d: /* fsqrt FRn */
1809 if (ctx
->fpscr
& FPSCR_PR
) {
1810 if (ctx
->opcode
& 0x0100)
1811 break; /* illegal instruction */
1812 TCGv_i64 fp
= tcg_temp_new_i64();
1813 gen_load_fpr64(fp
, DREG(B11_8
));
1814 gen_helper_fsqrt_DT(fp
, fp
);
1815 gen_store_fpr64(fp
, DREG(B11_8
));
1816 tcg_temp_free_i64(fp
);
1818 gen_helper_fsqrt_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)]);
1821 case 0xf07d: /* fsrra FRn */
1824 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1826 if (!(ctx
->fpscr
& FPSCR_PR
)) {
1827 tcg_gen_movi_i32(cpu_fregs
[FREG(B11_8
)], 0);
1830 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1832 if (!(ctx
->fpscr
& FPSCR_PR
)) {
1833 tcg_gen_movi_i32(cpu_fregs
[FREG(B11_8
)], 0x3f800000);
1836 case 0xf0ad: /* fcnvsd FPUL,DRn */
1839 TCGv_i64 fp
= tcg_temp_new_i64();
1840 gen_helper_fcnvsd_FT_DT(fp
, cpu_fpul
);
1841 gen_store_fpr64(fp
, DREG(B11_8
));
1842 tcg_temp_free_i64(fp
);
1845 case 0xf0bd: /* fcnvds DRn,FPUL */
1848 TCGv_i64 fp
= tcg_temp_new_i64();
1849 gen_load_fpr64(fp
, DREG(B11_8
));
1850 gen_helper_fcnvds_DT_FT(cpu_fpul
, fp
);
1851 tcg_temp_free_i64(fp
);
1854 case 0xf0ed: /* fipr FVm,FVn */
1856 if ((ctx
->fpscr
& FPSCR_PR
) == 0) {
1858 m
= tcg_const_i32((ctx
->opcode
>> 16) & 3);
1859 n
= tcg_const_i32((ctx
->opcode
>> 18) & 3);
1860 gen_helper_fipr(m
, n
);
1866 case 0xf0fd: /* ftrv XMTRX,FVn */
1868 if ((ctx
->opcode
& 0x0300) == 0x0100 &&
1869 (ctx
->fpscr
& FPSCR_PR
) == 0) {
1871 n
= tcg_const_i32((ctx
->opcode
>> 18) & 3);
1879 fprintf(stderr
, "unknown instruction 0x%04x at pc 0x%08x\n",
1880 ctx
->opcode
, ctx
->pc
);
1883 if (ctx
->flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
)) {
1884 gen_helper_raise_slot_illegal_instruction();
1886 gen_helper_raise_illegal_instruction();
1888 ctx
->bstate
= BS_EXCP
;
1891 static void decode_opc(DisasContext
* ctx
)
1893 uint32_t old_flags
= ctx
->flags
;
1897 if (old_flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
)) {
1898 if (ctx
->flags
& DELAY_SLOT_CLEARME
) {
1901 /* go out of the delay slot */
1902 uint32_t new_flags
= ctx
->flags
;
1903 new_flags
&= ~(DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
);
1904 gen_store_flags(new_flags
);
1907 ctx
->bstate
= BS_BRANCH
;
1908 if (old_flags
& DELAY_SLOT_CONDITIONAL
) {
1909 gen_delayed_conditional_jump(ctx
);
1910 } else if (old_flags
& DELAY_SLOT
) {
1916 /* go into a delay slot */
1917 if (ctx
->flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
))
1918 gen_store_flags(ctx
->flags
);
1922 gen_intermediate_code_internal(CPUState
* env
, TranslationBlock
* tb
,
1926 target_ulong pc_start
;
1927 static uint16_t *gen_opc_end
;
1934 gen_opc_end
= gen_opc_buf
+ OPC_MAX_SIZE
;
1936 ctx
.flags
= (uint32_t)tb
->flags
;
1937 ctx
.bstate
= BS_NONE
;
1939 ctx
.fpscr
= env
->fpscr
;
1940 ctx
.memidx
= (env
->sr
& SR_MD
) == 0 ? 1 : 0;
1941 /* We don't know if the delayed pc came from a dynamic or static branch,
1942 so assume it is a dynamic branch. */
1943 ctx
.delayed_pc
= -1; /* use delayed pc from env pointer */
1945 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
1946 ctx
.features
= env
->features
;
1947 ctx
.has_movcal
= (tb
->flags
& TB_FLAG_PENDING_MOVCA
);
1951 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
1953 max_insns
= CF_COUNT_MASK
;
1955 while (ctx
.bstate
== BS_NONE
&& gen_opc_ptr
< gen_opc_end
) {
1956 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
1957 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
1958 if (ctx
.pc
== bp
->pc
) {
1959 /* We have hit a breakpoint - make sure PC is up-to-date */
1960 tcg_gen_movi_i32(cpu_pc
, ctx
.pc
);
1962 ctx
.bstate
= BS_EXCP
;
1968 i
= gen_opc_ptr
- gen_opc_buf
;
1972 gen_opc_instr_start
[ii
++] = 0;
1974 gen_opc_pc
[ii
] = ctx
.pc
;
1975 gen_opc_hflags
[ii
] = ctx
.flags
;
1976 gen_opc_instr_start
[ii
] = 1;
1977 gen_opc_icount
[ii
] = num_insns
;
1979 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
1982 fprintf(stderr
, "Loading opcode at address 0x%08x\n", ctx
.pc
);
1985 ctx
.opcode
= lduw_code(ctx
.pc
);
1989 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
1991 if (env
->singlestep_enabled
)
1993 if (num_insns
>= max_insns
)
1998 if (tb
->cflags
& CF_LAST_IO
)
2000 if (env
->singlestep_enabled
) {
2001 tcg_gen_movi_i32(cpu_pc
, ctx
.pc
);
2004 switch (ctx
.bstate
) {
2006 /* gen_op_interrupt_restart(); */
2010 gen_store_flags(ctx
.flags
| DELAY_SLOT_CLEARME
);
2012 gen_goto_tb(&ctx
, 0, ctx
.pc
);
2015 /* gen_op_interrupt_restart(); */
2024 gen_icount_end(tb
, num_insns
);
2025 *gen_opc_ptr
= INDEX_op_end
;
2027 i
= gen_opc_ptr
- gen_opc_buf
;
2030 gen_opc_instr_start
[ii
++] = 0;
2032 tb
->size
= ctx
.pc
- pc_start
;
2033 tb
->icount
= num_insns
;
2037 #ifdef SH4_DEBUG_DISAS
2038 qemu_log_mask(CPU_LOG_TB_IN_ASM
, "\n");
2040 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
2041 qemu_log("IN:\n"); /* , lookup_symbol(pc_start)); */
2042 log_target_disas(pc_start
, ctx
.pc
- pc_start
, 0);
2048 void gen_intermediate_code(CPUState
* env
, struct TranslationBlock
*tb
)
2050 gen_intermediate_code_internal(env
, tb
, 0);
2053 void gen_intermediate_code_pc(CPUState
* env
, struct TranslationBlock
*tb
)
2055 gen_intermediate_code_internal(env
, tb
, 1);
2058 void gen_pc_load(CPUState
*env
, TranslationBlock
*tb
,
2059 unsigned long searched_pc
, int pc_pos
, void *puc
)
2061 env
->pc
= gen_opc_pc
[pc_pos
];
2062 env
->flags
= gen_opc_hflags
[pc_pos
];