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