Revision 9b9e4393 target-mips/translate.c
b/target-mips/translate.c | ||
---|---|---|
569 | 569 |
} \ |
570 | 570 |
} while (0) |
571 | 571 |
|
572 |
#ifdef TARGET_MIPS64 |
|
573 |
#define GEN_LOAD_IMM_TN(Tn, Imm) \ |
|
574 |
do { \ |
|
575 |
if (Imm == 0) { \ |
|
576 |
glue(gen_op_reset_, Tn)(); \ |
|
577 |
} else if ((int32_t)Imm == Imm) { \ |
|
578 |
glue(gen_op_set_, Tn)(Imm); \ |
|
579 |
} else { \ |
|
580 |
glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm); \ |
|
581 |
} \ |
|
582 |
} while (0) |
|
583 |
#else |
|
572 | 584 |
#define GEN_LOAD_IMM_TN(Tn, Imm) \ |
573 | 585 |
do { \ |
574 | 586 |
if (Imm == 0) { \ |
... | ... | |
577 | 589 |
glue(gen_op_set_, Tn)(Imm); \ |
578 | 590 |
} \ |
579 | 591 |
} while (0) |
592 |
#endif |
|
580 | 593 |
|
581 | 594 |
#define GEN_STORE_TN_REG(Rn, Tn) \ |
582 | 595 |
do { \ |
... | ... | |
595 | 608 |
glue(gen_op_store_fpr_, FTn)(Fn); \ |
596 | 609 |
} while (0) |
597 | 610 |
|
611 |
static inline void gen_save_pc(target_ulong pc) |
|
612 |
{ |
|
613 |
#ifdef TARGET_MIPS64 |
|
614 |
if (pc == (int32_t)pc) { |
|
615 |
gen_op_save_pc(pc); |
|
616 |
} else { |
|
617 |
gen_op_save_pc64(pc >> 32, (uint32_t)pc); |
|
618 |
} |
|
619 |
#else |
|
620 |
gen_op_save_pc(pc); |
|
621 |
#endif |
|
622 |
} |
|
623 |
|
|
624 |
static inline void gen_save_btarget(target_ulong btarget) |
|
625 |
{ |
|
626 |
#ifdef TARGET_MIPS64 |
|
627 |
if (btarget == (int32_t)btarget) { |
|
628 |
gen_op_save_btarget(btarget); |
|
629 |
} else { |
|
630 |
gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget); |
|
631 |
} |
|
632 |
#else |
|
633 |
gen_op_save_btarget(btarget); |
|
634 |
#endif |
|
635 |
} |
|
636 |
|
|
598 | 637 |
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) |
599 | 638 |
{ |
600 | 639 |
#if defined MIPS_DEBUG_DISAS |
... | ... | |
604 | 643 |
} |
605 | 644 |
#endif |
606 | 645 |
if (do_save_pc && ctx->pc != ctx->saved_pc) { |
607 |
gen_op_save_pc(ctx->pc);
|
|
646 |
gen_save_pc(ctx->pc); |
|
608 | 647 |
ctx->saved_pc = ctx->pc; |
609 | 648 |
} |
610 | 649 |
if (ctx->hflags != ctx->saved_hflags) { |
... | ... | |
621 | 660 |
/* bcond was already saved by the BL insn */ |
622 | 661 |
/* fall through */ |
623 | 662 |
case MIPS_HFLAG_B: |
624 |
gen_op_save_btarget(ctx->btarget);
|
|
663 |
gen_save_btarget(ctx->btarget); |
|
625 | 664 |
break; |
626 | 665 |
} |
627 | 666 |
} |
... | ... | |
946 | 985 |
GEN_LOAD_IMM_TN(T1, uimm); |
947 | 986 |
break; |
948 | 987 |
case OPC_LUI: |
949 |
GEN_LOAD_IMM_TN(T0, uimm << 16);
|
|
988 |
GEN_LOAD_IMM_TN(T0, imm << 16); |
|
950 | 989 |
break; |
951 | 990 |
case OPC_SLL: |
952 | 991 |
case OPC_SRA: |
... | ... | |
1491 | 1530 |
gen_op_goto_tb0(TBPARAM(tb)); |
1492 | 1531 |
else |
1493 | 1532 |
gen_op_goto_tb1(TBPARAM(tb)); |
1494 |
gen_op_save_pc(dest);
|
|
1533 |
gen_save_pc(dest); |
|
1495 | 1534 |
gen_op_set_T0((long)tb + n); |
1496 | 1535 |
} else { |
1497 |
gen_op_save_pc(dest);
|
|
1536 |
gen_save_pc(dest); |
|
1498 | 1537 |
gen_op_reset_T0(); |
1499 | 1538 |
} |
1500 | 1539 |
gen_op_exit_tb(); |
... | ... | |
1556 | 1595 |
case OPC_J: |
1557 | 1596 |
case OPC_JAL: |
1558 | 1597 |
/* Jump to immediate */ |
1559 |
btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset; |
|
1598 |
btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
|
|
1560 | 1599 |
break; |
1561 | 1600 |
case OPC_JR: |
1562 | 1601 |
case OPC_JALR: |
... | ... | |
1602 | 1641 |
MIPS_DEBUG("bnever (NOP)"); |
1603 | 1642 |
return; |
1604 | 1643 |
case OPC_BLTZAL: /* 0 < 0 */ |
1605 |
gen_op_set_T0(ctx->pc + 8);
|
|
1644 |
GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
|
|
1606 | 1645 |
gen_op_store_T0_gpr(31); |
1607 | 1646 |
MIPS_DEBUG("bnever and link"); |
1608 | 1647 |
return; |
1609 | 1648 |
case OPC_BLTZALL: /* 0 < 0 likely */ |
1610 |
gen_op_set_T0(ctx->pc + 8);
|
|
1649 |
GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
|
|
1611 | 1650 |
gen_op_store_T0_gpr(31); |
1612 | 1651 |
/* Skip the instruction in the delay slot */ |
1613 | 1652 |
MIPS_DEBUG("bnever, link and skip"); |
... | ... | |
1732 | 1771 |
} |
1733 | 1772 |
MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, |
1734 | 1773 |
blink, ctx->hflags, btarget); |
1774 |
|
|
1735 | 1775 |
ctx->btarget = btarget; |
1736 | 1776 |
if (blink > 0) { |
1737 |
gen_op_set_T0(ctx->pc + 8);
|
|
1777 |
GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
|
|
1738 | 1778 |
gen_op_store_T0_gpr(blink); |
1739 | 1779 |
} |
1740 | 1780 |
} |
Also available in: Unified diff