diff options
Diffstat (limited to 'deps/v8/src/compiler/x64')
-rw-r--r-- | deps/v8/src/compiler/x64/code-generator-x64.cc | 213 | ||||
-rw-r--r-- | deps/v8/src/compiler/x64/instruction-codes-x64.h | 22 | ||||
-rw-r--r-- | deps/v8/src/compiler/x64/instruction-scheduler-x64.cc | 22 | ||||
-rw-r--r-- | deps/v8/src/compiler/x64/instruction-selector-x64.cc | 110 |
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(); } |