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
);
1546 case 0x40e9: /* movua.l @Rm+,R0 */
1548 /* Load non-boundary-aligned data */
1549 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
,
1550 MO_TEUL
| MO_UNALN
);
1551 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1554 case 0x0029: /* movt Rn */
1555 tcg_gen_mov_i32(REG(B11_8
), cpu_sr_t
);
1560 * If (T == 1) R0 -> (Rn)
1563 * The above description doesn't work in a parallel context.
1564 * Since we currently support no smp boards, this implies user-mode.
1565 * But we can still support the official mechanism while user-mode
1566 * is single-threaded. */
1569 TCGLabel
*fail
= gen_new_label();
1570 TCGLabel
*done
= gen_new_label();
1572 if ((tb_cflags(ctx
->base
.tb
) & CF_PARALLEL
)) {
1575 tcg_gen_brcond_i32(TCG_COND_NE
, REG(B11_8
),
1576 cpu_lock_addr
, fail
);
1577 tmp
= tcg_temp_new();
1578 tcg_gen_atomic_cmpxchg_i32(tmp
, REG(B11_8
), cpu_lock_value
,
1579 REG(0), ctx
->memidx
, MO_TEUL
);
1580 tcg_gen_setcond_i32(TCG_COND_EQ
, cpu_sr_t
, tmp
, cpu_lock_value
);
1583 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_lock_addr
, -1, fail
);
1584 tcg_gen_qemu_st_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1585 tcg_gen_movi_i32(cpu_sr_t
, 1);
1589 gen_set_label(fail
);
1590 tcg_gen_movi_i32(cpu_sr_t
, 0);
1592 gen_set_label(done
);
1593 tcg_gen_movi_i32(cpu_lock_addr
, -1);
1600 * When interrupt/exception
1601 * occurred 0 -> LDST
1603 * In a parallel context, we must also save the loaded value
1604 * for use with the cmpxchg that we'll use with movco.l. */
1606 if ((tb_cflags(ctx
->base
.tb
) & CF_PARALLEL
)) {
1607 TCGv tmp
= tcg_temp_new();
1608 tcg_gen_mov_i32(tmp
, REG(B11_8
));
1609 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TESL
);
1610 tcg_gen_mov_i32(cpu_lock_value
, REG(0));
1611 tcg_gen_mov_i32(cpu_lock_addr
, tmp
);
1614 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TESL
);
1615 tcg_gen_movi_i32(cpu_lock_addr
, 0);
1618 case 0x0093: /* ocbi @Rn */
1620 gen_helper_ocbi(cpu_env
, REG(B11_8
));
1623 case 0x00a3: /* ocbp @Rn */
1624 case 0x00b3: /* ocbwb @Rn */
1625 /* These instructions are supposed to do nothing in case of
1626 a cache miss. Given that we only partially emulate caches
1627 it is safe to simply ignore them. */
1629 case 0x0083: /* pref @Rn */
1631 case 0x00d3: /* prefi @Rn */
1634 case 0x00e3: /* icbi @Rn */
1637 case 0x00ab: /* synco */
1639 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
1642 case 0x4024: /* rotcl Rn */
1644 TCGv tmp
= tcg_temp_new();
1645 tcg_gen_mov_i32(tmp
, cpu_sr_t
);
1646 tcg_gen_shri_i32(cpu_sr_t
, REG(B11_8
), 31);
1647 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1648 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), tmp
);
1652 case 0x4025: /* rotcr Rn */
1654 TCGv tmp
= tcg_temp_new();
1655 tcg_gen_shli_i32(tmp
, cpu_sr_t
, 31);
1656 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1657 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1658 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), tmp
);
1662 case 0x4004: /* rotl Rn */
1663 tcg_gen_rotli_i32(REG(B11_8
), REG(B11_8
), 1);
1664 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 0);
1666 case 0x4005: /* rotr Rn */
1667 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 0);
1668 tcg_gen_rotri_i32(REG(B11_8
), REG(B11_8
), 1);
1670 case 0x4000: /* shll Rn */
1671 case 0x4020: /* shal Rn */
1672 tcg_gen_shri_i32(cpu_sr_t
, REG(B11_8
), 31);
1673 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1675 case 0x4021: /* shar Rn */
1676 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1677 tcg_gen_sari_i32(REG(B11_8
), REG(B11_8
), 1);
1679 case 0x4001: /* shlr Rn */
1680 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1681 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1683 case 0x4008: /* shll2 Rn */
1684 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 2);
1686 case 0x4018: /* shll8 Rn */
1687 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 8);
1689 case 0x4028: /* shll16 Rn */
1690 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 16);
1692 case 0x4009: /* shlr2 Rn */
1693 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 2);
1695 case 0x4019: /* shlr8 Rn */
1696 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 8);
1698 case 0x4029: /* shlr16 Rn */
1699 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 16);
1701 case 0x401b: /* tas.b @Rn */
1703 TCGv val
= tcg_const_i32(0x80);
1704 tcg_gen_atomic_fetch_or_i32(val
, REG(B11_8
), val
,
1705 ctx
->memidx
, MO_UB
);
1706 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
1710 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1712 tcg_gen_mov_i32(FREG(B11_8
), cpu_fpul
);
1714 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1716 tcg_gen_mov_i32(cpu_fpul
, FREG(B11_8
));
1718 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1720 if (ctx
->tbflags
& FPSCR_PR
) {
1722 if (ctx
->opcode
& 0x0100) {
1725 fp
= tcg_temp_new_i64();
1726 gen_helper_float_DT(fp
, cpu_env
, cpu_fpul
);
1727 gen_store_fpr64(ctx
, fp
, B11_8
);
1728 tcg_temp_free_i64(fp
);
1731 gen_helper_float_FT(FREG(B11_8
), cpu_env
, cpu_fpul
);
1734 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1736 if (ctx
->tbflags
& FPSCR_PR
) {
1738 if (ctx
->opcode
& 0x0100) {
1741 fp
= tcg_temp_new_i64();
1742 gen_load_fpr64(ctx
, fp
, B11_8
);
1743 gen_helper_ftrc_DT(cpu_fpul
, cpu_env
, fp
);
1744 tcg_temp_free_i64(fp
);
1747 gen_helper_ftrc_FT(cpu_fpul
, cpu_env
, FREG(B11_8
));
1750 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1752 tcg_gen_xori_i32(FREG(B11_8
), FREG(B11_8
), 0x80000000);
1754 case 0xf05d: /* fabs FRn/DRn - FPCSR: Nothing */
1756 tcg_gen_andi_i32(FREG(B11_8
), FREG(B11_8
), 0x7fffffff);
1758 case 0xf06d: /* fsqrt FRn */
1760 if (ctx
->tbflags
& FPSCR_PR
) {
1761 if (ctx
->opcode
& 0x0100) {
1764 TCGv_i64 fp
= tcg_temp_new_i64();
1765 gen_load_fpr64(ctx
, fp
, B11_8
);
1766 gen_helper_fsqrt_DT(fp
, cpu_env
, fp
);
1767 gen_store_fpr64(ctx
, fp
, B11_8
);
1768 tcg_temp_free_i64(fp
);
1770 gen_helper_fsqrt_FT(FREG(B11_8
), cpu_env
, FREG(B11_8
));
1773 case 0xf07d: /* fsrra FRn */
1776 gen_helper_fsrra_FT(FREG(B11_8
), cpu_env
, FREG(B11_8
));
1778 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1781 tcg_gen_movi_i32(FREG(B11_8
), 0);
1783 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1786 tcg_gen_movi_i32(FREG(B11_8
), 0x3f800000);
1788 case 0xf0ad: /* fcnvsd FPUL,DRn */
1791 TCGv_i64 fp
= tcg_temp_new_i64();
1792 gen_helper_fcnvsd_FT_DT(fp
, cpu_env
, cpu_fpul
);
1793 gen_store_fpr64(ctx
, fp
, B11_8
);
1794 tcg_temp_free_i64(fp
);
1797 case 0xf0bd: /* fcnvds DRn,FPUL */
1800 TCGv_i64 fp
= tcg_temp_new_i64();
1801 gen_load_fpr64(ctx
, fp
, B11_8
);
1802 gen_helper_fcnvds_DT_FT(cpu_fpul
, cpu_env
, fp
);
1803 tcg_temp_free_i64(fp
);
1806 case 0xf0ed: /* fipr FVm,FVn */
1810 TCGv m
= tcg_const_i32((ctx
->opcode
>> 8) & 3);
1811 TCGv n
= tcg_const_i32((ctx
->opcode
>> 10) & 3);
1812 gen_helper_fipr(cpu_env
, m
, n
);
1818 case 0xf0fd: /* ftrv XMTRX,FVn */
1822 if ((ctx
->opcode
& 0x0300) != 0x0100) {
1825 TCGv n
= tcg_const_i32((ctx
->opcode
>> 10) & 3);
1826 gen_helper_ftrv(cpu_env
, n
);
1833 fprintf(stderr
, "unknown instruction 0x%04x at pc 0x%08x\n",
1834 ctx
->opcode
, ctx
->base
.pc_next
);
1838 if (ctx
->envflags
& DELAY_SLOT_MASK
) {
1840 gen_save_cpu_state(ctx
, true);
1841 gen_helper_raise_slot_illegal_instruction(cpu_env
);
1843 gen_save_cpu_state(ctx
, true);
1844 gen_helper_raise_illegal_instruction(cpu_env
);
1846 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1850 gen_save_cpu_state(ctx
, true);
1851 if (ctx
->envflags
& DELAY_SLOT_MASK
) {
1852 gen_helper_raise_slot_fpu_disable(cpu_env
);
1854 gen_helper_raise_fpu_disable(cpu_env
);
1856 ctx
->base
.is_jmp
= DISAS_NORETURN
;
1860 static void decode_opc(DisasContext
* ctx
)
1862 uint32_t old_flags
= ctx
->envflags
;
1866 if (old_flags
& DELAY_SLOT_MASK
) {
1867 /* go out of the delay slot */
1868 ctx
->envflags
&= ~DELAY_SLOT_MASK
;
1870 /* When in an exclusive region, we must continue to the end
1871 for conditional branches. */
1872 if (ctx
->tbflags
& GUSA_EXCLUSIVE
1873 && old_flags
& DELAY_SLOT_CONDITIONAL
) {
1874 gen_delayed_conditional_jump(ctx
);
1877 /* Otherwise this is probably an invalid gUSA region.
1878 Drop the GUSA bits so the next TB doesn't see them. */
1879 ctx
->envflags
&= ~GUSA_MASK
;
1881 tcg_gen_movi_i32(cpu_flags
, ctx
->envflags
);
1882 if (old_flags
& DELAY_SLOT_CONDITIONAL
) {
1883 gen_delayed_conditional_jump(ctx
);
1890 #ifdef CONFIG_USER_ONLY
1891 /* For uniprocessors, SH4 uses optimistic restartable atomic sequences.
1892 Upon an interrupt, a real kernel would simply notice magic values in
1893 the registers and reset the PC to the start of the sequence.
1895 For QEMU, we cannot do this in quite the same way. Instead, we notice
1896 the normal start of such a sequence (mov #-x,r15). While we can handle
1897 any sequence via cpu_exec_step_atomic, we can recognize the "normal"
1898 sequences and transform them into atomic operations as seen by the host.
1900 static void decode_gusa(DisasContext
*ctx
, CPUSH4State
*env
)
1903 int ld_adr
, ld_dst
, ld_mop
;
1904 int op_dst
, op_src
, op_opc
;
1905 int mv_src
, mt_dst
, st_src
, st_mop
;
1907 uint32_t pc
= ctx
->base
.pc_next
;
1908 uint32_t pc_end
= ctx
->base
.tb
->cs_base
;
1909 int max_insns
= (pc_end
- pc
) / 2;
1912 /* The state machine below will consume only a few insns.
1913 If there are more than that in a region, fail now. */
1914 if (max_insns
> ARRAY_SIZE(insns
)) {
1918 /* Read all of the insns for the region. */
1919 for (i
= 0; i
< max_insns
; ++i
) {
1920 insns
[i
] = translator_lduw(env
, pc
+ i
* 2);
1923 ld_adr
= ld_dst
= ld_mop
= -1;
1925 op_dst
= op_src
= op_opc
= -1;
1927 st_src
= st_mop
= -1;
1932 do { if (i >= max_insns) goto fail; ctx->opcode = insns[i++]; } while (0)
1935 * Expect a load to begin the region.
1938 switch (ctx
->opcode
& 0xf00f) {
1939 case 0x6000: /* mov.b @Rm,Rn */
1942 case 0x6001: /* mov.w @Rm,Rn */
1945 case 0x6002: /* mov.l @Rm,Rn */
1953 if (ld_adr
== ld_dst
) {
1956 /* Unless we see a mov, any two-operand operation must use ld_dst. */
1960 * Expect an optional register move.
1963 switch (ctx
->opcode
& 0xf00f) {
1964 case 0x6003: /* mov Rm,Rn */
1965 /* Here we want to recognize ld_dst being saved for later consumtion,
1966 or for another input register being copied so that ld_dst need not
1967 be clobbered during the operation. */
1970 if (op_dst
== ld_dst
) {
1971 /* Overwriting the load output. */
1974 if (mv_src
!= ld_dst
) {
1975 /* Copying a new input; constrain op_src to match the load. */
1981 /* Put back and re-examine as operation. */
1986 * Expect the operation.
1989 switch (ctx
->opcode
& 0xf00f) {
1990 case 0x300c: /* add Rm,Rn */
1991 op_opc
= INDEX_op_add_i32
;
1993 case 0x2009: /* and Rm,Rn */
1994 op_opc
= INDEX_op_and_i32
;
1996 case 0x200a: /* xor Rm,Rn */
1997 op_opc
= INDEX_op_xor_i32
;
1999 case 0x200b: /* or Rm,Rn */
2000 op_opc
= INDEX_op_or_i32
;
2002 /* The operation register should be as expected, and the
2003 other input cannot depend on the load. */
2004 if (op_dst
!= B11_8
) {
2008 /* Unconstrainted input. */
2010 } else if (op_src
== B7_4
) {
2011 /* Constrained input matched load. All operations are
2012 commutative; "swap" them by "moving" the load output
2013 to the (implicit) first argument and the move source
2014 to the (explicit) second argument. */
2019 op_arg
= REG(op_src
);
2022 case 0x6007: /* not Rm,Rn */
2023 if (ld_dst
!= B7_4
|| mv_src
>= 0) {
2027 op_opc
= INDEX_op_xor_i32
;
2028 op_arg
= tcg_const_i32(-1);
2031 case 0x7000 ... 0x700f: /* add #imm,Rn */
2032 if (op_dst
!= B11_8
|| mv_src
>= 0) {
2035 op_opc
= INDEX_op_add_i32
;
2036 op_arg
= tcg_const_i32(B7_0s
);
2039 case 0x3000: /* cmp/eq Rm,Rn */
2040 /* Looking for the middle of a compare-and-swap sequence,
2041 beginning with the compare. Operands can be either order,
2042 but with only one overlapping the load. */
2043 if ((ld_dst
== B11_8
) + (ld_dst
== B7_4
) != 1 || mv_src
>= 0) {
2046 op_opc
= INDEX_op_setcond_i32
; /* placeholder */
2047 op_src
= (ld_dst
== B11_8
? B7_4
: B11_8
);
2048 op_arg
= REG(op_src
);
2051 switch (ctx
->opcode
& 0xff00) {
2052 case 0x8b00: /* bf label */
2053 case 0x8f00: /* bf/s label */
2054 if (pc
+ (i
+ 1 + B7_0s
) * 2 != pc_end
) {
2057 if ((ctx
->opcode
& 0xff00) == 0x8b00) { /* bf label */
2060 /* We're looking to unconditionally modify Rn with the
2061 result of the comparison, within the delay slot of
2062 the branch. This is used by older gcc. */
2064 if ((ctx
->opcode
& 0xf0ff) == 0x0029) { /* movt Rn */
2076 case 0x2008: /* tst Rm,Rn */
2077 /* Looking for a compare-and-swap against zero. */
2078 if (ld_dst
!= B11_8
|| ld_dst
!= B7_4
|| mv_src
>= 0) {
2081 op_opc
= INDEX_op_setcond_i32
;
2082 op_arg
= tcg_const_i32(0);
2085 if ((ctx
->opcode
& 0xff00) != 0x8900 /* bt label */
2086 || pc
+ (i
+ 1 + B7_0s
) * 2 != pc_end
) {
2092 /* Put back and re-examine as store. */
2099 /* The store must be the last insn. */
2100 if (i
!= max_insns
- 1) {
2104 switch (ctx
->opcode
& 0xf00f) {
2105 case 0x2000: /* mov.b Rm,@Rn */
2108 case 0x2001: /* mov.w Rm,@Rn */
2111 case 0x2002: /* mov.l Rm,@Rn */
2117 /* The store must match the load. */
2118 if (ld_adr
!= B11_8
|| st_mop
!= (ld_mop
& MO_SIZE
)) {
2126 * Emit the operation.
2130 /* No operation found. Look for exchange pattern. */
2131 if (st_src
== ld_dst
|| mv_src
>= 0) {
2134 tcg_gen_atomic_xchg_i32(REG(ld_dst
), REG(ld_adr
), REG(st_src
),
2135 ctx
->memidx
, ld_mop
);
2138 case INDEX_op_add_i32
:
2139 if (op_dst
!= st_src
) {
2142 if (op_dst
== ld_dst
&& st_mop
== MO_UL
) {
2143 tcg_gen_atomic_add_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2144 op_arg
, ctx
->memidx
, ld_mop
);
2146 tcg_gen_atomic_fetch_add_i32(REG(ld_dst
), REG(ld_adr
),
2147 op_arg
, ctx
->memidx
, ld_mop
);
2148 if (op_dst
!= ld_dst
) {
2149 /* Note that mop sizes < 4 cannot use add_fetch
2150 because it won't carry into the higher bits. */
2151 tcg_gen_add_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2156 case INDEX_op_and_i32
:
2157 if (op_dst
!= st_src
) {
2160 if (op_dst
== ld_dst
) {
2161 tcg_gen_atomic_and_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2162 op_arg
, ctx
->memidx
, ld_mop
);
2164 tcg_gen_atomic_fetch_and_i32(REG(ld_dst
), REG(ld_adr
),
2165 op_arg
, ctx
->memidx
, ld_mop
);
2166 tcg_gen_and_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2170 case INDEX_op_or_i32
:
2171 if (op_dst
!= st_src
) {
2174 if (op_dst
== ld_dst
) {
2175 tcg_gen_atomic_or_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2176 op_arg
, ctx
->memidx
, ld_mop
);
2178 tcg_gen_atomic_fetch_or_i32(REG(ld_dst
), REG(ld_adr
),
2179 op_arg
, ctx
->memidx
, ld_mop
);
2180 tcg_gen_or_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2184 case INDEX_op_xor_i32
:
2185 if (op_dst
!= st_src
) {
2188 if (op_dst
== ld_dst
) {
2189 tcg_gen_atomic_xor_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2190 op_arg
, ctx
->memidx
, ld_mop
);
2192 tcg_gen_atomic_fetch_xor_i32(REG(ld_dst
), REG(ld_adr
),
2193 op_arg
, ctx
->memidx
, ld_mop
);
2194 tcg_gen_xor_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2198 case INDEX_op_setcond_i32
:
2199 if (st_src
== ld_dst
) {
2202 tcg_gen_atomic_cmpxchg_i32(REG(ld_dst
), REG(ld_adr
), op_arg
,
2203 REG(st_src
), ctx
->memidx
, ld_mop
);
2204 tcg_gen_setcond_i32(TCG_COND_EQ
, cpu_sr_t
, REG(ld_dst
), op_arg
);
2206 tcg_gen_mov_i32(REG(mt_dst
), cpu_sr_t
);
2211 g_assert_not_reached();
2214 /* If op_src is not a valid register, then op_arg was a constant. */
2215 if (op_src
< 0 && op_arg
) {
2216 tcg_temp_free_i32(op_arg
);
2219 /* The entire region has been translated. */
2220 ctx
->envflags
&= ~GUSA_MASK
;
2221 ctx
->base
.pc_next
= pc_end
;
2222 ctx
->base
.num_insns
+= max_insns
- 1;
2226 qemu_log_mask(LOG_UNIMP
, "Unrecognized gUSA sequence %08x-%08x\n",
2229 /* Restart with the EXCLUSIVE bit set, within a TB run via
2230 cpu_exec_step_atomic holding the exclusive lock. */
2231 ctx
->envflags
|= GUSA_EXCLUSIVE
;
2232 gen_save_cpu_state(ctx
, false);
2233 gen_helper_exclusive(cpu_env
);
2234 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2236 /* We're not executing an instruction, but we must report one for the
2237 purposes of accounting within the TB. We might as well report the
2238 entire region consumed via ctx->base.pc_next so that it's immediately
2239 available in the disassembly dump. */
2240 ctx
->base
.pc_next
= pc_end
;
2241 ctx
->base
.num_insns
+= max_insns
- 1;
2245 static void sh4_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2247 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2248 CPUSH4State
*env
= cs
->env_ptr
;
2252 ctx
->tbflags
= tbflags
= ctx
->base
.tb
->flags
;
2253 ctx
->envflags
= tbflags
& TB_FLAG_ENVFLAGS_MASK
;
2254 ctx
->memidx
= (tbflags
& (1u << SR_MD
)) == 0 ? 1 : 0;
2255 /* We don't know if the delayed pc came from a dynamic or static branch,
2256 so assume it is a dynamic branch. */
2257 ctx
->delayed_pc
= -1; /* use delayed pc from env pointer */
2258 ctx
->features
= env
->features
;
2259 ctx
->has_movcal
= (tbflags
& TB_FLAG_PENDING_MOVCA
);
2260 ctx
->gbank
= ((tbflags
& (1 << SR_MD
)) &&
2261 (tbflags
& (1 << SR_RB
))) * 0x10;
2262 ctx
->fbank
= tbflags
& FPSCR_FR
? 0x10 : 0;
2264 if (tbflags
& GUSA_MASK
) {
2265 uint32_t pc
= ctx
->base
.pc_next
;
2266 uint32_t pc_end
= ctx
->base
.tb
->cs_base
;
2267 int backup
= sextract32(ctx
->tbflags
, GUSA_SHIFT
, 8);
2268 int max_insns
= (pc_end
- pc
) / 2;
2270 if (pc
!= pc_end
+ backup
|| max_insns
< 2) {
2271 /* This is a malformed gUSA region. Don't do anything special,
2272 since the interpreter is likely to get confused. */
2273 ctx
->envflags
&= ~GUSA_MASK
;
2274 } else if (tbflags
& GUSA_EXCLUSIVE
) {
2275 /* Regardless of single-stepping or the end of the page,
2276 we must complete execution of the gUSA region while
2277 holding the exclusive lock. */
2278 ctx
->base
.max_insns
= max_insns
;
2283 /* Since the ISA is fixed-width, we can bound by the number
2284 of instructions remaining on the page. */
2285 bound
= -(ctx
->base
.pc_next
| TARGET_PAGE_MASK
) / 2;
2286 ctx
->base
.max_insns
= MIN(ctx
->base
.max_insns
, bound
);
2289 static void sh4_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2293 static void sh4_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2295 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2297 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->envflags
);
2300 static bool sh4_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
2301 const CPUBreakpoint
*bp
)
2303 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2305 /* We have hit a breakpoint - make sure PC is up-to-date */
2306 gen_save_cpu_state(ctx
, true);
2307 gen_helper_debug(cpu_env
);
2308 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2309 /* The address covered by the breakpoint must be included in
2310 [tb->pc, tb->pc + tb->size) in order to for it to be
2311 properly cleared -- thus we increment the PC here so that
2312 the logic setting tb->size below does the right thing. */
2313 ctx
->base
.pc_next
+= 2;
2317 static void sh4_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
2319 CPUSH4State
*env
= cs
->env_ptr
;
2320 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2322 #ifdef CONFIG_USER_ONLY
2323 if (unlikely(ctx
->envflags
& GUSA_MASK
)
2324 && !(ctx
->envflags
& GUSA_EXCLUSIVE
)) {
2325 /* We're in an gUSA region, and we have not already fallen
2326 back on using an exclusive region. Attempt to parse the
2327 region into a single supported atomic operation. Failure
2328 is handled within the parser by raising an exception to
2329 retry using an exclusive region. */
2330 decode_gusa(ctx
, env
);
2335 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
2337 ctx
->base
.pc_next
+= 2;
2340 static void sh4_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
2342 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2344 if (ctx
->tbflags
& GUSA_EXCLUSIVE
) {
2345 /* Ending the region of exclusivity. Clear the bits. */
2346 ctx
->envflags
&= ~GUSA_MASK
;
2349 switch (ctx
->base
.is_jmp
) {
2351 gen_save_cpu_state(ctx
, true);
2352 if (ctx
->base
.singlestep_enabled
) {
2353 gen_helper_debug(cpu_env
);
2355 tcg_gen_exit_tb(NULL
, 0);
2359 case DISAS_TOO_MANY
:
2360 gen_save_cpu_state(ctx
, false);
2361 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
2363 case DISAS_NORETURN
:
2366 g_assert_not_reached();
2370 static void sh4_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
2372 qemu_log("IN:\n"); /* , lookup_symbol(dcbase->pc_first)); */
2373 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
2376 static const TranslatorOps sh4_tr_ops
= {
2377 .init_disas_context
= sh4_tr_init_disas_context
,
2378 .tb_start
= sh4_tr_tb_start
,
2379 .insn_start
= sh4_tr_insn_start
,
2380 .breakpoint_check
= sh4_tr_breakpoint_check
,
2381 .translate_insn
= sh4_tr_translate_insn
,
2382 .tb_stop
= sh4_tr_tb_stop
,
2383 .disas_log
= sh4_tr_disas_log
,
2386 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
2390 translator_loop(&sh4_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
2393 void restore_state_to_opc(CPUSH4State
*env
, TranslationBlock
*tb
,
2397 env
->flags
= data
[1];
2398 /* Theoretically delayed_pc should also be restored. In practice the
2399 branch instruction is re-executed after exception, so the delayed
2400 branch target will be recomputed. */