Commit 9b9e4393dd08481530f8d6389ed0ac64405aa4fa
1 parent
4020f277
MIPS64 addressing fixes, by Aurelien Jarno.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2888 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
81 additions
and
9 deletions
target-mips/op.c
@@ -976,6 +976,14 @@ void op_save_btarget (void) | @@ -976,6 +976,14 @@ void op_save_btarget (void) | ||
976 | RETURN(); | 976 | RETURN(); |
977 | } | 977 | } |
978 | 978 | ||
979 | +#ifdef TARGET_MIPS64 | ||
980 | +void op_save_btarget64 (void) | ||
981 | +{ | ||
982 | + env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; | ||
983 | + RETURN(); | ||
984 | +} | ||
985 | +#endif | ||
986 | + | ||
979 | /* Conditional branch */ | 987 | /* Conditional branch */ |
980 | void op_set_bcond (void) | 988 | void op_set_bcond (void) |
981 | { | 989 | { |
@@ -2409,6 +2417,14 @@ void op_save_pc (void) | @@ -2409,6 +2417,14 @@ void op_save_pc (void) | ||
2409 | RETURN(); | 2417 | RETURN(); |
2410 | } | 2418 | } |
2411 | 2419 | ||
2420 | +#ifdef TARGET_MIPS64 | ||
2421 | +void op_save_pc64 (void) | ||
2422 | +{ | ||
2423 | + env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; | ||
2424 | + RETURN(); | ||
2425 | +} | ||
2426 | +#endif | ||
2427 | + | ||
2412 | void op_interrupt_restart (void) | 2428 | void op_interrupt_restart (void) |
2413 | { | 2429 | { |
2414 | if (!(env->CP0_Status & (1 << CP0St_EXL)) && | 2430 | if (!(env->CP0_Status & (1 << CP0St_EXL)) && |
target-mips/op_template.c
@@ -68,4 +68,20 @@ SET_RESET(T1, _T1) | @@ -68,4 +68,20 @@ SET_RESET(T1, _T1) | ||
68 | SET_RESET(T2, _T2) | 68 | SET_RESET(T2, _T2) |
69 | 69 | ||
70 | #undef SET_RESET | 70 | #undef SET_RESET |
71 | + | ||
72 | +#ifdef TARGET_MIPS64 | ||
73 | +#define SET64(treg, tregname) \ | ||
74 | + void glue(op_set64, tregname)(void) \ | ||
75 | + { \ | ||
76 | + treg = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; \ | ||
77 | + RETURN(); \ | ||
78 | + } | ||
79 | + | ||
80 | +SET64(T0, _T0) | ||
81 | +SET64(T1, _T1) | ||
82 | +SET64(T2, _T2) | ||
83 | + | ||
84 | +#undef SET64 | ||
85 | + | ||
86 | +#endif | ||
71 | #endif | 87 | #endif |
target-mips/translate.c
@@ -569,6 +569,18 @@ do { \ | @@ -569,6 +569,18 @@ do { \ | ||
569 | } \ | 569 | } \ |
570 | } while (0) | 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 | #define GEN_LOAD_IMM_TN(Tn, Imm) \ | 584 | #define GEN_LOAD_IMM_TN(Tn, Imm) \ |
573 | do { \ | 585 | do { \ |
574 | if (Imm == 0) { \ | 586 | if (Imm == 0) { \ |
@@ -577,6 +589,7 @@ do { \ | @@ -577,6 +589,7 @@ do { \ | ||
577 | glue(gen_op_set_, Tn)(Imm); \ | 589 | glue(gen_op_set_, Tn)(Imm); \ |
578 | } \ | 590 | } \ |
579 | } while (0) | 591 | } while (0) |
592 | +#endif | ||
580 | 593 | ||
581 | #define GEN_STORE_TN_REG(Rn, Tn) \ | 594 | #define GEN_STORE_TN_REG(Rn, Tn) \ |
582 | do { \ | 595 | do { \ |
@@ -595,6 +608,32 @@ do { \ | @@ -595,6 +608,32 @@ do { \ | ||
595 | glue(gen_op_store_fpr_, FTn)(Fn); \ | 608 | glue(gen_op_store_fpr_, FTn)(Fn); \ |
596 | } while (0) | 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 | static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) | 637 | static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) |
599 | { | 638 | { |
600 | #if defined MIPS_DEBUG_DISAS | 639 | #if defined MIPS_DEBUG_DISAS |
@@ -604,7 +643,7 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) | @@ -604,7 +643,7 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) | ||
604 | } | 643 | } |
605 | #endif | 644 | #endif |
606 | if (do_save_pc && ctx->pc != ctx->saved_pc) { | 645 | if (do_save_pc && ctx->pc != ctx->saved_pc) { |
607 | - gen_op_save_pc(ctx->pc); | 646 | + gen_save_pc(ctx->pc); |
608 | ctx->saved_pc = ctx->pc; | 647 | ctx->saved_pc = ctx->pc; |
609 | } | 648 | } |
610 | if (ctx->hflags != ctx->saved_hflags) { | 649 | if (ctx->hflags != ctx->saved_hflags) { |
@@ -621,7 +660,7 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) | @@ -621,7 +660,7 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) | ||
621 | /* bcond was already saved by the BL insn */ | 660 | /* bcond was already saved by the BL insn */ |
622 | /* fall through */ | 661 | /* fall through */ |
623 | case MIPS_HFLAG_B: | 662 | case MIPS_HFLAG_B: |
624 | - gen_op_save_btarget(ctx->btarget); | 663 | + gen_save_btarget(ctx->btarget); |
625 | break; | 664 | break; |
626 | } | 665 | } |
627 | } | 666 | } |
@@ -946,7 +985,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, | @@ -946,7 +985,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, | ||
946 | GEN_LOAD_IMM_TN(T1, uimm); | 985 | GEN_LOAD_IMM_TN(T1, uimm); |
947 | break; | 986 | break; |
948 | case OPC_LUI: | 987 | case OPC_LUI: |
949 | - GEN_LOAD_IMM_TN(T0, uimm << 16); | 988 | + GEN_LOAD_IMM_TN(T0, imm << 16); |
950 | break; | 989 | break; |
951 | case OPC_SLL: | 990 | case OPC_SLL: |
952 | case OPC_SRA: | 991 | case OPC_SRA: |
@@ -1491,10 +1530,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) | @@ -1491,10 +1530,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) | ||
1491 | gen_op_goto_tb0(TBPARAM(tb)); | 1530 | gen_op_goto_tb0(TBPARAM(tb)); |
1492 | else | 1531 | else |
1493 | gen_op_goto_tb1(TBPARAM(tb)); | 1532 | gen_op_goto_tb1(TBPARAM(tb)); |
1494 | - gen_op_save_pc(dest); | 1533 | + gen_save_pc(dest); |
1495 | gen_op_set_T0((long)tb + n); | 1534 | gen_op_set_T0((long)tb + n); |
1496 | } else { | 1535 | } else { |
1497 | - gen_op_save_pc(dest); | 1536 | + gen_save_pc(dest); |
1498 | gen_op_reset_T0(); | 1537 | gen_op_reset_T0(); |
1499 | } | 1538 | } |
1500 | gen_op_exit_tb(); | 1539 | gen_op_exit_tb(); |
@@ -1556,7 +1595,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, | @@ -1556,7 +1595,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, | ||
1556 | case OPC_J: | 1595 | case OPC_J: |
1557 | case OPC_JAL: | 1596 | case OPC_JAL: |
1558 | /* Jump to immediate */ | 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 | break; | 1599 | break; |
1561 | case OPC_JR: | 1600 | case OPC_JR: |
1562 | case OPC_JALR: | 1601 | case OPC_JALR: |
@@ -1602,12 +1641,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, | @@ -1602,12 +1641,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, | ||
1602 | MIPS_DEBUG("bnever (NOP)"); | 1641 | MIPS_DEBUG("bnever (NOP)"); |
1603 | return; | 1642 | return; |
1604 | case OPC_BLTZAL: /* 0 < 0 */ | 1643 | case OPC_BLTZAL: /* 0 < 0 */ |
1605 | - gen_op_set_T0(ctx->pc + 8); | 1644 | + GEN_LOAD_IMM_TN(T0, ctx->pc + 8); |
1606 | gen_op_store_T0_gpr(31); | 1645 | gen_op_store_T0_gpr(31); |
1607 | MIPS_DEBUG("bnever and link"); | 1646 | MIPS_DEBUG("bnever and link"); |
1608 | return; | 1647 | return; |
1609 | case OPC_BLTZALL: /* 0 < 0 likely */ | 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 | gen_op_store_T0_gpr(31); | 1650 | gen_op_store_T0_gpr(31); |
1612 | /* Skip the instruction in the delay slot */ | 1651 | /* Skip the instruction in the delay slot */ |
1613 | MIPS_DEBUG("bnever, link and skip"); | 1652 | MIPS_DEBUG("bnever, link and skip"); |
@@ -1732,9 +1771,10 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, | @@ -1732,9 +1771,10 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, | ||
1732 | } | 1771 | } |
1733 | MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, | 1772 | MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, |
1734 | blink, ctx->hflags, btarget); | 1773 | blink, ctx->hflags, btarget); |
1774 | + | ||
1735 | ctx->btarget = btarget; | 1775 | ctx->btarget = btarget; |
1736 | if (blink > 0) { | 1776 | if (blink > 0) { |
1737 | - gen_op_set_T0(ctx->pc + 8); | 1777 | + GEN_LOAD_IMM_TN(T0, ctx->pc + 8); |
1738 | gen_op_store_T0_gpr(blink); | 1778 | gen_op_store_T0_gpr(blink); |
1739 | } | 1779 | } |
1740 | } | 1780 | } |