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