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