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