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