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> ...@@ -251,6 +251,7 @@ Yi Wang <wangyi8848@gmail.com>
Yong Wang <ccyongwang@tencent.com> Yong Wang <ccyongwang@tencent.com>
Youfeng Hao <ajihyf@gmail.com> Youfeng Hao <ajihyf@gmail.com>
Yu Yin <xwafish@gmail.com> Yu Yin <xwafish@gmail.com>
Yujie Wang <hex6770@gmail.com>
Yuri Iozzelli <yuri@leaningtech.com> Yuri Iozzelli <yuri@leaningtech.com>
Yusif Khudhur <yusif.khudhur@gmail.com> Yusif Khudhur <yusif.khudhur@gmail.com>
Zac Hansen <xaxxon@gmail.com> Zac Hansen <xaxxon@gmail.com>
......
...@@ -1172,6 +1172,17 @@ void Assembler::GenInstrV(uint8_t funct6, Opcode opcode, Register rd, ...@@ -1172,6 +1172,17 @@ void Assembler::GenInstrV(uint8_t funct6, Opcode opcode, Register rd,
emit(instr); 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 // OPIVX OPMVX
void Assembler::GenInstrV(uint8_t funct6, Opcode opcode, VRegister vd, void Assembler::GenInstrV(uint8_t funct6, Opcode opcode, VRegister vd,
Register rs1, VRegister vs2, MaskType mask) { Register rs1, VRegister vs2, MaskType mask) {
...@@ -2561,6 +2572,26 @@ void Assembler::vrgather_vx(VRegister vd, VRegister vs2, Register rs1, ...@@ -2561,6 +2572,26 @@ void Assembler::vrgather_vx(VRegister vd, VRegister vs2, Register rs1,
GenInstrV(funct6, OP_FVF, vd, fs1, vs2, mask); \ 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_OPIVV(vadd, VADD_FUNCT6)
DEFINE_OPIVX(vadd, VADD_FUNCT6) DEFINE_OPIVX(vadd, VADD_FUNCT6)
DEFINE_OPIVI(vadd, VADD_FUNCT6) DEFINE_OPIVI(vadd, VADD_FUNCT6)
...@@ -2663,11 +2694,40 @@ DEFINE_OPFVV(vfsngjn, VFSGNJN_FUNCT6) ...@@ -2663,11 +2694,40 @@ DEFINE_OPFVV(vfsngjn, VFSGNJN_FUNCT6)
DEFINE_OPFVF(vfsngjn, VFSGNJN_FUNCT6) DEFINE_OPFVF(vfsngjn, VFSGNJN_FUNCT6)
DEFINE_OPFVV(vfsngjx, VFSGNJX_FUNCT6) DEFINE_OPFVV(vfsngjx, VFSGNJX_FUNCT6)
DEFINE_OPFVF(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_OPIVI
#undef DEFINE_OPIVV #undef DEFINE_OPIVV
#undef DEFINE_OPIVX #undef DEFINE_OPIVX
#undef DEFINE_OPFVV #undef DEFINE_OPFVV
#undef DEFINE_OPFVF #undef DEFINE_OPFVF
#undef DEFINE_OPFVV_FMA
#undef DEFINE_OPFVF_FMA
void Assembler::vsetvli(Register rd, Register rs1, VSew vsew, Vlmul vlmul, void Assembler::vsetvli(Register rd, Register rs1, VSew vsew, Vlmul vlmul,
TailAgnosticType tail, MaskAgnosticType mask) { TailAgnosticType tail, MaskAgnosticType mask) {
......
...@@ -746,6 +746,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -746,6 +746,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void vmadc_vx(VRegister vd, Register rs1, VRegister vs2); void vmadc_vx(VRegister vd, Register rs1, VRegister vs2);
void vmadc_vi(VRegister vd, uint8_t imm5, 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) \ #define DEFINE_OPIVV(name, funct6) \
void name##_vv(VRegister vd, VRegister vs2, VRegister vs1, \ void name##_vv(VRegister vd, VRegister vs2, VRegister vs1, \
MaskType mask = NoMask); MaskType mask = NoMask);
...@@ -774,6 +777,14 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -774,6 +777,14 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void name##_vf(VRegister vd, VRegister vs2, FPURegister fs1, \ void name##_vf(VRegister vd, VRegister vs2, FPURegister fs1, \
MaskType mask = NoMask); 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_OPIVV(vadd, VADD_FUNCT6)
DEFINE_OPIVX(vadd, VADD_FUNCT6) DEFINE_OPIVX(vadd, VADD_FUNCT6)
DEFINE_OPIVI(vadd, VADD_FUNCT6) DEFINE_OPIVI(vadd, VADD_FUNCT6)
...@@ -881,6 +892,32 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -881,6 +892,32 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
DEFINE_OPFVV(vfsngjx, VFSGNJX_FUNCT6) DEFINE_OPFVV(vfsngjx, VFSGNJX_FUNCT6)
DEFINE_OPFVF(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_OPIVI
#undef DEFINE_OPIVV #undef DEFINE_OPIVV
#undef DEFINE_OPIVX #undef DEFINE_OPIVX
...@@ -888,6 +925,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -888,6 +925,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
#undef DEFINE_OPMVX #undef DEFINE_OPMVX
#undef DEFINE_OPFVV #undef DEFINE_OPFVV
#undef DEFINE_OPFVF #undef DEFINE_OPFVF
#undef DEFINE_OPFVV_FMA
#undef DEFINE_OPFVF_FMA
#define DEFINE_VFUNARY(name, funct6, vs1) \ #define DEFINE_VFUNARY(name, funct6, vs1) \
void name(VRegister vd, VRegister vs2, MaskType mask = NoMask) { \ void name(VRegister vd, VRegister vs2, MaskType mask = NoMask) { \
...@@ -1497,6 +1536,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -1497,6 +1536,9 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
// OPMVV OPFVV // OPMVV OPFVV
void GenInstrV(uint8_t funct6, Opcode opcode, Register rd, VRegister vs1, void GenInstrV(uint8_t funct6, Opcode opcode, Register rd, VRegister vs1,
VRegister vs2, MaskType mask = NoMask); VRegister vs2, MaskType mask = NoMask);
// OPFVV
void GenInstrV(uint8_t funct6, Opcode opcode, FPURegister fd, VRegister vs1,
VRegister vs2, MaskType mask = NoMask);
// OPIVX OPMVX // OPIVX OPMVX
void GenInstrV(uint8_t funct6, Opcode opcode, VRegister vd, Register rs1, void GenInstrV(uint8_t funct6, Opcode opcode, VRegister vd, Register rs1,
......
...@@ -774,6 +774,7 @@ enum Opcode : uint32_t { ...@@ -774,6 +774,7 @@ enum Opcode : uint32_t {
RO_V_VMV_VI = OP_IVI | (VMV_FUNCT6 << kRvvFunct6Shift), RO_V_VMV_VI = OP_IVI | (VMV_FUNCT6 << kRvvFunct6Shift),
RO_V_VMV_VV = OP_IVV | (VMV_FUNCT6 << kRvvFunct6Shift), RO_V_VMV_VV = OP_IVV | (VMV_FUNCT6 << kRvvFunct6Shift),
RO_V_VMV_VX = OP_IVX | (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_VI = RO_V_VMV_VI,
RO_V_VMERGE_VV = RO_V_VMV_VV, RO_V_VMERGE_VV = RO_V_VMV_VV,
...@@ -849,6 +850,9 @@ enum Opcode : uint32_t { ...@@ -849,6 +850,9 @@ enum Opcode : uint32_t {
RO_V_VWXUNARY0 = OP_MVV | (VWXUNARY0_FUNCT6 << kRvvFunct6Shift), RO_V_VWXUNARY0 = OP_MVV | (VWXUNARY0_FUNCT6 << kRvvFunct6Shift),
RO_V_VRXUNARY0 = OP_MVX | (VRXUNARY0_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, VREDMAXU_FUNCT6 = 0b000110,
RO_V_VREDMAXU = OP_MVV | (VREDMAXU_FUNCT6 << kRvvFunct6Shift), RO_V_VREDMAXU = OP_MVV | (VREDMAXU_FUNCT6 << kRvvFunct6Shift),
VREDMAX_FUNCT6 = 0b000111, VREDMAX_FUNCT6 = 0b000111,
...@@ -929,6 +933,48 @@ enum Opcode : uint32_t { ...@@ -929,6 +933,48 @@ enum Opcode : uint32_t {
VFSGNJX_FUNCT6 = 0b001010, VFSGNJX_FUNCT6 = 0b001010,
RO_V_VFSGNJX_VV = OP_FVV | (VFSGNJX_FUNCT6 << kRvvFunct6Shift), RO_V_VFSGNJX_VV = OP_FVV | (VFSGNJX_FUNCT6 << kRvvFunct6Shift),
RO_V_VFSGNJX_VF = OP_FVF | (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. // ----- Emulated conditions.
......
...@@ -1986,6 +1986,12 @@ void Decoder::DecodeRvvIVV(Instruction* instr) { ...@@ -1986,6 +1986,12 @@ void Decoder::DecodeRvvIVV(Instruction* instr) {
UNREACHABLE(); UNREACHABLE();
} }
break; 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: default:
UNSUPPORTED_RISCV(); UNSUPPORTED_RISCV();
break; break;
...@@ -2067,6 +2073,12 @@ void Decoder::DecodeRvvIVI(Instruction* instr) { ...@@ -2067,6 +2073,12 @@ void Decoder::DecodeRvvIVI(Instruction* instr) {
UNREACHABLE(); UNREACHABLE();
} }
break; 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: default:
UNSUPPORTED_RISCV(); UNSUPPORTED_RISCV();
break; break;
...@@ -2172,6 +2184,12 @@ void Decoder::DecodeRvvIVX(Instruction* instr) { ...@@ -2172,6 +2184,12 @@ void Decoder::DecodeRvvIVX(Instruction* instr) {
case RO_V_VSRL_VX: case RO_V_VSRL_VX:
Format(instr, "vsrl.vx 'vd, 'vs2, 'rs1"); Format(instr, "vsrl.vx 'vd, 'vs2, 'rs1");
break; 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: default:
UNSUPPORTED_RISCV(); UNSUPPORTED_RISCV();
break; break;
...@@ -2303,6 +2321,37 @@ void Decoder::DecodeRvvFVV(Instruction* instr) { ...@@ -2303,6 +2321,37 @@ void Decoder::DecodeRvvFVV(Instruction* instr) {
case RO_V_VFMUL_VV: case RO_V_VFMUL_VV:
Format(instr, "vfmul.vv 'vd, 'vs2, 'vs1'vm"); Format(instr, "vfmul.vv 'vd, 'vs2, 'vs1'vm");
break; 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: default:
UNSUPPORTED_RISCV(); UNSUPPORTED_RISCV();
break; break;
...@@ -2321,6 +2370,33 @@ void Decoder::DecodeRvvFVF(Instruction* instr) { ...@@ -2321,6 +2370,33 @@ void Decoder::DecodeRvvFVF(Instruction* instr) {
case RO_V_VFSGNJX_VF: case RO_V_VFSGNJX_VF:
Format(instr, "vfsgnjn.vf 'vd, 'vs2, 'fs1'vm"); Format(instr, "vfsgnjn.vf 'vd, 'vs2, 'fs1'vm");
break; 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: default:
UNSUPPORTED_RISCV(); UNSUPPORTED_RISCV();
break; break;
...@@ -2345,7 +2421,7 @@ void Decoder::DecodeVType(Instruction* instr) { ...@@ -2345,7 +2421,7 @@ void Decoder::DecodeVType(Instruction* instr) {
DecodeRvvIVX(instr); DecodeRvvIVX(instr);
return; return;
case OP_FVF: case OP_FVF:
UNSUPPORTED_RISCV(); DecodeRvvFVF(instr);
return; return;
case OP_MVX: case OP_MVX:
DecodeRvvMVX(instr); DecodeRvvMVX(instr);
......
This diff is collapsed.
...@@ -762,6 +762,20 @@ class Simulator : public SimulatorBase { ...@@ -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 uimm5 = (type_usew_t<x>::type)(instr_.RvvUimm5()); \
type_usew_t<x>::type vs2 = Rvvelt<type_usew_t<x>::type>(rvv_vs2_reg(), i); 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) \ #define VXI_PARAMS(x) \
type_sew_t<x>::type& vd = \ type_sew_t<x>::type& vd = \
Rvvelt<type_sew_t<x>::type>(rvv_vd_reg(), i, true); \ Rvvelt<type_sew_t<x>::type>(rvv_vd_reg(), i, true); \
...@@ -873,9 +887,24 @@ class Simulator : public SimulatorBase { ...@@ -873,9 +887,24 @@ class Simulator : public SimulatorBase {
vlenb_ = value; 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> template <typename T, typename Func>
inline T CanonicalizeFPUOp3(Func fn) { 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 src1 = std::is_same<float, T>::value ? frs1() : drs1();
T src2 = std::is_same<float, T>::value ? frs2() : drs2(); T src2 = std::is_same<float, T>::value ? frs2() : drs2();
T src3 = std::is_same<float, T>::value ? frs3() : drs3(); T src3 = std::is_same<float, T>::value ? frs3() : drs3();
...@@ -893,7 +922,7 @@ class Simulator : public SimulatorBase { ...@@ -893,7 +922,7 @@ class Simulator : public SimulatorBase {
template <typename T, typename Func> template <typename T, typename Func>
inline T CanonicalizeFPUOp2(Func fn) { 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 src1 = std::is_same<float, T>::value ? frs1() : drs1();
T src2 = std::is_same<float, T>::value ? frs2() : drs2(); T src2 = std::is_same<float, T>::value ? frs2() : drs2();
auto alu_out = fn(src1, src2); auto alu_out = fn(src1, src2);
...@@ -909,7 +938,7 @@ class Simulator : public SimulatorBase { ...@@ -909,7 +938,7 @@ class Simulator : public SimulatorBase {
template <typename T, typename Func> template <typename T, typename Func>
inline T CanonicalizeFPUOp1(Func fn) { 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(); T src1 = std::is_same<float, T>::value ? frs1() : drs1();
auto alu_out = fn(src1); auto alu_out = fn(src1);
// if any input or result is NaN, the result is quiet_NaN // if any input or result is NaN, the result is quiet_NaN
......
...@@ -2767,13 +2767,39 @@ void LiftoffAssembler::emit_i8x16_uconvert_i16x8(LiftoffRegister dst, ...@@ -2767,13 +2767,39 @@ void LiftoffAssembler::emit_i8x16_uconvert_i16x8(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_sconvert_i32x4(LiftoffRegister dst, void LiftoffAssembler::emit_i16x8_sconvert_i32x4(LiftoffRegister dst,
LiftoffRegister lhs, LiftoffRegister lhs,
LiftoffRegister rhs) { 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, void LiftoffAssembler::emit_i16x8_uconvert_i32x4(LiftoffRegister dst,
LiftoffRegister lhs, LiftoffRegister lhs,
LiftoffRegister rhs) { 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, void LiftoffAssembler::emit_i16x8_sconvert_i8x16_low(LiftoffRegister dst,
...@@ -2863,7 +2889,6 @@ void LiftoffAssembler::emit_i16x8_extadd_pairwise_i8x16_u(LiftoffRegister dst, ...@@ -2863,7 +2889,6 @@ void LiftoffAssembler::emit_i16x8_extadd_pairwise_i8x16_u(LiftoffRegister dst,
bailout(kSimd, "i16x8.extadd_pairwise_i8x16_u"); bailout(kSimd, "i16x8.extadd_pairwise_i8x16_u");
} }
void LiftoffAssembler::emit_i32x4_abs(LiftoffRegister dst, void LiftoffAssembler::emit_i32x4_abs(LiftoffRegister dst,
LiftoffRegister src) { LiftoffRegister src) {
VU.set(kScratchReg, E32, m1); VU.set(kScratchReg, E32, m1);
......
This diff is collapsed.
...@@ -580,6 +580,40 @@ TEST(RVV) { ...@@ -580,6 +580,40 @@ TEST(RVV) {
COMPARE(vadc_vv(v7, v9, v6), "406483d7 vadc.vvm v7, v6, v9"); 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_vx(v7, t6, v9), "409fc3d7 vadc.vxm v7, v9, t6");
COMPARE(vadc_vi(v7, 5, v9), "4092b3d7 vadc.vim v7, v9, 5"); 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(); VERIFY_RUN();
} }
#endif #endif
......
...@@ -328,6 +328,11 @@ GeneratedCode<Signature> AssembleCode(Func assemble) { ...@@ -328,6 +328,11 @@ GeneratedCode<Signature> AssembleCode(Func assemble) {
return GeneratedCode<Signature>::FromCode(*AssembleCodeImpl(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 internal
} // namespace v8 } // 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