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