]> git.proxmox.com Git - qemu.git/blame - target-sh4/translate.c
Fix FCC handling for Sparc64 target, initial patch by Vince Weaver
[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
a4625612
AJ
286static inline void gen_set_t(void)
287{
288 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);
289}
290
291static inline void gen_clr_t(void)
292{
293 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);
294}
295
296static inline void gen_cmp(int cond, TCGv t0, TCGv t1)
297{
298 int label1 = gen_new_label();
299 int label2 = gen_new_label();
300 tcg_gen_brcond_i32(cond, t1, t0, label1);
301 gen_clr_t();
302 tcg_gen_br(label2);
303 gen_set_label(label1);
304 gen_set_t();
305 gen_set_label(label2);
306}
307
308static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm)
309{
310 int label1 = gen_new_label();
311 int label2 = gen_new_label();
312 tcg_gen_brcondi_i32(cond, t0, imm, label1);
313 gen_clr_t();
314 tcg_gen_br(label2);
315 gen_set_label(label1);
316 gen_set_t();
317 gen_set_label(label2);
318}
319
fdf9b3e8
FB
320#define B3_0 (ctx->opcode & 0xf)
321#define B6_4 ((ctx->opcode >> 4) & 0x7)
322#define B7_4 ((ctx->opcode >> 4) & 0xf)
323#define B7_0 (ctx->opcode & 0xff)
324#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
325#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
326 (ctx->opcode & 0xfff))
327#define B11_8 ((ctx->opcode >> 8) & 0xf)
328#define B15_12 ((ctx->opcode >> 12) & 0xf)
329
330#define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
331 (x) + 16 : (x))
332
333#define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
334 ? (x) + 16 : (x))
335
eda9b09b 336#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
f09111e0 337#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
eda9b09b 338#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
ea6cf6be 339#define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
eda9b09b 340
fdf9b3e8
FB
341#define CHECK_NOT_DELAY_SLOT \
342 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
823029f9 343 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
fdf9b3e8
FB
344 return;}
345
823029f9 346void _decode_opc(DisasContext * ctx)
fdf9b3e8
FB
347{
348#if 0
349 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
350#endif
351 switch (ctx->opcode) {
352 case 0x0019: /* div0u */
3a8a44c4 353 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));
fdf9b3e8
FB
354 return;
355 case 0x000b: /* rts */
356 CHECK_NOT_DELAY_SLOT gen_op_rts();
357 ctx->flags |= DELAY_SLOT;
358 ctx->delayed_pc = (uint32_t) - 1;
359 return;
360 case 0x0028: /* clrmac */
3a8a44c4
AJ
361 tcg_gen_movi_i32(cpu_mach, 0);
362 tcg_gen_movi_i32(cpu_macl, 0);
fdf9b3e8
FB
363 return;
364 case 0x0048: /* clrs */
3a8a44c4 365 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);
fdf9b3e8
FB
366 return;
367 case 0x0008: /* clrt */
a4625612 368 gen_clr_t();
fdf9b3e8
FB
369 return;
370 case 0x0038: /* ldtlb */
ea2b542a 371#if defined(CONFIG_USER_ONLY)
fdf9b3e8 372 assert(0); /* XXXXX */
ea2b542a
AJ
373#else
374 gen_op_ldtlb();
375#endif
fdf9b3e8 376 return;
c5e814b2 377 case 0x002b: /* rte */
fdf9b3e8
FB
378 CHECK_NOT_DELAY_SLOT gen_op_rte();
379 ctx->flags |= DELAY_SLOT;
380 ctx->delayed_pc = (uint32_t) - 1;
381 return;
382 case 0x0058: /* sets */
3a8a44c4 383 tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);
fdf9b3e8
FB
384 return;
385 case 0x0018: /* sett */
a4625612 386 gen_set_t();
fdf9b3e8 387 return;
24988dc2 388 case 0xfbfd: /* frchg */
eda9b09b 389 gen_op_frchg();
823029f9 390 ctx->bstate = BS_STOP;
fdf9b3e8 391 return;
24988dc2 392 case 0xf3fd: /* fschg */
eda9b09b 393 gen_op_fschg();
823029f9 394 ctx->bstate = BS_STOP;
fdf9b3e8
FB
395 return;
396 case 0x0009: /* nop */
397 return;
398 case 0x001b: /* sleep */
833ed386
AJ
399 if (ctx->memidx) {
400 gen_op_sleep();
401 } else {
402 gen_op_raise_illegal_instruction();
403 ctx->bstate = BS_EXCP;
404 }
fdf9b3e8
FB
405 return;
406 }
407
408 switch (ctx->opcode & 0xf000) {
409 case 0x1000: /* mov.l Rm,@(disp,Rn) */
1e8864f7
AJ
410 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
411 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 412 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 4);
fdf9b3e8
FB
413 gen_op_stl_T0_T1(ctx);
414 return;
415 case 0x5000: /* mov.l @(disp,Rm),Rn */
1e8864f7 416 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d 417 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 4);
fdf9b3e8 418 gen_op_ldl_T0_T0(ctx);
1e8864f7 419 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8 420 return;
24988dc2 421 case 0xe000: /* mov #imm,Rn */
1e8864f7 422 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
fdf9b3e8
FB
423 return;
424 case 0x9000: /* mov.w @(disp,PC),Rn */
3bf73a49 425 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
fdf9b3e8 426 gen_op_ldw_T0_T0(ctx);
1e8864f7 427 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
428 return;
429 case 0xd000: /* mov.l @(disp,PC),Rn */
3bf73a49 430 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
fdf9b3e8 431 gen_op_ldl_T0_T0(ctx);
1e8864f7 432 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8 433 return;
24988dc2 434 case 0x7000: /* add #imm,Rn */
559dd74d 435 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], B7_0s);
fdf9b3e8
FB
436 return;
437 case 0xa000: /* bra disp */
438 CHECK_NOT_DELAY_SLOT
439 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
440 ctx->flags |= DELAY_SLOT;
441 return;
442 case 0xb000: /* bsr disp */
443 CHECK_NOT_DELAY_SLOT
444 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
445 ctx->pc + 4 + B11_0s * 2);
446 ctx->flags |= DELAY_SLOT;
447 return;
448 }
449
450 switch (ctx->opcode & 0xf00f) {
451 case 0x6003: /* mov Rm,Rn */
1e8864f7
AJ
452 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
453 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
454 return;
455 case 0x2000: /* mov.b Rm,@Rn */
1e8864f7
AJ
456 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
457 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
458 gen_op_stb_T0_T1(ctx);
459 return;
460 case 0x2001: /* mov.w Rm,@Rn */
1e8864f7
AJ
461 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
462 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
463 gen_op_stw_T0_T1(ctx);
464 return;
465 case 0x2002: /* mov.l Rm,@Rn */
1e8864f7
AJ
466 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
467 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
468 gen_op_stl_T0_T1(ctx);
469 return;
470 case 0x6000: /* mov.b @Rm,Rn */
1e8864f7 471 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 472 gen_op_ldb_T0_T0(ctx);
1e8864f7 473 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
474 return;
475 case 0x6001: /* mov.w @Rm,Rn */
1e8864f7 476 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 477 gen_op_ldw_T0_T0(ctx);
1e8864f7 478 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
479 return;
480 case 0x6002: /* mov.l @Rm,Rn */
1e8864f7 481 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 482 gen_op_ldl_T0_T0(ctx);
1e8864f7 483 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
484 return;
485 case 0x2004: /* mov.b Rm,@-Rn */
1e8864f7 486 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d
AJ
487 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
488 cpu_gregs[REG(B11_8)], 1); /* modify register status */
1e8864f7 489 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d
AJ
490 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
491 cpu_gregs[REG(B11_8)], 1); /* recover register status */
492 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
493 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
494 cpu_gregs[REG(B11_8)], 1); /* modify register status */
fdf9b3e8
FB
495 return;
496 case 0x2005: /* mov.w Rm,@-Rn */
1e8864f7 497 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d
AJ
498 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
499 cpu_gregs[REG(B11_8)], 2);
1e8864f7 500 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d
AJ
501 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
502 cpu_gregs[REG(B11_8)], 2);
fdf9b3e8 503 gen_op_stw_T0_T1(ctx);
559dd74d
AJ
504 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
505 cpu_gregs[REG(B11_8)], 2);
fdf9b3e8
FB
506 return;
507 case 0x2006: /* mov.l Rm,@-Rn */
1e8864f7 508 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d
AJ
509 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
510 cpu_gregs[REG(B11_8)], 4);
1e8864f7 511 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d
AJ
512 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
513 cpu_gregs[REG(B11_8)], 4);
fdf9b3e8 514 gen_op_stl_T0_T1(ctx);
559dd74d
AJ
515 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
516 cpu_gregs[REG(B11_8)], 4);
fdf9b3e8 517 return;
eda9b09b 518 case 0x6004: /* mov.b @Rm+,Rn */
1e8864f7 519 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 520 gen_op_ldb_T0_T0(ctx);
1e8864f7 521 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
24988dc2 522 if ( B11_8 != B7_4 )
559dd74d
AJ
523 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
524 cpu_gregs[REG(B7_4)], 1);
fdf9b3e8
FB
525 return;
526 case 0x6005: /* mov.w @Rm+,Rn */
1e8864f7 527 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 528 gen_op_ldw_T0_T0(ctx);
1e8864f7 529 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
24988dc2 530 if ( B11_8 != B7_4 )
559dd74d
AJ
531 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
532 cpu_gregs[REG(B7_4)], 2);
fdf9b3e8
FB
533 return;
534 case 0x6006: /* mov.l @Rm+,Rn */
1e8864f7 535 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 536 gen_op_ldl_T0_T0(ctx);
1e8864f7 537 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
24988dc2 538 if ( B11_8 != B7_4 )
559dd74d
AJ
539 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
540 cpu_gregs[REG(B7_4)], 4);
fdf9b3e8
FB
541 return;
542 case 0x0004: /* mov.b Rm,@(R0,Rn) */
1e8864f7
AJ
543 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
544 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 545 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
fdf9b3e8
FB
546 gen_op_stb_T0_T1(ctx);
547 return;
548 case 0x0005: /* mov.w Rm,@(R0,Rn) */
1e8864f7
AJ
549 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
550 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 551 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
fdf9b3e8
FB
552 gen_op_stw_T0_T1(ctx);
553 return;
554 case 0x0006: /* mov.l Rm,@(R0,Rn) */
1e8864f7
AJ
555 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
556 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 557 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
fdf9b3e8
FB
558 gen_op_stl_T0_T1(ctx);
559 return;
560 case 0x000c: /* mov.b @(R0,Rm),Rn */
559dd74d 561 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
fdf9b3e8 562 gen_op_ldb_T0_T0(ctx);
1e8864f7 563 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
564 return;
565 case 0x000d: /* mov.w @(R0,Rm),Rn */
559dd74d 566 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
fdf9b3e8 567 gen_op_ldw_T0_T0(ctx);
1e8864f7 568 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
569 return;
570 case 0x000e: /* mov.l @(R0,Rm),Rn */
559dd74d 571 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
fdf9b3e8 572 gen_op_ldl_T0_T0(ctx);
1e8864f7 573 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
574 return;
575 case 0x6008: /* swap.b Rm,Rn */
559dd74d
AJ
576 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], 0xffff0000);
577 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xff);
578 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
579 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
580 tcg_gen_shri_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 8);
581 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
582 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
583 return;
584 case 0x6009: /* swap.w Rm,Rn */
559dd74d
AJ
585 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
586 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
587 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B7_4)], 16);
588 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
589 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
590 return;
591 case 0x200d: /* xtrct Rm,Rn */
559dd74d
AJ
592 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
593 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
594 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 16);
595 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
5aa3b1ea 596 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
597 return;
598 case 0x300c: /* add Rm,Rn */
559dd74d 599 tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
600 return;
601 case 0x300e: /* addc Rm,Rn */
1e8864f7
AJ
602 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
603 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 604 gen_op_addc_T0_T1();
1e8864f7 605 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
606 return;
607 case 0x300f: /* addv 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 610 gen_op_addv_T0_T1();
1e8864f7 611 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
612 return;
613 case 0x2009: /* and Rm,Rn */
559dd74d 614 tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
615 return;
616 case 0x3000: /* cmp/eq Rm,Rn */
1e8864f7
AJ
617 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
618 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
a4625612 619 gen_cmp(TCG_COND_EQ, cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
620 return;
621 case 0x3003: /* cmp/ge Rm,Rn */
1e8864f7
AJ
622 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
623 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
a4625612 624 gen_cmp(TCG_COND_GE, cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
625 return;
626 case 0x3007: /* cmp/gt Rm,Rn */
1e8864f7
AJ
627 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
628 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
a4625612 629 gen_cmp(TCG_COND_GT, cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
630 return;
631 case 0x3006: /* cmp/hi Rm,Rn */
1e8864f7
AJ
632 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
633 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
a4625612 634 gen_cmp(TCG_COND_GTU, cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
635 return;
636 case 0x3002: /* cmp/hs Rm,Rn */
1e8864f7
AJ
637 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
638 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
a4625612 639 gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]);
fdf9b3e8
FB
640 return;
641 case 0x200c: /* cmp/str Rm,Rn */
1e8864f7
AJ
642 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
643 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
644 gen_op_cmp_str_T0_T1();
645 return;
646 case 0x2007: /* div0s Rm,Rn */
1e8864f7
AJ
647 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
648 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 649 gen_op_div0s_T0_T1();
fdf9b3e8
FB
650 return;
651 case 0x3004: /* div1 Rm,Rn */
1e8864f7
AJ
652 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
653 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 654 gen_op_div1_T0_T1();
1e8864f7 655 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
656 return;
657 case 0x300d: /* dmuls.l Rm,Rn */
1e8864f7
AJ
658 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
659 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
660 gen_op_dmulsl_T0_T1();
661 return;
662 case 0x3005: /* dmulu.l Rm,Rn */
1e8864f7
AJ
663 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
664 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
665 gen_op_dmulul_T0_T1();
666 return;
667 case 0x600e: /* exts.b Rm,Rn */
1e8864f7 668 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49
AJ
669 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
670 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
1e8864f7 671 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
672 return;
673 case 0x600f: /* exts.w Rm,Rn */
1e8864f7 674 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49
AJ
675 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
676 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1e8864f7 677 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
678 return;
679 case 0x600c: /* extu.b Rm,Rn */
1e8864f7 680 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49 681 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
1e8864f7 682 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
683 return;
684 case 0x600d: /* extu.w Rm,Rn */
1e8864f7 685 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49 686 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
1e8864f7 687 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8 688 return;
24988dc2 689 case 0x000f: /* mac.l @Rm+,@Rn+ */
1e8864f7 690 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8 691 gen_op_ldl_T0_T0(ctx);
829337a6 692 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 693 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
694 gen_op_ldl_T0_T0(ctx);
695 gen_op_macl_T0_T1();
559dd74d
AJ
696 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
697 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8
FB
698 return;
699 case 0x400f: /* mac.w @Rm+,@Rn+ */
1e8864f7 700 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8 701 gen_op_ldl_T0_T0(ctx);
829337a6 702 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 703 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
704 gen_op_ldl_T0_T0(ctx);
705 gen_op_macw_T0_T1();
559dd74d
AJ
706 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
707 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
fdf9b3e8
FB
708 return;
709 case 0x0007: /* mul.l Rm,Rn */
1e8864f7
AJ
710 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
711 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
712 gen_op_mull_T0_T1();
713 return;
714 case 0x200f: /* muls.w Rm,Rn */
1e8864f7 715 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49
AJ
716 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
717 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
1e8864f7 718 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
3bf73a49
AJ
719 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
720 tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
fdf9b3e8
FB
721 gen_op_mulsw_T0_T1();
722 return;
723 case 0x200e: /* mulu.w Rm,Rn */
1e8864f7 724 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
3bf73a49 725 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
1e8864f7 726 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
3bf73a49 727 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
fdf9b3e8
FB
728 gen_op_muluw_T0_T1();
729 return;
730 case 0x600b: /* neg Rm,Rn */
559dd74d 731 tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
732 return;
733 case 0x600a: /* negc Rm,Rn */
1e8864f7 734 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
fdf9b3e8 735 gen_op_negc_T0();
1e8864f7 736 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
737 return;
738 case 0x6007: /* not Rm,Rn */
559dd74d 739 tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
740 return;
741 case 0x200b: /* or Rm,Rn */
559dd74d 742 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
743 return;
744 case 0x400c: /* shad Rm,Rn */
1e8864f7
AJ
745 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
746 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 747 gen_op_shad_T0_T1();
1e8864f7 748 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
749 return;
750 case 0x400d: /* shld Rm,Rn */
1e8864f7
AJ
751 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
752 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 753 gen_op_shld_T0_T1();
1e8864f7 754 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
755 return;
756 case 0x3008: /* sub Rm,Rn */
559dd74d 757 tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8
FB
758 return;
759 case 0x300a: /* subc Rm,Rn */
1e8864f7
AJ
760 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
761 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 762 gen_op_subc_T0_T1();
1e8864f7 763 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
764 return;
765 case 0x300b: /* subv Rm,Rn */
1e8864f7
AJ
766 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
767 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8 768 gen_op_subv_T0_T1();
1e8864f7 769 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
fdf9b3e8
FB
770 return;
771 case 0x2008: /* tst Rm,Rn */
1e8864f7
AJ
772 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
773 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
a4625612
AJ
774 tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
775 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
fdf9b3e8
FB
776 return;
777 case 0x200a: /* xor Rm,Rn */
559dd74d 778 tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
fdf9b3e8 779 return;
e67888a7 780 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 781 if (ctx->fpscr & FPSCR_SZ) {
24988dc2
AJ
782 gen_op_fmov_drN_DT0(XREG(B7_4));
783 gen_op_fmov_DT0_drN(XREG(B11_8));
eda9b09b
FB
784 } else {
785 gen_op_fmov_frN_FT0(FREG(B7_4));
786 gen_op_fmov_FT0_frN(FREG(B11_8));
787 }
788 return;
e67888a7 789 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
022a22c7 790 if (ctx->fpscr & FPSCR_SZ) {
24988dc2 791 gen_op_fmov_drN_DT0(XREG(B7_4));
1e8864f7 792 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
eda9b09b
FB
793 gen_op_stfq_DT0_T1(ctx);
794 } else {
795 gen_op_fmov_frN_FT0(FREG(B7_4));
1e8864f7 796 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
eda9b09b
FB
797 gen_op_stfl_FT0_T1(ctx);
798 }
799 return;
e67888a7 800 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 801 if (ctx->fpscr & FPSCR_SZ) {
1e8864f7 802 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 803 gen_op_ldfq_T0_DT0(ctx);
24988dc2 804 gen_op_fmov_DT0_drN(XREG(B11_8));
eda9b09b 805 } else {
1e8864f7 806 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 807 gen_op_ldfl_T0_FT0(ctx);
f09111e0 808 gen_op_fmov_FT0_frN(FREG(B11_8));
eda9b09b
FB
809 }
810 return;
e67888a7 811 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
022a22c7 812 if (ctx->fpscr & FPSCR_SZ) {
1e8864f7 813 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 814 gen_op_ldfq_T0_DT0(ctx);
24988dc2 815 gen_op_fmov_DT0_drN(XREG(B11_8));
559dd74d
AJ
816 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
817 cpu_gregs[REG(B7_4)], 8);
eda9b09b 818 } else {
1e8864f7 819 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
eda9b09b 820 gen_op_ldfl_T0_FT0(ctx);
f09111e0 821 gen_op_fmov_FT0_frN(FREG(B11_8));
559dd74d
AJ
822 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
823 cpu_gregs[REG(B7_4)], 4);
eda9b09b
FB
824 }
825 return;
e67888a7 826 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
022a22c7 827 if (ctx->fpscr & FPSCR_SZ) {
559dd74d 828 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
24988dc2 829 gen_op_fmov_drN_DT0(XREG(B7_4));
1e8864f7 830 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 831 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
eda9b09b 832 gen_op_stfq_DT0_T1(ctx);
559dd74d 833 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
eda9b09b 834 } else {
559dd74d 835 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
eda9b09b 836 gen_op_fmov_frN_FT0(FREG(B7_4));
1e8864f7 837 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 838 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
eda9b09b 839 gen_op_stfl_FT0_T1(ctx);
559dd74d 840 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
eda9b09b
FB
841 }
842 return;
e67888a7 843 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
559dd74d 844 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
022a22c7 845 if (ctx->fpscr & FPSCR_SZ) {
eda9b09b 846 gen_op_ldfq_T0_DT0(ctx);
24988dc2 847 gen_op_fmov_DT0_drN(XREG(B11_8));
eda9b09b 848 } else {
eda9b09b 849 gen_op_ldfl_T0_FT0(ctx);
f09111e0 850 gen_op_fmov_FT0_frN(FREG(B11_8));
eda9b09b
FB
851 }
852 return;
e67888a7 853 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
022a22c7 854 if (ctx->fpscr & FPSCR_SZ) {
24988dc2 855 gen_op_fmov_drN_DT0(XREG(B7_4));
1e8864f7 856 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 857 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
eda9b09b
FB
858 gen_op_stfq_DT0_T1(ctx);
859 } else {
860 gen_op_fmov_frN_FT0(FREG(B7_4));
1e8864f7 861 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559dd74d 862 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
eda9b09b
FB
863 gen_op_stfl_FT0_T1(ctx);
864 }
865 return;
e67888a7
TS
866 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
867 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
868 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
869 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
870 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
871 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
ea6cf6be
TS
872 if (ctx->fpscr & FPSCR_PR) {
873 if (ctx->opcode & 0x0110)
874 break; /* illegal instruction */
875 gen_op_fmov_drN_DT1(DREG(B7_4));
876 gen_op_fmov_drN_DT0(DREG(B11_8));
877 }
878 else {
879 gen_op_fmov_frN_FT1(FREG(B7_4));
880 gen_op_fmov_frN_FT0(FREG(B11_8));
881 }
882
883 switch (ctx->opcode & 0xf00f) {
884 case 0xf000: /* fadd Rm,Rn */
885 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
886 break;
887 case 0xf001: /* fsub Rm,Rn */
888 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
889 break;
890 case 0xf002: /* fmul Rm,Rn */
891 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
892 break;
893 case 0xf003: /* fdiv Rm,Rn */
894 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
895 break;
896 case 0xf004: /* fcmp/eq Rm,Rn */
24988dc2 897 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
ea6cf6be
TS
898 return;
899 case 0xf005: /* fcmp/gt Rm,Rn */
24988dc2 900 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
ea6cf6be
TS
901 return;
902 }
903
904 if (ctx->fpscr & FPSCR_PR) {
905 gen_op_fmov_DT0_drN(DREG(B11_8));
906 }
907 else {
908 gen_op_fmov_FT0_frN(FREG(B11_8));
909 }
910 return;
fdf9b3e8
FB
911 }
912
913 switch (ctx->opcode & 0xff00) {
914 case 0xc900: /* and #imm,R0 */
559dd74d 915 tcg_gen_andi_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
fdf9b3e8 916 return;
24988dc2 917 case 0xcd00: /* and.b #imm,@(R0,GBR) */
1e8864f7 918 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 919 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
829337a6 920 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
24988dc2 921 gen_op_ldub_T0_T0(ctx);
559dd74d 922 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8
FB
923 gen_op_stb_T0_T1(ctx);
924 return;
925 case 0x8b00: /* bf label */
926 CHECK_NOT_DELAY_SLOT
927 gen_conditional_jump(ctx, ctx->pc + 2,
928 ctx->pc + 4 + B7_0s * 2);
823029f9 929 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
930 return;
931 case 0x8f00: /* bf/s label */
932 CHECK_NOT_DELAY_SLOT
933 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
934 ctx->flags |= DELAY_SLOT_CONDITIONAL;
935 return;
936 case 0x8900: /* bt label */
937 CHECK_NOT_DELAY_SLOT
938 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
939 ctx->pc + 2);
823029f9 940 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
941 return;
942 case 0x8d00: /* bt/s label */
943 CHECK_NOT_DELAY_SLOT
944 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
945 ctx->flags |= DELAY_SLOT_CONDITIONAL;
946 return;
947 case 0x8800: /* cmp/eq #imm,R0 */
1e8864f7 948 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
a4625612 949 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], B7_0s);
fdf9b3e8
FB
950 return;
951 case 0xc400: /* mov.b @(disp,GBR),R0 */
952 gen_op_stc_gbr_T0();
559dd74d 953 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8 954 gen_op_ldb_T0_T0(ctx);
1e8864f7 955 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
956 return;
957 case 0xc500: /* mov.w @(disp,GBR),R0 */
958 gen_op_stc_gbr_T0();
559dd74d 959 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
fdf9b3e8 960 gen_op_ldw_T0_T0(ctx);
1e8864f7 961 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
962 return;
963 case 0xc600: /* mov.l @(disp,GBR),R0 */
964 gen_op_stc_gbr_T0();
559dd74d 965 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
fdf9b3e8 966 gen_op_ldl_T0_T0(ctx);
1e8864f7 967 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
968 return;
969 case 0xc000: /* mov.b R0,@(disp,GBR) */
970 gen_op_stc_gbr_T0();
559dd74d 971 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
829337a6 972 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 973 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
fdf9b3e8
FB
974 gen_op_stb_T0_T1(ctx);
975 return;
976 case 0xc100: /* mov.w R0,@(disp,GBR) */
977 gen_op_stc_gbr_T0();
559dd74d 978 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
829337a6 979 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 980 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
fdf9b3e8
FB
981 gen_op_stw_T0_T1(ctx);
982 return;
983 case 0xc200: /* mov.l R0,@(disp,GBR) */
984 gen_op_stc_gbr_T0();
559dd74d 985 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
829337a6 986 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1e8864f7 987 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
fdf9b3e8
FB
988 gen_op_stl_T0_T1(ctx);
989 return;
990 case 0x8000: /* mov.b R0,@(disp,Rn) */
1e8864f7
AJ
991 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
992 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
559dd74d 993 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0);
fdf9b3e8
FB
994 gen_op_stb_T0_T1(ctx);
995 return;
996 case 0x8100: /* mov.w R0,@(disp,Rn) */
1e8864f7
AJ
997 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
998 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
559dd74d 999 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 2);
fdf9b3e8
FB
1000 gen_op_stw_T0_T1(ctx);
1001 return;
1002 case 0x8400: /* mov.b @(disp,Rn),R0 */
1e8864f7 1003 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d 1004 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0);
8c2cc7ce 1005 gen_op_ldb_T0_T0(ctx);
1e8864f7 1006 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
1007 return;
1008 case 0x8500: /* mov.w @(disp,Rn),R0 */
1e8864f7 1009 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
559dd74d 1010 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 2);
fdf9b3e8 1011 gen_op_ldw_T0_T0(ctx);
1e8864f7 1012 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
fdf9b3e8
FB
1013 return;
1014 case 0xc700: /* mova @(disp,PC),R0 */
1e8864f7
AJ
1015 tcg_gen_movi_i32(cpu_gregs[REG(0)],
1016 ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
fdf9b3e8
FB
1017 return;
1018 case 0xcb00: /* or #imm,R0 */
559dd74d 1019 tcg_gen_ori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
fdf9b3e8 1020 return;
24988dc2 1021 case 0xcf00: /* or.b #imm,@(R0,GBR) */
1e8864f7 1022 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 1023 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
3bf73a49 1024 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
24988dc2 1025 gen_op_ldub_T0_T0(ctx);
559dd74d 1026 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8
FB
1027 gen_op_stb_T0_T1(ctx);
1028 return;
1029 case 0xc300: /* trapa #imm */
3a8a44c4 1030 CHECK_NOT_DELAY_SLOT tcg_gen_movi_i32(cpu_pc, ctx->pc);
fdf9b3e8 1031 gen_op_trapa(B7_0);
823029f9 1032 ctx->bstate = BS_BRANCH;
fdf9b3e8
FB
1033 return;
1034 case 0xc800: /* tst #imm,R0 */
a4625612
AJ
1035 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(0)], B7_0);
1036 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
fdf9b3e8 1037 return;
24988dc2 1038 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
1e8864f7 1039 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 1040 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
24988dc2 1041 gen_op_ldub_T0_T0(ctx);
a4625612
AJ
1042 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
1043 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
fdf9b3e8
FB
1044 return;
1045 case 0xca00: /* xor #imm,R0 */
559dd74d 1046 tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
fdf9b3e8 1047 return;
24988dc2 1048 case 0xce00: /* xor.b #imm,@(R0,GBR) */
1e8864f7 1049 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
3a8a44c4 1050 tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr);
829337a6 1051 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
24988dc2 1052 gen_op_ldub_T0_T0(ctx);
559dd74d 1053 tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
fdf9b3e8
FB
1054 gen_op_stb_T0_T1(ctx);
1055 return;
1056 }
1057
1058 switch (ctx->opcode & 0xf08f) {
1059 case 0x408e: /* ldc Rm,Rn_BANK */
1e8864f7
AJ
1060 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1061 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
fdf9b3e8
FB
1062 return;
1063 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
1e8864f7 1064 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8 1065 gen_op_ldl_T0_T0(ctx);
1e8864f7 1066 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
559dd74d 1067 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8
FB
1068 return;
1069 case 0x0082: /* stc Rm_BANK,Rn */
1e8864f7
AJ
1070 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1071 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
fdf9b3e8
FB
1072 return;
1073 case 0x4083: /* stc.l Rm_BANK,@-Rn */
559dd74d 1074 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1e8864f7
AJ
1075 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1076 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
559dd74d 1077 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8 1078 gen_op_stl_T0_T1(ctx);
559dd74d 1079 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
fdf9b3e8
FB
1080 return;
1081 }
1082
1083 switch (ctx->opcode & 0xf0ff) {
1084 case 0x0023: /* braf Rn */
1e8864f7 1085 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1086 gen_op_braf_T0(ctx->pc + 4);
1087 ctx->flags |= DELAY_SLOT;
1088 ctx->delayed_pc = (uint32_t) - 1;
1089 return;
1090 case 0x0003: /* bsrf Rn */
1e8864f7 1091 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1092 gen_op_bsrf_T0(ctx->pc + 4);
1093 ctx->flags |= DELAY_SLOT;
1094 ctx->delayed_pc = (uint32_t) - 1;
1095 return;
1096 case 0x4015: /* cmp/pl Rn */
1e8864f7 1097 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
a4625612 1098 gen_cmp_imm(TCG_COND_GT, cpu_T[0], 0);
fdf9b3e8
FB
1099 return;
1100 case 0x4011: /* cmp/pz Rn */
1e8864f7 1101 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
a4625612 1102 gen_cmp_imm(TCG_COND_GE, cpu_T[0], 0);
fdf9b3e8
FB
1103 return;
1104 case 0x4010: /* dt Rn */
a4625612
AJ
1105 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1);
1106 gen_cmp_imm(TCG_COND_EQ, cpu_gregs[REG(B11_8)], 0);
fdf9b3e8
FB
1107 return;
1108 case 0x402b: /* jmp @Rn */
1e8864f7 1109 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1110 gen_op_jmp_T0();
1111 ctx->flags |= DELAY_SLOT;
1112 ctx->delayed_pc = (uint32_t) - 1;
1113 return;
1114 case 0x400b: /* jsr @Rn */
1e8864f7 1115 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1116 gen_op_jsr_T0(ctx->pc + 4);
1117 ctx->flags |= DELAY_SLOT;
1118 ctx->delayed_pc = (uint32_t) - 1;
1119 return;
1120#define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1121 case ldnum: \
1e8864f7 1122 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
fdf9b3e8
FB
1123 gen_op_##ldop##_T0_##reg (); \
1124 extrald \
1125 return; \
1126 case ldpnum: \
1e8864f7 1127 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
fdf9b3e8 1128 gen_op_ldl_T0_T0 (ctx); \
559dd74d
AJ
1129 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1130 cpu_gregs[REG(B11_8)], 4); \
fdf9b3e8
FB
1131 gen_op_##ldop##_T0_##reg (); \
1132 extrald \
1133 return; \
1134 case stnum: \
8f99cc6c 1135 gen_op_##stop##_##reg##_T0 (); \
1e8864f7 1136 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]); \
fdf9b3e8
FB
1137 return; \
1138 case stpnum: \
1139 gen_op_##stop##_##reg##_T0 (); \
559dd74d
AJ
1140 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1141 cpu_gregs[REG(B11_8)], 4); \
1e8864f7 1142 tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]); \
559dd74d
AJ
1143 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1144 cpu_gregs[REG(B11_8)], 4); \
fdf9b3e8 1145 gen_op_stl_T0_T1 (ctx); \
559dd74d
AJ
1146 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1147 cpu_gregs[REG(B11_8)], 4); \
fdf9b3e8 1148 return;
823029f9
TS
1149 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1150 BS_STOP;)
eda9b09b
FB
1151 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1152 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1153 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1154 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1155 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1156 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1157 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1158 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
8bf5a804 1159 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
823029f9
TS
1160 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1161 BS_STOP;)
fdf9b3e8 1162 case 0x00c3: /* movca.l R0,@Rm */
1e8864f7
AJ
1163 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1164 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1165 gen_op_stl_T0_T1(ctx);
1166 return;
1167 case 0x0029: /* movt Rn */
3a8a44c4 1168 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_sr, SR_T);
fdf9b3e8
FB
1169 return;
1170 case 0x0093: /* ocbi @Rn */
1e8864f7 1171 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1172 gen_op_ldl_T0_T0(ctx);
1173 return;
24988dc2 1174 case 0x00a3: /* ocbp @Rn */
1e8864f7 1175 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1176 gen_op_ldl_T0_T0(ctx);
1177 return;
1178 case 0x00b3: /* ocbwb @Rn */
1e8864f7 1179 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
fdf9b3e8
FB
1180 gen_op_ldl_T0_T0(ctx);
1181 return;
1182 case 0x0083: /* pref @Rn */
1183 return;
1184 case 0x4024: /* rotcl Rn */
1185 gen_op_rotcl_Rn(REG(B11_8));
1186 return;
1187 case 0x4025: /* rotcr Rn */
1188 gen_op_rotcr_Rn(REG(B11_8));
1189 return;
1190 case 0x4004: /* rotl Rn */
1191 gen_op_rotl_Rn(REG(B11_8));
1192 return;
1193 case 0x4005: /* rotr Rn */
1194 gen_op_rotr_Rn(REG(B11_8));
1195 return;
1196 case 0x4000: /* shll Rn */
1197 case 0x4020: /* shal Rn */
1198 gen_op_shal_Rn(REG(B11_8));
1199 return;
1200 case 0x4021: /* shar Rn */
1201 gen_op_shar_Rn(REG(B11_8));
1202 return;
1203 case 0x4001: /* shlr Rn */
1204 gen_op_shlr_Rn(REG(B11_8));
1205 return;
1206 case 0x4008: /* shll2 Rn */
559dd74d 1207 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
fdf9b3e8
FB
1208 return;
1209 case 0x4018: /* shll8 Rn */
559dd74d 1210 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
fdf9b3e8
FB
1211 return;
1212 case 0x4028: /* shll16 Rn */
559dd74d 1213 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
fdf9b3e8
FB
1214 return;
1215 case 0x4009: /* shlr2 Rn */
559dd74d 1216 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
fdf9b3e8
FB
1217 return;
1218 case 0x4019: /* shlr8 Rn */
559dd74d 1219 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
fdf9b3e8
FB
1220 return;
1221 case 0x4029: /* shlr16 Rn */
559dd74d 1222 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
fdf9b3e8
FB
1223 return;
1224 case 0x401b: /* tas.b @Rn */
1e8864f7 1225 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
829337a6 1226 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
825c69ce 1227 gen_op_ldub_T0_T0(ctx);
a4625612 1228 gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0);
559dd74d 1229 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
825c69ce 1230 gen_op_stb_T0_T1(ctx);
fdf9b3e8 1231 return;
e67888a7 1232 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
eda9b09b
FB
1233 gen_op_movl_fpul_FT0();
1234 gen_op_fmov_FT0_frN(FREG(B11_8));
1235 return;
e67888a7 1236 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
eda9b09b
FB
1237 gen_op_fmov_frN_FT0(FREG(B11_8));
1238 gen_op_movl_FT0_fpul();
1239 return;
e67888a7 1240 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
ea6cf6be
TS
1241 if (ctx->fpscr & FPSCR_PR) {
1242 if (ctx->opcode & 0x0100)
1243 break; /* illegal instruction */
1244 gen_op_float_DT();
1245 gen_op_fmov_DT0_drN(DREG(B11_8));
1246 }
1247 else {
1248 gen_op_float_FT();
1249 gen_op_fmov_FT0_frN(FREG(B11_8));
1250 }
1251 return;
e67888a7 1252 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
ea6cf6be
TS
1253 if (ctx->fpscr & FPSCR_PR) {
1254 if (ctx->opcode & 0x0100)
1255 break; /* illegal instruction */
1256 gen_op_fmov_drN_DT0(DREG(B11_8));
1257 gen_op_ftrc_DT();
1258 }
1259 else {
1260 gen_op_fmov_frN_FT0(FREG(B11_8));
1261 gen_op_ftrc_FT();
1262 }
1263 return;
24988dc2
AJ
1264 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1265 gen_op_fneg_frN(FREG(B11_8));
1266 return;
1267 case 0xf05d: /* fabs FRn/DRn */
1268 if (ctx->fpscr & FPSCR_PR) {
1269 if (ctx->opcode & 0x0100)
1270 break; /* illegal instruction */
1271 gen_op_fmov_drN_DT0(DREG(B11_8));
1272 gen_op_fabs_DT();
1273 gen_op_fmov_DT0_drN(DREG(B11_8));
1274 } else {
1275 gen_op_fmov_frN_FT0(FREG(B11_8));
1276 gen_op_fabs_FT();
1277 gen_op_fmov_FT0_frN(FREG(B11_8));
1278 }
1279 return;
1280 case 0xf06d: /* fsqrt FRn */
1281 if (ctx->fpscr & FPSCR_PR) {
1282 if (ctx->opcode & 0x0100)
1283 break; /* illegal instruction */
1284 gen_op_fmov_drN_DT0(FREG(B11_8));
1285 gen_op_fsqrt_DT();
1286 gen_op_fmov_DT0_drN(FREG(B11_8));
1287 } else {
1288 gen_op_fmov_frN_FT0(FREG(B11_8));
1289 gen_op_fsqrt_FT();
1290 gen_op_fmov_FT0_frN(FREG(B11_8));
1291 }
1292 return;
1293 case 0xf07d: /* fsrra FRn */
1294 break;
e67888a7 1295 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
ea6cf6be 1296 if (!(ctx->fpscr & FPSCR_PR)) {
3bf73a49 1297 tcg_gen_movi_i32(cpu_T[0], 0);
ea6cf6be
TS
1298 gen_op_fmov_T0_frN(FREG(B11_8));
1299 return;
1300 }
1301 break;
e67888a7 1302 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
ea6cf6be 1303 if (!(ctx->fpscr & FPSCR_PR)) {
3bf73a49 1304 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
ea6cf6be
TS
1305 gen_op_fmov_T0_frN(FREG(B11_8));
1306 return;
1307 }
1308 break;
24988dc2
AJ
1309 case 0xf0ad: /* fcnvsd FPUL,DRn */
1310 gen_op_movl_fpul_FT0();
1311 gen_op_fcnvsd_FT_DT();
1312 gen_op_fmov_DT0_drN(DREG(B11_8));
1313 return;
1314 case 0xf0bd: /* fcnvds DRn,FPUL */
1315 gen_op_fmov_drN_DT0(DREG(B11_8));
1316 gen_op_fcnvds_DT_FT();
1317 gen_op_movl_FT0_fpul();
1318 return;
fdf9b3e8
FB
1319 }
1320
1321 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1322 ctx->opcode, ctx->pc);
1323 gen_op_raise_illegal_instruction();
823029f9
TS
1324 ctx->bstate = BS_EXCP;
1325}
1326
1327void decode_opc(DisasContext * ctx)
1328{
1329 uint32_t old_flags = ctx->flags;
1330
1331 _decode_opc(ctx);
1332
1333 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1334 if (ctx->flags & DELAY_SLOT_CLEARME) {
1335 gen_op_store_flags(0);
274a9e70
AJ
1336 } else {
1337 /* go out of the delay slot */
1338 uint32_t new_flags = ctx->flags;
1339 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1340 gen_op_store_flags(new_flags);
823029f9
TS
1341 }
1342 ctx->flags = 0;
1343 ctx->bstate = BS_BRANCH;
1344 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1345 gen_delayed_conditional_jump(ctx);
1346 } else if (old_flags & DELAY_SLOT) {
1347 gen_jump(ctx);
1348 }
1349
1350 }
274a9e70
AJ
1351
1352 /* go into a delay slot */
1353 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1354 gen_op_store_flags(ctx->flags);
fdf9b3e8
FB
1355}
1356
2cfc5f17 1357static inline void
820e00f2
TS
1358gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1359 int search_pc)
fdf9b3e8
FB
1360{
1361 DisasContext ctx;
1362 target_ulong pc_start;
1363 static uint16_t *gen_opc_end;
355fb23d 1364 int i, ii;
2e70f6ef
PB
1365 int num_insns;
1366 int max_insns;
fdf9b3e8
FB
1367
1368 pc_start = tb->pc;
fdf9b3e8 1369 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
fdf9b3e8 1370 ctx.pc = pc_start;
823029f9
TS
1371 ctx.flags = (uint32_t)tb->flags;
1372 ctx.bstate = BS_NONE;
fdf9b3e8 1373 ctx.sr = env->sr;
eda9b09b 1374 ctx.fpscr = env->fpscr;
fdf9b3e8 1375 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
9854bc46
PB
1376 /* We don't know if the delayed pc came from a dynamic or static branch,
1377 so assume it is a dynamic branch. */
823029f9 1378 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
fdf9b3e8
FB
1379 ctx.tb = tb;
1380 ctx.singlestep_enabled = env->singlestep_enabled;
fdf9b3e8
FB
1381
1382#ifdef DEBUG_DISAS
1383 if (loglevel & CPU_LOG_TB_CPU) {
1384 fprintf(logfile,
1385 "------------------------------------------------\n");
1386 cpu_dump_state(env, logfile, fprintf, 0);
1387 }
1388#endif
1389
355fb23d 1390 ii = -1;
2e70f6ef
PB
1391 num_insns = 0;
1392 max_insns = tb->cflags & CF_COUNT_MASK;
1393 if (max_insns == 0)
1394 max_insns = CF_COUNT_MASK;
1395 gen_icount_start();
823029f9 1396 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
fdf9b3e8
FB
1397 if (env->nb_breakpoints > 0) {
1398 for (i = 0; i < env->nb_breakpoints; i++) {
1399 if (ctx.pc == env->breakpoints[i]) {
1400 /* We have hit a breakpoint - make sure PC is up-to-date */
3a8a44c4 1401 tcg_gen_movi_i32(cpu_pc, ctx.pc);
fdf9b3e8 1402 gen_op_debug();
823029f9 1403 ctx.bstate = BS_EXCP;
fdf9b3e8
FB
1404 break;
1405 }
1406 }
1407 }
355fb23d
PB
1408 if (search_pc) {
1409 i = gen_opc_ptr - gen_opc_buf;
1410 if (ii < i) {
1411 ii++;
1412 while (ii < i)
1413 gen_opc_instr_start[ii++] = 0;
1414 }
1415 gen_opc_pc[ii] = ctx.pc;
823029f9 1416 gen_opc_hflags[ii] = ctx.flags;
355fb23d 1417 gen_opc_instr_start[ii] = 1;
2e70f6ef 1418 gen_opc_icount[ii] = num_insns;
355fb23d 1419 }
2e70f6ef
PB
1420 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1421 gen_io_start();
fdf9b3e8
FB
1422#if 0
1423 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1424 fflush(stderr);
1425#endif
1426 ctx.opcode = lduw_code(ctx.pc);
1427 decode_opc(&ctx);
2e70f6ef 1428 num_insns++;
fdf9b3e8
FB
1429 ctx.pc += 2;
1430 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1431 break;
1432 if (env->singlestep_enabled)
1433 break;
2e70f6ef
PB
1434 if (num_insns >= max_insns)
1435 break;
fdf9b3e8
FB
1436#ifdef SH4_SINGLE_STEP
1437 break;
1438#endif
1439 }
2e70f6ef
PB
1440 if (tb->cflags & CF_LAST_IO)
1441 gen_io_end();
fdf9b3e8 1442 if (env->singlestep_enabled) {
823029f9
TS
1443 gen_op_debug();
1444 } else {
1445 switch (ctx.bstate) {
1446 case BS_STOP:
1447 /* gen_op_interrupt_restart(); */
1448 /* fall through */
1449 case BS_NONE:
1450 if (ctx.flags) {
1451 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1452 }
1453 gen_goto_tb(&ctx, 0, ctx.pc);
1454 break;
1455 case BS_EXCP:
1456 /* gen_op_interrupt_restart(); */
57fec1fe 1457 tcg_gen_exit_tb(0);
823029f9
TS
1458 break;
1459 case BS_BRANCH:
1460 default:
1461 break;
1462 }
fdf9b3e8 1463 }
823029f9 1464
2e70f6ef 1465 gen_icount_end(tb, num_insns);
fdf9b3e8 1466 *gen_opc_ptr = INDEX_op_end;
355fb23d
PB
1467 if (search_pc) {
1468 i = gen_opc_ptr - gen_opc_buf;
1469 ii++;
1470 while (ii <= i)
1471 gen_opc_instr_start[ii++] = 0;
355fb23d
PB
1472 } else {
1473 tb->size = ctx.pc - pc_start;
2e70f6ef 1474 tb->icount = num_insns;
355fb23d 1475 }
fdf9b3e8
FB
1476
1477#ifdef DEBUG_DISAS
1478#ifdef SH4_DEBUG_DISAS
1479 if (loglevel & CPU_LOG_TB_IN_ASM)
1480 fprintf(logfile, "\n");
1481#endif
1482 if (loglevel & CPU_LOG_TB_IN_ASM) {
1483 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1484 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1485 fprintf(logfile, "\n");
1486 }
fdf9b3e8 1487#endif
fdf9b3e8
FB
1488}
1489
2cfc5f17 1490void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
fdf9b3e8 1491{
2cfc5f17 1492 gen_intermediate_code_internal(env, tb, 0);
fdf9b3e8
FB
1493}
1494
2cfc5f17 1495void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
fdf9b3e8 1496{
2cfc5f17 1497 gen_intermediate_code_internal(env, tb, 1);
fdf9b3e8 1498}
d2856f1a
AJ
1499
1500void gen_pc_load(CPUState *env, TranslationBlock *tb,
1501 unsigned long searched_pc, int pc_pos, void *puc)
1502{
1503 env->pc = gen_opc_pc[pc_pos];
1504 env->flags = gen_opc_hflags[pc_pos];
1505}