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