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