Display TCGCond name in tcg dumper (original patch by Tristan Gingold)
[qemu/mini2440.git] / target-sh4 / translate.c
blob8e97696e683d2d982fc861e9f828437908662019
1 /*
2 * SH4 translation
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <assert.h>
27 #define DEBUG_DISAS
28 #define SH4_DEBUG_DISAS
29 //#define SH4_SINGLE_STEP
31 #include "cpu.h"
32 #include "exec-all.h"
33 #include "disas.h"
34 #include "helper.h"
35 #include "tcg-op.h"
36 #include "qemu-common.h"
38 typedef struct DisasContext {
39 struct TranslationBlock *tb;
40 target_ulong pc;
41 uint32_t sr;
42 uint32_t fpscr;
43 uint16_t opcode;
44 uint32_t flags;
45 int bstate;
46 int memidx;
47 uint32_t delayed_pc;
48 int singlestep_enabled;
49 } DisasContext;
51 enum {
52 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
53 * exception condition
55 BS_STOP = 1, /* We want to stop translation for any reason */
56 BS_BRANCH = 2, /* We reached a branch condition */
57 BS_EXCP = 3, /* We reached an exception condition */
60 /* global register indexes */
61 static TCGv cpu_env;
62 static TCGv cpu_gregs[24];
63 static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64 static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65 static TCGv cpu_pr, cpu_fpscr, cpu_fpul, cpu_flags;
67 /* internal register indexes */
68 static TCGv cpu_flags, cpu_delayed_pc;
70 #include "gen-icount.h"
72 static void sh4_translate_init(void)
74 int i;
75 static int done_init = 0;
76 static const char * const gregnames[24] = {
77 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
78 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
79 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
80 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
81 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
84 if (done_init)
85 return;
87 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
89 for (i = 0; i < 24; i++)
90 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
91 offsetof(CPUState, gregs[i]),
92 gregnames[i]);
94 cpu_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
95 offsetof(CPUState, pc), "PC");
96 cpu_sr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
97 offsetof(CPUState, sr), "SR");
98 cpu_ssr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
99 offsetof(CPUState, ssr), "SSR");
100 cpu_spc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
101 offsetof(CPUState, spc), "SPC");
102 cpu_gbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
103 offsetof(CPUState, gbr), "GBR");
104 cpu_vbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
105 offsetof(CPUState, vbr), "VBR");
106 cpu_sgr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
107 offsetof(CPUState, sgr), "SGR");
108 cpu_dbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
109 offsetof(CPUState, dbr), "DBR");
110 cpu_mach = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
111 offsetof(CPUState, mach), "MACH");
112 cpu_macl = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
113 offsetof(CPUState, macl), "MACL");
114 cpu_pr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
115 offsetof(CPUState, pr), "PR");
116 cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
117 offsetof(CPUState, fpscr), "FPSCR");
118 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
119 offsetof(CPUState, fpul), "FPUL");
121 cpu_flags = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
122 offsetof(CPUState, flags), "_flags_");
123 cpu_delayed_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
124 offsetof(CPUState, delayed_pc),
125 "_delayed_pc_");
127 /* register helpers */
128 #undef DEF_HELPER
129 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
130 #include "helper.h"
132 done_init = 1;
135 void cpu_dump_state(CPUState * env, FILE * f,
136 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
137 int flags)
139 int i;
140 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
141 env->pc, env->sr, env->pr, env->fpscr);
142 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
143 env->spc, env->ssr, env->gbr, env->vbr);
144 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
145 env->sgr, env->dbr, env->delayed_pc, env->fpul);
146 for (i = 0; i < 24; i += 4) {
147 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
148 i, env->gregs[i], i + 1, env->gregs[i + 1],
149 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
151 if (env->flags & DELAY_SLOT) {
152 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
153 env->delayed_pc);
154 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
155 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
156 env->delayed_pc);
160 void cpu_sh4_reset(CPUSH4State * env)
162 #if defined(CONFIG_USER_ONLY)
163 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
164 #else
165 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
166 #endif
167 env->vbr = 0;
168 env->pc = 0xA0000000;
169 #if defined(CONFIG_USER_ONLY)
170 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
171 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
172 #else
173 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
174 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
175 #endif
176 env->mmucr = 0;
179 typedef struct {
180 const unsigned char *name;
181 int id;
182 uint32_t pvr;
183 uint32_t prr;
184 uint32_t cvr;
185 } sh4_def_t;
187 static sh4_def_t sh4_defs[] = {
189 .name = "SH7750R",
190 .id = SH_CPU_SH7750R,
191 .pvr = 0x00050000,
192 .prr = 0x00000100,
193 .cvr = 0x00110000,
194 }, {
195 .name = "SH7751R",
196 .id = SH_CPU_SH7751R,
197 .pvr = 0x04050005,
198 .prr = 0x00000113,
199 .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */
203 static const sh4_def_t *cpu_sh4_find_by_name(const unsigned char *name)
205 int i;
207 if (strcasecmp(name, "any") == 0)
208 return &sh4_defs[0];
210 for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
211 if (strcasecmp(name, sh4_defs[i].name) == 0)
212 return &sh4_defs[i];
214 return NULL;
217 void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
219 int i;
221 for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
222 (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
225 static int cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
227 env->pvr = def->pvr;
228 env->prr = def->prr;
229 env->cvr = def->cvr;
230 env->id = def->id;
233 CPUSH4State *cpu_sh4_init(const char *cpu_model)
235 CPUSH4State *env;
236 const sh4_def_t *def;
238 def = cpu_sh4_find_by_name(cpu_model);
239 if (!def)
240 return NULL;
241 env = qemu_mallocz(sizeof(CPUSH4State));
242 if (!env)
243 return NULL;
244 cpu_exec_init(env);
245 sh4_translate_init();
246 cpu_sh4_reset(env);
247 cpu_sh4_register(env, def);
248 tlb_flush(env, 1);
249 return env;
252 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
254 TranslationBlock *tb;
255 tb = ctx->tb;
257 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
258 !ctx->singlestep_enabled) {
259 /* Use a direct jump if in same page and singlestep not enabled */
260 tcg_gen_goto_tb(n);
261 tcg_gen_movi_i32(cpu_pc, dest);
262 tcg_gen_exit_tb((long) tb + n);
263 } else {
264 tcg_gen_movi_i32(cpu_pc, dest);
265 if (ctx->singlestep_enabled)
266 tcg_gen_helper_0_0(helper_debug);
267 tcg_gen_exit_tb(0);
271 static void gen_jump(DisasContext * ctx)
273 if (ctx->delayed_pc == (uint32_t) - 1) {
274 /* Target is not statically known, it comes necessarily from a
275 delayed jump as immediate jump are conditinal jumps */
276 tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
277 if (ctx->singlestep_enabled)
278 tcg_gen_helper_0_0(helper_debug);
279 tcg_gen_exit_tb(0);
280 } else {
281 gen_goto_tb(ctx, 0, ctx->delayed_pc);
285 static inline void gen_branch_slot(uint32_t delayed_pc, int t)
287 TCGv sr;
288 int label = gen_new_label();
289 tcg_gen_movi_i32(cpu_delayed_pc, delayed_pc);
290 sr = tcg_temp_new(TCG_TYPE_I32);
291 tcg_gen_andi_i32(sr, cpu_sr, SR_T);
292 tcg_gen_brcondi_i32(TCG_COND_NE, sr, t ? SR_T : 0, label);
293 tcg_gen_ori_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
294 gen_set_label(label);
297 /* Immediate conditional jump (bt or bf) */
298 static void gen_conditional_jump(DisasContext * ctx,
299 target_ulong ift, target_ulong ifnott)
301 int l1;
302 TCGv sr;
304 l1 = gen_new_label();
305 sr = tcg_temp_new(TCG_TYPE_I32);
306 tcg_gen_andi_i32(sr, cpu_sr, SR_T);
307 tcg_gen_brcondi_i32(TCG_COND_EQ, sr, SR_T, l1);
308 gen_goto_tb(ctx, 0, ifnott);
309 gen_set_label(l1);
310 gen_goto_tb(ctx, 1, ift);
313 /* Delayed conditional jump (bt or bf) */
314 static void gen_delayed_conditional_jump(DisasContext * ctx)
316 int l1;
317 TCGv ds;
319 l1 = gen_new_label();
320 ds = tcg_temp_new(TCG_TYPE_I32);
321 tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);
322 tcg_gen_brcondi_i32(TCG_COND_EQ, ds, DELAY_SLOT_TRUE, l1);
323 gen_goto_tb(ctx, 1, ctx->pc + 2);
324 gen_set_label(l1);
325 tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);
326 gen_jump(ctx);
329 static inline void gen_set_t(void)
331 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
334 static inline void gen_clr_t(void)
336 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
339 static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
341 int label1 = gen_new_label();
342 int label2 = gen_new_label();
343 tcg_gen_brcond_i32(cond, t1, t0, label1);
344 gen_clr_t();
345 tcg_gen_br(label2);
346 gen_set_label(label1);
347 gen_set_t();
348 gen_set_label(label2);
351 static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
353 int label1 = gen_new_label();
354 int label2 = gen_new_label();
355 tcg_gen_brcondi_i32(cond, t0, imm, label1);
356 gen_clr_t();
357 tcg_gen_br(label2);
358 gen_set_label(label1);
359 gen_set_t();
360 gen_set_label(label2);
363 static inline void gen_store_flags(uint32_t flags)
365 tcg_gen_andi_i32(cpu_flags, cpu_flags, DELAY_SLOT_TRUE);
366 tcg_gen_ori_i32(cpu_flags, cpu_flags, flags);
369 static inline void gen_copy_bit_i32(TCGv t0, int p0, TCGv t1, int p1)
371 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
373 p0 &= 0x1f;
374 p1 &= 0x1f;
376 tcg_gen_andi_i32(tmp, t1, (1 << p1));
377 tcg_gen_andi_i32(t0, t0, ~(1 << p0));
378 if (p0 < p1)
379 tcg_gen_shri_i32(tmp, tmp, p1 - p0);
380 else if (p0 > p1)
381 tcg_gen_shli_i32(tmp, tmp, p0 - p1);
382 tcg_gen_or_i32(t0, t0, tmp);
384 tcg_temp_free(tmp);
388 static inline void gen_load_fpr32(TCGv t, int reg)
390 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
393 static inline void gen_load_fpr64(TCGv t, int reg)
395 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I32);
396 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
398 tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg]));
399 tcg_gen_extu_i32_i64(t, tmp1);
400 tcg_gen_shli_i64(t, t, 32);
401 tcg_gen_ld_i32(tmp1, cpu_env, offsetof(CPUState, fregs[reg + 1]));
402 tcg_gen_extu_i32_i64(tmp2, tmp1);
403 tcg_temp_free(tmp1);
404 tcg_gen_or_i64(t, t, tmp2);
405 tcg_temp_free(tmp2);
408 static inline void gen_store_fpr32(TCGv t, int reg)
410 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, fregs[reg]));
413 static inline void gen_store_fpr64 (TCGv t, int reg)
415 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
417 tcg_gen_trunc_i64_i32(tmp, t);
418 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg + 1]));
419 tcg_gen_shri_i64(t, t, 32);
420 tcg_gen_trunc_i64_i32(tmp, t);
421 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, fregs[reg]));
422 tcg_temp_free(tmp);
425 #define B3_0 (ctx->opcode & 0xf)
426 #define B6_4 ((ctx->opcode >> 4) & 0x7)
427 #define B7_4 ((ctx->opcode >> 4) & 0xf)
428 #define B7_0 (ctx->opcode & 0xff)
429 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
430 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
431 (ctx->opcode & 0xfff))
432 #define B11_8 ((ctx->opcode >> 8) & 0xf)
433 #define B15_12 ((ctx->opcode >> 12) & 0xf)
435 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
436 (cpu_gregs[x + 16]) : (cpu_gregs[x]))
438 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
439 ? (cpu_gregs[x + 16]) : (cpu_gregs[x]))
441 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
442 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
443 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
444 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
446 #define CHECK_NOT_DELAY_SLOT \
447 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
448 {tcg_gen_helper_0_0(helper_raise_slot_illegal_instruction); ctx->bstate = BS_EXCP; \
449 return;}
451 void _decode_opc(DisasContext * ctx)
453 #if 0
454 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
455 #endif
456 switch (ctx->opcode) {
457 case 0x0019: /* div0u */
458 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
459 return;
460 case 0x000b: /* rts */
461 CHECK_NOT_DELAY_SLOT
462 tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
463 ctx->flags |= DELAY_SLOT;
464 ctx->delayed_pc = (uint32_t) - 1;
465 return;
466 case 0x0028: /* clrmac */
467 tcg_gen_movi_i32(cpu_mach, 0);
468 tcg_gen_movi_i32(cpu_macl, 0);
469 return;
470 case 0x0048: /* clrs */
471 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
472 return;
473 case 0x0008: /* clrt */
474 gen_clr_t();
475 return;
476 case 0x0038: /* ldtlb */
477 #if defined(CONFIG_USER_ONLY)
478 assert(0); /* XXXXX */
479 #else
480 tcg_gen_helper_0_0(helper_ldtlb);
481 #endif
482 return;
483 case 0x002b: /* rte */
484 CHECK_NOT_DELAY_SLOT
485 tcg_gen_mov_i32(cpu_sr, cpu_ssr);
486 tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
487 ctx->flags |= DELAY_SLOT;
488 ctx->delayed_pc = (uint32_t) - 1;
489 return;
490 case 0x0058: /* sets */
491 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
492 return;
493 case 0x0018: /* sett */
494 gen_set_t();
495 return;
496 case 0xfbfd: /* frchg */
497 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
498 ctx->bstate = BS_STOP;
499 return;
500 case 0xf3fd: /* fschg */
501 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
502 ctx->bstate = BS_STOP;
503 return;
504 case 0x0009: /* nop */
505 return;
506 case 0x001b: /* sleep */
507 if (ctx->memidx) {
508 tcg_gen_helper_0_0(helper_sleep);
509 } else {
510 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
511 ctx->bstate = BS_EXCP;
513 return;
516 switch (ctx->opcode & 0xf000) {
517 case 0x1000: /* mov.l Rm,@(disp,Rn) */
519 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
520 tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
521 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
522 tcg_temp_free(addr);
524 return;
525 case 0x5000: /* mov.l @(disp,Rm),Rn */
527 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
528 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
529 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
530 tcg_temp_free(addr);
532 return;
533 case 0xe000: /* mov #imm,Rn */
534 tcg_gen_movi_i32(REG(B11_8), B7_0s);
535 return;
536 case 0x9000: /* mov.w @(disp,PC),Rn */
538 TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);
539 tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
540 tcg_temp_free(addr);
542 return;
543 case 0xd000: /* mov.l @(disp,PC),Rn */
545 TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);
546 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
547 tcg_temp_free(addr);
549 return;
550 case 0x7000: /* add #imm,Rn */
551 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
552 return;
553 case 0xa000: /* bra disp */
554 CHECK_NOT_DELAY_SLOT
555 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
556 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
557 ctx->flags |= DELAY_SLOT;
558 return;
559 case 0xb000: /* bsr disp */
560 CHECK_NOT_DELAY_SLOT
561 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
562 ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;
563 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
564 ctx->flags |= DELAY_SLOT;
565 return;
568 switch (ctx->opcode & 0xf00f) {
569 case 0x6003: /* mov Rm,Rn */
570 tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
571 return;
572 case 0x2000: /* mov.b Rm,@Rn */
573 tcg_gen_qemu_st8(REG(B7_4), REG(B11_8), ctx->memidx);
574 return;
575 case 0x2001: /* mov.w Rm,@Rn */
576 tcg_gen_qemu_st16(REG(B7_4), REG(B11_8), ctx->memidx);
577 return;
578 case 0x2002: /* mov.l Rm,@Rn */
579 tcg_gen_qemu_st32(REG(B7_4), REG(B11_8), ctx->memidx);
580 return;
581 case 0x6000: /* mov.b @Rm,Rn */
582 tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
583 return;
584 case 0x6001: /* mov.w @Rm,Rn */
585 tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
586 return;
587 case 0x6002: /* mov.l @Rm,Rn */
588 tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
589 return;
590 case 0x2004: /* mov.b Rm,@-Rn */
592 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
593 tcg_gen_subi_i32(addr, REG(B11_8), 1);
594 tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx); /* might cause re-execution */
595 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1); /* modify register status */
596 tcg_temp_free(addr);
598 return;
599 case 0x2005: /* mov.w Rm,@-Rn */
601 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
602 tcg_gen_subi_i32(addr, REG(B11_8), 2);
603 tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
604 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 2);
605 tcg_temp_free(addr);
607 return;
608 case 0x2006: /* mov.l Rm,@-Rn */
610 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
611 tcg_gen_subi_i32(addr, REG(B11_8), 4);
612 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
613 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
615 return;
616 case 0x6004: /* mov.b @Rm+,Rn */
617 tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);
618 if ( B11_8 != B7_4 )
619 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
620 return;
621 case 0x6005: /* mov.w @Rm+,Rn */
622 tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);
623 if ( B11_8 != B7_4 )
624 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
625 return;
626 case 0x6006: /* mov.l @Rm+,Rn */
627 tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);
628 if ( B11_8 != B7_4 )
629 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
630 return;
631 case 0x0004: /* mov.b Rm,@(R0,Rn) */
633 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
634 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
635 tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);
636 tcg_temp_free(addr);
638 return;
639 case 0x0005: /* mov.w Rm,@(R0,Rn) */
641 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
642 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
643 tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);
644 tcg_temp_free(addr);
646 return;
647 case 0x0006: /* mov.l Rm,@(R0,Rn) */
649 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
650 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
651 tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);
652 tcg_temp_free(addr);
654 return;
655 case 0x000c: /* mov.b @(R0,Rm),Rn */
657 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
658 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
659 tcg_gen_qemu_ld8s(REG(B11_8), addr, ctx->memidx);
660 tcg_temp_free(addr);
662 return;
663 case 0x000d: /* mov.w @(R0,Rm),Rn */
665 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
666 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
667 tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);
668 tcg_temp_free(addr);
670 return;
671 case 0x000e: /* mov.l @(R0,Rm),Rn */
673 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
674 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
675 tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);
676 tcg_temp_free(addr);
678 return;
679 case 0x6008: /* swap.b Rm,Rn */
681 TCGv high, low;
682 high = tcg_temp_new(TCG_TYPE_I32);
683 tcg_gen_ext8u_i32(high, REG(B7_4));
684 tcg_gen_shli_i32(high, high, 8);
685 low = tcg_temp_new(TCG_TYPE_I32);
686 tcg_gen_shri_i32(low, REG(B7_4), 8);
687 tcg_gen_ext8u_i32(low, low);
688 tcg_gen_or_i32(REG(B11_8), high, low);
689 tcg_temp_free(low);
690 tcg_temp_free(high);
692 return;
693 case 0x6009: /* swap.w Rm,Rn */
695 TCGv high, low;
696 high = tcg_temp_new(TCG_TYPE_I32);
697 tcg_gen_ext16u_i32(high, REG(B7_4));
698 tcg_gen_shli_i32(high, high, 16);
699 low = tcg_temp_new(TCG_TYPE_I32);
700 tcg_gen_shri_i32(low, REG(B7_4), 16);
701 tcg_gen_ext16u_i32(low, low);
702 tcg_gen_or_i32(REG(B11_8), high, low);
703 tcg_temp_free(low);
704 tcg_temp_free(high);
706 return;
707 case 0x200d: /* xtrct Rm,Rn */
709 TCGv high, low;
710 high = tcg_temp_new(TCG_TYPE_I32);
711 tcg_gen_ext16u_i32(high, REG(B7_4));
712 tcg_gen_shli_i32(high, high, 16);
713 low = tcg_temp_new(TCG_TYPE_I32);
714 tcg_gen_shri_i32(low, REG(B11_8), 16);
715 tcg_gen_ext16u_i32(low, low);
716 tcg_gen_or_i32(REG(B11_8), high, low);
717 tcg_temp_free(low);
718 tcg_temp_free(high);
720 return;
721 case 0x300c: /* add Rm,Rn */
722 tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
723 return;
724 case 0x300e: /* addc Rm,Rn */
725 tcg_gen_helper_1_2(helper_addc, REG(B11_8), REG(B7_4), REG(B11_8));
726 return;
727 case 0x300f: /* addv Rm,Rn */
728 tcg_gen_helper_1_2(helper_addv, REG(B11_8), REG(B7_4), REG(B11_8));
729 return;
730 case 0x2009: /* and Rm,Rn */
731 tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
732 return;
733 case 0x3000: /* cmp/eq Rm,Rn */
734 gen_cmp(TCG_COND_EQ, REG(B7_4), REG(B11_8));
735 return;
736 case 0x3003: /* cmp/ge Rm,Rn */
737 gen_cmp(TCG_COND_GE, REG(B7_4), REG(B11_8));
738 return;
739 case 0x3007: /* cmp/gt Rm,Rn */
740 gen_cmp(TCG_COND_GT, REG(B7_4), REG(B11_8));
741 return;
742 case 0x3006: /* cmp/hi Rm,Rn */
743 gen_cmp(TCG_COND_GTU, REG(B7_4), REG(B11_8));
744 return;
745 case 0x3002: /* cmp/hs Rm,Rn */
746 gen_cmp(TCG_COND_GEU, REG(B7_4), REG(B11_8));
747 return;
748 case 0x200c: /* cmp/str Rm,Rn */
750 int label1 = gen_new_label();
751 int label2 = gen_new_label();
752 TCGv cmp1 = tcg_temp_local_new(TCG_TYPE_I32);
753 TCGv cmp2 = tcg_temp_local_new(TCG_TYPE_I32);
754 tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8));
755 tcg_gen_andi_i32(cmp2, cmp1, 0xff000000);
756 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
757 tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000);
758 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
759 tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00);
760 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
761 tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff);
762 tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);
763 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
764 tcg_gen_br(label2);
765 gen_set_label(label1);
766 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
767 gen_set_label(label2);
768 tcg_temp_free(cmp2);
769 tcg_temp_free(cmp1);
771 return;
772 case 0x2007: /* div0s Rm,Rn */
774 gen_copy_bit_i32(cpu_sr, 8, REG(B11_8), 31); /* SR_Q */
775 gen_copy_bit_i32(cpu_sr, 9, REG(B7_4), 31); /* SR_M */
776 TCGv val = tcg_temp_new(TCG_TYPE_I32);
777 tcg_gen_xor_i32(val, REG(B7_4), REG(B11_8));
778 gen_copy_bit_i32(cpu_sr, 0, val, 31); /* SR_T */
779 tcg_temp_free(val);
781 return;
782 case 0x3004: /* div1 Rm,Rn */
783 tcg_gen_helper_1_2(helper_div1, REG(B11_8), REG(B7_4), REG(B11_8));
784 return;
785 case 0x300d: /* dmuls.l Rm,Rn */
787 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
788 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
790 tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
791 tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
792 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
793 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
794 tcg_gen_shri_i64(tmp1, tmp1, 32);
795 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
797 tcg_temp_free(tmp2);
798 tcg_temp_free(tmp1);
800 return;
801 case 0x3005: /* dmulu.l Rm,Rn */
803 TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);
804 TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);
806 tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
807 tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
808 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
809 tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
810 tcg_gen_shri_i64(tmp1, tmp1, 32);
811 tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
813 tcg_temp_free(tmp2);
814 tcg_temp_free(tmp1);
816 return;
817 case 0x600e: /* exts.b Rm,Rn */
818 tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
819 return;
820 case 0x600f: /* exts.w Rm,Rn */
821 tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
822 return;
823 case 0x600c: /* extu.b Rm,Rn */
824 tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
825 return;
826 case 0x600d: /* extu.w Rm,Rn */
827 tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
828 return;
829 case 0x000f: /* mac.l @Rm+,@Rn+ */
831 TCGv arg0, arg1;
832 arg0 = tcg_temp_new(TCG_TYPE_I32);
833 tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
834 arg1 = tcg_temp_new(TCG_TYPE_I32);
835 tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
836 tcg_gen_helper_0_2(helper_macl, arg0, arg1);
837 tcg_temp_free(arg1);
838 tcg_temp_free(arg0);
839 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
840 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
842 return;
843 case 0x400f: /* mac.w @Rm+,@Rn+ */
845 TCGv arg0, arg1;
846 arg0 = tcg_temp_new(TCG_TYPE_I32);
847 tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
848 arg1 = tcg_temp_new(TCG_TYPE_I32);
849 tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
850 tcg_gen_helper_0_2(helper_macw, arg0, arg1);
851 tcg_temp_free(arg1);
852 tcg_temp_free(arg0);
853 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
854 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
856 return;
857 case 0x0007: /* mul.l Rm,Rn */
858 tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
859 return;
860 case 0x200f: /* muls.w Rm,Rn */
862 TCGv arg0, arg1;
863 arg0 = tcg_temp_new(TCG_TYPE_I32);
864 tcg_gen_ext16s_i32(arg0, REG(B7_4));
865 arg1 = tcg_temp_new(TCG_TYPE_I32);
866 tcg_gen_ext16s_i32(arg1, REG(B11_8));
867 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
868 tcg_temp_free(arg1);
869 tcg_temp_free(arg0);
871 return;
872 case 0x200e: /* mulu.w Rm,Rn */
874 TCGv arg0, arg1;
875 arg0 = tcg_temp_new(TCG_TYPE_I32);
876 tcg_gen_ext16u_i32(arg0, REG(B7_4));
877 arg1 = tcg_temp_new(TCG_TYPE_I32);
878 tcg_gen_ext16u_i32(arg1, REG(B11_8));
879 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
880 tcg_temp_free(arg1);
881 tcg_temp_free(arg0);
883 return;
884 case 0x600b: /* neg Rm,Rn */
885 tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
886 return;
887 case 0x600a: /* negc Rm,Rn */
888 tcg_gen_helper_1_1(helper_negc, REG(B11_8), REG(B7_4));
889 return;
890 case 0x6007: /* not Rm,Rn */
891 tcg_gen_not_i32(REG(B11_8), REG(B7_4));
892 return;
893 case 0x200b: /* or Rm,Rn */
894 tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
895 return;
896 case 0x400c: /* shad Rm,Rn */
898 int label1 = gen_new_label();
899 int label2 = gen_new_label();
900 int label3 = gen_new_label();
901 int label4 = gen_new_label();
902 TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
903 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
904 /* Rm positive, shift to the left */
905 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
906 tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
907 tcg_gen_br(label4);
908 /* Rm negative, shift to the right */
909 gen_set_label(label1);
910 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
911 tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
912 tcg_gen_not_i32(shift, REG(B7_4));
913 tcg_gen_andi_i32(shift, shift, 0x1f);
914 tcg_gen_addi_i32(shift, shift, 1);
915 tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift);
916 tcg_gen_br(label4);
917 /* Rm = -32 */
918 gen_set_label(label2);
919 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);
920 tcg_gen_movi_i32(REG(B11_8), 0);
921 tcg_gen_br(label4);
922 gen_set_label(label3);
923 tcg_gen_movi_i32(REG(B11_8), 0xffffffff);
924 gen_set_label(label4);
925 tcg_temp_free(shift);
927 return;
928 case 0x400d: /* shld Rm,Rn */
930 int label1 = gen_new_label();
931 int label2 = gen_new_label();
932 int label3 = gen_new_label();
933 TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);
934 tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
935 /* Rm positive, shift to the left */
936 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
937 tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
938 tcg_gen_br(label3);
939 /* Rm negative, shift to the right */
940 gen_set_label(label1);
941 tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
942 tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
943 tcg_gen_not_i32(shift, REG(B7_4));
944 tcg_gen_andi_i32(shift, shift, 0x1f);
945 tcg_gen_addi_i32(shift, shift, 1);
946 tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift);
947 tcg_gen_br(label3);
948 /* Rm = -32 */
949 gen_set_label(label2);
950 tcg_gen_movi_i32(REG(B11_8), 0);
951 gen_set_label(label3);
952 tcg_temp_free(shift);
954 return;
955 case 0x3008: /* sub Rm,Rn */
956 tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
957 return;
958 case 0x300a: /* subc Rm,Rn */
959 tcg_gen_helper_1_2(helper_subc, REG(B11_8), REG(B7_4), REG(B11_8));
960 return;
961 case 0x300b: /* subv Rm,Rn */
962 tcg_gen_helper_1_2(helper_subv, REG(B11_8), REG(B7_4), REG(B11_8));
963 return;
964 case 0x2008: /* tst Rm,Rn */
966 TCGv val = tcg_temp_new(TCG_TYPE_I32);
967 tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
968 gen_cmp_imm(TCG_COND_EQ, val, 0);
969 tcg_temp_free(val);
971 return;
972 case 0x200a: /* xor Rm,Rn */
973 tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
974 return;
975 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
976 if (ctx->fpscr & FPSCR_SZ) {
977 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
978 gen_load_fpr64(fp, XREG(B7_4));
979 gen_store_fpr64(fp, XREG(B11_8));
980 tcg_temp_free(fp);
981 } else {
982 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
983 gen_load_fpr32(fp, FREG(B7_4));
984 gen_store_fpr32(fp, FREG(B11_8));
985 tcg_temp_free(fp);
987 return;
988 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
989 if (ctx->fpscr & FPSCR_SZ) {
990 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
991 gen_load_fpr64(fp, XREG(B7_4));
992 tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx);
993 tcg_temp_free(fp);
994 } else {
995 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
996 gen_load_fpr32(fp, FREG(B7_4));
997 tcg_gen_qemu_st32(fp, REG(B11_8), ctx->memidx);
998 tcg_temp_free(fp);
1000 return;
1001 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
1002 if (ctx->fpscr & FPSCR_SZ) {
1003 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1004 tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
1005 gen_store_fpr64(fp, XREG(B11_8));
1006 tcg_temp_free(fp);
1007 } else {
1008 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1009 tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
1010 gen_store_fpr32(fp, FREG(B11_8));
1011 tcg_temp_free(fp);
1013 return;
1014 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
1015 if (ctx->fpscr & FPSCR_SZ) {
1016 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1017 tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);
1018 gen_store_fpr64(fp, XREG(B11_8));
1019 tcg_temp_free(fp);
1020 tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8);
1021 } else {
1022 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1023 tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);
1024 gen_store_fpr32(fp, FREG(B11_8));
1025 tcg_temp_free(fp);
1026 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
1028 return;
1029 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
1030 if (ctx->fpscr & FPSCR_SZ) {
1031 TCGv addr, fp;
1032 addr = tcg_temp_new(TCG_TYPE_I32);
1033 tcg_gen_subi_i32(addr, REG(B11_8), 8);
1034 fp = tcg_temp_new(TCG_TYPE_I64);
1035 gen_load_fpr64(fp, XREG(B7_4));
1036 tcg_gen_qemu_st64(fp, addr, ctx->memidx);
1037 tcg_temp_free(fp);
1038 tcg_temp_free(addr);
1039 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);
1040 } else {
1041 TCGv addr, fp;
1042 addr = tcg_temp_new(TCG_TYPE_I32);
1043 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1044 fp = tcg_temp_new(TCG_TYPE_I32);
1045 gen_load_fpr32(fp, FREG(B7_4));
1046 tcg_gen_qemu_st32(fp, addr, ctx->memidx);
1047 tcg_temp_free(fp);
1048 tcg_temp_free(addr);
1049 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1051 return;
1052 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
1054 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1055 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1056 if (ctx->fpscr & FPSCR_SZ) {
1057 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1058 tcg_gen_qemu_ld64(fp, addr, ctx->memidx);
1059 gen_store_fpr64(fp, XREG(B11_8));
1060 tcg_temp_free(fp);
1061 } else {
1062 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1063 tcg_gen_qemu_ld32u(fp, addr, ctx->memidx);
1064 gen_store_fpr32(fp, FREG(B11_8));
1065 tcg_temp_free(fp);
1067 tcg_temp_free(addr);
1069 return;
1070 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
1072 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1073 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1074 if (ctx->fpscr & FPSCR_SZ) {
1075 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1076 gen_load_fpr64(fp, XREG(B7_4));
1077 tcg_gen_qemu_st64(fp, addr, ctx->memidx);
1078 tcg_temp_free(fp);
1079 } else {
1080 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1081 gen_load_fpr32(fp, FREG(B7_4));
1082 tcg_gen_qemu_st32(fp, addr, ctx->memidx);
1083 tcg_temp_free(fp);
1085 tcg_temp_free(addr);
1087 return;
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] */
1095 TCGv fp0, fp1;
1097 if (ctx->fpscr & FPSCR_PR) {
1098 if (ctx->opcode & 0x0110)
1099 break; /* illegal instruction */
1100 fp0 = tcg_temp_new(TCG_TYPE_I64);
1101 fp1 = tcg_temp_new(TCG_TYPE_I64);
1102 gen_load_fpr64(fp0, DREG(B11_8));
1103 gen_load_fpr64(fp1, DREG(B7_4));
1105 else {
1106 fp0 = tcg_temp_new(TCG_TYPE_I32);
1107 fp1 = tcg_temp_new(TCG_TYPE_I32);
1108 gen_load_fpr32(fp0, FREG(B11_8));
1109 gen_load_fpr32(fp1, FREG(B7_4));
1112 switch (ctx->opcode & 0xf00f) {
1113 case 0xf000: /* fadd Rm,Rn */
1114 if (ctx->fpscr & FPSCR_PR)
1115 tcg_gen_helper_1_2(helper_fadd_DT, fp0, fp0, fp1);
1116 else
1117 tcg_gen_helper_1_2(helper_fadd_FT, fp0, fp0, fp1);
1118 break;
1119 case 0xf001: /* fsub Rm,Rn */
1120 if (ctx->fpscr & FPSCR_PR)
1121 tcg_gen_helper_1_2(helper_fsub_DT, fp0, fp0, fp1);
1122 else
1123 tcg_gen_helper_1_2(helper_fsub_FT, fp0, fp0, fp1);
1124 break;
1125 case 0xf002: /* fmul Rm,Rn */
1126 if (ctx->fpscr & FPSCR_PR)
1127 tcg_gen_helper_1_2(helper_fmul_DT, fp0, fp0, fp1);
1128 else
1129 tcg_gen_helper_1_2(helper_fmul_FT, fp0, fp0, fp1);
1130 break;
1131 case 0xf003: /* fdiv Rm,Rn */
1132 if (ctx->fpscr & FPSCR_PR)
1133 tcg_gen_helper_1_2(helper_fdiv_DT, fp0, fp0, fp1);
1134 else
1135 tcg_gen_helper_1_2(helper_fdiv_FT, fp0, fp0, fp1);
1136 break;
1137 case 0xf004: /* fcmp/eq Rm,Rn */
1138 if (ctx->fpscr & FPSCR_PR)
1139 tcg_gen_helper_0_2(helper_fcmp_eq_DT, fp0, fp1);
1140 else
1141 tcg_gen_helper_0_2(helper_fcmp_eq_FT, fp0, fp1);
1142 return;
1143 case 0xf005: /* fcmp/gt Rm,Rn */
1144 if (ctx->fpscr & FPSCR_PR)
1145 tcg_gen_helper_0_2(helper_fcmp_gt_DT, fp0, fp1);
1146 else
1147 tcg_gen_helper_0_2(helper_fcmp_gt_FT, fp0, fp1);
1148 return;
1151 if (ctx->fpscr & FPSCR_PR) {
1152 gen_store_fpr64(fp0, DREG(B11_8));
1154 else {
1155 gen_store_fpr32(fp0, FREG(B11_8));
1157 tcg_temp_free(fp1);
1158 tcg_temp_free(fp0);
1160 return;
1163 switch (ctx->opcode & 0xff00) {
1164 case 0xc900: /* and #imm,R0 */
1165 tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1166 return;
1167 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1169 TCGv addr, val;
1170 addr = tcg_temp_new(TCG_TYPE_I32);
1171 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1172 val = tcg_temp_new(TCG_TYPE_I32);
1173 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1174 tcg_gen_andi_i32(val, val, B7_0);
1175 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1176 tcg_temp_free(val);
1177 tcg_temp_free(addr);
1179 return;
1180 case 0x8b00: /* bf label */
1181 CHECK_NOT_DELAY_SLOT
1182 gen_conditional_jump(ctx, ctx->pc + 2,
1183 ctx->pc + 4 + B7_0s * 2);
1184 ctx->bstate = BS_BRANCH;
1185 return;
1186 case 0x8f00: /* bf/s label */
1187 CHECK_NOT_DELAY_SLOT
1188 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);
1189 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1190 return;
1191 case 0x8900: /* bt label */
1192 CHECK_NOT_DELAY_SLOT
1193 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
1194 ctx->pc + 2);
1195 ctx->bstate = BS_BRANCH;
1196 return;
1197 case 0x8d00: /* bt/s label */
1198 CHECK_NOT_DELAY_SLOT
1199 gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);
1200 ctx->flags |= DELAY_SLOT_CONDITIONAL;
1201 return;
1202 case 0x8800: /* cmp/eq #imm,R0 */
1203 gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);
1204 return;
1205 case 0xc400: /* mov.b @(disp,GBR),R0 */
1207 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1208 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1209 tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1210 tcg_temp_free(addr);
1212 return;
1213 case 0xc500: /* mov.w @(disp,GBR),R0 */
1215 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1216 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1217 tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1218 tcg_temp_free(addr);
1220 return;
1221 case 0xc600: /* mov.l @(disp,GBR),R0 */
1223 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1224 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1225 tcg_gen_qemu_ld32s(REG(0), addr, ctx->memidx);
1226 tcg_temp_free(addr);
1228 return;
1229 case 0xc000: /* mov.b R0,@(disp,GBR) */
1231 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1232 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1233 tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1234 tcg_temp_free(addr);
1236 return;
1237 case 0xc100: /* mov.w R0,@(disp,GBR) */
1239 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1240 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1241 tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1242 tcg_temp_free(addr);
1244 return;
1245 case 0xc200: /* mov.l R0,@(disp,GBR) */
1247 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1248 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1249 tcg_gen_qemu_st32(REG(0), addr, ctx->memidx);
1250 tcg_temp_free(addr);
1252 return;
1253 case 0x8000: /* mov.b R0,@(disp,Rn) */
1255 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1256 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1257 tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);
1258 tcg_temp_free(addr);
1260 return;
1261 case 0x8100: /* mov.w R0,@(disp,Rn) */
1263 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1264 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1265 tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);
1266 tcg_temp_free(addr);
1268 return;
1269 case 0x8400: /* mov.b @(disp,Rn),R0 */
1271 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1272 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1273 tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);
1274 tcg_temp_free(addr);
1276 return;
1277 case 0x8500: /* mov.w @(disp,Rn),R0 */
1279 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1280 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1281 tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);
1282 tcg_temp_free(addr);
1284 return;
1285 case 0xc700: /* mova @(disp,PC),R0 */
1286 tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
1287 return;
1288 case 0xcb00: /* or #imm,R0 */
1289 tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1290 return;
1291 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1293 TCGv addr, val;
1294 addr = tcg_temp_new(TCG_TYPE_I32);
1295 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1296 val = tcg_temp_new(TCG_TYPE_I32);
1297 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1298 tcg_gen_ori_i32(val, val, B7_0);
1299 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1300 tcg_temp_free(val);
1301 tcg_temp_free(addr);
1303 return;
1304 case 0xc300: /* trapa #imm */
1306 TCGv imm;
1307 CHECK_NOT_DELAY_SLOT
1308 tcg_gen_movi_i32(cpu_pc, ctx->pc);
1309 imm = tcg_const_i32(B7_0);
1310 tcg_gen_helper_0_1(helper_trapa, imm);
1311 tcg_temp_free(imm);
1312 ctx->bstate = BS_BRANCH;
1314 return;
1315 case 0xc800: /* tst #imm,R0 */
1317 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1318 tcg_gen_andi_i32(val, REG(0), B7_0);
1319 gen_cmp_imm(TCG_COND_EQ, val, 0);
1320 tcg_temp_free(val);
1322 return;
1323 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1325 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1326 tcg_gen_add_i32(val, REG(0), cpu_gbr);
1327 tcg_gen_qemu_ld8u(val, val, ctx->memidx);
1328 tcg_gen_andi_i32(val, val, B7_0);
1329 gen_cmp_imm(TCG_COND_EQ, val, 0);
1330 tcg_temp_free(val);
1332 return;
1333 case 0xca00: /* xor #imm,R0 */
1334 tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1335 return;
1336 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1338 TCGv addr, val;
1339 addr = tcg_temp_new(TCG_TYPE_I32);
1340 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1341 val = tcg_temp_new(TCG_TYPE_I32);
1342 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1343 tcg_gen_xori_i32(val, val, B7_0);
1344 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1345 tcg_temp_free(val);
1346 tcg_temp_free(addr);
1348 return;
1351 switch (ctx->opcode & 0xf08f) {
1352 case 0x408e: /* ldc Rm,Rn_BANK */
1353 tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1354 return;
1355 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1356 tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);
1357 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1358 return;
1359 case 0x0082: /* stc Rm_BANK,Rn */
1360 tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1361 return;
1362 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1364 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1365 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1366 tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);
1367 tcg_temp_free(addr);
1368 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1370 return;
1373 switch (ctx->opcode & 0xf0ff) {
1374 case 0x0023: /* braf Rn */
1375 CHECK_NOT_DELAY_SLOT
1376 tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);
1377 ctx->flags |= DELAY_SLOT;
1378 ctx->delayed_pc = (uint32_t) - 1;
1379 return;
1380 case 0x0003: /* bsrf Rn */
1381 CHECK_NOT_DELAY_SLOT
1382 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1383 tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1384 ctx->flags |= DELAY_SLOT;
1385 ctx->delayed_pc = (uint32_t) - 1;
1386 return;
1387 case 0x4015: /* cmp/pl Rn */
1388 gen_cmp_imm(TCG_COND_GT, REG(B11_8), 0);
1389 return;
1390 case 0x4011: /* cmp/pz Rn */
1391 gen_cmp_imm(TCG_COND_GE, REG(B11_8), 0);
1392 return;
1393 case 0x4010: /* dt Rn */
1394 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1395 gen_cmp_imm(TCG_COND_EQ, REG(B11_8), 0);
1396 return;
1397 case 0x402b: /* jmp @Rn */
1398 CHECK_NOT_DELAY_SLOT
1399 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1400 ctx->flags |= DELAY_SLOT;
1401 ctx->delayed_pc = (uint32_t) - 1;
1402 return;
1403 case 0x400b: /* jsr @Rn */
1404 CHECK_NOT_DELAY_SLOT
1405 tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);
1406 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1407 ctx->flags |= DELAY_SLOT;
1408 ctx->delayed_pc = (uint32_t) - 1;
1409 return;
1410 case 0x400e: /* lds Rm,SR */
1411 tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3);
1412 ctx->bstate = BS_STOP;
1413 return;
1414 case 0x4007: /* lds.l @Rm+,SR */
1416 TCGv val = tcg_temp_new(TCG_TYPE_I32);
1417 tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx);
1418 tcg_gen_andi_i32(cpu_sr, val, 0x700083f3);
1419 tcg_temp_free(val);
1420 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1421 ctx->bstate = BS_STOP;
1423 return;
1424 case 0x0002: /* sts SR,Rn */
1425 tcg_gen_mov_i32(REG(B11_8), cpu_sr);
1426 return;
1427 case 0x4003: /* sts SR,@-Rn */
1429 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1430 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1431 tcg_gen_qemu_st32(cpu_sr, addr, ctx->memidx);
1432 tcg_temp_free(addr);
1433 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1435 return;
1436 #define LDST(reg,ldnum,ldpnum,stnum,stpnum) \
1437 case ldnum: \
1438 tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \
1439 return; \
1440 case ldpnum: \
1441 tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx); \
1442 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \
1443 return; \
1444 case stnum: \
1445 tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \
1446 return; \
1447 case stpnum: \
1449 TCGv addr = tcg_temp_new(TCG_TYPE_I32); \
1450 tcg_gen_subi_i32(addr, REG(B11_8), 4); \
1451 tcg_gen_qemu_st32 (cpu_##reg, addr, ctx->memidx); \
1452 tcg_temp_free(addr); \
1453 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4); \
1455 return;
1456 LDST(gbr, 0x401e, 0x4017, 0x0012, 0x4013)
1457 LDST(vbr, 0x402e, 0x4027, 0x0022, 0x4023)
1458 LDST(ssr, 0x403e, 0x4037, 0x0032, 0x4033)
1459 LDST(spc, 0x404e, 0x4047, 0x0042, 0x4043)
1460 LDST(dbr, 0x40fa, 0x40f6, 0x00fa, 0x40f2)
1461 LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002)
1462 LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012)
1463 LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022)
1464 LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052)
1465 case 0x406a: /* lds Rm,FPSCR */
1466 tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8));
1467 ctx->bstate = BS_STOP;
1468 return;
1469 case 0x4066: /* lds.l @Rm+,FPSCR */
1471 TCGv addr = tcg_temp_new(TCG_TYPE_I32);
1472 tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
1473 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1474 tcg_gen_helper_0_1(helper_ld_fpscr, addr);
1475 tcg_temp_free(addr);
1476 ctx->bstate = BS_STOP;
1478 return;
1479 case 0x006a: /* sts FPSCR,Rn */
1480 tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1481 return;
1482 case 0x4062: /* sts FPSCR,@-Rn */
1484 TCGv addr, val;
1485 val = tcg_temp_new(TCG_TYPE_I32);
1486 tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1487 addr = tcg_temp_new(TCG_TYPE_I32);
1488 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1489 tcg_gen_qemu_st32(val, addr, ctx->memidx);
1490 tcg_temp_free(addr);
1491 tcg_temp_free(val);
1492 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);
1494 return;
1495 case 0x00c3: /* movca.l R0,@Rm */
1496 tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
1497 return;
1498 case 0x0029: /* movt Rn */
1499 tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T);
1500 return;
1501 case 0x0093: /* ocbi @Rn */
1503 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1504 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1505 tcg_temp_free(dummy);
1507 return;
1508 case 0x00a3: /* ocbp @Rn */
1510 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1511 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1512 tcg_temp_free(dummy);
1514 return;
1515 case 0x00b3: /* ocbwb @Rn */
1517 TCGv dummy = tcg_temp_new(TCG_TYPE_I32);
1518 tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
1519 tcg_temp_free(dummy);
1521 return;
1522 case 0x0083: /* pref @Rn */
1523 return;
1524 case 0x4024: /* rotcl Rn */
1526 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1527 tcg_gen_mov_i32(tmp, cpu_sr);
1528 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1529 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1530 gen_copy_bit_i32(REG(B11_8), 0, tmp, 0);
1531 tcg_temp_free(tmp);
1533 return;
1534 case 0x4025: /* rotcr Rn */
1536 TCGv tmp = tcg_temp_new(TCG_TYPE_I32);
1537 tcg_gen_mov_i32(tmp, cpu_sr);
1538 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1539 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1540 gen_copy_bit_i32(REG(B11_8), 31, tmp, 0);
1541 tcg_temp_free(tmp);
1543 return;
1544 case 0x4004: /* rotl Rn */
1545 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1546 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1547 gen_copy_bit_i32(REG(B11_8), 0, cpu_sr, 0);
1548 return;
1549 case 0x4005: /* rotr Rn */
1550 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1551 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1552 gen_copy_bit_i32(REG(B11_8), 31, cpu_sr, 0);
1553 return;
1554 case 0x4000: /* shll Rn */
1555 case 0x4020: /* shal Rn */
1556 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);
1557 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1558 return;
1559 case 0x4021: /* shar Rn */
1560 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1561 tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1562 return;
1563 case 0x4001: /* shlr Rn */
1564 gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);
1565 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1566 return;
1567 case 0x4008: /* shll2 Rn */
1568 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1569 return;
1570 case 0x4018: /* shll8 Rn */
1571 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1572 return;
1573 case 0x4028: /* shll16 Rn */
1574 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1575 return;
1576 case 0x4009: /* shlr2 Rn */
1577 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1578 return;
1579 case 0x4019: /* shlr8 Rn */
1580 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1581 return;
1582 case 0x4029: /* shlr16 Rn */
1583 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1584 return;
1585 case 0x401b: /* tas.b @Rn */
1587 TCGv addr, val;
1588 addr = tcg_temp_local_new(TCG_TYPE_I32);
1589 tcg_gen_mov_i32(addr, REG(B11_8));
1590 val = tcg_temp_local_new(TCG_TYPE_I32);
1591 tcg_gen_qemu_ld8u(val, addr, ctx->memidx);
1592 gen_cmp_imm(TCG_COND_EQ, val, 0);
1593 tcg_gen_ori_i32(val, val, 0x80);
1594 tcg_gen_qemu_st8(val, addr, ctx->memidx);
1595 tcg_temp_free(val);
1596 tcg_temp_free(addr);
1598 return;
1599 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1601 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1602 tcg_gen_mov_i32(fp, cpu_fpul);
1603 gen_store_fpr32(fp, FREG(B11_8));
1604 tcg_temp_free(fp);
1606 return;
1607 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1609 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1610 gen_load_fpr32(fp, FREG(B11_8));
1611 tcg_gen_mov_i32(cpu_fpul, fp);
1612 tcg_temp_free(fp);
1614 return;
1615 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1616 if (ctx->fpscr & FPSCR_PR) {
1617 TCGv fp;
1618 if (ctx->opcode & 0x0100)
1619 break; /* illegal instruction */
1620 fp = tcg_temp_new(TCG_TYPE_I64);
1621 tcg_gen_helper_1_1(helper_float_DT, fp, cpu_fpul);
1622 gen_store_fpr64(fp, DREG(B11_8));
1623 tcg_temp_free(fp);
1625 else {
1626 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1627 tcg_gen_helper_1_1(helper_float_FT, fp, cpu_fpul);
1628 gen_store_fpr32(fp, FREG(B11_8));
1629 tcg_temp_free(fp);
1631 return;
1632 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1633 if (ctx->fpscr & FPSCR_PR) {
1634 TCGv fp;
1635 if (ctx->opcode & 0x0100)
1636 break; /* illegal instruction */
1637 fp = tcg_temp_new(TCG_TYPE_I64);
1638 gen_load_fpr64(fp, DREG(B11_8));
1639 tcg_gen_helper_1_1(helper_ftrc_DT, cpu_fpul, fp);
1640 tcg_temp_free(fp);
1642 else {
1643 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1644 gen_load_fpr32(fp, FREG(B11_8));
1645 tcg_gen_helper_1_1(helper_ftrc_FT, cpu_fpul, fp);
1646 tcg_temp_free(fp);
1648 return;
1649 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1651 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1652 gen_load_fpr32(fp, FREG(B11_8));
1653 tcg_gen_helper_1_1(helper_fneg_T, fp, fp);
1654 gen_store_fpr32(fp, FREG(B11_8));
1655 tcg_temp_free(fp);
1657 return;
1658 case 0xf05d: /* fabs FRn/DRn */
1659 if (ctx->fpscr & FPSCR_PR) {
1660 if (ctx->opcode & 0x0100)
1661 break; /* illegal instruction */
1662 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1663 gen_load_fpr64(fp, DREG(B11_8));
1664 tcg_gen_helper_1_1(helper_fabs_DT, fp, fp);
1665 gen_store_fpr64(fp, DREG(B11_8));
1666 tcg_temp_free(fp);
1667 } else {
1668 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1669 gen_load_fpr32(fp, FREG(B11_8));
1670 tcg_gen_helper_1_1(helper_fabs_FT, fp, fp);
1671 gen_store_fpr32(fp, FREG(B11_8));
1672 tcg_temp_free(fp);
1674 return;
1675 case 0xf06d: /* fsqrt FRn */
1676 if (ctx->fpscr & FPSCR_PR) {
1677 if (ctx->opcode & 0x0100)
1678 break; /* illegal instruction */
1679 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1680 gen_load_fpr64(fp, DREG(B11_8));
1681 tcg_gen_helper_1_1(helper_fsqrt_DT, fp, fp);
1682 gen_store_fpr64(fp, DREG(B11_8));
1683 tcg_temp_free(fp);
1684 } else {
1685 TCGv fp = tcg_temp_new(TCG_TYPE_I32);
1686 gen_load_fpr32(fp, FREG(B11_8));
1687 tcg_gen_helper_1_1(helper_fsqrt_FT, fp, fp);
1688 gen_store_fpr32(fp, FREG(B11_8));
1689 tcg_temp_free(fp);
1691 return;
1692 case 0xf07d: /* fsrra FRn */
1693 break;
1694 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1695 if (!(ctx->fpscr & FPSCR_PR)) {
1696 TCGv val = tcg_const_i32(0);
1697 gen_load_fpr32(val, FREG(B11_8));
1698 tcg_temp_free(val);
1699 return;
1701 break;
1702 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1703 if (!(ctx->fpscr & FPSCR_PR)) {
1704 TCGv val = tcg_const_i32(0x3f800000);
1705 gen_load_fpr32(val, FREG(B11_8));
1706 tcg_temp_free(val);
1707 return;
1709 break;
1710 case 0xf0ad: /* fcnvsd FPUL,DRn */
1712 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1713 tcg_gen_helper_1_1(helper_fcnvsd_FT_DT, fp, cpu_fpul);
1714 gen_store_fpr64(fp, DREG(B11_8));
1715 tcg_temp_free(fp);
1717 return;
1718 case 0xf0bd: /* fcnvds DRn,FPUL */
1720 TCGv fp = tcg_temp_new(TCG_TYPE_I64);
1721 gen_load_fpr64(fp, DREG(B11_8));
1722 tcg_gen_helper_1_1(helper_fcnvds_DT_FT, cpu_fpul, fp);
1723 tcg_temp_free(fp);
1725 return;
1728 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1729 ctx->opcode, ctx->pc);
1730 tcg_gen_helper_0_0(helper_raise_illegal_instruction);
1731 ctx->bstate = BS_EXCP;
1734 void decode_opc(DisasContext * ctx)
1736 uint32_t old_flags = ctx->flags;
1738 _decode_opc(ctx);
1740 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1741 if (ctx->flags & DELAY_SLOT_CLEARME) {
1742 gen_store_flags(0);
1743 } else {
1744 /* go out of the delay slot */
1745 uint32_t new_flags = ctx->flags;
1746 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1747 gen_store_flags(new_flags);
1749 ctx->flags = 0;
1750 ctx->bstate = BS_BRANCH;
1751 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1752 gen_delayed_conditional_jump(ctx);
1753 } else if (old_flags & DELAY_SLOT) {
1754 gen_jump(ctx);
1759 /* go into a delay slot */
1760 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1761 gen_store_flags(ctx->flags);
1764 static inline void
1765 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1766 int search_pc)
1768 DisasContext ctx;
1769 target_ulong pc_start;
1770 static uint16_t *gen_opc_end;
1771 int i, ii;
1772 int num_insns;
1773 int max_insns;
1775 pc_start = tb->pc;
1776 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1777 ctx.pc = pc_start;
1778 ctx.flags = (uint32_t)tb->flags;
1779 ctx.bstate = BS_NONE;
1780 ctx.sr = env->sr;
1781 ctx.fpscr = env->fpscr;
1782 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1783 /* We don't know if the delayed pc came from a dynamic or static branch,
1784 so assume it is a dynamic branch. */
1785 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1786 ctx.tb = tb;
1787 ctx.singlestep_enabled = env->singlestep_enabled;
1789 #ifdef DEBUG_DISAS
1790 if (loglevel & CPU_LOG_TB_CPU) {
1791 fprintf(logfile,
1792 "------------------------------------------------\n");
1793 cpu_dump_state(env, logfile, fprintf, 0);
1795 #endif
1797 ii = -1;
1798 num_insns = 0;
1799 max_insns = tb->cflags & CF_COUNT_MASK;
1800 if (max_insns == 0)
1801 max_insns = CF_COUNT_MASK;
1802 gen_icount_start();
1803 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1804 if (env->nb_breakpoints > 0) {
1805 for (i = 0; i < env->nb_breakpoints; i++) {
1806 if (ctx.pc == env->breakpoints[i]) {
1807 /* We have hit a breakpoint - make sure PC is up-to-date */
1808 tcg_gen_movi_i32(cpu_pc, ctx.pc);
1809 tcg_gen_helper_0_0(helper_debug);
1810 ctx.bstate = BS_EXCP;
1811 break;
1815 if (search_pc) {
1816 i = gen_opc_ptr - gen_opc_buf;
1817 if (ii < i) {
1818 ii++;
1819 while (ii < i)
1820 gen_opc_instr_start[ii++] = 0;
1822 gen_opc_pc[ii] = ctx.pc;
1823 gen_opc_hflags[ii] = ctx.flags;
1824 gen_opc_instr_start[ii] = 1;
1825 gen_opc_icount[ii] = num_insns;
1827 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1828 gen_io_start();
1829 #if 0
1830 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1831 fflush(stderr);
1832 #endif
1833 ctx.opcode = lduw_code(ctx.pc);
1834 decode_opc(&ctx);
1835 num_insns++;
1836 ctx.pc += 2;
1837 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1838 break;
1839 if (env->singlestep_enabled)
1840 break;
1841 if (num_insns >= max_insns)
1842 break;
1843 #ifdef SH4_SINGLE_STEP
1844 break;
1845 #endif
1847 if (tb->cflags & CF_LAST_IO)
1848 gen_io_end();
1849 if (env->singlestep_enabled) {
1850 tcg_gen_helper_0_0(helper_debug);
1851 } else {
1852 switch (ctx.bstate) {
1853 case BS_STOP:
1854 /* gen_op_interrupt_restart(); */
1855 /* fall through */
1856 case BS_NONE:
1857 if (ctx.flags) {
1858 gen_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1860 gen_goto_tb(&ctx, 0, ctx.pc);
1861 break;
1862 case BS_EXCP:
1863 /* gen_op_interrupt_restart(); */
1864 tcg_gen_exit_tb(0);
1865 break;
1866 case BS_BRANCH:
1867 default:
1868 break;
1872 gen_icount_end(tb, num_insns);
1873 *gen_opc_ptr = INDEX_op_end;
1874 if (search_pc) {
1875 i = gen_opc_ptr - gen_opc_buf;
1876 ii++;
1877 while (ii <= i)
1878 gen_opc_instr_start[ii++] = 0;
1879 } else {
1880 tb->size = ctx.pc - pc_start;
1881 tb->icount = num_insns;
1884 #ifdef DEBUG_DISAS
1885 #ifdef SH4_DEBUG_DISAS
1886 if (loglevel & CPU_LOG_TB_IN_ASM)
1887 fprintf(logfile, "\n");
1888 #endif
1889 if (loglevel & CPU_LOG_TB_IN_ASM) {
1890 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1891 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1892 fprintf(logfile, "\n");
1894 #endif
1897 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1899 gen_intermediate_code_internal(env, tb, 0);
1902 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1904 gen_intermediate_code_internal(env, tb, 1);
1907 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1908 unsigned long searched_pc, int pc_pos, void *puc)
1910 env->pc = gen_opc_pc[pc_pos];
1911 env->flags = gen_opc_hflags[pc_pos];