Commit fcd3ef48 authored by Lu Yahan's avatar Lu Yahan Committed by V8 LUCI CQ

[riscv64][wasm]Add Vector instrs

 - Add vsetivli/I8x16Add/vl/vse8
 - In Rvv, Vector regs is different from Float Regs. But in this cl, in order to facilitate modification, it is assumed that the vector register and float register share a set of register codes.
 - Because v0 is mask reg, we can't allocate it . And transfer float into vector reg, so i delete ft0 from AllocateReg.

Bug: v8:11976
Change-Id: I66185d1f5ead985489bcbdf671b131f02a6bd7c2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3005768
Commit-Queue: Ji Qiu <qiuji@iscas.ac.cn>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Reviewed-by: 's avatarJi Qiu <qiuji@iscas.ac.cn>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76700}
parent 255aaed9
......@@ -2733,7 +2733,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
for (Register gp_param_reg : wasm::kGpParamRegisters) {
gp_regs |= gp_param_reg.bit();
}
// Also push x1, because we must push multiples of 16 bytes (see
// Also push a1, because we must push multiples of 16 bytes (see
// {TurboAssembler::PushCPURegList}.
CHECK_EQ(0, NumRegs(gp_regs) % 2);
......
This diff is collapsed.
This diff is collapsed.
......@@ -105,6 +105,45 @@ int FPURegisters::Number(const char* name) {
return kInvalidFPURegister;
}
const char* VRegisters::names_[kNumVRegisters] = {
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10",
"v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
"v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"};
const VRegisters::RegisterAlias VRegisters::aliases_[] = {
{kInvalidRegister, nullptr}};
const char* VRegisters::Name(int creg) {
const char* result;
if ((0 <= creg) && (creg < kNumVRegisters)) {
result = names_[creg];
} else {
result = "nocreg";
}
return result;
}
int VRegisters::Number(const char* name) {
// Look through the canonical names.
for (int i = 0; i < kNumVRegisters; i++) {
if (strcmp(names_[i], name) == 0) {
return i;
}
}
// Look through the alias names.
int i = 0;
while (aliases_[i].creg != kInvalidRegister) {
if (strcmp(aliases_[i].name, name) == 0) {
return aliases_[i].creg;
}
i++;
}
// No Cregister with the reguested name found.
return kInvalidVRegister;
}
InstructionBase::Type InstructionBase::InstructionType() const {
if (IsIllegalInstruction()) {
return kUnsupported;
......@@ -193,6 +232,8 @@ InstructionBase::Type InstructionBase::InstructionType() const {
return kJType;
case SYSTEM:
return kIType;
case OP_V:
return kVType;
}
}
return kUnsupported;
......
This diff is collapsed.
......@@ -3870,7 +3870,74 @@ void MacroAssembler::GetInstanceTypeRange(Register map, Register type_reg,
Lhu(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
Sub64(range, type_reg, Operand(lower_limit));
}
//------------------------------------------------------------------------------
// Wasm
void TurboAssembler::WasmRvvEq(VRegister dst, VRegister lhs, VRegister rhs,
VSew sew, Vlmul lmul) {
VU.set(kScratchReg, sew, lmul);
vmseq_vv(v0, lhs, rhs);
li(kScratchReg, -1);
vmv_vx(dst, zero_reg);
vmerge_vx(dst, kScratchReg, dst);
}
void TurboAssembler::WasmRvvNe(VRegister dst, VRegister lhs, VRegister rhs,
VSew sew, Vlmul lmul) {
VU.set(kScratchReg, sew, lmul);
vmsne_vv(v0, lhs, rhs);
li(kScratchReg, -1);
vmv_vx(dst, zero_reg);
vmerge_vx(dst, kScratchReg, dst);
}
void TurboAssembler::WasmRvvGeS(VRegister dst, VRegister lhs, VRegister rhs,
VSew sew, Vlmul lmul) {
VU.set(kScratchReg, sew, lmul);
vmsle_vv(v0, rhs, lhs);
li(kScratchReg, -1);
vmv_vx(dst, zero_reg);
vmerge_vx(dst, kScratchReg, dst);
}
void TurboAssembler::WasmRvvGeU(VRegister dst, VRegister lhs, VRegister rhs,
VSew sew, Vlmul lmul) {
VU.set(kScratchReg, sew, lmul);
vmsleu_vv(v0, rhs, lhs);
li(kScratchReg, -1);
vmv_vx(dst, zero_reg);
vmerge_vx(dst, kScratchReg, dst);
}
void TurboAssembler::WasmRvvGtS(VRegister dst, VRegister lhs, VRegister rhs,
VSew sew, Vlmul lmul) {
VU.set(kScratchReg, sew, lmul);
vmslt_vv(v0, rhs, lhs);
li(kScratchReg, -1);
vmv_vx(dst, zero_reg);
vmerge_vx(dst, kScratchReg, dst);
}
void TurboAssembler::WasmRvvGtU(VRegister dst, VRegister lhs, VRegister rhs,
VSew sew, Vlmul lmul) {
VU.set(kScratchReg, sew, lmul);
vmsltu_vv(v0, rhs, lhs);
li(kScratchReg, -1);
vmv_vx(dst, zero_reg);
vmerge_vx(dst, kScratchReg, dst);
}
void TurboAssembler::WasmRvvS128const(VRegister dst, const uint8_t imms[16]) {
uint64_t imm1 = *(reinterpret_cast<const uint64_t*>(imms));
uint64_t imm2 = *((reinterpret_cast<const uint64_t*>(imms)) + 1);
VU.set(kScratchReg, VSew::E64, Vlmul::m1);
li(kScratchReg, 1);
vmv_vx(v0, kScratchReg);
li(kScratchReg, imm1);
vmerge_vx(dst, kScratchReg, dst);
li(kScratchReg, imm2);
vsll_vi(v0, v0, 1);
vmerge_vx(dst, kScratchReg, dst);
}
// -----------------------------------------------------------------------------
// Runtime calls.
......
......@@ -910,6 +910,31 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
Sub64(rd, rs1, rs2);
}
}
// Wasm into RVV
void WasmRvvExtractLane(Register dst, VRegister src, int8_t idx, VSew sew,
Vlmul lmul) {
VU.set(kScratchReg, sew, lmul);
VRegister Vsrc = idx != 0 ? kSimd128ScratchReg : src;
if (idx != 0) {
vslidedown_vi(kSimd128ScratchReg, src, idx);
}
vmv_xs(dst, Vsrc);
}
void WasmRvvEq(VRegister dst, VRegister lhs, VRegister rhs, VSew sew,
Vlmul lmul);
void WasmRvvNe(VRegister dst, VRegister lhs, VRegister rhs, VSew sew,
Vlmul lmul);
void WasmRvvGeS(VRegister dst, VRegister lhs, VRegister rhs, VSew sew,
Vlmul lmul);
void WasmRvvGeU(VRegister dst, VRegister lhs, VRegister rhs, VSew sew,
Vlmul lmul);
void WasmRvvGtS(VRegister dst, VRegister lhs, VRegister rhs, VSew sew,
Vlmul lmul);
void WasmRvvGtU(VRegister dst, VRegister lhs, VRegister rhs, VSew sew,
Vlmul lmul);
void WasmRvvS128const(VRegister dst, const uint8_t imms[16]);
protected:
inline Register GetRtAsRegisterHelper(const Operand& rt, Register scratch);
......
......@@ -49,16 +49,16 @@ namespace internal {
V(fs8) V(fs9) V(fs10) V(fs11) V(ft8) V(ft9) V(ft10) V(ft11)
#define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS(V) \
V(w0) V(w1) V(w2) V(w3) V(w4) V(w5) V(w6) V(w7) \
V(w8) V(w9) V(w10) V(w11) V(w12) V(w13) V(w14) V(w15) \
V(w16) V(w17) V(w18) V(w19) V(w20) V(w21) V(w22) V(w23) \
V(w24) V(w25) V(w26) V(w27) V(w28) V(w29) V(w30) V(w31)
#define VECTOR_REGISTERS(V) \
V(v0) V(v1) V(v2) V(v3) V(v4) V(v5) V(v6) V(v7) \
V(v8) V(v9) V(v10) V(v11) V(v12) V(v13) V(v14) V(v15) \
V(v16) V(v17) V(v18) V(v19) V(v20) V(v21) V(v22) V(v23) \
V(v24) V(v25) V(v26) V(v27) V(v28) V(v29) V(v30) V(v31)
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(ft0) V(ft1) V(ft2) V(ft3) \
V(ft4) V(ft5) V(ft6) V(ft7) V(fa0) V(fa1) V(fa2) V(fa3) V(fa4) V(fa5) \
V(fa6) V(fa7)
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(ft1) V(ft2) V(ft3) V(ft4) V(ft5) V(ft6) V(ft7) V(ft8) \
V(ft9) V(ft10) V(ft11) V(fa0) V(fa1) V(fa2) V(fa3) V(fa4) V(fa5) \
V(fa6) V(fa7)
// Returns the number of padding slots needed for stack pointer alignment.
constexpr int ArgumentPaddingSlots(int argument_count) {
......@@ -256,6 +256,19 @@ enum DoubleRegisterCode {
kDoubleAfterLast
};
enum VRegisterCode {
#define REGISTER_CODE(R) kVRCode_##R,
VECTOR_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kVRAfterLast
};
class VRegister : public RegisterBase<VRegister, kVRAfterLast> {
friend class RegisterBase;
public:
explicit constexpr VRegister(int code) : RegisterBase(code) {}
};
// Coprocessor register.
class FPURegister : public RegisterBase<FPURegister, kDoubleAfterLast> {
public:
......@@ -274,25 +287,24 @@ class FPURegister : public RegisterBase<FPURegister, kDoubleAfterLast> {
return FPURegister::from_code(code() + 1);
}
// FIXME(riscv64): In Rvv, Vector regs is different from Float Regs. But in
// this cl, in order to facilitate modification, it is assumed that the vector
// register and floating point register are shared.
VRegister toV() const {
DCHECK(base::IsInRange(code(), 0, kVRAfterLast - 1));
// FIXME(riscv): Because V0 is a special mask reg, so can't allocate it.
// And v8 is unallocated so we replace v0 with v8
if (code() == 0) {
return VRegister(8);
}
return VRegister(code());
}
private:
friend class RegisterBase;
explicit constexpr FPURegister(int code) : RegisterBase(code) {}
};
enum MSARegisterCode {
#define REGISTER_CODE(R) kMsaCode_##R,
SIMD128_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kMsaAfterLast
};
// MIPS SIMD (MSA) register
// TODO(RISCV): Remove MIPS MSA registers.
// https://github.com/v8-riscv/v8/issues/429
class MSARegister : public RegisterBase<MSARegister, kMsaAfterLast> {
friend class RegisterBase;
explicit constexpr MSARegister(int code) : RegisterBase(code) {}
};
// A few double registers are reserved: one as a scratch register and one to
// hold 0.0.
......@@ -304,6 +316,8 @@ using FloatRegister = FPURegister;
using DoubleRegister = FPURegister;
using Simd128Register = VRegister;
#define DECLARE_DOUBLE_REGISTER(R) \
constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
DOUBLE_REGISTERS(DECLARE_DOUBLE_REGISTER)
......@@ -311,15 +325,12 @@ DOUBLE_REGISTERS(DECLARE_DOUBLE_REGISTER)
constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
// SIMD registers.
using Simd128Register = MSARegister;
#define DECLARE_SIMD128_REGISTER(R) \
constexpr Simd128Register R = Simd128Register::from_code(kMsaCode_##R);
SIMD128_REGISTERS(DECLARE_SIMD128_REGISTER)
#undef DECLARE_SIMD128_REGISTER
#define DECLARE_VECTOR_REGISTER(R) \
constexpr VRegister R = VRegister::from_code(kVRCode_##R);
VECTOR_REGISTERS(DECLARE_VECTOR_REGISTER)
#undef DECLARE_VECTOR_REGISTER
const Simd128Register no_msareg = Simd128Register::no_reg();
const VRegister no_msareg = VRegister::no_reg();
// Register aliases.
// cp is assumed to be a callee saved register.
......@@ -328,14 +339,14 @@ constexpr Register cp = s7;
constexpr Register kScratchReg = s3;
constexpr Register kScratchReg2 = s4;
constexpr DoubleRegister kScratchDoubleReg = fs11;
constexpr DoubleRegister kScratchDoubleReg = ft0;
constexpr DoubleRegister kDoubleRegZero = fs9;
// Define {RegisterName} methods for the register types.
DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
DEFINE_REGISTER_NAMES(FPURegister, DOUBLE_REGISTERS)
DEFINE_REGISTER_NAMES(MSARegister, SIMD128_REGISTERS)
DEFINE_REGISTER_NAMES(VRegister, VECTOR_REGISTERS)
// Give alias names to registers for calling conventions.
constexpr Register kReturnRegister0 = a0;
......@@ -363,6 +374,9 @@ constexpr Register kWasmInstanceRegister = a0;
constexpr Register kWasmCompileLazyFuncIndexRegister = t0;
constexpr DoubleRegister kFPReturnRegister0 = fa0;
constexpr VRegister kSimd128ScratchReg = v27;
constexpr VRegister kSimd128ScratchReg2 = v26;
constexpr VRegister kSimd128RegZero = v25;
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
constexpr Register kPtrComprCageBaseRegister = s11; // callee save
......
......@@ -2754,11 +2754,12 @@ void InstructionSelector::VisitI64x2ReplaceLaneI32Pair(Node* node) {
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_PPC64
#if !V8_TARGET_ARCH_ARM64
#if !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_LOONG64
#if !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_LOONG64 && !V8_TARGET_ARCH_RISCV64
void InstructionSelector::VisitI64x2Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ExtractLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitI64x2ReplaceLane(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_LOONG64
#endif // !V8_TARGET_ARCH_MIPS64 && !V8_TARGET_ARCH_LOONG64 &&
// !V8_TARGET_ARCH_RISCV64
void InstructionSelector::VisitF64x2Qfma(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Qfms(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Qfma(Node* node) { UNIMPLEMENTED(); }
......
......@@ -355,7 +355,7 @@ namespace compiler {
V(RiscvS8x16PackOdd) \
V(RiscvS8x16InterleaveEven) \
V(RiscvS8x16InterleaveOdd) \
V(RiscvS8x16Shuffle) \
V(RiscvI8x16Shuffle) \
V(RiscvI8x16Swizzle) \
V(RiscvS8x16Concat) \
V(RiscvS8x8Reverse) \
......@@ -373,8 +373,8 @@ namespace compiler {
V(RiscvS128Load32x2U) \
V(RiscvS128LoadLane) \
V(RiscvS128StoreLane) \
V(RiscvMsaLd) \
V(RiscvMsaSt) \
V(RiscvRvvLd) \
V(RiscvRvvSt) \
V(RiscvI32x4SConvertI16x8Low) \
V(RiscvI32x4SConvertI16x8High) \
V(RiscvI32x4UConvertI16x8Low) \
......
......@@ -318,7 +318,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kRiscvS8x2Reverse:
case kRiscvS8x4Reverse:
case kRiscvS8x8Reverse:
case kRiscvS8x16Shuffle:
case kRiscvI8x16Shuffle:
case kRiscvI8x16Swizzle:
case kRiscvSar32:
case kRiscvSignExtendByte:
......@@ -352,7 +352,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kRiscvLw:
case kRiscvLoadFloat:
case kRiscvLwu:
case kRiscvMsaLd:
case kRiscvRvvLd:
case kRiscvPeek:
case kRiscvUld:
case kRiscvULoadDouble:
......@@ -380,7 +380,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kRiscvModD:
case kRiscvModS:
case kRiscvMsaSt:
case kRiscvRvvSt:
case kRiscvPush:
case kRiscvSb:
case kRiscvSd:
......
......@@ -475,7 +475,7 @@ void InstructionSelector::VisitLoad(Node* node) {
opcode = kRiscvLd;
break;
case MachineRepresentation::kSimd128:
opcode = kRiscvMsaLd;
opcode = kRiscvRvvLd;
break;
case MachineRepresentation::kCompressedPointer:
case MachineRepresentation::kCompressed:
......@@ -554,7 +554,7 @@ void InstructionSelector::VisitStore(Node* node) {
opcode = kRiscvSd;
break;
case MachineRepresentation::kSimd128:
opcode = kRiscvMsaSt;
opcode = kRiscvRvvSt;
break;
case MachineRepresentation::kCompressedPointer: // Fall through.
case MachineRepresentation::kCompressed:
......@@ -1632,7 +1632,7 @@ void InstructionSelector::VisitUnalignedLoad(Node* node) {
opcode = kRiscvUld;
break;
case MachineRepresentation::kSimd128:
opcode = kRiscvMsaLd;
opcode = kRiscvRvvLd;
break;
case MachineRepresentation::kBit: // Fall through.
case MachineRepresentation::kCompressedPointer: // Fall through.
......@@ -1686,7 +1686,7 @@ void InstructionSelector::VisitUnalignedStore(Node* node) {
opcode = kRiscvUsd;
break;
case MachineRepresentation::kSimd128:
opcode = kRiscvMsaSt;
opcode = kRiscvRvvSt;
break;
case MachineRepresentation::kBit: // Fall through.
case MachineRepresentation::kCompressedPointer: // Fall through.
......@@ -2684,6 +2684,7 @@ void InstructionSelector::VisitInt64AbsWithOverflow(Node* node) {
#define SIMD_TYPE_LIST(V) \
V(F32x4) \
V(I64x2) \
V(I32x4) \
V(I16x8) \
V(I8x16)
......@@ -2888,6 +2889,7 @@ SIMD_VISIT_SPLAT(F64x2)
SIMD_VISIT_EXTRACT_LANE(F64x2, )
SIMD_VISIT_EXTRACT_LANE(F32x4, )
SIMD_VISIT_EXTRACT_LANE(I32x4, )
SIMD_VISIT_EXTRACT_LANE(I64x2, )
SIMD_VISIT_EXTRACT_LANE(I16x8, U)
SIMD_VISIT_EXTRACT_LANE(I16x8, S)
SIMD_VISIT_EXTRACT_LANE(I8x16, U)
......@@ -2934,73 +2936,75 @@ struct ShuffleEntry {
ArchOpcode opcode;
};
static const ShuffleEntry arch_shuffles[] = {
{{0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23},
kRiscvS32x4InterleaveRight},
{{8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31},
kRiscvS32x4InterleaveLeft},
{{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27},
kRiscvS32x4PackEven},
{{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31},
kRiscvS32x4PackOdd},
{{0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11, 24, 25, 26, 27},
kRiscvS32x4InterleaveEven},
{{4, 5, 6, 7, 20, 21, 22, 23, 12, 13, 14, 15, 28, 29, 30, 31},
kRiscvS32x4InterleaveOdd},
{{0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23},
kRiscvS16x8InterleaveRight},
{{8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31},
kRiscvS16x8InterleaveLeft},
{{0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29},
kRiscvS16x8PackEven},
{{2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31},
kRiscvS16x8PackOdd},
{{0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29},
kRiscvS16x8InterleaveEven},
{{2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31},
kRiscvS16x8InterleaveOdd},
{{6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9},
kRiscvS16x4Reverse},
{{2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13},
kRiscvS16x2Reverse},
{{0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23},
kRiscvS8x16InterleaveRight},
{{8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31},
kRiscvS8x16InterleaveLeft},
{{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30},
kRiscvS8x16PackEven},
{{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
kRiscvS8x16PackOdd},
{{0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30},
kRiscvS8x16InterleaveEven},
{{1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31},
kRiscvS8x16InterleaveOdd},
{{7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8}, kRiscvS8x8Reverse},
{{3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12}, kRiscvS8x4Reverse},
{{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14},
kRiscvS8x2Reverse}};
bool TryMatchArchShuffle(const uint8_t* shuffle, const ShuffleEntry* table,
size_t num_entries, bool is_swizzle,
ArchOpcode* opcode) {
uint8_t mask = is_swizzle ? kSimd128Size - 1 : 2 * kSimd128Size - 1;
for (size_t i = 0; i < num_entries; ++i) {
const ShuffleEntry& entry = table[i];
int j = 0;
for (; j < kSimd128Size; ++j) {
if ((entry.shuffle[j] & mask) != (shuffle[j] & mask)) {
break;
}
}
if (j == kSimd128Size) {
*opcode = entry.opcode;
return true;
}
}
return false;
}
// static const ShuffleEntry arch_shuffles[] = {
// {{0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23},
// kRiscvS32x4InterleaveRight},
// {{8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31},
// kRiscvS32x4InterleaveLeft},
// {{0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27},
// kRiscvS32x4PackEven},
// {{4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31},
// kRiscvS32x4PackOdd},
// {{0, 1, 2, 3, 16, 17, 18, 19, 8, 9, 10, 11, 24, 25, 26, 27},
// kRiscvS32x4InterleaveEven},
// {{4, 5, 6, 7, 20, 21, 22, 23, 12, 13, 14, 15, 28, 29, 30, 31},
// kRiscvS32x4InterleaveOdd},
// {{0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23},
// kRiscvS16x8InterleaveRight},
// {{8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31},
// kRiscvS16x8InterleaveLeft},
// {{0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29},
// kRiscvS16x8PackEven},
// {{2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31},
// kRiscvS16x8PackOdd},
// {{0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29},
// kRiscvS16x8InterleaveEven},
// {{2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31},
// kRiscvS16x8InterleaveOdd},
// {{6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9},
// kRiscvS16x4Reverse},
// {{2, 3, 0, 1, 6, 7, 4, 5, 10, 11, 8, 9, 14, 15, 12, 13},
// kRiscvS16x2Reverse},
// {{0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23},
// kRiscvS8x16InterleaveRight},
// {{8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31},
// kRiscvS8x16InterleaveLeft},
// {{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30},
// kRiscvS8x16PackEven},
// {{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31},
// kRiscvS8x16PackOdd},
// {{0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30},
// kRiscvS8x16InterleaveEven},
// {{1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31},
// kRiscvS8x16InterleaveOdd},
// {{7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8},
// kRiscvS8x8Reverse},
// {{3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12},
// kRiscvS8x4Reverse},
// {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14},
// kRiscvS8x2Reverse}};
// bool TryMatchArchShuffle(const uint8_t* shuffle, const ShuffleEntry* table,
// size_t num_entries, bool is_swizzle,
// ArchOpcode* opcode) {
// uint8_t mask = is_swizzle ? kSimd128Size - 1 : 2 * kSimd128Size - 1;
// for (size_t i = 0; i < num_entries; ++i) {
// const ShuffleEntry& entry = table[i];
// int j = 0;
// for (; j < kSimd128Size; ++j) {
// if ((entry.shuffle[j] & mask) != (shuffle[j] & mask)) {
// break;
// }
// }
// if (j == kSimd128Size) {
// *opcode = entry.opcode;
// return true;
// }
// }
// return false;
// }
} // namespace
......@@ -3008,29 +3012,29 @@ void InstructionSelector::VisitI8x16Shuffle(Node* node) {
uint8_t shuffle[kSimd128Size];
bool is_swizzle;
CanonicalizeShuffle(node, shuffle, &is_swizzle);
uint8_t shuffle32x4[4];
ArchOpcode opcode;
if (TryMatchArchShuffle(shuffle, arch_shuffles, arraysize(arch_shuffles),
is_swizzle, &opcode)) {
VisitRRR(this, opcode, node);
return;
}
Node* input0 = node->InputAt(0);
Node* input1 = node->InputAt(1);
uint8_t offset;
RiscvOperandGenerator g(this);
if (wasm::SimdShuffle::TryMatchConcat(shuffle, &offset)) {
Emit(kRiscvS8x16Concat, g.DefineSameAsFirst(node), g.UseRegister(input1),
g.UseRegister(input0), g.UseImmediate(offset));
return;
}
if (wasm::SimdShuffle::TryMatch32x4Shuffle(shuffle, shuffle32x4)) {
Emit(kRiscvS32x4Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
g.UseRegister(input1),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle32x4)));
return;
}
Emit(kRiscvS8x16Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
// uint8_t shuffle32x4[4];
// ArchOpcode opcode;
// if (TryMatchArchShuffle(shuffle, arch_shuffles, arraysize(arch_shuffles),
// is_swizzle, &opcode)) {
// VisitRRR(this, opcode, node);
// return;
// }
// uint8_t offset;
// if (wasm::SimdShuffle::TryMatchConcat(shuffle, &offset)) {
// Emit(kRiscvS8x16Concat, g.DefineSameAsFirst(node), g.UseRegister(input1),
// g.UseRegister(input0), g.UseImmediate(offset));
// return;
// }
// if (wasm::SimdShuffle::TryMatch32x4Shuffle(shuffle, shuffle32x4)) {
// Emit(kRiscvS32x4Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
// g.UseRegister(input1),
// g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle32x4)));
// return;
// }
Emit(kRiscvI8x16Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
g.UseRegister(input1),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 4)),
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -105,8 +105,8 @@ constexpr RegList kLiftoffAssemblerGpCacheRegs =
// Any change of kLiftoffAssemblerGpCacheRegs also need to update
// kPushedFpRegs in frame-constants-riscv64.h
constexpr RegList kLiftoffAssemblerFpCacheRegs =
DoubleRegister::ListOf(ft0, ft1, ft2, ft3, ft4, ft5, ft6, ft7, fa0, fa1,
fa2, fa3, fa4, fa5, fa6, fa7, ft8, ft9, ft10, ft11);
DoubleRegister::ListOf(ft1, ft2, ft3, ft4, ft5, ft6, ft7, fa0, fa1, fa2,
fa3, fa4, fa5, fa6, fa7, ft8, ft9, ft10, ft11);
#else
constexpr RegList kLiftoffAssemblerGpCacheRegs = 0xff;
......
......@@ -1977,6 +1977,39 @@ TEST(li_estimate) {
}
}
#define UTEST_LOAD_STORE_RVV(ldname, stname, SEW, arg...) \
TEST(RISCV_UTEST_##stname##ldname##SEW) { \
CcTest::InitializeVM(); \
Isolate* isolate = CcTest::i_isolate(); \
HandleScope scope(isolate); \
int8_t src[16] = {arg}; \
int8_t dst[16]; \
auto fn = [](MacroAssembler& assm) { \
__ VU.set(t0, SEW, Vlmul::m1); \
__ vl(v2, a0, 0, VSew::E8); \
__ vs(v2, a1, 0, VSew::E8); \
}; \
GenAndRunTest<int32_t, int64_t>((int64_t)src, (int64_t)dst, fn); \
CHECK(!memcmp(src, dst, sizeof(src))); \
}
#ifdef CAN_USE_RVV_INSTRUCTIONS
UTEST_LOAD_STORE_RVV(vl, vs, E8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16)
// UTEST_LOAD_STORE_RVV(vl, vs, E8, 127, 127, 127, 127, 127, 127, 127)
TEST(RVV_VSETIVLI) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
auto fn = [](MacroAssembler& assm) {
__ VU.set(t0, VSew::E8, Vlmul::m1);
__ vsetivli(t0, 16, VSew::E128, Vlmul::m1);
};
GenAndRunTest(fn);
}
#endif
#undef __
} // namespace internal
......
......@@ -527,5 +527,61 @@ TEST(Previleged) {
VERIFY_RUN();
}
*/
#ifdef CAN_USE_RVV_INSTRUCTIONS
TEST(RVV) {
SET_UP();
COMPARE(vsetvlmax(kScratchReg, E64, m1),
"018079d7 vsetvli s3, zero_reg, E64, m1");
COMPARE(vl(v2, a0, 0, VSew::E8), "02050107 vle8.v v2, (a0)");
COMPARE(vl(v2, a0, 0, VSew::E8), "02050107 vle8.v v2, (a0)");
COMPARE(vl(v2, a0, 0, VSew::E16), "02055107 vle16.v v2, (a0)");
COMPARE(vl(v2, a0, 0, VSew::E32), "02056107 vle32.v v2, (a0)");
COMPARE(vadd_vv(v0, v0, v1), "02008057 vadd.vv v0, v0, v1");
COMPARE(vadd_vx(v0, v1, t0), "0212c057 vadd.vx v0, v1, t0");
COMPARE(vadd_vi(v0, v1, 3), "0211b057 vadd.vi v0, v1, 3");
COMPARE(vsub_vv(v2, v3, v4), "0a320157 vsub.vv v2, v3, v4");
COMPARE(vsub_vx(v2, v3, a4), "0a374157 vsub.vx v2, v3, a4");
COMPARE(vsadd_vv(v0, v0, v1), "86008057 vsadd.vv v0, v0, v1");
COMPARE(vsadd_vx(v4, v5, t1), "86534257 vsadd.vx v4, v5, t1");
COMPARE(vsadd_vi(v6, v7, 5), "8672b357 vsadd.vi v6, v7, 5");
COMPARE(vssub_vv(v2, v3, v4), "8e320157 vssub.vv v2, v3, v4");
COMPARE(vssub_vx(v2, v3, t4), "8e3ec157 vssub.vx v2, v3, t4");
COMPARE(vor_vv(v21, v31, v9), "2bf48ad7 vor.vv v21, v31, v9");
COMPARE(vor_vx(v19, v29, s7), "2bdbc9d7 vor.vx v19, v29, s7");
COMPARE(vor_vi(v17, v28, 7), "2bc3b8d7 vor.vi v17, v28, 7");
COMPARE(vxor_vv(v21, v31, v9), "2ff48ad7 vxor.vv v21, v31, v9");
COMPARE(vxor_vx(v19, v29, s7), "2fdbc9d7 vxor.vx v19, v29, s7");
COMPARE(vxor_vi(v17, v28, 7), "2fc3b8d7 vxor.vi v17, v28, 7");
COMPARE(vand_vv(v21, v31, v9), "27f48ad7 vand.vv v21, v31, v9");
COMPARE(vand_vx(v19, v29, s7), "27dbc9d7 vand.vx v19, v29, s7");
COMPARE(vand_vi(v17, v28, 7), "27c3b8d7 vand.vi v17, v28, 7");
COMPARE(vmseq_vv(v17, v28, v29),
"63ce88d7 vmseq.vv v17, v28, v29");
COMPARE(vmsne_vv(v17, v28, v29), "67ce88d7 vmsne.vv v17, v28, v29");
COMPARE(vmseq_vx(v17, v28, t2), "63c3c8d7 vmseq.vx v17, v28, t2");
COMPARE(vmsne_vx(v17, v28, t6), "67cfc8d7 vmsne.vx v17, v28, t6");
COMPARE(vmseq_vi(v17, v28, 7), "63c3b8d7 vmseq.vi v17, v28, 7");
COMPARE(vmsne_vi(v17, v28, 7), "67c3b8d7 vmsne.vi v17, v28, 7");
COMPARE(vmsltu_vv(v17, v28, v14), "6bc708d7 vmsltu.vv v17, v28, v14");
COMPARE(vmsltu_vx(v17, v28, a5), "6bc7c8d7 vmsltu.vx v17, v28, a5");
COMPARE(vmslt_vv(v17, v28, v14), "6fc708d7 vmslt.vv v17, v28, v14");
COMPARE(vmslt_vx(v17, v28, a5), "6fc7c8d7 vmslt.vx v17, v28, a5");
COMPARE(vmsleu_vv(v17, v28, v14), "73c708d7 vmsleu.vv v17, v28, v14");
COMPARE(vmsleu_vx(v17, v28, a5), "73c7c8d7 vmsleu.vx v17, v28, a5");
COMPARE(vmsleu_vi(v17, v28, 5), "73c2b8d7 vmsleu.vi v17, v28, 5");
COMPARE(vmsle_vv(v17, v28, v14), "77c708d7 vmsle.vv v17, v28, v14");
COMPARE(vmsle_vx(v17, v28, a5), "77c7c8d7 vmsle.vx v17, v28, a5");
COMPARE(vmsle_vi(v17, v28, 5), "77c2b8d7 vmsle.vi v17, v28, 5");
COMPARE(vmsgt_vx(v17, v28, a5), "7fc7c8d7 vmsgt.vx v17, v28, a5");
COMPARE(vmsgt_vi(v17, v28, 5), "7fc2b8d7 vmsgt.vi v17, v28, 5");
COMPARE(vmsgtu_vx(v17, v28, a5), "7bc7c8d7 vmsgtu.vx v17, v28, a5");
COMPARE(vmsgtu_vi(v17, v28, 5), "7bc2b8d7 vmsgtu.vi v17, v28, 5");
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");
VERIFY_RUN();
}
#endif
} // 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