[arm][arm64] Use signed extract lane.

Replace unsigned extract lane followed by sign extend
as added here https://chromium-review.googlesource.com/c/v8/v8/+/1846711
with a signed extract lane for I8x16 and I16x8.

Change-Id: I5a701417b772d12f5ef038efbb081716bb27e25a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1873700
Commit-Queue: Martyn Capewell <martyn.capewell@arm.com>
Reviewed-by: Deepti Gandluri <gdeepti@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65307}
This commit is contained in:
George Wort 2019-11-19 10:45:06 +00:00 committed by Commit Bot
parent c31ea1e8d0
commit 9fcbb5e314
23 changed files with 191 additions and 83 deletions

View File

@ -2258,11 +2258,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ vdup(Neon16, i.OutputSimd128Register(), i.InputRegister(0));
break;
}
case kArmI16x8ExtractLane: {
case kArmI16x8ExtractLaneU: {
__ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonU16,
i.InputInt8(1));
break;
}
case kArmI16x8ExtractLaneS: {
__ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonS16,
i.InputInt8(1));
break;
}
case kArmI16x8ReplaceLane: {
__ ReplaceLane(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputRegister(2), NeonS16, i.InputInt8(1));
@ -2424,11 +2429,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ vdup(Neon8, i.OutputSimd128Register(), i.InputRegister(0));
break;
}
case kArmI8x16ExtractLane: {
case kArmI8x16ExtractLaneU: {
__ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonU8,
i.InputInt8(1));
break;
}
case kArmI8x16ExtractLaneS: {
__ ExtractLane(i.OutputRegister(), i.InputSimd128Register(0), NeonS8,
i.InputInt8(1));
break;
}
case kArmI8x16ReplaceLane: {
__ ReplaceLane(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputRegister(2), NeonS8, i.InputInt8(1));

View File

@ -199,7 +199,7 @@ namespace compiler {
V(ArmI32x4GtU) \
V(ArmI32x4GeU) \
V(ArmI16x8Splat) \
V(ArmI16x8ExtractLane) \
V(ArmI16x8ExtractLaneS) \
V(ArmI16x8ReplaceLane) \
V(ArmI16x8SConvertI8x16Low) \
V(ArmI16x8SConvertI8x16High) \
@ -219,6 +219,7 @@ namespace compiler {
V(ArmI16x8Ne) \
V(ArmI16x8GtS) \
V(ArmI16x8GeS) \
V(ArmI16x8ExtractLaneU) \
V(ArmI16x8UConvertI8x16Low) \
V(ArmI16x8UConvertI8x16High) \
V(ArmI16x8ShrU) \
@ -230,7 +231,7 @@ namespace compiler {
V(ArmI16x8GtU) \
V(ArmI16x8GeU) \
V(ArmI8x16Splat) \
V(ArmI8x16ExtractLane) \
V(ArmI8x16ExtractLaneS) \
V(ArmI8x16ReplaceLane) \
V(ArmI8x16Neg) \
V(ArmI8x16Shl) \
@ -247,6 +248,7 @@ namespace compiler {
V(ArmI8x16Ne) \
V(ArmI8x16GtS) \
V(ArmI8x16GeS) \
V(ArmI8x16ExtractLaneU) \
V(ArmI8x16ShrU) \
V(ArmI8x16UConvertI16x8) \
V(ArmI8x16AddSaturateU) \

View File

@ -179,7 +179,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmI32x4GtU:
case kArmI32x4GeU:
case kArmI16x8Splat:
case kArmI16x8ExtractLane:
case kArmI16x8ExtractLaneS:
case kArmI16x8ReplaceLane:
case kArmI16x8SConvertI8x16Low:
case kArmI16x8SConvertI8x16High:
@ -199,6 +199,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmI16x8Ne:
case kArmI16x8GtS:
case kArmI16x8GeS:
case kArmI16x8ExtractLaneU:
case kArmI16x8UConvertI8x16Low:
case kArmI16x8UConvertI8x16High:
case kArmI16x8ShrU:
@ -210,7 +211,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmI16x8GtU:
case kArmI16x8GeU:
case kArmI8x16Splat:
case kArmI8x16ExtractLane:
case kArmI8x16ExtractLaneS:
case kArmI8x16ReplaceLane:
case kArmI8x16Neg:
case kArmI8x16Shl:
@ -227,6 +228,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmI8x16Ne:
case kArmI8x16GtS:
case kArmI8x16GeS:
case kArmI8x16ExtractLaneU:
case kArmI8x16UConvertI16x8:
case kArmI8x16AddSaturateU:
case kArmI8x16SubSaturateU:

View File

@ -2582,12 +2582,17 @@ SIMD_TYPE_LIST(SIMD_VISIT_SPLAT)
SIMD_VISIT_SPLAT(F64x2)
#undef SIMD_VISIT_SPLAT
#define SIMD_VISIT_EXTRACT_LANE(Type) \
void InstructionSelector::Visit##Type##ExtractLane(Node* node) { \
VisitRRI(this, kArm##Type##ExtractLane, node); \
#define SIMD_VISIT_EXTRACT_LANE(Type, Sign) \
void InstructionSelector::Visit##Type##ExtractLane##Sign(Node* node) { \
VisitRRI(this, kArm##Type##ExtractLane##Sign, node); \
}
SIMD_TYPE_LIST(SIMD_VISIT_EXTRACT_LANE)
SIMD_VISIT_EXTRACT_LANE(F64x2)
SIMD_VISIT_EXTRACT_LANE(F64x2, )
SIMD_VISIT_EXTRACT_LANE(F32x4, )
SIMD_VISIT_EXTRACT_LANE(I32x4, )
SIMD_VISIT_EXTRACT_LANE(I16x8, U)
SIMD_VISIT_EXTRACT_LANE(I16x8, S)
SIMD_VISIT_EXTRACT_LANE(I8x16, U)
SIMD_VISIT_EXTRACT_LANE(I8x16, S)
#undef SIMD_VISIT_EXTRACT_LANE
#define SIMD_VISIT_REPLACE_LANE(Type) \

View File

@ -2133,11 +2133,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Dup(i.OutputSimd128Register().V8H(), i.InputRegister32(0));
break;
}
case kArm64I16x8ExtractLane: {
case kArm64I16x8ExtractLaneU: {
__ Umov(i.OutputRegister32(), i.InputSimd128Register(0).V8H(),
i.InputInt8(1));
break;
}
case kArm64I16x8ExtractLaneS: {
__ Smov(i.OutputRegister32(), i.InputSimd128Register(0).V8H(),
i.InputInt8(1));
break;
}
case kArm64I16x8ReplaceLane: {
VRegister dst = i.OutputSimd128Register().V8H(),
src1 = i.InputSimd128Register(0).V8H();
@ -2247,11 +2252,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Dup(i.OutputSimd128Register().V16B(), i.InputRegister32(0));
break;
}
case kArm64I8x16ExtractLane: {
case kArm64I8x16ExtractLaneU: {
__ Umov(i.OutputRegister32(), i.InputSimd128Register(0).V16B(),
i.InputInt8(1));
break;
}
case kArm64I8x16ExtractLaneS: {
__ Smov(i.OutputRegister32(), i.InputSimd128Register(0).V16B(),
i.InputInt8(1));
break;
}
case kArm64I8x16ReplaceLane: {
VRegister dst = i.OutputSimd128Register().V16B(),
src1 = i.InputSimd128Register(0).V16B();

View File

@ -253,7 +253,8 @@ namespace compiler {
V(Arm64I32x4GtU) \
V(Arm64I32x4GeU) \
V(Arm64I16x8Splat) \
V(Arm64I16x8ExtractLane) \
V(Arm64I16x8ExtractLaneU) \
V(Arm64I16x8ExtractLaneS) \
V(Arm64I16x8ReplaceLane) \
V(Arm64I16x8SConvertI8x16Low) \
V(Arm64I16x8SConvertI8x16High) \
@ -284,7 +285,8 @@ namespace compiler {
V(Arm64I16x8GtU) \
V(Arm64I16x8GeU) \
V(Arm64I8x16Splat) \
V(Arm64I8x16ExtractLane) \
V(Arm64I8x16ExtractLaneU) \
V(Arm64I8x16ExtractLaneS) \
V(Arm64I8x16ReplaceLane) \
V(Arm64I8x16Neg) \
V(Arm64I8x16Shl) \

View File

@ -223,7 +223,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64I32x4GtU:
case kArm64I32x4GeU:
case kArm64I16x8Splat:
case kArm64I16x8ExtractLane:
case kArm64I16x8ExtractLaneU:
case kArm64I16x8ExtractLaneS:
case kArm64I16x8ReplaceLane:
case kArm64I16x8SConvertI8x16Low:
case kArm64I16x8SConvertI8x16High:
@ -254,7 +255,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArm64I16x8GtU:
case kArm64I16x8GeU:
case kArm64I8x16Splat:
case kArm64I8x16ExtractLane:
case kArm64I8x16ExtractLaneU:
case kArm64I8x16ExtractLaneS:
case kArm64I8x16ReplaceLane:
case kArm64I8x16Neg:
case kArm64I8x16Shl:

View File

@ -3274,11 +3274,18 @@ void InstructionSelector::VisitS128Zero(Node* node) {
SIMD_TYPE_LIST(SIMD_VISIT_SPLAT)
#undef SIMD_VISIT_SPLAT
#define SIMD_VISIT_EXTRACT_LANE(Type) \
void InstructionSelector::Visit##Type##ExtractLane(Node* node) { \
VisitRRI(this, kArm64##Type##ExtractLane, node); \
#define SIMD_VISIT_EXTRACT_LANE(Type, Sign) \
void InstructionSelector::Visit##Type##ExtractLane##Sign(Node* node) { \
VisitRRI(this, kArm64##Type##ExtractLane##Sign, node); \
}
SIMD_TYPE_LIST(SIMD_VISIT_EXTRACT_LANE)
SIMD_VISIT_EXTRACT_LANE(F64x2, )
SIMD_VISIT_EXTRACT_LANE(F32x4, )
SIMD_VISIT_EXTRACT_LANE(I64x2, )
SIMD_VISIT_EXTRACT_LANE(I32x4, )
SIMD_VISIT_EXTRACT_LANE(I16x8, U)
SIMD_VISIT_EXTRACT_LANE(I16x8, S)
SIMD_VISIT_EXTRACT_LANE(I8x16, U)
SIMD_VISIT_EXTRACT_LANE(I8x16, S)
#undef SIMD_VISIT_EXTRACT_LANE
#define SIMD_VISIT_REPLACE_LANE(Type) \

View File

@ -2798,11 +2798,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Pshufd(dst, dst, 0x0);
break;
}
case kIA32I16x8ExtractLane: {
case kIA32I16x8ExtractLaneU: {
Register dst = i.OutputRegister();
__ Pextrw(dst, i.InputSimd128Register(0), i.InputInt8(1));
break;
}
case kIA32I16x8ExtractLaneS: {
Register dst = i.OutputRegister();
__ Pextrw(dst, i.InputSimd128Register(0), i.InputInt8(1));
__ movsx_w(dst, dst);
break;
}
case kSSEI16x8ReplaceLane: {
DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
__ pinsrw(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1));
@ -3165,11 +3171,17 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Pshufb(dst, kScratchDoubleReg);
break;
}
case kIA32I8x16ExtractLane: {
case kIA32I8x16ExtractLaneU: {
Register dst = i.OutputRegister();
__ Pextrb(dst, i.InputSimd128Register(0), i.InputInt8(1));
break;
}
case kIA32I8x16ExtractLaneS: {
Register dst = i.OutputRegister();
__ Pextrb(dst, i.InputSimd128Register(0), i.InputInt8(1));
__ movsx_b(dst, dst);
break;
}
case kSSEI8x16ReplaceLane: {
DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
CpuFeatureScope sse_scope(tasm(), SSE4_1);

View File

@ -229,7 +229,8 @@ namespace compiler {
V(SSEI32x4GeU) \
V(AVXI32x4GeU) \
V(IA32I16x8Splat) \
V(IA32I16x8ExtractLane) \
V(IA32I16x8ExtractLaneU) \
V(IA32I16x8ExtractLaneS) \
V(SSEI16x8ReplaceLane) \
V(AVXI16x8ReplaceLane) \
V(IA32I16x8SConvertI8x16Low) \
@ -284,7 +285,8 @@ namespace compiler {
V(SSEI16x8GeU) \
V(AVXI16x8GeU) \
V(IA32I8x16Splat) \
V(IA32I8x16ExtractLane) \
V(IA32I8x16ExtractLaneU) \
V(IA32I8x16ExtractLaneS) \
V(SSEI8x16ReplaceLane) \
V(AVXI8x16ReplaceLane) \
V(SSEI8x16SConvertI16x8) \

View File

@ -210,7 +210,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kSSEI32x4GeU:
case kAVXI32x4GeU:
case kIA32I16x8Splat:
case kIA32I16x8ExtractLane:
case kIA32I16x8ExtractLaneU:
case kIA32I16x8ExtractLaneS:
case kSSEI16x8ReplaceLane:
case kAVXI16x8ReplaceLane:
case kIA32I16x8SConvertI8x16Low:
@ -265,7 +266,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kSSEI16x8GeU:
case kAVXI16x8GeU:
case kIA32I8x16Splat:
case kIA32I8x16ExtractLane:
case kIA32I8x16ExtractLaneU:
case kIA32I8x16ExtractLaneS:
case kSSEI8x16ReplaceLane:
case kAVXI8x16ReplaceLane:
case kSSEI8x16SConvertI16x8:

View File

@ -276,7 +276,7 @@ void VisitRRISimd(InstructionSelector* selector, Node* node,
g.UseImmediate(OpParameter<int32_t>(node->op()));
// 8x16 uses movsx_b on dest to extract a byte, which only works
// if dest is a byte register.
InstructionOperand dest = opcode == kIA32I8x16ExtractLane
InstructionOperand dest = opcode == kIA32I8x16ExtractLaneS
? g.DefineAsFixed(node, eax)
: g.DefineAsRegister(node);
selector->Emit(opcode, dest, operand0, operand1);
@ -2231,12 +2231,16 @@ void InstructionSelector::VisitS128Select(Node* node) {
SIMD_INT_TYPES(VISIT_SIMD_SPLAT)
#undef VISIT_SIMD_SPLAT
#define VISIT_SIMD_EXTRACT_LANE(Type) \
void InstructionSelector::Visit##Type##ExtractLane(Node* node) { \
VisitRRISimd(this, node, kIA32##Type##ExtractLane); \
#define SIMD_VISIT_EXTRACT_LANE(Type, Sign) \
void InstructionSelector::Visit##Type##ExtractLane##Sign(Node* node) { \
VisitRRISimd(this, node, kIA32##Type##ExtractLane##Sign); \
}
SIMD_INT_TYPES(VISIT_SIMD_EXTRACT_LANE)
#undef VISIT_SIMD_EXTRACT_LANE
SIMD_VISIT_EXTRACT_LANE(I32x4, )
SIMD_VISIT_EXTRACT_LANE(I16x8, U)
SIMD_VISIT_EXTRACT_LANE(I16x8, S)
SIMD_VISIT_EXTRACT_LANE(I8x16, U)
SIMD_VISIT_EXTRACT_LANE(I8x16, S)
#undef SIMD_VISIT_EXTRACT_LANE
#define VISIT_SIMD_REPLACE_LANE(Type) \
void InstructionSelector::Visit##Type##ReplaceLane(Node* node) { \

View File

@ -2033,8 +2033,10 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsSimd128(node), VisitI32x4GeU(node);
case IrOpcode::kI16x8Splat:
return MarkAsSimd128(node), VisitI16x8Splat(node);
case IrOpcode::kI16x8ExtractLane:
return MarkAsWord32(node), VisitI16x8ExtractLane(node);
case IrOpcode::kI16x8ExtractLaneU:
return MarkAsWord32(node), VisitI16x8ExtractLaneU(node);
case IrOpcode::kI16x8ExtractLaneS:
return MarkAsWord32(node), VisitI16x8ExtractLaneS(node);
case IrOpcode::kI16x8ReplaceLane:
return MarkAsSimd128(node), VisitI16x8ReplaceLane(node);
case IrOpcode::kI16x8SConvertI8x16Low:
@ -2095,8 +2097,10 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsSimd128(node), VisitI16x8GeU(node);
case IrOpcode::kI8x16Splat:
return MarkAsSimd128(node), VisitI8x16Splat(node);
case IrOpcode::kI8x16ExtractLane:
return MarkAsWord32(node), VisitI8x16ExtractLane(node);
case IrOpcode::kI8x16ExtractLaneU:
return MarkAsWord32(node), VisitI8x16ExtractLaneU(node);
case IrOpcode::kI8x16ExtractLaneS:
return MarkAsWord32(node), VisitI8x16ExtractLaneS(node);
case IrOpcode::kI8x16ReplaceLane:
return MarkAsSimd128(node), VisitI8x16ReplaceLane(node);
case IrOpcode::kI8x16Neg:

View File

@ -3141,12 +3141,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ pshufd(dst, dst, 0x0);
break;
}
case kX64I16x8ExtractLane: {
case kX64I16x8ExtractLaneU: {
CpuFeatureScope sse_scope(tasm(), SSE4_1);
Register dst = i.OutputRegister();
__ Pextrw(dst, i.InputSimd128Register(0), i.InputInt8(1));
break;
}
case kX64I16x8ExtractLaneS: {
CpuFeatureScope sse_scope(tasm(), SSE4_1);
Register dst = i.OutputRegister();
__ Pextrw(dst, i.InputSimd128Register(0), i.InputInt8(1));
__ movsxwl(dst, dst);
break;
}
case kX64I16x8ReplaceLane: {
CpuFeatureScope sse_scope(tasm(), SSE4_1);
if (HasRegisterInput(instr, 2)) {
@ -3340,12 +3347,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ Pshufb(dst, kScratchDoubleReg);
break;
}
case kX64I8x16ExtractLane: {
case kX64I8x16ExtractLaneU: {
CpuFeatureScope sse_scope(tasm(), SSE4_1);
Register dst = i.OutputRegister();
__ Pextrb(dst, i.InputSimd128Register(0), i.InputInt8(1));
break;
}
case kX64I8x16ExtractLaneS: {
CpuFeatureScope sse_scope(tasm(), SSE4_1);
Register dst = i.OutputRegister();
__ Pextrb(dst, i.InputSimd128Register(0), i.InputInt8(1));
__ movsxbl(dst, dst);
break;
}
case kX64I8x16ReplaceLane: {
CpuFeatureScope sse_scope(tasm(), SSE4_1);
if (HasRegisterInput(instr, 2)) {

View File

@ -243,7 +243,8 @@ namespace compiler {
V(X64I32x4GtU) \
V(X64I32x4GeU) \
V(X64I16x8Splat) \
V(X64I16x8ExtractLane) \
V(X64I16x8ExtractLaneU) \
V(X64I16x8ExtractLaneS) \
V(X64I16x8ReplaceLane) \
V(X64I16x8SConvertI8x16Low) \
V(X64I16x8SConvertI8x16High) \
@ -274,7 +275,8 @@ namespace compiler {
V(X64I16x8GtU) \
V(X64I16x8GeU) \
V(X64I8x16Splat) \
V(X64I8x16ExtractLane) \
V(X64I8x16ExtractLaneU) \
V(X64I8x16ExtractLaneS) \
V(X64I8x16ReplaceLane) \
V(X64I8x16SConvertI16x8) \
V(X64I8x16Neg) \

View File

@ -215,7 +215,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I32x4GtU:
case kX64I32x4GeU:
case kX64I16x8Splat:
case kX64I16x8ExtractLane:
case kX64I16x8ExtractLaneU:
case kX64I16x8ExtractLaneS:
case kX64I16x8ReplaceLane:
case kX64I16x8SConvertI8x16Low:
case kX64I16x8SConvertI8x16High:
@ -246,7 +247,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I16x8GtU:
case kX64I16x8GeU:
case kX64I8x16Splat:
case kX64I8x16ExtractLane:
case kX64I8x16ExtractLaneU:
case kX64I8x16ExtractLaneS:
case kX64I8x16ReplaceLane:
case kX64I8x16SConvertI16x8:
case kX64I8x16Neg:

View File

@ -2769,15 +2769,22 @@ void InstructionSelector::VisitS128Zero(Node* node) {
SIMD_TYPES(VISIT_SIMD_SPLAT)
#undef VISIT_SIMD_SPLAT
#define VISIT_SIMD_EXTRACT_LANE(Type) \
void InstructionSelector::Visit##Type##ExtractLane(Node* node) { \
X64OperandGenerator g(this); \
int32_t lane = OpParameter<int32_t>(node->op()); \
Emit(kX64##Type##ExtractLane, g.DefineAsRegister(node), \
g.UseRegister(node->InputAt(0)), g.UseImmediate(lane)); \
#define SIMD_VISIT_EXTRACT_LANE(Type, Sign) \
void InstructionSelector::Visit##Type##ExtractLane##Sign(Node* node) { \
X64OperandGenerator g(this); \
int32_t lane = OpParameter<int32_t>(node->op()); \
Emit(kX64##Type##ExtractLane##Sign, g.DefineAsRegister(node), \
g.UseRegister(node->InputAt(0)), g.UseImmediate(lane)); \
}
SIMD_TYPES(VISIT_SIMD_EXTRACT_LANE)
#undef VISIT_SIMD_EXTRACT_LANE
SIMD_VISIT_EXTRACT_LANE(F64x2, )
SIMD_VISIT_EXTRACT_LANE(F32x4, )
SIMD_VISIT_EXTRACT_LANE(I64x2, )
SIMD_VISIT_EXTRACT_LANE(I32x4, )
SIMD_VISIT_EXTRACT_LANE(I16x8, U)
SIMD_VISIT_EXTRACT_LANE(I16x8, S)
SIMD_VISIT_EXTRACT_LANE(I8x16, U)
SIMD_VISIT_EXTRACT_LANE(I8x16, S)
#undef SIMD_VISIT_EXTRACT_LANE
#define VISIT_SIMD_REPLACE_LANE(Type) \
void InstructionSelector::Visit##Type##ReplaceLane(Node* node) { \

View File

@ -261,8 +261,10 @@ class MachineRepresentationInferrer {
case IrOpcode::kTruncateFloat32ToUint32:
case IrOpcode::kBitcastFloat32ToInt32:
case IrOpcode::kI32x4ExtractLane:
case IrOpcode::kI16x8ExtractLane:
case IrOpcode::kI8x16ExtractLane:
case IrOpcode::kI16x8ExtractLaneU:
case IrOpcode::kI16x8ExtractLaneS:
case IrOpcode::kI8x16ExtractLaneU:
case IrOpcode::kI8x16ExtractLaneS:
case IrOpcode::kInt32Constant:
case IrOpcode::kRelocatableInt32Constant:
case IrOpcode::kTruncateFloat64ToWord32:
@ -434,8 +436,10 @@ class MachineRepresentationChecker {
CheckValueInputForInt64Op(node, 1);
break;
case IrOpcode::kI32x4ExtractLane:
case IrOpcode::kI16x8ExtractLane:
case IrOpcode::kI8x16ExtractLane:
case IrOpcode::kI16x8ExtractLaneU:
case IrOpcode::kI16x8ExtractLaneS:
case IrOpcode::kI8x16ExtractLaneU:
case IrOpcode::kI8x16ExtractLaneS:
CheckValueInputRepresentationIs(node, 0,
MachineRepresentation::kSimd128);
break;

View File

@ -1466,14 +1466,25 @@ const Operator* MachineOperatorBuilder::Word64PoisonOnSpeculation() {
return &cache_.kWord64PoisonOnSpeculation;
}
#define SIMD_LANE_OPS(Type, lane_count) \
const Operator* MachineOperatorBuilder::Type##ExtractLane( \
int32_t lane_index) { \
DCHECK(0 <= lane_index && lane_index < lane_count); \
return new (zone_) \
Operator1<int32_t>(IrOpcode::k##Type##ExtractLane, Operator::kPure, \
"Extract lane", 1, 0, 0, 1, 0, 0, lane_index); \
} \
#define EXTRACT_LANE_OP(Type, Sign, lane_count) \
const Operator* MachineOperatorBuilder::Type##ExtractLane##Sign( \
int32_t lane_index) { \
DCHECK(0 <= lane_index && lane_index < lane_count); \
return new (zone_) Operator1<int32_t>( \
IrOpcode::k##Type##ExtractLane##Sign, Operator::kPure, "Extract lane", \
1, 0, 0, 1, 0, 0, lane_index); \
}
EXTRACT_LANE_OP(F64x2, , 2)
EXTRACT_LANE_OP(F32x4, , 4)
EXTRACT_LANE_OP(I64x2, , 2)
EXTRACT_LANE_OP(I32x4, , 4)
EXTRACT_LANE_OP(I16x8, U, 8)
EXTRACT_LANE_OP(I16x8, S, 8)
EXTRACT_LANE_OP(I8x16, U, 16)
EXTRACT_LANE_OP(I8x16, S, 16)
#undef EXTRACT_LANE_OP
#define REPLACE_LANE_OP(Type, lane_count) \
const Operator* MachineOperatorBuilder::Type##ReplaceLane( \
int32_t lane_index) { \
DCHECK(0 <= lane_index && lane_index < lane_count); \
@ -1481,8 +1492,8 @@ const Operator* MachineOperatorBuilder::Word64PoisonOnSpeculation() {
Operator1<int32_t>(IrOpcode::k##Type##ReplaceLane, Operator::kPure, \
"Replace lane", 2, 0, 0, 1, 0, 0, lane_index); \
}
SIMD_LANE_OP_LIST(SIMD_LANE_OPS)
#undef SIMD_LANE_OPS
SIMD_LANE_OP_LIST(REPLACE_LANE_OP)
#undef REPLACE_LANE_OP
const Operator* MachineOperatorBuilder::I64x2ReplaceLaneI32Pair(
int32_t lane_index) {

View File

@ -634,7 +634,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const Operator* I32x4GeU();
const Operator* I16x8Splat();
const Operator* I16x8ExtractLane(int32_t);
const Operator* I16x8ExtractLaneU(int32_t);
const Operator* I16x8ExtractLaneS(int32_t);
const Operator* I16x8ReplaceLane(int32_t);
const Operator* I16x8SConvertI8x16Low();
const Operator* I16x8SConvertI8x16High();
@ -667,7 +668,8 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const Operator* I16x8GeU();
const Operator* I8x16Splat();
const Operator* I8x16ExtractLane(int32_t);
const Operator* I8x16ExtractLaneU(int32_t);
const Operator* I8x16ExtractLaneS(int32_t);
const Operator* I8x16ReplaceLane(int32_t);
const Operator* I8x16Neg();
const Operator* I8x16Shl();

View File

@ -841,7 +841,8 @@
V(I32x4GtU) \
V(I32x4GeU) \
V(I16x8Splat) \
V(I16x8ExtractLane) \
V(I16x8ExtractLaneU) \
V(I16x8ExtractLaneS) \
V(I16x8ReplaceLane) \
V(I16x8SConvertI8x16Low) \
V(I16x8SConvertI8x16High) \
@ -876,7 +877,8 @@
V(I16x8GtU) \
V(I16x8GeU) \
V(I8x16Splat) \
V(I8x16ExtractLane) \
V(I8x16ExtractLaneU) \
V(I8x16ExtractLaneS) \
V(I8x16ReplaceLane) \
V(I8x16SConvertI16x8) \
V(I8x16Neg) \

View File

@ -153,7 +153,8 @@ void SimdScalarLowering::LowerGraph() {
#define FOREACH_INT16X8_OPCODE(V) \
V(I16x8Splat) \
V(I16x8ExtractLane) \
V(I16x8ExtractLaneU) \
V(I16x8ExtractLaneS) \
V(I16x8ReplaceLane) \
V(I16x8SConvertI8x16Low) \
V(I16x8SConvertI8x16High) \
@ -186,7 +187,8 @@ void SimdScalarLowering::LowerGraph() {
#define FOREACH_INT8X16_OPCODE(V) \
V(I8x16Splat) \
V(I8x16ExtractLane) \
V(I8x16ExtractLaneU) \
V(I8x16ExtractLaneS) \
V(I8x16ReplaceLane) \
V(I8x16SConvertI16x8) \
V(I8x16Neg) \
@ -1282,8 +1284,10 @@ void SimdScalarLowering::LowerNode(Node* node) {
}
case IrOpcode::kI32x4ExtractLane:
case IrOpcode::kF32x4ExtractLane:
case IrOpcode::kI16x8ExtractLane:
case IrOpcode::kI8x16ExtractLane: {
case IrOpcode::kI16x8ExtractLaneU:
case IrOpcode::kI16x8ExtractLaneS:
case IrOpcode::kI8x16ExtractLaneU:
case IrOpcode::kI8x16ExtractLaneS: {
int32_t lane = OpParameter<int32_t>(node->op());
Node** rep_node = zone()->NewArray<Node*>(num_lanes);
rep_node[0] = GetReplacementsWithType(node->InputAt(0), rep_type)[lane];

View File

@ -4556,23 +4556,19 @@ Node* WasmGraphBuilder::SimdLaneOp(wasm::WasmOpcode opcode, uint8_t lane,
return graph()->NewNode(mcgraph()->machine()->I32x4ReplaceLane(lane),
inputs[0], inputs[1]);
case wasm::kExprI16x8ExtractLaneS:
return graph()->NewNode(
mcgraph()->machine()->SignExtendWord16ToInt32(),
graph()->NewNode(mcgraph()->machine()->I16x8ExtractLane(lane),
inputs[0]));
return graph()->NewNode(mcgraph()->machine()->I16x8ExtractLaneS(lane),
inputs[0]);
case wasm::kExprI16x8ExtractLaneU:
return graph()->NewNode(mcgraph()->machine()->I16x8ExtractLane(lane),
return graph()->NewNode(mcgraph()->machine()->I16x8ExtractLaneU(lane),
inputs[0]);
case wasm::kExprI16x8ReplaceLane:
return graph()->NewNode(mcgraph()->machine()->I16x8ReplaceLane(lane),
inputs[0], inputs[1]);
case wasm::kExprI8x16ExtractLaneS:
return graph()->NewNode(
mcgraph()->machine()->SignExtendWord8ToInt32(),
graph()->NewNode(mcgraph()->machine()->I8x16ExtractLane(lane),
inputs[0]));
return graph()->NewNode(mcgraph()->machine()->I8x16ExtractLaneS(lane),
inputs[0]);
case wasm::kExprI8x16ExtractLaneU:
return graph()->NewNode(mcgraph()->machine()->I8x16ExtractLane(lane),
return graph()->NewNode(mcgraph()->machine()->I8x16ExtractLaneU(lane),
inputs[0]);
case wasm::kExprI8x16ReplaceLane:
return graph()->NewNode(mcgraph()->machine()->I8x16ReplaceLane(lane),