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 | } |