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