summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/x64
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/x64')
-rw-r--r--deps/v8/src/compiler/x64/code-generator-x64.cc213
-rw-r--r--deps/v8/src/compiler/x64/instruction-codes-x64.h22
-rw-r--r--deps/v8/src/compiler/x64/instruction-scheduler-x64.cc22
-rw-r--r--deps/v8/src/compiler/x64/instruction-selector-x64.cc110
4 files changed, 341 insertions, 26 deletions
diff --git a/deps/v8/src/compiler/x64/code-generator-x64.cc b/deps/v8/src/compiler/x64/code-generator-x64.cc
index 2ccb56907d..178d2b33b9 100644
--- a/deps/v8/src/compiler/x64/code-generator-x64.cc
+++ b/deps/v8/src/compiler/x64/code-generator-x64.cc
@@ -353,7 +353,6 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} // namespace
-
#define ASSEMBLE_UNOP(asm_instr) \
do { \
if (instr->Output()->IsRegister()) { \
@@ -361,7 +360,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} else { \
__ asm_instr(i.OutputOperand()); \
} \
- } while (0)
+ } while (false)
#define ASSEMBLE_BINOP(asm_instr) \
do { \
@@ -384,7 +383,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} \
} \
} \
- } while (0)
+ } while (false)
#define ASSEMBLE_COMPARE(asm_instr) \
do { \
@@ -411,7 +410,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} \
} \
} \
- } while (0)
+ } while (false)
#define ASSEMBLE_MULT(asm_instr) \
do { \
@@ -430,8 +429,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
__ asm_instr(i.OutputRegister(), i.InputOperand(1)); \
} \
} \
- } while (0)
-
+ } while (false)
#define ASSEMBLE_SHIFT(asm_instr, width) \
do { \
@@ -448,8 +446,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
__ asm_instr##_cl(i.OutputOperand()); \
} \
} \
- } while (0)
-
+ } while (false)
#define ASSEMBLE_MOVX(asm_instr) \
do { \
@@ -460,7 +457,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} else { \
__ asm_instr(i.OutputRegister(), i.InputOperand(0)); \
} \
- } while (0)
+ } while (false)
#define ASSEMBLE_SSE_BINOP(asm_instr) \
do { \
@@ -469,7 +466,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} else { \
__ asm_instr(i.InputDoubleRegister(0), i.InputOperand(1)); \
} \
- } while (0)
+ } while (false)
#define ASSEMBLE_SSE_UNOP(asm_instr) \
do { \
@@ -478,7 +475,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
} else { \
__ asm_instr(i.OutputDoubleRegister(), i.InputOperand(0)); \
} \
- } while (0)
+ } while (false)
#define ASSEMBLE_AVX_BINOP(asm_instr) \
do { \
@@ -490,7 +487,7 @@ void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen,
__ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
i.InputOperand(1)); \
} \
- } while (0)
+ } while (false)
#define ASSEMBLE_IEEE754_BINOP(name) \
do { \
@@ -2140,6 +2137,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ insertps(i.OutputSimd128Register(), i.InputDoubleRegister(2), select);
break;
}
+ case kX64F32x4SConvertI32x4: {
+ __ cvtdq2ps(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ break;
+ }
+ case kX64F32x4UConvertI32x4: {
+ DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ DCHECK_NE(i.OutputSimd128Register(), kScratchDoubleReg);
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ __ pxor(kScratchDoubleReg, kScratchDoubleReg); // zeros
+ __ pblendw(kScratchDoubleReg, dst, 0x55); // get lo 16 bits
+ __ psubd(dst, kScratchDoubleReg); // get hi 16 bits
+ __ cvtdq2ps(kScratchDoubleReg, kScratchDoubleReg); // convert lo exactly
+ __ psrld(dst, 1); // divide by 2 to get in unsigned range
+ __ cvtdq2ps(dst, dst); // convert hi exactly
+ __ addps(dst, dst); // double hi, exactly
+ __ addps(dst, kScratchDoubleReg); // add hi and lo, may round.
+ break;
+ }
case kX64F32x4Abs: {
XMMRegister dst = i.OutputSimd128Register();
XMMRegister src = i.InputSimd128Register(0);
@@ -2248,6 +2264,36 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
}
+ case kX64I32x4SConvertF32x4: {
+ DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ XMMRegister dst = i.OutputSimd128Register();
+ // NAN->0
+ __ movaps(kScratchDoubleReg, dst);
+ __ cmpeqps(kScratchDoubleReg, kScratchDoubleReg);
+ __ pand(dst, kScratchDoubleReg);
+ // Set top bit if >= 0 (but not -0.0!)
+ __ pxor(kScratchDoubleReg, dst);
+ // Convert
+ __ cvttps2dq(dst, dst);
+ // Set top bit if >=0 is now < 0
+ __ pand(kScratchDoubleReg, dst);
+ __ psrad(kScratchDoubleReg, 31);
+ // Set positive overflow lanes to 0x7FFFFFFF
+ __ pxor(dst, kScratchDoubleReg);
+ break;
+ }
+ case kX64I32x4SConvertI16x8Low: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ __ pmovsxwd(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ break;
+ }
+ case kX64I32x4SConvertI16x8High: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ __ palignr(dst, i.InputSimd128Register(0), 8);
+ __ pmovsxwd(dst, dst);
+ break;
+ }
case kX64I32x4Neg: {
CpuFeatureScope sse_scope(tasm(), SSSE3);
XMMRegister dst = i.OutputSimd128Register();
@@ -2319,6 +2365,46 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ pcmpeqd(dst, src);
break;
}
+ case kX64I32x4UConvertF32x4: {
+ DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ XMMRegister tmp = i.ToSimd128Register(instr->TempAt(0));
+ // NAN->0, negative->0
+ __ pxor(kScratchDoubleReg, kScratchDoubleReg);
+ __ maxps(dst, kScratchDoubleReg);
+ // scratch: float representation of max_signed
+ __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+ __ psrld(kScratchDoubleReg, 1); // 0x7fffffff
+ __ cvtdq2ps(kScratchDoubleReg, kScratchDoubleReg); // 0x4f000000
+ // tmp: convert (src-max_signed).
+ // Positive overflow lanes -> 0x7FFFFFFF
+ // Negative lanes -> 0
+ __ movaps(tmp, dst);
+ __ subps(tmp, kScratchDoubleReg);
+ __ cmpleps(kScratchDoubleReg, tmp);
+ __ cvttps2dq(tmp, tmp);
+ __ pxor(tmp, kScratchDoubleReg);
+ __ pxor(kScratchDoubleReg, kScratchDoubleReg);
+ __ pmaxsd(tmp, kScratchDoubleReg);
+ // convert. Overflow lanes above max_signed will be 0x80000000
+ __ cvttps2dq(dst, dst);
+ // Add (src-max_signed) for overflow lanes.
+ __ paddd(dst, tmp);
+ break;
+ }
+ case kX64I32x4UConvertI16x8Low: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ __ pmovzxwd(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ break;
+ }
+ case kX64I32x4UConvertI16x8High: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ __ palignr(dst, i.InputSimd128Register(0), 8);
+ __ pmovzxwd(dst, dst);
+ break;
+ }
case kX64I32x4ShrU: {
__ psrld(i.OutputSimd128Register(), i.InputInt8(1));
break;
@@ -2380,6 +2466,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
}
+ case kX64I16x8SConvertI8x16Low: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ __ pmovsxbw(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ break;
+ }
+ case kX64I16x8SConvertI8x16High: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ __ palignr(dst, i.InputSimd128Register(0), 8);
+ __ pmovsxbw(dst, dst);
+ break;
+ }
case kX64I16x8Neg: {
CpuFeatureScope sse_scope(tasm(), SSSE3);
XMMRegister dst = i.OutputSimd128Register();
@@ -2401,6 +2499,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ psraw(i.OutputSimd128Register(), i.InputInt8(1));
break;
}
+ case kX64I16x8SConvertI32x4: {
+ DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ __ packssdw(i.OutputSimd128Register(), i.InputSimd128Register(1));
+ break;
+ }
case kX64I16x8Add: {
__ paddw(i.OutputSimd128Register(), i.InputSimd128Register(1));
break;
@@ -2459,10 +2562,34 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ pcmpeqw(dst, src);
break;
}
+ case kX64I16x8UConvertI8x16Low: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ __ pmovzxbw(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ break;
+ }
+ case kX64I16x8UConvertI8x16High: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ __ palignr(dst, i.InputSimd128Register(0), 8);
+ __ pmovzxbw(dst, dst);
+ break;
+ }
case kX64I16x8ShrU: {
__ psrlw(i.OutputSimd128Register(), i.InputInt8(1));
break;
}
+ case kX64I16x8UConvertI32x4: {
+ DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ // Change negative lanes to 0x7FFFFFFF
+ __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+ __ psrld(kScratchDoubleReg, 1);
+ __ pminud(dst, kScratchDoubleReg);
+ __ pminud(kScratchDoubleReg, i.InputSimd128Register(1));
+ __ packusdw(dst, kScratchDoubleReg);
+ break;
+ }
case kX64I16x8AddSaturateU: {
__ paddusw(i.OutputSimd128Register(), i.InputSimd128Register(1));
break;
@@ -2524,6 +2651,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
break;
}
+ case kX64I8x16SConvertI16x8: {
+ DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ __ packsswb(i.OutputSimd128Register(), i.InputSimd128Register(1));
+ break;
+ }
case kX64I8x16Neg: {
CpuFeatureScope sse_scope(tasm(), SSSE3);
XMMRegister dst = i.OutputSimd128Register();
@@ -2585,6 +2717,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ pcmpeqb(dst, src);
break;
}
+ case kX64I8x16UConvertI16x8: {
+ DCHECK_EQ(i.OutputSimd128Register(), i.InputSimd128Register(0));
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ XMMRegister dst = i.OutputSimd128Register();
+ // Change negative lanes to 0x7FFF
+ __ pcmpeqw(kScratchDoubleReg, kScratchDoubleReg);
+ __ psrlw(kScratchDoubleReg, 1);
+ __ pminuw(dst, kScratchDoubleReg);
+ __ pminuw(kScratchDoubleReg, i.InputSimd128Register(1));
+ __ packuswb(dst, kScratchDoubleReg);
+ break;
+ }
case kX64I8x16AddSaturateU: {
__ paddusb(i.OutputSimd128Register(), i.InputSimd128Register(1));
break;
@@ -2656,8 +2800,44 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ xorps(dst, i.InputSimd128Register(2));
break;
}
+ case kX64S1x4AnyTrue:
+ case kX64S1x8AnyTrue:
+ case kX64S1x16AnyTrue: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ Register dst = i.OutputRegister();
+ XMMRegister src = i.InputSimd128Register(0);
+ Register tmp = i.TempRegister(0);
+ __ xorq(tmp, tmp);
+ __ movq(dst, Immediate(-1));
+ __ ptest(src, src);
+ __ cmovq(zero, dst, tmp);
+ break;
+ }
+ case kX64S1x4AllTrue:
+ case kX64S1x8AllTrue:
+ case kX64S1x16AllTrue: {
+ CpuFeatureScope sse_scope(tasm(), SSE4_1);
+ Register dst = i.OutputRegister();
+ XMMRegister src = i.InputSimd128Register(0);
+ Register tmp = i.TempRegister(0);
+ __ movq(tmp, Immediate(-1));
+ __ xorq(dst, dst);
+ // Compare all src lanes to false.
+ __ pxor(kScratchDoubleReg, kScratchDoubleReg);
+ if (arch_opcode == kX64S1x4AllTrue) {
+ __ pcmpeqd(kScratchDoubleReg, src);
+ } else if (arch_opcode == kX64S1x8AllTrue) {
+ __ pcmpeqw(kScratchDoubleReg, src);
+ } else {
+ __ pcmpeqb(kScratchDoubleReg, src);
+ }
+ // If kScratchDoubleReg is all zero, none of src lanes are false.
+ __ ptest(kScratchDoubleReg, kScratchDoubleReg);
+ __ cmovq(zero, dst, tmp);
+ break;
+ }
case kX64StackCheck:
- __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
+ __ CompareRoot(rsp, RootIndex::kStackLimit);
break;
case kWord32AtomicExchangeInt8: {
__ xchgb(i.InputRegister(0), i.MemoryOperand(1));
@@ -3273,7 +3453,7 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
break;
case Constant::kHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
- Heap::RootListIndex index;
+ RootIndex index;
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
@@ -3281,6 +3461,11 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
}
+ case Constant::kDelayedStringConstant: {
+ const StringConstantBase* src_constant = src.ToDelayedStringConstant();
+ __ MoveStringConstant(dst, src_constant);
+ break;
+ }
case Constant::kRpoNumber:
UNREACHABLE(); // TODO(dcarney): load of labels on x64.
break;
diff --git a/deps/v8/src/compiler/x64/instruction-codes-x64.h b/deps/v8/src/compiler/x64/instruction-codes-x64.h
index 6a9e313f4e..c2a194e94a 100644
--- a/deps/v8/src/compiler/x64/instruction-codes-x64.h
+++ b/deps/v8/src/compiler/x64/instruction-codes-x64.h
@@ -151,6 +151,8 @@ namespace compiler {
V(X64F32x4Splat) \
V(X64F32x4ExtractLane) \
V(X64F32x4ReplaceLane) \
+ V(X64F32x4SConvertI32x4) \
+ V(X64F32x4UConvertI32x4) \
V(X64F32x4Abs) \
V(X64F32x4Neg) \
V(X64F32x4RecipApprox) \
@@ -168,6 +170,9 @@ namespace compiler {
V(X64I32x4Splat) \
V(X64I32x4ExtractLane) \
V(X64I32x4ReplaceLane) \
+ V(X64I32x4SConvertF32x4) \
+ V(X64I32x4SConvertI16x8Low) \
+ V(X64I32x4SConvertI16x8High) \
V(X64I32x4Neg) \
V(X64I32x4Shl) \
V(X64I32x4ShrS) \
@@ -181,6 +186,9 @@ namespace compiler {
V(X64I32x4Ne) \
V(X64I32x4GtS) \
V(X64I32x4GeS) \
+ V(X64I32x4UConvertF32x4) \
+ V(X64I32x4UConvertI16x8Low) \
+ V(X64I32x4UConvertI16x8High) \
V(X64I32x4ShrU) \
V(X64I32x4MinU) \
V(X64I32x4MaxU) \
@@ -189,9 +197,12 @@ namespace compiler {
V(X64I16x8Splat) \
V(X64I16x8ExtractLane) \
V(X64I16x8ReplaceLane) \
+ V(X64I16x8SConvertI8x16Low) \
+ V(X64I16x8SConvertI8x16High) \
V(X64I16x8Neg) \
V(X64I16x8Shl) \
V(X64I16x8ShrS) \
+ V(X64I16x8SConvertI32x4) \
V(X64I16x8Add) \
V(X64I16x8AddSaturateS) \
V(X64I16x8AddHoriz) \
@@ -204,7 +215,10 @@ namespace compiler {
V(X64I16x8Ne) \
V(X64I16x8GtS) \
V(X64I16x8GeS) \
+ V(X64I16x8UConvertI8x16Low) \
+ V(X64I16x8UConvertI8x16High) \
V(X64I16x8ShrU) \
+ V(X64I16x8UConvertI32x4) \
V(X64I16x8AddSaturateU) \
V(X64I16x8SubSaturateU) \
V(X64I16x8MinU) \
@@ -214,6 +228,7 @@ namespace compiler {
V(X64I8x16Splat) \
V(X64I8x16ExtractLane) \
V(X64I8x16ReplaceLane) \
+ V(X64I8x16SConvertI16x8) \
V(X64I8x16Neg) \
V(X64I8x16Add) \
V(X64I8x16AddSaturateS) \
@@ -225,6 +240,7 @@ namespace compiler {
V(X64I8x16Ne) \
V(X64I8x16GtS) \
V(X64I8x16GeS) \
+ V(X64I8x16UConvertI16x8) \
V(X64I8x16AddSaturateU) \
V(X64I8x16SubSaturateU) \
V(X64I8x16MinU) \
@@ -237,6 +253,12 @@ namespace compiler {
V(X64S128Not) \
V(X64S128Select) \
V(X64S128Zero) \
+ V(X64S1x4AnyTrue) \
+ V(X64S1x4AllTrue) \
+ V(X64S1x8AnyTrue) \
+ V(X64S1x8AllTrue) \
+ V(X64S1x16AnyTrue) \
+ V(X64S1x16AllTrue) \
V(X64Word64AtomicLoadUint8) \
V(X64Word64AtomicLoadUint16) \
V(X64Word64AtomicLoadUint32) \
diff --git a/deps/v8/src/compiler/x64/instruction-scheduler-x64.cc b/deps/v8/src/compiler/x64/instruction-scheduler-x64.cc
index b1f380badf..e5523fd49d 100644
--- a/deps/v8/src/compiler/x64/instruction-scheduler-x64.cc
+++ b/deps/v8/src/compiler/x64/instruction-scheduler-x64.cc
@@ -128,6 +128,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64F32x4Splat:
case kX64F32x4ExtractLane:
case kX64F32x4ReplaceLane:
+ case kX64F32x4SConvertI32x4:
+ case kX64F32x4UConvertI32x4:
case kX64F32x4RecipApprox:
case kX64F32x4RecipSqrtApprox:
case kX64F32x4Abs:
@@ -145,6 +147,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I32x4Splat:
case kX64I32x4ExtractLane:
case kX64I32x4ReplaceLane:
+ case kX64I32x4SConvertF32x4:
+ case kX64I32x4SConvertI16x8Low:
+ case kX64I32x4SConvertI16x8High:
case kX64I32x4Neg:
case kX64I32x4Shl:
case kX64I32x4ShrS:
@@ -158,6 +163,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I32x4Ne:
case kX64I32x4GtS:
case kX64I32x4GeS:
+ case kX64I32x4UConvertF32x4:
+ case kX64I32x4UConvertI16x8Low:
+ case kX64I32x4UConvertI16x8High:
case kX64I32x4ShrU:
case kX64I32x4MinU:
case kX64I32x4MaxU:
@@ -166,9 +174,12 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I16x8Splat:
case kX64I16x8ExtractLane:
case kX64I16x8ReplaceLane:
+ case kX64I16x8SConvertI8x16Low:
+ case kX64I16x8SConvertI8x16High:
case kX64I16x8Neg:
case kX64I16x8Shl:
case kX64I16x8ShrS:
+ case kX64I16x8SConvertI32x4:
case kX64I16x8Add:
case kX64I16x8AddSaturateS:
case kX64I16x8AddHoriz:
@@ -181,6 +192,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I16x8Ne:
case kX64I16x8GtS:
case kX64I16x8GeS:
+ case kX64I16x8UConvertI8x16Low:
+ case kX64I16x8UConvertI8x16High:
+ case kX64I16x8UConvertI32x4:
case kX64I16x8ShrU:
case kX64I16x8AddSaturateU:
case kX64I16x8SubSaturateU:
@@ -191,6 +205,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I8x16Splat:
case kX64I8x16ExtractLane:
case kX64I8x16ReplaceLane:
+ case kX64I8x16SConvertI16x8:
case kX64I8x16Neg:
case kX64I8x16Add:
case kX64I8x16AddSaturateS:
@@ -202,6 +217,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64I8x16Ne:
case kX64I8x16GtS:
case kX64I8x16GeS:
+ case kX64I8x16UConvertI16x8:
case kX64I8x16AddSaturateU:
case kX64I8x16SubSaturateU:
case kX64I8x16MinU:
@@ -214,6 +230,12 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64S128Not:
case kX64S128Select:
case kX64S128Zero:
+ case kX64S1x4AnyTrue:
+ case kX64S1x4AllTrue:
+ case kX64S1x8AnyTrue:
+ case kX64S1x8AllTrue:
+ case kX64S1x16AnyTrue:
+ case kX64S1x16AllTrue:
return (instr->addressing_mode() == kMode_None)
? kNoOpcodeFlags
: kIsLoadOperation | kHasSideEffect;
diff --git a/deps/v8/src/compiler/x64/instruction-selector-x64.cc b/deps/v8/src/compiler/x64/instruction-selector-x64.cc
index b5d7fa6d55..211794ace8 100644
--- a/deps/v8/src/compiler/x64/instruction-selector-x64.cc
+++ b/deps/v8/src/compiler/x64/instruction-selector-x64.cc
@@ -1273,6 +1273,7 @@ void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input,
V(Float64Sqrt, kSSEFloat64Sqrt) \
V(Float32Sqrt, kSSEFloat32Sqrt) \
V(ChangeFloat64ToInt32, kSSEFloat64ToInt32) \
+ V(ChangeFloat64ToInt64, kSSEFloat64ToInt64) \
V(ChangeFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(1)) \
V(TruncateFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(0)) \
V(ChangeFloat64ToUint64, kSSEFloat64ToUint64) \
@@ -1281,6 +1282,7 @@ void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input,
V(TruncateFloat32ToInt32, kSSEFloat32ToInt32) \
V(TruncateFloat32ToUint32, kSSEFloat32ToUint32) \
V(ChangeInt32ToFloat64, kSSEInt32ToFloat64) \
+ V(ChangeInt64ToFloat64, kSSEInt64ToFloat64) \
V(ChangeUint32ToFloat64, kSSEUint32ToFloat64) \
V(RoundFloat64ToInt32, kSSEFloat64ToInt32) \
V(RoundInt32ToFloat32, kSSEInt32ToFloat32) \
@@ -1665,6 +1667,17 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
Node* left = node->InputAt(0);
Node* right = node->InputAt(1);
+ // The 32-bit comparisons automatically truncate Word64
+ // values to Word32 range, no need to do that explicitly.
+ if (opcode == kX64Cmp32 || opcode == kX64Test32) {
+ while (left->opcode() == IrOpcode::kTruncateInt64ToInt32) {
+ left = left->InputAt(0);
+ }
+ while (right->opcode() == IrOpcode::kTruncateInt64ToInt32) {
+ right = right->InputAt(0);
+ }
+ }
+
opcode = TryNarrowOpcodeSize(opcode, left, right, cont);
// If one of the two inputs is an immediate, make sure it's on the right, or
@@ -1708,7 +1721,7 @@ void VisitWord64Compare(InstructionSelector* selector, Node* node,
X64OperandGenerator g(selector);
if (selector->CanUseRootsRegister()) {
Heap* const heap = selector->isolate()->heap();
- Heap::RootListIndex root_index;
+ RootIndex root_index;
HeapObjectBinopMatcher m(node);
if (m.right().HasValue() &&
heap->IsRootHandle(m.right().Value(), &root_index)) {
@@ -2483,6 +2496,7 @@ VISIT_ATOMIC_BINOP(Xor)
V(I32x4MaxU) \
V(I32x4GtU) \
V(I32x4GeU) \
+ V(I16x8SConvertI32x4) \
V(I16x8Add) \
V(I16x8AddSaturateS) \
V(I16x8AddHoriz) \
@@ -2501,6 +2515,7 @@ VISIT_ATOMIC_BINOP(Xor)
V(I16x8MaxU) \
V(I16x8GtU) \
V(I16x8GeU) \
+ V(I8x16SConvertI16x8) \
V(I8x16Add) \
V(I8x16AddSaturateS) \
V(I8x16Sub) \
@@ -2521,14 +2536,23 @@ VISIT_ATOMIC_BINOP(Xor)
V(S128Or) \
V(S128Xor)
-#define SIMD_UNOP_LIST(V) \
- V(F32x4Abs) \
- V(F32x4Neg) \
- V(F32x4RecipApprox) \
- V(F32x4RecipSqrtApprox) \
- V(I32x4Neg) \
- V(I16x8Neg) \
- V(I8x16Neg) \
+#define SIMD_UNOP_LIST(V) \
+ V(F32x4SConvertI32x4) \
+ V(F32x4Abs) \
+ V(F32x4Neg) \
+ V(F32x4RecipApprox) \
+ V(F32x4RecipSqrtApprox) \
+ V(I32x4SConvertI16x8Low) \
+ V(I32x4SConvertI16x8High) \
+ V(I32x4Neg) \
+ V(I32x4UConvertI16x8Low) \
+ V(I32x4UConvertI16x8High) \
+ V(I16x8SConvertI8x16Low) \
+ V(I16x8SConvertI8x16High) \
+ V(I16x8Neg) \
+ V(I16x8UConvertI8x16Low) \
+ V(I16x8UConvertI8x16High) \
+ V(I8x16Neg) \
V(S128Not)
#define SIMD_SHIFT_OPCODES(V) \
@@ -2539,6 +2563,16 @@ VISIT_ATOMIC_BINOP(Xor)
V(I16x8ShrS) \
V(I16x8ShrU)
+#define SIMD_ANYTRUE_LIST(V) \
+ V(S1x4AnyTrue) \
+ V(S1x8AnyTrue) \
+ V(S1x16AnyTrue)
+
+#define SIMD_ALLTRUE_LIST(V) \
+ V(S1x4AllTrue) \
+ V(S1x8AllTrue) \
+ V(S1x16AllTrue)
+
void InstructionSelector::VisitS128Zero(Node* node) {
X64OperandGenerator g(this);
Emit(kX64S128Zero, g.DefineAsRegister(node), g.DefineAsRegister(node));
@@ -2583,6 +2617,7 @@ SIMD_TYPES(VISIT_SIMD_REPLACE_LANE)
}
SIMD_SHIFT_OPCODES(VISIT_SIMD_SHIFT)
#undef VISIT_SIMD_SHIFT
+#undef SIMD_SHIFT_OPCODES
#define VISIT_SIMD_UNOP(Opcode) \
void InstructionSelector::Visit##Opcode(Node* node) { \
@@ -2592,6 +2627,7 @@ SIMD_SHIFT_OPCODES(VISIT_SIMD_SHIFT)
}
SIMD_UNOP_LIST(VISIT_SIMD_UNOP)
#undef VISIT_SIMD_UNOP
+#undef SIMD_UNOP_LIST
#define VISIT_SIMD_BINOP(Opcode) \
void InstructionSelector::Visit##Opcode(Node* node) { \
@@ -2601,10 +2637,30 @@ SIMD_UNOP_LIST(VISIT_SIMD_UNOP)
}
SIMD_BINOP_LIST(VISIT_SIMD_BINOP)
#undef VISIT_SIMD_BINOP
-#undef SIMD_TYPES
#undef SIMD_BINOP_LIST
-#undef SIMD_UNOP_LIST
-#undef SIMD_SHIFT_OPCODES
+
+#define VISIT_SIMD_ANYTRUE(Opcode) \
+ void InstructionSelector::Visit##Opcode(Node* node) { \
+ X64OperandGenerator g(this); \
+ InstructionOperand temps[] = {g.TempRegister()}; \
+ Emit(kX64##Opcode, g.DefineAsRegister(node), \
+ g.UseUniqueRegister(node->InputAt(0)), arraysize(temps), temps); \
+ }
+SIMD_ANYTRUE_LIST(VISIT_SIMD_ANYTRUE)
+#undef VISIT_SIMD_ANYTRUE
+#undef SIMD_ANYTRUE_LIST
+
+#define VISIT_SIMD_ALLTRUE(Opcode) \
+ void InstructionSelector::Visit##Opcode(Node* node) { \
+ X64OperandGenerator g(this); \
+ InstructionOperand temps[] = {g.TempRegister()}; \
+ Emit(kX64##Opcode, g.DefineAsRegister(node), \
+ g.UseUniqueRegister(node->InputAt(0)), arraysize(temps), temps); \
+ }
+SIMD_ALLTRUE_LIST(VISIT_SIMD_ALLTRUE)
+#undef VISIT_SIMD_ALLTRUE
+#undef SIMD_ALLTRUE_LIST
+#undef SIMD_TYPES
void InstructionSelector::VisitS128Select(Node* node) {
X64OperandGenerator g(this);
@@ -2613,6 +2669,36 @@ void InstructionSelector::VisitS128Select(Node* node) {
g.UseRegister(node->InputAt(2)));
}
+void InstructionSelector::VisitF32x4UConvertI32x4(Node* node) {
+ X64OperandGenerator g(this);
+ Emit(kX64F32x4UConvertI32x4, g.DefineSameAsFirst(node),
+ g.UseRegister(node->InputAt(0)));
+}
+
+void InstructionSelector::VisitI32x4SConvertF32x4(Node* node) {
+ X64OperandGenerator g(this);
+ Emit(kX64I32x4SConvertF32x4, g.DefineSameAsFirst(node),
+ g.UseRegister(node->InputAt(0)));
+}
+
+void InstructionSelector::VisitI32x4UConvertF32x4(Node* node) {
+ X64OperandGenerator g(this);
+ Emit(kX64I32x4UConvertF32x4, g.DefineSameAsFirst(node),
+ g.UseRegister(node->InputAt(0)));
+}
+
+void InstructionSelector::VisitI16x8UConvertI32x4(Node* node) {
+ X64OperandGenerator g(this);
+ Emit(kX64I16x8UConvertI32x4, g.DefineSameAsFirst(node),
+ g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+}
+
+void InstructionSelector::VisitI8x16UConvertI16x8(Node* node) {
+ X64OperandGenerator g(this);
+ Emit(kX64I8x16UConvertI16x8, g.DefineSameAsFirst(node),
+ g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+}
+
void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) {
UNREACHABLE();
}