Commit 4240985a authored by Yujie Wang's avatar Yujie Wang Committed by V8 LUCI CQ

[riscv64] Add tests for RVV VI VF instructions

Implement `LiftoffAssembler::emit_i16x8_sconvert_i32x4` for riscv.
Add tests for rvv integer and floating-point instructions.
Add simulator support for rvv instructions, e.g. `vfmadd`, `vnclip`.
Fixed order of operands for `vfdiv.vv`.

Bug: v8:11976
Change-Id: I0691ac66771468533c5994be1fc8a86b09d3c738
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3225319Reviewed-by: 's avatarYahan Lu <yahan@iscas.ac.cn>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Yahan Lu <yahan@iscas.ac.cn>
Cr-Commit-Position: refs/heads/main@{#77595}
parent bddb7b02
......@@ -251,6 +251,7 @@ Yi Wang <wangyi8848@gmail.com>
Yong Wang <ccyongwang@tencent.com>
Youfeng Hao <ajihyf@gmail.com>
Yu Yin <xwafish@gmail.com>
Yujie Wang <hex6770@gmail.com>
Yuri Iozzelli <yuri@leaningtech.com>
Yusif Khudhur <yusif.khudhur@gmail.com>
Zac Hansen <xaxxon@gmail.com>
......
......@@ -1172,6 +1172,17 @@ void Assembler::GenInstrV(uint8_t funct6, Opcode opcode, Register rd,
emit(instr);
}
// OPFVV
void Assembler::GenInstrV(uint8_t funct6, Opcode opcode, FPURegister fd,
VRegister vs1, VRegister vs2, MaskType mask) {
DCHECK(opcode == OP_FVV);
Instr instr = (funct6 << kRvvFunct6Shift) | opcode | (mask << kRvvVmShift) |
((fd.code() & 0x1F) << kRvvVdShift) |
((vs1.code() & 0x1F) << kRvvVs1Shift) |
((vs2.code() & 0x1F) << kRvvVs2Shift);
emit(instr);
}
// OPIVX OPMVX
void Assembler::GenInstrV(uint8_t funct6, Opcode opcode, VRegister vd,
Register rs1, VRegister vs2, MaskType mask) {
......@@ -2561,6 +2572,26 @@ void Assembler::vrgather_vx(VRegister vd, VRegister vs2, Register rs1,
GenInstrV(funct6, OP_FVF, vd, fs1, vs2, mask); \
}
#define DEFINE_OPFVV_FMA(name, funct6) \
void Assembler::name##_vv(VRegister vd, VRegister vs1, VRegister vs2, \
MaskType mask) { \
GenInstrV(funct6, OP_FVV, vd, vs1, vs2, mask); \
}
#define DEFINE_OPFVF_FMA(name, funct6) \
void Assembler::name##_vf(VRegister vd, FPURegister fs1, VRegister vs2, \
MaskType mask) { \
GenInstrV(funct6, OP_FVF, vd, fs1, vs2, mask); \
}
void Assembler::vfmv_vf(VRegister vd, FPURegister fs1, MaskType mask) {
GenInstrV(VMV_FUNCT6, OP_FVF, vd, fs1, v0, mask);
}
void Assembler::vfmv_fs(FPURegister fd, VRegister vs2, MaskType mask) {
GenInstrV(VWFUNARY0_FUNCT6, OP_FVV, fd, v0, vs2, mask);
}
DEFINE_OPIVV(vadd, VADD_FUNCT6)
DEFINE_OPIVX(vadd, VADD_FUNCT6)
DEFINE_OPIVI(vadd, VADD_FUNCT6)
......@@ -2663,11 +2694,40 @@ DEFINE_OPFVV(vfsngjn, VFSGNJN_FUNCT6)
DEFINE_OPFVF(vfsngjn, VFSGNJN_FUNCT6)
DEFINE_OPFVV(vfsngjx, VFSGNJX_FUNCT6)
DEFINE_OPFVF(vfsngjx, VFSGNJX_FUNCT6)
// Vector Single-Width Floating-Point Fused Multiply-Add Instructions
DEFINE_OPFVV_FMA(vfmadd, VFMADD_FUNCT6)
DEFINE_OPFVF_FMA(vfmadd, VFMADD_FUNCT6)
DEFINE_OPFVV_FMA(vfmsub, VFMSUB_FUNCT6)
DEFINE_OPFVF_FMA(vfmsub, VFMSUB_FUNCT6)
DEFINE_OPFVV_FMA(vfmacc, VFMACC_FUNCT6)
DEFINE_OPFVF_FMA(vfmacc, VFMACC_FUNCT6)
DEFINE_OPFVV_FMA(vfmsac, VFMSAC_FUNCT6)
DEFINE_OPFVF_FMA(vfmsac, VFMSAC_FUNCT6)
DEFINE_OPFVV_FMA(vfnmadd, VFNMADD_FUNCT6)
DEFINE_OPFVF_FMA(vfnmadd, VFNMADD_FUNCT6)
DEFINE_OPFVV_FMA(vfnmsub, VFNMSUB_FUNCT6)
DEFINE_OPFVF_FMA(vfnmsub, VFNMSUB_FUNCT6)
DEFINE_OPFVV_FMA(vfnmacc, VFNMACC_FUNCT6)
DEFINE_OPFVF_FMA(vfnmacc, VFNMACC_FUNCT6)
DEFINE_OPFVV_FMA(vfnmsac, VFNMSAC_FUNCT6)
DEFINE_OPFVF_FMA(vfnmsac, VFNMSAC_FUNCT6)
// Vector Narrowing Fixed-Point Clip Instructions
DEFINE_OPIVV(vnclip, VNCLIP_FUNCT6)
DEFINE_OPIVX(vnclip, VNCLIP_FUNCT6)
DEFINE_OPIVI(vnclip, VNCLIP_FUNCT6)
DEFINE_OPIVV(vnclipu, VNCLIPU_FUNCT6)
DEFINE_OPIVX(vnclipu, VNCLIPU_FUNCT6)
DEFINE_OPIVI(vnclipu, VNCLIPU_FUNCT6)
#undef DEFINE_OPIVI
#undef DEFINE_OPIVV
#undef DEFINE_OPIVX
#undef DEFINE_OPFVV
#undef DEFINE_OPFVF
#undef DEFINE_OPFVV_FMA
#undef DEFINE_OPFVF_FMA
void Assembler::vsetvli(Register rd, Register rs1, VSew vsew, Vlmul vlmul,
TailAgnosticType tail, MaskAgnosticType mask) {
......
......@@ -746,6 +746,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void vmadc_vx(VRegister vd, Register rs1, VRegister vs2);
void vmadc_vi(VRegister vd, uint8_t imm5, VRegister vs2);
void vfmv_vf(VRegister vd, FPURegister fs1, MaskType mask = NoMask);
void vfmv_fs(FPURegister fd, VRegister vs2, MaskType mask = NoMask);
#define DEFINE_OPIVV(name, funct6) \
void name##_vv(VRegister vd, VRegister vs2, VRegister vs1, \
MaskType mask = NoMask);
......@@ -774,6 +777,14 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void name##_vf(VRegister vd, VRegister vs2, FPURegister fs1, \
MaskType mask = NoMask);
#define DEFINE_OPFVV_FMA(name, funct6) \
void name##_vv(VRegister vd, VRegister vs1, VRegister vs2, \
MaskType mask = NoMask);
#define DEFINE_OPFVF_FMA(name, funct6) \
void name##_vf(VRegister vd, FPURegister fs1, VRegister vs2, \
MaskType mask = NoMask);
DEFINE_OPIVV(vadd, VADD_FUNCT6)
DEFINE_OPIVX(vadd, VADD_FUNCT6)
DEFINE_OPIVI(vadd, VADD_FUNCT6)
......@@ -881,6 +892,32 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
DEFINE_OPFVV(vfsngjx, VFSGNJX_FUNCT6)
DEFINE_OPFVF(vfsngjx, VFSGNJX_FUNCT6)
// Vector Single-Width Floating-Point Fused Multiply-Add Instructions
DEFINE_OPFVV_FMA(vfmadd, VFMADD_FUNCT6)
DEFINE_OPFVF_FMA(vfmadd, VFMADD_FUNCT6)
DEFINE_OPFVV_FMA(vfmsub, VFMSUB_FUNCT6)
DEFINE_OPFVF_FMA(vfmsub, VFMSUB_FUNCT6)
DEFINE_OPFVV_FMA(vfmacc, VFMACC_FUNCT6)
DEFINE_OPFVF_FMA(vfmacc, VFMACC_FUNCT6)
DEFINE_OPFVV_FMA(vfmsac, VFMSAC_FUNCT6)
DEFINE_OPFVF_FMA(vfmsac, VFMSAC_FUNCT6)
DEFINE_OPFVV_FMA(vfnmadd, VFNMADD_FUNCT6)
DEFINE_OPFVF_FMA(vfnmadd, VFNMADD_FUNCT6)
DEFINE_OPFVV_FMA(vfnmsub, VFNMSUB_FUNCT6)
DEFINE_OPFVF_FMA(vfnmsub, VFNMSUB_FUNCT6)
DEFINE_OPFVV_FMA(vfnmacc, VFNMACC_FUNCT6)
DEFINE_OPFVF_FMA(vfnmacc, VFNMACC_FUNCT6)
DEFINE_OPFVV_FMA(vfnmsac, VFNMSAC_FUNCT6)
DEFINE_OPFVF_FMA(vfnmsac, VFNMSAC_FUNCT6)
// Vector Narrowing Fixed-Point Clip Instructions
DEFINE_OPIVV(vnclip, VNCLIP_FUNCT6)
DEFINE_OPIVX(vnclip, VNCLIP_FUNCT6)
DEFINE_OPIVI(vnclip, VNCLIP_FUNCT6)
DEFINE_OPIVV(vnclipu, VNCLIPU_FUNCT6)
DEFINE_OPIVX(vnclipu, VNCLIPU_FUNCT6)
DEFINE_OPIVI(vnclipu, VNCLIPU_FUNCT6)
#undef DEFINE_OPIVI
#undef DEFINE_OPIVV
#undef DEFINE_OPIVX
......@@ -888,6 +925,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
#undef DEFINE_OPMVX
#undef DEFINE_OPFVV
#undef DEFINE_OPFVF
#undef DEFINE_OPFVV_FMA
#undef DEFINE_OPFVF_FMA
#define DEFINE_VFUNARY(name, funct6, vs1) \
void name(VRegister vd, VRegister vs2, MaskType mask = NoMask) { \
......@@ -1497,6 +1536,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// OPMVV OPFVV
void GenInstrV(uint8_t funct6, Opcode opcode, Register rd, VRegister vs1,
VRegister vs2, MaskType mask = NoMask);
// OPFVV
void GenInstrV(uint8_t funct6, Opcode opcode, FPURegister fd, VRegister vs1,
VRegister vs2, MaskType mask = NoMask);
// OPIVX OPMVX
void GenInstrV(uint8_t funct6, Opcode opcode, VRegister vd, Register rs1,
......
......@@ -774,6 +774,7 @@ enum Opcode : uint32_t {
RO_V_VMV_VI = OP_IVI | (VMV_FUNCT6 << kRvvFunct6Shift),
RO_V_VMV_VV = OP_IVV | (VMV_FUNCT6 << kRvvFunct6Shift),
RO_V_VMV_VX = OP_IVX | (VMV_FUNCT6 << kRvvFunct6Shift),
RO_V_VFMV_VF = OP_FVF | (VMV_FUNCT6 << kRvvFunct6Shift),
RO_V_VMERGE_VI = RO_V_VMV_VI,
RO_V_VMERGE_VV = RO_V_VMV_VV,
......@@ -849,6 +850,9 @@ enum Opcode : uint32_t {
RO_V_VWXUNARY0 = OP_MVV | (VWXUNARY0_FUNCT6 << kRvvFunct6Shift),
RO_V_VRXUNARY0 = OP_MVX | (VRXUNARY0_FUNCT6 << kRvvFunct6Shift),
VWFUNARY0_FUNCT6 = 0b010000,
RO_V_VFMV_FS = OP_FVV | (VWFUNARY0_FUNCT6 << kRvvFunct6Shift),
VREDMAXU_FUNCT6 = 0b000110,
RO_V_VREDMAXU = OP_MVV | (VREDMAXU_FUNCT6 << kRvvFunct6Shift),
VREDMAX_FUNCT6 = 0b000111,
......@@ -929,6 +933,48 @@ enum Opcode : uint32_t {
VFSGNJX_FUNCT6 = 0b001010,
RO_V_VFSGNJX_VV = OP_FVV | (VFSGNJX_FUNCT6 << kRvvFunct6Shift),
RO_V_VFSGNJX_VF = OP_FVF | (VFSGNJX_FUNCT6 << kRvvFunct6Shift),
VFMADD_FUNCT6 = 0b101000,
RO_V_VFMADD_VV = OP_FVV | (VFMADD_FUNCT6 << kRvvFunct6Shift),
RO_V_VFMADD_VF = OP_FVF | (VFMADD_FUNCT6 << kRvvFunct6Shift),
VFNMADD_FUNCT6 = 0b101001,
RO_V_VFNMADD_VV = OP_FVV | (VFNMADD_FUNCT6 << kRvvFunct6Shift),
RO_V_VFNMADD_VF = OP_FVF | (VFNMADD_FUNCT6 << kRvvFunct6Shift),
VFMSUB_FUNCT6 = 0b101010,
RO_V_VFMSUB_VV = OP_FVV | (VFMSUB_FUNCT6 << kRvvFunct6Shift),
RO_V_VFMSUB_VF = OP_FVF | (VFMSUB_FUNCT6 << kRvvFunct6Shift),
VFNMSUB_FUNCT6 = 0b101011,
RO_V_VFNMSUB_VV = OP_FVV | (VFNMSUB_FUNCT6 << kRvvFunct6Shift),
RO_V_VFNMSUB_VF = OP_FVF | (VFNMSUB_FUNCT6 << kRvvFunct6Shift),
VFMACC_FUNCT6 = 0b101100,
RO_V_VFMACC_VV = OP_FVV | (VFMACC_FUNCT6 << kRvvFunct6Shift),
RO_V_VFMACC_VF = OP_FVF | (VFMACC_FUNCT6 << kRvvFunct6Shift),
VFNMACC_FUNCT6 = 0b101101,
RO_V_VFNMACC_VV = OP_FVV | (VFNMACC_FUNCT6 << kRvvFunct6Shift),
RO_V_VFNMACC_VF = OP_FVF | (VFNMACC_FUNCT6 << kRvvFunct6Shift),
VFMSAC_FUNCT6 = 0b101110,
RO_V_VFMSAC_VV = OP_FVV | (VFMSAC_FUNCT6 << kRvvFunct6Shift),
RO_V_VFMSAC_VF = OP_FVF | (VFMSAC_FUNCT6 << kRvvFunct6Shift),
VFNMSAC_FUNCT6 = 0b101111,
RO_V_VFNMSAC_VV = OP_FVV | (VFNMSAC_FUNCT6 << kRvvFunct6Shift),
RO_V_VFNMSAC_VF = OP_FVF | (VFNMSAC_FUNCT6 << kRvvFunct6Shift),
VNCLIP_FUNCT6 = 0b101111,
RO_V_VNCLIP_WV = OP_IVV | (VNCLIP_FUNCT6 << kRvvFunct6Shift),
RO_V_VNCLIP_WX = OP_IVX | (VNCLIP_FUNCT6 << kRvvFunct6Shift),
RO_V_VNCLIP_WI = OP_IVI | (VNCLIP_FUNCT6 << kRvvFunct6Shift),
VNCLIPU_FUNCT6 = 0b101110,
RO_V_VNCLIPU_WV = OP_IVV | (VNCLIPU_FUNCT6 << kRvvFunct6Shift),
RO_V_VNCLIPU_WX = OP_IVX | (VNCLIPU_FUNCT6 << kRvvFunct6Shift),
RO_V_VNCLIPU_WI = OP_IVI | (VNCLIPU_FUNCT6 << kRvvFunct6Shift),
};
// ----- Emulated conditions.
......
......@@ -1986,6 +1986,12 @@ void Decoder::DecodeRvvIVV(Instruction* instr) {
UNREACHABLE();
}
break;
case RO_V_VNCLIP_WV:
Format(instr, "vnclip.wv 'vd, 'vs2, 'vs1");
break;
case RO_V_VNCLIPU_WV:
Format(instr, "vnclipu.wv 'vd, 'vs2, 'vs1");
break;
default:
UNSUPPORTED_RISCV();
break;
......@@ -2067,6 +2073,12 @@ void Decoder::DecodeRvvIVI(Instruction* instr) {
UNREACHABLE();
}
break;
case RO_V_VNCLIP_WI:
Format(instr, "vnclip.wi 'vd, 'vs2, 'uimm5");
break;
case RO_V_VNCLIPU_WI:
Format(instr, "vnclipu.wi 'vd, 'vs2, 'uimm5");
break;
default:
UNSUPPORTED_RISCV();
break;
......@@ -2172,6 +2184,12 @@ void Decoder::DecodeRvvIVX(Instruction* instr) {
case RO_V_VSRL_VX:
Format(instr, "vsrl.vx 'vd, 'vs2, 'rs1");
break;
case RO_V_VNCLIP_WX:
Format(instr, "vnclip.wx 'vd, 'vs2, 'rs1");
break;
case RO_V_VNCLIPU_WX:
Format(instr, "vnclipu.wx 'vd, 'vs2, 'rs1");
break;
default:
UNSUPPORTED_RISCV();
break;
......@@ -2303,6 +2321,37 @@ void Decoder::DecodeRvvFVV(Instruction* instr) {
case RO_V_VFMUL_VV:
Format(instr, "vfmul.vv 'vd, 'vs2, 'vs1'vm");
break;
case RO_V_VFMADD_VV:
Format(instr, "vfmadd.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFNMADD_VV:
Format(instr, "vfnmadd.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFMSUB_VV:
Format(instr, "vfmsub.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFNMSUB_VV:
Format(instr, "vfnmsub.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFMACC_VV:
Format(instr, "vfmacc.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFNMACC_VV:
Format(instr, "vfnmacc.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFMSAC_VV:
Format(instr, "vfmsac.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFNMSAC_VV:
Format(instr, "vfnmsac.vv 'vd, 'vs1, 'vs2'vm");
break;
case RO_V_VFMV_FS:
if (instr->Vs1Value() == 0x0) {
Format(instr, "vfmv.f.s 'fd, 'vs2");
} else {
UNSUPPORTED_RISCV();
}
break;
default:
UNSUPPORTED_RISCV();
break;
......@@ -2321,6 +2370,33 @@ void Decoder::DecodeRvvFVF(Instruction* instr) {
case RO_V_VFSGNJX_VF:
Format(instr, "vfsgnjn.vf 'vd, 'vs2, 'fs1'vm");
break;
case RO_V_VFMV_VF:
Format(instr, "vfmv.v.f 'vd, 'fs1");
break;
case RO_V_VFMADD_VF:
Format(instr, "vfmadd.vf 'vd, 'fs1, 'vs2'vm");
break;
case RO_V_VFNMADD_VF:
Format(instr, "vfnmadd.vf 'vd, 'fs1, 'vs2'vm");
break;
case RO_V_VFMSUB_VF:
Format(instr, "vfmsub.vf 'vd, 'fs1, 'vs2'vm");
break;
case RO_V_VFNMSUB_VF:
Format(instr, "vfnmsub.vf 'vd, 'fs1, 'vs2'vm");
break;
case RO_V_VFMACC_VF:
Format(instr, "vfmacc.vf 'vd, 'fs1, 'vs2'vm");
break;
case RO_V_VFNMACC_VF:
Format(instr, "vfnmacc.vf 'vd, 'fs1, 'vs2'vm");
break;
case RO_V_VFMSAC_VF:
Format(instr, "vfmsac.vf 'vd, 'fs1, 'vs2'vm");
break;
case RO_V_VFNMSAC_VF:
Format(instr, "vfnmsac.vf 'vd, 'fs1, 'vs2'vm");
break;
default:
UNSUPPORTED_RISCV();
break;
......@@ -2345,7 +2421,7 @@ void Decoder::DecodeVType(Instruction* instr) {
DecodeRvvIVX(instr);
return;
case OP_FVF:
UNSUPPORTED_RISCV();
DecodeRvvFVF(instr);
return;
case OP_MVX:
DecodeRvvMVX(instr);
......
This diff is collapsed.
......@@ -762,6 +762,20 @@ class Simulator : public SimulatorBase {
type_usew_t<x>::type uimm5 = (type_usew_t<x>::type)(instr_.RvvUimm5()); \
type_usew_t<x>::type vs2 = Rvvelt<type_usew_t<x>::type>(rvv_vs2_reg(), i);
#define VN_PARAMS(x) \
constexpr int half_x = x >> 1; \
type_sew_t<half_x>::type& vd = \
Rvvelt<type_sew_t<half_x>::type>(rvv_vd_reg(), i, true); \
type_sew_t<x>::type uimm5 = (type_sew_t<x>::type)(instr_.RvvUimm5()); \
type_sew_t<x>::type vs2 = Rvvelt<type_sew_t<x>::type>(rvv_vs2_reg(), i);
#define VN_UPARAMS(x) \
constexpr int half_x = x >> 1; \
type_usew_t<half_x>::type& vd = \
Rvvelt<type_usew_t<half_x>::type>(rvv_vd_reg(), i, true); \
type_usew_t<x>::type uimm5 = (type_usew_t<x>::type)(instr_.RvvUimm5()); \
type_sew_t<x>::type vs2 = Rvvelt<type_sew_t<x>::type>(rvv_vs2_reg(), i);
#define VXI_PARAMS(x) \
type_sew_t<x>::type& vd = \
Rvvelt<type_sew_t<x>::type>(rvv_vd_reg(), i, true); \
......@@ -873,9 +887,24 @@ class Simulator : public SimulatorBase {
vlenb_ = value;
}
template <typename T, typename Func>
inline T CanonicalizeFPUOpFMA(Func fn, T dst, T src1, T src2) {
static_assert(std::is_floating_point<T>::value);
auto alu_out = fn(dst, src1, src2);
// if any input or result is NaN, the result is quiet_NaN
if (std::isnan(alu_out) || std::isnan(src1) || std::isnan(src2) ||
std::isnan(dst)) {
// signaling_nan sets kInvalidOperation bit
if (isSnan(alu_out) || isSnan(src1) || isSnan(src2) || isSnan(dst))
set_fflags(kInvalidOperation);
alu_out = std::numeric_limits<T>::quiet_NaN();
}
return alu_out;
}
template <typename T, typename Func>
inline T CanonicalizeFPUOp3(Func fn) {
DCHECK(std::is_floating_point<T>::value);
static_assert(std::is_floating_point<T>::value);
T src1 = std::is_same<float, T>::value ? frs1() : drs1();
T src2 = std::is_same<float, T>::value ? frs2() : drs2();
T src3 = std::is_same<float, T>::value ? frs3() : drs3();
......@@ -893,7 +922,7 @@ class Simulator : public SimulatorBase {
template <typename T, typename Func>
inline T CanonicalizeFPUOp2(Func fn) {
DCHECK(std::is_floating_point<T>::value);
static_assert(std::is_floating_point<T>::value);
T src1 = std::is_same<float, T>::value ? frs1() : drs1();
T src2 = std::is_same<float, T>::value ? frs2() : drs2();
auto alu_out = fn(src1, src2);
......@@ -909,7 +938,7 @@ class Simulator : public SimulatorBase {
template <typename T, typename Func>
inline T CanonicalizeFPUOp1(Func fn) {
DCHECK(std::is_floating_point<T>::value);
static_assert(std::is_floating_point<T>::value);
T src1 = std::is_same<float, T>::value ? frs1() : drs1();
auto alu_out = fn(src1);
// if any input or result is NaN, the result is quiet_NaN
......
......@@ -2767,13 +2767,39 @@ void LiftoffAssembler::emit_i8x16_uconvert_i16x8(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_sconvert_i32x4(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "emit_i16x8_sconvert_i32x4");
VRegister dst_v = dst.fp().toV();
VRegister lhs_v = lhs.fp().toV();
VRegister rhs_v = rhs.fp().toV();
VU.set(kScratchReg, E32, m2);
VRegister tmp_lo =
GetUnusedRegister(kFpReg, LiftoffRegList::ForRegs(lhs, rhs)).fp().toV();
VRegister tmp_hi = VRegister::from_code(tmp_lo.code() + 1);
VU.set(kScratchReg, E32, m1);
vmv_vv(tmp_lo, rhs_v);
vmv_vv(tmp_hi, lhs_v);
VU.set(kScratchReg, E16, m1);
VU.set(RoundingMode::RNE);
vnclip_vi(dst_v, tmp_lo, 0);
}
void LiftoffAssembler::emit_i16x8_uconvert_i32x4(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "emit_i16x8_uconvert_i32x4");
VRegister dst_v = dst.fp().toV();
VRegister lhs_v = lhs.fp().toV();
VRegister rhs_v = rhs.fp().toV();
VU.set(kScratchReg, E32, m2);
VRegister tmp_lo =
GetUnusedRegister(kFpReg, LiftoffRegList::ForRegs(lhs, rhs)).fp().toV();
VRegister tmp_hi = VRegister::from_code(tmp_lo.code() + 1);
VU.set(kScratchReg, E32, m1);
vmv_vv(tmp_lo, rhs_v);
vmv_vv(tmp_hi, lhs_v);
VU.set(kScratchReg, E32, m2);
vmax_vx(tmp_lo, tmp_lo, zero_reg);
VU.set(kScratchReg, E16, m1);
VU.set(RoundingMode::RNE);
vnclipu_vi(dst_v, tmp_lo, 0);
}
void LiftoffAssembler::emit_i16x8_sconvert_i8x16_low(LiftoffRegister dst,
......@@ -2863,7 +2889,6 @@ void LiftoffAssembler::emit_i16x8_extadd_pairwise_i8x16_u(LiftoffRegister dst,
bailout(kSimd, "i16x8.extadd_pairwise_i8x16_u");
}
void LiftoffAssembler::emit_i32x4_abs(LiftoffRegister dst,
LiftoffRegister src) {
VU.set(kScratchReg, E32, m1);
......
This diff is collapsed.
......@@ -580,6 +580,40 @@ TEST(RVV) {
COMPARE(vadc_vv(v7, v9, v6), "406483d7 vadc.vvm v7, v6, v9");
COMPARE(vadc_vx(v7, t6, v9), "409fc3d7 vadc.vxm v7, v9, t6");
COMPARE(vadc_vi(v7, 5, v9), "4092b3d7 vadc.vim v7, v9, 5");
COMPARE(vfadd_vv(v17, v14, v28), "02ee18d7 vfadd.vv v17, v14, v28");
COMPARE(vfsub_vv(v17, v14, v28), "0aee18d7 vfsub.vv v17, v14, v28");
COMPARE(vfmul_vv(v17, v14, v28), "92ee18d7 vfmul.vv v17, v14, v28");
COMPARE(vfdiv_vv(v17, v14, v28), "82ee18d7 vfdiv.vv v17, v14, v28");
COMPARE(vfmv_vf(v17, fa5), "5e07d8d7 vfmv.v.f v17, fa5");
COMPARE(vfmv_fs(fa5, v17), "431017d7 vfmv.f.s fa5, v17");
// Vector Single-Width Floating-Point Fused Multiply-Add Instructions
COMPARE(vfmadd_vv(v17, v14, v28), "a3c718d7 vfmadd.vv v17, v14, v28");
COMPARE(vfnmadd_vv(v17, v14, v28), "a7c718d7 vfnmadd.vv v17, v14, v28");
COMPARE(vfmsub_vv(v17, v14, v28), "abc718d7 vfmsub.vv v17, v14, v28");
COMPARE(vfnmsub_vv(v17, v14, v28), "afc718d7 vfnmsub.vv v17, v14, v28");
COMPARE(vfmacc_vv(v17, v14, v28), "b3c718d7 vfmacc.vv v17, v14, v28");
COMPARE(vfnmacc_vv(v17, v14, v28), "b7c718d7 vfnmacc.vv v17, v14, v28");
COMPARE(vfmsac_vv(v17, v14, v28), "bbc718d7 vfmsac.vv v17, v14, v28");
COMPARE(vfnmsac_vv(v17, v14, v28), "bfc718d7 vfnmsac.vv v17, v14, v28");
COMPARE(vfmadd_vf(v17, fa5, v28), "a3c7d8d7 vfmadd.vf v17, fa5, v28");
COMPARE(vfnmadd_vf(v17, fa5, v28), "a7c7d8d7 vfnmadd.vf v17, fa5, v28");
COMPARE(vfmsub_vf(v17, fa5, v28), "abc7d8d7 vfmsub.vf v17, fa5, v28");
COMPARE(vfnmsub_vf(v17, fa5, v28), "afc7d8d7 vfnmsub.vf v17, fa5, v28");
COMPARE(vfmacc_vf(v17, fa5, v28), "b3c7d8d7 vfmacc.vf v17, fa5, v28");
COMPARE(vfnmacc_vf(v17, fa5, v28), "b7c7d8d7 vfnmacc.vf v17, fa5, v28");
COMPARE(vfmsac_vf(v17, fa5, v28), "bbc7d8d7 vfmsac.vf v17, fa5, v28");
COMPARE(vfnmsac_vf(v17, fa5, v28), "bfc7d8d7 vfnmsac.vf v17, fa5, v28");
// Vector Narrowing Fixed-Point Clip Instructions
COMPARE(vnclip_vi(v17, v14, 5), "bee2b8d7 vnclip.wi v17, v14, 5");
COMPARE(vnclip_vx(v17, v14, a5), "bee7c8d7 vnclip.wx v17, v14, a5");
COMPARE(vnclip_vv(v17, v14, v28), "beee08d7 vnclip.wv v17, v14, v28");
COMPARE(vnclipu_vi(v17, v14, 5), "bae2b8d7 vnclipu.wi v17, v14, 5");
COMPARE(vnclipu_vx(v17, v14, a5), "bae7c8d7 vnclipu.wx v17, v14, a5");
COMPARE(vnclipu_vv(v17, v14, v28), "baee08d7 vnclipu.wv v17, v14, v28");
VERIFY_RUN();
}
#endif
......
......@@ -328,6 +328,11 @@ GeneratedCode<Signature> AssembleCode(Func assemble) {
return GeneratedCode<Signature>::FromCode(*AssembleCodeImpl(assemble));
}
template <typename T>
T UseCanonicalNan(T x) {
return isnan(x) ? std::numeric_limits<T>::quiet_NaN() : x;
}
} // namespace internal
} // namespace v8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment