SH4, fix several instructions
[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 0xfbfd:                /* frchg */
272         gen_op_frchg();
273         ctx->bstate = BS_STOP;
274         return;
275     case 0xf3fd:                /* 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 #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 #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_movl_rN_T0(REG(B7_4));
365         gen_op_dec1_rN(REG(B11_8));
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_movl_rN_T0(REG(B7_4));
371         gen_op_dec2_rN(REG(B11_8));
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_movl_rN_T0(REG(B7_4));
377         gen_op_dec4_rN(REG(B11_8));
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         if ( B11_8 != B7_4 )
386                 gen_op_inc1_rN(REG(B7_4));
387         return;
388     case 0x6005:                /* mov.w @Rm+,Rn */
389         gen_op_movl_rN_T0(REG(B7_4));
390         gen_op_ldw_T0_T0(ctx);
391         gen_op_movl_T0_rN(REG(B11_8));
392         if ( B11_8 != B7_4 )
393                 gen_op_inc2_rN(REG(B7_4));
394         return;
395     case 0x6006:                /* 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         if ( B11_8 != B7_4 )
400                 gen_op_inc4_rN(REG(B7_4));
401         return;
402     case 0x0004:                /* mov.b Rm,@(R0,Rn) */
403         gen_op_movl_rN_T0(REG(B7_4));
404         gen_op_movl_rN_T1(REG(B11_8));
405         gen_op_add_rN_T1(REG(0));
406         gen_op_stb_T0_T1(ctx);
407         return;
408     case 0x0005:                /* mov.w Rm,@(R0,Rn) */
409         gen_op_movl_rN_T0(REG(B7_4));
410         gen_op_movl_rN_T1(REG(B11_8));
411         gen_op_add_rN_T1(REG(0));
412         gen_op_stw_T0_T1(ctx);
413         return;
414     case 0x0006:                /* mov.l Rm,@(R0,Rn) */
415         gen_op_movl_rN_T0(REG(B7_4));
416         gen_op_movl_rN_T1(REG(B11_8));
417         gen_op_add_rN_T1(REG(0));
418         gen_op_stl_T0_T1(ctx);
419         return;
420     case 0x000c:                /* mov.b @(R0,Rm),Rn */
421         gen_op_movl_rN_T0(REG(B7_4));
422         gen_op_add_rN_T0(REG(0));
423         gen_op_ldb_T0_T0(ctx);
424         gen_op_movl_T0_rN(REG(B11_8));
425         return;
426     case 0x000d:                /* mov.w @(R0,Rm),Rn */
427         gen_op_movl_rN_T0(REG(B7_4));
428         gen_op_add_rN_T0(REG(0));
429         gen_op_ldw_T0_T0(ctx);
430         gen_op_movl_T0_rN(REG(B11_8));
431         return;
432     case 0x000e:                /* mov.l @(R0,Rm),Rn */
433         gen_op_movl_rN_T0(REG(B7_4));
434         gen_op_add_rN_T0(REG(0));
435         gen_op_ldl_T0_T0(ctx);
436         gen_op_movl_T0_rN(REG(B11_8));
437         return;
438     case 0x6008:                /* swap.b Rm,Rn */
439         gen_op_movl_rN_T0(REG(B7_4));
440         gen_op_swapb_T0();
441         gen_op_movl_T0_rN(REG(B11_8));
442         return;
443     case 0x6009:                /* swap.w Rm,Rn */
444         gen_op_movl_rN_T0(REG(B7_4));
445         gen_op_swapw_T0();
446         gen_op_movl_T0_rN(REG(B11_8));
447         return;
448     case 0x200d:                /* xtrct Rm,Rn */
449         gen_op_movl_rN_T0(REG(B7_4));
450         gen_op_movl_rN_T1(REG(B11_8));
451         gen_op_xtrct_T0_T1();
452         gen_op_movl_T1_rN(REG(B11_8));
453         return;
454     case 0x300c:                /* add Rm,Rn */
455         gen_op_movl_rN_T0(REG(B7_4));
456         gen_op_add_T0_rN(REG(B11_8));
457         return;
458     case 0x300e:                /* addc Rm,Rn */
459         gen_op_movl_rN_T0(REG(B7_4));
460         gen_op_movl_rN_T1(REG(B11_8));
461         gen_op_addc_T0_T1();
462         gen_op_movl_T1_rN(REG(B11_8));
463         return;
464     case 0x300f:                /* addv Rm,Rn */
465         gen_op_movl_rN_T0(REG(B7_4));
466         gen_op_movl_rN_T1(REG(B11_8));
467         gen_op_addv_T0_T1();
468         gen_op_movl_T1_rN(REG(B11_8));
469         return;
470     case 0x2009:                /* and Rm,Rn */
471         gen_op_movl_rN_T0(REG(B7_4));
472         gen_op_and_T0_rN(REG(B11_8));
473         return;
474     case 0x3000:                /* cmp/eq Rm,Rn */
475         gen_op_movl_rN_T0(REG(B7_4));
476         gen_op_movl_rN_T1(REG(B11_8));
477         gen_op_cmp_eq_T0_T1();
478         return;
479     case 0x3003:                /* cmp/ge Rm,Rn */
480         gen_op_movl_rN_T0(REG(B7_4));
481         gen_op_movl_rN_T1(REG(B11_8));
482         gen_op_cmp_ge_T0_T1();
483         return;
484     case 0x3007:                /* cmp/gt Rm,Rn */
485         gen_op_movl_rN_T0(REG(B7_4));
486         gen_op_movl_rN_T1(REG(B11_8));
487         gen_op_cmp_gt_T0_T1();
488         return;
489     case 0x3006:                /* cmp/hi Rm,Rn */
490         gen_op_movl_rN_T0(REG(B7_4));
491         gen_op_movl_rN_T1(REG(B11_8));
492         gen_op_cmp_hi_T0_T1();
493         return;
494     case 0x3002:                /* cmp/hs Rm,Rn */
495         gen_op_movl_rN_T0(REG(B7_4));
496         gen_op_movl_rN_T1(REG(B11_8));
497         gen_op_cmp_hs_T0_T1();
498         return;
499     case 0x200c:                /* cmp/str Rm,Rn */
500         gen_op_movl_rN_T0(REG(B7_4));
501         gen_op_movl_rN_T1(REG(B11_8));
502         gen_op_cmp_str_T0_T1();
503         return;
504     case 0x2007:                /* div0s Rm,Rn */
505         gen_op_movl_rN_T0(REG(B7_4));
506         gen_op_movl_rN_T1(REG(B11_8));
507         gen_op_div0s_T0_T1();
508         return;
509     case 0x3004:                /* div1 Rm,Rn */
510         gen_op_movl_rN_T0(REG(B7_4));
511         gen_op_movl_rN_T1(REG(B11_8));
512         gen_op_div1_T0_T1();
513         gen_op_movl_T1_rN(REG(B11_8));
514         return;
515     case 0x300d:                /* dmuls.l Rm,Rn */
516         gen_op_movl_rN_T0(REG(B7_4));
517         gen_op_movl_rN_T1(REG(B11_8));
518         gen_op_dmulsl_T0_T1();
519         return;
520     case 0x3005:                /* dmulu.l Rm,Rn */
521         gen_op_movl_rN_T0(REG(B7_4));
522         gen_op_movl_rN_T1(REG(B11_8));
523         gen_op_dmulul_T0_T1();
524         return;
525     case 0x600e:                /* exts.b Rm,Rn */
526         gen_op_movb_rN_T0(REG(B7_4));
527         gen_op_movl_T0_rN(REG(B11_8));
528         return;
529     case 0x600f:                /* exts.w Rm,Rn */
530         gen_op_movw_rN_T0(REG(B7_4));
531         gen_op_movl_T0_rN(REG(B11_8));
532         return;
533     case 0x600c:                /* extu.b Rm,Rn */
534         gen_op_movub_rN_T0(REG(B7_4));
535         gen_op_movl_T0_rN(REG(B11_8));
536         return;
537     case 0x600d:                /* extu.w Rm,Rn */
538         gen_op_movuw_rN_T0(REG(B7_4));
539         gen_op_movl_T0_rN(REG(B11_8));
540         return;
541     case 0x000f:                /* mac.l @Rm+,@Rn+ */
542         gen_op_movl_rN_T0(REG(B11_8));
543         gen_op_ldl_T0_T0(ctx);
544         gen_op_movl_T0_T1();
545         gen_op_inc4_rN(REG(B11_8));
546         gen_op_movl_rN_T0(REG(B7_4));
547         gen_op_ldl_T0_T0(ctx);
548         gen_op_macl_T0_T1();
549         gen_op_inc4_rN(REG(B7_4));
550         return;
551     case 0x400f:                /* mac.w @Rm+,@Rn+ */
552         gen_op_movl_rN_T0(REG(B11_8));
553         gen_op_ldl_T0_T0(ctx);
554         gen_op_movl_T0_T1();
555         gen_op_inc2_rN(REG(B11_8));
556         gen_op_movl_rN_T0(REG(B7_4));
557         gen_op_ldl_T0_T0(ctx);
558         gen_op_macw_T0_T1();
559         gen_op_inc2_rN(REG(B7_4));
560         return;
561     case 0x0007:                /* mul.l Rm,Rn */
562         gen_op_movl_rN_T0(REG(B7_4));
563         gen_op_movl_rN_T1(REG(B11_8));
564         gen_op_mull_T0_T1();
565         return;
566     case 0x200f:                /* muls.w Rm,Rn */
567         gen_op_movw_rN_T0(REG(B7_4));
568         gen_op_movw_rN_T1(REG(B11_8));
569         gen_op_mulsw_T0_T1();
570         return;
571     case 0x200e:                /* mulu.w Rm,Rn */
572         gen_op_movuw_rN_T0(REG(B7_4));
573         gen_op_movuw_rN_T1(REG(B11_8));
574         gen_op_muluw_T0_T1();
575         return;
576     case 0x600b:                /* neg Rm,Rn */
577         gen_op_movl_rN_T0(REG(B7_4));
578         gen_op_neg_T0();
579         gen_op_movl_T0_rN(REG(B11_8));
580         return;
581     case 0x600a:                /* negc Rm,Rn */
582         gen_op_movl_rN_T0(REG(B7_4));
583         gen_op_negc_T0();
584         gen_op_movl_T0_rN(REG(B11_8));
585         return;
586     case 0x6007:                /* not Rm,Rn */
587         gen_op_movl_rN_T0(REG(B7_4));
588         gen_op_not_T0();
589         gen_op_movl_T0_rN(REG(B11_8));
590         return;
591     case 0x200b:                /* or Rm,Rn */
592         gen_op_movl_rN_T0(REG(B7_4));
593         gen_op_or_T0_rN(REG(B11_8));
594         return;
595     case 0x400c:                /* shad Rm,Rn */
596         gen_op_movl_rN_T0(REG(B7_4));
597         gen_op_movl_rN_T1(REG(B11_8));
598         gen_op_shad_T0_T1();
599         gen_op_movl_T1_rN(REG(B11_8));
600         return;
601     case 0x400d:                /* shld Rm,Rn */
602         gen_op_movl_rN_T0(REG(B7_4));
603         gen_op_movl_rN_T1(REG(B11_8));
604         gen_op_shld_T0_T1();
605         gen_op_movl_T1_rN(REG(B11_8));
606         return;
607     case 0x3008:                /* sub Rm,Rn */
608         gen_op_movl_rN_T0(REG(B7_4));
609         gen_op_sub_T0_rN(REG(B11_8));
610         return;
611     case 0x300a:                /* subc Rm,Rn */
612         gen_op_movl_rN_T0(REG(B7_4));
613         gen_op_movl_rN_T1(REG(B11_8));
614         gen_op_subc_T0_T1();
615         gen_op_movl_T1_rN(REG(B11_8));
616         return;
617     case 0x300b:                /* subv Rm,Rn */
618         gen_op_movl_rN_T0(REG(B7_4));
619         gen_op_movl_rN_T1(REG(B11_8));
620         gen_op_subv_T0_T1();
621         gen_op_movl_T1_rN(REG(B11_8));
622         return;
623     case 0x2008:                /* tst Rm,Rn */
624         gen_op_movl_rN_T0(REG(B7_4));
625         gen_op_movl_rN_T1(REG(B11_8));
626         gen_op_tst_T0_T1();
627         return;
628     case 0x200a:                /* xor Rm,Rn */
629         gen_op_movl_rN_T0(REG(B7_4));
630         gen_op_xor_T0_rN(REG(B11_8));
631         return;
632     case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
633         if (ctx->fpscr & FPSCR_SZ) {
634             gen_op_fmov_drN_DT0(XREG(B7_4));
635             gen_op_fmov_DT0_drN(XREG(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             gen_op_fmov_drN_DT0(XREG(B7_4));
644             gen_op_movl_rN_T1(REG(B11_8));
645             gen_op_stfq_DT0_T1(ctx);
646         } else {
647             gen_op_fmov_frN_FT0(FREG(B7_4));
648             gen_op_movl_rN_T1(REG(B11_8));
649             gen_op_stfl_FT0_T1(ctx);
650         }
651         return;
652     case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
653         if (ctx->fpscr & FPSCR_SZ) {
654             gen_op_movl_rN_T0(REG(B7_4));
655             gen_op_ldfq_T0_DT0(ctx);
656             gen_op_fmov_DT0_drN(XREG(B11_8));
657         } else {
658             gen_op_movl_rN_T0(REG(B7_4));
659             gen_op_ldfl_T0_FT0(ctx);
660             gen_op_fmov_FT0_frN(FREG(B11_8));
661         }
662         return;
663     case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
664         if (ctx->fpscr & FPSCR_SZ) {
665             gen_op_movl_rN_T0(REG(B7_4));
666             gen_op_ldfq_T0_DT0(ctx);
667             gen_op_fmov_DT0_drN(XREG(B11_8));
668             gen_op_inc8_rN(REG(B7_4));
669         } else {
670             gen_op_movl_rN_T0(REG(B7_4));
671             gen_op_ldfl_T0_FT0(ctx);
672             gen_op_fmov_FT0_frN(FREG(B11_8));
673             gen_op_inc4_rN(REG(B7_4));
674         }
675         return;
676     case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
677         if (ctx->fpscr & FPSCR_SZ) {
678             gen_op_dec8_rN(REG(B11_8));
679             gen_op_fmov_drN_DT0(XREG(B7_4));
680             gen_op_movl_rN_T1(REG(B11_8));
681             gen_op_stfq_DT0_T1(ctx);
682         } else {
683             gen_op_dec4_rN(REG(B11_8));
684             gen_op_fmov_frN_FT0(FREG(B7_4));
685             gen_op_movl_rN_T1(REG(B11_8));
686             gen_op_stfl_FT0_T1(ctx);
687         }
688         return;
689     case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
690         if (ctx->fpscr & FPSCR_SZ) {
691             gen_op_movl_rN_T0(REG(B7_4));
692             gen_op_add_rN_T0(REG(0));
693             gen_op_ldfq_T0_DT0(ctx);
694             gen_op_fmov_DT0_drN(XREG(B11_8));
695         } else {
696             gen_op_movl_rN_T0(REG(B7_4));
697             gen_op_add_rN_T0(REG(0));
698             gen_op_ldfl_T0_FT0(ctx);
699             gen_op_fmov_FT0_frN(FREG(B11_8));
700         }
701         return;
702     case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
703         if (ctx->fpscr & FPSCR_SZ) {
704             gen_op_fmov_drN_DT0(XREG(B7_4));
705             gen_op_movl_rN_T1(REG(B11_8));
706             gen_op_add_rN_T1(REG(0));
707             gen_op_stfq_DT0_T1(ctx);
708         } else {
709             gen_op_fmov_frN_FT0(FREG(B7_4));
710             gen_op_movl_rN_T1(REG(B11_8));
711             gen_op_add_rN_T1(REG(0));
712             gen_op_stfl_FT0_T1(ctx);
713         }
714         return;
715     case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
716     case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
717     case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
718     case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
719     case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
720     case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
721         if (ctx->fpscr & FPSCR_PR) {
722             if (ctx->opcode & 0x0110)
723                 break; /* illegal instruction */
724             gen_op_fmov_drN_DT1(DREG(B7_4));
725             gen_op_fmov_drN_DT0(DREG(B11_8));
726         }
727         else {
728             gen_op_fmov_frN_FT1(FREG(B7_4));
729             gen_op_fmov_frN_FT0(FREG(B11_8));
730         }
731
732         switch (ctx->opcode & 0xf00f) {
733         case 0xf000:            /* fadd Rm,Rn */
734             ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
735             break;
736         case 0xf001:            /* fsub Rm,Rn */
737             ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
738             break;
739         case 0xf002:            /* fmul Rm,Rn */
740             ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
741             break;
742         case 0xf003:            /* fdiv Rm,Rn */
743             ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
744             break;
745         case 0xf004:            /* fcmp/eq Rm,Rn */
746             ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
747             return;
748         case 0xf005:            /* fcmp/gt Rm,Rn */
749             ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
750             return;
751         }
752
753         if (ctx->fpscr & FPSCR_PR) {
754             gen_op_fmov_DT0_drN(DREG(B11_8));
755         }
756         else {
757             gen_op_fmov_FT0_frN(FREG(B11_8));
758         }
759         return;
760     }
761
762     switch (ctx->opcode & 0xff00) {
763     case 0xc900:                /* and #imm,R0 */
764         gen_op_and_imm_rN(B7_0, REG(0));
765         return;
766     case 0xcd00:                /* and.b #imm,@(R0,GBR) */
767         gen_op_movl_rN_T0(REG(0));
768         gen_op_addl_GBR_T0();
769         gen_op_movl_T0_T1();
770         gen_op_ldub_T0_T0(ctx);
771         gen_op_and_imm_T0(B7_0);
772         gen_op_stb_T0_T1(ctx);
773         return;
774     case 0x8b00:                /* bf label */
775         CHECK_NOT_DELAY_SLOT
776             gen_conditional_jump(ctx, ctx->pc + 2,
777                                  ctx->pc + 4 + B7_0s * 2);
778         ctx->bstate = BS_BRANCH;
779         return;
780     case 0x8f00:                /* bf/s label */
781         CHECK_NOT_DELAY_SLOT
782             gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
783         ctx->flags |= DELAY_SLOT_CONDITIONAL;
784         return;
785     case 0x8900:                /* bt label */
786         CHECK_NOT_DELAY_SLOT
787             gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
788                                  ctx->pc + 2);
789         ctx->bstate = BS_BRANCH;
790         return;
791     case 0x8d00:                /* bt/s label */
792         CHECK_NOT_DELAY_SLOT
793             gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
794         ctx->flags |= DELAY_SLOT_CONDITIONAL;
795         return;
796     case 0x8800:                /* cmp/eq #imm,R0 */
797         gen_op_movl_rN_T0(REG(0));
798         gen_op_cmp_eq_imm_T0(B7_0s);
799         return;
800     case 0xc400:                /* mov.b @(disp,GBR),R0 */
801         gen_op_stc_gbr_T0();
802         gen_op_addl_imm_T0(B7_0);
803         gen_op_ldb_T0_T0(ctx);
804         gen_op_movl_T0_rN(REG(0));
805         return;
806     case 0xc500:                /* mov.w @(disp,GBR),R0 */
807         gen_op_stc_gbr_T0();
808         gen_op_addl_imm_T0(B7_0 * 2);
809         gen_op_ldw_T0_T0(ctx);
810         gen_op_movl_T0_rN(REG(0));
811         return;
812     case 0xc600:                /* mov.l @(disp,GBR),R0 */
813         gen_op_stc_gbr_T0();
814         gen_op_addl_imm_T0(B7_0 * 4);
815         gen_op_ldl_T0_T0(ctx);
816         gen_op_movl_T0_rN(REG(0));
817         return;
818     case 0xc000:                /* mov.b R0,@(disp,GBR) */
819         gen_op_stc_gbr_T0();
820         gen_op_addl_imm_T0(B7_0);
821         gen_op_movl_T0_T1();
822         gen_op_movl_rN_T0(REG(0));
823         gen_op_stb_T0_T1(ctx);
824         return;
825     case 0xc100:                /* mov.w R0,@(disp,GBR) */
826         gen_op_stc_gbr_T0();
827         gen_op_addl_imm_T0(B7_0 * 2);
828         gen_op_movl_T0_T1();
829         gen_op_movl_rN_T0(REG(0));
830         gen_op_stw_T0_T1(ctx);
831         return;
832     case 0xc200:                /* mov.l R0,@(disp,GBR) */
833         gen_op_stc_gbr_T0();
834         gen_op_addl_imm_T0(B7_0 * 4);
835         gen_op_movl_T0_T1();
836         gen_op_movl_rN_T0(REG(0));
837         gen_op_stl_T0_T1(ctx);
838         return;
839     case 0x8000:                /* mov.b R0,@(disp,Rn) */
840         gen_op_movl_rN_T0(REG(0));
841         gen_op_movl_rN_T1(REG(B7_4));
842         gen_op_addl_imm_T1(B3_0);
843         gen_op_stb_T0_T1(ctx);
844         return;
845     case 0x8100:                /* mov.w R0,@(disp,Rn) */
846         gen_op_movl_rN_T0(REG(0));
847         gen_op_movl_rN_T1(REG(B7_4));
848         gen_op_addl_imm_T1(B3_0 * 2);
849         gen_op_stw_T0_T1(ctx);
850         return;
851     case 0x8400:                /* mov.b @(disp,Rn),R0 */
852         gen_op_movl_rN_T0(REG(B7_4));
853         gen_op_addl_imm_T0(B3_0);
854         gen_op_ldb_T0_T0(ctx);
855         gen_op_movl_T0_rN(REG(0));
856         return;
857     case 0x8500:                /* mov.w @(disp,Rn),R0 */
858         gen_op_movl_rN_T0(REG(B7_4));
859         gen_op_addl_imm_T0(B3_0 * 2);
860         gen_op_ldw_T0_T0(ctx);
861         gen_op_movl_T0_rN(REG(0));
862         return;
863     case 0xc700:                /* mova @(disp,PC),R0 */
864         gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
865                            REG(0));
866         return;
867     case 0xcb00:                /* or #imm,R0 */
868         gen_op_or_imm_rN(B7_0, REG(0));
869         return;
870     case 0xcf00:                /* or.b #imm,@(R0,GBR) */
871         gen_op_movl_rN_T0(REG(0));
872         gen_op_addl_GBR_T0();
873         gen_op_movl_T0_T1();
874         gen_op_ldub_T0_T0(ctx);
875         gen_op_or_imm_T0(B7_0);
876         gen_op_stb_T0_T1(ctx);
877         return;
878     case 0xc300:                /* trapa #imm */
879         CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
880         gen_op_trapa(B7_0);
881         ctx->bstate = BS_BRANCH;
882         return;
883     case 0xc800:                /* tst #imm,R0 */
884         gen_op_tst_imm_rN(B7_0, REG(0));
885         return;
886     case 0xcc00:                /* tst.b #imm,@(R0,GBR) */
887         gen_op_movl_rN_T0(REG(0));
888         gen_op_addl_GBR_T0();
889         gen_op_ldub_T0_T0(ctx);
890         gen_op_tst_imm_T0(B7_0);
891         return;
892     case 0xca00:                /* xor #imm,R0 */
893         gen_op_xor_imm_rN(B7_0, REG(0));
894         return;
895     case 0xce00:                /* xor.b #imm,@(R0,GBR) */
896         gen_op_movl_rN_T0(REG(0));
897         gen_op_addl_GBR_T0();
898         gen_op_movl_T0_T1();
899         gen_op_ldub_T0_T0(ctx);
900         gen_op_xor_imm_T0(B7_0);
901         gen_op_stb_T0_T1(ctx);
902         return;
903     }
904
905     switch (ctx->opcode & 0xf08f) {
906     case 0x408e:                /* ldc Rm,Rn_BANK */
907         gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
908         return;
909     case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
910         gen_op_movl_rN_T0(REG(B11_8));
911         gen_op_ldl_T0_T0(ctx);
912         gen_op_movl_T0_rN(ALTREG(B6_4));
913         gen_op_inc4_rN(REG(B11_8));
914         return;
915     case 0x0082:                /* stc Rm_BANK,Rn */
916         gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
917         return;
918     case 0x4083:                /* stc.l Rm_BANK,@-Rn */
919         gen_op_dec4_rN(REG(B11_8));
920         gen_op_movl_rN_T1(REG(B11_8));
921         gen_op_movl_rN_T0(ALTREG(B6_4));
922         gen_op_stl_T0_T1(ctx);
923         return;
924     }
925
926     switch (ctx->opcode & 0xf0ff) {
927     case 0x0023:                /* braf Rn */
928         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
929         gen_op_braf_T0(ctx->pc + 4);
930         ctx->flags |= DELAY_SLOT;
931         ctx->delayed_pc = (uint32_t) - 1;
932         return;
933     case 0x0003:                /* bsrf Rn */
934         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
935         gen_op_bsrf_T0(ctx->pc + 4);
936         ctx->flags |= DELAY_SLOT;
937         ctx->delayed_pc = (uint32_t) - 1;
938         return;
939     case 0x4015:                /* cmp/pl Rn */
940         gen_op_movl_rN_T0(REG(B11_8));
941         gen_op_cmp_pl_T0();
942         return;
943     case 0x4011:                /* cmp/pz Rn */
944         gen_op_movl_rN_T0(REG(B11_8));
945         gen_op_cmp_pz_T0();
946         return;
947     case 0x4010:                /* dt Rn */
948         gen_op_dt_rN(REG(B11_8));
949         return;
950     case 0x402b:                /* jmp @Rn */
951         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
952         gen_op_jmp_T0();
953         ctx->flags |= DELAY_SLOT;
954         ctx->delayed_pc = (uint32_t) - 1;
955         return;
956     case 0x400b:                /* jsr @Rn */
957         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
958         gen_op_jsr_T0(ctx->pc + 4);
959         ctx->flags |= DELAY_SLOT;
960         ctx->delayed_pc = (uint32_t) - 1;
961         return;
962 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)   \
963   case ldnum:                                                   \
964     gen_op_movl_rN_T0 (REG(B11_8));                             \
965     gen_op_##ldop##_T0_##reg ();                                \
966     extrald                                                     \
967     return;                                                     \
968   case ldpnum:                                                  \
969     gen_op_movl_rN_T0 (REG(B11_8));                             \
970     gen_op_ldl_T0_T0 (ctx);                                     \
971     gen_op_inc4_rN (REG(B11_8));                                \
972     gen_op_##ldop##_T0_##reg ();                                \
973     extrald                                                     \
974     return;                                                     \
975   case stnum:                                                   \
976     gen_op_##stop##_##reg##_T0 ();                                      \
977     gen_op_movl_T0_rN (REG(B11_8));                             \
978     return;                                                     \
979   case stpnum:                                                  \
980     gen_op_##stop##_##reg##_T0 ();                              \
981     gen_op_dec4_rN (REG(B11_8));                                \
982     gen_op_movl_rN_T1 (REG(B11_8));                             \
983     gen_op_stl_T0_T1 (ctx);                                     \
984     return;
985         LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
986              BS_STOP;)
987         LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
988         LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
989         LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
990         LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
991         LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
992         LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
993         LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
994         LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
995         LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
996         LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
997              BS_STOP;)
998     case 0x00c3:                /* movca.l R0,@Rm */
999         gen_op_movl_rN_T0(REG(0));
1000         gen_op_movl_rN_T1(REG(B11_8));
1001         gen_op_stl_T0_T1(ctx);
1002         return;
1003     case 0x0029:                /* movt Rn */
1004         gen_op_movt_rN(REG(B11_8));
1005         return;
1006     case 0x0093:                /* ocbi @Rn */
1007         gen_op_movl_rN_T0(REG(B11_8));
1008         gen_op_ldl_T0_T0(ctx);
1009         return;
1010     case 0x00a3:                /* ocbp @Rn */
1011         gen_op_movl_rN_T0(REG(B11_8));
1012         gen_op_ldl_T0_T0(ctx);
1013         return;
1014     case 0x00b3:                /* ocbwb @Rn */
1015         gen_op_movl_rN_T0(REG(B11_8));
1016         gen_op_ldl_T0_T0(ctx);
1017         return;
1018     case 0x0083:                /* pref @Rn */
1019         return;
1020     case 0x4024:                /* rotcl Rn */
1021         gen_op_rotcl_Rn(REG(B11_8));
1022         return;
1023     case 0x4025:                /* rotcr Rn */
1024         gen_op_rotcr_Rn(REG(B11_8));
1025         return;
1026     case 0x4004:                /* rotl Rn */
1027         gen_op_rotl_Rn(REG(B11_8));
1028         return;
1029     case 0x4005:                /* rotr Rn */
1030         gen_op_rotr_Rn(REG(B11_8));
1031         return;
1032     case 0x4000:                /* shll Rn */
1033     case 0x4020:                /* shal Rn */
1034         gen_op_shal_Rn(REG(B11_8));
1035         return;
1036     case 0x4021:                /* shar Rn */
1037         gen_op_shar_Rn(REG(B11_8));
1038         return;
1039     case 0x4001:                /* shlr Rn */
1040         gen_op_shlr_Rn(REG(B11_8));
1041         return;
1042     case 0x4008:                /* shll2 Rn */
1043         gen_op_shll2_Rn(REG(B11_8));
1044         return;
1045     case 0x4018:                /* shll8 Rn */
1046         gen_op_shll8_Rn(REG(B11_8));
1047         return;
1048     case 0x4028:                /* shll16 Rn */
1049         gen_op_shll16_Rn(REG(B11_8));
1050         return;
1051     case 0x4009:                /* shlr2 Rn */
1052         gen_op_shlr2_Rn(REG(B11_8));
1053         return;
1054     case 0x4019:                /* shlr8 Rn */
1055         gen_op_shlr8_Rn(REG(B11_8));
1056         return;
1057     case 0x4029:                /* shlr16 Rn */
1058         gen_op_shlr16_Rn(REG(B11_8));
1059         return;
1060     case 0x401b:                /* tas.b @Rn */
1061         gen_op_tasb_rN(REG(B11_8));
1062         return;
1063     case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1064         gen_op_movl_fpul_FT0();
1065         gen_op_fmov_FT0_frN(FREG(B11_8));
1066         return;
1067     case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1068         gen_op_fmov_frN_FT0(FREG(B11_8));
1069         gen_op_movl_FT0_fpul();
1070         return;
1071     case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1072         if (ctx->fpscr & FPSCR_PR) {
1073             if (ctx->opcode & 0x0100)
1074                 break; /* illegal instruction */
1075             gen_op_float_DT();
1076             gen_op_fmov_DT0_drN(DREG(B11_8));
1077         }
1078         else {
1079             gen_op_float_FT();
1080             gen_op_fmov_FT0_frN(FREG(B11_8));
1081         }
1082         return;
1083     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1084         if (ctx->fpscr & FPSCR_PR) {
1085             if (ctx->opcode & 0x0100)
1086                 break; /* illegal instruction */
1087             gen_op_fmov_drN_DT0(DREG(B11_8));
1088             gen_op_ftrc_DT();
1089         }
1090         else {
1091             gen_op_fmov_frN_FT0(FREG(B11_8));
1092             gen_op_ftrc_FT();
1093         }
1094         return;
1095     case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1096         gen_op_fneg_frN(FREG(B11_8));
1097         return;
1098     case 0xf05d: /* fabs FRn/DRn */
1099         if (ctx->fpscr & FPSCR_PR) {
1100             if (ctx->opcode & 0x0100)
1101                 break; /* illegal instruction */
1102             gen_op_fmov_drN_DT0(DREG(B11_8));
1103             gen_op_fabs_DT();
1104             gen_op_fmov_DT0_drN(DREG(B11_8));
1105         } else {
1106             gen_op_fmov_frN_FT0(FREG(B11_8));
1107             gen_op_fabs_FT();
1108             gen_op_fmov_FT0_frN(FREG(B11_8));
1109         }
1110         return;
1111     case 0xf06d: /* fsqrt FRn */
1112         if (ctx->fpscr & FPSCR_PR) {
1113             if (ctx->opcode & 0x0100)
1114                 break; /* illegal instruction */
1115             gen_op_fmov_drN_DT0(FREG(B11_8));
1116             gen_op_fsqrt_DT();
1117             gen_op_fmov_DT0_drN(FREG(B11_8));
1118         } else {
1119             gen_op_fmov_frN_FT0(FREG(B11_8));
1120             gen_op_fsqrt_FT();
1121             gen_op_fmov_FT0_frN(FREG(B11_8));
1122         }
1123         return;
1124     case 0xf07d: /* fsrra FRn */
1125         break;
1126     case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1127         if (!(ctx->fpscr & FPSCR_PR)) {
1128             gen_op_movl_imm_T0(0);
1129             gen_op_fmov_T0_frN(FREG(B11_8));
1130             return;
1131         }
1132         break;
1133     case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1134         if (!(ctx->fpscr & FPSCR_PR)) {
1135             gen_op_movl_imm_T0(0x3f800000);
1136             gen_op_fmov_T0_frN(FREG(B11_8));
1137             return;
1138         }
1139         break;
1140     case 0xf0ad: /* fcnvsd FPUL,DRn */
1141         gen_op_movl_fpul_FT0();
1142         gen_op_fcnvsd_FT_DT();
1143         gen_op_fmov_DT0_drN(DREG(B11_8));
1144         return;
1145     case 0xf0bd: /* fcnvds DRn,FPUL */
1146         gen_op_fmov_drN_DT0(DREG(B11_8));
1147         gen_op_fcnvds_DT_FT();
1148         gen_op_movl_FT0_fpul();
1149         return;
1150     }
1151
1152     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1153             ctx->opcode, ctx->pc);
1154     gen_op_raise_illegal_instruction();
1155     ctx->bstate = BS_EXCP;
1156 }
1157
1158 void decode_opc(DisasContext * ctx)
1159 {
1160     uint32_t old_flags = ctx->flags;
1161
1162     _decode_opc(ctx);
1163
1164     if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1165         if (ctx->flags & DELAY_SLOT_CLEARME) {
1166             gen_op_store_flags(0);
1167         }
1168         ctx->flags = 0;
1169         ctx->bstate = BS_BRANCH;
1170         if (old_flags & DELAY_SLOT_CONDITIONAL) {
1171             gen_delayed_conditional_jump(ctx);
1172         } else if (old_flags & DELAY_SLOT) {
1173             gen_jump(ctx);
1174         }
1175
1176     }
1177 }
1178
1179 static inline int
1180 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1181                                int search_pc)
1182 {
1183     DisasContext ctx;
1184     target_ulong pc_start;
1185     static uint16_t *gen_opc_end;
1186     int i, ii;
1187
1188     pc_start = tb->pc;
1189     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1190     ctx.pc = pc_start;
1191     ctx.flags = (uint32_t)tb->flags;
1192     ctx.bstate = BS_NONE;
1193     ctx.sr = env->sr;
1194     ctx.fpscr = env->fpscr;
1195     ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1196     /* We don't know if the delayed pc came from a dynamic or static branch,
1197        so assume it is a dynamic branch.  */
1198     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1199     ctx.tb = tb;
1200     ctx.singlestep_enabled = env->singlestep_enabled;
1201
1202 #ifdef DEBUG_DISAS
1203     if (loglevel & CPU_LOG_TB_CPU) {
1204         fprintf(logfile,
1205                 "------------------------------------------------\n");
1206         cpu_dump_state(env, logfile, fprintf, 0);
1207     }
1208 #endif
1209
1210     ii = -1;
1211     while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1212         if (env->nb_breakpoints > 0) {
1213             for (i = 0; i < env->nb_breakpoints; i++) {
1214                 if (ctx.pc == env->breakpoints[i]) {
1215                     /* We have hit a breakpoint - make sure PC is up-to-date */
1216                     gen_op_movl_imm_PC(ctx.pc);
1217                     gen_op_debug();
1218                     ctx.bstate = BS_EXCP;
1219                     break;
1220                 }
1221             }
1222         }
1223         if (search_pc) {
1224             i = gen_opc_ptr - gen_opc_buf;
1225             if (ii < i) {
1226                 ii++;
1227                 while (ii < i)
1228                     gen_opc_instr_start[ii++] = 0;
1229             }
1230             gen_opc_pc[ii] = ctx.pc;
1231             gen_opc_hflags[ii] = ctx.flags;
1232             gen_opc_instr_start[ii] = 1;
1233         }
1234 #if 0
1235         fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1236         fflush(stderr);
1237 #endif
1238         ctx.opcode = lduw_code(ctx.pc);
1239         decode_opc(&ctx);
1240         ctx.pc += 2;
1241         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1242             break;
1243         if (env->singlestep_enabled)
1244             break;
1245 #ifdef SH4_SINGLE_STEP
1246         break;
1247 #endif
1248     }
1249     if (env->singlestep_enabled) {
1250         gen_op_debug();
1251     } else {
1252         switch (ctx.bstate) {
1253         case BS_STOP:
1254             /* gen_op_interrupt_restart(); */
1255             /* fall through */
1256         case BS_NONE:
1257             if (ctx.flags) {
1258                 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1259             }
1260             gen_goto_tb(&ctx, 0, ctx.pc);
1261             break;
1262         case BS_EXCP:
1263             /* gen_op_interrupt_restart(); */
1264             tcg_gen_exit_tb(0);
1265             break;
1266         case BS_BRANCH:
1267         default:
1268             break;
1269         }
1270     }
1271
1272     *gen_opc_ptr = INDEX_op_end;
1273     if (search_pc) {
1274         i = gen_opc_ptr - gen_opc_buf;
1275         ii++;
1276         while (ii <= i)
1277             gen_opc_instr_start[ii++] = 0;
1278     } else {
1279         tb->size = ctx.pc - pc_start;
1280     }
1281
1282 #ifdef DEBUG_DISAS
1283 #ifdef SH4_DEBUG_DISAS
1284     if (loglevel & CPU_LOG_TB_IN_ASM)
1285         fprintf(logfile, "\n");
1286 #endif
1287     if (loglevel & CPU_LOG_TB_IN_ASM) {
1288         fprintf(logfile, "IN:\n");      /* , lookup_symbol(pc_start)); */
1289         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1290         fprintf(logfile, "\n");
1291     }
1292 #endif
1293     return 0;
1294 }
1295
1296 int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1297 {
1298     return gen_intermediate_code_internal(env, tb, 0);
1299 }
1300
1301 int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1302 {
1303     return gen_intermediate_code_internal(env, tb, 1);
1304 }