Commit 9b9e4393dd08481530f8d6389ed0ac64405aa4fa

Authored by ths
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
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 }