[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:
parent
c31ea1e8d0
commit
9fcbb5e314
@ -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));
|
||||
|
@ -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) \
|
||||
|
@ -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:
|
||||
|
@ -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) \
|
||||
|
@ -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();
|
||||
|
@ -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) \
|
||||
|
@ -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:
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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:
|
||||
|
@ -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) { \
|
||||
|
@ -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:
|
||||
|
@ -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)) {
|
||||
|
@ -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) \
|
||||
|
@ -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:
|
||||
|
@ -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) { \
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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) \
|
||||
|
@ -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];
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user