Revision 26135ead target-mips/translate.c

b/target-mips/translate.c
2582 2582
}
2583 2583

  
2584 2584
/* Arithmetic on HI/LO registers */
2585
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2585
static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2586 2586
{
2587 2587
    const char *opn = "hilo";
2588
    unsigned int acc;
2589 2588

  
2590 2589
    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2591 2590
        /* Treat as NOP. */
......
2593 2592
        return;
2594 2593
    }
2595 2594

  
2596
    if (opc == OPC_MFHI || opc == OPC_MFLO) {
2597
        acc = ((ctx->opcode) >> 21) & 0x03;
2598
    } else {
2599
        acc = ((ctx->opcode) >> 11) & 0x03;
2600
    }
2601

  
2602 2595
    if (acc != 0) {
2603 2596
        check_dsp(ctx);
2604 2597
    }
......
2661 2654
    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2662 2655
}
2663 2656

  
2664
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2665
                        int rs, int rt)
2657
static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2658
                       int acc, int rs, int rt)
2666 2659
{
2667 2660
    const char *opn = "mul/div";
2668 2661
    TCGv t0, t1;
2669
    unsigned int acc;
2670 2662

  
2671 2663
    t0 = tcg_temp_new();
2672 2664
    t1 = tcg_temp_new();
......
2674 2666
    gen_load_gpr(t0, rs);
2675 2667
    gen_load_gpr(t1, rt);
2676 2668

  
2669
    if (acc != 0) {
2670
        check_dsp(ctx);
2671
    }
2672

  
2677 2673
    switch (opc) {
2678 2674
    case OPC_DIV:
2679 2675
        {
......
2688 2684
            tcg_gen_or_tl(t2, t2, t3);
2689 2685
            tcg_gen_movi_tl(t3, 0);
2690 2686
            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2691
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2692
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2693
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2694
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2687
            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2688
            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2689
            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2690
            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2695 2691
            tcg_temp_free(t3);
2696 2692
            tcg_temp_free(t2);
2697 2693
        }
......
2704 2700
            tcg_gen_ext32u_tl(t0, t0);
2705 2701
            tcg_gen_ext32u_tl(t1, t1);
2706 2702
            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2707
            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2708
            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2709
            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2710
            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2703
            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2704
            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2705
            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2706
            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2711 2707
            tcg_temp_free(t3);
2712 2708
            tcg_temp_free(t2);
2713 2709
        }
......
2717 2713
        {
2718 2714
            TCGv_i32 t2 = tcg_temp_new_i32();
2719 2715
            TCGv_i32 t3 = tcg_temp_new_i32();
2720
            acc = ((ctx->opcode) >> 11) & 0x03;
2721
            if (acc != 0) {
2722
                check_dsp(ctx);
2723
            }
2724

  
2725 2716
            tcg_gen_trunc_tl_i32(t2, t0);
2726 2717
            tcg_gen_trunc_tl_i32(t3, t1);
2727 2718
            tcg_gen_muls2_i32(t2, t3, t2, t3);
......
2736 2727
        {
2737 2728
            TCGv_i32 t2 = tcg_temp_new_i32();
2738 2729
            TCGv_i32 t3 = tcg_temp_new_i32();
2739
            acc = ((ctx->opcode) >> 11) & 0x03;
2740
            if (acc != 0) {
2741
                check_dsp(ctx);
2742
            }
2743

  
2744 2730
            tcg_gen_trunc_tl_i32(t2, t0);
2745 2731
            tcg_gen_trunc_tl_i32(t3, t1);
2746 2732
            tcg_gen_mulu2_i32(t2, t3, t2, t3);
......
2763 2749
            tcg_gen_or_tl(t2, t2, t3);
2764 2750
            tcg_gen_movi_tl(t3, 0);
2765 2751
            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2766
            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2767
            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2752
            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2753
            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2768 2754
            tcg_temp_free(t3);
2769 2755
            tcg_temp_free(t2);
2770 2756
        }
......
2775 2761
            TCGv t2 = tcg_const_tl(0);
2776 2762
            TCGv t3 = tcg_const_tl(1);
2777 2763
            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2778
            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2779
            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2764
            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2765
            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2780 2766
            tcg_temp_free(t3);
2781 2767
            tcg_temp_free(t2);
2782 2768
        }
2783 2769
        opn = "ddivu";
2784 2770
        break;
2785 2771
    case OPC_DMULT:
2786
        tcg_gen_muls2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
2772
        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2787 2773
        opn = "dmult";
2788 2774
        break;
2789 2775
    case OPC_DMULTU:
2790
        tcg_gen_mulu2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
2776
        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2791 2777
        opn = "dmultu";
2792 2778
        break;
2793 2779
#endif
......
2795 2781
        {
2796 2782
            TCGv_i64 t2 = tcg_temp_new_i64();
2797 2783
            TCGv_i64 t3 = tcg_temp_new_i64();
2798
            acc = ((ctx->opcode) >> 11) & 0x03;
2799
            if (acc != 0) {
2800
                check_dsp(ctx);
2801
            }
2802 2784

  
2803 2785
            tcg_gen_ext_tl_i64(t2, t0);
2804 2786
            tcg_gen_ext_tl_i64(t3, t1);
......
2819 2801
        {
2820 2802
            TCGv_i64 t2 = tcg_temp_new_i64();
2821 2803
            TCGv_i64 t3 = tcg_temp_new_i64();
2822
            acc = ((ctx->opcode) >> 11) & 0x03;
2823
            if (acc != 0) {
2824
                check_dsp(ctx);
2825
            }
2826 2804

  
2827 2805
            tcg_gen_ext32u_tl(t0, t0);
2828 2806
            tcg_gen_ext32u_tl(t1, t1);
......
2845 2823
        {
2846 2824
            TCGv_i64 t2 = tcg_temp_new_i64();
2847 2825
            TCGv_i64 t3 = tcg_temp_new_i64();
2848
            acc = ((ctx->opcode) >> 11) & 0x03;
2849
            if (acc != 0) {
2850
                check_dsp(ctx);
2851
            }
2852 2826

  
2853 2827
            tcg_gen_ext_tl_i64(t2, t0);
2854 2828
            tcg_gen_ext_tl_i64(t3, t1);
......
2869 2843
        {
2870 2844
            TCGv_i64 t2 = tcg_temp_new_i64();
2871 2845
            TCGv_i64 t3 = tcg_temp_new_i64();
2872
            acc = ((ctx->opcode) >> 11) & 0x03;
2873
            if (acc != 0) {
2874
                check_dsp(ctx);
2875
            }
2876 2846

  
2877 2847
            tcg_gen_ext32u_tl(t0, t0);
2878 2848
            tcg_gen_ext32u_tl(t1, t1);
......
10135 10105
            gen_logic(ctx, OPC_NOR, rx, ry, 0);
10136 10106
            break;
10137 10107
        case RR_MFHI:
10138
            gen_HILO(ctx, OPC_MFHI, rx);
10108
            gen_HILO(ctx, OPC_MFHI, 0, rx);
10139 10109
            break;
10140 10110
        case RR_CNVT:
10141 10111
            switch (cnvt_op) {
......
10167 10137
            }
10168 10138
            break;
10169 10139
        case RR_MFLO:
10170
            gen_HILO(ctx, OPC_MFLO, rx);
10140
            gen_HILO(ctx, OPC_MFLO, 0, rx);
10171 10141
            break;
10172 10142
#if defined (TARGET_MIPS64)
10173 10143
        case RR_DSRA:
......
10188 10158
            break;
10189 10159
#endif
10190 10160
        case RR_MULT:
10191
            gen_muldiv(ctx, OPC_MULT, rx, ry);
10161
            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10192 10162
            break;
10193 10163
        case RR_MULTU:
10194
            gen_muldiv(ctx, OPC_MULTU, rx, ry);
10164
            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10195 10165
            break;
10196 10166
        case RR_DIV:
10197
            gen_muldiv(ctx, OPC_DIV, rx, ry);
10167
            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10198 10168
            break;
10199 10169
        case RR_DIVU:
10200
            gen_muldiv(ctx, OPC_DIVU, rx, ry);
10170
            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10201 10171
            break;
10202 10172
#if defined (TARGET_MIPS64)
10203 10173
        case RR_DMULT:
10204 10174
            check_mips_64(ctx);
10205
            gen_muldiv(ctx, OPC_DMULT, rx, ry);
10175
            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10206 10176
            break;
10207 10177
        case RR_DMULTU:
10208 10178
            check_mips_64(ctx);
10209
            gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10179
            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10210 10180
            break;
10211 10181
        case RR_DDIV:
10212 10182
            check_mips_64(ctx);
10213
            gen_muldiv(ctx, OPC_DDIV, rx, ry);
10183
            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10214 10184
            break;
10215 10185
        case RR_DDIVU:
10216 10186
            check_mips_64(ctx);
10217
            gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10187
            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10218 10188
            break;
10219 10189
#endif
10220 10190
        default:
......
10923 10893
        break;
10924 10894
    case MFHI16 + 0:
10925 10895
    case MFHI16 + 1:
10926
        gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10896
        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10927 10897
        break;
10928 10898
    case MFLO16 + 0:
10929 10899
    case MFLO16 + 1:
10930
        gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10900
        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10931 10901
        break;
10932 10902
    case BREAK16:
10933 10903
        generate_exception(ctx, EXCP_BREAK);
......
11125 11095
            break;
11126 11096
        case MULT:
11127 11097
            mips32_op = OPC_MULT;
11128
            goto do_muldiv;
11098
            goto do_mul;
11129 11099
        case MULTU:
11130 11100
            mips32_op = OPC_MULTU;
11131
            goto do_muldiv;
11101
            goto do_mul;
11132 11102
        case DIV:
11133 11103
            mips32_op = OPC_DIV;
11134
            goto do_muldiv;
11104
            goto do_div;
11135 11105
        case DIVU:
11136 11106
            mips32_op = OPC_DIVU;
11137
            goto do_muldiv;
11107
            goto do_div;
11108
        do_div:
11109
            check_insn(ctx, ISA_MIPS32);
11110
            gen_muldiv(ctx, mips32_op, 0, rs, rt);
11111
            break;
11138 11112
        case MADD:
11139 11113
            mips32_op = OPC_MADD;
11140
            goto do_muldiv;
11114
            goto do_mul;
11141 11115
        case MADDU:
11142 11116
            mips32_op = OPC_MADDU;
11143
            goto do_muldiv;
11117
            goto do_mul;
11144 11118
        case MSUB:
11145 11119
            mips32_op = OPC_MSUB;
11146
            goto do_muldiv;
11120
            goto do_mul;
11147 11121
        case MSUBU:
11148 11122
            mips32_op = OPC_MSUBU;
11149
        do_muldiv:
11123
        do_mul:
11150 11124
            check_insn(ctx, ISA_MIPS32);
11151
            gen_muldiv(ctx, mips32_op, rs, rt);
11125
            gen_muldiv(ctx, mips32_op, (ctx->opcode >> 14) & 3, rs, rt);
11152 11126
            break;
11153 11127
        default:
11154 11128
            goto pool32axf_invalid;
......
11285 11259
        }
11286 11260
        break;
11287 11261
    case 0x35:
11288
        switch (minor) {
11262
        switch (minor & 3) {
11289 11263
        case MFHI32:
11290
            gen_HILO(ctx, OPC_MFHI, rs);
11264
            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11291 11265
            break;
11292 11266
        case MFLO32:
11293
            gen_HILO(ctx, OPC_MFLO, rs);
11267
            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11294 11268
            break;
11295 11269
        case MTHI32:
11296
            gen_HILO(ctx, OPC_MTHI, rs);
11270
            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11297 11271
            break;
11298 11272
        case MTLO32:
11299
            gen_HILO(ctx, OPC_MTLO, rs);
11273
            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11300 11274
            break;
11301 11275
        default:
11302 11276
            goto pool32axf_invalid;
......
14469 14443
        case OPC_XOR:
14470 14444
            gen_logic(ctx, op1, rd, rs, rt);
14471 14445
            break;
14472
        case OPC_MULT ... OPC_DIVU:
14446
        case OPC_MULT:
14447
        case OPC_MULTU:
14473 14448
            if (sa) {
14474 14449
                check_insn(ctx, INSN_VR54XX);
14475 14450
                op1 = MASK_MUL_VR54XX(ctx->opcode);
14476 14451
                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14477
            } else
14478
                gen_muldiv(ctx, op1, rs, rt);
14452
            } else {
14453
                gen_muldiv(ctx, op1, rd & 3, rs, rt);
14454
            }
14455
            break;
14456
        case OPC_DIV:
14457
        case OPC_DIVU:
14458
            gen_muldiv(ctx, op1, 0, rs, rt);
14479 14459
            break;
14480 14460
        case OPC_JR ... OPC_JALR:
14481 14461
            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
......
14487 14467
            break;
14488 14468
        case OPC_MFHI:          /* Move from HI/LO */
14489 14469
        case OPC_MFLO:
14490
            gen_HILO(ctx, op1, rd);
14470
            gen_HILO(ctx, op1, rs & 3, rd);
14491 14471
            break;
14492 14472
        case OPC_MTHI:
14493 14473
        case OPC_MTLO:          /* Move to HI/LO */
14494
            gen_HILO(ctx, op1, rs);
14474
            gen_HILO(ctx, op1, rd & 3, rs);
14495 14475
            break;
14496 14476
        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
14497 14477
#ifdef MIPS_STRICT_STANDARD
......
14611 14591
        case OPC_DMULT ... OPC_DDIVU:
14612 14592
            check_insn(ctx, ISA_MIPS3);
14613 14593
            check_mips_64(ctx);
14614
            gen_muldiv(ctx, op1, rs, rt);
14594
            gen_muldiv(ctx, op1, 0, rs, rt);
14615 14595
            break;
14616 14596
#endif
14617 14597
        default:            /* Invalid */
......
14626 14606
        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14627 14607
        case OPC_MSUB ... OPC_MSUBU:
14628 14608
            check_insn(ctx, ISA_MIPS32);
14629
            gen_muldiv(ctx, op1, rs, rt);
14609
            gen_muldiv(ctx, op1, rd & 3, rs, rt);
14630 14610
            break;
14631 14611
        case OPC_MUL:
14632 14612
            gen_arith(ctx, op1, rd, rs, rt);

Also available in: Unified diff