Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions target/i386/latx/translator/tr-avx-cvt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
53 changes: 21 additions & 32 deletions target/i386/latx/translator/tr-avx-lsx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions target/i386/latx/translator/tr-avx-shift.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
Loading