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