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