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