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