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;
62 int singlestep_enabled;
65 #ifdef CONFIG_USER_ONLY
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(); \
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(); \
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();\
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();\
104 void cpu_dump_state(CPUState * env, FILE * f,
105 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
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]);
116 if (env->flags & DELAY_SLOT) {
117 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
119 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
120 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
125 void cpu_sh4_reset(CPUSH4State * env)
127 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
129 env->pc = 0xA0000000;
130 env->fpscr = 0x00040001;
134 CPUSH4State *cpu_sh4_init(void)
138 env = qemu_mallocz(sizeof(CPUSH4State));
147 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
149 TranslationBlock *tb;
152 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
153 !ctx->singlestep_enabled) {
154 /* Use a direct jump if in same page and singlestep not enabled */
156 gen_op_goto_tb0(TBPARAM(tb));
158 gen_op_goto_tb1(TBPARAM(tb));
159 gen_op_movl_imm_T0((long) tb + n);
161 gen_op_movl_imm_T0(0);
163 gen_op_movl_imm_PC(dest);
164 if (ctx->singlestep_enabled)
169 /* Jump to pc after an exception */
170 static void gen_jump_exception(DisasContext * ctx)
172 gen_op_movl_imm_T0(0);
173 if (ctx->singlestep_enabled)
178 static void gen_jump(DisasContext * ctx)
180 if (ctx->delayed_pc == (uint32_t) - 1) {
181 /* Target is not statically known, it comes necessarily from a
182 delayed jump as immediate jump are conditinal jumps */
183 gen_op_movl_delayed_pc_PC();
184 gen_op_movl_imm_T0(0);
185 if (ctx->singlestep_enabled)
189 gen_goto_tb(ctx, 0, ctx->delayed_pc);
193 /* Immediate conditional jump (bt or bf) */
194 static void gen_conditional_jump(DisasContext * ctx,
195 target_ulong ift, target_ulong ifnott)
199 l1 = gen_new_label();
201 gen_goto_tb(ctx, 0, ifnott);
203 gen_goto_tb(ctx, 1, ift);
206 /* Delayed conditional jump (bt or bf) */
207 static void gen_delayed_conditional_jump(DisasContext * ctx)
211 l1 = gen_new_label();
213 gen_goto_tb(ctx, 0, ctx->pc);
215 gen_goto_tb(ctx, 1, ctx->delayed_pc);
218 #define B3_0 (ctx->opcode & 0xf)
219 #define B6_4 ((ctx->opcode >> 4) & 0x7)
220 #define B7_4 ((ctx->opcode >> 4) & 0xf)
221 #define B7_0 (ctx->opcode & 0xff)
222 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
223 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
224 (ctx->opcode & 0xfff))
225 #define B11_8 ((ctx->opcode >> 8) & 0xf)
226 #define B15_12 ((ctx->opcode >> 12) & 0xf)
228 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
231 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
234 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
235 #define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1)
236 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
238 #define CHECK_NOT_DELAY_SLOT \
239 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
240 {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
243 void decode_opc(DisasContext * ctx)
246 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
248 switch (ctx->opcode) {
249 case 0x0019: /* div0u */
253 case 0x000b: /* rts */
254 CHECK_NOT_DELAY_SLOT gen_op_rts();
255 ctx->flags |= DELAY_SLOT;
256 ctx->delayed_pc = (uint32_t) - 1;
258 case 0x0028: /* clrmac */
261 case 0x0048: /* clrs */
264 case 0x0008: /* clrt */
267 case 0x0038: /* ldtlb */
268 assert(0); /* XXXXX */
270 case 0x004b: /* rte */
271 CHECK_NOT_DELAY_SLOT gen_op_rte();
272 ctx->flags |= DELAY_SLOT;
273 ctx->delayed_pc = (uint32_t) - 1;
275 case 0x0058: /* sets */
278 case 0x0018: /* sett */
281 case 0xfbfb: /* frchg */
283 ctx->flags |= MODE_CHANGE;
285 case 0xf3fb: /* fschg */
287 ctx->flags |= MODE_CHANGE;
289 case 0x0009: /* nop */
291 case 0x001b: /* sleep */
292 assert(0); /* XXXXX */
296 switch (ctx->opcode & 0xf000) {
297 case 0x1000: /* mov.l Rm,@(disp,Rn) */
298 gen_op_movl_rN_T0(REG(B7_4));
299 gen_op_movl_rN_T1(REG(B11_8));
300 gen_op_addl_imm_T1(B3_0 * 4);
301 gen_op_stl_T0_T1(ctx);
303 case 0x5000: /* mov.l @(disp,Rm),Rn */
304 gen_op_movl_rN_T0(REG(B7_4));
305 gen_op_addl_imm_T0(B3_0 * 4);
306 gen_op_ldl_T0_T0(ctx);
307 gen_op_movl_T0_rN(REG(B11_8));
309 case 0xe000: /* mov.l #imm,Rn */
310 gen_op_movl_imm_rN(B7_0s, REG(B11_8));
312 case 0x9000: /* mov.w @(disp,PC),Rn */
313 gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
314 gen_op_ldw_T0_T0(ctx);
315 gen_op_movl_T0_rN(REG(B11_8));
317 case 0xd000: /* mov.l @(disp,PC),Rn */
318 gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
319 gen_op_ldl_T0_T0(ctx);
320 gen_op_movl_T0_rN(REG(B11_8));
322 case 0x7000: /* add.l #imm,Rn */
323 gen_op_add_imm_rN(B7_0s, REG(B11_8));
325 case 0xa000: /* bra disp */
327 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
328 ctx->flags |= DELAY_SLOT;
330 case 0xb000: /* bsr disp */
332 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
333 ctx->pc + 4 + B11_0s * 2);
334 ctx->flags |= DELAY_SLOT;
338 switch (ctx->opcode & 0xf00f) {
339 case 0x6003: /* mov Rm,Rn */
340 gen_op_movl_rN_T0(REG(B7_4));
341 gen_op_movl_T0_rN(REG(B11_8));
343 case 0x2000: /* mov.b Rm,@Rn */
344 gen_op_movl_rN_T0(REG(B7_4));
345 gen_op_movl_rN_T1(REG(B11_8));
346 gen_op_stb_T0_T1(ctx);
348 case 0x2001: /* mov.w Rm,@Rn */
349 gen_op_movl_rN_T0(REG(B7_4));
350 gen_op_movl_rN_T1(REG(B11_8));
351 gen_op_stw_T0_T1(ctx);
353 case 0x2002: /* mov.l Rm,@Rn */
354 gen_op_movl_rN_T0(REG(B7_4));
355 gen_op_movl_rN_T1(REG(B11_8));
356 gen_op_stl_T0_T1(ctx);
358 case 0x6000: /* mov.b @Rm,Rn */
359 gen_op_movl_rN_T0(REG(B7_4));
360 gen_op_ldb_T0_T0(ctx);
361 gen_op_movl_T0_rN(REG(B11_8));
363 case 0x6001: /* mov.w @Rm,Rn */
364 gen_op_movl_rN_T0(REG(B7_4));
365 gen_op_ldw_T0_T0(ctx);
366 gen_op_movl_T0_rN(REG(B11_8));
368 case 0x6002: /* mov.l @Rm,Rn */
369 gen_op_movl_rN_T0(REG(B7_4));
370 gen_op_ldl_T0_T0(ctx);
371 gen_op_movl_T0_rN(REG(B11_8));
373 case 0x2004: /* mov.b Rm,@-Rn */
374 gen_op_dec1_rN(REG(B11_8));
375 gen_op_movl_rN_T0(REG(B7_4));
376 gen_op_movl_rN_T1(REG(B11_8));
377 gen_op_stb_T0_T1(ctx);
379 case 0x2005: /* mov.w Rm,@-Rn */
380 gen_op_dec2_rN(REG(B11_8));
381 gen_op_movl_rN_T0(REG(B7_4));
382 gen_op_movl_rN_T1(REG(B11_8));
383 gen_op_stw_T0_T1(ctx);
385 case 0x2006: /* mov.l Rm,@-Rn */
386 gen_op_dec4_rN(REG(B11_8));
387 gen_op_movl_rN_T0(REG(B7_4));
388 gen_op_movl_rN_T1(REG(B11_8));
389 gen_op_stl_T0_T1(ctx);
391 case 0x6004: /* mov.b @Rm+,Rn */
392 gen_op_movl_rN_T0(REG(B7_4));
393 gen_op_ldb_T0_T0(ctx);
394 gen_op_movl_T0_rN(REG(B11_8));
395 gen_op_inc1_rN(REG(B7_4));
397 case 0x6005: /* mov.w @Rm+,Rn */
398 gen_op_movl_rN_T0(REG(B7_4));
399 gen_op_ldw_T0_T0(ctx);
400 gen_op_movl_T0_rN(REG(B11_8));
401 gen_op_inc2_rN(REG(B7_4));
403 case 0x6006: /* mov.l @Rm+,Rn */
404 gen_op_movl_rN_T0(REG(B7_4));
405 gen_op_ldl_T0_T0(ctx);
406 gen_op_movl_T0_rN(REG(B11_8));
407 gen_op_inc4_rN(REG(B7_4));
409 case 0x0004: /* mov.b Rm,@(R0,Rn) */
410 gen_op_movl_rN_T0(REG(B7_4));
411 gen_op_movl_rN_T1(REG(B11_8));
412 gen_op_add_rN_T1(REG(0));
413 gen_op_stb_T0_T1(ctx);
415 case 0x0005: /* mov.w Rm,@(R0,Rn) */
416 gen_op_movl_rN_T0(REG(B7_4));
417 gen_op_movl_rN_T1(REG(B11_8));
418 gen_op_add_rN_T1(REG(0));
419 gen_op_stw_T0_T1(ctx);
421 case 0x0006: /* mov.l Rm,@(R0,Rn) */
422 gen_op_movl_rN_T0(REG(B7_4));
423 gen_op_movl_rN_T1(REG(B11_8));
424 gen_op_add_rN_T1(REG(0));
425 gen_op_stl_T0_T1(ctx);
427 case 0x000c: /* mov.b @(R0,Rm),Rn */
428 gen_op_movl_rN_T0(REG(B7_4));
429 gen_op_add_rN_T0(REG(0));
430 gen_op_ldb_T0_T0(ctx);
431 gen_op_movl_T0_rN(REG(B11_8));
433 case 0x000d: /* mov.w @(R0,Rm),Rn */
434 gen_op_movl_rN_T0(REG(B7_4));
435 gen_op_add_rN_T0(REG(0));
436 gen_op_ldw_T0_T0(ctx);
437 gen_op_movl_T0_rN(REG(B11_8));
439 case 0x000e: /* mov.l @(R0,Rm),Rn */
440 gen_op_movl_rN_T0(REG(B7_4));
441 gen_op_add_rN_T0(REG(0));
442 gen_op_ldl_T0_T0(ctx);
443 gen_op_movl_T0_rN(REG(B11_8));
445 case 0x6008: /* swap.b Rm,Rn */
446 gen_op_movl_rN_T0(REG(B7_4));
448 gen_op_movl_T0_rN(REG(B11_8));
450 case 0x6009: /* swap.w Rm,Rn */
451 gen_op_movl_rN_T0(REG(B7_4));
453 gen_op_movl_T0_rN(REG(B11_8));
455 case 0x200d: /* xtrct Rm,Rn */
456 gen_op_movl_rN_T0(REG(B7_4));
457 gen_op_movl_rN_T1(REG(B11_8));
458 gen_op_xtrct_T0_T1();
459 gen_op_movl_T1_rN(REG(B11_8));
461 case 0x300c: /* add Rm,Rn */
462 gen_op_movl_rN_T0(REG(B7_4));
463 gen_op_add_T0_rN(REG(B11_8));
465 case 0x300e: /* addc Rm,Rn */
466 gen_op_movl_rN_T0(REG(B7_4));
467 gen_op_movl_rN_T1(REG(B11_8));
469 gen_op_movl_T1_rN(REG(B11_8));
471 case 0x300f: /* addv Rm,Rn */
472 gen_op_movl_rN_T0(REG(B7_4));
473 gen_op_movl_rN_T1(REG(B11_8));
475 gen_op_movl_T1_rN(REG(B11_8));
477 case 0x2009: /* and Rm,Rn */
478 gen_op_movl_rN_T0(REG(B7_4));
479 gen_op_and_T0_rN(REG(B11_8));
481 case 0x3000: /* cmp/eq Rm,Rn */
482 gen_op_movl_rN_T0(REG(B7_4));
483 gen_op_movl_rN_T1(REG(B11_8));
484 gen_op_cmp_eq_T0_T1();
486 case 0x3003: /* cmp/ge Rm,Rn */
487 gen_op_movl_rN_T0(REG(B7_4));
488 gen_op_movl_rN_T1(REG(B11_8));
489 gen_op_cmp_ge_T0_T1();
491 case 0x3007: /* cmp/gt Rm,Rn */
492 gen_op_movl_rN_T0(REG(B7_4));
493 gen_op_movl_rN_T1(REG(B11_8));
494 gen_op_cmp_gt_T0_T1();
496 case 0x3006: /* cmp/hi Rm,Rn */
497 gen_op_movl_rN_T0(REG(B7_4));
498 gen_op_movl_rN_T1(REG(B11_8));
499 gen_op_cmp_hi_T0_T1();
501 case 0x3002: /* cmp/hs Rm,Rn */
502 gen_op_movl_rN_T0(REG(B7_4));
503 gen_op_movl_rN_T1(REG(B11_8));
504 gen_op_cmp_hs_T0_T1();
506 case 0x200c: /* cmp/str Rm,Rn */
507 gen_op_movl_rN_T0(REG(B7_4));
508 gen_op_movl_rN_T1(REG(B11_8));
509 gen_op_cmp_str_T0_T1();
511 case 0x2007: /* div0s Rm,Rn */
513 gen_op_movl_rN_T0(REG(B7_4));
514 gen_op_movl_rN_T1(REG(B11_8));
515 gen_op_div0s_T0_T1();
516 gen_op_movl_T1_rN(REG(B11_8));
518 case 0x3004: /* div1 Rm,Rn */
519 gen_op_movl_rN_T0(REG(B7_4));
520 gen_op_movl_rN_T1(REG(B11_8));
522 gen_op_movl_T1_rN(REG(B11_8));
524 case 0x300d: /* dmuls.l Rm,Rn */
525 gen_op_movl_rN_T0(REG(B7_4));
526 gen_op_movl_rN_T1(REG(B11_8));
527 gen_op_dmulsl_T0_T1();
529 case 0x3005: /* dmulu.l Rm,Rn */
530 gen_op_movl_rN_T0(REG(B7_4));
531 gen_op_movl_rN_T1(REG(B11_8));
532 gen_op_dmulul_T0_T1();
534 case 0x600e: /* exts.b Rm,Rn */
535 gen_op_movb_rN_T0(REG(B7_4));
536 gen_op_movl_T0_rN(REG(B11_8));
538 case 0x600f: /* exts.w Rm,Rn */
539 gen_op_movw_rN_T0(REG(B7_4));
540 gen_op_movl_T0_rN(REG(B11_8));
542 case 0x600c: /* extu.b Rm,Rn */
543 gen_op_movub_rN_T0(REG(B7_4));
544 gen_op_movl_T0_rN(REG(B11_8));
546 case 0x600d: /* extu.w Rm,Rn */
547 gen_op_movuw_rN_T0(REG(B7_4));
548 gen_op_movl_T0_rN(REG(B11_8));
550 case 0x000f: /* mac.l @Rm+,@Rn- */
551 gen_op_movl_rN_T0(REG(B11_8));
552 gen_op_ldl_T0_T0(ctx);
554 gen_op_movl_rN_T1(REG(B7_4));
555 gen_op_ldl_T0_T0(ctx);
557 gen_op_inc4_rN(REG(B7_4));
558 gen_op_inc4_rN(REG(B11_8));
560 case 0x400f: /* mac.w @Rm+,@Rn+ */
561 gen_op_movl_rN_T0(REG(B11_8));
562 gen_op_ldl_T0_T0(ctx);
564 gen_op_movl_rN_T1(REG(B7_4));
565 gen_op_ldl_T0_T0(ctx);
567 gen_op_inc2_rN(REG(B7_4));
568 gen_op_inc2_rN(REG(B11_8));
570 case 0x0007: /* mul.l Rm,Rn */
571 gen_op_movl_rN_T0(REG(B7_4));
572 gen_op_movl_rN_T1(REG(B11_8));
575 case 0x200f: /* muls.w Rm,Rn */
576 gen_op_movw_rN_T0(REG(B7_4));
577 gen_op_movw_rN_T1(REG(B11_8));
578 gen_op_mulsw_T0_T1();
580 case 0x200e: /* mulu.w Rm,Rn */
581 gen_op_movuw_rN_T0(REG(B7_4));
582 gen_op_movuw_rN_T1(REG(B11_8));
583 gen_op_muluw_T0_T1();
585 case 0x600b: /* neg Rm,Rn */
586 gen_op_movl_rN_T0(REG(B7_4));
588 gen_op_movl_T0_rN(REG(B11_8));
590 case 0x600a: /* negc Rm,Rn */
591 gen_op_movl_rN_T0(REG(B7_4));
593 gen_op_movl_T0_rN(REG(B11_8));
595 case 0x6007: /* not Rm,Rn */
596 gen_op_movl_rN_T0(REG(B7_4));
598 gen_op_movl_T0_rN(REG(B11_8));
600 case 0x200b: /* or Rm,Rn */
601 gen_op_movl_rN_T0(REG(B7_4));
602 gen_op_or_T0_rN(REG(B11_8));
604 case 0x400c: /* shad Rm,Rn */
605 gen_op_movl_rN_T0(REG(B7_4));
606 gen_op_movl_rN_T1(REG(B11_8));
608 gen_op_movl_T1_rN(REG(B11_8));
610 case 0x400d: /* shld Rm,Rn */
611 gen_op_movl_rN_T0(REG(B7_4));
612 gen_op_movl_rN_T1(REG(B11_8));
614 gen_op_movl_T1_rN(REG(B11_8));
616 case 0x3008: /* sub Rm,Rn */
617 gen_op_movl_rN_T0(REG(B7_4));
618 gen_op_sub_T0_rN(REG(B11_8));
620 case 0x300a: /* subc Rm,Rn */
621 gen_op_movl_rN_T0(REG(B7_4));
622 gen_op_movl_rN_T1(REG(B11_8));
624 gen_op_movl_T1_rN(REG(B11_8));
626 case 0x300b: /* subv Rm,Rn */
627 gen_op_movl_rN_T0(REG(B7_4));
628 gen_op_movl_rN_T1(REG(B11_8));
630 gen_op_movl_T1_rN(REG(B11_8));
632 case 0x2008: /* tst Rm,Rn */
633 gen_op_movl_rN_T0(REG(B7_4));
634 gen_op_movl_rN_T1(REG(B11_8));
637 case 0x200a: /* xor Rm,Rn */
638 gen_op_movl_rN_T0(REG(B7_4));
639 gen_op_xor_T0_rN(REG(B11_8));
641 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn */
642 if (ctx->fpscr & FPSCR_PR) {
643 gen_op_fmov_drN_DT0(XREG(B7_4));
644 gen_op_fmov_DT0_drN(XREG(B11_8));
645 } else if (ctx->fpscr & FPSCR_SZ) {
646 if (ctx->opcode & 0x0110)
647 break; /* illegal instruction */
648 gen_op_fmov_drN_DT0(XREG(B7_4));
649 gen_op_fmov_DT0_drN(XREG(B11_8));
651 gen_op_fmov_frN_FT0(FREG(B7_4));
652 gen_op_fmov_FT0_frN(FREG(B11_8));
655 case 0xf00a: /* fmov {F,D,X}Rm,@Rn */
656 if (ctx->fpscr & FPSCR_PR) {
657 gen_op_fmov_drN_DT0(XREG(B7_4));
658 gen_op_movl_rN_T1(REG(B11_8));
659 gen_op_stfq_DT0_T1(ctx);
660 } else if (ctx->fpscr & FPSCR_SZ) {
661 if (ctx->opcode & 0x0010)
662 break; /* illegal instruction */
663 gen_op_fmov_drN_DT0(XREG(B7_4));
664 gen_op_movl_rN_T1(REG(B11_8));
665 gen_op_stfq_DT0_T1(ctx);
667 gen_op_fmov_frN_FT0(FREG(B7_4));
668 gen_op_movl_rN_T1(REG(B11_8));
669 gen_op_stfl_FT0_T1(ctx);
672 case 0xf008: /* fmov @Rm,{F,D,X}Rn */
673 if (ctx->fpscr & FPSCR_PR) {
674 gen_op_movl_rN_T0(REG(B7_4));
675 gen_op_ldfq_T0_DT0(ctx);
676 gen_op_fmov_DT0_drN(XREG(B11_8));
677 } else if (ctx->fpscr & FPSCR_SZ) {
678 if (ctx->opcode & 0x0100)
679 break; /* illegal instruction */
680 gen_op_movl_rN_T0(REG(B7_4));
681 gen_op_ldfq_T0_DT0(ctx);
682 gen_op_fmov_DT0_drN(XREG(B11_8));
684 gen_op_movl_rN_T0(REG(B7_4));
685 gen_op_ldfl_T0_FT0(ctx);
686 gen_op_fmov_FT0_frN(XREG(B11_8));
689 case 0xf009: /* fmov @Rm+,{F,D,X}Rn */
690 if (ctx->fpscr & FPSCR_PR) {
691 gen_op_movl_rN_T0(REG(B7_4));
692 gen_op_ldfq_T0_DT0(ctx);
693 gen_op_fmov_DT0_drN(XREG(B11_8));
694 gen_op_inc8_rN(REG(B7_4));
695 } else if (ctx->fpscr & FPSCR_SZ) {
696 if (ctx->opcode & 0x0100)
697 break; /* illegal instruction */
698 gen_op_movl_rN_T0(REG(B7_4));
699 gen_op_ldfq_T0_DT0(ctx);
700 gen_op_fmov_DT0_drN(XREG(B11_8));
701 gen_op_inc8_rN(REG(B7_4));
703 gen_op_movl_rN_T0(REG(B7_4));
704 gen_op_ldfl_T0_FT0(ctx);
705 gen_op_fmov_FT0_frN(XREG(B11_8));
706 gen_op_inc4_rN(REG(B7_4));
709 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn */
710 if (ctx->fpscr & FPSCR_PR) {
711 gen_op_dec8_rN(REG(B11_8));
712 gen_op_fmov_drN_DT0(XREG(B7_4));
713 gen_op_movl_rN_T1(REG(B11_8));
714 gen_op_stfq_DT0_T1(ctx);
715 } else if (ctx->fpscr & FPSCR_SZ) {
716 if (ctx->opcode & 0x0100)
717 break; /* illegal instruction */
718 gen_op_dec8_rN(REG(B11_8));
719 gen_op_fmov_drN_DT0(XREG(B7_4));
720 gen_op_movl_rN_T1(REG(B11_8));
721 gen_op_stfq_DT0_T1(ctx);
723 gen_op_dec4_rN(REG(B11_8));
724 gen_op_fmov_frN_FT0(FREG(B7_4));
725 gen_op_movl_rN_T1(REG(B11_8));
726 gen_op_stfl_FT0_T1(ctx);
729 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */
730 if (ctx->fpscr & FPSCR_PR) {
731 gen_op_movl_rN_T0(REG(B7_4));
732 gen_op_add_rN_T0(REG(0));
733 gen_op_ldfq_T0_DT0(ctx);
734 gen_op_fmov_DT0_drN(XREG(B11_8));
735 } else if (ctx->fpscr & FPSCR_SZ) {
736 if (ctx->opcode & 0x0100)
737 break; /* illegal instruction */
738 gen_op_movl_rN_T0(REG(B7_4));
739 gen_op_add_rN_T0(REG(0));
740 gen_op_ldfq_T0_DT0(ctx);
741 gen_op_fmov_DT0_drN(XREG(B11_8));
743 gen_op_movl_rN_T0(REG(B7_4));
744 gen_op_add_rN_T0(REG(0));
745 gen_op_ldfl_T0_FT0(ctx);
746 gen_op_fmov_FT0_frN(XREG(B11_8));
749 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */
750 if (ctx->fpscr & FPSCR_PR) {
751 gen_op_fmov_drN_DT0(XREG(B7_4));
752 gen_op_movl_rN_T1(REG(B11_8));
753 gen_op_add_rN_T1(REG(0));
754 gen_op_stfq_DT0_T1(ctx);
755 } else if (ctx->fpscr & FPSCR_SZ) {
756 if (ctx->opcode & 0x0010)
757 break; /* illegal instruction */
758 gen_op_fmov_drN_DT0(XREG(B7_4));
759 gen_op_movl_rN_T1(REG(B11_8));
760 gen_op_add_rN_T1(REG(0));
761 gen_op_stfq_DT0_T1(ctx);
763 gen_op_fmov_frN_FT0(FREG(B7_4));
764 gen_op_movl_rN_T1(REG(B11_8));
765 gen_op_add_rN_T1(REG(0));
766 gen_op_stfl_FT0_T1(ctx);
771 switch (ctx->opcode & 0xff00) {
772 case 0xc900: /* and #imm,R0 */
773 gen_op_and_imm_rN(B7_0, REG(0));
775 case 0xcd00: /* and.b #imm,@(R0+GBR) */
776 gen_op_movl_rN_T0(REG(0));
777 gen_op_addl_GBR_T0();
779 gen_op_ldb_T0_T0(ctx);
780 gen_op_and_imm_T0(B7_0);
781 gen_op_stb_T0_T1(ctx);
783 case 0x8b00: /* bf label */
785 gen_conditional_jump(ctx, ctx->pc + 2,
786 ctx->pc + 4 + B7_0s * 2);
787 ctx->flags |= BRANCH_CONDITIONAL;
789 case 0x8f00: /* bf/s label */
791 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
792 ctx->flags |= DELAY_SLOT_CONDITIONAL;
794 case 0x8900: /* bt label */
796 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
798 ctx->flags |= BRANCH_CONDITIONAL;
800 case 0x8d00: /* bt/s label */
802 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
803 ctx->flags |= DELAY_SLOT_CONDITIONAL;
805 case 0x8800: /* cmp/eq #imm,R0 */
806 gen_op_movl_rN_T0(REG(0));
807 gen_op_cmp_eq_imm_T0(B7_0s);
809 case 0xc400: /* mov.b @(disp,GBR),R0 */
811 gen_op_addl_imm_T0(B7_0);
812 gen_op_ldb_T0_T0(ctx);
813 gen_op_movl_T0_rN(REG(0));
815 case 0xc500: /* mov.w @(disp,GBR),R0 */
817 gen_op_addl_imm_T0(B7_0);
818 gen_op_ldw_T0_T0(ctx);
819 gen_op_movl_T0_rN(REG(0));
821 case 0xc600: /* mov.l @(disp,GBR),R0 */
823 gen_op_addl_imm_T0(B7_0);
824 gen_op_ldl_T0_T0(ctx);
825 gen_op_movl_T0_rN(REG(0));
827 case 0xc000: /* mov.b R0,@(disp,GBR) */
829 gen_op_addl_imm_T0(B7_0);
831 gen_op_movl_rN_T0(REG(0));
832 gen_op_stb_T0_T1(ctx);
834 case 0xc100: /* mov.w R0,@(disp,GBR) */
836 gen_op_addl_imm_T0(B7_0);
838 gen_op_movl_rN_T0(REG(0));
839 gen_op_stw_T0_T1(ctx);
841 case 0xc200: /* mov.l R0,@(disp,GBR) */
843 gen_op_addl_imm_T0(B7_0);
845 gen_op_movl_rN_T0(REG(0));
846 gen_op_stl_T0_T1(ctx);
848 case 0x8000: /* mov.b R0,@(disp,Rn) */
849 gen_op_movl_rN_T0(REG(0));
850 gen_op_movl_rN_T1(REG(B7_4));
851 gen_op_addl_imm_T1(B3_0);
852 gen_op_stb_T0_T1(ctx);
854 case 0x8100: /* mov.w R0,@(disp,Rn) */
855 gen_op_movl_rN_T0(REG(0));
856 gen_op_movl_rN_T1(REG(B7_4));
857 gen_op_addl_imm_T1(B3_0 * 2);
858 gen_op_stw_T0_T1(ctx);
860 case 0x8400: /* mov.b @(disp,Rn),R0 */
861 gen_op_movl_rN_T0(REG(0));
862 gen_op_movl_rN_T1(REG(B7_4));
863 gen_op_addl_imm_T1(B3_0);
864 gen_op_stb_T0_T1(ctx);
866 case 0x8500: /* mov.w @(disp,Rn),R0 */
867 gen_op_movl_rN_T0(REG(B7_4));
868 gen_op_addl_imm_T0(B3_0 * 2);
869 gen_op_ldw_T0_T0(ctx);
870 gen_op_movl_T0_rN(REG(0));
872 case 0xc700: /* mova @(disp,PC),R0 */
873 gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
876 case 0xcb00: /* or #imm,R0 */
877 gen_op_or_imm_rN(B7_0, REG(0));
879 case 0xcf00: /* or.b #imm,@(R0+GBR) */
880 gen_op_movl_rN_T0(REG(0));
881 gen_op_addl_GBR_T0();
883 gen_op_ldb_T0_T0(ctx);
884 gen_op_or_imm_T0(B7_0);
885 gen_op_stb_T0_T1(ctx);
887 case 0xc300: /* trapa #imm */
888 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
890 ctx->flags |= BRANCH;
892 case 0xc800: /* tst #imm,R0 */
893 gen_op_tst_imm_rN(B7_0, REG(0));
895 case 0xcc00: /* tst #imm,@(R0+GBR) */
896 gen_op_movl_rN_T0(REG(0));
897 gen_op_addl_GBR_T0();
898 gen_op_ldb_T0_T0(ctx);
899 gen_op_tst_imm_T0(B7_0);
901 case 0xca00: /* xor #imm,R0 */
902 gen_op_xor_imm_rN(B7_0, REG(0));
904 case 0xce00: /* xor.b #imm,@(R0+GBR) */
905 gen_op_movl_rN_T0(REG(0));
906 gen_op_addl_GBR_T0();
908 gen_op_ldb_T0_T0(ctx);
909 gen_op_xor_imm_T0(B7_0);
910 gen_op_stb_T0_T1(ctx);
914 switch (ctx->opcode & 0xf08f) {
915 case 0x408e: /* ldc Rm,Rn_BANK */
916 gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
918 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
919 gen_op_movl_rN_T0(REG(B11_8));
920 gen_op_ldl_T0_T0(ctx);
921 gen_op_movl_T0_rN(ALTREG(B6_4));
922 gen_op_inc4_rN(REG(B11_8));
924 case 0x0082: /* stc Rm_BANK,Rn */
925 gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
927 case 0x4083: /* stc.l Rm_BANK,@-Rn */
928 gen_op_dec4_rN(REG(B11_8));
929 gen_op_movl_rN_T1(REG(B11_8));
930 gen_op_movl_rN_T0(ALTREG(B6_4));
931 gen_op_stl_T0_T1(ctx);
935 switch (ctx->opcode & 0xf0ff) {
936 case 0x0023: /* braf Rn */
937 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
938 gen_op_braf_T0(ctx->pc + 4);
939 ctx->flags |= DELAY_SLOT;
940 ctx->delayed_pc = (uint32_t) - 1;
942 case 0x0003: /* bsrf Rn */
943 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
944 gen_op_bsrf_T0(ctx->pc + 4);
945 ctx->flags |= DELAY_SLOT;
946 ctx->delayed_pc = (uint32_t) - 1;
948 case 0x4015: /* cmp/pl Rn */
949 gen_op_movl_rN_T0(REG(B11_8));
952 case 0x4011: /* cmp/pz Rn */
953 gen_op_movl_rN_T0(REG(B11_8));
956 case 0x4010: /* dt Rn */
957 gen_op_dt_rN(REG(B11_8));
959 case 0x402b: /* jmp @Rn */
960 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
962 ctx->flags |= DELAY_SLOT;
963 ctx->delayed_pc = (uint32_t) - 1;
965 case 0x400b: /* jsr @Rn */
966 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
967 gen_op_jsr_T0(ctx->pc + 4);
968 ctx->flags |= DELAY_SLOT;
969 ctx->delayed_pc = (uint32_t) - 1;
971 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
973 gen_op_movl_rN_T0 (REG(B11_8)); \
974 gen_op_##ldop##_T0_##reg (); \
978 gen_op_movl_rN_T0 (REG(B11_8)); \
979 gen_op_ldl_T0_T0 (ctx); \
980 gen_op_inc4_rN (REG(B11_8)); \
981 gen_op_##ldop##_T0_##reg (); \
985 gen_op_##stop##_##reg##_T0 (); \
986 gen_op_movl_T0_rN (REG(B11_8)); \
989 gen_op_##stop##_##reg##_T0 (); \
990 gen_op_dec4_rN (REG(B11_8)); \
991 gen_op_movl_rN_T1 (REG(B11_8)); \
992 gen_op_stl_T0_T1 (ctx); \
994 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
996 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
997 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
998 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
999 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1000 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1001 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1002 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1003 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1004 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,)
1005 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |=
1007 case 0x00c3: /* movca.l R0,@Rm */
1008 gen_op_movl_rN_T0(REG(0));
1009 gen_op_movl_rN_T1(REG(B11_8));
1010 gen_op_stl_T0_T1(ctx);
1012 case 0x0029: /* movt Rn */
1013 gen_op_movt_rN(REG(B11_8));
1015 case 0x0093: /* ocbi @Rn */
1016 gen_op_movl_rN_T0(REG(B11_8));
1017 gen_op_ldl_T0_T0(ctx);
1019 case 0x00a2: /* ocbp @Rn */
1020 gen_op_movl_rN_T0(REG(B11_8));
1021 gen_op_ldl_T0_T0(ctx);
1023 case 0x00b3: /* ocbwb @Rn */
1024 gen_op_movl_rN_T0(REG(B11_8));
1025 gen_op_ldl_T0_T0(ctx);
1027 case 0x0083: /* pref @Rn */
1029 case 0x4024: /* rotcl Rn */
1030 gen_op_rotcl_Rn(REG(B11_8));
1032 case 0x4025: /* rotcr Rn */
1033 gen_op_rotcr_Rn(REG(B11_8));
1035 case 0x4004: /* rotl Rn */
1036 gen_op_rotl_Rn(REG(B11_8));
1038 case 0x4005: /* rotr Rn */
1039 gen_op_rotr_Rn(REG(B11_8));
1041 case 0x4000: /* shll Rn */
1042 case 0x4020: /* shal Rn */
1043 gen_op_shal_Rn(REG(B11_8));
1045 case 0x4021: /* shar Rn */
1046 gen_op_shar_Rn(REG(B11_8));
1048 case 0x4001: /* shlr Rn */
1049 gen_op_shlr_Rn(REG(B11_8));
1051 case 0x4008: /* shll2 Rn */
1052 gen_op_shll2_Rn(REG(B11_8));
1054 case 0x4018: /* shll8 Rn */
1055 gen_op_shll8_Rn(REG(B11_8));
1057 case 0x4028: /* shll16 Rn */
1058 gen_op_shll16_Rn(REG(B11_8));
1060 case 0x4009: /* shlr2 Rn */
1061 gen_op_shlr2_Rn(REG(B11_8));
1063 case 0x4019: /* shlr8 Rn */
1064 gen_op_shlr8_Rn(REG(B11_8));
1066 case 0x4029: /* shlr16 Rn */
1067 gen_op_shlr16_Rn(REG(B11_8));
1069 case 0x401b: /* tas.b @Rn */
1070 gen_op_tasb_rN(REG(B11_8));
1072 case 0xf00d: /* fsts FPUL,FRn */
1073 gen_op_movl_fpul_FT0();
1074 gen_op_fmov_FT0_frN(FREG(B11_8));
1076 case 0xf01d: /* flds FRm.FPUL */
1077 gen_op_fmov_frN_FT0(FREG(B11_8));
1078 gen_op_movl_FT0_fpul();
1082 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1083 ctx->opcode, ctx->pc);
1084 gen_op_raise_illegal_instruction();
1085 ctx->flags |= BRANCH_EXCEPTION;
1088 int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1092 target_ulong pc_start;
1093 static uint16_t *gen_opc_end;
1098 gen_opc_ptr = gen_opc_buf;
1099 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1100 gen_opparam_ptr = gen_opparam_buf;
1102 ctx.flags = env->flags;
1105 ctx.fpscr = env->fpscr;
1106 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1107 /* We don't know if the delayed pc came from a dynamic or static branch,
1108 so assume it is a dynamic branch. */
1109 ctx.delayed_pc = -1;
1111 ctx.singlestep_enabled = env->singlestep_enabled;
1115 if (loglevel & CPU_LOG_TB_CPU) {
1117 "------------------------------------------------\n");
1118 cpu_dump_state(env, logfile, fprintf, 0);
1123 while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1124 (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1125 BRANCH_EXCEPTION)) == 0 &&
1126 gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1127 old_flags = ctx.flags;
1128 if (env->nb_breakpoints > 0) {
1129 for (i = 0; i < env->nb_breakpoints; i++) {
1130 if (ctx.pc == env->breakpoints[i]) {
1131 /* We have hit a breakpoint - make sure PC is up-to-date */
1132 gen_op_movl_imm_PC(ctx.pc);
1134 ctx.flags |= BRANCH_EXCEPTION;
1140 i = gen_opc_ptr - gen_opc_buf;
1144 gen_opc_instr_start[ii++] = 0;
1146 gen_opc_pc[ii] = ctx.pc;
1147 gen_opc_instr_start[ii] = 1;
1150 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1153 ctx.opcode = lduw_code(ctx.pc);
1156 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1158 if (env->singlestep_enabled)
1160 #ifdef SH4_SINGLE_STEP
1165 switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) {
1166 case DELAY_SLOT_CONDITIONAL:
1167 gen_op_clr_delay_slot_conditional();
1168 gen_delayed_conditional_jump(&ctx);
1171 gen_op_clr_delay_slot();
1175 if (ctx.flags & BRANCH_EXCEPTION) {
1176 gen_jump_exception(&ctx);
1177 } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1178 gen_goto_tb(&ctx, 0, ctx.pc);
1182 /* Both cannot be set at the same time */
1186 if (env->singlestep_enabled) {
1189 *gen_opc_ptr = INDEX_op_end;
1191 i = gen_opc_ptr - gen_opc_buf;
1194 gen_opc_instr_start[ii++] = 0;
1197 tb->size = ctx.pc - pc_start;
1201 #ifdef SH4_DEBUG_DISAS
1202 if (loglevel & CPU_LOG_TB_IN_ASM)
1203 fprintf(logfile, "\n");
1205 if (loglevel & CPU_LOG_TB_IN_ASM) {
1206 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1207 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1208 fprintf(logfile, "\n");
1210 if (loglevel & CPU_LOG_TB_OP) {
1211 fprintf(logfile, "OP:\n");
1212 dump_ops(gen_opc_buf, gen_opparam_buf);
1213 fprintf(logfile, "\n");
1219 int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1221 return gen_intermediate_code_internal(env, tb, 0);
1224 int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1226 return gen_intermediate_code_internal(env, tb, 1);