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