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