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.1 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/>.
22 #include "qemu/osdep.h"
24 #include "disas/disas.h"
25 #include "exec/exec-all.h"
26 #include "tcg/tcg-op.h"
27 #include "exec/cpu_ldst.h"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30 #include "exec/translator.h"
31 #include "trace-tcg.h"
33 #include "qemu/qemu-print.h"
36 typedef struct DisasContext
{
37 DisasContextBase base
;
39 uint32_t tbflags
; /* should stay unmodified during the TB translation */
40 uint32_t envflags
; /* should stay in sync with env->flags using TCG ops */
52 #if defined(CONFIG_USER_ONLY)
53 #define IS_USER(ctx) 1
55 #define IS_USER(ctx) (!(ctx->tbflags & (1u << SR_MD)))
58 /* Target-specific values for ctx->base.is_jmp. */
59 /* We want to exit back to the cpu loop for some reason.
60 Usually this is to recognize interrupts immediately. */
61 #define DISAS_STOP DISAS_TARGET_0
63 /* global register indexes */
64 static TCGv cpu_gregs
[32];
65 static TCGv cpu_sr
, cpu_sr_m
, cpu_sr_q
, cpu_sr_t
;
66 static TCGv cpu_pc
, cpu_ssr
, cpu_spc
, cpu_gbr
;
67 static TCGv cpu_vbr
, cpu_sgr
, cpu_dbr
, cpu_mach
, cpu_macl
;
68 static TCGv cpu_pr
, cpu_fpscr
, cpu_fpul
;
69 static TCGv cpu_lock_addr
, cpu_lock_value
;
70 static TCGv cpu_fregs
[32];
72 /* internal register indexes */
73 static TCGv cpu_flags
, cpu_delayed_pc
, cpu_delayed_cond
;
75 #include "exec/gen-icount.h"
77 void sh4_translate_init(void)
80 static const char * const gregnames
[24] = {
81 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
82 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
83 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
84 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
85 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
87 static const char * const fregnames
[32] = {
88 "FPR0_BANK0", "FPR1_BANK0", "FPR2_BANK0", "FPR3_BANK0",
89 "FPR4_BANK0", "FPR5_BANK0", "FPR6_BANK0", "FPR7_BANK0",
90 "FPR8_BANK0", "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
91 "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
92 "FPR0_BANK1", "FPR1_BANK1", "FPR2_BANK1", "FPR3_BANK1",
93 "FPR4_BANK1", "FPR5_BANK1", "FPR6_BANK1", "FPR7_BANK1",
94 "FPR8_BANK1", "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
95 "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
98 for (i
= 0; i
< 24; i
++) {
99 cpu_gregs
[i
] = tcg_global_mem_new_i32(cpu_env
,
100 offsetof(CPUSH4State
, gregs
[i
]),
103 memcpy(cpu_gregs
+ 24, cpu_gregs
+ 8, 8 * sizeof(TCGv
));
105 cpu_pc
= tcg_global_mem_new_i32(cpu_env
,
106 offsetof(CPUSH4State
, pc
), "PC");
107 cpu_sr
= tcg_global_mem_new_i32(cpu_env
,
108 offsetof(CPUSH4State
, sr
), "SR");
109 cpu_sr_m
= tcg_global_mem_new_i32(cpu_env
,
110 offsetof(CPUSH4State
, sr_m
), "SR_M");
111 cpu_sr_q
= tcg_global_mem_new_i32(cpu_env
,
112 offsetof(CPUSH4State
, sr_q
), "SR_Q");
113 cpu_sr_t
= tcg_global_mem_new_i32(cpu_env
,
114 offsetof(CPUSH4State
, sr_t
), "SR_T");
115 cpu_ssr
= tcg_global_mem_new_i32(cpu_env
,
116 offsetof(CPUSH4State
, ssr
), "SSR");
117 cpu_spc
= tcg_global_mem_new_i32(cpu_env
,
118 offsetof(CPUSH4State
, spc
), "SPC");
119 cpu_gbr
= tcg_global_mem_new_i32(cpu_env
,
120 offsetof(CPUSH4State
, gbr
), "GBR");
121 cpu_vbr
= tcg_global_mem_new_i32(cpu_env
,
122 offsetof(CPUSH4State
, vbr
), "VBR");
123 cpu_sgr
= tcg_global_mem_new_i32(cpu_env
,
124 offsetof(CPUSH4State
, sgr
), "SGR");
125 cpu_dbr
= tcg_global_mem_new_i32(cpu_env
,
126 offsetof(CPUSH4State
, dbr
), "DBR");
127 cpu_mach
= tcg_global_mem_new_i32(cpu_env
,
128 offsetof(CPUSH4State
, mach
), "MACH");
129 cpu_macl
= tcg_global_mem_new_i32(cpu_env
,
130 offsetof(CPUSH4State
, macl
), "MACL");
131 cpu_pr
= tcg_global_mem_new_i32(cpu_env
,
132 offsetof(CPUSH4State
, pr
), "PR");
133 cpu_fpscr
= tcg_global_mem_new_i32(cpu_env
,
134 offsetof(CPUSH4State
, fpscr
), "FPSCR");
135 cpu_fpul
= tcg_global_mem_new_i32(cpu_env
,
136 offsetof(CPUSH4State
, fpul
), "FPUL");
138 cpu_flags
= tcg_global_mem_new_i32(cpu_env
,
139 offsetof(CPUSH4State
, flags
), "_flags_");
140 cpu_delayed_pc
= tcg_global_mem_new_i32(cpu_env
,
141 offsetof(CPUSH4State
, delayed_pc
),
143 cpu_delayed_cond
= tcg_global_mem_new_i32(cpu_env
,
144 offsetof(CPUSH4State
,
147 cpu_lock_addr
= tcg_global_mem_new_i32(cpu_env
,
148 offsetof(CPUSH4State
, lock_addr
),
150 cpu_lock_value
= tcg_global_mem_new_i32(cpu_env
,
151 offsetof(CPUSH4State
, lock_value
),
154 for (i
= 0; i
< 32; i
++)
155 cpu_fregs
[i
] = tcg_global_mem_new_i32(cpu_env
,
156 offsetof(CPUSH4State
, fregs
[i
]),
160 void superh_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
162 SuperHCPU
*cpu
= SUPERH_CPU(cs
);
163 CPUSH4State
*env
= &cpu
->env
;
166 qemu_fprintf(f
, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
167 env
->pc
, cpu_read_sr(env
), env
->pr
, env
->fpscr
);
168 qemu_fprintf(f
, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
169 env
->spc
, env
->ssr
, env
->gbr
, env
->vbr
);
170 qemu_fprintf(f
, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
171 env
->sgr
, env
->dbr
, env
->delayed_pc
, env
->fpul
);
172 for (i
= 0; i
< 24; i
+= 4) {
173 qemu_printf("r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
174 i
, env
->gregs
[i
], i
+ 1, env
->gregs
[i
+ 1],
175 i
+ 2, env
->gregs
[i
+ 2], i
+ 3, env
->gregs
[i
+ 3]);
177 if (env
->flags
& DELAY_SLOT
) {
178 qemu_printf("in delay slot (delayed_pc=0x%08x)\n",
180 } else if (env
->flags
& DELAY_SLOT_CONDITIONAL
) {
181 qemu_printf("in conditional delay slot (delayed_pc=0x%08x)\n",
183 } else if (env
->flags
& DELAY_SLOT_RTE
) {
184 qemu_fprintf(f
, "in rte delay slot (delayed_pc=0x%08x)\n",
189 static void gen_read_sr(TCGv dst
)
191 TCGv t0
= tcg_temp_new();
192 tcg_gen_shli_i32(t0
, cpu_sr_q
, SR_Q
);
193 tcg_gen_or_i32(dst
, dst
, t0
);
194 tcg_gen_shli_i32(t0
, cpu_sr_m
, SR_M
);
195 tcg_gen_or_i32(dst
, dst
, t0
);
196 tcg_gen_shli_i32(t0
, cpu_sr_t
, SR_T
);
197 tcg_gen_or_i32(dst
, cpu_sr
, t0
);
198 tcg_temp_free_i32(t0
);
201 static void gen_write_sr(TCGv src
)
203 tcg_gen_andi_i32(cpu_sr
, src
,
204 ~((1u << SR_Q
) | (1u << SR_M
) | (1u << SR_T
)));
205 tcg_gen_extract_i32(cpu_sr_q
, src
, SR_Q
, 1);
206 tcg_gen_extract_i32(cpu_sr_m
, src
, SR_M
, 1);
207 tcg_gen_extract_i32(cpu_sr_t
, src
, SR_T
, 1);
210 static inline void gen_save_cpu_state(DisasContext
*ctx
, bool save_pc
)
213 tcg_gen_movi_i32(cpu_pc
, ctx
->base
.pc_next
);
215 if (ctx
->delayed_pc
!= (uint32_t) -1) {
216 tcg_gen_movi_i32(cpu_delayed_pc
, ctx
->delayed_pc
);
218 if ((ctx
->tbflags
& TB_FLAG_ENVFLAGS_MASK
) != ctx
->envflags
) {
219 tcg_gen_movi_i32(cpu_flags
, ctx
->envflags
);
223 static inline bool use_exit_tb(DisasContext
*ctx
)
225 return (ctx
->tbflags
& GUSA_EXCLUSIVE
) != 0;
228 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
230 /* Use a direct jump if in same page and singlestep not enabled */
231 if (unlikely(ctx
->base
.singlestep_enabled
|| use_exit_tb(ctx
))) {
234 #ifndef CONFIG_USER_ONLY
235 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
241 static void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
243 if (use_goto_tb(ctx
, dest
)) {
245 tcg_gen_movi_i32(cpu_pc
, dest
);
246 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
248 tcg_gen_movi_i32(cpu_pc
, dest
);
249 if (ctx
->base
.singlestep_enabled
) {
250 gen_helper_debug(cpu_env
);
251 } else if (use_exit_tb(ctx
)) {
252 tcg_gen_exit_tb(NULL
, 0);
254 tcg_gen_lookup_and_goto_ptr();
257 ctx
->base
.is_jmp
= DISAS_NORETURN
;
260 static void gen_jump(DisasContext
* ctx
)
262 if (ctx
->delayed_pc
== -1) {
263 /* Target is not statically known, it comes necessarily from a
264 delayed jump as immediate jump are conditinal jumps */
265 tcg_gen_mov_i32(cpu_pc
, cpu_delayed_pc
);
266 tcg_gen_discard_i32(cpu_delayed_pc
);
267 if (ctx
->base
.singlestep_enabled
) {
268 gen_helper_debug(cpu_env
);
269 } else if (use_exit_tb(ctx
)) {
270 tcg_gen_exit_tb(NULL
, 0);
272 tcg_gen_lookup_and_goto_ptr();
274 ctx
->base
.is_jmp
= DISAS_NORETURN
;
276 gen_goto_tb(ctx
, 0, ctx
->delayed_pc
);
280 /* Immediate conditional jump (bt or bf) */
281 static void gen_conditional_jump(DisasContext
*ctx
, target_ulong dest
,
284 TCGLabel
*l1
= gen_new_label();
285 TCGCond cond_not_taken
= jump_if_true
? TCG_COND_EQ
: TCG_COND_NE
;
287 if (ctx
->tbflags
& GUSA_EXCLUSIVE
) {
288 /* When in an exclusive region, we must continue to the end.
289 Therefore, exit the region on a taken branch, but otherwise
290 fall through to the next instruction. */
291 tcg_gen_brcondi_i32(cond_not_taken
, cpu_sr_t
, 0, l1
);
292 tcg_gen_movi_i32(cpu_flags
, ctx
->envflags
& ~GUSA_MASK
);
293 /* Note that this won't actually use a goto_tb opcode because we
294 disallow it in use_goto_tb, but it handles exit + singlestep. */
295 gen_goto_tb(ctx
, 0, dest
);
297 ctx
->base
.is_jmp
= DISAS_NEXT
;
301 gen_save_cpu_state(ctx
, false);
302 tcg_gen_brcondi_i32(cond_not_taken
, cpu_sr_t
, 0, l1
);
303 gen_goto_tb(ctx
, 0, dest
);
305 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 2);
306 ctx
->base
.is_jmp
= DISAS_NORETURN
;
309 /* Delayed conditional jump (bt or bf) */
310 static void gen_delayed_conditional_jump(DisasContext
* ctx
)
312 TCGLabel
*l1
= gen_new_label();
313 TCGv ds
= tcg_temp_new();
315 tcg_gen_mov_i32(ds
, cpu_delayed_cond
);
316 tcg_gen_discard_i32(cpu_delayed_cond
);
318 if (ctx
->tbflags
& GUSA_EXCLUSIVE
) {
319 /* When in an exclusive region, we must continue to the end.
320 Therefore, exit the region on a taken branch, but otherwise
321 fall through to the next instruction. */
322 tcg_gen_brcondi_i32(TCG_COND_EQ
, ds
, 0, l1
);
324 /* Leave the gUSA region. */
325 tcg_gen_movi_i32(cpu_flags
, ctx
->envflags
& ~GUSA_MASK
);
329 ctx
->base
.is_jmp
= DISAS_NEXT
;
333 tcg_gen_brcondi_i32(TCG_COND_NE
, ds
, 0, l1
);
334 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 2);
339 static inline void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
341 /* We have already signaled illegal instruction for odd Dr. */
342 tcg_debug_assert((reg
& 1) == 0);
344 tcg_gen_concat_i32_i64(t
, cpu_fregs
[reg
+ 1], cpu_fregs
[reg
]);
347 static inline void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
349 /* We have already signaled illegal instruction for odd Dr. */
350 tcg_debug_assert((reg
& 1) == 0);
352 tcg_gen_extr_i64_i32(cpu_fregs
[reg
+ 1], cpu_fregs
[reg
], t
);
355 #define B3_0 (ctx->opcode & 0xf)
356 #define B6_4 ((ctx->opcode >> 4) & 0x7)
357 #define B7_4 ((ctx->opcode >> 4) & 0xf)
358 #define B7_0 (ctx->opcode & 0xff)
359 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
360 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
361 (ctx->opcode & 0xfff))
362 #define B11_8 ((ctx->opcode >> 8) & 0xf)
363 #define B15_12 ((ctx->opcode >> 12) & 0xf)
365 #define REG(x) cpu_gregs[(x) ^ ctx->gbank]
366 #define ALTREG(x) cpu_gregs[(x) ^ ctx->gbank ^ 0x10]
367 #define FREG(x) cpu_fregs[(x) ^ ctx->fbank]
369 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
371 #define CHECK_NOT_DELAY_SLOT \
372 if (ctx->envflags & DELAY_SLOT_MASK) { \
373 goto do_illegal_slot; \
376 #define CHECK_PRIVILEGED \
377 if (IS_USER(ctx)) { \
381 #define CHECK_FPU_ENABLED \
382 if (ctx->tbflags & (1u << SR_FD)) { \
383 goto do_fpu_disabled; \
386 #define CHECK_FPSCR_PR_0 \
387 if (ctx->tbflags & FPSCR_PR) { \
391 #define CHECK_FPSCR_PR_1 \
392 if (!(ctx->tbflags & FPSCR_PR)) { \
397 if (!(ctx->features & SH_FEATURE_SH4A)) { \
401 static void _decode_opc(DisasContext
* ctx
)
403 /* This code tries to make movcal emulation sufficiently
404 accurate for Linux purposes. This instruction writes
405 memory, and prior to that, always allocates a cache line.
406 It is used in two contexts:
407 - in memcpy, where data is copied in blocks, the first write
408 of to a block uses movca.l for performance.
409 - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
410 to flush the cache. Here, the data written by movcal.l is never
411 written to memory, and the data written is just bogus.
413 To simulate this, we simulate movcal.l, we store the value to memory,
414 but we also remember the previous content. If we see ocbi, we check
415 if movcal.l for that address was done previously. If so, the write should
416 not have hit the memory, so we restore the previous content.
417 When we see an instruction that is neither movca.l
418 nor ocbi, the previous content is discarded.
420 To optimize, we only try to flush stores when we're at the start of
421 TB, or if we already saw movca.l in this TB and did not flush stores
425 int opcode
= ctx
->opcode
& 0xf0ff;
426 if (opcode
!= 0x0093 /* ocbi */
427 && opcode
!= 0x00c3 /* movca.l */)
429 gen_helper_discard_movcal_backup(cpu_env
);
435 fprintf(stderr
, "Translating opcode 0x%04x\n", ctx
->opcode
);
438 switch (ctx
->opcode
) {
439 case 0x0019: /* div0u */
440 tcg_gen_movi_i32(cpu_sr_m
, 0);
441 tcg_gen_movi_i32(cpu_sr_q
, 0);
442 tcg_gen_movi_i32(cpu_sr_t
, 0);
444 case 0x000b: /* rts */
446 tcg_gen_mov_i32(cpu_delayed_pc
, cpu_pr
);
447 ctx
->envflags
|= DELAY_SLOT
;
448 ctx
->delayed_pc
= (uint32_t) - 1;
450 case 0x0028: /* clrmac */
451 tcg_gen_movi_i32(cpu_mach
, 0);
452 tcg_gen_movi_i32(cpu_macl
, 0);
454 case 0x0048: /* clrs */
455 tcg_gen_andi_i32(cpu_sr
, cpu_sr
, ~(1u << SR_S
));
457 case 0x0008: /* clrt */
458 tcg_gen_movi_i32(cpu_sr_t
, 0);
460 case 0x0038: /* ldtlb */
462 gen_helper_ldtlb(cpu_env
);
464 case 0x002b: /* rte */
467 gen_write_sr(cpu_ssr
);
468 tcg_gen_mov_i32(cpu_delayed_pc
, cpu_spc
);
469 ctx
->envflags
|= DELAY_SLOT_RTE
;
470 ctx
->delayed_pc
= (uint32_t) - 1;
471 ctx
->base
.is_jmp
= DISAS_STOP
;
473 case 0x0058: /* sets */
474 tcg_gen_ori_i32(cpu_sr
, cpu_sr
, (1u << SR_S
));
476 case 0x0018: /* sett */
477 tcg_gen_movi_i32(cpu_sr_t
, 1);
479 case 0xfbfd: /* frchg */
481 tcg_gen_xori_i32(cpu_fpscr
, cpu_fpscr
, FPSCR_FR
);
482 ctx
->base
.is_jmp
= DISAS_STOP
;
484 case 0xf3fd: /* fschg */
486 tcg_gen_xori_i32(cpu_fpscr
, cpu_fpscr
, FPSCR_SZ
);
487 ctx
->base
.is_jmp
= DISAS_STOP
;
489 case 0xf7fd: /* fpchg */
491 tcg_gen_xori_i32(cpu_fpscr
, cpu_fpscr
, FPSCR_PR
);
492 ctx
->base
.is_jmp
= DISAS_STOP
;
494 case 0x0009: /* nop */
496 case 0x001b: /* sleep */
498 tcg_gen_movi_i32(cpu_pc
, ctx
->base
.pc_next
+ 2);
499 gen_helper_sleep(cpu_env
);
503 switch (ctx
->opcode
& 0xf000) {
504 case 0x1000: /* mov.l Rm,@(disp,Rn) */
506 TCGv addr
= tcg_temp_new();
507 tcg_gen_addi_i32(addr
, REG(B11_8
), B3_0
* 4);
508 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
512 case 0x5000: /* mov.l @(disp,Rm),Rn */
514 TCGv addr
= tcg_temp_new();
515 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 4);
516 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESL
);
520 case 0xe000: /* mov #imm,Rn */
521 #ifdef CONFIG_USER_ONLY
522 /* Detect the start of a gUSA region. If so, update envflags
523 and end the TB. This will allow us to see the end of the
524 region (stored in R0) in the next TB. */
525 if (B11_8
== 15 && B7_0s
< 0 &&
526 (tb_cflags(ctx
->base
.tb
) & CF_PARALLEL
)) {
527 ctx
->envflags
= deposit32(ctx
->envflags
, GUSA_SHIFT
, 8, B7_0s
);
528 ctx
->base
.is_jmp
= DISAS_STOP
;
531 tcg_gen_movi_i32(REG(B11_8
), B7_0s
);
533 case 0x9000: /* mov.w @(disp,PC),Rn */
535 TCGv addr
= tcg_const_i32(ctx
->base
.pc_next
+ 4 + B7_0
* 2);
536 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESW
);
540 case 0xd000: /* mov.l @(disp,PC),Rn */
542 TCGv addr
= tcg_const_i32((ctx
->base
.pc_next
+ 4 + B7_0
* 4) & ~3);
543 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESL
);
547 case 0x7000: /* add #imm,Rn */
548 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), B7_0s
);
550 case 0xa000: /* bra disp */
552 ctx
->delayed_pc
= ctx
->base
.pc_next
+ 4 + B11_0s
* 2;
553 ctx
->envflags
|= DELAY_SLOT
;
555 case 0xb000: /* bsr disp */
557 tcg_gen_movi_i32(cpu_pr
, ctx
->base
.pc_next
+ 4);
558 ctx
->delayed_pc
= ctx
->base
.pc_next
+ 4 + B11_0s
* 2;
559 ctx
->envflags
|= DELAY_SLOT
;
563 switch (ctx
->opcode
& 0xf00f) {
564 case 0x6003: /* mov Rm,Rn */
565 tcg_gen_mov_i32(REG(B11_8
), REG(B7_4
));
567 case 0x2000: /* mov.b Rm,@Rn */
568 tcg_gen_qemu_st_i32(REG(B7_4
), REG(B11_8
), ctx
->memidx
, MO_UB
);
570 case 0x2001: /* mov.w Rm,@Rn */
571 tcg_gen_qemu_st_i32(REG(B7_4
), REG(B11_8
), ctx
->memidx
, MO_TEUW
);
573 case 0x2002: /* mov.l Rm,@Rn */
574 tcg_gen_qemu_st_i32(REG(B7_4
), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
576 case 0x6000: /* mov.b @Rm,Rn */
577 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_SB
);
579 case 0x6001: /* mov.w @Rm,Rn */
580 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESW
);
582 case 0x6002: /* mov.l @Rm,Rn */
583 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESL
);
585 case 0x2004: /* mov.b Rm,@-Rn */
587 TCGv addr
= tcg_temp_new();
588 tcg_gen_subi_i32(addr
, REG(B11_8
), 1);
589 /* might cause re-execution */
590 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_UB
);
591 tcg_gen_mov_i32(REG(B11_8
), addr
); /* modify register status */
595 case 0x2005: /* mov.w Rm,@-Rn */
597 TCGv addr
= tcg_temp_new();
598 tcg_gen_subi_i32(addr
, REG(B11_8
), 2);
599 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUW
);
600 tcg_gen_mov_i32(REG(B11_8
), addr
);
604 case 0x2006: /* mov.l Rm,@-Rn */
606 TCGv addr
= tcg_temp_new();
607 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
608 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
609 tcg_gen_mov_i32(REG(B11_8
), addr
);
613 case 0x6004: /* mov.b @Rm+,Rn */
614 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_SB
);
616 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 1);
618 case 0x6005: /* mov.w @Rm+,Rn */
619 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESW
);
621 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 2);
623 case 0x6006: /* mov.l @Rm+,Rn */
624 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESL
);
626 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
628 case 0x0004: /* mov.b Rm,@(R0,Rn) */
630 TCGv addr
= tcg_temp_new();
631 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
632 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_UB
);
636 case 0x0005: /* mov.w Rm,@(R0,Rn) */
638 TCGv addr
= tcg_temp_new();
639 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
640 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUW
);
644 case 0x0006: /* mov.l Rm,@(R0,Rn) */
646 TCGv addr
= tcg_temp_new();
647 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
648 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
652 case 0x000c: /* mov.b @(R0,Rm),Rn */
654 TCGv addr
= tcg_temp_new();
655 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
656 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_SB
);
660 case 0x000d: /* mov.w @(R0,Rm),Rn */
662 TCGv addr
= tcg_temp_new();
663 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
664 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESW
);
668 case 0x000e: /* mov.l @(R0,Rm),Rn */
670 TCGv addr
= tcg_temp_new();
671 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
672 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESL
);
676 case 0x6008: /* swap.b Rm,Rn */
678 TCGv low
= tcg_temp_new();
679 tcg_gen_ext16u_i32(low
, REG(B7_4
));
680 tcg_gen_bswap16_i32(low
, low
);
681 tcg_gen_deposit_i32(REG(B11_8
), REG(B7_4
), low
, 0, 16);
685 case 0x6009: /* swap.w Rm,Rn */
686 tcg_gen_rotli_i32(REG(B11_8
), REG(B7_4
), 16);
688 case 0x200d: /* xtrct Rm,Rn */
691 high
= tcg_temp_new();
692 tcg_gen_shli_i32(high
, REG(B7_4
), 16);
693 low
= tcg_temp_new();
694 tcg_gen_shri_i32(low
, REG(B11_8
), 16);
695 tcg_gen_or_i32(REG(B11_8
), high
, low
);
700 case 0x300c: /* add Rm,Rn */
701 tcg_gen_add_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
703 case 0x300e: /* addc Rm,Rn */
706 t0
= tcg_const_tl(0);
708 tcg_gen_add2_i32(t1
, cpu_sr_t
, cpu_sr_t
, t0
, REG(B7_4
), t0
);
709 tcg_gen_add2_i32(REG(B11_8
), cpu_sr_t
,
710 REG(B11_8
), t0
, t1
, cpu_sr_t
);
715 case 0x300f: /* addv Rm,Rn */
719 tcg_gen_add_i32(t0
, REG(B7_4
), REG(B11_8
));
721 tcg_gen_xor_i32(t1
, t0
, REG(B11_8
));
723 tcg_gen_xor_i32(t2
, REG(B7_4
), REG(B11_8
));
724 tcg_gen_andc_i32(cpu_sr_t
, t1
, t2
);
726 tcg_gen_shri_i32(cpu_sr_t
, cpu_sr_t
, 31);
728 tcg_gen_mov_i32(REG(B7_4
), t0
);
732 case 0x2009: /* and Rm,Rn */
733 tcg_gen_and_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
735 case 0x3000: /* cmp/eq Rm,Rn */
736 tcg_gen_setcond_i32(TCG_COND_EQ
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
738 case 0x3003: /* cmp/ge Rm,Rn */
739 tcg_gen_setcond_i32(TCG_COND_GE
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
741 case 0x3007: /* cmp/gt Rm,Rn */
742 tcg_gen_setcond_i32(TCG_COND_GT
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
744 case 0x3006: /* cmp/hi Rm,Rn */
745 tcg_gen_setcond_i32(TCG_COND_GTU
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
747 case 0x3002: /* cmp/hs Rm,Rn */
748 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
750 case 0x200c: /* cmp/str Rm,Rn */
752 TCGv cmp1
= tcg_temp_new();
753 TCGv cmp2
= tcg_temp_new();
754 tcg_gen_xor_i32(cmp2
, REG(B7_4
), REG(B11_8
));
755 tcg_gen_subi_i32(cmp1
, cmp2
, 0x01010101);
756 tcg_gen_andc_i32(cmp1
, cmp1
, cmp2
);
757 tcg_gen_andi_i32(cmp1
, cmp1
, 0x80808080);
758 tcg_gen_setcondi_i32(TCG_COND_NE
, cpu_sr_t
, cmp1
, 0);
763 case 0x2007: /* div0s Rm,Rn */
764 tcg_gen_shri_i32(cpu_sr_q
, REG(B11_8
), 31); /* SR_Q */
765 tcg_gen_shri_i32(cpu_sr_m
, REG(B7_4
), 31); /* SR_M */
766 tcg_gen_xor_i32(cpu_sr_t
, cpu_sr_q
, cpu_sr_m
); /* SR_T */
768 case 0x3004: /* div1 Rm,Rn */
770 TCGv t0
= tcg_temp_new();
771 TCGv t1
= tcg_temp_new();
772 TCGv t2
= tcg_temp_new();
773 TCGv zero
= tcg_const_i32(0);
775 /* shift left arg1, saving the bit being pushed out and inserting
777 tcg_gen_shri_i32(t0
, REG(B11_8
), 31);
778 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
779 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), cpu_sr_t
);
781 /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
782 using 64-bit temps, we compute arg0's high part from q ^ m, so
783 that it is 0x00000000 when adding the value or 0xffffffff when
785 tcg_gen_xor_i32(t1
, cpu_sr_q
, cpu_sr_m
);
786 tcg_gen_subi_i32(t1
, t1
, 1);
787 tcg_gen_neg_i32(t2
, REG(B7_4
));
788 tcg_gen_movcond_i32(TCG_COND_EQ
, t2
, t1
, zero
, REG(B7_4
), t2
);
789 tcg_gen_add2_i32(REG(B11_8
), t1
, REG(B11_8
), zero
, t2
, t1
);
791 /* compute T and Q depending on carry */
792 tcg_gen_andi_i32(t1
, t1
, 1);
793 tcg_gen_xor_i32(t1
, t1
, t0
);
794 tcg_gen_xori_i32(cpu_sr_t
, t1
, 1);
795 tcg_gen_xor_i32(cpu_sr_q
, cpu_sr_m
, t1
);
803 case 0x300d: /* dmuls.l Rm,Rn */
804 tcg_gen_muls2_i32(cpu_macl
, cpu_mach
, REG(B7_4
), REG(B11_8
));
806 case 0x3005: /* dmulu.l Rm,Rn */
807 tcg_gen_mulu2_i32(cpu_macl
, cpu_mach
, REG(B7_4
), REG(B11_8
));
809 case 0x600e: /* exts.b Rm,Rn */
810 tcg_gen_ext8s_i32(REG(B11_8
), REG(B7_4
));
812 case 0x600f: /* exts.w Rm,Rn */
813 tcg_gen_ext16s_i32(REG(B11_8
), REG(B7_4
));
815 case 0x600c: /* extu.b Rm,Rn */
816 tcg_gen_ext8u_i32(REG(B11_8
), REG(B7_4
));
818 case 0x600d: /* extu.w Rm,Rn */
819 tcg_gen_ext16u_i32(REG(B11_8
), REG(B7_4
));
821 case 0x000f: /* mac.l @Rm+,@Rn+ */
824 arg0
= tcg_temp_new();
825 tcg_gen_qemu_ld_i32(arg0
, REG(B7_4
), ctx
->memidx
, MO_TESL
);
826 arg1
= tcg_temp_new();
827 tcg_gen_qemu_ld_i32(arg1
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
828 gen_helper_macl(cpu_env
, arg0
, arg1
);
831 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
832 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
835 case 0x400f: /* mac.w @Rm+,@Rn+ */
838 arg0
= tcg_temp_new();
839 tcg_gen_qemu_ld_i32(arg0
, REG(B7_4
), ctx
->memidx
, MO_TESL
);
840 arg1
= tcg_temp_new();
841 tcg_gen_qemu_ld_i32(arg1
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
842 gen_helper_macw(cpu_env
, arg0
, arg1
);
845 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 2);
846 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 2);
849 case 0x0007: /* mul.l Rm,Rn */
850 tcg_gen_mul_i32(cpu_macl
, REG(B7_4
), REG(B11_8
));
852 case 0x200f: /* muls.w Rm,Rn */
855 arg0
= tcg_temp_new();
856 tcg_gen_ext16s_i32(arg0
, REG(B7_4
));
857 arg1
= tcg_temp_new();
858 tcg_gen_ext16s_i32(arg1
, REG(B11_8
));
859 tcg_gen_mul_i32(cpu_macl
, arg0
, arg1
);
864 case 0x200e: /* mulu.w Rm,Rn */
867 arg0
= tcg_temp_new();
868 tcg_gen_ext16u_i32(arg0
, REG(B7_4
));
869 arg1
= tcg_temp_new();
870 tcg_gen_ext16u_i32(arg1
, REG(B11_8
));
871 tcg_gen_mul_i32(cpu_macl
, arg0
, arg1
);
876 case 0x600b: /* neg Rm,Rn */
877 tcg_gen_neg_i32(REG(B11_8
), REG(B7_4
));
879 case 0x600a: /* negc Rm,Rn */
881 TCGv t0
= tcg_const_i32(0);
882 tcg_gen_add2_i32(REG(B11_8
), cpu_sr_t
,
883 REG(B7_4
), t0
, cpu_sr_t
, t0
);
884 tcg_gen_sub2_i32(REG(B11_8
), cpu_sr_t
,
885 t0
, t0
, REG(B11_8
), cpu_sr_t
);
886 tcg_gen_andi_i32(cpu_sr_t
, cpu_sr_t
, 1);
890 case 0x6007: /* not Rm,Rn */
891 tcg_gen_not_i32(REG(B11_8
), REG(B7_4
));
893 case 0x200b: /* or Rm,Rn */
894 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
896 case 0x400c: /* shad Rm,Rn */
898 TCGv t0
= tcg_temp_new();
899 TCGv t1
= tcg_temp_new();
900 TCGv t2
= tcg_temp_new();
902 tcg_gen_andi_i32(t0
, REG(B7_4
), 0x1f);
904 /* positive case: shift to the left */
905 tcg_gen_shl_i32(t1
, REG(B11_8
), t0
);
907 /* negative case: shift to the right in two steps to
908 correctly handle the -32 case */
909 tcg_gen_xori_i32(t0
, t0
, 0x1f);
910 tcg_gen_sar_i32(t2
, REG(B11_8
), t0
);
911 tcg_gen_sari_i32(t2
, t2
, 1);
913 /* select between the two cases */
914 tcg_gen_movi_i32(t0
, 0);
915 tcg_gen_movcond_i32(TCG_COND_GE
, REG(B11_8
), REG(B7_4
), t0
, t1
, t2
);
922 case 0x400d: /* shld Rm,Rn */
924 TCGv t0
= tcg_temp_new();
925 TCGv t1
= tcg_temp_new();
926 TCGv t2
= tcg_temp_new();
928 tcg_gen_andi_i32(t0
, REG(B7_4
), 0x1f);
930 /* positive case: shift to the left */
931 tcg_gen_shl_i32(t1
, REG(B11_8
), t0
);
933 /* negative case: shift to the right in two steps to
934 correctly handle the -32 case */
935 tcg_gen_xori_i32(t0
, t0
, 0x1f);
936 tcg_gen_shr_i32(t2
, REG(B11_8
), t0
);
937 tcg_gen_shri_i32(t2
, t2
, 1);
939 /* select between the two cases */
940 tcg_gen_movi_i32(t0
, 0);
941 tcg_gen_movcond_i32(TCG_COND_GE
, REG(B11_8
), REG(B7_4
), t0
, t1
, t2
);
948 case 0x3008: /* sub Rm,Rn */
949 tcg_gen_sub_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
951 case 0x300a: /* subc Rm,Rn */
954 t0
= tcg_const_tl(0);
956 tcg_gen_add2_i32(t1
, cpu_sr_t
, cpu_sr_t
, t0
, REG(B7_4
), t0
);
957 tcg_gen_sub2_i32(REG(B11_8
), cpu_sr_t
,
958 REG(B11_8
), t0
, t1
, cpu_sr_t
);
959 tcg_gen_andi_i32(cpu_sr_t
, cpu_sr_t
, 1);
964 case 0x300b: /* subv Rm,Rn */
968 tcg_gen_sub_i32(t0
, REG(B11_8
), REG(B7_4
));
970 tcg_gen_xor_i32(t1
, t0
, REG(B7_4
));
972 tcg_gen_xor_i32(t2
, REG(B11_8
), REG(B7_4
));
973 tcg_gen_and_i32(t1
, t1
, t2
);
975 tcg_gen_shri_i32(cpu_sr_t
, t1
, 31);
977 tcg_gen_mov_i32(REG(B11_8
), t0
);
981 case 0x2008: /* tst Rm,Rn */
983 TCGv val
= tcg_temp_new();
984 tcg_gen_and_i32(val
, REG(B7_4
), REG(B11_8
));
985 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
989 case 0x200a: /* xor Rm,Rn */
990 tcg_gen_xor_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
992 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
994 if (ctx
->tbflags
& FPSCR_SZ
) {
995 int xsrc
= XHACK(B7_4
);
996 int xdst
= XHACK(B11_8
);
997 tcg_gen_mov_i32(FREG(xdst
), FREG(xsrc
));
998 tcg_gen_mov_i32(FREG(xdst
+ 1), FREG(xsrc
+ 1));
1000 tcg_gen_mov_i32(FREG(B11_8
), FREG(B7_4
));
1003 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
1005 if (ctx
->tbflags
& FPSCR_SZ
) {
1006 TCGv_i64 fp
= tcg_temp_new_i64();
1007 gen_load_fpr64(ctx
, fp
, XHACK(B7_4
));
1008 tcg_gen_qemu_st_i64(fp
, REG(B11_8
), ctx
->memidx
, MO_TEQ
);
1009 tcg_temp_free_i64(fp
);
1011 tcg_gen_qemu_st_i32(FREG(B7_4
), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1014 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
1016 if (ctx
->tbflags
& FPSCR_SZ
) {
1017 TCGv_i64 fp
= tcg_temp_new_i64();
1018 tcg_gen_qemu_ld_i64(fp
, REG(B7_4
), ctx
->memidx
, MO_TEQ
);
1019 gen_store_fpr64(ctx
, fp
, XHACK(B11_8
));
1020 tcg_temp_free_i64(fp
);
1022 tcg_gen_qemu_ld_i32(FREG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TEUL
);
1025 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
1027 if (ctx
->tbflags
& FPSCR_SZ
) {
1028 TCGv_i64 fp
= tcg_temp_new_i64();
1029 tcg_gen_qemu_ld_i64(fp
, REG(B7_4
), ctx
->memidx
, MO_TEQ
);
1030 gen_store_fpr64(ctx
, fp
, XHACK(B11_8
));
1031 tcg_temp_free_i64(fp
);
1032 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 8);
1034 tcg_gen_qemu_ld_i32(FREG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TEUL
);
1035 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
1038 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
1041 TCGv addr
= tcg_temp_new_i32();
1042 if (ctx
->tbflags
& FPSCR_SZ
) {
1043 TCGv_i64 fp
= tcg_temp_new_i64();
1044 gen_load_fpr64(ctx
, fp
, XHACK(B7_4
));
1045 tcg_gen_subi_i32(addr
, REG(B11_8
), 8);
1046 tcg_gen_qemu_st_i64(fp
, addr
, ctx
->memidx
, MO_TEQ
);
1047 tcg_temp_free_i64(fp
);
1049 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1050 tcg_gen_qemu_st_i32(FREG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
1052 tcg_gen_mov_i32(REG(B11_8
), addr
);
1053 tcg_temp_free(addr
);
1056 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1059 TCGv addr
= tcg_temp_new_i32();
1060 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
1061 if (ctx
->tbflags
& FPSCR_SZ
) {
1062 TCGv_i64 fp
= tcg_temp_new_i64();
1063 tcg_gen_qemu_ld_i64(fp
, addr
, ctx
->memidx
, MO_TEQ
);
1064 gen_store_fpr64(ctx
, fp
, XHACK(B11_8
));
1065 tcg_temp_free_i64(fp
);
1067 tcg_gen_qemu_ld_i32(FREG(B11_8
), addr
, ctx
->memidx
, MO_TEUL
);
1069 tcg_temp_free(addr
);
1072 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1075 TCGv addr
= tcg_temp_new();
1076 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
1077 if (ctx
->tbflags
& FPSCR_SZ
) {
1078 TCGv_i64 fp
= tcg_temp_new_i64();
1079 gen_load_fpr64(ctx
, fp
, XHACK(B7_4
));
1080 tcg_gen_qemu_st_i64(fp
, addr
, ctx
->memidx
, MO_TEQ
);
1081 tcg_temp_free_i64(fp
);
1083 tcg_gen_qemu_st_i32(FREG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
1085 tcg_temp_free(addr
);
1088 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1089 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1090 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1091 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1092 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1093 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1096 if (ctx
->tbflags
& FPSCR_PR
) {
1099 if (ctx
->opcode
& 0x0110) {
1102 fp0
= tcg_temp_new_i64();
1103 fp1
= tcg_temp_new_i64();
1104 gen_load_fpr64(ctx
, fp0
, B11_8
);
1105 gen_load_fpr64(ctx
, fp1
, B7_4
);
1106 switch (ctx
->opcode
& 0xf00f) {
1107 case 0xf000: /* fadd Rm,Rn */
1108 gen_helper_fadd_DT(fp0
, cpu_env
, fp0
, fp1
);
1110 case 0xf001: /* fsub Rm,Rn */
1111 gen_helper_fsub_DT(fp0
, cpu_env
, fp0
, fp1
);
1113 case 0xf002: /* fmul Rm,Rn */
1114 gen_helper_fmul_DT(fp0
, cpu_env
, fp0
, fp1
);
1116 case 0xf003: /* fdiv Rm,Rn */
1117 gen_helper_fdiv_DT(fp0
, cpu_env
, fp0
, fp1
);
1119 case 0xf004: /* fcmp/eq Rm,Rn */
1120 gen_helper_fcmp_eq_DT(cpu_sr_t
, cpu_env
, fp0
, fp1
);
1122 case 0xf005: /* fcmp/gt Rm,Rn */
1123 gen_helper_fcmp_gt_DT(cpu_sr_t
, cpu_env
, fp0
, fp1
);
1126 gen_store_fpr64(ctx
, fp0
, B11_8
);
1127 tcg_temp_free_i64(fp0
);
1128 tcg_temp_free_i64(fp1
);
1130 switch (ctx
->opcode
& 0xf00f) {
1131 case 0xf000: /* fadd Rm,Rn */
1132 gen_helper_fadd_FT(FREG(B11_8
), cpu_env
,
1133 FREG(B11_8
), FREG(B7_4
));
1135 case 0xf001: /* fsub Rm,Rn */
1136 gen_helper_fsub_FT(FREG(B11_8
), cpu_env
,
1137 FREG(B11_8
), FREG(B7_4
));
1139 case 0xf002: /* fmul Rm,Rn */
1140 gen_helper_fmul_FT(FREG(B11_8
), cpu_env
,
1141 FREG(B11_8
), FREG(B7_4
));
1143 case 0xf003: /* fdiv Rm,Rn */
1144 gen_helper_fdiv_FT(FREG(B11_8
), cpu_env
,
1145 FREG(B11_8
), FREG(B7_4
));
1147 case 0xf004: /* fcmp/eq Rm,Rn */
1148 gen_helper_fcmp_eq_FT(cpu_sr_t
, cpu_env
,
1149 FREG(B11_8
), FREG(B7_4
));
1151 case 0xf005: /* fcmp/gt Rm,Rn */
1152 gen_helper_fcmp_gt_FT(cpu_sr_t
, cpu_env
,
1153 FREG(B11_8
), FREG(B7_4
));
1159 case 0xf00e: /* fmac FR0,RM,Rn */
1162 gen_helper_fmac_FT(FREG(B11_8
), cpu_env
,
1163 FREG(0), FREG(B7_4
), FREG(B11_8
));
1167 switch (ctx
->opcode
& 0xff00) {
1168 case 0xc900: /* and #imm,R0 */
1169 tcg_gen_andi_i32(REG(0), REG(0), B7_0
);
1171 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1174 addr
= tcg_temp_new();
1175 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1176 val
= tcg_temp_new();
1177 tcg_gen_qemu_ld_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1178 tcg_gen_andi_i32(val
, val
, B7_0
);
1179 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1181 tcg_temp_free(addr
);
1184 case 0x8b00: /* bf label */
1185 CHECK_NOT_DELAY_SLOT
1186 gen_conditional_jump(ctx
, ctx
->base
.pc_next
+ 4 + B7_0s
* 2, false);
1188 case 0x8f00: /* bf/s label */
1189 CHECK_NOT_DELAY_SLOT
1190 tcg_gen_xori_i32(cpu_delayed_cond
, cpu_sr_t
, 1);
1191 ctx
->delayed_pc
= ctx
->base
.pc_next
+ 4 + B7_0s
* 2;
1192 ctx
->envflags
|= DELAY_SLOT_CONDITIONAL
;
1194 case 0x8900: /* bt label */
1195 CHECK_NOT_DELAY_SLOT
1196 gen_conditional_jump(ctx
, ctx
->base
.pc_next
+ 4 + B7_0s
* 2, true);
1198 case 0x8d00: /* bt/s label */
1199 CHECK_NOT_DELAY_SLOT
1200 tcg_gen_mov_i32(cpu_delayed_cond
, cpu_sr_t
);
1201 ctx
->delayed_pc
= ctx
->base
.pc_next
+ 4 + B7_0s
* 2;
1202 ctx
->envflags
|= DELAY_SLOT_CONDITIONAL
;
1204 case 0x8800: /* cmp/eq #imm,R0 */
1205 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, REG(0), B7_0s
);
1207 case 0xc400: /* mov.b @(disp,GBR),R0 */
1209 TCGv addr
= tcg_temp_new();
1210 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
);
1211 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_SB
);
1212 tcg_temp_free(addr
);
1215 case 0xc500: /* mov.w @(disp,GBR),R0 */
1217 TCGv addr
= tcg_temp_new();
1218 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 2);
1219 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_TESW
);
1220 tcg_temp_free(addr
);
1223 case 0xc600: /* mov.l @(disp,GBR),R0 */
1225 TCGv addr
= tcg_temp_new();
1226 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 4);
1227 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_TESL
);
1228 tcg_temp_free(addr
);
1231 case 0xc000: /* mov.b R0,@(disp,GBR) */
1233 TCGv addr
= tcg_temp_new();
1234 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
);
1235 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_UB
);
1236 tcg_temp_free(addr
);
1239 case 0xc100: /* mov.w R0,@(disp,GBR) */
1241 TCGv addr
= tcg_temp_new();
1242 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 2);
1243 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_TEUW
);
1244 tcg_temp_free(addr
);
1247 case 0xc200: /* mov.l R0,@(disp,GBR) */
1249 TCGv addr
= tcg_temp_new();
1250 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 4);
1251 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_TEUL
);
1252 tcg_temp_free(addr
);
1255 case 0x8000: /* mov.b R0,@(disp,Rn) */
1257 TCGv addr
= tcg_temp_new();
1258 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
);
1259 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_UB
);
1260 tcg_temp_free(addr
);
1263 case 0x8100: /* mov.w R0,@(disp,Rn) */
1265 TCGv addr
= tcg_temp_new();
1266 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 2);
1267 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_TEUW
);
1268 tcg_temp_free(addr
);
1271 case 0x8400: /* mov.b @(disp,Rn),R0 */
1273 TCGv addr
= tcg_temp_new();
1274 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
);
1275 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_SB
);
1276 tcg_temp_free(addr
);
1279 case 0x8500: /* mov.w @(disp,Rn),R0 */
1281 TCGv addr
= tcg_temp_new();
1282 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 2);
1283 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_TESW
);
1284 tcg_temp_free(addr
);
1287 case 0xc700: /* mova @(disp,PC),R0 */
1288 tcg_gen_movi_i32(REG(0), ((ctx
->base
.pc_next
& 0xfffffffc) +
1289 4 + B7_0
* 4) & ~3);
1291 case 0xcb00: /* or #imm,R0 */
1292 tcg_gen_ori_i32(REG(0), REG(0), B7_0
);
1294 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1297 addr
= tcg_temp_new();
1298 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1299 val
= tcg_temp_new();
1300 tcg_gen_qemu_ld_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1301 tcg_gen_ori_i32(val
, val
, B7_0
);
1302 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1304 tcg_temp_free(addr
);
1307 case 0xc300: /* trapa #imm */
1310 CHECK_NOT_DELAY_SLOT
1311 gen_save_cpu_state(ctx
, true);
1312 imm
= tcg_const_i32(B7_0
);
1313 gen_helper_trapa(cpu_env
, imm
);
1315 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1318 case 0xc800: /* tst #imm,R0 */
1320 TCGv val
= tcg_temp_new();
1321 tcg_gen_andi_i32(val
, REG(0), B7_0
);
1322 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
1326 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1328 TCGv val
= tcg_temp_new();
1329 tcg_gen_add_i32(val
, REG(0), cpu_gbr
);
1330 tcg_gen_qemu_ld_i32(val
, val
, ctx
->memidx
, MO_UB
);
1331 tcg_gen_andi_i32(val
, val
, B7_0
);
1332 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
1336 case 0xca00: /* xor #imm,R0 */
1337 tcg_gen_xori_i32(REG(0), REG(0), B7_0
);
1339 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1342 addr
= tcg_temp_new();
1343 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1344 val
= tcg_temp_new();
1345 tcg_gen_qemu_ld_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1346 tcg_gen_xori_i32(val
, val
, B7_0
);
1347 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1349 tcg_temp_free(addr
);
1354 switch (ctx
->opcode
& 0xf08f) {
1355 case 0x408e: /* ldc Rm,Rn_BANK */
1357 tcg_gen_mov_i32(ALTREG(B6_4
), REG(B11_8
));
1359 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1361 tcg_gen_qemu_ld_i32(ALTREG(B6_4
), REG(B11_8
), ctx
->memidx
, MO_TESL
);
1362 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1364 case 0x0082: /* stc Rm_BANK,Rn */
1366 tcg_gen_mov_i32(REG(B11_8
), ALTREG(B6_4
));
1368 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1371 TCGv addr
= tcg_temp_new();
1372 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1373 tcg_gen_qemu_st_i32(ALTREG(B6_4
), addr
, ctx
->memidx
, MO_TEUL
);
1374 tcg_gen_mov_i32(REG(B11_8
), addr
);
1375 tcg_temp_free(addr
);
1380 switch (ctx
->opcode
& 0xf0ff) {
1381 case 0x0023: /* braf Rn */
1382 CHECK_NOT_DELAY_SLOT
1383 tcg_gen_addi_i32(cpu_delayed_pc
, REG(B11_8
), ctx
->base
.pc_next
+ 4);
1384 ctx
->envflags
|= DELAY_SLOT
;
1385 ctx
->delayed_pc
= (uint32_t) - 1;
1387 case 0x0003: /* bsrf Rn */
1388 CHECK_NOT_DELAY_SLOT
1389 tcg_gen_movi_i32(cpu_pr
, ctx
->base
.pc_next
+ 4);
1390 tcg_gen_add_i32(cpu_delayed_pc
, REG(B11_8
), cpu_pr
);
1391 ctx
->envflags
|= DELAY_SLOT
;
1392 ctx
->delayed_pc
= (uint32_t) - 1;
1394 case 0x4015: /* cmp/pl Rn */
1395 tcg_gen_setcondi_i32(TCG_COND_GT
, cpu_sr_t
, REG(B11_8
), 0);
1397 case 0x4011: /* cmp/pz Rn */
1398 tcg_gen_setcondi_i32(TCG_COND_GE
, cpu_sr_t
, REG(B11_8
), 0);
1400 case 0x4010: /* dt Rn */
1401 tcg_gen_subi_i32(REG(B11_8
), REG(B11_8
), 1);
1402 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, REG(B11_8
), 0);
1404 case 0x402b: /* jmp @Rn */
1405 CHECK_NOT_DELAY_SLOT
1406 tcg_gen_mov_i32(cpu_delayed_pc
, REG(B11_8
));
1407 ctx
->envflags
|= DELAY_SLOT
;
1408 ctx
->delayed_pc
= (uint32_t) - 1;
1410 case 0x400b: /* jsr @Rn */
1411 CHECK_NOT_DELAY_SLOT
1412 tcg_gen_movi_i32(cpu_pr
, ctx
->base
.pc_next
+ 4);
1413 tcg_gen_mov_i32(cpu_delayed_pc
, REG(B11_8
));
1414 ctx
->envflags
|= DELAY_SLOT
;
1415 ctx
->delayed_pc
= (uint32_t) - 1;
1417 case 0x400e: /* ldc Rm,SR */
1420 TCGv val
= tcg_temp_new();
1421 tcg_gen_andi_i32(val
, REG(B11_8
), 0x700083f3);
1424 ctx
->base
.is_jmp
= DISAS_STOP
;
1427 case 0x4007: /* ldc.l @Rm+,SR */
1430 TCGv val
= tcg_temp_new();
1431 tcg_gen_qemu_ld_i32(val
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
1432 tcg_gen_andi_i32(val
, val
, 0x700083f3);
1435 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1436 ctx
->base
.is_jmp
= DISAS_STOP
;
1439 case 0x0002: /* stc SR,Rn */
1441 gen_read_sr(REG(B11_8
));
1443 case 0x4003: /* stc SR,@-Rn */
1446 TCGv addr
= tcg_temp_new();
1447 TCGv val
= tcg_temp_new();
1448 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1450 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_TEUL
);
1451 tcg_gen_mov_i32(REG(B11_8
), addr
);
1453 tcg_temp_free(addr
);
1456 #define LD(reg,ldnum,ldpnum,prechk) \
1459 tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \
1463 tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1464 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \
1466 #define ST(reg,stnum,stpnum,prechk) \
1469 tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \
1474 TCGv addr = tcg_temp_new(); \
1475 tcg_gen_subi_i32(addr, REG(B11_8), 4); \
1476 tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1477 tcg_gen_mov_i32(REG(B11_8), addr); \
1478 tcg_temp_free(addr); \
1481 #define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk) \
1482 LD(reg,ldnum,ldpnum,prechk) \
1483 ST(reg,stnum,stpnum,prechk)
1484 LDST(gbr
, 0x401e, 0x4017, 0x0012, 0x4013, {})
1485 LDST(vbr
, 0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED
)
1486 LDST(ssr
, 0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED
)
1487 LDST(spc
, 0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED
)
1488 ST(sgr
, 0x003a, 0x4032, CHECK_PRIVILEGED
)
1489 LD(sgr
, 0x403a, 0x4036, CHECK_PRIVILEGED CHECK_SH4A
)
1490 LDST(dbr
, 0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED
)
1491 LDST(mach
, 0x400a, 0x4006, 0x000a, 0x4002, {})
1492 LDST(macl
, 0x401a, 0x4016, 0x001a, 0x4012, {})
1493 LDST(pr
, 0x402a, 0x4026, 0x002a, 0x4022, {})
1494 LDST(fpul
, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED
})
1495 case 0x406a: /* lds Rm,FPSCR */
1497 gen_helper_ld_fpscr(cpu_env
, REG(B11_8
));
1498 ctx
->base
.is_jmp
= DISAS_STOP
;
1500 case 0x4066: /* lds.l @Rm+,FPSCR */
1503 TCGv addr
= tcg_temp_new();
1504 tcg_gen_qemu_ld_i32(addr
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
1505 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1506 gen_helper_ld_fpscr(cpu_env
, addr
);
1507 tcg_temp_free(addr
);
1508 ctx
->base
.is_jmp
= DISAS_STOP
;
1511 case 0x006a: /* sts FPSCR,Rn */
1513 tcg_gen_andi_i32(REG(B11_8
), cpu_fpscr
, 0x003fffff);
1515 case 0x4062: /* sts FPSCR,@-Rn */
1519 val
= tcg_temp_new();
1520 tcg_gen_andi_i32(val
, cpu_fpscr
, 0x003fffff);
1521 addr
= tcg_temp_new();
1522 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1523 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_TEUL
);
1524 tcg_gen_mov_i32(REG(B11_8
), addr
);
1525 tcg_temp_free(addr
);
1529 case 0x00c3: /* movca.l R0,@Rm */
1531 TCGv val
= tcg_temp_new();
1532 tcg_gen_qemu_ld_i32(val
, REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1533 gen_helper_movcal(cpu_env
, REG(B11_8
), val
);
1534 tcg_gen_qemu_st_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1537 ctx
->has_movcal
= 1;
1539 case 0x40a9: /* movua.l @Rm,R0 */
1541 /* Load non-boundary-aligned data */
1542 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
,
1543 MO_TEUL
| MO_UNALN
);
1545 case 0x40e9: /* movua.l @Rm+,R0 */
1547 /* Load non-boundary-aligned data */
1548 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
,
1549 MO_TEUL
| MO_UNALN
);
1550 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1552 case 0x0029: /* movt Rn */
1553 tcg_gen_mov_i32(REG(B11_8
), cpu_sr_t
);
1558 * If (T == 1) R0 -> (Rn)
1561 * The above description doesn't work in a parallel context.
1562 * Since we currently support no smp boards, this implies user-mode.
1563 * But we can still support the official mechanism while user-mode
1564 * is single-threaded. */
1567 TCGLabel
*fail
= gen_new_label();
1568 TCGLabel
*done
= gen_new_label();
1570 if ((tb_cflags(ctx
->base
.tb
) & CF_PARALLEL
)) {
1573 tcg_gen_brcond_i32(TCG_COND_NE
, REG(B11_8
),
1574 cpu_lock_addr
, fail
);
1575 tmp
= tcg_temp_new();
1576 tcg_gen_atomic_cmpxchg_i32(tmp
, REG(B11_8
), cpu_lock_value
,
1577 REG(0), ctx
->memidx
, MO_TEUL
);
1578 tcg_gen_setcond_i32(TCG_COND_EQ
, cpu_sr_t
, tmp
, cpu_lock_value
);
1581 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_lock_addr
, -1, fail
);
1582 tcg_gen_qemu_st_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1583 tcg_gen_movi_i32(cpu_sr_t
, 1);
1587 gen_set_label(fail
);
1588 tcg_gen_movi_i32(cpu_sr_t
, 0);
1590 gen_set_label(done
);
1591 tcg_gen_movi_i32(cpu_lock_addr
, -1);
1598 * When interrupt/exception
1599 * occurred 0 -> LDST
1601 * In a parallel context, we must also save the loaded value
1602 * for use with the cmpxchg that we'll use with movco.l. */
1604 if ((tb_cflags(ctx
->base
.tb
) & CF_PARALLEL
)) {
1605 TCGv tmp
= tcg_temp_new();
1606 tcg_gen_mov_i32(tmp
, REG(B11_8
));
1607 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TESL
);
1608 tcg_gen_mov_i32(cpu_lock_value
, REG(0));
1609 tcg_gen_mov_i32(cpu_lock_addr
, tmp
);
1612 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TESL
);
1613 tcg_gen_movi_i32(cpu_lock_addr
, 0);
1616 case 0x0093: /* ocbi @Rn */
1618 gen_helper_ocbi(cpu_env
, REG(B11_8
));
1621 case 0x00a3: /* ocbp @Rn */
1622 case 0x00b3: /* ocbwb @Rn */
1623 /* These instructions are supposed to do nothing in case of
1624 a cache miss. Given that we only partially emulate caches
1625 it is safe to simply ignore them. */
1627 case 0x0083: /* pref @Rn */
1629 case 0x00d3: /* prefi @Rn */
1632 case 0x00e3: /* icbi @Rn */
1635 case 0x00ab: /* synco */
1637 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
1639 case 0x4024: /* rotcl Rn */
1641 TCGv tmp
= tcg_temp_new();
1642 tcg_gen_mov_i32(tmp
, cpu_sr_t
);
1643 tcg_gen_shri_i32(cpu_sr_t
, REG(B11_8
), 31);
1644 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1645 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), tmp
);
1649 case 0x4025: /* rotcr Rn */
1651 TCGv tmp
= tcg_temp_new();
1652 tcg_gen_shli_i32(tmp
, cpu_sr_t
, 31);
1653 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1654 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1655 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), tmp
);
1659 case 0x4004: /* rotl Rn */
1660 tcg_gen_rotli_i32(REG(B11_8
), REG(B11_8
), 1);
1661 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 0);
1663 case 0x4005: /* rotr Rn */
1664 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 0);
1665 tcg_gen_rotri_i32(REG(B11_8
), REG(B11_8
), 1);
1667 case 0x4000: /* shll Rn */
1668 case 0x4020: /* shal Rn */
1669 tcg_gen_shri_i32(cpu_sr_t
, REG(B11_8
), 31);
1670 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1672 case 0x4021: /* shar Rn */
1673 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1674 tcg_gen_sari_i32(REG(B11_8
), REG(B11_8
), 1);
1676 case 0x4001: /* shlr Rn */
1677 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1678 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1680 case 0x4008: /* shll2 Rn */
1681 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 2);
1683 case 0x4018: /* shll8 Rn */
1684 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 8);
1686 case 0x4028: /* shll16 Rn */
1687 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 16);
1689 case 0x4009: /* shlr2 Rn */
1690 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 2);
1692 case 0x4019: /* shlr8 Rn */
1693 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 8);
1695 case 0x4029: /* shlr16 Rn */
1696 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 16);
1698 case 0x401b: /* tas.b @Rn */
1700 TCGv val
= tcg_const_i32(0x80);
1701 tcg_gen_atomic_fetch_or_i32(val
, REG(B11_8
), val
,
1702 ctx
->memidx
, MO_UB
);
1703 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
1707 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1709 tcg_gen_mov_i32(FREG(B11_8
), cpu_fpul
);
1711 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1713 tcg_gen_mov_i32(cpu_fpul
, FREG(B11_8
));
1715 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1717 if (ctx
->tbflags
& FPSCR_PR
) {
1719 if (ctx
->opcode
& 0x0100) {
1722 fp
= tcg_temp_new_i64();
1723 gen_helper_float_DT(fp
, cpu_env
, cpu_fpul
);
1724 gen_store_fpr64(ctx
, fp
, B11_8
);
1725 tcg_temp_free_i64(fp
);
1728 gen_helper_float_FT(FREG(B11_8
), cpu_env
, cpu_fpul
);
1731 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1733 if (ctx
->tbflags
& FPSCR_PR
) {
1735 if (ctx
->opcode
& 0x0100) {
1738 fp
= tcg_temp_new_i64();
1739 gen_load_fpr64(ctx
, fp
, B11_8
);
1740 gen_helper_ftrc_DT(cpu_fpul
, cpu_env
, fp
);
1741 tcg_temp_free_i64(fp
);
1744 gen_helper_ftrc_FT(cpu_fpul
, cpu_env
, FREG(B11_8
));
1747 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1749 tcg_gen_xori_i32(FREG(B11_8
), FREG(B11_8
), 0x80000000);
1751 case 0xf05d: /* fabs FRn/DRn - FPCSR: Nothing */
1753 tcg_gen_andi_i32(FREG(B11_8
), FREG(B11_8
), 0x7fffffff);
1755 case 0xf06d: /* fsqrt FRn */
1757 if (ctx
->tbflags
& FPSCR_PR
) {
1758 if (ctx
->opcode
& 0x0100) {
1761 TCGv_i64 fp
= tcg_temp_new_i64();
1762 gen_load_fpr64(ctx
, fp
, B11_8
);
1763 gen_helper_fsqrt_DT(fp
, cpu_env
, fp
);
1764 gen_store_fpr64(ctx
, fp
, B11_8
);
1765 tcg_temp_free_i64(fp
);
1767 gen_helper_fsqrt_FT(FREG(B11_8
), cpu_env
, FREG(B11_8
));
1770 case 0xf07d: /* fsrra FRn */
1773 gen_helper_fsrra_FT(FREG(B11_8
), cpu_env
, FREG(B11_8
));
1775 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1778 tcg_gen_movi_i32(FREG(B11_8
), 0);
1780 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1783 tcg_gen_movi_i32(FREG(B11_8
), 0x3f800000);
1785 case 0xf0ad: /* fcnvsd FPUL,DRn */
1788 TCGv_i64 fp
= tcg_temp_new_i64();
1789 gen_helper_fcnvsd_FT_DT(fp
, cpu_env
, cpu_fpul
);
1790 gen_store_fpr64(ctx
, fp
, B11_8
);
1791 tcg_temp_free_i64(fp
);
1794 case 0xf0bd: /* fcnvds DRn,FPUL */
1797 TCGv_i64 fp
= tcg_temp_new_i64();
1798 gen_load_fpr64(ctx
, fp
, B11_8
);
1799 gen_helper_fcnvds_DT_FT(cpu_fpul
, cpu_env
, fp
);
1800 tcg_temp_free_i64(fp
);
1803 case 0xf0ed: /* fipr FVm,FVn */
1807 TCGv m
= tcg_const_i32((ctx
->opcode
>> 8) & 3);
1808 TCGv n
= tcg_const_i32((ctx
->opcode
>> 10) & 3);
1809 gen_helper_fipr(cpu_env
, m
, n
);
1815 case 0xf0fd: /* ftrv XMTRX,FVn */
1819 if ((ctx
->opcode
& 0x0300) != 0x0100) {
1822 TCGv n
= tcg_const_i32((ctx
->opcode
>> 10) & 3);
1823 gen_helper_ftrv(cpu_env
, n
);
1830 fprintf(stderr
, "unknown instruction 0x%04x at pc 0x%08x\n",
1831 ctx
->opcode
, ctx
->base
.pc_next
);
1835 if (ctx
->envflags
& DELAY_SLOT_MASK
) {
1837 gen_save_cpu_state(ctx
, true);
1838 gen_helper_raise_slot_illegal_instruction(cpu_env
);
1840 gen_save_cpu_state(ctx
, true);
1841 gen_helper_raise_illegal_instruction(cpu_env
);
1843 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1847 gen_save_cpu_state(ctx
, true);
1848 if (ctx
->envflags
& DELAY_SLOT_MASK
) {
1849 gen_helper_raise_slot_fpu_disable(cpu_env
);
1851 gen_helper_raise_fpu_disable(cpu_env
);
1853 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1857 static void decode_opc(DisasContext
* ctx
)
1859 uint32_t old_flags
= ctx
->envflags
;
1863 if (old_flags
& DELAY_SLOT_MASK
) {
1864 /* go out of the delay slot */
1865 ctx
->envflags
&= ~DELAY_SLOT_MASK
;
1867 /* When in an exclusive region, we must continue to the end
1868 for conditional branches. */
1869 if (ctx
->tbflags
& GUSA_EXCLUSIVE
1870 && old_flags
& DELAY_SLOT_CONDITIONAL
) {
1871 gen_delayed_conditional_jump(ctx
);
1874 /* Otherwise this is probably an invalid gUSA region.
1875 Drop the GUSA bits so the next TB doesn't see them. */
1876 ctx
->envflags
&= ~GUSA_MASK
;
1878 tcg_gen_movi_i32(cpu_flags
, ctx
->envflags
);
1879 if (old_flags
& DELAY_SLOT_CONDITIONAL
) {
1880 gen_delayed_conditional_jump(ctx
);
1887 #ifdef CONFIG_USER_ONLY
1888 /* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
1889 Upon an interrupt, a real kernel would simply notice magic values in
1890 the registers and reset the PC to the start of the sequence.
1892 For QEMU, we cannot do this in quite the same way. Instead, we notice
1893 the normal start of such a sequence (mov #-x,r15). While we can handle
1894 any sequence via cpu_exec_step_atomic, we can recognize the "normal"
1895 sequences and transform them into atomic operations as seen by the host.
1897 static void decode_gusa(DisasContext
*ctx
, CPUSH4State
*env
)
1900 int ld_adr
, ld_dst
, ld_mop
;
1901 int op_dst
, op_src
, op_opc
;
1902 int mv_src
, mt_dst
, st_src
, st_mop
;
1904 uint32_t pc
= ctx
->base
.pc_next
;
1905 uint32_t pc_end
= ctx
->base
.tb
->cs_base
;
1906 int max_insns
= (pc_end
- pc
) / 2;
1909 /* The state machine below will consume only a few insns.
1910 If there are more than that in a region, fail now. */
1911 if (max_insns
> ARRAY_SIZE(insns
)) {
1915 /* Read all of the insns for the region. */
1916 for (i
= 0; i
< max_insns
; ++i
) {
1917 insns
[i
] = translator_lduw(env
, pc
+ i
* 2);
1920 ld_adr
= ld_dst
= ld_mop
= -1;
1922 op_dst
= op_src
= op_opc
= -1;
1924 st_src
= st_mop
= -1;
1929 do { if (i >= max_insns) goto fail; ctx->opcode = insns[i++]; } while (0)
1932 * Expect a load to begin the region.
1935 switch (ctx
->opcode
& 0xf00f) {
1936 case 0x6000: /* mov.b @Rm,Rn */
1939 case 0x6001: /* mov.w @Rm,Rn */
1942 case 0x6002: /* mov.l @Rm,Rn */
1950 if (ld_adr
== ld_dst
) {
1953 /* Unless we see a mov, any two-operand operation must use ld_dst. */
1957 * Expect an optional register move.
1960 switch (ctx
->opcode
& 0xf00f) {
1961 case 0x6003: /* mov Rm,Rn */
1962 /* Here we want to recognize ld_dst being saved for later consumtion,
1963 or for another input register being copied so that ld_dst need not
1964 be clobbered during the operation. */
1967 if (op_dst
== ld_dst
) {
1968 /* Overwriting the load output. */
1971 if (mv_src
!= ld_dst
) {
1972 /* Copying a new input; constrain op_src to match the load. */
1978 /* Put back and re-examine as operation. */
1983 * Expect the operation.
1986 switch (ctx
->opcode
& 0xf00f) {
1987 case 0x300c: /* add Rm,Rn */
1988 op_opc
= INDEX_op_add_i32
;
1990 case 0x2009: /* and Rm,Rn */
1991 op_opc
= INDEX_op_and_i32
;
1993 case 0x200a: /* xor Rm,Rn */
1994 op_opc
= INDEX_op_xor_i32
;
1996 case 0x200b: /* or Rm,Rn */
1997 op_opc
= INDEX_op_or_i32
;
1999 /* The operation register should be as expected, and the
2000 other input cannot depend on the load. */
2001 if (op_dst
!= B11_8
) {
2005 /* Unconstrainted input. */
2007 } else if (op_src
== B7_4
) {
2008 /* Constrained input matched load. All operations are
2009 commutative; "swap" them by "moving" the load output
2010 to the (implicit) first argument and the move source
2011 to the (explicit) second argument. */
2016 op_arg
= REG(op_src
);
2019 case 0x6007: /* not Rm,Rn */
2020 if (ld_dst
!= B7_4
|| mv_src
>= 0) {
2024 op_opc
= INDEX_op_xor_i32
;
2025 op_arg
= tcg_const_i32(-1);
2028 case 0x7000 ... 0x700f: /* add #imm,Rn */
2029 if (op_dst
!= B11_8
|| mv_src
>= 0) {
2032 op_opc
= INDEX_op_add_i32
;
2033 op_arg
= tcg_const_i32(B7_0s
);
2036 case 0x3000: /* cmp/eq Rm,Rn */
2037 /* Looking for the middle of a compare-and-swap sequence,
2038 beginning with the compare. Operands can be either order,
2039 but with only one overlapping the load. */
2040 if ((ld_dst
== B11_8
) + (ld_dst
== B7_4
) != 1 || mv_src
>= 0) {
2043 op_opc
= INDEX_op_setcond_i32
; /* placeholder */
2044 op_src
= (ld_dst
== B11_8
? B7_4
: B11_8
);
2045 op_arg
= REG(op_src
);
2048 switch (ctx
->opcode
& 0xff00) {
2049 case 0x8b00: /* bf label */
2050 case 0x8f00: /* bf/s label */
2051 if (pc
+ (i
+ 1 + B7_0s
) * 2 != pc_end
) {
2054 if ((ctx
->opcode
& 0xff00) == 0x8b00) { /* bf label */
2057 /* We're looking to unconditionally modify Rn with the
2058 result of the comparison, within the delay slot of
2059 the branch. This is used by older gcc. */
2061 if ((ctx
->opcode
& 0xf0ff) == 0x0029) { /* movt Rn */
2073 case 0x2008: /* tst Rm,Rn */
2074 /* Looking for a compare-and-swap against zero. */
2075 if (ld_dst
!= B11_8
|| ld_dst
!= B7_4
|| mv_src
>= 0) {
2078 op_opc
= INDEX_op_setcond_i32
;
2079 op_arg
= tcg_const_i32(0);
2082 if ((ctx
->opcode
& 0xff00) != 0x8900 /* bt label */
2083 || pc
+ (i
+ 1 + B7_0s
) * 2 != pc_end
) {
2089 /* Put back and re-examine as store. */
2096 /* The store must be the last insn. */
2097 if (i
!= max_insns
- 1) {
2101 switch (ctx
->opcode
& 0xf00f) {
2102 case 0x2000: /* mov.b Rm,@Rn */
2105 case 0x2001: /* mov.w Rm,@Rn */
2108 case 0x2002: /* mov.l Rm,@Rn */
2114 /* The store must match the load. */
2115 if (ld_adr
!= B11_8
|| st_mop
!= (ld_mop
& MO_SIZE
)) {
2123 * Emit the operation.
2127 /* No operation found. Look for exchange pattern. */
2128 if (st_src
== ld_dst
|| mv_src
>= 0) {
2131 tcg_gen_atomic_xchg_i32(REG(ld_dst
), REG(ld_adr
), REG(st_src
),
2132 ctx
->memidx
, ld_mop
);
2135 case INDEX_op_add_i32
:
2136 if (op_dst
!= st_src
) {
2139 if (op_dst
== ld_dst
&& st_mop
== MO_UL
) {
2140 tcg_gen_atomic_add_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2141 op_arg
, ctx
->memidx
, ld_mop
);
2143 tcg_gen_atomic_fetch_add_i32(REG(ld_dst
), REG(ld_adr
),
2144 op_arg
, ctx
->memidx
, ld_mop
);
2145 if (op_dst
!= ld_dst
) {
2146 /* Note that mop sizes < 4 cannot use add_fetch
2147 because it won't carry into the higher bits. */
2148 tcg_gen_add_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2153 case INDEX_op_and_i32
:
2154 if (op_dst
!= st_src
) {
2157 if (op_dst
== ld_dst
) {
2158 tcg_gen_atomic_and_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2159 op_arg
, ctx
->memidx
, ld_mop
);
2161 tcg_gen_atomic_fetch_and_i32(REG(ld_dst
), REG(ld_adr
),
2162 op_arg
, ctx
->memidx
, ld_mop
);
2163 tcg_gen_and_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2167 case INDEX_op_or_i32
:
2168 if (op_dst
!= st_src
) {
2171 if (op_dst
== ld_dst
) {
2172 tcg_gen_atomic_or_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2173 op_arg
, ctx
->memidx
, ld_mop
);
2175 tcg_gen_atomic_fetch_or_i32(REG(ld_dst
), REG(ld_adr
),
2176 op_arg
, ctx
->memidx
, ld_mop
);
2177 tcg_gen_or_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2181 case INDEX_op_xor_i32
:
2182 if (op_dst
!= st_src
) {
2185 if (op_dst
== ld_dst
) {
2186 tcg_gen_atomic_xor_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2187 op_arg
, ctx
->memidx
, ld_mop
);
2189 tcg_gen_atomic_fetch_xor_i32(REG(ld_dst
), REG(ld_adr
),
2190 op_arg
, ctx
->memidx
, ld_mop
);
2191 tcg_gen_xor_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2195 case INDEX_op_setcond_i32
:
2196 if (st_src
== ld_dst
) {
2199 tcg_gen_atomic_cmpxchg_i32(REG(ld_dst
), REG(ld_adr
), op_arg
,
2200 REG(st_src
), ctx
->memidx
, ld_mop
);
2201 tcg_gen_setcond_i32(TCG_COND_EQ
, cpu_sr_t
, REG(ld_dst
), op_arg
);
2203 tcg_gen_mov_i32(REG(mt_dst
), cpu_sr_t
);
2208 g_assert_not_reached();
2211 /* If op_src is not a valid register, then op_arg was a constant. */
2212 if (op_src
< 0 && op_arg
) {
2213 tcg_temp_free_i32(op_arg
);
2216 /* The entire region has been translated. */
2217 ctx
->envflags
&= ~GUSA_MASK
;
2218 ctx
->base
.pc_next
= pc_end
;
2219 ctx
->base
.num_insns
+= max_insns
- 1;
2223 qemu_log_mask(LOG_UNIMP
, "Unrecognized gUSA sequence %08x-%08x\n",
2226 /* Restart with the EXCLUSIVE bit set, within a TB run via
2227 cpu_exec_step_atomic holding the exclusive lock. */
2228 ctx
->envflags
|= GUSA_EXCLUSIVE
;
2229 gen_save_cpu_state(ctx
, false);
2230 gen_helper_exclusive(cpu_env
);
2231 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2233 /* We're not executing an instruction, but we must report one for the
2234 purposes of accounting within the TB. We might as well report the
2235 entire region consumed via ctx->base.pc_next so that it's immediately
2236 available in the disassembly dump. */
2237 ctx
->base
.pc_next
= pc_end
;
2238 ctx
->base
.num_insns
+= max_insns
- 1;
2242 static void sh4_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2244 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2245 CPUSH4State
*env
= cs
->env_ptr
;
2249 ctx
->tbflags
= tbflags
= ctx
->base
.tb
->flags
;
2250 ctx
->envflags
= tbflags
& TB_FLAG_ENVFLAGS_MASK
;
2251 ctx
->memidx
= (tbflags
& (1u << SR_MD
)) == 0 ? 1 : 0;
2252 /* We don't know if the delayed pc came from a dynamic or static branch,
2253 so assume it is a dynamic branch. */
2254 ctx
->delayed_pc
= -1; /* use delayed pc from env pointer */
2255 ctx
->features
= env
->features
;
2256 ctx
->has_movcal
= (tbflags
& TB_FLAG_PENDING_MOVCA
);
2257 ctx
->gbank
= ((tbflags
& (1 << SR_MD
)) &&
2258 (tbflags
& (1 << SR_RB
))) * 0x10;
2259 ctx
->fbank
= tbflags
& FPSCR_FR
? 0x10 : 0;
2261 if (tbflags
& GUSA_MASK
) {
2262 uint32_t pc
= ctx
->base
.pc_next
;
2263 uint32_t pc_end
= ctx
->base
.tb
->cs_base
;
2264 int backup
= sextract32(ctx
->tbflags
, GUSA_SHIFT
, 8);
2265 int max_insns
= (pc_end
- pc
) / 2;
2267 if (pc
!= pc_end
+ backup
|| max_insns
< 2) {
2268 /* This is a malformed gUSA region. Don't do anything special,
2269 since the interpreter is likely to get confused. */
2270 ctx
->envflags
&= ~GUSA_MASK
;
2271 } else if (tbflags
& GUSA_EXCLUSIVE
) {
2272 /* Regardless of single-stepping or the end of the page,
2273 we must complete execution of the gUSA region while
2274 holding the exclusive lock. */
2275 ctx
->base
.max_insns
= max_insns
;
2280 /* Since the ISA is fixed-width, we can bound by the number
2281 of instructions remaining on the page. */
2282 bound
= -(ctx
->base
.pc_next
| TARGET_PAGE_MASK
) / 2;
2283 ctx
->base
.max_insns
= MIN(ctx
->base
.max_insns
, bound
);
2286 static void sh4_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2290 static void sh4_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2292 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2294 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->envflags
);
2297 static bool sh4_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
2298 const CPUBreakpoint
*bp
)
2300 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2302 /* We have hit a breakpoint - make sure PC is up-to-date */
2303 gen_save_cpu_state(ctx
, true);
2304 gen_helper_debug(cpu_env
);
2305 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2306 /* The address covered by the breakpoint must be included in
2307 [tb->pc, tb->pc + tb->size) in order to for it to be
2308 properly cleared -- thus we increment the PC here so that
2309 the logic setting tb->size below does the right thing. */
2310 ctx
->base
.pc_next
+= 2;
2314 static void sh4_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
2316 CPUSH4State
*env
= cs
->env_ptr
;
2317 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2319 #ifdef CONFIG_USER_ONLY
2320 if (unlikely(ctx
->envflags
& GUSA_MASK
)
2321 && !(ctx
->envflags
& GUSA_EXCLUSIVE
)) {
2322 /* We're in an gUSA region, and we have not already fallen
2323 back on using an exclusive region. Attempt to parse the
2324 region into a single supported atomic operation. Failure
2325 is handled within the parser by raising an exception to
2326 retry using an exclusive region. */
2327 decode_gusa(ctx
, env
);
2332 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
2334 ctx
->base
.pc_next
+= 2;
2337 static void sh4_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
2339 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2341 if (ctx
->tbflags
& GUSA_EXCLUSIVE
) {
2342 /* Ending the region of exclusivity. Clear the bits. */
2343 ctx
->envflags
&= ~GUSA_MASK
;
2346 switch (ctx
->base
.is_jmp
) {
2348 gen_save_cpu_state(ctx
, true);
2349 if (ctx
->base
.singlestep_enabled
) {
2350 gen_helper_debug(cpu_env
);
2352 tcg_gen_exit_tb(NULL
, 0);
2356 case DISAS_TOO_MANY
:
2357 gen_save_cpu_state(ctx
, false);
2358 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
2360 case DISAS_NORETURN
:
2363 g_assert_not_reached();
2367 static void sh4_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
2369 qemu_log("IN:\n"); /* , lookup_symbol(dcbase->pc_first)); */
2370 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
2373 static const TranslatorOps sh4_tr_ops
= {
2374 .init_disas_context
= sh4_tr_init_disas_context
,
2375 .tb_start
= sh4_tr_tb_start
,
2376 .insn_start
= sh4_tr_insn_start
,
2377 .breakpoint_check
= sh4_tr_breakpoint_check
,
2378 .translate_insn
= sh4_tr_translate_insn
,
2379 .tb_stop
= sh4_tr_tb_stop
,
2380 .disas_log
= sh4_tr_disas_log
,
2383 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
2387 translator_loop(&sh4_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
2390 void restore_state_to_opc(CPUSH4State
*env
, TranslationBlock
*tb
,
2394 env
->flags
= data
[1];
2395 /* Theoretically delayed_pc should also be restored. In practice the
2396 branch instruction is re-executed after exception, so the delayed
2397 branch target will be recomputed. */