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