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