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