[wasm][revec] Add instruction selection for simd256
Bug: v8:12716 Change-Id: Ib94e3e99b29d6715b1465f50d0a5bdb15bcbd29b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3849644 Commit-Queue: Jie Pan <jie.pan@intel.com> Reviewed-by: Maya Lekova <mslekova@chromium.org> Cr-Commit-Position: refs/heads/main@{#85380}
This commit is contained in:
parent
263493add5
commit
0c2608724e
@ -1473,7 +1473,13 @@ void InstructionSelector::VisitNode(Node* node) {
|
||||
return VisitLoad(node);
|
||||
}
|
||||
case IrOpcode::kLoadTransform: {
|
||||
MarkAsRepresentation(MachineRepresentation::kSimd128, node);
|
||||
LoadTransformParameters params = LoadTransformParametersOf(node->op());
|
||||
if (params.transformation == LoadTransformation::kS256Load32Splat ||
|
||||
params.transformation == LoadTransformation::kS256Load64Splat) {
|
||||
MarkAsRepresentation(MachineRepresentation::kSimd256, node);
|
||||
} else {
|
||||
MarkAsRepresentation(MachineRepresentation::kSimd128, node);
|
||||
}
|
||||
return VisitLoadTransform(node);
|
||||
}
|
||||
case IrOpcode::kLoadLane: {
|
||||
@ -2378,6 +2384,14 @@ void InstructionSelector::VisitNode(Node* node) {
|
||||
return MarkAsSimd128(node), VisitI16x8DotI8x16I7x16S(node);
|
||||
case IrOpcode::kI32x4DotI8x16I7x16AddS:
|
||||
return MarkAsSimd128(node), VisitI32x4DotI8x16I7x16AddS(node);
|
||||
|
||||
// SIMD256
|
||||
#if V8_TARGET_ARCH_X64
|
||||
case IrOpcode::kF32x8Add:
|
||||
return MarkAsSimd256(node), VisitF32x8Add(node);
|
||||
case IrOpcode::kF32x8Sub:
|
||||
return MarkAsSimd256(node), VisitF32x8Sub(node);
|
||||
#endif // V8_TARGET_ARCH_X64
|
||||
default:
|
||||
FATAL("Unexpected operator #%d:%s @ node #%d", node->opcode(),
|
||||
node->op()->mnemonic(), node->id());
|
||||
|
@ -518,6 +518,9 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
|
||||
void MarkAsSimd128(Node* node) {
|
||||
MarkAsRepresentation(MachineRepresentation::kSimd128, node);
|
||||
}
|
||||
void MarkAsSimd256(Node* node) {
|
||||
MarkAsRepresentation(MachineRepresentation::kSimd256, node);
|
||||
}
|
||||
void MarkAsTagged(Node* node) {
|
||||
MarkAsRepresentation(MachineRepresentation::kTagged, node);
|
||||
}
|
||||
|
@ -224,6 +224,11 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperand& op) {
|
||||
} else if (op.IsFloatRegister()) {
|
||||
os << "[" << FloatRegister::from_code(allocated.register_code())
|
||||
<< "|R";
|
||||
#if V8_TARGET_ARCH_X64
|
||||
} else if (op.IsSimd256Register()) {
|
||||
os << "[" << Simd256Register::from_code(allocated.register_code())
|
||||
<< "|R";
|
||||
#endif // V8_TARGET_ARCH_X64
|
||||
} else {
|
||||
DCHECK(op.IsSimd128Register());
|
||||
os << "[" << Simd128Register::from_code(allocated.register_code())
|
||||
|
@ -93,12 +93,14 @@ class V8_EXPORT_PRIVATE INSTRUCTION_OPERAND_ALIGN InstructionOperand {
|
||||
inline bool IsFloatRegister() const;
|
||||
inline bool IsDoubleRegister() const;
|
||||
inline bool IsSimd128Register() const;
|
||||
inline bool IsSimd256Register() const;
|
||||
inline bool IsAnyStackSlot() const;
|
||||
inline bool IsStackSlot() const;
|
||||
inline bool IsFPStackSlot() const;
|
||||
inline bool IsFloatStackSlot() const;
|
||||
inline bool IsDoubleStackSlot() const;
|
||||
inline bool IsSimd128StackSlot() const;
|
||||
inline bool IsSimd256StackSlot() const;
|
||||
|
||||
template <typename SubKindOperand>
|
||||
static SubKindOperand* New(Zone* zone, const SubKindOperand& op) {
|
||||
@ -536,6 +538,13 @@ class LocationOperand : public InstructionOperand {
|
||||
return Simd128Register::from_code(register_code());
|
||||
}
|
||||
|
||||
#if defined(V8_TARGET_ARCH_X64)
|
||||
Simd256Register GetSimd256Register() const {
|
||||
DCHECK(IsSimd256Register());
|
||||
return Simd256Register::from_code(register_code());
|
||||
}
|
||||
#endif
|
||||
|
||||
LocationKind location_kind() const {
|
||||
return LocationKindField::decode(value_);
|
||||
}
|
||||
@ -654,6 +663,11 @@ bool InstructionOperand::IsSimd128Register() const {
|
||||
MachineRepresentation::kSimd128;
|
||||
}
|
||||
|
||||
bool InstructionOperand::IsSimd256Register() const {
|
||||
return IsAnyRegister() && LocationOperand::cast(this)->representation() ==
|
||||
MachineRepresentation::kSimd256;
|
||||
}
|
||||
|
||||
bool InstructionOperand::IsAnyStackSlot() const {
|
||||
return IsAnyLocationOperand() &&
|
||||
LocationOperand::cast(this)->location_kind() ==
|
||||
@ -694,6 +708,14 @@ bool InstructionOperand::IsSimd128StackSlot() const {
|
||||
MachineRepresentation::kSimd128;
|
||||
}
|
||||
|
||||
bool InstructionOperand::IsSimd256StackSlot() const {
|
||||
return IsAnyLocationOperand() &&
|
||||
LocationOperand::cast(this)->location_kind() ==
|
||||
LocationOperand::STACK_SLOT &&
|
||||
LocationOperand::cast(this)->representation() ==
|
||||
MachineRepresentation::kSimd256;
|
||||
}
|
||||
|
||||
uint64_t InstructionOperand::GetCanonicalizedValue() const {
|
||||
if (IsAnyLocationOperand()) {
|
||||
MachineRepresentation canonical = MachineRepresentation::kNone;
|
||||
@ -1712,7 +1734,8 @@ class V8_EXPORT_PRIVATE InstructionSequence final
|
||||
constexpr int kFPRepMask =
|
||||
RepresentationBit(MachineRepresentation::kFloat32) |
|
||||
RepresentationBit(MachineRepresentation::kFloat64) |
|
||||
RepresentationBit(MachineRepresentation::kSimd128);
|
||||
RepresentationBit(MachineRepresentation::kSimd128) |
|
||||
RepresentationBit(MachineRepresentation::kSimd256);
|
||||
return (representation_mask() & kFPRepMask) != 0;
|
||||
}
|
||||
|
||||
|
@ -4577,6 +4577,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
case kAtomicLoadUint16:
|
||||
case kAtomicLoadWord32:
|
||||
UNREACHABLE(); // Won't be generated by instruction selector.
|
||||
|
||||
// SIMD256
|
||||
case kX64F32x8Add:
|
||||
case kX64F32x8Sub:
|
||||
case kX64S256Load32Splat:
|
||||
case kX64S256Load64Splat:
|
||||
case kX64Movdqu256:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
return kSuccess;
|
||||
} // NOLadability/fn_size)
|
||||
|
@ -56,7 +56,10 @@ namespace compiler {
|
||||
V(X64Word64AtomicOrUint64) \
|
||||
V(X64Word64AtomicXorUint64) \
|
||||
V(X64Word64AtomicExchangeUint64) \
|
||||
V(X64Word64AtomicCompareExchangeUint64)
|
||||
V(X64Word64AtomicCompareExchangeUint64) \
|
||||
V(X64Movdqu256) \
|
||||
V(X64S256Load32Splat) \
|
||||
V(X64S256Load64Splat)
|
||||
|
||||
#define TARGET_ARCH_OPCODE_LIST(V) \
|
||||
TARGET_ARCH_OPCODE_WITH_MEMORY_ACCESS_MODE_LIST(V) \
|
||||
@ -413,7 +416,9 @@ namespace compiler {
|
||||
V(X64Blendvpd) \
|
||||
V(X64Blendvps) \
|
||||
V(X64Pblendvb) \
|
||||
V(X64TraceInstruction)
|
||||
V(X64TraceInstruction) \
|
||||
V(X64F32x8Add) \
|
||||
V(X64F32x8Sub)
|
||||
|
||||
// Addressing modes represent the "shape" of inputs to an instruction.
|
||||
// Many instructions support multiple addressing modes. Addressing modes
|
||||
|
@ -167,7 +167,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
case kX64F32x4Neg:
|
||||
case kX64F32x4Sqrt:
|
||||
case kX64F32x4Add:
|
||||
case kX64F32x8Add:
|
||||
case kX64F32x4Sub:
|
||||
case kX64F32x8Sub:
|
||||
case kX64F32x4Mul:
|
||||
case kX64F32x4Div:
|
||||
case kX64F32x4Min:
|
||||
@ -410,10 +412,13 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
case kX64Movsd:
|
||||
case kX64Movss:
|
||||
case kX64Movdqu:
|
||||
case kX64Movdqu256:
|
||||
case kX64S128Load8Splat:
|
||||
case kX64S128Load16Splat:
|
||||
case kX64S128Load32Splat:
|
||||
case kX64S256Load32Splat:
|
||||
case kX64S128Load64Splat:
|
||||
case kX64S256Load64Splat:
|
||||
case kX64S128Load8x8S:
|
||||
case kX64S128Load8x8U:
|
||||
case kX64S128Load16x4S:
|
||||
|
@ -338,6 +338,8 @@ ArchOpcode GetLoadOpcode(LoadRepresentation load_rep) {
|
||||
opcode = kX64Movdqu;
|
||||
break;
|
||||
case MachineRepresentation::kSimd256: // Fall through.
|
||||
opcode = kX64Movdqu256;
|
||||
break;
|
||||
case MachineRepresentation::kNone: // Fall through.
|
||||
case MachineRepresentation::kMapWord: // Fall through.
|
||||
UNREACHABLE();
|
||||
@ -376,6 +378,7 @@ ArchOpcode GetStoreOpcode(StoreRepresentation store_rep) {
|
||||
case MachineRepresentation::kSimd128:
|
||||
return kX64Movdqu;
|
||||
case MachineRepresentation::kSimd256: // Fall through.
|
||||
return kX64Movdqu256;
|
||||
case MachineRepresentation::kNone: // Fall through.
|
||||
case MachineRepresentation::kMapWord: // Fall through.
|
||||
UNREACHABLE();
|
||||
@ -509,6 +512,13 @@ void InstructionSelector::VisitLoadTransform(Node* node) {
|
||||
case LoadTransformation::kS128Load64Zero:
|
||||
opcode = kX64Movsd;
|
||||
break;
|
||||
// Simd256
|
||||
case LoadTransformation::kS256Load32Splat:
|
||||
opcode = kX64S256Load32Splat;
|
||||
break;
|
||||
case LoadTransformation::kS256Load64Splat:
|
||||
opcode = kX64S256Load64Splat;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -3357,6 +3367,10 @@ VISIT_ATOMIC_BINOP(Xor)
|
||||
V(S128Or) \
|
||||
V(S128Xor)
|
||||
|
||||
#define SIMD256_BINOP_SSE_AVX_LIST(V) \
|
||||
V(F32x8Add) \
|
||||
V(F32x8Sub)
|
||||
|
||||
#define SIMD_BINOP_LIST(V) \
|
||||
V(F64x2Min) \
|
||||
V(F64x2Max) \
|
||||
@ -3603,9 +3617,19 @@ SIMD_BINOP_LIST(VISIT_SIMD_BINOP)
|
||||
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); \
|
||||
} \
|
||||
}
|
||||
#define VISIT_SIMD256_BINOP(Opcode) \
|
||||
void InstructionSelector::Visit##Opcode(Node* node) { \
|
||||
X64OperandGenerator g(this); \
|
||||
Emit(kX64##Opcode, g.DefineAsRegister(node), \
|
||||
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); \
|
||||
}
|
||||
|
||||
SIMD_BINOP_SSE_AVX_LIST(VISIT_SIMD_BINOP)
|
||||
SIMD256_BINOP_SSE_AVX_LIST(VISIT_SIMD256_BINOP)
|
||||
#undef VISIT_SIMD_BINOP
|
||||
#undef VISIT_SIMD256_BINOP
|
||||
#undef SIMD_BINOP_SSE_AVX_LIST
|
||||
#undef SIMD256_BINOP_SSE_AVX_LIST
|
||||
|
||||
void InstructionSelector::VisitV128AnyTrue(Node* node) {
|
||||
X64OperandGenerator g(this);
|
||||
|
@ -770,6 +770,10 @@ void GraphC1Visualizer::PrintLiveRange(const LiveRange* range, const char* type,
|
||||
os_ << " \"" << DoubleRegister::from_code(op.register_code()) << "\"";
|
||||
} else if (op.IsFloatRegister()) {
|
||||
os_ << " \"" << FloatRegister::from_code(op.register_code()) << "\"";
|
||||
#if defined(V8_TARGET_ARCH_X64)
|
||||
} else if (op.IsSimd256Register()) {
|
||||
os_ << " \"" << Simd256Register::from_code(op.register_code()) << "\"";
|
||||
#endif
|
||||
} else {
|
||||
DCHECK(op.IsSimd128Register());
|
||||
os_ << " \"" << Simd128Register::from_code(op.register_code()) << "\"";
|
||||
@ -1235,6 +1239,10 @@ std::ostream& operator<<(std::ostream& os, const InstructionOperandAsJSON& o) {
|
||||
os << DoubleRegister::from_code(allocated->register_code());
|
||||
} else if (op->IsFloatRegister()) {
|
||||
os << FloatRegister::from_code(allocated->register_code());
|
||||
#if defined(V8_TARGET_ARCH_X64)
|
||||
} else if (op->IsSimd256Register()) {
|
||||
os << Simd256Register::from_code(allocated->register_code());
|
||||
#endif
|
||||
} else {
|
||||
DCHECK(op->IsSimd128Register());
|
||||
os << Simd128Register::from_code(allocated->register_code());
|
||||
|
Loading…
Reference in New Issue
Block a user