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