diff options
Diffstat (limited to 'deps/v8/src/compiler/ppc/instruction-selector-ppc.cc')
-rw-r--r-- | deps/v8/src/compiler/ppc/instruction-selector-ppc.cc | 264 |
1 files changed, 124 insertions, 140 deletions
diff --git a/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc b/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc index fced5565df..70a6c9ee69 100644 --- a/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc +++ b/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc @@ -194,7 +194,7 @@ void InstructionSelector::VisitLoad(Node* node) { PPCOperandGenerator g(this); Node* base = node->InputAt(0); Node* offset = node->InputAt(1); - ArchOpcode opcode = kArchNop; + InstructionCode opcode = kArchNop; ImmediateMode mode = kInt16Imm; switch (load_rep.representation()) { case MachineRepresentation::kFloat32: @@ -234,6 +234,12 @@ void InstructionSelector::VisitLoad(Node* node) { UNREACHABLE(); return; } + + if (node->opcode() == IrOpcode::kPoisonedLoad && + load_poisoning_ == LoadPoisoning::kDoPoison) { + opcode |= MiscField::encode(kMemoryAccessPoisoned); + } + if (g.CanBeImmediate(offset, mode)) { Emit(opcode | AddressingModeField::encode(kMode_MRI), g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset)); @@ -246,6 +252,8 @@ void InstructionSelector::VisitLoad(Node* node) { } } +void InstructionSelector::VisitPoisonedLoad(Node* node) { VisitLoad(node); } + void InstructionSelector::VisitProtectedLoad(Node* node) { // TODO(eholk) UNIMPLEMENTED(); @@ -1118,6 +1126,16 @@ void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) { VisitRR(this, kPPC_DoubleToUint32, node); } +void InstructionSelector::VisitSignExtendWord8ToInt32(Node* node) { + // TODO(mbrandy): inspect input to see if nop is appropriate. + VisitRR(this, kPPC_ExtendSignWord8, node); +} + +void InstructionSelector::VisitSignExtendWord16ToInt32(Node* node) { + // TODO(mbrandy): inspect input to see if nop is appropriate. + VisitRR(this, kPPC_ExtendSignWord16, node); +} + #if V8_TARGET_ARCH_PPC64 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { VisitTryTruncateDouble(this, kPPC_DoubleToInt64, node); @@ -1144,6 +1162,20 @@ void InstructionSelector::VisitChangeInt32ToInt64(Node* node) { VisitRR(this, kPPC_ExtendSignWord32, node); } +void InstructionSelector::VisitSignExtendWord8ToInt64(Node* node) { + // TODO(mbrandy): inspect input to see if nop is appropriate. + VisitRR(this, kPPC_ExtendSignWord8, node); +} + +void InstructionSelector::VisitSignExtendWord16ToInt64(Node* node) { + // TODO(mbrandy): inspect input to see if nop is appropriate. + VisitRR(this, kPPC_ExtendSignWord16, node); +} + +void InstructionSelector::VisitSignExtendWord32ToInt64(Node* node) { + // TODO(mbrandy): inspect input to see if nop is appropriate. + VisitRR(this, kPPC_ExtendSignWord32, node); +} void InstructionSelector::VisitChangeUint32ToUint64(Node* node) { // TODO(mbrandy): inspect input to see if nop is appropriate. @@ -1533,14 +1565,13 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node, g.UseRegister(right), cont); } +} // namespace // Shared routine for word comparisons against zero. -void VisitWordCompareZero(InstructionSelector* selector, Node* user, - Node* value, InstructionCode opcode, - FlagsContinuation* cont) { +void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, + FlagsContinuation* cont) { // Try to combine with comparisons against 0 by simply inverting the branch. - while (value->opcode() == IrOpcode::kWord32Equal && - selector->CanCover(user, value)) { + while (value->opcode() == IrOpcode::kWord32Equal && CanCover(user, value)) { Int32BinopMatcher m(value); if (!m.right().Is(0)) break; @@ -1549,58 +1580,58 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, cont->Negate(); } - if (selector->CanCover(user, value)) { + if (CanCover(user, value)) { switch (value->opcode()) { case IrOpcode::kWord32Equal: cont->OverwriteAndNegateIfEqual(kEqual); - return VisitWord32Compare(selector, value, cont); + return VisitWord32Compare(this, value, cont); case IrOpcode::kInt32LessThan: cont->OverwriteAndNegateIfEqual(kSignedLessThan); - return VisitWord32Compare(selector, value, cont); + return VisitWord32Compare(this, value, cont); case IrOpcode::kInt32LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); - return VisitWord32Compare(selector, value, cont); + return VisitWord32Compare(this, value, cont); case IrOpcode::kUint32LessThan: cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); - return VisitWord32Compare(selector, value, cont); + return VisitWord32Compare(this, value, cont); case IrOpcode::kUint32LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); - return VisitWord32Compare(selector, value, cont); + return VisitWord32Compare(this, value, cont); #if V8_TARGET_ARCH_PPC64 case IrOpcode::kWord64Equal: cont->OverwriteAndNegateIfEqual(kEqual); - return VisitWord64Compare(selector, value, cont); + return VisitWord64Compare(this, value, cont); case IrOpcode::kInt64LessThan: cont->OverwriteAndNegateIfEqual(kSignedLessThan); - return VisitWord64Compare(selector, value, cont); + return VisitWord64Compare(this, value, cont); case IrOpcode::kInt64LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); - return VisitWord64Compare(selector, value, cont); + return VisitWord64Compare(this, value, cont); case IrOpcode::kUint64LessThan: cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); - return VisitWord64Compare(selector, value, cont); + return VisitWord64Compare(this, value, cont); case IrOpcode::kUint64LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); - return VisitWord64Compare(selector, value, cont); + return VisitWord64Compare(this, value, cont); #endif case IrOpcode::kFloat32Equal: cont->OverwriteAndNegateIfEqual(kEqual); - return VisitFloat32Compare(selector, value, cont); + return VisitFloat32Compare(this, value, cont); case IrOpcode::kFloat32LessThan: cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); - return VisitFloat32Compare(selector, value, cont); + return VisitFloat32Compare(this, value, cont); case IrOpcode::kFloat32LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); - return VisitFloat32Compare(selector, value, cont); + return VisitFloat32Compare(this, value, cont); case IrOpcode::kFloat64Equal: cont->OverwriteAndNegateIfEqual(kEqual); - return VisitFloat64Compare(selector, value, cont); + return VisitFloat64Compare(this, value, cont); case IrOpcode::kFloat64LessThan: cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); - return VisitFloat64Compare(selector, value, cont); + return VisitFloat64Compare(this, value, cont); case IrOpcode::kFloat64LessThanOrEqual: cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); - return VisitFloat64Compare(selector, value, cont); + return VisitFloat64Compare(this, value, cont); case IrOpcode::kProjection: // Check if this is the overflow output projection of an // <Operation>WithOverflow node. @@ -1612,28 +1643,27 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, // *AFTER* this branch). Node* const node = value->InputAt(0); Node* const result = NodeProperties::FindProjection(node, 0); - if (result == nullptr || selector->IsDefined(result)) { + if (result == nullptr || IsDefined(result)) { switch (node->opcode()) { case IrOpcode::kInt32AddWithOverflow: cont->OverwriteAndNegateIfEqual(kOverflow); return VisitBinop<Int32BinopMatcher>( - selector, node, kPPC_AddWithOverflow32, kInt16Imm, cont); + this, node, kPPC_AddWithOverflow32, kInt16Imm, cont); case IrOpcode::kInt32SubWithOverflow: cont->OverwriteAndNegateIfEqual(kOverflow); - return VisitBinop<Int32BinopMatcher>(selector, node, - kPPC_SubWithOverflow32, - kInt16Imm_Negate, cont); + return VisitBinop<Int32BinopMatcher>( + this, node, kPPC_SubWithOverflow32, kInt16Imm_Negate, cont); case IrOpcode::kInt32MulWithOverflow: cont->OverwriteAndNegateIfEqual(kNotEqual); - return EmitInt32MulWithOverflow(selector, node, cont); + return EmitInt32MulWithOverflow(this, node, cont); #if V8_TARGET_ARCH_PPC64 case IrOpcode::kInt64AddWithOverflow: cont->OverwriteAndNegateIfEqual(kOverflow); - return VisitBinop<Int64BinopMatcher>(selector, node, kPPC_Add64, + return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add64, kInt16Imm, cont); case IrOpcode::kInt64SubWithOverflow: cont->OverwriteAndNegateIfEqual(kOverflow); - return VisitBinop<Int64BinopMatcher>(selector, node, kPPC_Sub, + return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate, cont); #endif default: @@ -1643,10 +1673,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, } break; case IrOpcode::kInt32Sub: - return VisitWord32Compare(selector, value, cont); + return VisitWord32Compare(this, value, cont); case IrOpcode::kWord32And: // TODO(mbandy): opportunity for rlwinm? - return VisitWordCompare(selector, value, kPPC_Tst32, cont, true, + return VisitWordCompare(this, value, kPPC_Tst32, cont, true, kInt16Imm_Unsigned); // TODO(mbrandy): Handle? // case IrOpcode::kInt32Add: @@ -1658,10 +1688,10 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, // case IrOpcode::kWord32Ror: #if V8_TARGET_ARCH_PPC64 case IrOpcode::kInt64Sub: - return VisitWord64Compare(selector, value, cont); + return VisitWord64Compare(this, value, cont); case IrOpcode::kWord64And: // TODO(mbandy): opportunity for rldic? - return VisitWordCompare(selector, value, kPPC_Tst64, cont, true, + return VisitWordCompare(this, value, kPPC_Tst64, cont, true, kInt16Imm_Unsigned); // TODO(mbrandy): Handle? // case IrOpcode::kInt64Add: @@ -1678,84 +1708,36 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, } // Branch could not be combined with a compare, emit compare against 0. - PPCOperandGenerator g(selector); - VisitCompare(selector, opcode, g.UseRegister(value), g.TempImmediate(0), + PPCOperandGenerator g(this); + VisitCompare(this, kPPC_Cmp32, g.UseRegister(value), g.TempImmediate(0), cont); } - -void VisitWord32CompareZero(InstructionSelector* selector, Node* user, - Node* value, FlagsContinuation* cont) { - VisitWordCompareZero(selector, user, value, kPPC_Cmp32, cont); -} - - -#if V8_TARGET_ARCH_PPC64 -void VisitWord64CompareZero(InstructionSelector* selector, Node* user, - Node* value, FlagsContinuation* cont) { - VisitWordCompareZero(selector, user, value, kPPC_Cmp64, cont); -} -#endif - -} // namespace - - -void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, - BasicBlock* fbranch) { - FlagsContinuation cont(kNotEqual, tbranch, fbranch); - VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont); -} - -void InstructionSelector::VisitDeoptimizeIf(Node* node) { - DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); - FlagsContinuation cont = FlagsContinuation::ForDeoptimize( - kNotEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1)); - VisitWord32CompareZero(this, node, node->InputAt(0), &cont); -} - -void InstructionSelector::VisitDeoptimizeUnless(Node* node) { - DeoptimizeParameters p = DeoptimizeParametersOf(node->op()); - FlagsContinuation cont = FlagsContinuation::ForDeoptimize( - kEqual, p.kind(), p.reason(), p.feedback(), node->InputAt(1)); - VisitWord32CompareZero(this, node, node->InputAt(0), &cont); -} - -void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { - FlagsContinuation cont = - FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); - VisitWord32CompareZero(this, node, node->InputAt(0), &cont); -} - -void InstructionSelector::VisitTrapUnless(Node* node, - Runtime::FunctionId func_id) { - FlagsContinuation cont = - FlagsContinuation::ForTrap(kEqual, func_id, node->InputAt(1)); - VisitWord32CompareZero(this, node, node->InputAt(0), &cont); -} - void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { PPCOperandGenerator g(this); InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); // Emit either ArchTableSwitch or ArchLookupSwitch. - static const size_t kMaxTableSwitchValueRange = 2 << 16; - size_t table_space_cost = 4 + sw.value_range; - size_t table_time_cost = 3; - size_t lookup_space_cost = 3 + 2 * sw.case_count; - size_t lookup_time_cost = sw.case_count; - if (sw.case_count > 0 && - table_space_cost + 3 * table_time_cost <= - lookup_space_cost + 3 * lookup_time_cost && - sw.min_value > std::numeric_limits<int32_t>::min() && - sw.value_range <= kMaxTableSwitchValueRange) { - InstructionOperand index_operand = value_operand; - if (sw.min_value) { - index_operand = g.TempRegister(); - Emit(kPPC_Sub, index_operand, value_operand, - g.TempImmediate(sw.min_value)); + if (enable_switch_jump_table_ == kEnableSwitchJumpTable) { + static const size_t kMaxTableSwitchValueRange = 2 << 16; + size_t table_space_cost = 4 + sw.value_range; + size_t table_time_cost = 3; + size_t lookup_space_cost = 3 + 2 * sw.case_count; + size_t lookup_time_cost = sw.case_count; + if (sw.case_count > 0 && + table_space_cost + 3 * table_time_cost <= + lookup_space_cost + 3 * lookup_time_cost && + sw.min_value > std::numeric_limits<int32_t>::min() && + sw.value_range <= kMaxTableSwitchValueRange) { + InstructionOperand index_operand = value_operand; + if (sw.min_value) { + index_operand = g.TempRegister(); + Emit(kPPC_Sub, index_operand, value_operand, + g.TempImmediate(sw.min_value)); + } + // Generate a table lookup. + return EmitTableSwitch(sw, index_operand); } - // Generate a table lookup. - return EmitTableSwitch(sw, index_operand); } // Generate a sequence of conditional jumps. @@ -1765,10 +1747,6 @@ void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { void InstructionSelector::VisitWord32Equal(Node* const node) { FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); - Int32BinopMatcher m(node); - if (m.right().Is(0)) { - return VisitWord32CompareZero(this, m.node(), m.left().node(), &cont); - } VisitWord32Compare(this, node, &cont); } @@ -1802,10 +1780,6 @@ void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { #if V8_TARGET_ARCH_PPC64 void InstructionSelector::VisitWord64Equal(Node* const node) { FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); - Int64BinopMatcher m(node); - if (m.right().Is(0)) { - return VisitWord64CompareZero(this, m.node(), m.left().node(), &cont); - } VisitWord64Compare(this, node, &cont); } @@ -1883,16 +1857,15 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { VisitFloat64Compare(this, node, &cont); } - void InstructionSelector::EmitPrepareArguments( - ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor, + ZoneVector<PushParameter>* arguments, const CallDescriptor* call_descriptor, Node* node) { PPCOperandGenerator g(this); // Prepare for C function call. - if (descriptor->IsCFunctionCall()) { - Emit(kArchPrepareCallCFunction | - MiscField::encode(static_cast<int>(descriptor->ParameterCount())), + if (call_descriptor->IsCFunctionCall()) { + Emit(kArchPrepareCallCFunction | MiscField::encode(static_cast<int>( + call_descriptor->ParameterCount())), 0, nullptr, 0, nullptr); // Poke any stack arguments. @@ -1962,7 +1935,7 @@ void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) { g.UseRegister(left), g.UseRegister(right)); } -void InstructionSelector::VisitAtomicLoad(Node* node) { +void InstructionSelector::VisitWord32AtomicLoad(Node* node) { LoadRepresentation load_rep = LoadRepresentationOf(node->op()); PPCOperandGenerator g(this); Node* base = node->InputAt(0); @@ -1970,13 +1943,15 @@ void InstructionSelector::VisitAtomicLoad(Node* node) { ArchOpcode opcode = kArchNop; switch (load_rep.representation()) { case MachineRepresentation::kWord8: - opcode = load_rep.IsSigned() ? kAtomicLoadInt8 : kAtomicLoadUint8; + opcode = + load_rep.IsSigned() ? kWord32AtomicLoadInt8 : kWord32AtomicLoadUint8; break; case MachineRepresentation::kWord16: - opcode = load_rep.IsSigned() ? kAtomicLoadInt16 : kAtomicLoadUint16; + opcode = load_rep.IsSigned() ? kWord32AtomicLoadInt16 + : kWord32AtomicLoadUint16; break; case MachineRepresentation::kWord32: - opcode = kAtomicLoadWord32; + opcode = kWord32AtomicLoadWord32; break; default: UNREACHABLE(); @@ -1986,7 +1961,7 @@ void InstructionSelector::VisitAtomicLoad(Node* node) { g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); } -void InstructionSelector::VisitAtomicStore(Node* node) { +void InstructionSelector::VisitWord32AtomicStore(Node* node) { MachineRepresentation rep = AtomicStoreRepresentationOf(node->op()); PPCOperandGenerator g(this); Node* base = node->InputAt(0); @@ -1995,13 +1970,13 @@ void InstructionSelector::VisitAtomicStore(Node* node) { ArchOpcode opcode = kArchNop; switch (rep) { case MachineRepresentation::kWord8: - opcode = kAtomicStoreWord8; + opcode = kWord32AtomicStoreWord8; break; case MachineRepresentation::kWord16: - opcode = kAtomicStoreWord16; + opcode = kWord32AtomicStoreWord16; break; case MachineRepresentation::kWord32: - opcode = kAtomicStoreWord32; + opcode = kWord32AtomicStoreWord32; break; default: UNREACHABLE(); @@ -2017,7 +1992,7 @@ void InstructionSelector::VisitAtomicStore(Node* node) { 0, nullptr, input_count, inputs); } -void InstructionSelector::VisitAtomicExchange(Node* node) { +void InstructionSelector::VisitWord32AtomicExchange(Node* node) { PPCOperandGenerator g(this); Node* base = node->InputAt(0); Node* index = node->InputAt(1); @@ -2025,15 +2000,15 @@ void InstructionSelector::VisitAtomicExchange(Node* node) { ArchOpcode opcode = kArchNop; MachineType type = AtomicOpRepresentationOf(node->op()); if (type == MachineType::Int8()) { - opcode = kAtomicExchangeInt8; + opcode = kWord32AtomicExchangeInt8; } else if (type == MachineType::Uint8()) { - opcode = kAtomicExchangeUint8; + opcode = kWord32AtomicExchangeUint8; } else if (type == MachineType::Int16()) { - opcode = kAtomicExchangeInt16; + opcode = kWord32AtomicExchangeInt16; } else if (type == MachineType::Uint16()) { - opcode = kAtomicExchangeUint16; + opcode = kWord32AtomicExchangeUint16; } else if (type == MachineType::Int32() || type == MachineType::Uint32()) { - opcode = kAtomicExchangeWord32; + opcode = kWord32AtomicExchangeWord32; } else { UNREACHABLE(); return; @@ -2051,19 +2026,19 @@ void InstructionSelector::VisitAtomicExchange(Node* node) { Emit(code, 1, outputs, input_count, inputs); } -void InstructionSelector::VisitAtomicCompareExchange(Node* node) { +void InstructionSelector::VisitWord32AtomicCompareExchange(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitAtomicAdd(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitWord32AtomicAdd(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitAtomicSub(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitWord32AtomicSub(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitAtomicAnd(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitWord32AtomicAnd(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitAtomicOr(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitWord32AtomicOr(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::VisitAtomicXor(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitWord32AtomicXor(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitInt32AbsWithOverflow(Node* node) { UNREACHABLE(); @@ -2241,9 +2216,9 @@ void InstructionSelector::VisitF32x4ExtractLane(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); } -void InstructionSelector::EmitPrepareResults(ZoneVector<PushParameter>* results, - const CallDescriptor* descriptor, - Node* node) { +void InstructionSelector::EmitPrepareResults( + ZoneVector<PushParameter>* results, const CallDescriptor* call_descriptor, + Node* node) { // TODO(John): Port. } @@ -2257,6 +2232,12 @@ void InstructionSelector::VisitF32x4Min(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitF32x4Max(Node* node) { UNIMPLEMENTED(); } +void InstructionSelector::VisitS128Select(Node* node) { UNIMPLEMENTED(); } + +void InstructionSelector::VisitF32x4Neg(Node* node) { UNIMPLEMENTED(); } + +void InstructionSelector::VisitF32x4Abs(Node* node) { UNIMPLEMENTED(); } + // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { @@ -2279,6 +2260,9 @@ InstructionSelector::AlignmentRequirements() { FullUnalignedAccessSupport(); } +// static +bool InstructionSelector::SupportsSpeculationPoisoning() { return true; } + } // namespace compiler } // namespace internal } // namespace v8 |