4 * Copyright (c) 2005 Samuel Tardieu
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 #include "disas/disas.h"
25 #include "exec/cpu_ldst.h"
27 #include "exec/helper-proto.h"
28 #include "exec/helper-gen.h"
30 #include "trace-tcg.h"
33 typedef struct DisasContext
{
34 struct TranslationBlock
*tb
;
41 int singlestep_enabled
;
46 #if defined(CONFIG_USER_ONLY)
47 #define IS_USER(ctx) 1
49 #define IS_USER(ctx) (!(ctx->flags & (1u << SR_MD)))
53 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
56 BS_STOP
= 1, /* We want to stop translation for any reason */
57 BS_BRANCH
= 2, /* We reached a branch condition */
58 BS_EXCP
= 3, /* We reached an exception condition */
61 /* global register indexes */
62 static TCGv_ptr cpu_env
;
63 static TCGv cpu_gregs
[24];
64 static TCGv cpu_sr
, cpu_sr_m
, cpu_sr_q
, cpu_sr_t
;
65 static TCGv cpu_pc
, cpu_ssr
, cpu_spc
, cpu_gbr
;
66 static TCGv cpu_vbr
, cpu_sgr
, cpu_dbr
, cpu_mach
, cpu_macl
;
67 static TCGv cpu_pr
, cpu_fpscr
, cpu_fpul
, cpu_ldst
;
68 static TCGv cpu_fregs
[32];
70 /* internal register indexes */
71 static TCGv cpu_flags
, cpu_delayed_pc
;
73 #include "exec/gen-icount.h"
75 void sh4_translate_init(void)
78 static int done_init
= 0;
79 static const char * const gregnames
[24] = {
80 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
81 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
82 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
83 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
84 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
86 static const char * const fregnames
[32] = {
87 "FPR0_BANK0", "FPR1_BANK0", "FPR2_BANK0", "FPR3_BANK0",
88 "FPR4_BANK0", "FPR5_BANK0", "FPR6_BANK0", "FPR7_BANK0",
89 "FPR8_BANK0", "FPR9_BANK0", "FPR10_BANK0", "FPR11_BANK0",
90 "FPR12_BANK0", "FPR13_BANK0", "FPR14_BANK0", "FPR15_BANK0",
91 "FPR0_BANK1", "FPR1_BANK1", "FPR2_BANK1", "FPR3_BANK1",
92 "FPR4_BANK1", "FPR5_BANK1", "FPR6_BANK1", "FPR7_BANK1",
93 "FPR8_BANK1", "FPR9_BANK1", "FPR10_BANK1", "FPR11_BANK1",
94 "FPR12_BANK1", "FPR13_BANK1", "FPR14_BANK1", "FPR15_BANK1",
100 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
102 for (i
= 0; i
< 24; i
++)
103 cpu_gregs
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
104 offsetof(CPUSH4State
, gregs
[i
]),
107 cpu_pc
= tcg_global_mem_new_i32(TCG_AREG0
,
108 offsetof(CPUSH4State
, pc
), "PC");
109 cpu_sr
= tcg_global_mem_new_i32(TCG_AREG0
,
110 offsetof(CPUSH4State
, sr
), "SR");
111 cpu_sr_m
= tcg_global_mem_new_i32(TCG_AREG0
,
112 offsetof(CPUSH4State
, sr_m
), "SR_M");
113 cpu_sr_q
= tcg_global_mem_new_i32(TCG_AREG0
,
114 offsetof(CPUSH4State
, sr_q
), "SR_Q");
115 cpu_sr_t
= tcg_global_mem_new_i32(TCG_AREG0
,
116 offsetof(CPUSH4State
, sr_t
), "SR_T");
117 cpu_ssr
= tcg_global_mem_new_i32(TCG_AREG0
,
118 offsetof(CPUSH4State
, ssr
), "SSR");
119 cpu_spc
= tcg_global_mem_new_i32(TCG_AREG0
,
120 offsetof(CPUSH4State
, spc
), "SPC");
121 cpu_gbr
= tcg_global_mem_new_i32(TCG_AREG0
,
122 offsetof(CPUSH4State
, gbr
), "GBR");
123 cpu_vbr
= tcg_global_mem_new_i32(TCG_AREG0
,
124 offsetof(CPUSH4State
, vbr
), "VBR");
125 cpu_sgr
= tcg_global_mem_new_i32(TCG_AREG0
,
126 offsetof(CPUSH4State
, sgr
), "SGR");
127 cpu_dbr
= tcg_global_mem_new_i32(TCG_AREG0
,
128 offsetof(CPUSH4State
, dbr
), "DBR");
129 cpu_mach
= tcg_global_mem_new_i32(TCG_AREG0
,
130 offsetof(CPUSH4State
, mach
), "MACH");
131 cpu_macl
= tcg_global_mem_new_i32(TCG_AREG0
,
132 offsetof(CPUSH4State
, macl
), "MACL");
133 cpu_pr
= tcg_global_mem_new_i32(TCG_AREG0
,
134 offsetof(CPUSH4State
, pr
), "PR");
135 cpu_fpscr
= tcg_global_mem_new_i32(TCG_AREG0
,
136 offsetof(CPUSH4State
, fpscr
), "FPSCR");
137 cpu_fpul
= tcg_global_mem_new_i32(TCG_AREG0
,
138 offsetof(CPUSH4State
, fpul
), "FPUL");
140 cpu_flags
= tcg_global_mem_new_i32(TCG_AREG0
,
141 offsetof(CPUSH4State
, flags
), "_flags_");
142 cpu_delayed_pc
= tcg_global_mem_new_i32(TCG_AREG0
,
143 offsetof(CPUSH4State
, delayed_pc
),
145 cpu_ldst
= tcg_global_mem_new_i32(TCG_AREG0
,
146 offsetof(CPUSH4State
, ldst
), "_ldst_");
148 for (i
= 0; i
< 32; i
++)
149 cpu_fregs
[i
] = tcg_global_mem_new_i32(TCG_AREG0
,
150 offsetof(CPUSH4State
, fregs
[i
]),
156 void superh_cpu_dump_state(CPUState
*cs
, FILE *f
,
157 fprintf_function cpu_fprintf
, int flags
)
159 SuperHCPU
*cpu
= SUPERH_CPU(cs
);
160 CPUSH4State
*env
= &cpu
->env
;
162 cpu_fprintf(f
, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
163 env
->pc
, cpu_read_sr(env
), env
->pr
, env
->fpscr
);
164 cpu_fprintf(f
, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
165 env
->spc
, env
->ssr
, env
->gbr
, env
->vbr
);
166 cpu_fprintf(f
, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
167 env
->sgr
, env
->dbr
, env
->delayed_pc
, env
->fpul
);
168 for (i
= 0; i
< 24; i
+= 4) {
169 cpu_fprintf(f
, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
170 i
, env
->gregs
[i
], i
+ 1, env
->gregs
[i
+ 1],
171 i
+ 2, env
->gregs
[i
+ 2], i
+ 3, env
->gregs
[i
+ 3]);
173 if (env
->flags
& DELAY_SLOT
) {
174 cpu_fprintf(f
, "in delay slot (delayed_pc=0x%08x)\n",
176 } else if (env
->flags
& DELAY_SLOT_CONDITIONAL
) {
177 cpu_fprintf(f
, "in conditional delay slot (delayed_pc=0x%08x)\n",
182 static void gen_read_sr(TCGv dst
)
184 TCGv t0
= tcg_temp_new();
185 tcg_gen_shli_i32(t0
, cpu_sr_q
, SR_Q
);
186 tcg_gen_or_i32(dst
, dst
, t0
);
187 tcg_gen_shli_i32(t0
, cpu_sr_m
, SR_M
);
188 tcg_gen_or_i32(dst
, dst
, t0
);
189 tcg_gen_shli_i32(t0
, cpu_sr_t
, SR_T
);
190 tcg_gen_or_i32(dst
, cpu_sr
, t0
);
191 tcg_temp_free_i32(t0
);
194 static void gen_write_sr(TCGv src
)
196 tcg_gen_andi_i32(cpu_sr
, src
,
197 ~((1u << SR_Q
) | (1u << SR_M
) | (1u << SR_T
)));
198 tcg_gen_shri_i32(cpu_sr_q
, src
, SR_Q
);
199 tcg_gen_andi_i32(cpu_sr_q
, cpu_sr_q
, 1);
200 tcg_gen_shri_i32(cpu_sr_m
, src
, SR_M
);
201 tcg_gen_andi_i32(cpu_sr_m
, cpu_sr_m
, 1);
202 tcg_gen_shri_i32(cpu_sr_t
, src
, SR_T
);
203 tcg_gen_andi_i32(cpu_sr_t
, cpu_sr_t
, 1);
206 static void gen_goto_tb(DisasContext
* ctx
, int n
, target_ulong dest
)
208 TranslationBlock
*tb
;
211 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
212 !ctx
->singlestep_enabled
) {
213 /* Use a direct jump if in same page and singlestep not enabled */
215 tcg_gen_movi_i32(cpu_pc
, dest
);
216 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
218 tcg_gen_movi_i32(cpu_pc
, dest
);
219 if (ctx
->singlestep_enabled
)
220 gen_helper_debug(cpu_env
);
225 static void gen_jump(DisasContext
* ctx
)
227 if (ctx
->delayed_pc
== (uint32_t) - 1) {
228 /* Target is not statically known, it comes necessarily from a
229 delayed jump as immediate jump are conditinal jumps */
230 tcg_gen_mov_i32(cpu_pc
, cpu_delayed_pc
);
231 if (ctx
->singlestep_enabled
)
232 gen_helper_debug(cpu_env
);
235 gen_goto_tb(ctx
, 0, ctx
->delayed_pc
);
239 static inline void gen_branch_slot(uint32_t delayed_pc
, int t
)
241 TCGLabel
*label
= gen_new_label();
242 tcg_gen_movi_i32(cpu_delayed_pc
, delayed_pc
);
243 tcg_gen_brcondi_i32(t
? TCG_COND_EQ
: TCG_COND_NE
, cpu_sr_t
, 0, label
);
244 tcg_gen_ori_i32(cpu_flags
, cpu_flags
, DELAY_SLOT_TRUE
);
245 gen_set_label(label
);
248 /* Immediate conditional jump (bt or bf) */
249 static void gen_conditional_jump(DisasContext
* ctx
,
250 target_ulong ift
, target_ulong ifnott
)
252 TCGLabel
*l1
= gen_new_label();
253 tcg_gen_brcondi_i32(TCG_COND_NE
, cpu_sr_t
, 0, l1
);
254 gen_goto_tb(ctx
, 0, ifnott
);
256 gen_goto_tb(ctx
, 1, ift
);
259 /* Delayed conditional jump (bt or bf) */
260 static void gen_delayed_conditional_jump(DisasContext
* ctx
)
265 l1
= gen_new_label();
267 tcg_gen_andi_i32(ds
, cpu_flags
, DELAY_SLOT_TRUE
);
268 tcg_gen_brcondi_i32(TCG_COND_NE
, ds
, 0, l1
);
269 gen_goto_tb(ctx
, 1, ctx
->pc
+ 2);
271 tcg_gen_andi_i32(cpu_flags
, cpu_flags
, ~DELAY_SLOT_TRUE
);
275 static inline void gen_store_flags(uint32_t flags
)
277 tcg_gen_andi_i32(cpu_flags
, cpu_flags
, DELAY_SLOT_TRUE
);
278 tcg_gen_ori_i32(cpu_flags
, cpu_flags
, flags
);
281 static inline void gen_load_fpr64(TCGv_i64 t
, int reg
)
283 tcg_gen_concat_i32_i64(t
, cpu_fregs
[reg
+ 1], cpu_fregs
[reg
]);
286 static inline void gen_store_fpr64 (TCGv_i64 t
, int reg
)
288 TCGv_i32 tmp
= tcg_temp_new_i32();
289 tcg_gen_extrl_i64_i32(tmp
, t
);
290 tcg_gen_mov_i32(cpu_fregs
[reg
+ 1], tmp
);
291 tcg_gen_shri_i64(t
, t
, 32);
292 tcg_gen_extrl_i64_i32(tmp
, t
);
293 tcg_gen_mov_i32(cpu_fregs
[reg
], tmp
);
294 tcg_temp_free_i32(tmp
);
297 #define B3_0 (ctx->opcode & 0xf)
298 #define B6_4 ((ctx->opcode >> 4) & 0x7)
299 #define B7_4 ((ctx->opcode >> 4) & 0xf)
300 #define B7_0 (ctx->opcode & 0xff)
301 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
302 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
303 (ctx->opcode & 0xfff))
304 #define B11_8 ((ctx->opcode >> 8) & 0xf)
305 #define B15_12 ((ctx->opcode >> 12) & 0xf)
307 #define REG(x) ((x) < 8 && (ctx->flags & (1u << SR_MD))\
308 && (ctx->flags & (1u << SR_RB))\
309 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
311 #define ALTREG(x) ((x) < 8 && (!(ctx->flags & (1u << SR_MD))\
312 || !(ctx->flags & (1u << SR_RB)))\
313 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
315 #define FREG(x) (ctx->flags & FPSCR_FR ? (x) ^ 0x10 : (x))
316 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
317 #define XREG(x) (ctx->flags & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
318 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
320 #define CHECK_NOT_DELAY_SLOT \
321 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
323 tcg_gen_movi_i32(cpu_pc, ctx->pc); \
324 gen_helper_raise_slot_illegal_instruction(cpu_env); \
325 ctx->bstate = BS_BRANCH; \
329 #define CHECK_PRIVILEGED \
330 if (IS_USER(ctx)) { \
331 tcg_gen_movi_i32(cpu_pc, ctx->pc); \
332 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
333 gen_helper_raise_slot_illegal_instruction(cpu_env); \
335 gen_helper_raise_illegal_instruction(cpu_env); \
337 ctx->bstate = BS_BRANCH; \
341 #define CHECK_FPU_ENABLED \
342 if (ctx->flags & (1u << SR_FD)) { \
343 tcg_gen_movi_i32(cpu_pc, ctx->pc); \
344 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
345 gen_helper_raise_slot_fpu_disable(cpu_env); \
347 gen_helper_raise_fpu_disable(cpu_env); \
349 ctx->bstate = BS_BRANCH; \
353 static void _decode_opc(DisasContext
* ctx
)
355 /* This code tries to make movcal emulation sufficiently
356 accurate for Linux purposes. This instruction writes
357 memory, and prior to that, always allocates a cache line.
358 It is used in two contexts:
359 - in memcpy, where data is copied in blocks, the first write
360 of to a block uses movca.l for performance.
361 - in arch/sh/mm/cache-sh4.c, movcal.l + ocbi combination is used
362 to flush the cache. Here, the data written by movcal.l is never
363 written to memory, and the data written is just bogus.
365 To simulate this, we simulate movcal.l, we store the value to memory,
366 but we also remember the previous content. If we see ocbi, we check
367 if movcal.l for that address was done previously. If so, the write should
368 not have hit the memory, so we restore the previous content.
369 When we see an instruction that is neither movca.l
370 nor ocbi, the previous content is discarded.
372 To optimize, we only try to flush stores when we're at the start of
373 TB, or if we already saw movca.l in this TB and did not flush stores
377 int opcode
= ctx
->opcode
& 0xf0ff;
378 if (opcode
!= 0x0093 /* ocbi */
379 && opcode
!= 0x00c3 /* movca.l */)
381 gen_helper_discard_movcal_backup(cpu_env
);
387 fprintf(stderr
, "Translating opcode 0x%04x\n", ctx
->opcode
);
390 switch (ctx
->opcode
) {
391 case 0x0019: /* div0u */
392 tcg_gen_movi_i32(cpu_sr_m
, 0);
393 tcg_gen_movi_i32(cpu_sr_q
, 0);
394 tcg_gen_movi_i32(cpu_sr_t
, 0);
396 case 0x000b: /* rts */
398 tcg_gen_mov_i32(cpu_delayed_pc
, cpu_pr
);
399 ctx
->flags
|= DELAY_SLOT
;
400 ctx
->delayed_pc
= (uint32_t) - 1;
402 case 0x0028: /* clrmac */
403 tcg_gen_movi_i32(cpu_mach
, 0);
404 tcg_gen_movi_i32(cpu_macl
, 0);
406 case 0x0048: /* clrs */
407 tcg_gen_andi_i32(cpu_sr
, cpu_sr
, ~(1u << SR_S
));
409 case 0x0008: /* clrt */
410 tcg_gen_movi_i32(cpu_sr_t
, 0);
412 case 0x0038: /* ldtlb */
414 gen_helper_ldtlb(cpu_env
);
416 case 0x002b: /* rte */
419 gen_write_sr(cpu_ssr
);
420 tcg_gen_mov_i32(cpu_delayed_pc
, cpu_spc
);
421 ctx
->flags
|= DELAY_SLOT
;
422 ctx
->delayed_pc
= (uint32_t) - 1;
424 case 0x0058: /* sets */
425 tcg_gen_ori_i32(cpu_sr
, cpu_sr
, (1u << SR_S
));
427 case 0x0018: /* sett */
428 tcg_gen_movi_i32(cpu_sr_t
, 1);
430 case 0xfbfd: /* frchg */
431 tcg_gen_xori_i32(cpu_fpscr
, cpu_fpscr
, FPSCR_FR
);
432 ctx
->bstate
= BS_STOP
;
434 case 0xf3fd: /* fschg */
435 tcg_gen_xori_i32(cpu_fpscr
, cpu_fpscr
, FPSCR_SZ
);
436 ctx
->bstate
= BS_STOP
;
438 case 0x0009: /* nop */
440 case 0x001b: /* sleep */
442 tcg_gen_movi_i32(cpu_pc
, ctx
->pc
+ 2);
443 gen_helper_sleep(cpu_env
);
447 switch (ctx
->opcode
& 0xf000) {
448 case 0x1000: /* mov.l Rm,@(disp,Rn) */
450 TCGv addr
= tcg_temp_new();
451 tcg_gen_addi_i32(addr
, REG(B11_8
), B3_0
* 4);
452 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
456 case 0x5000: /* mov.l @(disp,Rm),Rn */
458 TCGv addr
= tcg_temp_new();
459 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 4);
460 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESL
);
464 case 0xe000: /* mov #imm,Rn */
465 tcg_gen_movi_i32(REG(B11_8
), B7_0s
);
467 case 0x9000: /* mov.w @(disp,PC),Rn */
469 TCGv addr
= tcg_const_i32(ctx
->pc
+ 4 + B7_0
* 2);
470 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESW
);
474 case 0xd000: /* mov.l @(disp,PC),Rn */
476 TCGv addr
= tcg_const_i32((ctx
->pc
+ 4 + B7_0
* 4) & ~3);
477 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESL
);
481 case 0x7000: /* add #imm,Rn */
482 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), B7_0s
);
484 case 0xa000: /* bra disp */
486 ctx
->delayed_pc
= ctx
->pc
+ 4 + B11_0s
* 2;
487 tcg_gen_movi_i32(cpu_delayed_pc
, ctx
->delayed_pc
);
488 ctx
->flags
|= DELAY_SLOT
;
490 case 0xb000: /* bsr disp */
492 tcg_gen_movi_i32(cpu_pr
, ctx
->pc
+ 4);
493 ctx
->delayed_pc
= ctx
->pc
+ 4 + B11_0s
* 2;
494 tcg_gen_movi_i32(cpu_delayed_pc
, ctx
->delayed_pc
);
495 ctx
->flags
|= DELAY_SLOT
;
499 switch (ctx
->opcode
& 0xf00f) {
500 case 0x6003: /* mov Rm,Rn */
501 tcg_gen_mov_i32(REG(B11_8
), REG(B7_4
));
503 case 0x2000: /* mov.b Rm,@Rn */
504 tcg_gen_qemu_st_i32(REG(B7_4
), REG(B11_8
), ctx
->memidx
, MO_UB
);
506 case 0x2001: /* mov.w Rm,@Rn */
507 tcg_gen_qemu_st_i32(REG(B7_4
), REG(B11_8
), ctx
->memidx
, MO_TEUW
);
509 case 0x2002: /* mov.l Rm,@Rn */
510 tcg_gen_qemu_st_i32(REG(B7_4
), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
512 case 0x6000: /* mov.b @Rm,Rn */
513 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_SB
);
515 case 0x6001: /* mov.w @Rm,Rn */
516 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESW
);
518 case 0x6002: /* mov.l @Rm,Rn */
519 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESL
);
521 case 0x2004: /* mov.b Rm,@-Rn */
523 TCGv addr
= tcg_temp_new();
524 tcg_gen_subi_i32(addr
, REG(B11_8
), 1);
525 /* might cause re-execution */
526 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_UB
);
527 tcg_gen_mov_i32(REG(B11_8
), addr
); /* modify register status */
531 case 0x2005: /* mov.w Rm,@-Rn */
533 TCGv addr
= tcg_temp_new();
534 tcg_gen_subi_i32(addr
, REG(B11_8
), 2);
535 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUW
);
536 tcg_gen_mov_i32(REG(B11_8
), addr
);
540 case 0x2006: /* mov.l Rm,@-Rn */
542 TCGv addr
= tcg_temp_new();
543 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
544 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
545 tcg_gen_mov_i32(REG(B11_8
), addr
);
548 case 0x6004: /* mov.b @Rm+,Rn */
549 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_SB
);
551 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 1);
553 case 0x6005: /* mov.w @Rm+,Rn */
554 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESW
);
556 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 2);
558 case 0x6006: /* mov.l @Rm+,Rn */
559 tcg_gen_qemu_ld_i32(REG(B11_8
), REG(B7_4
), ctx
->memidx
, MO_TESL
);
561 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
563 case 0x0004: /* mov.b Rm,@(R0,Rn) */
565 TCGv addr
= tcg_temp_new();
566 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
567 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_UB
);
571 case 0x0005: /* mov.w Rm,@(R0,Rn) */
573 TCGv addr
= tcg_temp_new();
574 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
575 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUW
);
579 case 0x0006: /* mov.l Rm,@(R0,Rn) */
581 TCGv addr
= tcg_temp_new();
582 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
583 tcg_gen_qemu_st_i32(REG(B7_4
), addr
, ctx
->memidx
, MO_TEUL
);
587 case 0x000c: /* mov.b @(R0,Rm),Rn */
589 TCGv addr
= tcg_temp_new();
590 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
591 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_SB
);
595 case 0x000d: /* mov.w @(R0,Rm),Rn */
597 TCGv addr
= tcg_temp_new();
598 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
599 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESW
);
603 case 0x000e: /* mov.l @(R0,Rm),Rn */
605 TCGv addr
= tcg_temp_new();
606 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
607 tcg_gen_qemu_ld_i32(REG(B11_8
), addr
, ctx
->memidx
, MO_TESL
);
611 case 0x6008: /* swap.b Rm,Rn */
613 TCGv low
= tcg_temp_new();;
614 tcg_gen_ext16u_i32(low
, REG(B7_4
));
615 tcg_gen_bswap16_i32(low
, low
);
616 tcg_gen_deposit_i32(REG(B11_8
), REG(B7_4
), low
, 0, 16);
620 case 0x6009: /* swap.w Rm,Rn */
621 tcg_gen_rotli_i32(REG(B11_8
), REG(B7_4
), 16);
623 case 0x200d: /* xtrct Rm,Rn */
626 high
= tcg_temp_new();
627 tcg_gen_shli_i32(high
, REG(B7_4
), 16);
628 low
= tcg_temp_new();
629 tcg_gen_shri_i32(low
, REG(B11_8
), 16);
630 tcg_gen_or_i32(REG(B11_8
), high
, low
);
635 case 0x300c: /* add Rm,Rn */
636 tcg_gen_add_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
638 case 0x300e: /* addc Rm,Rn */
641 t0
= tcg_const_tl(0);
643 tcg_gen_add2_i32(t1
, cpu_sr_t
, cpu_sr_t
, t0
, REG(B7_4
), t0
);
644 tcg_gen_add2_i32(REG(B11_8
), cpu_sr_t
,
645 REG(B11_8
), t0
, t1
, cpu_sr_t
);
650 case 0x300f: /* addv Rm,Rn */
654 tcg_gen_add_i32(t0
, REG(B7_4
), REG(B11_8
));
656 tcg_gen_xor_i32(t1
, t0
, REG(B11_8
));
658 tcg_gen_xor_i32(t2
, REG(B7_4
), REG(B11_8
));
659 tcg_gen_andc_i32(cpu_sr_t
, t1
, t2
);
661 tcg_gen_shri_i32(cpu_sr_t
, cpu_sr_t
, 31);
663 tcg_gen_mov_i32(REG(B7_4
), t0
);
667 case 0x2009: /* and Rm,Rn */
668 tcg_gen_and_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
670 case 0x3000: /* cmp/eq Rm,Rn */
671 tcg_gen_setcond_i32(TCG_COND_EQ
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
673 case 0x3003: /* cmp/ge Rm,Rn */
674 tcg_gen_setcond_i32(TCG_COND_GE
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
676 case 0x3007: /* cmp/gt Rm,Rn */
677 tcg_gen_setcond_i32(TCG_COND_GT
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
679 case 0x3006: /* cmp/hi Rm,Rn */
680 tcg_gen_setcond_i32(TCG_COND_GTU
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
682 case 0x3002: /* cmp/hs Rm,Rn */
683 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_sr_t
, REG(B11_8
), REG(B7_4
));
685 case 0x200c: /* cmp/str Rm,Rn */
687 TCGv cmp1
= tcg_temp_new();
688 TCGv cmp2
= tcg_temp_new();
689 tcg_gen_xor_i32(cmp2
, REG(B7_4
), REG(B11_8
));
690 tcg_gen_subi_i32(cmp1
, cmp2
, 0x01010101);
691 tcg_gen_andc_i32(cmp1
, cmp1
, cmp2
);
692 tcg_gen_andi_i32(cmp1
, cmp1
, 0x80808080);
693 tcg_gen_setcondi_i32(TCG_COND_NE
, cpu_sr_t
, cmp1
, 0);
698 case 0x2007: /* div0s Rm,Rn */
699 tcg_gen_shri_i32(cpu_sr_q
, REG(B11_8
), 31); /* SR_Q */
700 tcg_gen_shri_i32(cpu_sr_m
, REG(B7_4
), 31); /* SR_M */
701 tcg_gen_xor_i32(cpu_sr_t
, cpu_sr_q
, cpu_sr_m
); /* SR_T */
703 case 0x3004: /* div1 Rm,Rn */
705 TCGv t0
= tcg_temp_new();
706 TCGv t1
= tcg_temp_new();
707 TCGv t2
= tcg_temp_new();
708 TCGv zero
= tcg_const_i32(0);
710 /* shift left arg1, saving the bit being pushed out and inserting
712 tcg_gen_shri_i32(t0
, REG(B11_8
), 31);
713 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
714 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), cpu_sr_t
);
716 /* Add or subtract arg0 from arg1 depending if Q == M. To avoid
717 using 64-bit temps, we compute arg0's high part from q ^ m, so
718 that it is 0x00000000 when adding the value or 0xffffffff when
720 tcg_gen_xor_i32(t1
, cpu_sr_q
, cpu_sr_m
);
721 tcg_gen_subi_i32(t1
, t1
, 1);
722 tcg_gen_neg_i32(t2
, REG(B7_4
));
723 tcg_gen_movcond_i32(TCG_COND_EQ
, t2
, t1
, zero
, REG(B7_4
), t2
);
724 tcg_gen_add2_i32(REG(B11_8
), t1
, REG(B11_8
), zero
, t2
, t1
);
726 /* compute T and Q depending on carry */
727 tcg_gen_andi_i32(t1
, t1
, 1);
728 tcg_gen_xor_i32(t1
, t1
, t0
);
729 tcg_gen_xori_i32(cpu_sr_t
, t1
, 1);
730 tcg_gen_xor_i32(cpu_sr_q
, cpu_sr_m
, t1
);
738 case 0x300d: /* dmuls.l Rm,Rn */
739 tcg_gen_muls2_i32(cpu_macl
, cpu_mach
, REG(B7_4
), REG(B11_8
));
741 case 0x3005: /* dmulu.l Rm,Rn */
742 tcg_gen_mulu2_i32(cpu_macl
, cpu_mach
, REG(B7_4
), REG(B11_8
));
744 case 0x600e: /* exts.b Rm,Rn */
745 tcg_gen_ext8s_i32(REG(B11_8
), REG(B7_4
));
747 case 0x600f: /* exts.w Rm,Rn */
748 tcg_gen_ext16s_i32(REG(B11_8
), REG(B7_4
));
750 case 0x600c: /* extu.b Rm,Rn */
751 tcg_gen_ext8u_i32(REG(B11_8
), REG(B7_4
));
753 case 0x600d: /* extu.w Rm,Rn */
754 tcg_gen_ext16u_i32(REG(B11_8
), REG(B7_4
));
756 case 0x000f: /* mac.l @Rm+,@Rn+ */
759 arg0
= tcg_temp_new();
760 tcg_gen_qemu_ld_i32(arg0
, REG(B7_4
), ctx
->memidx
, MO_TESL
);
761 arg1
= tcg_temp_new();
762 tcg_gen_qemu_ld_i32(arg1
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
763 gen_helper_macl(cpu_env
, arg0
, arg1
);
766 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
767 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
770 case 0x400f: /* mac.w @Rm+,@Rn+ */
773 arg0
= tcg_temp_new();
774 tcg_gen_qemu_ld_i32(arg0
, REG(B7_4
), ctx
->memidx
, MO_TESL
);
775 arg1
= tcg_temp_new();
776 tcg_gen_qemu_ld_i32(arg1
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
777 gen_helper_macw(cpu_env
, arg0
, arg1
);
780 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 2);
781 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 2);
784 case 0x0007: /* mul.l Rm,Rn */
785 tcg_gen_mul_i32(cpu_macl
, REG(B7_4
), REG(B11_8
));
787 case 0x200f: /* muls.w Rm,Rn */
790 arg0
= tcg_temp_new();
791 tcg_gen_ext16s_i32(arg0
, REG(B7_4
));
792 arg1
= tcg_temp_new();
793 tcg_gen_ext16s_i32(arg1
, REG(B11_8
));
794 tcg_gen_mul_i32(cpu_macl
, arg0
, arg1
);
799 case 0x200e: /* mulu.w Rm,Rn */
802 arg0
= tcg_temp_new();
803 tcg_gen_ext16u_i32(arg0
, REG(B7_4
));
804 arg1
= tcg_temp_new();
805 tcg_gen_ext16u_i32(arg1
, REG(B11_8
));
806 tcg_gen_mul_i32(cpu_macl
, arg0
, arg1
);
811 case 0x600b: /* neg Rm,Rn */
812 tcg_gen_neg_i32(REG(B11_8
), REG(B7_4
));
814 case 0x600a: /* negc Rm,Rn */
816 TCGv t0
= tcg_const_i32(0);
817 tcg_gen_add2_i32(REG(B11_8
), cpu_sr_t
,
818 REG(B7_4
), t0
, cpu_sr_t
, t0
);
819 tcg_gen_sub2_i32(REG(B11_8
), cpu_sr_t
,
820 t0
, t0
, REG(B11_8
), cpu_sr_t
);
821 tcg_gen_andi_i32(cpu_sr_t
, cpu_sr_t
, 1);
825 case 0x6007: /* not Rm,Rn */
826 tcg_gen_not_i32(REG(B11_8
), REG(B7_4
));
828 case 0x200b: /* or Rm,Rn */
829 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
831 case 0x400c: /* shad Rm,Rn */
833 TCGv t0
= tcg_temp_new();
834 TCGv t1
= tcg_temp_new();
835 TCGv t2
= tcg_temp_new();
837 tcg_gen_andi_i32(t0
, REG(B7_4
), 0x1f);
839 /* positive case: shift to the left */
840 tcg_gen_shl_i32(t1
, REG(B11_8
), t0
);
842 /* negative case: shift to the right in two steps to
843 correctly handle the -32 case */
844 tcg_gen_xori_i32(t0
, t0
, 0x1f);
845 tcg_gen_sar_i32(t2
, REG(B11_8
), t0
);
846 tcg_gen_sari_i32(t2
, t2
, 1);
848 /* select between the two cases */
849 tcg_gen_movi_i32(t0
, 0);
850 tcg_gen_movcond_i32(TCG_COND_GE
, REG(B11_8
), REG(B7_4
), t0
, t1
, t2
);
857 case 0x400d: /* shld Rm,Rn */
859 TCGv t0
= tcg_temp_new();
860 TCGv t1
= tcg_temp_new();
861 TCGv t2
= tcg_temp_new();
863 tcg_gen_andi_i32(t0
, REG(B7_4
), 0x1f);
865 /* positive case: shift to the left */
866 tcg_gen_shl_i32(t1
, REG(B11_8
), t0
);
868 /* negative case: shift to the right in two steps to
869 correctly handle the -32 case */
870 tcg_gen_xori_i32(t0
, t0
, 0x1f);
871 tcg_gen_shr_i32(t2
, REG(B11_8
), t0
);
872 tcg_gen_shri_i32(t2
, t2
, 1);
874 /* select between the two cases */
875 tcg_gen_movi_i32(t0
, 0);
876 tcg_gen_movcond_i32(TCG_COND_GE
, REG(B11_8
), REG(B7_4
), t0
, t1
, t2
);
883 case 0x3008: /* sub Rm,Rn */
884 tcg_gen_sub_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
886 case 0x300a: /* subc Rm,Rn */
889 t0
= tcg_const_tl(0);
891 tcg_gen_add2_i32(t1
, cpu_sr_t
, cpu_sr_t
, t0
, REG(B7_4
), t0
);
892 tcg_gen_sub2_i32(REG(B11_8
), cpu_sr_t
,
893 REG(B11_8
), t0
, t1
, cpu_sr_t
);
894 tcg_gen_andi_i32(cpu_sr_t
, cpu_sr_t
, 1);
899 case 0x300b: /* subv Rm,Rn */
903 tcg_gen_sub_i32(t0
, REG(B11_8
), REG(B7_4
));
905 tcg_gen_xor_i32(t1
, t0
, REG(B7_4
));
907 tcg_gen_xor_i32(t2
, REG(B11_8
), REG(B7_4
));
908 tcg_gen_and_i32(t1
, t1
, t2
);
910 tcg_gen_shri_i32(cpu_sr_t
, t1
, 31);
912 tcg_gen_mov_i32(REG(B11_8
), t0
);
916 case 0x2008: /* tst Rm,Rn */
918 TCGv val
= tcg_temp_new();
919 tcg_gen_and_i32(val
, REG(B7_4
), REG(B11_8
));
920 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
924 case 0x200a: /* xor Rm,Rn */
925 tcg_gen_xor_i32(REG(B11_8
), REG(B11_8
), REG(B7_4
));
927 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
929 if (ctx
->flags
& FPSCR_SZ
) {
930 TCGv_i64 fp
= tcg_temp_new_i64();
931 gen_load_fpr64(fp
, XREG(B7_4
));
932 gen_store_fpr64(fp
, XREG(B11_8
));
933 tcg_temp_free_i64(fp
);
935 tcg_gen_mov_i32(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B7_4
)]);
938 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
940 if (ctx
->flags
& FPSCR_SZ
) {
941 TCGv addr_hi
= tcg_temp_new();
943 tcg_gen_addi_i32(addr_hi
, REG(B11_8
), 4);
944 tcg_gen_qemu_st_i32(cpu_fregs
[fr
], REG(B11_8
),
945 ctx
->memidx
, MO_TEUL
);
946 tcg_gen_qemu_st_i32(cpu_fregs
[fr
+1], addr_hi
,
947 ctx
->memidx
, MO_TEUL
);
948 tcg_temp_free(addr_hi
);
950 tcg_gen_qemu_st_i32(cpu_fregs
[FREG(B7_4
)], REG(B11_8
),
951 ctx
->memidx
, MO_TEUL
);
954 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
956 if (ctx
->flags
& FPSCR_SZ
) {
957 TCGv addr_hi
= tcg_temp_new();
958 int fr
= XREG(B11_8
);
959 tcg_gen_addi_i32(addr_hi
, REG(B7_4
), 4);
960 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
], REG(B7_4
), ctx
->memidx
, MO_TEUL
);
961 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
+1], addr_hi
, ctx
->memidx
, MO_TEUL
);
962 tcg_temp_free(addr_hi
);
964 tcg_gen_qemu_ld_i32(cpu_fregs
[FREG(B11_8
)], REG(B7_4
),
965 ctx
->memidx
, MO_TEUL
);
968 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
970 if (ctx
->flags
& FPSCR_SZ
) {
971 TCGv addr_hi
= tcg_temp_new();
972 int fr
= XREG(B11_8
);
973 tcg_gen_addi_i32(addr_hi
, REG(B7_4
), 4);
974 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
], REG(B7_4
), ctx
->memidx
, MO_TEUL
);
975 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
+1], addr_hi
, ctx
->memidx
, MO_TEUL
);
976 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 8);
977 tcg_temp_free(addr_hi
);
979 tcg_gen_qemu_ld_i32(cpu_fregs
[FREG(B11_8
)], REG(B7_4
),
980 ctx
->memidx
, MO_TEUL
);
981 tcg_gen_addi_i32(REG(B7_4
), REG(B7_4
), 4);
984 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
986 TCGv addr
= tcg_temp_new_i32();
987 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
988 if (ctx
->flags
& FPSCR_SZ
) {
990 tcg_gen_qemu_st_i32(cpu_fregs
[fr
+1], addr
, ctx
->memidx
, MO_TEUL
);
991 tcg_gen_subi_i32(addr
, addr
, 4);
992 tcg_gen_qemu_st_i32(cpu_fregs
[fr
], addr
, ctx
->memidx
, MO_TEUL
);
994 tcg_gen_qemu_st_i32(cpu_fregs
[FREG(B7_4
)], addr
,
995 ctx
->memidx
, MO_TEUL
);
997 tcg_gen_mov_i32(REG(B11_8
), addr
);
1000 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1003 TCGv addr
= tcg_temp_new_i32();
1004 tcg_gen_add_i32(addr
, REG(B7_4
), REG(0));
1005 if (ctx
->flags
& FPSCR_SZ
) {
1006 int fr
= XREG(B11_8
);
1007 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
], addr
,
1008 ctx
->memidx
, MO_TEUL
);
1009 tcg_gen_addi_i32(addr
, addr
, 4);
1010 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
+1], addr
,
1011 ctx
->memidx
, MO_TEUL
);
1013 tcg_gen_qemu_ld_i32(cpu_fregs
[FREG(B11_8
)], addr
,
1014 ctx
->memidx
, MO_TEUL
);
1016 tcg_temp_free(addr
);
1019 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1022 TCGv addr
= tcg_temp_new();
1023 tcg_gen_add_i32(addr
, REG(B11_8
), REG(0));
1024 if (ctx
->flags
& FPSCR_SZ
) {
1025 int fr
= XREG(B7_4
);
1026 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
], addr
,
1027 ctx
->memidx
, MO_TEUL
);
1028 tcg_gen_addi_i32(addr
, addr
, 4);
1029 tcg_gen_qemu_ld_i32(cpu_fregs
[fr
+1], addr
,
1030 ctx
->memidx
, MO_TEUL
);
1032 tcg_gen_qemu_st_i32(cpu_fregs
[FREG(B7_4
)], addr
,
1033 ctx
->memidx
, MO_TEUL
);
1035 tcg_temp_free(addr
);
1038 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1039 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1040 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1041 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
1042 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1043 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1046 if (ctx
->flags
& FPSCR_PR
) {
1049 if (ctx
->opcode
& 0x0110)
1050 break; /* illegal instruction */
1051 fp0
= tcg_temp_new_i64();
1052 fp1
= tcg_temp_new_i64();
1053 gen_load_fpr64(fp0
, DREG(B11_8
));
1054 gen_load_fpr64(fp1
, DREG(B7_4
));
1055 switch (ctx
->opcode
& 0xf00f) {
1056 case 0xf000: /* fadd Rm,Rn */
1057 gen_helper_fadd_DT(fp0
, cpu_env
, fp0
, fp1
);
1059 case 0xf001: /* fsub Rm,Rn */
1060 gen_helper_fsub_DT(fp0
, cpu_env
, fp0
, fp1
);
1062 case 0xf002: /* fmul Rm,Rn */
1063 gen_helper_fmul_DT(fp0
, cpu_env
, fp0
, fp1
);
1065 case 0xf003: /* fdiv Rm,Rn */
1066 gen_helper_fdiv_DT(fp0
, cpu_env
, fp0
, fp1
);
1068 case 0xf004: /* fcmp/eq Rm,Rn */
1069 gen_helper_fcmp_eq_DT(cpu_env
, fp0
, fp1
);
1071 case 0xf005: /* fcmp/gt Rm,Rn */
1072 gen_helper_fcmp_gt_DT(cpu_env
, fp0
, fp1
);
1075 gen_store_fpr64(fp0
, DREG(B11_8
));
1076 tcg_temp_free_i64(fp0
);
1077 tcg_temp_free_i64(fp1
);
1079 switch (ctx
->opcode
& 0xf00f) {
1080 case 0xf000: /* fadd Rm,Rn */
1081 gen_helper_fadd_FT(cpu_fregs
[FREG(B11_8
)], cpu_env
,
1082 cpu_fregs
[FREG(B11_8
)],
1083 cpu_fregs
[FREG(B7_4
)]);
1085 case 0xf001: /* fsub Rm,Rn */
1086 gen_helper_fsub_FT(cpu_fregs
[FREG(B11_8
)], cpu_env
,
1087 cpu_fregs
[FREG(B11_8
)],
1088 cpu_fregs
[FREG(B7_4
)]);
1090 case 0xf002: /* fmul Rm,Rn */
1091 gen_helper_fmul_FT(cpu_fregs
[FREG(B11_8
)], cpu_env
,
1092 cpu_fregs
[FREG(B11_8
)],
1093 cpu_fregs
[FREG(B7_4
)]);
1095 case 0xf003: /* fdiv Rm,Rn */
1096 gen_helper_fdiv_FT(cpu_fregs
[FREG(B11_8
)], cpu_env
,
1097 cpu_fregs
[FREG(B11_8
)],
1098 cpu_fregs
[FREG(B7_4
)]);
1100 case 0xf004: /* fcmp/eq Rm,Rn */
1101 gen_helper_fcmp_eq_FT(cpu_env
, cpu_fregs
[FREG(B11_8
)],
1102 cpu_fregs
[FREG(B7_4
)]);
1104 case 0xf005: /* fcmp/gt Rm,Rn */
1105 gen_helper_fcmp_gt_FT(cpu_env
, cpu_fregs
[FREG(B11_8
)],
1106 cpu_fregs
[FREG(B7_4
)]);
1112 case 0xf00e: /* fmac FR0,RM,Rn */
1115 if (ctx
->flags
& FPSCR_PR
) {
1116 break; /* illegal instruction */
1118 gen_helper_fmac_FT(cpu_fregs
[FREG(B11_8
)], cpu_env
,
1119 cpu_fregs
[FREG(0)], cpu_fregs
[FREG(B7_4
)],
1120 cpu_fregs
[FREG(B11_8
)]);
1126 switch (ctx
->opcode
& 0xff00) {
1127 case 0xc900: /* and #imm,R0 */
1128 tcg_gen_andi_i32(REG(0), REG(0), B7_0
);
1130 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1133 addr
= tcg_temp_new();
1134 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1135 val
= tcg_temp_new();
1136 tcg_gen_qemu_ld_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1137 tcg_gen_andi_i32(val
, val
, B7_0
);
1138 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1140 tcg_temp_free(addr
);
1143 case 0x8b00: /* bf label */
1144 CHECK_NOT_DELAY_SLOT
1145 gen_conditional_jump(ctx
, ctx
->pc
+ 2,
1146 ctx
->pc
+ 4 + B7_0s
* 2);
1147 ctx
->bstate
= BS_BRANCH
;
1149 case 0x8f00: /* bf/s label */
1150 CHECK_NOT_DELAY_SLOT
1151 gen_branch_slot(ctx
->delayed_pc
= ctx
->pc
+ 4 + B7_0s
* 2, 0);
1152 ctx
->flags
|= DELAY_SLOT_CONDITIONAL
;
1154 case 0x8900: /* bt label */
1155 CHECK_NOT_DELAY_SLOT
1156 gen_conditional_jump(ctx
, ctx
->pc
+ 4 + B7_0s
* 2,
1158 ctx
->bstate
= BS_BRANCH
;
1160 case 0x8d00: /* bt/s label */
1161 CHECK_NOT_DELAY_SLOT
1162 gen_branch_slot(ctx
->delayed_pc
= ctx
->pc
+ 4 + B7_0s
* 2, 1);
1163 ctx
->flags
|= DELAY_SLOT_CONDITIONAL
;
1165 case 0x8800: /* cmp/eq #imm,R0 */
1166 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, REG(0), B7_0s
);
1168 case 0xc400: /* mov.b @(disp,GBR),R0 */
1170 TCGv addr
= tcg_temp_new();
1171 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
);
1172 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_SB
);
1173 tcg_temp_free(addr
);
1176 case 0xc500: /* mov.w @(disp,GBR),R0 */
1178 TCGv addr
= tcg_temp_new();
1179 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 2);
1180 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_TESW
);
1181 tcg_temp_free(addr
);
1184 case 0xc600: /* mov.l @(disp,GBR),R0 */
1186 TCGv addr
= tcg_temp_new();
1187 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 4);
1188 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_TESL
);
1189 tcg_temp_free(addr
);
1192 case 0xc000: /* mov.b R0,@(disp,GBR) */
1194 TCGv addr
= tcg_temp_new();
1195 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
);
1196 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_UB
);
1197 tcg_temp_free(addr
);
1200 case 0xc100: /* mov.w R0,@(disp,GBR) */
1202 TCGv addr
= tcg_temp_new();
1203 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 2);
1204 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_TEUW
);
1205 tcg_temp_free(addr
);
1208 case 0xc200: /* mov.l R0,@(disp,GBR) */
1210 TCGv addr
= tcg_temp_new();
1211 tcg_gen_addi_i32(addr
, cpu_gbr
, B7_0
* 4);
1212 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_TEUL
);
1213 tcg_temp_free(addr
);
1216 case 0x8000: /* mov.b R0,@(disp,Rn) */
1218 TCGv addr
= tcg_temp_new();
1219 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
);
1220 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_UB
);
1221 tcg_temp_free(addr
);
1224 case 0x8100: /* mov.w R0,@(disp,Rn) */
1226 TCGv addr
= tcg_temp_new();
1227 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 2);
1228 tcg_gen_qemu_st_i32(REG(0), addr
, ctx
->memidx
, MO_TEUW
);
1229 tcg_temp_free(addr
);
1232 case 0x8400: /* mov.b @(disp,Rn),R0 */
1234 TCGv addr
= tcg_temp_new();
1235 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
);
1236 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_SB
);
1237 tcg_temp_free(addr
);
1240 case 0x8500: /* mov.w @(disp,Rn),R0 */
1242 TCGv addr
= tcg_temp_new();
1243 tcg_gen_addi_i32(addr
, REG(B7_4
), B3_0
* 2);
1244 tcg_gen_qemu_ld_i32(REG(0), addr
, ctx
->memidx
, MO_TESW
);
1245 tcg_temp_free(addr
);
1248 case 0xc700: /* mova @(disp,PC),R0 */
1249 tcg_gen_movi_i32(REG(0), ((ctx
->pc
& 0xfffffffc) + 4 + B7_0
* 4) & ~3);
1251 case 0xcb00: /* or #imm,R0 */
1252 tcg_gen_ori_i32(REG(0), REG(0), B7_0
);
1254 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1257 addr
= tcg_temp_new();
1258 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1259 val
= tcg_temp_new();
1260 tcg_gen_qemu_ld_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1261 tcg_gen_ori_i32(val
, val
, B7_0
);
1262 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1264 tcg_temp_free(addr
);
1267 case 0xc300: /* trapa #imm */
1270 CHECK_NOT_DELAY_SLOT
1271 tcg_gen_movi_i32(cpu_pc
, ctx
->pc
);
1272 imm
= tcg_const_i32(B7_0
);
1273 gen_helper_trapa(cpu_env
, imm
);
1275 ctx
->bstate
= BS_BRANCH
;
1278 case 0xc800: /* tst #imm,R0 */
1280 TCGv val
= tcg_temp_new();
1281 tcg_gen_andi_i32(val
, REG(0), B7_0
);
1282 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
1286 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1288 TCGv val
= tcg_temp_new();
1289 tcg_gen_add_i32(val
, REG(0), cpu_gbr
);
1290 tcg_gen_qemu_ld_i32(val
, val
, ctx
->memidx
, MO_UB
);
1291 tcg_gen_andi_i32(val
, val
, B7_0
);
1292 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
1296 case 0xca00: /* xor #imm,R0 */
1297 tcg_gen_xori_i32(REG(0), REG(0), B7_0
);
1299 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1302 addr
= tcg_temp_new();
1303 tcg_gen_add_i32(addr
, REG(0), cpu_gbr
);
1304 val
= tcg_temp_new();
1305 tcg_gen_qemu_ld_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1306 tcg_gen_xori_i32(val
, val
, B7_0
);
1307 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1309 tcg_temp_free(addr
);
1314 switch (ctx
->opcode
& 0xf08f) {
1315 case 0x408e: /* ldc Rm,Rn_BANK */
1317 tcg_gen_mov_i32(ALTREG(B6_4
), REG(B11_8
));
1319 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1321 tcg_gen_qemu_ld_i32(ALTREG(B6_4
), REG(B11_8
), ctx
->memidx
, MO_TESL
);
1322 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1324 case 0x0082: /* stc Rm_BANK,Rn */
1326 tcg_gen_mov_i32(REG(B11_8
), ALTREG(B6_4
));
1328 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1331 TCGv addr
= tcg_temp_new();
1332 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1333 tcg_gen_qemu_st_i32(ALTREG(B6_4
), addr
, ctx
->memidx
, MO_TEUL
);
1334 tcg_gen_mov_i32(REG(B11_8
), addr
);
1335 tcg_temp_free(addr
);
1340 switch (ctx
->opcode
& 0xf0ff) {
1341 case 0x0023: /* braf Rn */
1342 CHECK_NOT_DELAY_SLOT
1343 tcg_gen_addi_i32(cpu_delayed_pc
, REG(B11_8
), ctx
->pc
+ 4);
1344 ctx
->flags
|= DELAY_SLOT
;
1345 ctx
->delayed_pc
= (uint32_t) - 1;
1347 case 0x0003: /* bsrf Rn */
1348 CHECK_NOT_DELAY_SLOT
1349 tcg_gen_movi_i32(cpu_pr
, ctx
->pc
+ 4);
1350 tcg_gen_add_i32(cpu_delayed_pc
, REG(B11_8
), cpu_pr
);
1351 ctx
->flags
|= DELAY_SLOT
;
1352 ctx
->delayed_pc
= (uint32_t) - 1;
1354 case 0x4015: /* cmp/pl Rn */
1355 tcg_gen_setcondi_i32(TCG_COND_GT
, cpu_sr_t
, REG(B11_8
), 0);
1357 case 0x4011: /* cmp/pz Rn */
1358 tcg_gen_setcondi_i32(TCG_COND_GE
, cpu_sr_t
, REG(B11_8
), 0);
1360 case 0x4010: /* dt Rn */
1361 tcg_gen_subi_i32(REG(B11_8
), REG(B11_8
), 1);
1362 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, REG(B11_8
), 0);
1364 case 0x402b: /* jmp @Rn */
1365 CHECK_NOT_DELAY_SLOT
1366 tcg_gen_mov_i32(cpu_delayed_pc
, REG(B11_8
));
1367 ctx
->flags
|= DELAY_SLOT
;
1368 ctx
->delayed_pc
= (uint32_t) - 1;
1370 case 0x400b: /* jsr @Rn */
1371 CHECK_NOT_DELAY_SLOT
1372 tcg_gen_movi_i32(cpu_pr
, ctx
->pc
+ 4);
1373 tcg_gen_mov_i32(cpu_delayed_pc
, REG(B11_8
));
1374 ctx
->flags
|= DELAY_SLOT
;
1375 ctx
->delayed_pc
= (uint32_t) - 1;
1377 case 0x400e: /* ldc Rm,SR */
1380 TCGv val
= tcg_temp_new();
1381 tcg_gen_andi_i32(val
, REG(B11_8
), 0x700083f3);
1384 ctx
->bstate
= BS_STOP
;
1387 case 0x4007: /* ldc.l @Rm+,SR */
1390 TCGv val
= tcg_temp_new();
1391 tcg_gen_qemu_ld_i32(val
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
1392 tcg_gen_andi_i32(val
, val
, 0x700083f3);
1395 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1396 ctx
->bstate
= BS_STOP
;
1399 case 0x0002: /* stc SR,Rn */
1401 gen_read_sr(REG(B11_8
));
1403 case 0x4003: /* stc SR,@-Rn */
1406 TCGv addr
= tcg_temp_new();
1407 TCGv val
= tcg_temp_new();
1408 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1410 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_TEUL
);
1411 tcg_gen_mov_i32(REG(B11_8
), addr
);
1413 tcg_temp_free(addr
);
1416 #define LD(reg,ldnum,ldpnum,prechk) \
1419 tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \
1423 tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1424 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \
1426 #define ST(reg,stnum,stpnum,prechk) \
1429 tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \
1434 TCGv addr = tcg_temp_new(); \
1435 tcg_gen_subi_i32(addr, REG(B11_8), 4); \
1436 tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1437 tcg_gen_mov_i32(REG(B11_8), addr); \
1438 tcg_temp_free(addr); \
1441 #define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk) \
1442 LD(reg,ldnum,ldpnum,prechk) \
1443 ST(reg,stnum,stpnum,prechk)
1444 LDST(gbr
, 0x401e, 0x4017, 0x0012, 0x4013, {})
1445 LDST(vbr
, 0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED
)
1446 LDST(ssr
, 0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED
)
1447 LDST(spc
, 0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED
)
1448 ST(sgr
, 0x003a, 0x4032, CHECK_PRIVILEGED
)
1449 LD(sgr
, 0x403a, 0x4036, CHECK_PRIVILEGED
if (!(ctx
->features
& SH_FEATURE_SH4A
)) break;)
1450 LDST(dbr
, 0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED
)
1451 LDST(mach
, 0x400a, 0x4006, 0x000a, 0x4002, {})
1452 LDST(macl
, 0x401a, 0x4016, 0x001a, 0x4012, {})
1453 LDST(pr
, 0x402a, 0x4026, 0x002a, 0x4022, {})
1454 LDST(fpul
, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED
})
1455 case 0x406a: /* lds Rm,FPSCR */
1457 gen_helper_ld_fpscr(cpu_env
, REG(B11_8
));
1458 ctx
->bstate
= BS_STOP
;
1460 case 0x4066: /* lds.l @Rm+,FPSCR */
1463 TCGv addr
= tcg_temp_new();
1464 tcg_gen_qemu_ld_i32(addr
, REG(B11_8
), ctx
->memidx
, MO_TESL
);
1465 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1466 gen_helper_ld_fpscr(cpu_env
, addr
);
1467 tcg_temp_free(addr
);
1468 ctx
->bstate
= BS_STOP
;
1471 case 0x006a: /* sts FPSCR,Rn */
1473 tcg_gen_andi_i32(REG(B11_8
), cpu_fpscr
, 0x003fffff);
1475 case 0x4062: /* sts FPSCR,@-Rn */
1479 val
= tcg_temp_new();
1480 tcg_gen_andi_i32(val
, cpu_fpscr
, 0x003fffff);
1481 addr
= tcg_temp_new();
1482 tcg_gen_subi_i32(addr
, REG(B11_8
), 4);
1483 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_TEUL
);
1484 tcg_gen_mov_i32(REG(B11_8
), addr
);
1485 tcg_temp_free(addr
);
1489 case 0x00c3: /* movca.l R0,@Rm */
1491 TCGv val
= tcg_temp_new();
1492 tcg_gen_qemu_ld_i32(val
, REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1493 gen_helper_movcal(cpu_env
, REG(B11_8
), val
);
1494 tcg_gen_qemu_st_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1496 ctx
->has_movcal
= 1;
1499 /* MOVUA.L @Rm,R0 (Rm) -> R0
1500 Load non-boundary-aligned data */
1501 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1504 /* MOVUA.L @Rm+,R0 (Rm) -> R0, Rm + 4 -> Rm
1505 Load non-boundary-aligned data */
1506 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1507 tcg_gen_addi_i32(REG(B11_8
), REG(B11_8
), 4);
1509 case 0x0029: /* movt Rn */
1510 tcg_gen_mov_i32(REG(B11_8
), cpu_sr_t
);
1515 If (T == 1) R0 -> (Rn)
1518 if (ctx
->features
& SH_FEATURE_SH4A
) {
1519 TCGLabel
*label
= gen_new_label();
1520 tcg_gen_mov_i32(cpu_sr_t
, cpu_ldst
);
1521 tcg_gen_brcondi_i32(TCG_COND_EQ
, cpu_ldst
, 0, label
);
1522 tcg_gen_qemu_st_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TEUL
);
1523 gen_set_label(label
);
1524 tcg_gen_movi_i32(cpu_ldst
, 0);
1532 When interrupt/exception
1535 if (ctx
->features
& SH_FEATURE_SH4A
) {
1536 tcg_gen_movi_i32(cpu_ldst
, 0);
1537 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8
), ctx
->memidx
, MO_TESL
);
1538 tcg_gen_movi_i32(cpu_ldst
, 1);
1542 case 0x0093: /* ocbi @Rn */
1544 gen_helper_ocbi(cpu_env
, REG(B11_8
));
1547 case 0x00a3: /* ocbp @Rn */
1548 case 0x00b3: /* ocbwb @Rn */
1549 /* These instructions are supposed to do nothing in case of
1550 a cache miss. Given that we only partially emulate caches
1551 it is safe to simply ignore them. */
1553 case 0x0083: /* pref @Rn */
1555 case 0x00d3: /* prefi @Rn */
1556 if (ctx
->features
& SH_FEATURE_SH4A
)
1560 case 0x00e3: /* icbi @Rn */
1561 if (ctx
->features
& SH_FEATURE_SH4A
)
1565 case 0x00ab: /* synco */
1566 if (ctx
->features
& SH_FEATURE_SH4A
)
1570 case 0x4024: /* rotcl Rn */
1572 TCGv tmp
= tcg_temp_new();
1573 tcg_gen_mov_i32(tmp
, cpu_sr_t
);
1574 tcg_gen_shri_i32(cpu_sr_t
, REG(B11_8
), 31);
1575 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1576 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), tmp
);
1580 case 0x4025: /* rotcr Rn */
1582 TCGv tmp
= tcg_temp_new();
1583 tcg_gen_shli_i32(tmp
, cpu_sr_t
, 31);
1584 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1585 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1586 tcg_gen_or_i32(REG(B11_8
), REG(B11_8
), tmp
);
1590 case 0x4004: /* rotl Rn */
1591 tcg_gen_rotli_i32(REG(B11_8
), REG(B11_8
), 1);
1592 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 0);
1594 case 0x4005: /* rotr Rn */
1595 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 0);
1596 tcg_gen_rotri_i32(REG(B11_8
), REG(B11_8
), 1);
1598 case 0x4000: /* shll Rn */
1599 case 0x4020: /* shal Rn */
1600 tcg_gen_shri_i32(cpu_sr_t
, REG(B11_8
), 31);
1601 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 1);
1603 case 0x4021: /* shar Rn */
1604 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1605 tcg_gen_sari_i32(REG(B11_8
), REG(B11_8
), 1);
1607 case 0x4001: /* shlr Rn */
1608 tcg_gen_andi_i32(cpu_sr_t
, REG(B11_8
), 1);
1609 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 1);
1611 case 0x4008: /* shll2 Rn */
1612 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 2);
1614 case 0x4018: /* shll8 Rn */
1615 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 8);
1617 case 0x4028: /* shll16 Rn */
1618 tcg_gen_shli_i32(REG(B11_8
), REG(B11_8
), 16);
1620 case 0x4009: /* shlr2 Rn */
1621 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 2);
1623 case 0x4019: /* shlr8 Rn */
1624 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 8);
1626 case 0x4029: /* shlr16 Rn */
1627 tcg_gen_shri_i32(REG(B11_8
), REG(B11_8
), 16);
1629 case 0x401b: /* tas.b @Rn */
1632 addr
= tcg_temp_local_new();
1633 tcg_gen_mov_i32(addr
, REG(B11_8
));
1634 val
= tcg_temp_local_new();
1635 tcg_gen_qemu_ld_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1636 tcg_gen_setcondi_i32(TCG_COND_EQ
, cpu_sr_t
, val
, 0);
1637 tcg_gen_ori_i32(val
, val
, 0x80);
1638 tcg_gen_qemu_st_i32(val
, addr
, ctx
->memidx
, MO_UB
);
1640 tcg_temp_free(addr
);
1643 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1645 tcg_gen_mov_i32(cpu_fregs
[FREG(B11_8
)], cpu_fpul
);
1647 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1649 tcg_gen_mov_i32(cpu_fpul
, cpu_fregs
[FREG(B11_8
)]);
1651 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1653 if (ctx
->flags
& FPSCR_PR
) {
1655 if (ctx
->opcode
& 0x0100)
1656 break; /* illegal instruction */
1657 fp
= tcg_temp_new_i64();
1658 gen_helper_float_DT(fp
, cpu_env
, cpu_fpul
);
1659 gen_store_fpr64(fp
, DREG(B11_8
));
1660 tcg_temp_free_i64(fp
);
1663 gen_helper_float_FT(cpu_fregs
[FREG(B11_8
)], cpu_env
, cpu_fpul
);
1666 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1668 if (ctx
->flags
& FPSCR_PR
) {
1670 if (ctx
->opcode
& 0x0100)
1671 break; /* illegal instruction */
1672 fp
= tcg_temp_new_i64();
1673 gen_load_fpr64(fp
, DREG(B11_8
));
1674 gen_helper_ftrc_DT(cpu_fpul
, cpu_env
, fp
);
1675 tcg_temp_free_i64(fp
);
1678 gen_helper_ftrc_FT(cpu_fpul
, cpu_env
, cpu_fregs
[FREG(B11_8
)]);
1681 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1684 gen_helper_fneg_T(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)]);
1687 case 0xf05d: /* fabs FRn/DRn */
1689 if (ctx
->flags
& FPSCR_PR
) {
1690 if (ctx
->opcode
& 0x0100)
1691 break; /* illegal instruction */
1692 TCGv_i64 fp
= tcg_temp_new_i64();
1693 gen_load_fpr64(fp
, DREG(B11_8
));
1694 gen_helper_fabs_DT(fp
, fp
);
1695 gen_store_fpr64(fp
, DREG(B11_8
));
1696 tcg_temp_free_i64(fp
);
1698 gen_helper_fabs_FT(cpu_fregs
[FREG(B11_8
)], cpu_fregs
[FREG(B11_8
)]);
1701 case 0xf06d: /* fsqrt FRn */
1703 if (ctx
->flags
& FPSCR_PR
) {
1704 if (ctx
->opcode
& 0x0100)
1705 break; /* illegal instruction */
1706 TCGv_i64 fp
= tcg_temp_new_i64();
1707 gen_load_fpr64(fp
, DREG(B11_8
));
1708 gen_helper_fsqrt_DT(fp
, cpu_env
, fp
);
1709 gen_store_fpr64(fp
, DREG(B11_8
));
1710 tcg_temp_free_i64(fp
);
1712 gen_helper_fsqrt_FT(cpu_fregs
[FREG(B11_8
)], cpu_env
,
1713 cpu_fregs
[FREG(B11_8
)]);
1716 case 0xf07d: /* fsrra FRn */
1719 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1721 if (!(ctx
->flags
& FPSCR_PR
)) {
1722 tcg_gen_movi_i32(cpu_fregs
[FREG(B11_8
)], 0);
1725 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1727 if (!(ctx
->flags
& FPSCR_PR
)) {
1728 tcg_gen_movi_i32(cpu_fregs
[FREG(B11_8
)], 0x3f800000);
1731 case 0xf0ad: /* fcnvsd FPUL,DRn */
1734 TCGv_i64 fp
= tcg_temp_new_i64();
1735 gen_helper_fcnvsd_FT_DT(fp
, cpu_env
, cpu_fpul
);
1736 gen_store_fpr64(fp
, DREG(B11_8
));
1737 tcg_temp_free_i64(fp
);
1740 case 0xf0bd: /* fcnvds DRn,FPUL */
1743 TCGv_i64 fp
= tcg_temp_new_i64();
1744 gen_load_fpr64(fp
, DREG(B11_8
));
1745 gen_helper_fcnvds_DT_FT(cpu_fpul
, cpu_env
, fp
);
1746 tcg_temp_free_i64(fp
);
1749 case 0xf0ed: /* fipr FVm,FVn */
1751 if ((ctx
->flags
& FPSCR_PR
) == 0) {
1753 m
= tcg_const_i32((ctx
->opcode
>> 8) & 3);
1754 n
= tcg_const_i32((ctx
->opcode
>> 10) & 3);
1755 gen_helper_fipr(cpu_env
, m
, n
);
1761 case 0xf0fd: /* ftrv XMTRX,FVn */
1763 if ((ctx
->opcode
& 0x0300) == 0x0100 &&
1764 (ctx
->flags
& FPSCR_PR
) == 0) {
1766 n
= tcg_const_i32((ctx
->opcode
>> 10) & 3);
1767 gen_helper_ftrv(cpu_env
, n
);
1774 fprintf(stderr
, "unknown instruction 0x%04x at pc 0x%08x\n",
1775 ctx
->opcode
, ctx
->pc
);
1778 tcg_gen_movi_i32(cpu_pc
, ctx
->pc
);
1779 if (ctx
->flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
)) {
1780 gen_helper_raise_slot_illegal_instruction(cpu_env
);
1782 gen_helper_raise_illegal_instruction(cpu_env
);
1784 ctx
->bstate
= BS_BRANCH
;
1787 static void decode_opc(DisasContext
* ctx
)
1789 uint32_t old_flags
= ctx
->flags
;
1793 if (old_flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
)) {
1794 if (ctx
->flags
& DELAY_SLOT_CLEARME
) {
1797 /* go out of the delay slot */
1798 uint32_t new_flags
= ctx
->flags
;
1799 new_flags
&= ~(DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
);
1800 gen_store_flags(new_flags
);
1803 ctx
->bstate
= BS_BRANCH
;
1804 if (old_flags
& DELAY_SLOT_CONDITIONAL
) {
1805 gen_delayed_conditional_jump(ctx
);
1806 } else if (old_flags
& DELAY_SLOT
) {
1812 /* go into a delay slot */
1813 if (ctx
->flags
& (DELAY_SLOT
| DELAY_SLOT_CONDITIONAL
))
1814 gen_store_flags(ctx
->flags
);
1817 void gen_intermediate_code(CPUSH4State
* env
, struct TranslationBlock
*tb
)
1819 SuperHCPU
*cpu
= sh_env_get_cpu(env
);
1820 CPUState
*cs
= CPU(cpu
);
1822 target_ulong pc_start
;
1828 ctx
.flags
= (uint32_t)tb
->flags
;
1829 ctx
.bstate
= BS_NONE
;
1830 ctx
.memidx
= (ctx
.flags
& (1u << SR_MD
)) == 0 ? 1 : 0;
1831 /* We don't know if the delayed pc came from a dynamic or static branch,
1832 so assume it is a dynamic branch. */
1833 ctx
.delayed_pc
= -1; /* use delayed pc from env pointer */
1835 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
1836 ctx
.features
= env
->features
;
1837 ctx
.has_movcal
= (ctx
.flags
& TB_FLAG_PENDING_MOVCA
);
1840 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
1841 if (max_insns
== 0) {
1842 max_insns
= CF_COUNT_MASK
;
1844 if (max_insns
> TCG_MAX_INSNS
) {
1845 max_insns
= TCG_MAX_INSNS
;
1849 while (ctx
.bstate
== BS_NONE
&& !tcg_op_buf_full()) {
1850 tcg_gen_insn_start(ctx
.pc
, ctx
.flags
);
1853 if (unlikely(cpu_breakpoint_test(cs
, ctx
.pc
, BP_ANY
))) {
1854 /* We have hit a breakpoint - make sure PC is up-to-date */
1855 tcg_gen_movi_i32(cpu_pc
, ctx
.pc
);
1856 gen_helper_debug(cpu_env
);
1857 ctx
.bstate
= BS_BRANCH
;
1861 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
1865 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
1868 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
1870 if (cs
->singlestep_enabled
) {
1873 if (num_insns
>= max_insns
)
1878 if (tb
->cflags
& CF_LAST_IO
)
1880 if (cs
->singlestep_enabled
) {
1881 tcg_gen_movi_i32(cpu_pc
, ctx
.pc
);
1882 gen_helper_debug(cpu_env
);
1884 switch (ctx
.bstate
) {
1886 /* gen_op_interrupt_restart(); */
1890 gen_store_flags(ctx
.flags
| DELAY_SLOT_CLEARME
);
1892 gen_goto_tb(&ctx
, 0, ctx
.pc
);
1895 /* gen_op_interrupt_restart(); */
1904 gen_tb_end(tb
, num_insns
);
1906 tb
->size
= ctx
.pc
- pc_start
;
1907 tb
->icount
= num_insns
;
1910 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
1911 qemu_log("IN:\n"); /* , lookup_symbol(pc_start)); */
1912 log_target_disas(cs
, pc_start
, ctx
.pc
- pc_start
, 0);
1918 void restore_state_to_opc(CPUSH4State
*env
, TranslationBlock
*tb
,
1922 env
->flags
= data
[1];