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 */
1963 * Here we want to recognize ld_dst being saved for later consumption,
1964 * or for another input register being copied so that ld_dst need not
1965 * be clobbered during the operation.
1969 if (op_dst
== ld_dst
) {
1970 /* Overwriting the load output. */
1973 if (mv_src
!= ld_dst
) {
1974 /* Copying a new input; constrain op_src to match the load. */
1980 /* Put back and re-examine as operation. */
1985 * Expect the operation.
1988 switch (ctx
->opcode
& 0xf00f) {
1989 case 0x300c: /* add Rm,Rn */
1990 op_opc
= INDEX_op_add_i32
;
1992 case 0x2009: /* and Rm,Rn */
1993 op_opc
= INDEX_op_and_i32
;
1995 case 0x200a: /* xor Rm,Rn */
1996 op_opc
= INDEX_op_xor_i32
;
1998 case 0x200b: /* or Rm,Rn */
1999 op_opc
= INDEX_op_or_i32
;
2001 /* The operation register should be as expected, and the
2002 other input cannot depend on the load. */
2003 if (op_dst
!= B11_8
) {
2007 /* Unconstrainted input. */
2009 } else if (op_src
== B7_4
) {
2010 /* Constrained input matched load. All operations are
2011 commutative; "swap" them by "moving" the load output
2012 to the (implicit) first argument and the move source
2013 to the (explicit) second argument. */
2018 op_arg
= REG(op_src
);
2021 case 0x6007: /* not Rm,Rn */
2022 if (ld_dst
!= B7_4
|| mv_src
>= 0) {
2026 op_opc
= INDEX_op_xor_i32
;
2027 op_arg
= tcg_const_i32(-1);
2030 case 0x7000 ... 0x700f: /* add #imm,Rn */
2031 if (op_dst
!= B11_8
|| mv_src
>= 0) {
2034 op_opc
= INDEX_op_add_i32
;
2035 op_arg
= tcg_const_i32(B7_0s
);
2038 case 0x3000: /* cmp/eq Rm,Rn */
2039 /* Looking for the middle of a compare-and-swap sequence,
2040 beginning with the compare. Operands can be either order,
2041 but with only one overlapping the load. */
2042 if ((ld_dst
== B11_8
) + (ld_dst
== B7_4
) != 1 || mv_src
>= 0) {
2045 op_opc
= INDEX_op_setcond_i32
; /* placeholder */
2046 op_src
= (ld_dst
== B11_8
? B7_4
: B11_8
);
2047 op_arg
= REG(op_src
);
2050 switch (ctx
->opcode
& 0xff00) {
2051 case 0x8b00: /* bf label */
2052 case 0x8f00: /* bf/s label */
2053 if (pc
+ (i
+ 1 + B7_0s
) * 2 != pc_end
) {
2056 if ((ctx
->opcode
& 0xff00) == 0x8b00) { /* bf label */
2059 /* We're looking to unconditionally modify Rn with the
2060 result of the comparison, within the delay slot of
2061 the branch. This is used by older gcc. */
2063 if ((ctx
->opcode
& 0xf0ff) == 0x0029) { /* movt Rn */
2075 case 0x2008: /* tst Rm,Rn */
2076 /* Looking for a compare-and-swap against zero. */
2077 if (ld_dst
!= B11_8
|| ld_dst
!= B7_4
|| mv_src
>= 0) {
2080 op_opc
= INDEX_op_setcond_i32
;
2081 op_arg
= tcg_const_i32(0);
2084 if ((ctx
->opcode
& 0xff00) != 0x8900 /* bt label */
2085 || pc
+ (i
+ 1 + B7_0s
) * 2 != pc_end
) {
2091 /* Put back and re-examine as store. */
2098 /* The store must be the last insn. */
2099 if (i
!= max_insns
- 1) {
2103 switch (ctx
->opcode
& 0xf00f) {
2104 case 0x2000: /* mov.b Rm,@Rn */
2107 case 0x2001: /* mov.w Rm,@Rn */
2110 case 0x2002: /* mov.l Rm,@Rn */
2116 /* The store must match the load. */
2117 if (ld_adr
!= B11_8
|| st_mop
!= (ld_mop
& MO_SIZE
)) {
2125 * Emit the operation.
2129 /* No operation found. Look for exchange pattern. */
2130 if (st_src
== ld_dst
|| mv_src
>= 0) {
2133 tcg_gen_atomic_xchg_i32(REG(ld_dst
), REG(ld_adr
), REG(st_src
),
2134 ctx
->memidx
, ld_mop
);
2137 case INDEX_op_add_i32
:
2138 if (op_dst
!= st_src
) {
2141 if (op_dst
== ld_dst
&& st_mop
== MO_UL
) {
2142 tcg_gen_atomic_add_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2143 op_arg
, ctx
->memidx
, ld_mop
);
2145 tcg_gen_atomic_fetch_add_i32(REG(ld_dst
), REG(ld_adr
),
2146 op_arg
, ctx
->memidx
, ld_mop
);
2147 if (op_dst
!= ld_dst
) {
2148 /* Note that mop sizes < 4 cannot use add_fetch
2149 because it won't carry into the higher bits. */
2150 tcg_gen_add_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2155 case INDEX_op_and_i32
:
2156 if (op_dst
!= st_src
) {
2159 if (op_dst
== ld_dst
) {
2160 tcg_gen_atomic_and_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2161 op_arg
, ctx
->memidx
, ld_mop
);
2163 tcg_gen_atomic_fetch_and_i32(REG(ld_dst
), REG(ld_adr
),
2164 op_arg
, ctx
->memidx
, ld_mop
);
2165 tcg_gen_and_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2169 case INDEX_op_or_i32
:
2170 if (op_dst
!= st_src
) {
2173 if (op_dst
== ld_dst
) {
2174 tcg_gen_atomic_or_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2175 op_arg
, ctx
->memidx
, ld_mop
);
2177 tcg_gen_atomic_fetch_or_i32(REG(ld_dst
), REG(ld_adr
),
2178 op_arg
, ctx
->memidx
, ld_mop
);
2179 tcg_gen_or_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2183 case INDEX_op_xor_i32
:
2184 if (op_dst
!= st_src
) {
2187 if (op_dst
== ld_dst
) {
2188 tcg_gen_atomic_xor_fetch_i32(REG(ld_dst
), REG(ld_adr
),
2189 op_arg
, ctx
->memidx
, ld_mop
);
2191 tcg_gen_atomic_fetch_xor_i32(REG(ld_dst
), REG(ld_adr
),
2192 op_arg
, ctx
->memidx
, ld_mop
);
2193 tcg_gen_xor_i32(REG(op_dst
), REG(ld_dst
), op_arg
);
2197 case INDEX_op_setcond_i32
:
2198 if (st_src
== ld_dst
) {
2201 tcg_gen_atomic_cmpxchg_i32(REG(ld_dst
), REG(ld_adr
), op_arg
,
2202 REG(st_src
), ctx
->memidx
, ld_mop
);
2203 tcg_gen_setcond_i32(TCG_COND_EQ
, cpu_sr_t
, REG(ld_dst
), op_arg
);
2205 tcg_gen_mov_i32(REG(mt_dst
), cpu_sr_t
);
2210 g_assert_not_reached();
2213 /* If op_src is not a valid register, then op_arg was a constant. */
2214 if (op_src
< 0 && op_arg
) {
2215 tcg_temp_free_i32(op_arg
);
2218 /* The entire region has been translated. */
2219 ctx
->envflags
&= ~GUSA_MASK
;
2220 ctx
->base
.pc_next
= pc_end
;
2221 ctx
->base
.num_insns
+= max_insns
- 1;
2225 qemu_log_mask(LOG_UNIMP
, "Unrecognized gUSA sequence %08x-%08x\n",
2228 /* Restart with the EXCLUSIVE bit set, within a TB run via
2229 cpu_exec_step_atomic holding the exclusive lock. */
2230 ctx
->envflags
|= GUSA_EXCLUSIVE
;
2231 gen_save_cpu_state(ctx
, false);
2232 gen_helper_exclusive(cpu_env
);
2233 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2235 /* We're not executing an instruction, but we must report one for the
2236 purposes of accounting within the TB. We might as well report the
2237 entire region consumed via ctx->base.pc_next so that it's immediately
2238 available in the disassembly dump. */
2239 ctx
->base
.pc_next
= pc_end
;
2240 ctx
->base
.num_insns
+= max_insns
- 1;
2244 static void sh4_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
2246 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2247 CPUSH4State
*env
= cs
->env_ptr
;
2251 ctx
->tbflags
= tbflags
= ctx
->base
.tb
->flags
;
2252 ctx
->envflags
= tbflags
& TB_FLAG_ENVFLAGS_MASK
;
2253 ctx
->memidx
= (tbflags
& (1u << SR_MD
)) == 0 ? 1 : 0;
2254 /* We don't know if the delayed pc came from a dynamic or static branch,
2255 so assume it is a dynamic branch. */
2256 ctx
->delayed_pc
= -1; /* use delayed pc from env pointer */
2257 ctx
->features
= env
->features
;
2258 ctx
->has_movcal
= (tbflags
& TB_FLAG_PENDING_MOVCA
);
2259 ctx
->gbank
= ((tbflags
& (1 << SR_MD
)) &&
2260 (tbflags
& (1 << SR_RB
))) * 0x10;
2261 ctx
->fbank
= tbflags
& FPSCR_FR
? 0x10 : 0;
2263 if (tbflags
& GUSA_MASK
) {
2264 uint32_t pc
= ctx
->base
.pc_next
;
2265 uint32_t pc_end
= ctx
->base
.tb
->cs_base
;
2266 int backup
= sextract32(ctx
->tbflags
, GUSA_SHIFT
, 8);
2267 int max_insns
= (pc_end
- pc
) / 2;
2269 if (pc
!= pc_end
+ backup
|| max_insns
< 2) {
2270 /* This is a malformed gUSA region. Don't do anything special,
2271 since the interpreter is likely to get confused. */
2272 ctx
->envflags
&= ~GUSA_MASK
;
2273 } else if (tbflags
& GUSA_EXCLUSIVE
) {
2274 /* Regardless of single-stepping or the end of the page,
2275 we must complete execution of the gUSA region while
2276 holding the exclusive lock. */
2277 ctx
->base
.max_insns
= max_insns
;
2282 /* Since the ISA is fixed-width, we can bound by the number
2283 of instructions remaining on the page. */
2284 bound
= -(ctx
->base
.pc_next
| TARGET_PAGE_MASK
) / 2;
2285 ctx
->base
.max_insns
= MIN(ctx
->base
.max_insns
, bound
);
2288 static void sh4_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2292 static void sh4_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
2294 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2296 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->envflags
);
2299 static bool sh4_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
2300 const CPUBreakpoint
*bp
)
2302 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2304 /* We have hit a breakpoint - make sure PC is up-to-date */
2305 gen_save_cpu_state(ctx
, true);
2306 gen_helper_debug(cpu_env
);
2307 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2308 /* The address covered by the breakpoint must be included in
2309 [tb->pc, tb->pc + tb->size) in order to for it to be
2310 properly cleared -- thus we increment the PC here so that
2311 the logic setting tb->size below does the right thing. */
2312 ctx
->base
.pc_next
+= 2;
2316 static void sh4_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
2318 CPUSH4State
*env
= cs
->env_ptr
;
2319 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2321 #ifdef CONFIG_USER_ONLY
2322 if (unlikely(ctx
->envflags
& GUSA_MASK
)
2323 && !(ctx
->envflags
& GUSA_EXCLUSIVE
)) {
2324 /* We're in an gUSA region, and we have not already fallen
2325 back on using an exclusive region. Attempt to parse the
2326 region into a single supported atomic operation. Failure
2327 is handled within the parser by raising an exception to
2328 retry using an exclusive region. */
2329 decode_gusa(ctx
, env
);
2334 ctx
->opcode
= translator_lduw(env
, ctx
->base
.pc_next
);
2336 ctx
->base
.pc_next
+= 2;
2339 static void sh4_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
2341 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
2343 if (ctx
->tbflags
& GUSA_EXCLUSIVE
) {
2344 /* Ending the region of exclusivity. Clear the bits. */
2345 ctx
->envflags
&= ~GUSA_MASK
;
2348 switch (ctx
->base
.is_jmp
) {
2350 gen_save_cpu_state(ctx
, true);
2351 if (ctx
->base
.singlestep_enabled
) {
2352 gen_helper_debug(cpu_env
);
2354 tcg_gen_exit_tb(NULL
, 0);
2358 case DISAS_TOO_MANY
:
2359 gen_save_cpu_state(ctx
, false);
2360 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
2362 case DISAS_NORETURN
:
2365 g_assert_not_reached();
2369 static void sh4_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
2371 qemu_log("IN:\n"); /* , lookup_symbol(dcbase->pc_first)); */
2372 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
2375 static const TranslatorOps sh4_tr_ops
= {
2376 .init_disas_context
= sh4_tr_init_disas_context
,
2377 .tb_start
= sh4_tr_tb_start
,
2378 .insn_start
= sh4_tr_insn_start
,
2379 .breakpoint_check
= sh4_tr_breakpoint_check
,
2380 .translate_insn
= sh4_tr_translate_insn
,
2381 .tb_stop
= sh4_tr_tb_stop
,
2382 .disas_log
= sh4_tr_disas_log
,
2385 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
2389 translator_loop(&sh4_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
2392 void restore_state_to_opc(CPUSH4State
*env
, TranslationBlock
*tb
,
2396 env
->flags
= data
[1];
2397 /* Theoretically delayed_pc should also be restored. In practice the
2398 branch instruction is re-executed after exception, so the delayed
2399 branch target will be recomputed. */