]> Git Repo - qemu.git/blame - target-sh4/translate.c
SH4: convert a few control or system register functions to TCG
[qemu.git] / target-sh4 / translate.c
CommitLineData
fdf9b3e8
FB
1/*
2 * SH4 translation
5fafdf24 3 *
fdf9b3e8
FB
4 * Copyright (c) 2005 Samuel Tardieu
5 *
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.
10 *
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.
15 *
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
19 */
20#include <stdarg.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <string.h>
24#include <inttypes.h>
25#include <assert.h>
26
27#define DEBUG_DISAS
28#define SH4_DEBUG_DISAS
29//#define SH4_SINGLE_STEP
30
31#include "cpu.h"
32#include "exec-all.h"
33#include "disas.h"
988d7eaa 34#include "helper.h"
57fec1fe 35#include "tcg-op.h"
ca10f867 36#include "qemu-common.h"
fdf9b3e8
FB
37
38typedef struct DisasContext {
39 struct TranslationBlock *tb;
40 target_ulong pc;
41 uint32_t sr;
eda9b09b 42 uint32_t fpscr;
fdf9b3e8
FB
43 uint16_t opcode;
44 uint32_t flags;
823029f9 45 int bstate;
fdf9b3e8
FB
46 int memidx;
47 uint32_t delayed_pc;
48 int singlestep_enabled;
49} DisasContext;
50
823029f9
TS
51enum {
52 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
53 * exception condition
54 */
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 */
58};
59
1e8864f7
AJ
60/* global register indexes */
61static TCGv cpu_env;
62static TCGv cpu_gregs[24];
3a8a44c4
AJ
63static TCGv cpu_pc, cpu_sr, cpu_ssr, cpu_spc, cpu_gbr;
64static TCGv cpu_vbr, cpu_sgr, cpu_dbr, cpu_mach, cpu_macl;
65static TCGv cpu_pr, cpu_fpscr, cpu_fpul;
1e8864f7
AJ
66
67/* dyngen register indexes */
68static TCGv cpu_T[2];
2e70f6ef
PB
69
70#include "gen-icount.h"
71
a5f1b965 72static void sh4_translate_init(void)
2e70f6ef 73{
1e8864f7 74 int i;
2e70f6ef 75 static int done_init = 0;
559dd74d 76 static const char * const gregnames[24] = {
1e8864f7
AJ
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"
82 };
83
2e70f6ef
PB
84 if (done_init)
85 return;
1e8864f7 86
2e70f6ef 87 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
1e8864f7
AJ
88 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
89 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
90
91 for (i = 0; i < 24; i++)
92 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
93 offsetof(CPUState, gregs[i]),
94 gregnames[i]);
988d7eaa 95
3a8a44c4
AJ
96 cpu_pc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
97 offsetof(CPUState, pc), "PC");
98 cpu_sr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
99 offsetof(CPUState, sr), "SR");
100 cpu_ssr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
101 offsetof(CPUState, ssr), "SSR");
102 cpu_spc = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
103 offsetof(CPUState, spc), "SPC");
104 cpu_gbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
105 offsetof(CPUState, gbr), "GBR");
106 cpu_vbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
107 offsetof(CPUState, vbr), "VBR");
108 cpu_sgr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
109 offsetof(CPUState, sgr), "SGR");
110 cpu_dbr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
111 offsetof(CPUState, dbr), "DBR");
112 cpu_mach = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
113 offsetof(CPUState, mach), "MACH");
114 cpu_macl = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
115 offsetof(CPUState, macl), "MACL");
116 cpu_pr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
117 offsetof(CPUState, pr), "PR");
118 cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
119 offsetof(CPUState, fpscr), "FPSCR");
120 cpu_fpul = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
121 offsetof(CPUState, fpul), "FPUL");
122
988d7eaa
AJ
123 /* register helpers */
124#undef DEF_HELPER
125#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
126#include "helper.h"
127
2e70f6ef
PB
128 done_init = 1;
129}
130
fdf9b3e8
FB
131#ifdef CONFIG_USER_ONLY
132
eda9b09b
FB
133#define GEN_OP_LD(width, reg) \
134 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
135 gen_op_ld##width##_T0_##reg##_raw(); \
fdf9b3e8 136 }
eda9b09b
FB
137#define GEN_OP_ST(width, reg) \
138 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
139 gen_op_st##width##_##reg##_T1_raw(); \
fdf9b3e8
FB
140 }
141
142#else
143
eda9b09b
FB
144#define GEN_OP_LD(width, reg) \
145 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
146 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
147 else gen_op_ld##width##_T0_##reg##_user();\
fdf9b3e8 148 }
eda9b09b
FB
149#define GEN_OP_ST(width, reg) \
150 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
151 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
152 else gen_op_st##width##_##reg##_T1_user();\
fdf9b3e8
FB
153 }
154
155#endif
156
eda9b09b
FB
157GEN_OP_LD(ub, T0)
158GEN_OP_LD(b, T0)
159GEN_OP_ST(b, T0)
160GEN_OP_LD(uw, T0)
161GEN_OP_LD(w, T0)
162GEN_OP_ST(w, T0)
163GEN_OP_LD(l, T0)
164GEN_OP_ST(l, T0)
165GEN_OP_LD(fl, FT0)
166GEN_OP_ST(fl, FT0)
167GEN_OP_LD(fq, DT0)
168GEN_OP_ST(fq, DT0)
fdf9b3e8
FB
169
170void cpu_dump_state(CPUState * env, FILE * f,
171 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
172 int flags)
173{
174 int i;
eda9b09b
FB
175 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
176 env->pc, env->sr, env->pr, env->fpscr);
274a9e70
AJ
177 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
178 env->spc, env->ssr, env->gbr, env->vbr);
179 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
180 env->sgr, env->dbr, env->delayed_pc, env->fpul);
fdf9b3e8
FB
181 for (i = 0; i < 24; i += 4) {
182 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
183 i, env->gregs[i], i + 1, env->gregs[i + 1],
184 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
185 }
186 if (env->flags & DELAY_SLOT) {
187 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
188 env->delayed_pc);
189 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
190 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
191 env->delayed_pc);
192 }
193}
194
195void cpu_sh4_reset(CPUSH4State * env)
196{
9c2a9ea1 197#if defined(CONFIG_USER_ONLY)
4c909d14 198 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
9c2a9ea1 199#else
fdf9b3e8 200 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
9c2a9ea1 201#endif
fdf9b3e8
FB
202 env->vbr = 0;
203 env->pc = 0xA0000000;
ea6cf6be
TS
204#if defined(CONFIG_USER_ONLY)
205 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
b0b3de89 206 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
ea6cf6be
TS
207#else
208 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
b0b3de89 209 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
ea6cf6be 210#endif
fdf9b3e8
FB
211 env->mmucr = 0;
212}
213
aaed909a 214CPUSH4State *cpu_sh4_init(const char *cpu_model)
fdf9b3e8
FB
215{
216 CPUSH4State *env;
217
218 env = qemu_mallocz(sizeof(CPUSH4State));
219 if (!env)
220 return NULL;
221 cpu_exec_init(env);
2e70f6ef 222 sh4_translate_init();
fdf9b3e8
FB
223 cpu_sh4_reset(env);
224 tlb_flush(env, 1);
225 return env;
226}
227
fdf9b3e8
FB
228static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
229{
230 TranslationBlock *tb;
231 tb = ctx->tb;
232
233 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
234 !ctx->singlestep_enabled) {
235 /* Use a direct jump if in same page and singlestep not enabled */
57fec1fe 236 tcg_gen_goto_tb(n);
3a8a44c4 237 tcg_gen_movi_i32(cpu_pc, dest);
57fec1fe 238 tcg_gen_exit_tb((long) tb + n);
fdf9b3e8 239 } else {
3a8a44c4 240 tcg_gen_movi_i32(cpu_pc, dest);
57fec1fe
FB
241 if (ctx->singlestep_enabled)
242 gen_op_debug();
243 tcg_gen_exit_tb(0);
fdf9b3e8 244 }
fdf9b3e8
FB
245}
246
fdf9b3e8
FB
247static void gen_jump(DisasContext * ctx)
248{
249 if (ctx->delayed_pc == (uint32_t) - 1) {
250 /* Target is not statically known, it comes necessarily from a
251 delayed jump as immediate jump are conditinal jumps */
252 gen_op_movl_delayed_pc_PC();
fdf9b3e8
FB
253 if (ctx->singlestep_enabled)
254 gen_op_debug();
57fec1fe 255 tcg_gen_exit_tb(0);
fdf9b3e8
FB
256 } else {
257 gen_goto_tb(ctx, 0, ctx->delayed_pc);
258 }
259}
260
261/* Immediate conditional jump (bt or bf) */
262static void gen_conditional_jump(DisasContext * ctx,
263 target_ulong ift, target_ulong ifnott)
264{
265 int l1;
266
267 l1 = gen_new_label();
268 gen_op_jT(l1);
269 gen_goto_tb(ctx, 0, ifnott);
270 gen_set_label(l1);
271 gen_goto_tb(ctx, 1, ift);
272}
273
274/* Delayed conditional jump (bt or bf) */
275static void gen_delayed_conditional_jump(DisasContext * ctx)
276{
277 int l1;
278
279 l1 = gen_new_label();
9c2a9ea1 280 gen_op_jdelayed(l1);
823029f9 281 gen_goto_tb(ctx, 1, ctx->pc + 2);
fdf9b3e8 282 gen_set_label(l1);
9c2a9ea1 283 gen_jump(ctx);
fdf9b3e8
FB
284}
285
286#define B3_0 (ctx->opcode & 0xf)
287#define B6_4 ((ctx->opcode >> 4) & 0x7)
288#define B7_4 ((ctx->opcode >> 4) & 0xf)
289#define B7_0 (ctx->opcode & 0xff)
290#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
291#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
292 (ctx->opcode & 0xfff))
293#define B11_8 ((ctx->opcode >> 8) & 0xf)
294#define B15_12 ((ctx->opcode >> 12) & 0xf)
295
296#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
297 (x) + 16 : (x))
298
299#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
300 ? (x) + 16 : (x))
301
eda9b09b 302#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
f09111e0 303#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
eda9b09b 304#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
ea6cf6be 305#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
eda9b09b 306
fdf9b3e8
FB
307#define CHECK_NOT_DELAY_SLOT \
308 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
823029f9 309 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
fdf9b3e8
FB
310 return;}
311
823029f9 312void _decode_opc(DisasContext * ctx)
fdf9b3e8
FB
313{
314#if 0
315 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
316#endif
317 switch (ctx->opcode) {
318 case 0x0019: /* div0u */
3a8a44c4 319 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
fdf9b3e8
FB
320 return;
321 case 0x000b: /* rts */
322 CHECK_NOT_DELAY_SLOT gen_op_rts();
323 ctx->flags |= DELAY_SLOT;
324 ctx->delayed_pc = (uint32_t) - 1;
325 return;
326 case 0x0028: /* clrmac */
3a8a44c4
AJ
327 tcg_gen_movi_i32(cpu_mach, 0);
328 tcg_gen_movi_i32(cpu_macl, 0);
fdf9b3e8
FB
329 return;
330 case 0x0048: /* clrs */
3a8a44c4 331 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
fdf9b3e8
FB
332 return;
333 case 0x0008: /* clrt */
3a8a44c4 334 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
fdf9b3e8
FB
335 return;
336 case 0x0038: /* ldtlb */
ea2b542a 337#if defined(CONFIG_USER_ONLY)
fdf9b3e8 338 assert(0); /* XXXXX */
ea2b542a
AJ
339#else
340 gen_op_ldtlb();
341#endif
fdf9b3e8 342 return;
c5e814b2 343 case 0x002b: /* rte */
fdf9b3e8
FB
344 CHECK_NOT_DELAY_SLOT gen_op_rte();
345 ctx->flags |= DELAY_SLOT;
346 ctx->delayed_pc = (uint32_t) - 1;
347 return;
348 case 0x0058: /* sets */
3a8a44c4 349 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
fdf9b3e8
FB
350 return;
351 case 0x0018: /* sett */
3a8a44c4 352 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
fdf9b3e8 353 return;
24988dc2 354 case 0xfbfd: /* frchg */
eda9b09b 355 gen_op_frchg();
823029f9 356 ctx->bstate = BS_STOP;
fdf9b3e8 357 return;
24988dc2 358 case 0xf3fd: /* fschg */
eda9b09b 359 gen_op_fschg();
823029f9 360 ctx->bstate = BS_STOP;
fdf9b3e8
FB
361 return;
362 case 0x0009: /* nop */
363 return;
364 case 0x001b: /* sleep */
833ed386
AJ
365 if (ctx->memidx) {
366 gen_op_sleep();
367 } else {
368 gen_op_raise_illegal_instruction();
369 ctx->bstate = BS_EXCP;
370 }
fdf9b3e8
FB
371 return;
372 }
373
374 switch (ctx->opcode & 0xf000) {
375 case 0x1000: /* mov.l Rm,@(disp,Rn) */
1e8864f7
AJ
376 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
377 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 378 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 4);
fdf9b3e8
FB
379 gen_op_stl_T0_T1(ctx);
380 return;
381 case 0x5000: /* mov.l @(disp,Rm),Rn */
1e8864f7 382 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d 383 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 4);
fdf9b3e8 384 gen_op_ldl_T0_T0(ctx);
1e8864f7 385 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8 386 return;
24988dc2 387 case 0xe000: /* mov #imm,Rn */
1e8864f7 388 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
fdf9b3e8
FB
389 return;
390 case 0x9000: /* mov.w @(disp,PC),Rn */
3bf73a49 391 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
fdf9b3e8 392 gen_op_ldw_T0_T0(ctx);
1e8864f7 393 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
394 return;
395 case 0xd000: /* mov.l @(disp,PC),Rn */
3bf73a49 396 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
fdf9b3e8 397 gen_op_ldl_T0_T0(ctx);
1e8864f7 398 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8 399 return;
24988dc2 400 case 0x7000: /* add #imm,Rn */
559dd74d 401 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], B7_0s);
fdf9b3e8
FB
402 return;
403 case 0xa000: /* bra disp */
404 CHECK_NOT_DELAY_SLOT
405 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
406 ctx->flags |= DELAY_SLOT;
407 return;
408 case 0xb000: /* bsr disp */
409 CHECK_NOT_DELAY_SLOT
410 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
411 ctx->pc + 4 + B11_0s * 2);
412 ctx->flags |= DELAY_SLOT;
413 return;
414 }
415
416 switch (ctx->opcode & 0xf00f) {
417 case 0x6003: /* mov Rm,Rn */
1e8864f7
AJ
418 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
419 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
420 return;
421 case 0x2000: /* mov.b Rm,@Rn */
1e8864f7
AJ
422 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
423 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
424 gen_op_stb_T0_T1(ctx);
425 return;
426 case 0x2001: /* mov.w Rm,@Rn */
1e8864f7
AJ
427 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
428 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
429 gen_op_stw_T0_T1(ctx);
430 return;
431 case 0x2002: /* mov.l Rm,@Rn */
1e8864f7
AJ
432 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
433 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
434 gen_op_stl_T0_T1(ctx);
435 return;
436 case 0x6000: /* mov.b @Rm,Rn */
1e8864f7 437 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 438 gen_op_ldb_T0_T0(ctx);
1e8864f7 439 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
440 return;
441 case 0x6001: /* mov.w @Rm,Rn */
1e8864f7 442 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 443 gen_op_ldw_T0_T0(ctx);
1e8864f7 444 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
445 return;
446 case 0x6002: /* mov.l @Rm,Rn */
1e8864f7 447 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 448 gen_op_ldl_T0_T0(ctx);
1e8864f7 449 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
450 return;
451 case 0x2004: /* mov.b Rm,@-Rn */
1e8864f7 452 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d
AJ
453 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
454 cpu_gregs[REG(B11_8)], 1); /* modify register status */
1e8864f7 455 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d
AJ
456 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
457 cpu_gregs[REG(B11_8)], 1); /* recover register status */
458 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
459 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
460 cpu_gregs[REG(B11_8)], 1); /* modify register status */
fdf9b3e8
FB
461 return;
462 case 0x2005: /* mov.w Rm,@-Rn */
1e8864f7 463 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d
AJ
464 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
465 cpu_gregs[REG(B11_8)], 2);
1e8864f7 466 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d
AJ
467 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
468 cpu_gregs[REG(B11_8)], 2);
fdf9b3e8 469 gen_op_stw_T0_T1(ctx);
559dd74d
AJ
470 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
471 cpu_gregs[REG(B11_8)], 2);
fdf9b3e8
FB
472 return;
473 case 0x2006: /* mov.l Rm,@-Rn */
1e8864f7 474 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d
AJ
475 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
476 cpu_gregs[REG(B11_8)], 4);
1e8864f7 477 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d
AJ
478 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
479 cpu_gregs[REG(B11_8)], 4);
fdf9b3e8 480 gen_op_stl_T0_T1(ctx);
559dd74d
AJ
481 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
482 cpu_gregs[REG(B11_8)], 4);
fdf9b3e8 483 return;
eda9b09b 484 case 0x6004: /* mov.b @Rm+,Rn */
1e8864f7 485 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 486 gen_op_ldb_T0_T0(ctx);
1e8864f7 487 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
24988dc2 488 if ( B11_8 != B7_4 )
559dd74d
AJ
489 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
490 cpu_gregs[REG(B7_4)], 1);
fdf9b3e8
FB
491 return;
492 case 0x6005: /* mov.w @Rm+,Rn */
1e8864f7 493 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 494 gen_op_ldw_T0_T0(ctx);
1e8864f7 495 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
24988dc2 496 if ( B11_8 != B7_4 )
559dd74d
AJ
497 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
498 cpu_gregs[REG(B7_4)], 2);
fdf9b3e8
FB
499 return;
500 case 0x6006: /* mov.l @Rm+,Rn */
1e8864f7 501 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 502 gen_op_ldl_T0_T0(ctx);
1e8864f7 503 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
24988dc2 504 if ( B11_8 != B7_4 )
559dd74d
AJ
505 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
506 cpu_gregs[REG(B7_4)], 4);
fdf9b3e8
FB
507 return;
508 case 0x0004: /* mov.b Rm,@(R0,Rn) */
1e8864f7
AJ
509 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
510 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 511 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
fdf9b3e8
FB
512 gen_op_stb_T0_T1(ctx);
513 return;
514 case 0x0005: /* mov.w Rm,@(R0,Rn) */
1e8864f7
AJ
515 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
516 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 517 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
fdf9b3e8
FB
518 gen_op_stw_T0_T1(ctx);
519 return;
520 case 0x0006: /* mov.l Rm,@(R0,Rn) */
1e8864f7
AJ
521 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
522 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 523 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
fdf9b3e8
FB
524 gen_op_stl_T0_T1(ctx);
525 return;
526 case 0x000c: /* mov.b @(R0,Rm),Rn */
559dd74d 527 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
fdf9b3e8 528 gen_op_ldb_T0_T0(ctx);
1e8864f7 529 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
530 return;
531 case 0x000d: /* mov.w @(R0,Rm),Rn */
559dd74d 532 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
fdf9b3e8 533 gen_op_ldw_T0_T0(ctx);
1e8864f7 534 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
535 return;
536 case 0x000e: /* mov.l @(R0,Rm),Rn */
559dd74d 537 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
fdf9b3e8 538 gen_op_ldl_T0_T0(ctx);
1e8864f7 539 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
540 return;
541 case 0x6008: /* swap.b Rm,Rn */
559dd74d
AJ
542 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], 0xffff0000);
543 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xff);
544 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
545 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
546 tcg_gen_shri_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 8);
547 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
548 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
549 return;
550 case 0x6009: /* swap.w Rm,Rn */
559dd74d
AJ
551 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
552 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
553 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B7_4)], 16);
554 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
555 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
556 return;
557 case 0x200d: /* xtrct Rm,Rn */
559dd74d
AJ
558 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
559 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
560 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 16);
561 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
5aa3b1ea 562 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
563 return;
564 case 0x300c: /* add Rm,Rn */
559dd74d 565 tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
566 return;
567 case 0x300e: /* addc Rm,Rn */
1e8864f7
AJ
568 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
569 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 570 gen_op_addc_T0_T1();
1e8864f7 571 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
572 return;
573 case 0x300f: /* addv Rm,Rn */
1e8864f7
AJ
574 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
575 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 576 gen_op_addv_T0_T1();
1e8864f7 577 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
578 return;
579 case 0x2009: /* and Rm,Rn */
559dd74d 580 tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
581 return;
582 case 0x3000: /* cmp/eq Rm,Rn */
1e8864f7
AJ
583 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
584 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
585 gen_op_cmp_eq_T0_T1();
586 return;
587 case 0x3003: /* cmp/ge Rm,Rn */
1e8864f7
AJ
588 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
589 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
590 gen_op_cmp_ge_T0_T1();
591 return;
592 case 0x3007: /* cmp/gt Rm,Rn */
1e8864f7
AJ
593 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
594 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
595 gen_op_cmp_gt_T0_T1();
596 return;
597 case 0x3006: /* cmp/hi Rm,Rn */
1e8864f7
AJ
598 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
599 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
600 gen_op_cmp_hi_T0_T1();
601 return;
602 case 0x3002: /* cmp/hs Rm,Rn */
1e8864f7
AJ
603 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
604 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
605 gen_op_cmp_hs_T0_T1();
606 return;
607 case 0x200c: /* cmp/str Rm,Rn */
1e8864f7
AJ
608 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
609 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
610 gen_op_cmp_str_T0_T1();
611 return;
612 case 0x2007: /* div0s Rm,Rn */
1e8864f7
AJ
613 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
614 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 615 gen_op_div0s_T0_T1();
fdf9b3e8
FB
616 return;
617 case 0x3004: /* div1 Rm,Rn */
1e8864f7
AJ
618 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
619 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 620 gen_op_div1_T0_T1();
1e8864f7 621 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
622 return;
623 case 0x300d: /* dmuls.l Rm,Rn */
1e8864f7
AJ
624 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
625 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
626 gen_op_dmulsl_T0_T1();
627 return;
628 case 0x3005: /* dmulu.l Rm,Rn */
1e8864f7
AJ
629 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
630 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
631 gen_op_dmulul_T0_T1();
632 return;
633 case 0x600e: /* exts.b Rm,Rn */
1e8864f7 634 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49
AJ
635 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
636 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1e8864f7 637 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
638 return;
639 case 0x600f: /* exts.w Rm,Rn */
1e8864f7 640 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49
AJ
641 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
642 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1e8864f7 643 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
644 return;
645 case 0x600c: /* extu.b Rm,Rn */
1e8864f7 646 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49 647 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
1e8864f7 648 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
649 return;
650 case 0x600d: /* extu.w Rm,Rn */
1e8864f7 651 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49 652 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
1e8864f7 653 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8 654 return;
24988dc2 655 case 0x000f: /* mac.l @Rm+,@Rn+ */
1e8864f7 656 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8 657 gen_op_ldl_T0_T0(ctx);
829337a6 658 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 659 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
660 gen_op_ldl_T0_T0(ctx);
661 gen_op_macl_T0_T1();
559dd74d
AJ
662 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
663 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8
FB
664 return;
665 case 0x400f: /* mac.w @Rm+,@Rn+ */
1e8864f7 666 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8 667 gen_op_ldl_T0_T0(ctx);
829337a6 668 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 669 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
670 gen_op_ldl_T0_T0(ctx);
671 gen_op_macw_T0_T1();
559dd74d
AJ
672 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
673 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
fdf9b3e8
FB
674 return;
675 case 0x0007: /* mul.l Rm,Rn */
1e8864f7
AJ
676 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
677 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
678 gen_op_mull_T0_T1();
679 return;
680 case 0x200f: /* muls.w Rm,Rn */
1e8864f7 681 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49
AJ
682 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
683 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1e8864f7 684 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
3bf73a49
AJ
685 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
686 tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
fdf9b3e8
FB
687 gen_op_mulsw_T0_T1();
688 return;
689 case 0x200e: /* mulu.w Rm,Rn */
1e8864f7 690 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49 691 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
1e8864f7 692 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
3bf73a49 693 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
fdf9b3e8
FB
694 gen_op_muluw_T0_T1();
695 return;
696 case 0x600b: /* neg Rm,Rn */
559dd74d 697 tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
698 return;
699 case 0x600a: /* negc Rm,Rn */
1e8864f7 700 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 701 gen_op_negc_T0();
1e8864f7 702 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
703 return;
704 case 0x6007: /* not Rm,Rn */
559dd74d 705 tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
706 return;
707 case 0x200b: /* or Rm,Rn */
559dd74d 708 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
709 return;
710 case 0x400c: /* shad Rm,Rn */
1e8864f7
AJ
711 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
712 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 713 gen_op_shad_T0_T1();
1e8864f7 714 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
715 return;
716 case 0x400d: /* shld Rm,Rn */
1e8864f7
AJ
717 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
718 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 719 gen_op_shld_T0_T1();
1e8864f7 720 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
721 return;
722 case 0x3008: /* sub Rm,Rn */
559dd74d 723 tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
724 return;
725 case 0x300a: /* subc Rm,Rn */
1e8864f7
AJ
726 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
727 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 728 gen_op_subc_T0_T1();
1e8864f7 729 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
730 return;
731 case 0x300b: /* subv Rm,Rn */
1e8864f7
AJ
732 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
733 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 734 gen_op_subv_T0_T1();
1e8864f7 735 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
736 return;
737 case 0x2008: /* tst Rm,Rn */
1e8864f7
AJ
738 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
739 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
740 gen_op_tst_T0_T1();
741 return;
742 case 0x200a: /* xor Rm,Rn */
559dd74d 743 tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8 744 return;
e67888a7 745 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 746 if (ctx->fpscr & FPSCR_SZ) {
24988dc2
AJ
747 gen_op_fmov_drN_DT0(XREG(B7_4));
748 gen_op_fmov_DT0_drN(XREG(B11_8));
eda9b09b
FB
749 } else {
750 gen_op_fmov_frN_FT0(FREG(B7_4));
751 gen_op_fmov_FT0_frN(FREG(B11_8));
752 }
753 return;
e67888a7 754 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
022a22c7 755 if (ctx->fpscr & FPSCR_SZ) {
24988dc2 756 gen_op_fmov_drN_DT0(XREG(B7_4));
1e8864f7 757 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
eda9b09b
FB
758 gen_op_stfq_DT0_T1(ctx);
759 } else {
760 gen_op_fmov_frN_FT0(FREG(B7_4));
1e8864f7 761 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
eda9b09b
FB
762 gen_op_stfl_FT0_T1(ctx);
763 }
764 return;
e67888a7 765 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 766 if (ctx->fpscr & FPSCR_SZ) {
1e8864f7 767 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 768 gen_op_ldfq_T0_DT0(ctx);
24988dc2 769 gen_op_fmov_DT0_drN(XREG(B11_8));
eda9b09b 770 } else {
1e8864f7 771 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 772 gen_op_ldfl_T0_FT0(ctx);
f09111e0 773 gen_op_fmov_FT0_frN(FREG(B11_8));
eda9b09b
FB
774 }
775 return;
e67888a7 776 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 777 if (ctx->fpscr & FPSCR_SZ) {
1e8864f7 778 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 779 gen_op_ldfq_T0_DT0(ctx);
24988dc2 780 gen_op_fmov_DT0_drN(XREG(B11_8));
559dd74d
AJ
781 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
782 cpu_gregs[REG(B7_4)], 8);
eda9b09b 783 } else {
1e8864f7 784 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 785 gen_op_ldfl_T0_FT0(ctx);
f09111e0 786 gen_op_fmov_FT0_frN(FREG(B11_8));
559dd74d
AJ
787 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
788 cpu_gregs[REG(B7_4)], 4);
eda9b09b
FB
789 }
790 return;
e67888a7 791 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
022a22c7 792 if (ctx->fpscr & FPSCR_SZ) {
559dd74d 793 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
24988dc2 794 gen_op_fmov_drN_DT0(XREG(B7_4));
1e8864f7 795 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 796 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
eda9b09b 797 gen_op_stfq_DT0_T1(ctx);
559dd74d 798 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
eda9b09b 799 } else {
559dd74d 800 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
eda9b09b 801 gen_op_fmov_frN_FT0(FREG(B7_4));
1e8864f7 802 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 803 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
eda9b09b 804 gen_op_stfl_FT0_T1(ctx);
559dd74d 805 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
eda9b09b
FB
806 }
807 return;
e67888a7 808 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
559dd74d 809 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
022a22c7 810 if (ctx->fpscr & FPSCR_SZ) {
eda9b09b 811 gen_op_ldfq_T0_DT0(ctx);
24988dc2 812 gen_op_fmov_DT0_drN(XREG(B11_8));
eda9b09b 813 } else {
eda9b09b 814 gen_op_ldfl_T0_FT0(ctx);
f09111e0 815 gen_op_fmov_FT0_frN(FREG(B11_8));
eda9b09b
FB
816 }
817 return;
e67888a7 818 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
022a22c7 819 if (ctx->fpscr & FPSCR_SZ) {
24988dc2 820 gen_op_fmov_drN_DT0(XREG(B7_4));
1e8864f7 821 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 822 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
eda9b09b
FB
823 gen_op_stfq_DT0_T1(ctx);
824 } else {
825 gen_op_fmov_frN_FT0(FREG(B7_4));
1e8864f7 826 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 827 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
eda9b09b
FB
828 gen_op_stfl_FT0_T1(ctx);
829 }
830 return;
e67888a7
TS
831 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
832 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
833 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
834 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
835 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
836 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
ea6cf6be
TS
837 if (ctx->fpscr & FPSCR_PR) {
838 if (ctx->opcode & 0x0110)
839 break; /* illegal instruction */
840 gen_op_fmov_drN_DT1(DREG(B7_4));
841 gen_op_fmov_drN_DT0(DREG(B11_8));
842 }
843 else {
844 gen_op_fmov_frN_FT1(FREG(B7_4));
845 gen_op_fmov_frN_FT0(FREG(B11_8));
846 }
847
848 switch (ctx->opcode & 0xf00f) {
849 case 0xf000: /* fadd Rm,Rn */
850 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
851 break;
852 case 0xf001: /* fsub Rm,Rn */
853 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
854 break;
855 case 0xf002: /* fmul Rm,Rn */
856 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
857 break;
858 case 0xf003: /* fdiv Rm,Rn */
859 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
860 break;
861 case 0xf004: /* fcmp/eq Rm,Rn */
24988dc2 862 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
ea6cf6be
TS
863 return;
864 case 0xf005: /* fcmp/gt Rm,Rn */
24988dc2 865 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
ea6cf6be
TS
866 return;
867 }
868
869 if (ctx->fpscr & FPSCR_PR) {
870 gen_op_fmov_DT0_drN(DREG(B11_8));
871 }
872 else {
873 gen_op_fmov_FT0_frN(FREG(B11_8));
874 }
875 return;
fdf9b3e8
FB
876 }
877
878 switch (ctx->opcode & 0xff00) {
879 case 0xc900: /* and #imm,R0 */
559dd74d 880 tcg_gen_andi_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
fdf9b3e8 881 return;
24988dc2 882 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1e8864f7 883 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 884 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
829337a6 885 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
24988dc2 886 gen_op_ldub_T0_T0(ctx);
559dd74d 887 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8
FB
888 gen_op_stb_T0_T1(ctx);
889 return;
890 case 0x8b00: /* bf label */
891 CHECK_NOT_DELAY_SLOT
892 gen_conditional_jump(ctx, ctx->pc + 2,
893 ctx->pc + 4 + B7_0s * 2);
823029f9 894 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
895 return;
896 case 0x8f00: /* bf/s label */
897 CHECK_NOT_DELAY_SLOT
898 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
899 ctx->flags |= DELAY_SLOT_CONDITIONAL;
900 return;
901 case 0x8900: /* bt label */
902 CHECK_NOT_DELAY_SLOT
903 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
904 ctx->pc + 2);
823029f9 905 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
906 return;
907 case 0x8d00: /* bt/s label */
908 CHECK_NOT_DELAY_SLOT
909 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
910 ctx->flags |= DELAY_SLOT_CONDITIONAL;
911 return;
912 case 0x8800: /* cmp/eq #imm,R0 */
1e8864f7 913 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
fdf9b3e8
FB
914 gen_op_cmp_eq_imm_T0(B7_0s);
915 return;
916 case 0xc400: /* mov.b @(disp,GBR),R0 */
917 gen_op_stc_gbr_T0();
559dd74d 918 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8 919 gen_op_ldb_T0_T0(ctx);
1e8864f7 920 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
921 return;
922 case 0xc500: /* mov.w @(disp,GBR),R0 */
923 gen_op_stc_gbr_T0();
559dd74d 924 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
fdf9b3e8 925 gen_op_ldw_T0_T0(ctx);
1e8864f7 926 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
927 return;
928 case 0xc600: /* mov.l @(disp,GBR),R0 */
929 gen_op_stc_gbr_T0();
559dd74d 930 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
fdf9b3e8 931 gen_op_ldl_T0_T0(ctx);
1e8864f7 932 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
933 return;
934 case 0xc000: /* mov.b R0,@(disp,GBR) */
935 gen_op_stc_gbr_T0();
559dd74d 936 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
829337a6 937 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 938 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
fdf9b3e8
FB
939 gen_op_stb_T0_T1(ctx);
940 return;
941 case 0xc100: /* mov.w R0,@(disp,GBR) */
942 gen_op_stc_gbr_T0();
559dd74d 943 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
829337a6 944 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 945 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
fdf9b3e8
FB
946 gen_op_stw_T0_T1(ctx);
947 return;
948 case 0xc200: /* mov.l R0,@(disp,GBR) */
949 gen_op_stc_gbr_T0();
559dd74d 950 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
829337a6 951 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 952 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
fdf9b3e8
FB
953 gen_op_stl_T0_T1(ctx);
954 return;
955 case 0x8000: /* mov.b R0,@(disp,Rn) */
1e8864f7
AJ
956 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
957 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
559dd74d 958 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0);
fdf9b3e8
FB
959 gen_op_stb_T0_T1(ctx);
960 return;
961 case 0x8100: /* mov.w R0,@(disp,Rn) */
1e8864f7
AJ
962 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
963 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
559dd74d 964 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 2);
fdf9b3e8
FB
965 gen_op_stw_T0_T1(ctx);
966 return;
967 case 0x8400: /* mov.b @(disp,Rn),R0 */
1e8864f7 968 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d 969 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0);
8c2cc7ce 970 gen_op_ldb_T0_T0(ctx);
1e8864f7 971 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
972 return;
973 case 0x8500: /* mov.w @(disp,Rn),R0 */
1e8864f7 974 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d 975 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 2);
fdf9b3e8 976 gen_op_ldw_T0_T0(ctx);
1e8864f7 977 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
978 return;
979 case 0xc700: /* mova @(disp,PC),R0 */
1e8864f7
AJ
980 tcg_gen_movi_i32(cpu_gregs[REG(0)],
981 ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
fdf9b3e8
FB
982 return;
983 case 0xcb00: /* or #imm,R0 */
559dd74d 984 tcg_gen_ori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
fdf9b3e8 985 return;
24988dc2 986 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1e8864f7 987 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 988 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
3bf73a49 989 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
24988dc2 990 gen_op_ldub_T0_T0(ctx);
559dd74d 991 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8
FB
992 gen_op_stb_T0_T1(ctx);
993 return;
994 case 0xc300: /* trapa #imm */
3a8a44c4 995 CHECK_NOT_DELAY_SLOT tcg_gen_movi_i32(cpu_pc, ctx->pc);
fdf9b3e8 996 gen_op_trapa(B7_0);
823029f9 997 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
998 return;
999 case 0xc800: /* tst #imm,R0 */
1000 gen_op_tst_imm_rN(B7_0, REG(0));
1001 return;
24988dc2 1002 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1e8864f7 1003 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 1004 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
24988dc2 1005 gen_op_ldub_T0_T0(ctx);
fdf9b3e8
FB
1006 gen_op_tst_imm_T0(B7_0);
1007 return;
1008 case 0xca00: /* xor #imm,R0 */
559dd74d 1009 tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
fdf9b3e8 1010 return;
24988dc2 1011 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1e8864f7 1012 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 1013 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
829337a6 1014 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
24988dc2 1015 gen_op_ldub_T0_T0(ctx);
559dd74d 1016 tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8
FB
1017 gen_op_stb_T0_T1(ctx);
1018 return;
1019 }
1020
1021 switch (ctx->opcode & 0xf08f) {
1022 case 0x408e: /* ldc Rm,Rn_BANK */
1e8864f7
AJ
1023 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1024 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
fdf9b3e8
FB
1025 return;
1026 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1e8864f7 1027 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8 1028 gen_op_ldl_T0_T0(ctx);
1e8864f7 1029 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
559dd74d 1030 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8
FB
1031 return;
1032 case 0x0082: /* stc Rm_BANK,Rn */
1e8864f7
AJ
1033 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1034 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
1035 return;
1036 case 0x4083: /* stc.l Rm_BANK,@-Rn */
559dd74d 1037 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1e8864f7
AJ
1038 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1039 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
559dd74d 1040 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8 1041 gen_op_stl_T0_T1(ctx);
559dd74d 1042 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8
FB
1043 return;
1044 }
1045
1046 switch (ctx->opcode & 0xf0ff) {
1047 case 0x0023: /* braf Rn */
1e8864f7 1048 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1049 gen_op_braf_T0(ctx->pc + 4);
1050 ctx->flags |= DELAY_SLOT;
1051 ctx->delayed_pc = (uint32_t) - 1;
1052 return;
1053 case 0x0003: /* bsrf Rn */
1e8864f7 1054 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1055 gen_op_bsrf_T0(ctx->pc + 4);
1056 ctx->flags |= DELAY_SLOT;
1057 ctx->delayed_pc = (uint32_t) - 1;
1058 return;
1059 case 0x4015: /* cmp/pl Rn */
1e8864f7 1060 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1061 gen_op_cmp_pl_T0();
1062 return;
1063 case 0x4011: /* cmp/pz Rn */
1e8864f7 1064 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1065 gen_op_cmp_pz_T0();
1066 return;
1067 case 0x4010: /* dt Rn */
1068 gen_op_dt_rN(REG(B11_8));
1069 return;
1070 case 0x402b: /* jmp @Rn */
1e8864f7 1071 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1072 gen_op_jmp_T0();
1073 ctx->flags |= DELAY_SLOT;
1074 ctx->delayed_pc = (uint32_t) - 1;
1075 return;
1076 case 0x400b: /* jsr @Rn */
1e8864f7 1077 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1078 gen_op_jsr_T0(ctx->pc + 4);
1079 ctx->flags |= DELAY_SLOT;
1080 ctx->delayed_pc = (uint32_t) - 1;
1081 return;
1082#define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1083 case ldnum: \
1e8864f7 1084 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
fdf9b3e8
FB
1085 gen_op_##ldop##_T0_##reg (); \
1086 extrald \
1087 return; \
1088 case ldpnum: \
1e8864f7 1089 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
fdf9b3e8 1090 gen_op_ldl_T0_T0 (ctx); \
559dd74d
AJ
1091 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1092 cpu_gregs[REG(B11_8)], 4); \
fdf9b3e8
FB
1093 gen_op_##ldop##_T0_##reg (); \
1094 extrald \
1095 return; \
1096 case stnum: \
8f99cc6c 1097 gen_op_##stop##_##reg##_T0 (); \
1e8864f7 1098 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]); \
fdf9b3e8
FB
1099 return; \
1100 case stpnum: \
1101 gen_op_##stop##_##reg##_T0 (); \
559dd74d
AJ
1102 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1103 cpu_gregs[REG(B11_8)], 4); \
1e8864f7 1104 tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]); \
559dd74d
AJ
1105 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1106 cpu_gregs[REG(B11_8)], 4); \
fdf9b3e8 1107 gen_op_stl_T0_T1 (ctx); \
559dd74d
AJ
1108 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1109 cpu_gregs[REG(B11_8)], 4); \
fdf9b3e8 1110 return;
823029f9
TS
1111 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1112 BS_STOP;)
eda9b09b
FB
1113 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1114 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1115 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1116 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1117 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1118 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1119 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1120 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
8bf5a804 1121 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
823029f9
TS
1122 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1123 BS_STOP;)
fdf9b3e8 1124 case 0x00c3: /* movca.l R0,@Rm */
1e8864f7
AJ
1125 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1126 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1127 gen_op_stl_T0_T1(ctx);
1128 return;
1129 case 0x0029: /* movt Rn */
3a8a44c4 1130 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_sr, SR_T);
fdf9b3e8
FB
1131 return;
1132 case 0x0093: /* ocbi @Rn */
1e8864f7 1133 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1134 gen_op_ldl_T0_T0(ctx);
1135 return;
24988dc2 1136 case 0x00a3: /* ocbp @Rn */
1e8864f7 1137 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1138 gen_op_ldl_T0_T0(ctx);
1139 return;
1140 case 0x00b3: /* ocbwb @Rn */
1e8864f7 1141 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1142 gen_op_ldl_T0_T0(ctx);
1143 return;
1144 case 0x0083: /* pref @Rn */
1145 return;
1146 case 0x4024: /* rotcl Rn */
1147 gen_op_rotcl_Rn(REG(B11_8));
1148 return;
1149 case 0x4025: /* rotcr Rn */
1150 gen_op_rotcr_Rn(REG(B11_8));
1151 return;
1152 case 0x4004: /* rotl Rn */
1153 gen_op_rotl_Rn(REG(B11_8));
1154 return;
1155 case 0x4005: /* rotr Rn */
1156 gen_op_rotr_Rn(REG(B11_8));
1157 return;
1158 case 0x4000: /* shll Rn */
1159 case 0x4020: /* shal Rn */
1160 gen_op_shal_Rn(REG(B11_8));
1161 return;
1162 case 0x4021: /* shar Rn */
1163 gen_op_shar_Rn(REG(B11_8));
1164 return;
1165 case 0x4001: /* shlr Rn */
1166 gen_op_shlr_Rn(REG(B11_8));
1167 return;
1168 case 0x4008: /* shll2 Rn */
559dd74d 1169 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
fdf9b3e8
FB
1170 return;
1171 case 0x4018: /* shll8 Rn */
559dd74d 1172 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
fdf9b3e8
FB
1173 return;
1174 case 0x4028: /* shll16 Rn */
559dd74d 1175 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
fdf9b3e8
FB
1176 return;
1177 case 0x4009: /* shlr2 Rn */
559dd74d 1178 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
fdf9b3e8
FB
1179 return;
1180 case 0x4019: /* shlr8 Rn */
559dd74d 1181 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
fdf9b3e8
FB
1182 return;
1183 case 0x4029: /* shlr16 Rn */
559dd74d 1184 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
fdf9b3e8
FB
1185 return;
1186 case 0x401b: /* tas.b @Rn */
1e8864f7 1187 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
829337a6 1188 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
825c69ce
AJ
1189 gen_op_ldub_T0_T0(ctx);
1190 gen_op_cmp_eq_imm_T0(0);
559dd74d 1191 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
825c69ce 1192 gen_op_stb_T0_T1(ctx);
fdf9b3e8 1193 return;
e67888a7 1194 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
eda9b09b
FB
1195 gen_op_movl_fpul_FT0();
1196 gen_op_fmov_FT0_frN(FREG(B11_8));
1197 return;
e67888a7 1198 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
eda9b09b
FB
1199 gen_op_fmov_frN_FT0(FREG(B11_8));
1200 gen_op_movl_FT0_fpul();
1201 return;
e67888a7 1202 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
ea6cf6be
TS
1203 if (ctx->fpscr & FPSCR_PR) {
1204 if (ctx->opcode & 0x0100)
1205 break; /* illegal instruction */
1206 gen_op_float_DT();
1207 gen_op_fmov_DT0_drN(DREG(B11_8));
1208 }
1209 else {
1210 gen_op_float_FT();
1211 gen_op_fmov_FT0_frN(FREG(B11_8));
1212 }
1213 return;
e67888a7 1214 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
ea6cf6be
TS
1215 if (ctx->fpscr & FPSCR_PR) {
1216 if (ctx->opcode & 0x0100)
1217 break; /* illegal instruction */
1218 gen_op_fmov_drN_DT0(DREG(B11_8));
1219 gen_op_ftrc_DT();
1220 }
1221 else {
1222 gen_op_fmov_frN_FT0(FREG(B11_8));
1223 gen_op_ftrc_FT();
1224 }
1225 return;
24988dc2
AJ
1226 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1227 gen_op_fneg_frN(FREG(B11_8));
1228 return;
1229 case 0xf05d: /* fabs FRn/DRn */
1230 if (ctx->fpscr & FPSCR_PR) {
1231 if (ctx->opcode & 0x0100)
1232 break; /* illegal instruction */
1233 gen_op_fmov_drN_DT0(DREG(B11_8));
1234 gen_op_fabs_DT();
1235 gen_op_fmov_DT0_drN(DREG(B11_8));
1236 } else {
1237 gen_op_fmov_frN_FT0(FREG(B11_8));
1238 gen_op_fabs_FT();
1239 gen_op_fmov_FT0_frN(FREG(B11_8));
1240 }
1241 return;
1242 case 0xf06d: /* fsqrt FRn */
1243 if (ctx->fpscr & FPSCR_PR) {
1244 if (ctx->opcode & 0x0100)
1245 break; /* illegal instruction */
1246 gen_op_fmov_drN_DT0(FREG(B11_8));
1247 gen_op_fsqrt_DT();
1248 gen_op_fmov_DT0_drN(FREG(B11_8));
1249 } else {
1250 gen_op_fmov_frN_FT0(FREG(B11_8));
1251 gen_op_fsqrt_FT();
1252 gen_op_fmov_FT0_frN(FREG(B11_8));
1253 }
1254 return;
1255 case 0xf07d: /* fsrra FRn */
1256 break;
e67888a7 1257 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
ea6cf6be 1258 if (!(ctx->fpscr & FPSCR_PR)) {
3bf73a49 1259 tcg_gen_movi_i32(cpu_T[0], 0);
ea6cf6be
TS
1260 gen_op_fmov_T0_frN(FREG(B11_8));
1261 return;
1262 }
1263 break;
e67888a7 1264 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
ea6cf6be 1265 if (!(ctx->fpscr & FPSCR_PR)) {
3bf73a49 1266 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
ea6cf6be
TS
1267 gen_op_fmov_T0_frN(FREG(B11_8));
1268 return;
1269 }
1270 break;
24988dc2
AJ
1271 case 0xf0ad: /* fcnvsd FPUL,DRn */
1272 gen_op_movl_fpul_FT0();
1273 gen_op_fcnvsd_FT_DT();
1274 gen_op_fmov_DT0_drN(DREG(B11_8));
1275 return;
1276 case 0xf0bd: /* fcnvds DRn,FPUL */
1277 gen_op_fmov_drN_DT0(DREG(B11_8));
1278 gen_op_fcnvds_DT_FT();
1279 gen_op_movl_FT0_fpul();
1280 return;
fdf9b3e8
FB
1281 }
1282
1283 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1284 ctx->opcode, ctx->pc);
1285 gen_op_raise_illegal_instruction();
823029f9
TS
1286 ctx->bstate = BS_EXCP;
1287}
1288
1289void decode_opc(DisasContext * ctx)
1290{
1291 uint32_t old_flags = ctx->flags;
1292
1293 _decode_opc(ctx);
1294
1295 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1296 if (ctx->flags & DELAY_SLOT_CLEARME) {
1297 gen_op_store_flags(0);
274a9e70
AJ
1298 } else {
1299 /* go out of the delay slot */
1300 uint32_t new_flags = ctx->flags;
1301 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1302 gen_op_store_flags(new_flags);
823029f9
TS
1303 }
1304 ctx->flags = 0;
1305 ctx->bstate = BS_BRANCH;
1306 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1307 gen_delayed_conditional_jump(ctx);
1308 } else if (old_flags & DELAY_SLOT) {
1309 gen_jump(ctx);
1310 }
1311
1312 }
274a9e70
AJ
1313
1314 /* go into a delay slot */
1315 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1316 gen_op_store_flags(ctx->flags);
fdf9b3e8
FB
1317}
1318
2cfc5f17 1319static inline void
820e00f2
TS
1320gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1321 int search_pc)
fdf9b3e8
FB
1322{
1323 DisasContext ctx;
1324 target_ulong pc_start;
1325 static uint16_t *gen_opc_end;
355fb23d 1326 int i, ii;
2e70f6ef
PB
1327 int num_insns;
1328 int max_insns;
fdf9b3e8
FB
1329
1330 pc_start = tb->pc;
fdf9b3e8 1331 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
fdf9b3e8 1332 ctx.pc = pc_start;
823029f9
TS
1333 ctx.flags = (uint32_t)tb->flags;
1334 ctx.bstate = BS_NONE;
fdf9b3e8 1335 ctx.sr = env->sr;
eda9b09b 1336 ctx.fpscr = env->fpscr;
fdf9b3e8 1337 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
9854bc46
PB
1338 /* We don't know if the delayed pc came from a dynamic or static branch,
1339 so assume it is a dynamic branch. */
823029f9 1340 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
fdf9b3e8
FB
1341 ctx.tb = tb;
1342 ctx.singlestep_enabled = env->singlestep_enabled;
fdf9b3e8
FB
1343
1344#ifdef DEBUG_DISAS
1345 if (loglevel & CPU_LOG_TB_CPU) {
1346 fprintf(logfile,
1347 "------------------------------------------------\n");
1348 cpu_dump_state(env, logfile, fprintf, 0);
1349 }
1350#endif
1351
355fb23d 1352 ii = -1;
2e70f6ef
PB
1353 num_insns = 0;
1354 max_insns = tb->cflags & CF_COUNT_MASK;
1355 if (max_insns == 0)
1356 max_insns = CF_COUNT_MASK;
1357 gen_icount_start();
823029f9 1358 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
fdf9b3e8
FB
1359 if (env->nb_breakpoints > 0) {
1360 for (i = 0; i < env->nb_breakpoints; i++) {
1361 if (ctx.pc == env->breakpoints[i]) {
1362 /* We have hit a breakpoint - make sure PC is up-to-date */
3a8a44c4 1363 tcg_gen_movi_i32(cpu_pc, ctx.pc);
fdf9b3e8 1364 gen_op_debug();
823029f9 1365 ctx.bstate = BS_EXCP;
fdf9b3e8
FB
1366 break;
1367 }
1368 }
1369 }
355fb23d
PB
1370 if (search_pc) {
1371 i = gen_opc_ptr - gen_opc_buf;
1372 if (ii < i) {
1373 ii++;
1374 while (ii < i)
1375 gen_opc_instr_start[ii++] = 0;
1376 }
1377 gen_opc_pc[ii] = ctx.pc;
823029f9 1378 gen_opc_hflags[ii] = ctx.flags;
355fb23d 1379 gen_opc_instr_start[ii] = 1;
2e70f6ef 1380 gen_opc_icount[ii] = num_insns;
355fb23d 1381 }
2e70f6ef
PB
1382 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1383 gen_io_start();
fdf9b3e8
FB
1384#if 0
1385 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1386 fflush(stderr);
1387#endif
1388 ctx.opcode = lduw_code(ctx.pc);
1389 decode_opc(&ctx);
2e70f6ef 1390 num_insns++;
fdf9b3e8
FB
1391 ctx.pc += 2;
1392 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1393 break;
1394 if (env->singlestep_enabled)
1395 break;
2e70f6ef
PB
1396 if (num_insns >= max_insns)
1397 break;
fdf9b3e8
FB
1398#ifdef SH4_SINGLE_STEP
1399 break;
1400#endif
1401 }
2e70f6ef
PB
1402 if (tb->cflags & CF_LAST_IO)
1403 gen_io_end();
fdf9b3e8 1404 if (env->singlestep_enabled) {
823029f9
TS
1405 gen_op_debug();
1406 } else {
1407 switch (ctx.bstate) {
1408 case BS_STOP:
1409 /* gen_op_interrupt_restart(); */
1410 /* fall through */
1411 case BS_NONE:
1412 if (ctx.flags) {
1413 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1414 }
1415 gen_goto_tb(&ctx, 0, ctx.pc);
1416 break;
1417 case BS_EXCP:
1418 /* gen_op_interrupt_restart(); */
57fec1fe 1419 tcg_gen_exit_tb(0);
823029f9
TS
1420 break;
1421 case BS_BRANCH:
1422 default:
1423 break;
1424 }
fdf9b3e8 1425 }
823029f9 1426
2e70f6ef 1427 gen_icount_end(tb, num_insns);
fdf9b3e8 1428 *gen_opc_ptr = INDEX_op_end;
355fb23d
PB
1429 if (search_pc) {
1430 i = gen_opc_ptr - gen_opc_buf;
1431 ii++;
1432 while (ii <= i)
1433 gen_opc_instr_start[ii++] = 0;
355fb23d
PB
1434 } else {
1435 tb->size = ctx.pc - pc_start;
2e70f6ef 1436 tb->icount = num_insns;
355fb23d 1437 }
fdf9b3e8
FB
1438
1439#ifdef DEBUG_DISAS
1440#ifdef SH4_DEBUG_DISAS
1441 if (loglevel & CPU_LOG_TB_IN_ASM)
1442 fprintf(logfile, "\n");
1443#endif
1444 if (loglevel & CPU_LOG_TB_IN_ASM) {
1445 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1446 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1447 fprintf(logfile, "\n");
1448 }
fdf9b3e8 1449#endif
fdf9b3e8
FB
1450}
1451
2cfc5f17 1452void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
fdf9b3e8 1453{
2cfc5f17 1454 gen_intermediate_code_internal(env, tb, 0);
fdf9b3e8
FB
1455}
1456
2cfc5f17 1457void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
fdf9b3e8 1458{
2cfc5f17 1459 gen_intermediate_code_internal(env, tb, 1);
fdf9b3e8 1460}
d2856f1a
AJ
1461
1462void gen_pc_load(CPUState *env, TranslationBlock *tb,
1463 unsigned long searched_pc, int pc_pos, void *puc)
1464{
1465 env->pc = gen_opc_pc[pc_pos];
1466 env->flags = gen_opc_hflags[pc_pos];
1467}
This page took 0.390109 seconds and 4 git commands to generate.