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