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);