diff options
Diffstat (limited to 'deps/v8/src/compiler/arm/instruction-selector-arm.cc')
-rw-r--r-- | deps/v8/src/compiler/arm/instruction-selector-arm.cc | 202 |
1 files changed, 176 insertions, 26 deletions
diff --git a/deps/v8/src/compiler/arm/instruction-selector-arm.cc b/deps/v8/src/compiler/arm/instruction-selector-arm.cc index 14b30b1af0..76d9e3c66d 100644 --- a/deps/v8/src/compiler/arm/instruction-selector-arm.cc +++ b/deps/v8/src/compiler/arm/instruction-selector-arm.cc @@ -237,8 +237,13 @@ void VisitBinop(InstructionSelector* selector, Node* node, DCHECK_GE(arraysize(outputs), output_count); DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); - selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, - inputs); + opcode = cont->Encode(opcode); + if (cont->IsDeoptimize()) { + selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, + cont->frame_state()); + } else { + selector->Emit(opcode, output_count, outputs, input_count, inputs); + } } @@ -369,9 +374,7 @@ void InstructionSelector::VisitStore(Node* node) { inputs[input_count++] = g.UseUniqueRegister(index); addressing_mode = kMode_Offset_RR; } - inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) - ? g.UseRegister(value) - : g.UseUniqueRegister(value); + inputs[input_count++] = g.UseUniqueRegister(value); RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; switch (write_barrier_kind) { case kNoWriteBarrier: @@ -691,8 +694,13 @@ void VisitShift(InstructionSelector* selector, Node* node, DCHECK_GE(arraysize(outputs), output_count); DCHECK_NE(kMode_None, AddressingModeField::decode(opcode)); - selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, - inputs); + opcode = cont->Encode(opcode); + if (cont->IsDeoptimize()) { + selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, + cont->frame_state()); + } else { + selector->Emit(opcode, output_count, outputs, input_count, inputs); + } } @@ -759,6 +767,120 @@ void InstructionSelector::VisitWord32Sar(Node* node) { VisitShift(this, node, TryMatchASR); } +void InstructionSelector::VisitInt32PairAdd(Node* node) { + ArmOperandGenerator g(this); + + // We use UseUniqueRegister here to avoid register sharing with the output + // registers. + InstructionOperand inputs[] = { + g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), + g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; + + InstructionOperand outputs[] = { + g.DefineAsRegister(node), + g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + + Emit(kArmAddPair, 2, outputs, 4, inputs); +} + +void InstructionSelector::VisitInt32PairSub(Node* node) { + ArmOperandGenerator g(this); + + // We use UseUniqueRegister here to avoid register sharing with the output + // register. + InstructionOperand inputs[] = { + g.UseRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(1)), + g.UseRegister(node->InputAt(2)), g.UseUniqueRegister(node->InputAt(3))}; + + InstructionOperand outputs[] = { + g.DefineAsRegister(node), + g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + + Emit(kArmSubPair, 2, outputs, 4, inputs); +} + +void InstructionSelector::VisitInt32PairMul(Node* node) { + ArmOperandGenerator g(this); + InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), + g.UseUniqueRegister(node->InputAt(1)), + g.UseUniqueRegister(node->InputAt(2)), + g.UseUniqueRegister(node->InputAt(3))}; + + InstructionOperand outputs[] = { + g.DefineAsRegister(node), + g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + + Emit(kArmMulPair, 2, outputs, 4, inputs); +} + +void InstructionSelector::VisitWord32PairShl(Node* node) { + ArmOperandGenerator g(this); + // We use g.UseUniqueRegister here for InputAt(0) to guarantee that there is + // no register aliasing with output registers. + Int32Matcher m(node->InputAt(2)); + InstructionOperand shift_operand; + if (m.HasValue()) { + shift_operand = g.UseImmediate(m.node()); + } else { + shift_operand = g.UseUniqueRegister(m.node()); + } + + InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)), + g.UseRegister(node->InputAt(1)), + shift_operand}; + + InstructionOperand outputs[] = { + g.DefineAsRegister(node), + g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + + Emit(kArmLslPair, 2, outputs, 3, inputs); +} + +void InstructionSelector::VisitWord32PairShr(Node* node) { + ArmOperandGenerator g(this); + // We use g.UseUniqueRegister here for InputAt(1) and InputAt(2) to to + // guarantee that there is no register aliasing with output register. + Int32Matcher m(node->InputAt(2)); + InstructionOperand shift_operand; + if (m.HasValue()) { + shift_operand = g.UseImmediate(m.node()); + } else { + shift_operand = g.UseUniqueRegister(m.node()); + } + + InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), + g.UseUniqueRegister(node->InputAt(1)), + shift_operand}; + + InstructionOperand outputs[] = { + g.DefineAsRegister(node), + g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + + Emit(kArmLsrPair, 2, outputs, 3, inputs); +} + +void InstructionSelector::VisitWord32PairSar(Node* node) { + ArmOperandGenerator g(this); + // We use g.UseUniqueRegister here for InputAt(1) and InputAt(2) to to + // guarantee that there is no register aliasing with output register. + Int32Matcher m(node->InputAt(2)); + InstructionOperand shift_operand; + if (m.HasValue()) { + shift_operand = g.UseImmediate(m.node()); + } else { + shift_operand = g.UseUniqueRegister(m.node()); + } + + InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), + g.UseUniqueRegister(node->InputAt(1)), + shift_operand}; + + InstructionOperand outputs[] = { + g.DefineAsRegister(node), + g.DefineAsRegister(NodeProperties::FindProjection(node, 1))}; + + Emit(kArmAsrPair, 2, outputs, 3, inputs); +} void InstructionSelector::VisitWord32Ror(Node* node) { VisitShift(this, node, TryMatchROR); @@ -1013,7 +1135,9 @@ void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { VisitRR(this, kArmVcvtU32F64, node); } - +void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) { + VisitRR(this, kArmVcvtU32F64, node); +} void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { VisitRR(this, kArmVcvtF32F64, node); } @@ -1272,6 +1396,7 @@ void InstructionSelector::EmitPrepareArguments( bool InstructionSelector::IsTailCallAddressImmediate() { return false; } +int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; } namespace { @@ -1284,6 +1409,9 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, if (cont->IsBranch()) { selector->Emit(opcode, g.NoOutput(), left, right, g.Label(cont->true_block()), g.Label(cont->false_block())); + } else if (cont->IsDeoptimize()) { + selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, + cont->frame_state()); } else { DCHECK(cont->IsSet()); selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); @@ -1357,8 +1485,7 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, if (cont->IsBranch()) { inputs[input_count++] = g.Label(cont->true_block()); inputs[input_count++] = g.Label(cont->false_block()); - } else { - DCHECK(cont->IsSet()); + } else if (cont->IsSet()) { outputs[output_count++] = g.DefineAsRegister(cont->result()); } @@ -1366,8 +1493,13 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, DCHECK_GE(arraysize(inputs), input_count); DCHECK_GE(arraysize(outputs), output_count); - selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, - inputs); + opcode = cont->Encode(opcode); + if (cont->IsDeoptimize()) { + selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, + cont->frame_state()); + } else { + selector->Emit(opcode, output_count, outputs, input_count, inputs); + } } @@ -1482,7 +1614,11 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, if (cont->IsBranch()) { selector->Emit(opcode, g.NoOutput(), value_operand, value_operand, g.Label(cont->true_block()), g.Label(cont->false_block())); + } else if (cont->IsDeoptimize()) { + selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, value_operand, + cont->frame_state()); } else { + DCHECK(cont->IsSet()); selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, value_operand); } @@ -1490,13 +1626,23 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, } // namespace - void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, BasicBlock* fbranch) { FlagsContinuation cont(kNotEqual, tbranch, fbranch); VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); } +void InstructionSelector::VisitDeoptimizeIf(Node* node) { + FlagsContinuation cont = + FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1)); + VisitWordCompareZero(this, node, node->InputAt(0), &cont); +} + +void InstructionSelector::VisitDeoptimizeUnless(Node* node) { + FlagsContinuation cont = + FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1)); + VisitWordCompareZero(this, node, node->InputAt(0), &cont); +} void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { ArmOperandGenerator g(this); @@ -1527,7 +1673,7 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { void InstructionSelector::VisitWord32Equal(Node* const node) { - FlagsContinuation cont(kEqual, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); Int32BinopMatcher m(node); if (m.right().Is(0)) { return VisitWordCompareZero(this, m.node(), m.left().node(), &cont); @@ -1537,32 +1683,34 @@ void InstructionSelector::VisitWord32Equal(Node* const node) { void InstructionSelector::VisitInt32LessThan(Node* node) { - FlagsContinuation cont(kSignedLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); VisitWordCompare(this, node, &cont); } void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { - FlagsContinuation cont(kSignedLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); VisitWordCompare(this, node, &cont); } void InstructionSelector::VisitUint32LessThan(Node* node) { - FlagsContinuation cont(kUnsignedLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); VisitWordCompare(this, node, &cont); } void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { - FlagsContinuation cont(kUnsignedLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); VisitWordCompare(this, node, &cont); } void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) { - FlagsContinuation cont(kOverflow, ovf); + FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); return VisitBinop(this, node, kArmAdd, kArmAdd, &cont); } FlagsContinuation cont; @@ -1572,7 +1720,7 @@ void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { if (Node* ovf = NodeProperties::FindProjection(node, 1)) { - FlagsContinuation cont(kOverflow, ovf); + FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); return VisitBinop(this, node, kArmSub, kArmRsb, &cont); } FlagsContinuation cont; @@ -1581,37 +1729,39 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { void InstructionSelector::VisitFloat32Equal(Node* node) { - FlagsContinuation cont(kEqual, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); VisitFloat32Compare(this, node, &cont); } void InstructionSelector::VisitFloat32LessThan(Node* node) { - FlagsContinuation cont(kFloatLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node); VisitFloat32Compare(this, node, &cont); } void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { - FlagsContinuation cont(kFloatLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kFloatLessThanOrEqual, node); VisitFloat32Compare(this, node, &cont); } void InstructionSelector::VisitFloat64Equal(Node* node) { - FlagsContinuation cont(kEqual, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); VisitFloat64Compare(this, node, &cont); } void InstructionSelector::VisitFloat64LessThan(Node* node) { - FlagsContinuation cont(kFloatLessThan, node); + FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node); VisitFloat64Compare(this, node, &cont); } void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { - FlagsContinuation cont(kFloatLessThanOrEqual, node); + FlagsContinuation cont = + FlagsContinuation::ForSet(kFloatLessThanOrEqual, node); VisitFloat64Compare(this, node, &cont); } |