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