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