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