diff --git a/target/i386/latx/translator/tr-avx-cvt.c b/target/i386/latx/translator/tr-avx-cvt.c index e903ceeddd..e937da6b1e 100644 --- a/target/i386/latx/translator/tr-avx-cvt.c +++ b/target/i386/latx/translator/tr-avx-cvt.c @@ -102,26 +102,38 @@ static bool translate_vcvtps2dq_opt(IR1_INST * pir1) { IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src = load_freg256_from_ir1(opnd1); - IR2_OPND temp_f = ra_alloc_ftemp(); IR2_OPND sse_invalid = ra_alloc_ftemp(); IR2_OPND overflow = ra_alloc_ftemp(); IR2_OPND comp_mask = ra_alloc_ftemp(); + bool same_reg = ir1_opnd_is_same_reg(opnd0, opnd1); if (ir1_opnd_is_xmm(opnd0)) { - la_vftint_w_s(temp_f, src); - la_vldi(sse_invalid, 0b1001110000000); // broadcast 0x80000000 to all 0x1380 - la_vldi(overflow, (0b10011 << 8) | 0x4f); //0x134f - la_vfcmp_cond_s(comp_mask, overflow, src, 0xE); // get Nan mark 0xE=cULE - la_vbitsel_v(temp_f, temp_f, sse_invalid, comp_mask); - la_vand_v(dest, temp_f, temp_f); + if (same_reg) { + la_vldi(sse_invalid, 0b1001110000000); + la_vldi(overflow, (0b10011 << 8) | 0x4f); + la_vfcmp_cond_s(comp_mask, overflow, src, 0xE); + la_vftint_w_s(dest, src); + } else { + la_vftint_w_s(dest, src); + la_vldi(sse_invalid, 0b1001110000000); + la_vldi(overflow, (0b10011 << 8) | 0x4f); + la_vfcmp_cond_s(comp_mask, overflow, src, 0xE); + } + la_vbitsel_v(dest, dest, sse_invalid, comp_mask); set_high128_xreg_to_zero(dest); } else { - la_xvftint_w_s(temp_f, src); - la_xvldi(sse_invalid, 0b1001110000000); // broadcast 0x80000000 to all 0x1380 - la_xvldi(overflow, (0b10011 << 8) | 0x4f); //0x134f - la_xvfcmp_cond_s(comp_mask, overflow, src, 0xE); // get Nan mark 0xE=cULE - la_xvbitsel_v(temp_f, temp_f, sse_invalid, comp_mask); - la_xvand_v(dest, temp_f, temp_f); + if (same_reg) { + la_xvldi(sse_invalid, 0b1001110000000); + la_xvldi(overflow, (0b10011 << 8) | 0x4f); + la_xvfcmp_cond_s(comp_mask, overflow, src, 0xE); + la_xvftint_w_s(dest, src); + } else { + la_xvftint_w_s(dest, src); + la_xvldi(sse_invalid, 0b1001110000000); + la_xvldi(overflow, (0b10011 << 8) | 0x4f); + la_xvfcmp_cond_s(comp_mask, overflow, src, 0xE); + } + la_xvbitsel_v(dest, dest, sse_invalid, comp_mask); } return true; } @@ -829,26 +841,38 @@ static bool translate_vcvttps2dq_opt(IR1_INST * pir1) { IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src = load_freg256_from_ir1(opnd1); - IR2_OPND temp_f = ra_alloc_ftemp(); IR2_OPND sse_invalid = ra_alloc_ftemp(); IR2_OPND overflow = ra_alloc_ftemp(); IR2_OPND comp_mask = ra_alloc_ftemp(); + bool same_reg = ir1_opnd_is_same_reg(opnd0, opnd1); if (ir1_opnd_is_xmm(opnd0)) { - la_vftintrz_w_s(temp_f, src); - la_vldi(sse_invalid, 0b1001110000000); // broadcast 0x80000000 to all 0x1380 - la_vldi(overflow, (0b10011 << 8) | 0x4f); //0x134f 2^31 - la_vfcmp_cond_s(comp_mask, overflow, src, 0xE); // get Nan mark 0xE=cULE - la_vbitsel_v(temp_f, temp_f, sse_invalid, comp_mask); - la_vand_v(dest, temp_f, temp_f); + if (same_reg) { + la_vldi(sse_invalid, 0b1001110000000); + la_vldi(overflow, (0b10011 << 8) | 0x4f); + la_vfcmp_cond_s(comp_mask, overflow, src, 0xE); + la_vftintrz_w_s(dest, src); + } else { + la_vftintrz_w_s(dest, src); + la_vldi(sse_invalid, 0b1001110000000); + la_vldi(overflow, (0b10011 << 8) | 0x4f); + la_vfcmp_cond_s(comp_mask, overflow, src, 0xE); + } + la_vbitsel_v(dest, dest, sse_invalid, comp_mask); set_high128_xreg_to_zero(dest); } else { - la_xvftintrz_w_s(temp_f, src); - la_xvldi(sse_invalid, 0b1001110000000); // broadcast 0x80000000 to all 0x1380 - la_xvldi(overflow, (0b10011 << 8) | 0x4f); //0x134f 2^31 - la_xvfcmp_cond_s(comp_mask, overflow, src, 0xE); // get Nan mark 0xE=cULE - la_xvbitsel_v(temp_f, temp_f, sse_invalid, comp_mask); - la_xvand_v(dest, temp_f, temp_f); + if (same_reg) { + la_xvldi(sse_invalid, 0b1001110000000); + la_xvldi(overflow, (0b10011 << 8) | 0x4f); + la_xvfcmp_cond_s(comp_mask, overflow, src, 0xE); + la_xvftintrz_w_s(dest, src); + } else { + la_xvftintrz_w_s(dest, src); + la_xvldi(sse_invalid, 0b1001110000000); + la_xvldi(overflow, (0b10011 << 8) | 0x4f); + la_xvfcmp_cond_s(comp_mask, overflow, src, 0xE); + } + la_xvbitsel_v(dest, dest, sse_invalid, comp_mask); } return true; } diff --git a/target/i386/latx/translator/tr-avx-lsx.c b/target/i386/latx/translator/tr-avx-lsx.c index 10d8342950..5ac247a882 100644 --- a/target/i386/latx/translator/tr-avx-lsx.c +++ b/target/i386/latx/translator/tr-avx-lsx.c @@ -605,46 +605,35 @@ static bool translate_avx_integer_3op_custom_lsx( static void translate_vpmaddwd_lane_lsx(IR2_OPND dest, IR2_OPND src1, IR2_OPND src2) { - IR2_OPND temp = ra_alloc_ftemp(); + if (dest._reg_num != src1._reg_num && + dest._reg_num != src2._reg_num) { + la_vmulwev_w_h(dest, src1, src2); + la_vmaddwod_w_h(dest, src1, src2); + return; + } - la_vxor_v(temp, temp, temp); - la_vmaddwev_w_h(temp, src1, src2); - la_vmaddwod_w_h(temp, src1, src2); - la_vbsll_v(dest, temp, 0); - ra_free_temp(temp); + IR2_OPND even = ra_alloc_ftemp(); + IR2_OPND odd = ra_alloc_ftemp(); + + la_vmulwev_w_h(even, src1, src2); + la_vmulwod_w_h(odd, src1, src2); + la_vadd_w(dest, even, odd); + ra_free_temp(odd); + ra_free_temp(even); } static void translate_vpmaddubsw_lane_lsx(IR2_OPND dest, IR2_OPND src1, IR2_OPND src2) { - IR2_OPND temp1 = ra_alloc_ftemp(); - IR2_OPND temp2 = ra_alloc_ftemp(); - IR2_OPND temp3 = ra_alloc_ftemp(); - IR2_OPND temp4 = ra_alloc_ftemp(); - IR2_OPND temp5 = ra_alloc_ftemp(); - IR2_OPND one = ra_alloc_itemp(); + IR2_OPND even = ra_alloc_ftemp(); + IR2_OPND odd = ra_alloc_ftemp(); /* Unsigned src1 multiplied by signed src2, then saturated to halfwords. */ - la_vreplgr2vr_d(temp1, zero_ir2_opnd); - la_vabsd_b(temp3, src2, temp1); - la_vmaddwev_h_bu(temp1, src1, temp3); - la_vreplgr2vr_d(temp2, zero_ir2_opnd); - la_vmaddwod_h_bu(temp2, src1, temp3); - - la_ori(one, zero_ir2_opnd, 1); - la_vreplgr2vr_b(temp3, one); - la_vsigncov_b(temp4, src2, temp3); - la_vmulwev_h_b(temp5, temp4, temp3); - la_vmulwod_h_b(temp3, temp4, temp3); - la_vmul_h(temp1, temp1, temp5); - la_vmul_h(temp2, temp2, temp3); - la_vsadd_h(dest, temp2, temp1); - ra_free_temp(one); - ra_free_temp(temp5); - ra_free_temp(temp4); - ra_free_temp(temp3); - ra_free_temp(temp2); - ra_free_temp(temp1); + la_vmulwev_h_bu_b(even, src1, src2); + la_vmulwod_h_bu_b(odd, src1, src2); + la_vsadd_h(dest, even, odd); + ra_free_temp(odd); + ra_free_temp(even); } static void translate_vpmulhrsw_lane_lsx(IR2_OPND dest, IR2_OPND src1, diff --git a/target/i386/latx/translator/tr-avx-shift.c b/target/i386/latx/translator/tr-avx-shift.c index 6e75e3ece6..e89939163f 100644 --- a/target/i386/latx/translator/tr-avx-shift.c +++ b/target/i386/latx/translator/tr-avx-shift.c @@ -21,7 +21,7 @@ bool translate_vpslldq(IR1_INST * pir1) { lsassert((ir1_opnd_is_xmm(opnd0) && ir1_opnd_is_xmm(opnd1)) || (ir1_opnd_is_ymm(opnd0) && ir1_opnd_is_ymm(opnd1))); lsassert(ir1_opnd_is_imm(opnd2)); - IR2_OPND dest = load_freg256_from_ir1(opnd0); + IR2_OPND dest = ra_alloc_xmm(ir1_opnd_base_reg_num(opnd0)); IR2_OPND src = load_freg256_from_ir1(opnd1); uint8_t imm = ir1_opnd_uimm(opnd2); if (imm > 15) { @@ -118,7 +118,7 @@ bool translate_vpsrldq(IR1_INST * pir1) { lsassert((ir1_opnd_is_xmm(opnd0) && ir1_opnd_is_xmm(opnd1)) || (ir1_opnd_is_ymm(opnd0) && ir1_opnd_is_ymm(opnd1))); lsassert(ir1_opnd_is_imm(opnd2)); - IR2_OPND dest = load_freg256_from_ir1(opnd0); + IR2_OPND dest = ra_alloc_xmm(ir1_opnd_base_reg_num(opnd0)); IR2_OPND src = load_freg256_from_ir1(opnd1); uint8_t imm = ir1_opnd_uimm(opnd2); if (imm > 15) { diff --git a/target/i386/latx/translator/tr-avx.c b/target/i386/latx/translator/tr-avx.c index 7c809154e5..f54099c70e 100644 --- a/target/i386/latx/translator/tr-avx.c +++ b/target/i386/latx/translator/tr-avx.c @@ -1272,14 +1272,12 @@ bool translate_vextractf128(IR1_INST * pir1) { uint8 imm = ir1_opnd_uimm(ir1_get_opnd(pir1, 2)) & 0x1; if (ir1_opnd_is_xmm(ir1_get_opnd(pir1, 0))) { IR2_OPND dest = load_freg128_from_ir1(ir1_get_opnd(pir1, 0)); - IR2_OPND temp = ra_alloc_ftemp(); if (!imm) { - la_xvpermi_q(temp, src, VEXTRINS_IMM_4_0(3, 0)); + la_xvpermi_q(dest, src, VEXTRINS_IMM_4_0(3, 0)); } else { - la_xvpermi_q(temp, src, VEXTRINS_IMM_4_0(3, 1)); + la_xvpermi_q(dest, src, VEXTRINS_IMM_4_0(3, 1)); } - set_high128_xreg_to_zero(temp); - la_xvori_b(dest, temp, 0); + set_high128_xreg_to_zero(dest); } else { if (!imm) { store_freg128_to_ir1_mem(src, ir1_get_opnd(pir1, 0)); @@ -1374,14 +1372,25 @@ bool translate_vinserti128(IR1_INST * pir1) { IR2_OPND src1 = load_freg256_from_ir1(ir1_get_opnd(pir1, 1)); IR2_OPND src2 = load_freg128_from_ir1(ir1_get_opnd(pir1, 2)); uint8 imm = ir1_opnd_uimm(ir1_get_opnd(pir1, 3)) & 0x1; - IR2_OPND temp = ra_alloc_ftemp(); - la_xvori_b(temp, src1, 0); + bool dest_is_src1 = ir1_opnd_base_reg_num(ir1_get_opnd(pir1, 0)) == + ir1_opnd_base_reg_num(ir1_get_opnd(pir1, 1)); + bool dest_is_src2 = ir1_opnd_is_xmm(ir1_get_opnd(pir1, 2)) && + ir1_opnd_base_reg_num(ir1_get_opnd(pir1, 0)) == + ir1_opnd_base_reg_num(ir1_get_opnd(pir1, 2)); + IR2_OPND result = dest_is_src2 && !dest_is_src1 ? + ra_alloc_ftemp() : dest; + + if (!dest_is_src1) { + la_xvori_b(result, src1, 0); + } if (!imm) { - la_xvpermi_q(temp, src2, VEXTRINS_IMM_4_0(3, 0)); + la_xvpermi_q(result, src2, VEXTRINS_IMM_4_0(3, 0)); } else { - la_xvpermi_q(temp, src2, VEXTRINS_IMM_4_0(0, 2)); + la_xvpermi_q(result, src2, VEXTRINS_IMM_4_0(0, 2)); + } + if (dest_is_src2 && !dest_is_src1) { + la_xvori_b(dest, result, 0); } - la_xvori_b(dest, temp, 0); return true; } @@ -1702,41 +1711,42 @@ bool translate_vpackusxx(IR1_INST * pir1) { IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src1 = load_freg256_from_ir1(opnd1); IR2_OPND src2 = load_freg256_from_ir1(opnd2); - IR2_OPND temp1 = ra_alloc_ftemp(); IR2_OPND temp2; + bool dest_is_src2 = (ir1_opnd_is_xmm(opnd2) || + ir1_opnd_is_ymm(opnd2)) && + ir1_opnd_base_reg_num(opnd0) == + ir1_opnd_base_reg_num(opnd2); IR1_OPCODE op = ir1_opcode(pir1); - IR2_INST * ( * cmp_inst)(IR2_OPND, IR2_OPND, int); IR2_INST * ( * cvt_inst)(IR2_OPND, IR2_OPND, int); switch (op) { case dt_X86_INS_VPACKUSDW: - cmp_inst = la_xvslti_w; cvt_inst = la_xvssrani_hu_w; break; case dt_X86_INS_VPACKUSWB: - cmp_inst = la_xvslti_h; cvt_inst = la_xvssrani_bu_h; break; default: - cmp_inst = NULL; cvt_inst = NULL; lsassert(0); break; } - cmp_inst(temp1, src1, 0); - la_xvandn_v(temp1, temp1, src1); - if ((ir1_opnd_is_xmm(opnd2) || ir1_opnd_is_ymm(opnd2)) && + if (dest_is_src2) { + temp2 = dest; + } else if ((ir1_opnd_is_xmm(opnd2) || ir1_opnd_is_ymm(opnd2)) && ir1_opnd_base_reg_num(opnd1) == ir1_opnd_base_reg_num(opnd2)) { - temp2 = temp1; + temp2 = ra_alloc_ftemp(); + la_xvori_b(temp2, src2, 0); } else { temp2 = ra_alloc_ftemp(); - cmp_inst(temp2, src2, 0); - la_xvandn_v(temp2, temp2, src2); + la_xvori_b(temp2, src2, 0); } - cvt_inst(temp2, temp1, 0); + cvt_inst(temp2, src1, 0); if (ir1_opnd_is_xmm(opnd0)) { set_high128_xreg_to_zero(temp2); } - la_xvori_b(dest, temp2, 0); + if (!dest_is_src2) { + la_xvori_b(dest, temp2, 0); + } return true; } @@ -1929,15 +1939,15 @@ bool translate_vpblendvb(IR1_INST * pir1) { (ir1_opnd_is_ymm(opnd0) && ir1_opnd_is_ymm(opnd1))); IR2_OPND dest, src1, src2, src3; IR2_OPND temp = ra_alloc_ftemp(); - dest = load_freg256_from_ir1(opnd0); + dest = ra_alloc_xmm(ir1_opnd_base_reg_num(opnd0)); src1 = load_freg256_from_ir1(opnd1); src2 = load_freg256_from_ir1(opnd2); src3 = load_freg256_from_ir1(opnd3); la_xvslti_b(temp, src3, 0); - la_xvbitsel_v(temp, src1, src2, temp); - if (ir1_opnd_is_xmm(opnd0)) - set_high128_xreg_to_zero(temp); - la_xvori_b(dest, temp, 0); + la_xvbitsel_v(dest, src1, src2, temp); + if (ir1_opnd_is_xmm(opnd0)) { + set_high128_xreg_to_zero(dest); + } return true; } @@ -3495,8 +3505,6 @@ bool translate_vpbroadcastd(IR1_INST *pir1) la_xvreplve0_w(dest, src); } else if (ir1_opnd_is_ymm(opnd0)) { la_xvreplve0_w(dest, src); - la_xvinsve0_d(dest, dest, 2); - la_xvinsve0_d(dest, dest, 3); } else { lsassert(0); } @@ -3754,23 +3762,35 @@ bool translate_vpmaddwd(IR1_INST * pir1) { IR2_OPND dest = load_freg128_from_ir1(opnd0); IR2_OPND src1 = load_freg128_from_ir1(opnd1); IR2_OPND src2 = load_freg128_from_ir1(opnd2); - IR2_OPND temp = ra_alloc_ftemp(); + if (dest._reg_num != src1._reg_num && + dest._reg_num != src2._reg_num) { + la_vmulwev_w_h(dest, src1, src2); + la_vmaddwod_w_h(dest, src1, src2); + } else { + IR2_OPND even = ra_alloc_ftemp(); + IR2_OPND odd = ra_alloc_ftemp(); - la_vxor_v(temp, temp, temp); - la_vmaddwev_w_h(temp, src1, src2); - la_vmaddwod_w_h(temp, src1, src2); - la_vbsll_v(dest, temp, 0); + la_vmulwev_w_h(even, src1, src2); + la_vmulwod_w_h(odd, src1, src2); + la_vadd_w(dest, even, odd); + } set_high128_xreg_to_zero(dest); } else { IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src1 = load_freg256_from_ir1(opnd1); IR2_OPND src2 = load_freg256_from_ir1(opnd2); - IR2_OPND temp = ra_alloc_ftemp(); + if (dest._reg_num != src1._reg_num && + dest._reg_num != src2._reg_num) { + la_xvmulwev_w_h(dest, src1, src2); + la_xvmaddwod_w_h(dest, src1, src2); + } else { + IR2_OPND even = ra_alloc_ftemp(); + IR2_OPND odd = ra_alloc_ftemp(); - la_xvxor_v(temp, temp, temp); - la_xvmaddwev_w_h(temp, src1, src2); - la_xvmaddwod_w_h(temp, src1, src2); - la_xvbsll_v(dest, temp, 0); + la_xvmulwev_w_h(even, src1, src2); + la_xvmulwod_w_h(odd, src1, src2); + la_xvadd_w(dest, even, odd); + } } return true; } @@ -3788,29 +3808,13 @@ bool translate_vpmaddubsw(IR1_INST * pir1) { IR2_OPND src1 = load_freg128_from_ir1(opnd1); IR2_OPND src2 = load_freg128_from_ir1(opnd2); - IR2_OPND temp1 = ra_alloc_ftemp(); - IR2_OPND temp2 = ra_alloc_ftemp(); - IR2_OPND temp3 = ra_alloc_ftemp(); - IR2_OPND temp4 = ra_alloc_ftemp(); - IR2_OPND temp5 = ra_alloc_ftemp(); - IR2_OPND itmp = ra_alloc_itemp(); - /* unsigned src1 * signed src2 */ - la_vreplgr2vr_d(temp1, zero_ir2_opnd); - la_vabsd_b(temp3, src2, temp1); - la_vmaddwev_h_bu(temp1, src1, temp3); - la_vreplgr2vr_d(temp2, zero_ir2_opnd); - la_vmaddwod_h_bu(temp2, src1, temp3); - - la_ori(itmp, zero_ir2_opnd, 0x1); - la_vreplgr2vr_b(temp3, itmp); - la_vsigncov_b(temp4, src2, temp3); - - la_vmulwev_h_b(temp5, temp4, temp3); - la_vmulwod_h_b(temp3, temp4, temp3); - - la_vmul_h(temp1, temp1, temp5); - la_vmul_h(temp2, temp2, temp3); - la_vsadd_h(dest, temp2, temp1); + IR2_OPND even = ra_alloc_ftemp(); + IR2_OPND odd = ra_alloc_ftemp(); + + /* Unsigned src1 bytes times signed src2 bytes, pairwise saturated. */ + la_vmulwev_h_bu_b(even, src1, src2); + la_vmulwod_h_bu_b(odd, src1, src2); + la_vsadd_h(dest, even, odd); set_high128_xreg_to_zero(dest); @@ -3818,29 +3822,12 @@ bool translate_vpmaddubsw(IR1_INST * pir1) { IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src1 = load_freg256_from_ir1(opnd1); IR2_OPND src2 = load_freg256_from_ir1(opnd2); - IR2_OPND temp1 = ra_alloc_ftemp(); - IR2_OPND temp2 = ra_alloc_ftemp(); - IR2_OPND temp3 = ra_alloc_ftemp(); - IR2_OPND temp4 = ra_alloc_ftemp(); - IR2_OPND temp5 = ra_alloc_ftemp(); - IR2_OPND itmp = ra_alloc_itemp(); - /* unsigned src1 * signed src2 */ - la_xvreplgr2vr_d(temp1, zero_ir2_opnd); - la_xvabsd_b(temp3, src2, temp1); - la_xvmaddwev_h_bu(temp1, src1, temp3); - la_xvreplgr2vr_d(temp2, zero_ir2_opnd); - la_xvmaddwod_h_bu(temp2, src1, temp3); - - la_ori(itmp, zero_ir2_opnd, 0x1); - la_xvreplgr2vr_b(temp3, itmp); - la_xvsigncov_b(temp4, src2, temp3); - - la_xvmulwev_h_b(temp5, temp4, temp3); - la_xvmulwod_h_b(temp3, temp4, temp3); + IR2_OPND even = ra_alloc_ftemp(); + IR2_OPND odd = ra_alloc_ftemp(); - la_xvmul_h(temp1, temp1, temp5); - la_xvmul_h(temp2, temp2, temp3); - la_xvsadd_h(dest, temp2, temp1); + la_xvmulwev_h_bu_b(even, src1, src2); + la_xvmulwod_h_bu_b(odd, src1, src2); + la_xvsadd_h(dest, even, odd); } return true; } @@ -4107,15 +4094,13 @@ bool translate_vpshufd(IR1_INST * pir1) { IR2_OPND dest = load_freg128_from_ir1(opnd0); IR2_OPND src1 = load_freg128_from_ir1(opnd1); uint8_t imm = ir1_opnd_uimm(opnd2); - la_xvori_b(dest, src1, 0x00); - la_vpermi_w(dest, src1, imm); + la_xvshuf4i_w(dest, src1, imm); set_high128_xreg_to_zero(dest); } else { IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src1 = load_freg256_from_ir1(opnd1); uint8_t imm = ir1_opnd_uimm(opnd2); - la_xvori_b(dest, src1, 0x00); - la_xvpermi_w(dest, src1, imm); + la_xvshuf4i_w(dest, src1, imm); } return true; } @@ -4606,22 +4591,10 @@ bool translate_vpmulhrsw(IR1_INST * pir1) { IR2_OPND src2 = load_freg128_from_ir1(opnd2); IR2_OPND temp1 = ra_alloc_ftemp(); IR2_OPND temp2 = ra_alloc_ftemp(); - IR2_OPND temp3 = ra_alloc_ftemp(); la_vmulwev_w_h(temp1, src1, src2); la_vmulwod_w_h(temp2, src1, src2); - - la_vsrai_w(temp1, temp1, 0xe); - la_vsrai_w(temp2, temp2, 0xe); - - la_vandi_b(temp3, temp3, 0x0); - la_vbitseti_w(temp3, temp3, 0); - - la_vadd_w(temp1, temp1, temp3); - la_vadd_w(temp2, temp2, temp3); - - la_vsrai_w(temp1, temp1, 0x1); - la_vsrai_w(temp2, temp2, 0x1); - + la_vsrari_w(temp1, temp1, 15); + la_vsrari_w(temp2, temp2, 15); la_vpackev_h(dest, temp2, temp1); set_high128_xreg_to_zero(dest); @@ -4632,22 +4605,10 @@ bool translate_vpmulhrsw(IR1_INST * pir1) { IR2_OPND src2 = load_freg256_from_ir1(opnd2); IR2_OPND temp1 = ra_alloc_ftemp(); IR2_OPND temp2 = ra_alloc_ftemp(); - IR2_OPND temp3 = ra_alloc_ftemp(); la_xvmulwev_w_h(temp1, src1, src2); la_xvmulwod_w_h(temp2, src1, src2); - - la_xvsrai_w(temp1, temp1, 0xe); - la_xvsrai_w(temp2, temp2, 0xe); - - la_xvandi_b(temp3, temp3, 0x0); - la_xvbitseti_w(temp3, temp3, 0); - - la_xvadd_w(temp1, temp1, temp3); - la_xvadd_w(temp2, temp2, temp3); - - la_xvsrai_w(temp1, temp1, 0x1); - la_xvsrai_w(temp2, temp2, 0x1); - + la_xvsrari_w(temp1, temp1, 15); + la_xvsrari_w(temp2, temp2, 15); la_xvpackev_h(dest, temp2, temp1); } @@ -4805,6 +4766,12 @@ bool translate_vpackssxx(IR1_INST * pir1) { IR2_OPND src1 = load_freg256_from_ir1(opnd1); IR2_OPND src2 = load_freg256_from_ir1(opnd2); IR2_OPND temp; + bool dest_is_src1 = ir1_opnd_base_reg_num(opnd0) == + ir1_opnd_base_reg_num(opnd1); + bool dest_is_src2 = (ir1_opnd_is_xmm(opnd2) || + ir1_opnd_is_ymm(opnd2)) && + ir1_opnd_base_reg_num(opnd0) == + ir1_opnd_base_reg_num(opnd2); IR2_INST * ( * cvt_inst)(IR2_OPND, IR2_OPND, int); switch (ir1_opcode(pir1)) { case dt_X86_INS_VPACKSSDW: @@ -4818,9 +4785,15 @@ bool translate_vpackssxx(IR1_INST * pir1) { lsassert(0); break; } - if (ir1_opnd_is_xmm(opnd2) || ir1_opnd_is_ymm(opnd2)) { + if (dest_is_src2) { + temp = dest; + } else if ((ir1_opnd_is_xmm(opnd2) || ir1_opnd_is_ymm(opnd2)) && + dest_is_src1) { temp = ra_alloc_ftemp(); la_xvori_b(temp, src2, 0); + } else if (ir1_opnd_is_xmm(opnd2) || ir1_opnd_is_ymm(opnd2)) { + temp = dest; + la_xvori_b(temp, src2, 0); } else { temp = src2; } @@ -4828,7 +4801,9 @@ bool translate_vpackssxx(IR1_INST * pir1) { if (ir1_opnd_is_xmm(opnd0)) { set_high128_xreg_to_zero(temp); } - la_xvori_b(dest, temp, 0); + if (temp._reg_num != dest._reg_num) { + la_xvori_b(dest, temp, 0); + } return true; } @@ -4844,13 +4819,18 @@ bool translate_vpshufhw(IR1_INST *pir1) IR1_OPND *opnd1 = ir1_get_opnd(pir1, 1); IR1_OPND *opnd2 = ir1_get_opnd(pir1, 2); + uint64_t imm8 = ir1_opnd_uimm(opnd2); IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src = load_freg256_from_ir1(opnd1); - IR2_OPND temp = ra_alloc_ftemp(); - uint64_t imm8 = ir1_opnd_uimm(opnd2); - la_xvshuf4i_h(temp, src, imm8); - la_xvshuf4i_d(temp, src, 0x66); - la_xvori_b(dest, temp, 0); + if (dest._reg_num != src._reg_num) { + la_xvshuf4i_h(dest, src, imm8); + la_xvshuf4i_d(dest, src, 0x66); + } else { + IR2_OPND temp = ra_alloc_ftemp(); + la_xvshuf4i_h(temp, src, imm8); + la_xvshuf4i_d(temp, src, 0x66); + la_xvori_b(dest, temp, 0); + } if(ir1_opnd_is_xmm(opnd0)){ set_high128_xreg_to_zero(dest); } @@ -4869,13 +4849,18 @@ bool translate_vpshuflw(IR1_INST *pir1) IR1_OPND *opnd1 = ir1_get_opnd(pir1, 1); IR1_OPND *opnd2 = ir1_get_opnd(pir1, 2); + uint64_t imm8 = ir1_opnd_uimm(opnd2); IR2_OPND dest = load_freg256_from_ir1(opnd0); IR2_OPND src = load_freg256_from_ir1(opnd1); - IR2_OPND temp = ra_alloc_ftemp(); - uint64_t imm8 = ir1_opnd_uimm(opnd2); - la_xvshuf4i_h(temp, src, imm8); - la_xvshuf4i_d(temp, src, 0xcc); - la_xvori_b(dest, temp, 0); + if (dest._reg_num != src._reg_num) { + la_xvshuf4i_h(dest, src, imm8); + la_xvshuf4i_d(dest, src, 0xcc); + } else { + IR2_OPND temp = ra_alloc_ftemp(); + la_xvshuf4i_h(temp, src, imm8); + la_xvshuf4i_d(temp, src, 0xcc); + la_xvori_b(dest, temp, 0); + } if(ir1_opnd_is_xmm(opnd0)){ set_high128_xreg_to_zero(dest); } @@ -6467,8 +6452,6 @@ bool translate_vpbroadcastb(IR1_INST *pir1) la_xvreplve0_b(dest, src); } else if (ir1_opnd_is_ymm(opnd0)) { la_xvreplve0_b(dest, src); - la_xvinsve0_d(dest, dest, 2); - la_xvinsve0_d(dest, dest, 3); } else { lsassert(0); } @@ -6503,8 +6486,6 @@ bool translate_vpbroadcastw(IR1_INST *pir1) la_xvreplve0_h(dest, src); } else if (ir1_opnd_is_ymm(opnd0)) { la_xvreplve0_h(dest, src); - la_xvinsve0_d(dest, dest, 2); - la_xvinsve0_d(dest, dest, 3); } else { lsassert(0); }