Ignore PR flag in FPSCR when performing fmov, 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_SZ) {
652             if (ctx->opcode & 0x0110)
653                 break; /* illegal instruction */
654             gen_op_fmov_drN_DT0(DREG(B7_4));
655             gen_op_fmov_DT0_drN(DREG(B11_8));
656         } else {
657             gen_op_fmov_frN_FT0(FREG(B7_4));
658             gen_op_fmov_FT0_frN(FREG(B11_8));
659         }
660         return;
661     case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
662         if (ctx->fpscr & FPSCR_SZ) {
663             if (ctx->opcode & 0x0010)
664                 break; /* illegal instruction */
665             gen_op_fmov_drN_DT0(DREG(B7_4));
666             gen_op_movl_rN_T1(REG(B11_8));
667             gen_op_stfq_DT0_T1(ctx);
668         } else {
669             gen_op_fmov_frN_FT0(FREG(B7_4));
670             gen_op_movl_rN_T1(REG(B11_8));
671             gen_op_stfl_FT0_T1(ctx);
672         }
673         return;
674     case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
675         if (ctx->fpscr & FPSCR_SZ) {
676             if (ctx->opcode & 0x0100)
677                 break; /* illegal instruction */
678             gen_op_movl_rN_T0(REG(B7_4));
679             gen_op_ldfq_T0_DT0(ctx);
680             gen_op_fmov_DT0_drN(DREG(B11_8));
681         } else {
682             gen_op_movl_rN_T0(REG(B7_4));
683             gen_op_ldfl_T0_FT0(ctx);
684             gen_op_fmov_FT0_frN(FREG(B11_8));
685         }
686         return;
687     case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
688         if (ctx->fpscr & FPSCR_SZ) {
689             if (ctx->opcode & 0x0100)
690                 break; /* illegal instruction */
691             gen_op_movl_rN_T0(REG(B7_4));
692             gen_op_ldfq_T0_DT0(ctx);
693             gen_op_fmov_DT0_drN(DREG(B11_8));
694             gen_op_inc8_rN(REG(B7_4));
695         } else {
696             gen_op_movl_rN_T0(REG(B7_4));
697             gen_op_ldfl_T0_FT0(ctx);
698             gen_op_fmov_FT0_frN(FREG(B11_8));
699             gen_op_inc4_rN(REG(B7_4));
700         }
701         return;
702     case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
703         if (ctx->fpscr & FPSCR_SZ) {
704             if (ctx->opcode & 0x0100)
705                 break; /* illegal instruction */
706             gen_op_dec8_rN(REG(B11_8));
707             gen_op_fmov_drN_DT0(DREG(B7_4));
708             gen_op_movl_rN_T1(REG(B11_8));
709             gen_op_stfq_DT0_T1(ctx);
710         } else {
711             gen_op_dec4_rN(REG(B11_8));
712             gen_op_fmov_frN_FT0(FREG(B7_4));
713             gen_op_movl_rN_T1(REG(B11_8));
714             gen_op_stfl_FT0_T1(ctx);
715         }
716         return;
717     case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
718         if (ctx->fpscr & FPSCR_SZ) {
719             if (ctx->opcode & 0x0100)
720                 break; /* illegal instruction */
721             gen_op_movl_rN_T0(REG(B7_4));
722             gen_op_add_rN_T0(REG(0));
723             gen_op_ldfq_T0_DT0(ctx);
724             gen_op_fmov_DT0_drN(DREG(B11_8));
725         } else {
726             gen_op_movl_rN_T0(REG(B7_4));
727             gen_op_add_rN_T0(REG(0));
728             gen_op_ldfl_T0_FT0(ctx);
729             gen_op_fmov_FT0_frN(FREG(B11_8));
730         }
731         return;
732     case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
733         if (ctx->fpscr & FPSCR_SZ) {
734             if (ctx->opcode & 0x0010)
735                 break; /* illegal instruction */
736             gen_op_fmov_drN_DT0(DREG(B7_4));
737             gen_op_movl_rN_T1(REG(B11_8));
738             gen_op_add_rN_T1(REG(0));
739             gen_op_stfq_DT0_T1(ctx);
740         } else {
741             gen_op_fmov_frN_FT0(FREG(B7_4));
742             gen_op_movl_rN_T1(REG(B11_8));
743             gen_op_add_rN_T1(REG(0));
744             gen_op_stfl_FT0_T1(ctx);
745         }
746         return;
747     case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
748     case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
749     case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
750     case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
751     case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
752     case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
753         if (ctx->fpscr & FPSCR_PR) {
754             if (ctx->opcode & 0x0110)
755                 break; /* illegal instruction */
756             gen_op_fmov_drN_DT1(DREG(B7_4));
757             gen_op_fmov_drN_DT0(DREG(B11_8));
758         }
759         else {
760             gen_op_fmov_frN_FT1(FREG(B7_4));
761             gen_op_fmov_frN_FT0(FREG(B11_8));
762         }
763
764         switch (ctx->opcode & 0xf00f) {
765         case 0xf000:            /* fadd Rm,Rn */
766             ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
767             break;
768         case 0xf001:            /* fsub Rm,Rn */
769             ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
770             break;
771         case 0xf002:            /* fmul Rm,Rn */
772             ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
773             break;
774         case 0xf003:            /* fdiv Rm,Rn */
775             ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
776             break;
777         case 0xf004:            /* fcmp/eq Rm,Rn */
778             return;
779         case 0xf005:            /* fcmp/gt Rm,Rn */
780             return;
781         }
782
783         if (ctx->fpscr & FPSCR_PR) {
784             gen_op_fmov_DT0_drN(DREG(B11_8));
785         }
786         else {
787             gen_op_fmov_FT0_frN(FREG(B11_8));
788         }
789         return;
790     }
791
792     switch (ctx->opcode & 0xff00) {
793     case 0xc900:                /* and #imm,R0 */
794         gen_op_and_imm_rN(B7_0, REG(0));
795         return;
796     case 0xcd00:                /* and.b #imm,@(R0+GBR) */
797         gen_op_movl_rN_T0(REG(0));
798         gen_op_addl_GBR_T0();
799         gen_op_movl_T0_T1();
800         gen_op_ldb_T0_T0(ctx);
801         gen_op_and_imm_T0(B7_0);
802         gen_op_stb_T0_T1(ctx);
803         return;
804     case 0x8b00:                /* bf label */
805         CHECK_NOT_DELAY_SLOT
806             gen_conditional_jump(ctx, ctx->pc + 2,
807                                  ctx->pc + 4 + B7_0s * 2);
808         ctx->flags |= BRANCH_CONDITIONAL;
809         return;
810     case 0x8f00:                /* bf/s label */
811         CHECK_NOT_DELAY_SLOT
812             gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
813         ctx->flags |= DELAY_SLOT_CONDITIONAL;
814         return;
815     case 0x8900:                /* bt label */
816         CHECK_NOT_DELAY_SLOT
817             gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
818                                  ctx->pc + 2);
819         ctx->flags |= BRANCH_CONDITIONAL;
820         return;
821     case 0x8d00:                /* bt/s label */
822         CHECK_NOT_DELAY_SLOT
823             gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
824         ctx->flags |= DELAY_SLOT_CONDITIONAL;
825         return;
826     case 0x8800:                /* cmp/eq #imm,R0 */
827         gen_op_movl_rN_T0(REG(0));
828         gen_op_cmp_eq_imm_T0(B7_0s);
829         return;
830     case 0xc400:                /* mov.b @(disp,GBR),R0 */
831         gen_op_stc_gbr_T0();
832         gen_op_addl_imm_T0(B7_0);
833         gen_op_ldb_T0_T0(ctx);
834         gen_op_movl_T0_rN(REG(0));
835         return;
836     case 0xc500:                /* mov.w @(disp,GBR),R0 */
837         gen_op_stc_gbr_T0();
838         gen_op_addl_imm_T0(B7_0);
839         gen_op_ldw_T0_T0(ctx);
840         gen_op_movl_T0_rN(REG(0));
841         return;
842     case 0xc600:                /* mov.l @(disp,GBR),R0 */
843         gen_op_stc_gbr_T0();
844         gen_op_addl_imm_T0(B7_0);
845         gen_op_ldl_T0_T0(ctx);
846         gen_op_movl_T0_rN(REG(0));
847         return;
848     case 0xc000:                /* mov.b R0,@(disp,GBR) */
849         gen_op_stc_gbr_T0();
850         gen_op_addl_imm_T0(B7_0);
851         gen_op_movl_T0_T1();
852         gen_op_movl_rN_T0(REG(0));
853         gen_op_stb_T0_T1(ctx);
854         return;
855     case 0xc100:                /* mov.w R0,@(disp,GBR) */
856         gen_op_stc_gbr_T0();
857         gen_op_addl_imm_T0(B7_0);
858         gen_op_movl_T0_T1();
859         gen_op_movl_rN_T0(REG(0));
860         gen_op_stw_T0_T1(ctx);
861         return;
862     case 0xc200:                /* mov.l R0,@(disp,GBR) */
863         gen_op_stc_gbr_T0();
864         gen_op_addl_imm_T0(B7_0);
865         gen_op_movl_T0_T1();
866         gen_op_movl_rN_T0(REG(0));
867         gen_op_stl_T0_T1(ctx);
868         return;
869     case 0x8000:                /* mov.b R0,@(disp,Rn) */
870         gen_op_movl_rN_T0(REG(0));
871         gen_op_movl_rN_T1(REG(B7_4));
872         gen_op_addl_imm_T1(B3_0);
873         gen_op_stb_T0_T1(ctx);
874         return;
875     case 0x8100:                /* mov.w R0,@(disp,Rn) */
876         gen_op_movl_rN_T0(REG(0));
877         gen_op_movl_rN_T1(REG(B7_4));
878         gen_op_addl_imm_T1(B3_0 * 2);
879         gen_op_stw_T0_T1(ctx);
880         return;
881     case 0x8400:                /* mov.b @(disp,Rn),R0 */
882         gen_op_movl_rN_T0(REG(0));
883         gen_op_movl_rN_T1(REG(B7_4));
884         gen_op_addl_imm_T1(B3_0);
885         gen_op_stb_T0_T1(ctx);
886         return;
887     case 0x8500:                /* mov.w @(disp,Rn),R0 */
888         gen_op_movl_rN_T0(REG(B7_4));
889         gen_op_addl_imm_T0(B3_0 * 2);
890         gen_op_ldw_T0_T0(ctx);
891         gen_op_movl_T0_rN(REG(0));
892         return;
893     case 0xc700:                /* mova @(disp,PC),R0 */
894         gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
895                            REG(0));
896         return;
897     case 0xcb00:                /* or #imm,R0 */
898         gen_op_or_imm_rN(B7_0, REG(0));
899         return;
900     case 0xcf00:                /* or.b #imm,@(R0+GBR) */
901         gen_op_movl_rN_T0(REG(0));
902         gen_op_addl_GBR_T0();
903         gen_op_movl_T0_T1();
904         gen_op_ldb_T0_T0(ctx);
905         gen_op_or_imm_T0(B7_0);
906         gen_op_stb_T0_T1(ctx);
907         return;
908     case 0xc300:                /* trapa #imm */
909         CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
910         gen_op_trapa(B7_0);
911         ctx->flags |= BRANCH;
912         return;
913     case 0xc800:                /* tst #imm,R0 */
914         gen_op_tst_imm_rN(B7_0, REG(0));
915         return;
916     case 0xcc00:                /* tst #imm,@(R0+GBR) */
917         gen_op_movl_rN_T0(REG(0));
918         gen_op_addl_GBR_T0();
919         gen_op_ldb_T0_T0(ctx);
920         gen_op_tst_imm_T0(B7_0);
921         return;
922     case 0xca00:                /* xor #imm,R0 */
923         gen_op_xor_imm_rN(B7_0, REG(0));
924         return;
925     case 0xce00:                /* xor.b #imm,@(R0+GBR) */
926         gen_op_movl_rN_T0(REG(0));
927         gen_op_addl_GBR_T0();
928         gen_op_movl_T0_T1();
929         gen_op_ldb_T0_T0(ctx);
930         gen_op_xor_imm_T0(B7_0);
931         gen_op_stb_T0_T1(ctx);
932         return;
933     }
934
935     switch (ctx->opcode & 0xf08f) {
936     case 0x408e:                /* ldc Rm,Rn_BANK */
937         gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
938         return;
939     case 0x4087:                /* ldc.l @Rm+,Rn_BANK */
940         gen_op_movl_rN_T0(REG(B11_8));
941         gen_op_ldl_T0_T0(ctx);
942         gen_op_movl_T0_rN(ALTREG(B6_4));
943         gen_op_inc4_rN(REG(B11_8));
944         return;
945     case 0x0082:                /* stc Rm_BANK,Rn */
946         gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
947         return;
948     case 0x4083:                /* stc.l Rm_BANK,@-Rn */
949         gen_op_dec4_rN(REG(B11_8));
950         gen_op_movl_rN_T1(REG(B11_8));
951         gen_op_movl_rN_T0(ALTREG(B6_4));
952         gen_op_stl_T0_T1(ctx);
953         return;
954     }
955
956     switch (ctx->opcode & 0xf0ff) {
957     case 0x0023:                /* braf Rn */
958         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
959         gen_op_braf_T0(ctx->pc + 4);
960         ctx->flags |= DELAY_SLOT;
961         ctx->delayed_pc = (uint32_t) - 1;
962         return;
963     case 0x0003:                /* bsrf Rn */
964         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
965         gen_op_bsrf_T0(ctx->pc + 4);
966         ctx->flags |= DELAY_SLOT;
967         ctx->delayed_pc = (uint32_t) - 1;
968         return;
969     case 0x4015:                /* cmp/pl Rn */
970         gen_op_movl_rN_T0(REG(B11_8));
971         gen_op_cmp_pl_T0();
972         return;
973     case 0x4011:                /* cmp/pz Rn */
974         gen_op_movl_rN_T0(REG(B11_8));
975         gen_op_cmp_pz_T0();
976         return;
977     case 0x4010:                /* dt Rn */
978         gen_op_dt_rN(REG(B11_8));
979         return;
980     case 0x402b:                /* jmp @Rn */
981         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
982         gen_op_jmp_T0();
983         ctx->flags |= DELAY_SLOT;
984         ctx->delayed_pc = (uint32_t) - 1;
985         return;
986     case 0x400b:                /* jsr @Rn */
987         CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
988         gen_op_jsr_T0(ctx->pc + 4);
989         ctx->flags |= DELAY_SLOT;
990         ctx->delayed_pc = (uint32_t) - 1;
991         return;
992 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald)   \
993   case ldnum:                                                   \
994     gen_op_movl_rN_T0 (REG(B11_8));                             \
995     gen_op_##ldop##_T0_##reg ();                                \
996     extrald                                                     \
997     return;                                                     \
998   case ldpnum:                                                  \
999     gen_op_movl_rN_T0 (REG(B11_8));                             \
1000     gen_op_ldl_T0_T0 (ctx);                                     \
1001     gen_op_inc4_rN (REG(B11_8));                                \
1002     gen_op_##ldop##_T0_##reg ();                                \
1003     extrald                                                     \
1004     return;                                                     \
1005   case stnum:                                                   \
1006     gen_op_##stop##_##reg##_T0 ();                                      \
1007     gen_op_movl_T0_rN (REG(B11_8));                             \
1008     return;                                                     \
1009   case stpnum:                                                  \
1010     gen_op_##stop##_##reg##_T0 ();                              \
1011     gen_op_dec4_rN (REG(B11_8));                                \
1012     gen_op_movl_rN_T1 (REG(B11_8));                             \
1013     gen_op_stl_T0_T1 (ctx);                                     \
1014     return;
1015         LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
1016              MODE_CHANGE;)
1017         LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1018         LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1019         LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1020         LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1021         LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1022         LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1023         LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1024         LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1025         LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1026         LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->flags |=
1027              MODE_CHANGE;)
1028     case 0x00c3:                /* movca.l R0,@Rm */
1029         gen_op_movl_rN_T0(REG(0));
1030         gen_op_movl_rN_T1(REG(B11_8));
1031         gen_op_stl_T0_T1(ctx);
1032         return;
1033     case 0x0029:                /* movt Rn */
1034         gen_op_movt_rN(REG(B11_8));
1035         return;
1036     case 0x0093:                /* ocbi @Rn */
1037         gen_op_movl_rN_T0(REG(B11_8));
1038         gen_op_ldl_T0_T0(ctx);
1039         return;
1040     case 0x00a2:                /* ocbp @Rn */
1041         gen_op_movl_rN_T0(REG(B11_8));
1042         gen_op_ldl_T0_T0(ctx);
1043         return;
1044     case 0x00b3:                /* ocbwb @Rn */
1045         gen_op_movl_rN_T0(REG(B11_8));
1046         gen_op_ldl_T0_T0(ctx);
1047         return;
1048     case 0x0083:                /* pref @Rn */
1049         return;
1050     case 0x4024:                /* rotcl Rn */
1051         gen_op_rotcl_Rn(REG(B11_8));
1052         return;
1053     case 0x4025:                /* rotcr Rn */
1054         gen_op_rotcr_Rn(REG(B11_8));
1055         return;
1056     case 0x4004:                /* rotl Rn */
1057         gen_op_rotl_Rn(REG(B11_8));
1058         return;
1059     case 0x4005:                /* rotr Rn */
1060         gen_op_rotr_Rn(REG(B11_8));
1061         return;
1062     case 0x4000:                /* shll Rn */
1063     case 0x4020:                /* shal Rn */
1064         gen_op_shal_Rn(REG(B11_8));
1065         return;
1066     case 0x4021:                /* shar Rn */
1067         gen_op_shar_Rn(REG(B11_8));
1068         return;
1069     case 0x4001:                /* shlr Rn */
1070         gen_op_shlr_Rn(REG(B11_8));
1071         return;
1072     case 0x4008:                /* shll2 Rn */
1073         gen_op_shll2_Rn(REG(B11_8));
1074         return;
1075     case 0x4018:                /* shll8 Rn */
1076         gen_op_shll8_Rn(REG(B11_8));
1077         return;
1078     case 0x4028:                /* shll16 Rn */
1079         gen_op_shll16_Rn(REG(B11_8));
1080         return;
1081     case 0x4009:                /* shlr2 Rn */
1082         gen_op_shlr2_Rn(REG(B11_8));
1083         return;
1084     case 0x4019:                /* shlr8 Rn */
1085         gen_op_shlr8_Rn(REG(B11_8));
1086         return;
1087     case 0x4029:                /* shlr16 Rn */
1088         gen_op_shlr16_Rn(REG(B11_8));
1089         return;
1090     case 0x401b:                /* tas.b @Rn */
1091         gen_op_tasb_rN(REG(B11_8));
1092         return;
1093     case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1094         gen_op_movl_fpul_FT0();
1095         gen_op_fmov_FT0_frN(FREG(B11_8));
1096         return;
1097     case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1098         gen_op_fmov_frN_FT0(FREG(B11_8));
1099         gen_op_movl_FT0_fpul();
1100         return;
1101     case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1102         if (ctx->fpscr & FPSCR_PR) {
1103             if (ctx->opcode & 0x0100)
1104                 break; /* illegal instruction */
1105             gen_op_float_DT();
1106             gen_op_fmov_DT0_drN(DREG(B11_8));
1107         }
1108         else {
1109             gen_op_float_FT();
1110             gen_op_fmov_FT0_frN(FREG(B11_8));
1111         }
1112         return;
1113     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1114         if (ctx->fpscr & FPSCR_PR) {
1115             if (ctx->opcode & 0x0100)
1116                 break; /* illegal instruction */
1117             gen_op_fmov_drN_DT0(DREG(B11_8));
1118             gen_op_ftrc_DT();
1119         }
1120         else {
1121             gen_op_fmov_frN_FT0(FREG(B11_8));
1122             gen_op_ftrc_FT();
1123         }
1124         return;
1125     case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1126         if (!(ctx->fpscr & FPSCR_PR)) {
1127             gen_op_movl_imm_T0(0);
1128             gen_op_fmov_T0_frN(FREG(B11_8));
1129             return;
1130         }
1131         break;
1132     case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1133         if (!(ctx->fpscr & FPSCR_PR)) {
1134             gen_op_movl_imm_T0(0x3f800000);
1135             gen_op_fmov_T0_frN(FREG(B11_8));
1136             return;
1137         }
1138         break;
1139     }
1140
1141     fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1142             ctx->opcode, ctx->pc);
1143     gen_op_raise_illegal_instruction();
1144     ctx->flags |= BRANCH_EXCEPTION;
1145 }
1146
1147 static inline int
1148 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1149                                int search_pc)
1150 {
1151     DisasContext ctx;
1152     target_ulong pc_start;
1153     static uint16_t *gen_opc_end;
1154     uint32_t old_flags;
1155     int i, ii;
1156
1157     pc_start = tb->pc;
1158     gen_opc_ptr = gen_opc_buf;
1159     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1160     gen_opparam_ptr = gen_opparam_buf;
1161     ctx.pc = pc_start;
1162     ctx.flags = env->flags;
1163     old_flags = 0;
1164     ctx.sr = env->sr;
1165     ctx.fpscr = env->fpscr;
1166     ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1167     /* We don't know if the delayed pc came from a dynamic or static branch,
1168        so assume it is a dynamic branch.  */
1169     ctx.delayed_pc = -1;
1170     ctx.tb = tb;
1171     ctx.singlestep_enabled = env->singlestep_enabled;
1172     nb_gen_labels = 0;
1173
1174 #ifdef DEBUG_DISAS
1175     if (loglevel & CPU_LOG_TB_CPU) {
1176         fprintf(logfile,
1177                 "------------------------------------------------\n");
1178         cpu_dump_state(env, logfile, fprintf, 0);
1179     }
1180 #endif
1181
1182     ii = -1;
1183     while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1184            (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1185                          BRANCH_EXCEPTION)) == 0 &&
1186            gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1187         old_flags = ctx.flags;
1188         if (env->nb_breakpoints > 0) {
1189             for (i = 0; i < env->nb_breakpoints; i++) {
1190                 if (ctx.pc == env->breakpoints[i]) {
1191                     /* We have hit a breakpoint - make sure PC is up-to-date */
1192                     gen_op_movl_imm_PC(ctx.pc);
1193                     gen_op_debug();
1194                     ctx.flags |= BRANCH_EXCEPTION;
1195                     break;
1196                 }
1197             }
1198         }
1199         if (search_pc) {
1200             i = gen_opc_ptr - gen_opc_buf;
1201             if (ii < i) {
1202                 ii++;
1203                 while (ii < i)
1204                     gen_opc_instr_start[ii++] = 0;
1205             }
1206             gen_opc_pc[ii] = ctx.pc;
1207             gen_opc_instr_start[ii] = 1;
1208         }
1209 #if 0
1210         fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1211         fflush(stderr);
1212 #endif
1213         ctx.opcode = lduw_code(ctx.pc);
1214         decode_opc(&ctx);
1215         ctx.pc += 2;
1216         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1217             break;
1218         if (env->singlestep_enabled)
1219             break;
1220 #ifdef SH4_SINGLE_STEP
1221         break;
1222 #endif
1223     }
1224
1225     if (old_flags & DELAY_SLOT_CONDITIONAL) {
1226         gen_delayed_conditional_jump(&ctx);
1227     } else if (old_flags & DELAY_SLOT) {
1228         gen_op_clr_delay_slot();
1229         gen_jump(&ctx);
1230     } else if (ctx.flags & BRANCH_EXCEPTION) {
1231         gen_jump_exception(&ctx);
1232     } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1233         gen_goto_tb(&ctx, 0, ctx.pc);
1234     }
1235
1236     if (env->singlestep_enabled) {
1237         gen_op_debug();
1238     }
1239     *gen_opc_ptr = INDEX_op_end;
1240     if (search_pc) {
1241         i = gen_opc_ptr - gen_opc_buf;
1242         ii++;
1243         while (ii <= i)
1244             gen_opc_instr_start[ii++] = 0;
1245         tb->size = 0;
1246     } else {
1247         tb->size = ctx.pc - pc_start;
1248     }
1249
1250 #ifdef DEBUG_DISAS
1251 #ifdef SH4_DEBUG_DISAS
1252     if (loglevel & CPU_LOG_TB_IN_ASM)
1253         fprintf(logfile, "\n");
1254 #endif
1255     if (loglevel & CPU_LOG_TB_IN_ASM) {
1256         fprintf(logfile, "IN:\n");      /* , lookup_symbol(pc_start)); */
1257         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1258         fprintf(logfile, "\n");
1259     }
1260     if (loglevel & CPU_LOG_TB_OP) {
1261         fprintf(logfile, "OP:\n");
1262         dump_ops(gen_opc_buf, gen_opparam_buf);
1263         fprintf(logfile, "\n");
1264     }
1265 #endif
1266     return 0;
1267 }
1268
1269 int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1270 {
1271     return gen_intermediate_code_internal(env, tb, 0);
1272 }
1273
1274 int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1275 {
1276     return gen_intermediate_code_internal(env, tb, 1);
1277 }