4 * Copyright (c) 2005 Samuel Tardieu
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.
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.
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
28 #define SH4_DEBUG_DISAS
29 //#define SH4_SINGLE_STEP
36 #define DEF(s, n, copy_size) INDEX_op_ ## s,
42 #ifdef USE_DIRECT_JUMP
45 #define TBPARAM(x) ((long)(x))
48 static uint16_t *gen_opc_ptr;
49 static uint32_t *gen_opparam_ptr;
53 typedef struct DisasContext {
54 struct TranslationBlock *tb;
61 int singlestep_enabled;
64 #ifdef CONFIG_USER_ONLY
66 #define GEN_OP_LD(width) \
67 void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \
68 gen_op_ld##width##_T0_T0_raw(); \
70 #define GEN_OP_ST(width) \
71 void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \
72 gen_op_st##width##_T0_T1_raw(); \
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();\
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();\
99 void cpu_dump_state(CPUState * env, FILE * f,
100 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
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]);
111 if (env->flags & DELAY_SLOT) {
112 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
114 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
115 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
120 void cpu_sh4_reset(CPUSH4State * env)
122 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
124 env->pc = 0xA0000000;
125 env->fpscr = 0x00040001;
129 CPUSH4State *cpu_sh4_init(void)
133 env = qemu_mallocz(sizeof(CPUSH4State));
142 #ifdef CONFIG_USER_ONLY
143 target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
148 target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
150 target_ulong physical;
153 get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
158 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
160 TranslationBlock *tb;
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 */
167 gen_op_goto_tb0(TBPARAM(tb));
169 gen_op_goto_tb1(TBPARAM(tb));
170 gen_op_movl_imm_T0((long) tb + n);
172 gen_op_movl_imm_T0(0);
174 gen_op_movl_imm_PC(dest);
175 if (ctx->singlestep_enabled)
180 /* Jump to pc after an exception */
181 static void gen_jump_exception(DisasContext * ctx)
183 gen_op_movl_imm_T0(0);
184 if (ctx->singlestep_enabled)
189 static void gen_jump(DisasContext * ctx)
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)
200 gen_goto_tb(ctx, 0, ctx->delayed_pc);
204 /* Immediate conditional jump (bt or bf) */
205 static void gen_conditional_jump(DisasContext * ctx,
206 target_ulong ift, target_ulong ifnott)
210 l1 = gen_new_label();
212 gen_goto_tb(ctx, 0, ifnott);
214 gen_goto_tb(ctx, 1, ift);
217 /* Delayed conditional jump (bt or bf) */
218 static void gen_delayed_conditional_jump(DisasContext * ctx)
222 l1 = gen_new_label();
224 gen_goto_tb(ctx, 0, ctx->pc);
226 gen_goto_tb(ctx, 1, ctx->delayed_pc);
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)
239 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
242 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
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; \
250 void decode_opc(DisasContext * ctx)
253 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
255 switch (ctx->opcode) {
256 case 0x0019: /* div0u */
260 case 0x000b: /* rts */
261 CHECK_NOT_DELAY_SLOT gen_op_rts();
262 ctx->flags |= DELAY_SLOT;
263 ctx->delayed_pc = (uint32_t) - 1;
265 case 0x0028: /* clrmac */
268 case 0x0048: /* clrs */
271 case 0x0008: /* clrt */
274 case 0x0038: /* ldtlb */
275 assert(0); /* XXXXX */
277 case 0x004b: /* rte */
278 CHECK_NOT_DELAY_SLOT gen_op_rte();
279 ctx->flags |= DELAY_SLOT;
280 ctx->delayed_pc = (uint32_t) - 1;
282 case 0x0058: /* sets */
285 case 0x0018: /* sett */
288 case 0xfbfb: /* frchg */
289 assert(0); /* XXXXX */
291 case 0xf3fb: /* fschg */
292 assert(0); /* XXXXX */
294 case 0x0009: /* nop */
296 case 0x001b: /* sleep */
297 assert(0); /* XXXXX */
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);
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));
314 case 0xe000: /* mov.l #imm,Rn */
315 gen_op_movl_imm_rN(B7_0s, REG(B11_8));
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));
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));
327 case 0x7000: /* add.l #imm,Rn */
328 gen_op_add_imm_rN(B7_0s, REG(B11_8));
330 case 0xa000: /* bra disp */
332 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
333 ctx->flags |= DELAY_SLOT;
335 case 0xb000: /* bsr disp */
337 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
338 ctx->pc + 4 + B11_0s * 2);
339 ctx->flags |= DELAY_SLOT;
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));
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);
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);
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);
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));
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));
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));
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);
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);
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);
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));
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));
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));
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);
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);
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);
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));
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));
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));
450 case 0x6008: /* swap.b Rm,Rn */
451 gen_op_movl_rN_T0(REG(B7_4));
453 gen_op_movl_T0_rN(REG(B11_8));
455 case 0x6009: /* swap.w Rm,Rn */
456 gen_op_movl_rN_T0(REG(B7_4));
458 gen_op_movl_T0_rN(REG(B11_8));
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));
466 case 0x300c: /* add Rm,Rn */
467 gen_op_movl_rN_T0(REG(B7_4));
468 gen_op_add_T0_rN(REG(B11_8));
470 case 0x300e: /* addc Rm,Rn */
471 gen_op_movl_rN_T0(REG(B7_4));
472 gen_op_movl_rN_T1(REG(B11_8));
474 gen_op_movl_T1_rN(REG(B11_8));
476 case 0x300f: /* addv Rm,Rn */
477 gen_op_movl_rN_T0(REG(B7_4));
478 gen_op_movl_rN_T1(REG(B11_8));
480 gen_op_movl_T1_rN(REG(B11_8));
482 case 0x2009: /* and Rm,Rn */
483 gen_op_movl_rN_T0(REG(B7_4));
484 gen_op_and_T0_rN(REG(B11_8));
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();
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();
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();
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();
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();
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();
516 case 0x2007: /* div0s Rm,Rn */
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));
523 case 0x3004: /* div1 Rm,Rn */
524 gen_op_movl_rN_T0(REG(B7_4));
525 gen_op_movl_rN_T1(REG(B11_8));
527 gen_op_movl_T1_rN(REG(B11_8));
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();
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();
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));
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));
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));
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));
555 case 0x000f: /* mac.l @Rm+,@Rn- */
556 gen_op_movl_rN_T0(REG(B11_8));
557 gen_op_ldl_T0_T0(ctx);
559 gen_op_movl_rN_T1(REG(B7_4));
560 gen_op_ldl_T0_T0(ctx);
562 gen_op_inc4_rN(REG(B7_4));
563 gen_op_inc4_rN(REG(B11_8));
565 case 0x400f: /* mac.w @Rm+,@Rn+ */
566 gen_op_movl_rN_T0(REG(B11_8));
567 gen_op_ldl_T0_T0(ctx);
569 gen_op_movl_rN_T1(REG(B7_4));
570 gen_op_ldl_T0_T0(ctx);
572 gen_op_inc2_rN(REG(B7_4));
573 gen_op_inc2_rN(REG(B11_8));
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));
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();
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();
590 case 0x600b: /* neg Rm,Rn */
591 gen_op_movl_rN_T0(REG(B7_4));
593 gen_op_movl_T0_rN(REG(B11_8));
595 case 0x600a: /* negc Rm,Rn */
596 gen_op_movl_rN_T0(REG(B7_4));
598 gen_op_movl_T0_rN(REG(B11_8));
600 case 0x6007: /* not Rm,Rn */
601 gen_op_movl_rN_T0(REG(B7_4));
603 gen_op_movl_T0_rN(REG(B11_8));
605 case 0x200b: /* or Rm,Rn */
606 gen_op_movl_rN_T0(REG(B7_4));
607 gen_op_or_T0_rN(REG(B11_8));
609 case 0x400c: /* shad Rm,Rn */
610 gen_op_movl_rN_T0(REG(B7_4));
611 gen_op_movl_rN_T1(REG(B11_8));
613 gen_op_movl_T1_rN(REG(B11_8));
615 case 0x400d: /* shld Rm,Rn */
616 gen_op_movl_rN_T0(REG(B7_4));
617 gen_op_movl_rN_T1(REG(B11_8));
619 gen_op_movl_T1_rN(REG(B11_8));
621 case 0x3008: /* sub Rm,Rn */
622 gen_op_movl_rN_T0(REG(B7_4));
623 gen_op_sub_T0_rN(REG(B11_8));
625 case 0x300a: /* subc Rm,Rn */
626 gen_op_movl_rN_T0(REG(B7_4));
627 gen_op_movl_rN_T1(REG(B11_8));
629 gen_op_movl_T1_rN(REG(B11_8));
631 case 0x300b: /* subv Rm,Rn */
632 gen_op_movl_rN_T0(REG(B7_4));
633 gen_op_movl_rN_T1(REG(B11_8));
635 gen_op_movl_T1_rN(REG(B11_8));
637 case 0x2008: /* tst Rm,Rn */
638 gen_op_movl_rN_T0(REG(B7_4));
639 gen_op_movl_rN_T1(REG(B11_8));
642 case 0x200a: /* xor Rm,Rn */
643 gen_op_movl_rN_T0(REG(B7_4));
644 gen_op_xor_T0_rN(REG(B11_8));
648 switch (ctx->opcode & 0xff00) {
649 case 0xc900: /* and #imm,R0 */
650 gen_op_and_imm_rN(B7_0, REG(0));
652 case 0xcd00: /* and.b #imm,@(R0+GBR) */
653 gen_op_movl_rN_T0(REG(0));
654 gen_op_addl_GBR_T0();
656 gen_op_ldb_T0_T0(ctx);
657 gen_op_and_imm_T0(B7_0);
658 gen_op_stb_T0_T1(ctx);
660 case 0x8b00: /* bf label */
662 gen_conditional_jump(ctx, ctx->pc + 2,
663 ctx->pc + 4 + B7_0s * 2);
664 ctx->flags |= BRANCH_CONDITIONAL;
666 case 0x8f00: /* bf/s label */
668 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
669 ctx->flags |= DELAY_SLOT_CONDITIONAL;
671 case 0x8900: /* bt label */
673 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
675 ctx->flags |= BRANCH_CONDITIONAL;
677 case 0x8d00: /* bt/s label */
679 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
680 ctx->flags |= DELAY_SLOT_CONDITIONAL;
682 case 0x8800: /* cmp/eq #imm,R0 */
683 gen_op_movl_rN_T0(REG(0));
684 gen_op_cmp_eq_imm_T0(B7_0s);
686 case 0xc400: /* mov.b @(disp,GBR),R0 */
688 gen_op_addl_imm_T0(B7_0);
689 gen_op_ldb_T0_T0(ctx);
690 gen_op_movl_T0_rN(REG(0));
692 case 0xc500: /* mov.w @(disp,GBR),R0 */
694 gen_op_addl_imm_T0(B7_0);
695 gen_op_ldw_T0_T0(ctx);
696 gen_op_movl_T0_rN(REG(0));
698 case 0xc600: /* mov.l @(disp,GBR),R0 */
700 gen_op_addl_imm_T0(B7_0);
701 gen_op_ldl_T0_T0(ctx);
702 gen_op_movl_T0_rN(REG(0));
704 case 0xc000: /* mov.b R0,@(disp,GBR) */
706 gen_op_addl_imm_T0(B7_0);
708 gen_op_movl_rN_T0(REG(0));
709 gen_op_stb_T0_T1(ctx);
711 case 0xc100: /* mov.w R0,@(disp,GBR) */
713 gen_op_addl_imm_T0(B7_0);
715 gen_op_movl_rN_T0(REG(0));
716 gen_op_stw_T0_T1(ctx);
718 case 0xc200: /* mov.l R0,@(disp,GBR) */
720 gen_op_addl_imm_T0(B7_0);
722 gen_op_movl_rN_T0(REG(0));
723 gen_op_stl_T0_T1(ctx);
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);
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);
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);
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));
749 case 0xc700: /* mova @(disp,PC),R0 */
750 gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
753 case 0xcb00: /* or #imm,R0 */
754 gen_op_or_imm_rN(B7_0, REG(0));
756 case 0xcf00: /* or.b #imm,@(R0+GBR) */
757 gen_op_movl_rN_T0(REG(0));
758 gen_op_addl_GBR_T0();
760 gen_op_ldb_T0_T0(ctx);
761 gen_op_or_imm_T0(B7_0);
762 gen_op_stb_T0_T1(ctx);
764 case 0xc300: /* trapa #imm */
765 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
767 ctx->flags |= BRANCH;
769 case 0xc800: /* tst #imm,R0 */
770 gen_op_tst_imm_rN(B7_0, REG(0));
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);
778 case 0xca00: /* xor #imm,R0 */
779 gen_op_xor_imm_rN(B7_0, REG(0));
781 case 0xce00: /* xor.b #imm,@(R0+GBR) */
782 gen_op_movl_rN_T0(REG(0));
783 gen_op_addl_GBR_T0();
785 gen_op_ldb_T0_T0(ctx);
786 gen_op_xor_imm_T0(B7_0);
787 gen_op_stb_T0_T1(ctx);
791 switch (ctx->opcode & 0xf08f) {
792 case 0x408e: /* ldc Rm,Rn_BANK */
793 gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
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));
801 case 0x0082: /* stc Rm_BANK,Rn */
802 gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
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);
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;
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;
825 case 0x4015: /* cmp/pl Rn */
826 gen_op_movl_rN_T0(REG(B11_8));
829 case 0x4011: /* cmp/pz Rn */
830 gen_op_movl_rN_T0(REG(B11_8));
833 case 0x4010: /* dt Rn */
834 gen_op_dt_rN(REG(B11_8));
836 case 0x402b: /* jmp @Rn */
837 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
839 ctx->flags |= DELAY_SLOT;
840 ctx->delayed_pc = (uint32_t) - 1;
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;
848 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
850 gen_op_movl_rN_T0 (REG(B11_8)); \
851 gen_op_##ldop##_T0_##reg (); \
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 (); \
862 gen_op_##stop##_##reg##_T0 (); \
863 gen_op_movl_T0_rN (REG(B11_8)); \
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); \
871 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
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);
887 case 0x0029: /* movt Rn */
888 gen_op_movt_rN(REG(B11_8));
890 case 0x0093: /* ocbi @Rn */
891 gen_op_movl_rN_T0(REG(B11_8));
892 gen_op_ldl_T0_T0(ctx);
894 case 0x00a2: /* ocbp @Rn */
895 gen_op_movl_rN_T0(REG(B11_8));
896 gen_op_ldl_T0_T0(ctx);
898 case 0x00b3: /* ocbwb @Rn */
899 gen_op_movl_rN_T0(REG(B11_8));
900 gen_op_ldl_T0_T0(ctx);
902 case 0x0083: /* pref @Rn */
904 case 0x4024: /* rotcl Rn */
905 gen_op_rotcl_Rn(REG(B11_8));
907 case 0x4025: /* rotcr Rn */
908 gen_op_rotcr_Rn(REG(B11_8));
910 case 0x4004: /* rotl Rn */
911 gen_op_rotl_Rn(REG(B11_8));
913 case 0x4005: /* rotr Rn */
914 gen_op_rotr_Rn(REG(B11_8));
916 case 0x4000: /* shll Rn */
917 case 0x4020: /* shal Rn */
918 gen_op_shal_Rn(REG(B11_8));
920 case 0x4021: /* shar Rn */
921 gen_op_shar_Rn(REG(B11_8));
923 case 0x4001: /* shlr Rn */
924 gen_op_shlr_Rn(REG(B11_8));
926 case 0x4008: /* shll2 Rn */
927 gen_op_shll2_Rn(REG(B11_8));
929 case 0x4018: /* shll8 Rn */
930 gen_op_shll8_Rn(REG(B11_8));
932 case 0x4028: /* shll16 Rn */
933 gen_op_shll16_Rn(REG(B11_8));
935 case 0x4009: /* shlr2 Rn */
936 gen_op_shlr2_Rn(REG(B11_8));
938 case 0x4019: /* shlr8 Rn */
939 gen_op_shlr8_Rn(REG(B11_8));
941 case 0x4029: /* shlr16 Rn */
942 gen_op_shlr16_Rn(REG(B11_8));
944 case 0x401b: /* tas.b @Rn */
945 gen_op_tasb_rN(REG(B11_8));
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;
955 int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
959 target_ulong pc_start;
960 static uint16_t *gen_opc_end;
965 gen_opc_ptr = gen_opc_buf;
966 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
967 gen_opparam_ptr = gen_opparam_buf;
969 ctx.flags = env->flags;
972 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
973 ctx.delayed_pc = env->delayed_pc;
975 ctx.singlestep_enabled = env->singlestep_enabled;
979 if (loglevel & CPU_LOG_TB_CPU) {
981 "------------------------------------------------\n");
982 cpu_dump_state(env, logfile, fprintf, 0);
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);
997 ctx.flags |= BRANCH_EXCEPTION;
1003 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1006 ctx.opcode = lduw_code(ctx.pc);
1009 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1011 if (env->singlestep_enabled)
1013 #ifdef SH4_SINGLE_STEP
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);
1024 gen_op_clr_delay_slot();
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);
1035 /* Both cannot be set at the same time */
1039 if (env->singlestep_enabled) {
1042 *gen_opc_ptr = INDEX_op_end;
1043 tb->size = ctx.pc - pc_start;
1046 #ifdef SH4_DEBUG_DISAS
1047 if (loglevel & CPU_LOG_TB_IN_ASM)
1048 fprintf(logfile, "\n");
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");
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");
1064 int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1066 return gen_intermediate_code_internal(env, tb, 0);
1069 int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1072 return gen_intermediate_code_internal(env, tb, 1);