diff options
author | Michaël Zasso <targos@protonmail.com> | 2016-12-23 16:30:57 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-01-26 22:46:17 +0100 |
commit | 2739185b790e040c3b044c577327f5d44bffad4a (patch) | |
tree | 29a466999212f4c85958379d9d400eec8a185ba5 /deps/v8/src/compiler/arm | |
parent | a67a04d7654faaa04c8da00e42981ebc9fd0911c (diff) | |
download | node-new-2739185b790e040c3b044c577327f5d44bffad4a.tar.gz |
deps: update V8 to 5.5.372.40
PR-URL: https://github.com/nodejs/node/pull/9618
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/compiler/arm')
-rw-r--r-- | deps/v8/src/compiler/arm/code-generator-arm.cc | 279 | ||||
-rw-r--r-- | deps/v8/src/compiler/arm/instruction-selector-arm.cc | 28 |
2 files changed, 138 insertions, 169 deletions
diff --git a/deps/v8/src/compiler/arm/code-generator-arm.cc b/deps/v8/src/compiler/arm/code-generator-arm.cc index 4ae282a0d1..dbe182802a 100644 --- a/deps/v8/src/compiler/arm/code-generator-arm.cc +++ b/deps/v8/src/compiler/arm/code-generator-arm.cc @@ -5,7 +5,7 @@ #include "src/compiler/code-generator.h" #include "src/arm/macro-assembler-arm.h" -#include "src/ast/scopes.h" +#include "src/compilation-info.h" #include "src/compiler/code-generator-impl.h" #include "src/compiler/gap-resolver.h" #include "src/compiler/node-matchers.h" @@ -271,6 +271,37 @@ class OutOfLineRecordWrite final : public OutOfLineCode { UnwindingInfoWriter* const unwinding_info_writer_; }; +template <typename T> +class OutOfLineFloatMin final : public OutOfLineCode { + public: + OutOfLineFloatMin(CodeGenerator* gen, T result, T left, T right) + : OutOfLineCode(gen), result_(result), left_(left), right_(right) {} + + void Generate() final { __ FloatMinOutOfLine(result_, left_, right_); } + + private: + T const result_; + T const left_; + T const right_; +}; +typedef OutOfLineFloatMin<SwVfpRegister> OutOfLineFloat32Min; +typedef OutOfLineFloatMin<DwVfpRegister> OutOfLineFloat64Min; + +template <typename T> +class OutOfLineFloatMax final : public OutOfLineCode { + public: + OutOfLineFloatMax(CodeGenerator* gen, T result, T left, T right) + : OutOfLineCode(gen), result_(result), left_(left), right_(right) {} + + void Generate() final { __ FloatMaxOutOfLine(result_, left_, right_); } + + private: + T const result_; + T const left_; + T const right_; +}; +typedef OutOfLineFloatMax<SwVfpRegister> OutOfLineFloat32Max; +typedef OutOfLineFloatMax<DwVfpRegister> OutOfLineFloat64Max; Condition FlagsConditionToCondition(FlagsCondition condition) { switch (condition) { @@ -707,9 +738,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArchDebugBreak: __ stop("kArchDebugBreak"); break; - case kArchImpossible: - __ Abort(kConversionFromImpossibleValue); - break; case kArchComment: { Address comment_string = i.InputExternalReference(0).address(); __ RecordComment(reinterpret_cast<const char*>(comment_string)); @@ -725,8 +753,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore()); Deoptimizer::BailoutType bailout_type = Deoptimizer::BailoutType(MiscField::decode(instr->opcode())); - CodeGenResult result = - AssembleDeoptimizerCall(deopt_state_id, bailout_type); + CodeGenResult result = AssembleDeoptimizerCall( + deopt_state_id, bailout_type, current_source_position_); if (result != kSuccess) return result; break; } @@ -1199,33 +1227,51 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kArmVnegF64: __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; - case kArmVrintmF32: + case kArmVrintmF32: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintm(i.OutputFloat32Register(), i.InputFloat32Register(0)); break; - case kArmVrintmF64: + } + case kArmVrintmF64: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; - case kArmVrintpF32: + } + case kArmVrintpF32: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintp(i.OutputFloat32Register(), i.InputFloat32Register(0)); break; - case kArmVrintpF64: + } + case kArmVrintpF64: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; - case kArmVrintzF32: + } + case kArmVrintzF32: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintz(i.OutputFloat32Register(), i.InputFloat32Register(0)); break; - case kArmVrintzF64: + } + case kArmVrintzF64: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; - case kArmVrintaF64: + } + case kArmVrintaF64: { + CpuFeatureScope scope(masm(), ARMv8); __ vrinta(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; - case kArmVrintnF32: + } + case kArmVrintnF32: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintn(i.OutputFloat32Register(), i.InputFloat32Register(0)); break; - case kArmVrintnF64: + } + case kArmVrintnF64: { + CpuFeatureScope scope(masm(), ARMv8); __ vrintn(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); break; + } case kArmVcvtF32F64: { __ vcvt_f32_f64(i.OutputFloat32Register(), i.InputDoubleRegister(0)); DCHECK_EQ(LeaveCC, i.OutputSBit()); @@ -1380,145 +1426,59 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( DCHECK_EQ(LeaveCC, i.OutputSBit()); break; case kArmFloat32Max: { - FloatRegister left_reg = i.InputFloat32Register(0); - FloatRegister right_reg = i.InputFloat32Register(1); - FloatRegister result_reg = i.OutputFloat32Register(); - Label result_is_nan, return_left, return_right, check_zero, done; - __ VFPCompareAndSetFlags(left_reg, right_reg); - __ b(mi, &return_right); - __ b(gt, &return_left); - __ b(vs, &result_is_nan); - // Left equals right => check for -0. - __ VFPCompareAndSetFlags(left_reg, 0.0); - if (left_reg.is(result_reg) || right_reg.is(result_reg)) { - __ b(ne, &done); // left == right != 0. + SwVfpRegister result = i.OutputFloat32Register(); + SwVfpRegister left = i.InputFloat32Register(0); + SwVfpRegister right = i.InputFloat32Register(1); + if (left.is(right)) { + __ Move(result, left); } else { - __ b(ne, &return_left); // left == right != 0. + auto ool = new (zone()) OutOfLineFloat32Max(this, result, left, right); + __ FloatMax(result, left, right, ool->entry()); + __ bind(ool->exit()); } - // At this point, both left and right are either 0 or -0. - // Since we operate on +0 and/or -0, vadd and vand have the same effect; - // the decision for vadd is easy because vand is a NEON instruction. - __ vadd(result_reg, left_reg, right_reg); - __ b(&done); - __ bind(&result_is_nan); - __ vadd(result_reg, left_reg, right_reg); - __ b(&done); - __ bind(&return_right); - __ Move(result_reg, right_reg); - if (!left_reg.is(result_reg)) __ b(&done); - __ bind(&return_left); - __ Move(result_reg, left_reg); - __ bind(&done); + DCHECK_EQ(LeaveCC, i.OutputSBit()); break; } case kArmFloat64Max: { - DwVfpRegister left_reg = i.InputDoubleRegister(0); - DwVfpRegister right_reg = i.InputDoubleRegister(1); - DwVfpRegister result_reg = i.OutputDoubleRegister(); - Label result_is_nan, return_left, return_right, check_zero, done; - __ VFPCompareAndSetFlags(left_reg, right_reg); - __ b(mi, &return_right); - __ b(gt, &return_left); - __ b(vs, &result_is_nan); - // Left equals right => check for -0. - __ VFPCompareAndSetFlags(left_reg, 0.0); - if (left_reg.is(result_reg) || right_reg.is(result_reg)) { - __ b(ne, &done); // left == right != 0. + DwVfpRegister result = i.OutputDoubleRegister(); + DwVfpRegister left = i.InputDoubleRegister(0); + DwVfpRegister right = i.InputDoubleRegister(1); + if (left.is(right)) { + __ Move(result, left); } else { - __ b(ne, &return_left); // left == right != 0. + auto ool = new (zone()) OutOfLineFloat64Max(this, result, left, right); + __ FloatMax(result, left, right, ool->entry()); + __ bind(ool->exit()); } - // At this point, both left and right are either 0 or -0. - // Since we operate on +0 and/or -0, vadd and vand have the same effect; - // the decision for vadd is easy because vand is a NEON instruction. - __ vadd(result_reg, left_reg, right_reg); - __ b(&done); - __ bind(&result_is_nan); - __ vadd(result_reg, left_reg, right_reg); - __ b(&done); - __ bind(&return_right); - __ Move(result_reg, right_reg); - if (!left_reg.is(result_reg)) __ b(&done); - __ bind(&return_left); - __ Move(result_reg, left_reg); - __ bind(&done); + DCHECK_EQ(LeaveCC, i.OutputSBit()); break; } case kArmFloat32Min: { - FloatRegister left_reg = i.InputFloat32Register(0); - FloatRegister right_reg = i.InputFloat32Register(1); - FloatRegister result_reg = i.OutputFloat32Register(); - Label result_is_nan, return_left, return_right, check_zero, done; - __ VFPCompareAndSetFlags(left_reg, right_reg); - __ b(mi, &return_left); - __ b(gt, &return_right); - __ b(vs, &result_is_nan); - // Left equals right => check for -0. - __ VFPCompareAndSetFlags(left_reg, 0.0); - if (left_reg.is(result_reg) || right_reg.is(result_reg)) { - __ b(ne, &done); // left == right != 0. + SwVfpRegister result = i.OutputFloat32Register(); + SwVfpRegister left = i.InputFloat32Register(0); + SwVfpRegister right = i.InputFloat32Register(1); + if (left.is(right)) { + __ Move(result, left); } else { - __ b(ne, &return_left); // left == right != 0. + auto ool = new (zone()) OutOfLineFloat32Min(this, result, left, right); + __ FloatMin(result, left, right, ool->entry()); + __ bind(ool->exit()); } - // At this point, both left and right are either 0 or -0. - // We could use a single 'vorr' instruction here if we had NEON support. - // The algorithm is: -((-L) + (-R)), which in case of L and R being - // different registers is most efficiently expressed as -((-L) - R). - __ vneg(left_reg, left_reg); - if (left_reg.is(right_reg)) { - __ vadd(result_reg, left_reg, right_reg); - } else { - __ vsub(result_reg, left_reg, right_reg); - } - __ vneg(result_reg, result_reg); - __ b(&done); - __ bind(&result_is_nan); - __ vadd(result_reg, left_reg, right_reg); - __ b(&done); - __ bind(&return_right); - __ Move(result_reg, right_reg); - if (!left_reg.is(result_reg)) __ b(&done); - __ bind(&return_left); - __ Move(result_reg, left_reg); - __ bind(&done); + DCHECK_EQ(LeaveCC, i.OutputSBit()); break; } case kArmFloat64Min: { - DwVfpRegister left_reg = i.InputDoubleRegister(0); - DwVfpRegister right_reg = i.InputDoubleRegister(1); - DwVfpRegister result_reg = i.OutputDoubleRegister(); - Label result_is_nan, return_left, return_right, check_zero, done; - __ VFPCompareAndSetFlags(left_reg, right_reg); - __ b(mi, &return_left); - __ b(gt, &return_right); - __ b(vs, &result_is_nan); - // Left equals right => check for -0. - __ VFPCompareAndSetFlags(left_reg, 0.0); - if (left_reg.is(result_reg) || right_reg.is(result_reg)) { - __ b(ne, &done); // left == right != 0. - } else { - __ b(ne, &return_left); // left == right != 0. - } - // At this point, both left and right are either 0 or -0. - // We could use a single 'vorr' instruction here if we had NEON support. - // The algorithm is: -((-L) + (-R)), which in case of L and R being - // different registers is most efficiently expressed as -((-L) - R). - __ vneg(left_reg, left_reg); - if (left_reg.is(right_reg)) { - __ vadd(result_reg, left_reg, right_reg); + DwVfpRegister result = i.OutputDoubleRegister(); + DwVfpRegister left = i.InputDoubleRegister(0); + DwVfpRegister right = i.InputDoubleRegister(1); + if (left.is(right)) { + __ Move(result, left); } else { - __ vsub(result_reg, left_reg, right_reg); + auto ool = new (zone()) OutOfLineFloat64Min(this, result, left, right); + __ FloatMin(result, left, right, ool->entry()); + __ bind(ool->exit()); } - __ vneg(result_reg, result_reg); - __ b(&done); - __ bind(&result_is_nan); - __ vadd(result_reg, left_reg, right_reg); - __ b(&done); - __ bind(&return_right); - __ Move(result_reg, right_reg); - if (!left_reg.is(result_reg)) __ b(&done); - __ bind(&return_left); - __ Move(result_reg, left_reg); - __ bind(&done); + DCHECK_EQ(LeaveCC, i.OutputSBit()); break; } case kArmFloat64SilenceNaN: { @@ -1679,7 +1639,8 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { } CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall( - int deoptimization_id, Deoptimizer::BailoutType bailout_type) { + int deoptimization_id, Deoptimizer::BailoutType bailout_type, + SourcePosition pos) { Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( isolate(), deoptimization_id, bailout_type); // TODO(turbofan): We should be able to generate better code by sharing the @@ -1688,7 +1649,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall( if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts; DeoptimizeReason deoptimization_reason = GetDeoptimizationReason(deoptimization_id); - __ RecordDeoptReason(deoptimization_reason, 0, deoptimization_id); + __ RecordDeoptReason(deoptimization_reason, pos.raw(), deoptimization_id); __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); __ CheckConstPool(false, false); return kSuccess; @@ -1967,33 +1928,31 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source, __ vstr(temp_1, src); } else if (source->IsFPRegister()) { LowDwVfpRegister temp = kScratchDoubleReg; - DwVfpRegister src = g.ToDoubleRegister(source); - if (destination->IsFPRegister()) { - DwVfpRegister dst = g.ToDoubleRegister(destination); - __ Move(temp, src); - __ Move(src, dst); - __ Move(dst, temp); - } else { - DCHECK(destination->IsFPStackSlot()); - MemOperand dst = g.ToMemOperand(destination); - __ Move(temp, src); - __ vldr(src, dst); - __ vstr(temp, dst); - } + DwVfpRegister src = g.ToDoubleRegister(source); + if (destination->IsFPRegister()) { + DwVfpRegister dst = g.ToDoubleRegister(destination); + __ vswp(src, dst); + } else { + DCHECK(destination->IsFPStackSlot()); + MemOperand dst = g.ToMemOperand(destination); + __ Move(temp, src); + __ vldr(src, dst); + __ vstr(temp, dst); + } } else if (source->IsFPStackSlot()) { DCHECK(destination->IsFPStackSlot()); Register temp_0 = kScratchReg; LowDwVfpRegister temp_1 = kScratchDoubleReg; MemOperand src0 = g.ToMemOperand(source); MemOperand dst0 = g.ToMemOperand(destination); - MemOperand src1(src0.rn(), src0.offset() + kPointerSize); - MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize); - __ vldr(temp_1, dst0); // Save destination in temp_1. - __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. - __ str(temp_0, dst0); - __ ldr(temp_0, src1); - __ str(temp_0, dst1); - __ vstr(temp_1, src0); + MemOperand src1(src0.rn(), src0.offset() + kPointerSize); + MemOperand dst1(dst0.rn(), dst0.offset() + kPointerSize); + __ vldr(temp_1, dst0); // Save destination in temp_1. + __ ldr(temp_0, src0); // Then use temp_0 to copy source to destination. + __ str(temp_0, dst0); + __ ldr(temp_0, src1); + __ str(temp_0, dst1); + __ vstr(temp_1, src0); } else { // No other combinations are possible. UNREACHABLE(); diff --git a/deps/v8/src/compiler/arm/instruction-selector-arm.cc b/deps/v8/src/compiler/arm/instruction-selector-arm.cc index 4b0b6afb44..ceb5b2507f 100644 --- a/deps/v8/src/compiler/arm/instruction-selector-arm.cc +++ b/deps/v8/src/compiler/arm/instruction-selector-arm.cc @@ -252,14 +252,7 @@ void VisitBinop(InstructionSelector* selector, Node* node, inputs[input_count++] = g.Label(cont->false_block()); } - if (cont->IsDeoptimize()) { - // If we can deoptimize as a result of the binop, we need to make sure that - // the deopt inputs are not overwritten by the binop result. One way - // to achieve that is to declare the output register as same-as-first. - outputs[output_count++] = g.DefineSameAsFirst(node); - } else { - outputs[output_count++] = g.DefineAsRegister(node); - } + outputs[output_count++] = g.DefineAsRegister(node); if (cont->IsSet()) { outputs[output_count++] = g.DefineAsRegister(cont->result()); } @@ -419,6 +412,10 @@ void InstructionSelector::VisitLoad(Node* node) { EmitLoad(this, opcode, &output, base, index); } +void InstructionSelector::VisitProtectedLoad(Node* node) { + // TODO(eholk) + UNIMPLEMENTED(); +} void InstructionSelector::VisitStore(Node* node) { ArmOperandGenerator g(this); @@ -431,7 +428,7 @@ void InstructionSelector::VisitStore(Node* node) { MachineRepresentation rep = store_rep.representation(); if (write_barrier_kind != kNoWriteBarrier) { - DCHECK_EQ(MachineRepresentation::kTagged, rep); + DCHECK(CanBeTaggedPointer(rep)); AddressingMode addressing_mode; InstructionOperand inputs[3]; size_t input_count = 0; @@ -1516,46 +1513,55 @@ void InstructionSelector::VisitFloat64Sqrt(Node* node) { void InstructionSelector::VisitFloat32RoundDown(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintmF32, node); } void InstructionSelector::VisitFloat64RoundDown(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintmF64, node); } void InstructionSelector::VisitFloat32RoundUp(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintpF32, node); } void InstructionSelector::VisitFloat64RoundUp(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintpF64, node); } void InstructionSelector::VisitFloat32RoundTruncate(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintzF32, node); } void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintzF64, node); } void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintaF64, node); } void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintnF32, node); } void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) { + DCHECK(CpuFeatures::IsSupported(ARMv8)); VisitRR(this, kArmVrintnF64, node); } @@ -1965,6 +1971,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, break; } + if (user->opcode() == IrOpcode::kWord32Equal) { + return VisitWordCompare(selector, user, cont); + } + // Continuation could not be combined with a compare, emit compare against 0. ArmOperandGenerator g(selector); InstructionCode const opcode = |