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 | 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 | 987 | /* Conditional branch */ |
| 980 | 988 | void op_set_bcond (void) |
| 981 | 989 | { |
| ... | ... | @@ -2409,6 +2417,14 @@ void op_save_pc (void) |
| 2409 | 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 | 2428 | void op_interrupt_restart (void) |
| 2413 | 2429 | { |
| 2414 | 2430 | if (!(env->CP0_Status & (1 << CP0St_EXL)) && | ... | ... |
target-mips/op_template.c
| ... | ... | @@ -68,4 +68,20 @@ SET_RESET(T1, _T1) |
| 68 | 68 | SET_RESET(T2, _T2) |
| 69 | 69 | |
| 70 | 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 | 87 | #endif | ... | ... |
target-mips/translate.c
| ... | ... | @@ -569,6 +569,18 @@ do { \ |
| 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,6 +589,7 @@ do { \ |
| 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,6 +608,32 @@ 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,7 +643,7 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) |
| 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,7 +660,7 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) |
| 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,7 +985,7 @@ static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt, |
| 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,10 +1530,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) |
| 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,7 +1595,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, |
| 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,12 +1641,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, |
| 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,9 +1771,10 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, |
| 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 | } | ... | ... |