diff options
Diffstat (limited to 'deps/v8/src/compiler/mips64/instruction-selector-mips64.cc')
-rw-r--r-- | deps/v8/src/compiler/mips64/instruction-selector-mips64.cc | 202 |
1 files changed, 122 insertions, 80 deletions
diff --git a/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc b/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc index fbf09d6ca2..d48007b858 100644 --- a/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc +++ b/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc @@ -92,9 +92,35 @@ class Mips64OperandGenerator final : public OperandGenerator { case kMips64Tst: case kMips64Xor: return is_uint16(value); + case kMips64Lb: + case kMips64Lbu: + case kMips64Sb: + case kMips64Lh: + case kMips64Lhu: + case kMips64Sh: + case kMips64Lw: + case kMips64Sw: + case kMips64Ld: + case kMips64Sd: + case kMips64Lwc1: + case kMips64Swc1: case kMips64Ldc1: case kMips64Sdc1: - return is_int16(value + kIntSize); + case kCheckedLoadInt8: + case kCheckedLoadUint8: + case kCheckedLoadInt16: + case kCheckedLoadUint16: + case kCheckedLoadWord32: + case kCheckedLoadWord64: + case kCheckedStoreWord8: + case kCheckedStoreWord16: + case kCheckedStoreWord32: + case kCheckedStoreWord64: + case kCheckedLoadFloat32: + case kCheckedLoadFloat64: + case kCheckedStoreFloat32: + case kCheckedStoreFloat64: + return is_int32(value); default: return is_int16(value); } @@ -169,6 +195,16 @@ struct ExtendingLoadMatcher { DCHECK(m.IsWord64Sar()); if (m.left().IsLoad() && m.right().Is(32) && selector_->CanCover(m.node(), m.left().node())) { + MachineRepresentation rep = + LoadRepresentationOf(m.left().node()->op()).representation(); + DCHECK(ElementSizeLog2Of(rep) == 3); + if (rep != MachineRepresentation::kTaggedSigned && + rep != MachineRepresentation::kTaggedPointer && + rep != MachineRepresentation::kTagged && + rep != MachineRepresentation::kWord64) { + return; + } + Mips64OperandGenerator g(selector_); Node* load = m.left().node(); Node* offset = load->InputAt(1); @@ -186,7 +222,8 @@ struct ExtendingLoadMatcher { } }; -bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node) { +bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node, + Node* output_node) { ExtendingLoadMatcher m(node, selector); Mips64OperandGenerator g(selector); if (m.Matches()) { @@ -196,7 +233,7 @@ bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node) { m.opcode() | AddressingModeField::encode(kMode_MRI); DCHECK(is_int32(m.immediate())); inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate())); - InstructionOperand outputs[] = {g.DefineAsRegister(node)}; + InstructionOperand outputs[] = {g.DefineAsRegister(output_node)}; selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs), inputs); return true; @@ -247,6 +284,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node, if (cont->IsBranch()) { inputs[input_count++] = g.Label(cont->true_block()); inputs[input_count++] = g.Label(cont->false_block()); + } else if (cont->IsTrap()) { + inputs[input_count++] = g.TempImmediate(cont->trap_id()); } if (cont->IsDeoptimize()) { @@ -438,6 +477,10 @@ void InstructionSelector::VisitStore(Node* node) { } } +void InstructionSelector::VisitProtectedStore(Node* node) { + // TODO(eholk) + UNIMPLEMENTED(); +} void InstructionSelector::VisitWord32And(Node* node) { Mips64OperandGenerator g(this); @@ -748,7 +791,7 @@ void InstructionSelector::VisitWord64Shr(Node* node) { void InstructionSelector::VisitWord64Sar(Node* node) { - if (TryEmitExtendingLoad(this, node)) return; + if (TryEmitExtendingLoad(this, node, node)) return; VisitRRO(this, kMips64Dsar, node); } @@ -824,7 +867,7 @@ void InstructionSelector::VisitInt32Add(Node* node) { if (m.right().opcode() == IrOpcode::kWord32Shl && CanCover(node, m.left().node()) && CanCover(node, m.right().node())) { Int32BinopMatcher mright(m.right().node()); - if (mright.right().HasValue()) { + if (mright.right().HasValue() && !m.left().HasValue()) { int32_t shift_value = static_cast<int32_t>(mright.right().Value()); Emit(kMips64Lsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), g.TempImmediate(shift_value)); @@ -836,7 +879,7 @@ void InstructionSelector::VisitInt32Add(Node* node) { if (m.left().opcode() == IrOpcode::kWord32Shl && CanCover(node, m.right().node()) && CanCover(node, m.left().node())) { Int32BinopMatcher mleft(m.left().node()); - if (mleft.right().HasValue()) { + if (mleft.right().HasValue() && !m.right().HasValue()) { int32_t shift_value = static_cast<int32_t>(mleft.right().Value()); Emit(kMips64Lsa, g.DefineAsRegister(node), g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), @@ -856,7 +899,7 @@ void InstructionSelector::VisitInt64Add(Node* node) { if (m.right().opcode() == IrOpcode::kWord64Shl && CanCover(node, m.left().node()) && CanCover(node, m.right().node())) { Int64BinopMatcher mright(m.right().node()); - if (mright.right().HasValue()) { + if (mright.right().HasValue() && !m.left().HasValue()) { int32_t shift_value = static_cast<int32_t>(mright.right().Value()); Emit(kMips64Dlsa, g.DefineAsRegister(node), g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), @@ -869,7 +912,7 @@ void InstructionSelector::VisitInt64Add(Node* node) { if (m.left().opcode() == IrOpcode::kWord64Shl && CanCover(node, m.right().node()) && CanCover(node, m.left().node())) { Int64BinopMatcher mleft(m.left().node()); - if (mleft.right().HasValue()) { + if (mleft.right().HasValue() && !m.right().HasValue()) { int32_t shift_value = static_cast<int32_t>(mleft.right().Value()); Emit(kMips64Dlsa, g.DefineAsRegister(node), g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), @@ -1318,13 +1361,17 @@ void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { if (CanCover(node, value)) { switch (value->opcode()) { case IrOpcode::kWord64Sar: { - Int64BinopMatcher m(value); - if (m.right().IsInRange(32, 63)) { - // After smi untagging no need for truncate. Combine sequence. - Emit(kMips64Dsar, g.DefineSameAsFirst(node), - g.UseRegister(m.left().node()), - g.UseImmediate(m.right().node())); + if (TryEmitExtendingLoad(this, value, node)) { return; + } else { + Int64BinopMatcher m(value); + if (m.right().IsInRange(32, 63)) { + // After smi untagging no need for truncate. Combine sequence. + Emit(kMips64Dsar, g.DefineSameAsFirst(node), + g.UseRegister(m.left().node()), + g.UseImmediate(m.right().node())); + return; + } } break; } @@ -1404,35 +1451,23 @@ void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) { void InstructionSelector::VisitFloat32Add(Node* node) { Mips64OperandGenerator g(this); - Float32BinopMatcher m(node); - if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) { - // For Add.S(Mul.S(x, y), z): - Float32BinopMatcher mleft(m.left().node()); - if (kArchVariant == kMips64r2) { // Select Madd.S(z, x, y). + if (kArchVariant == kMips64r2) { // Select Madd.S(z, x, y). + Float32BinopMatcher m(node); + if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) { + // For Add.S(Mul.S(x, y), z): + Float32BinopMatcher mleft(m.left().node()); Emit(kMips64MaddS, g.DefineAsRegister(node), g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), g.UseRegister(mleft.right().node())); return; - } else if (kArchVariant == kMips64r6) { // Select Maddf.S(z, x, y). - Emit(kMips64MaddfS, g.DefineSameAsFirst(node), - g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), - g.UseRegister(mleft.right().node())); - return; } - } - if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) { - // For Add.S(x, Mul.S(y, z)): - Float32BinopMatcher mright(m.right().node()); - if (kArchVariant == kMips64r2) { // Select Madd.S(x, y, z). + if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) { + // For Add.S(x, Mul.S(y, z)): + Float32BinopMatcher mright(m.right().node()); Emit(kMips64MaddS, g.DefineAsRegister(node), g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), g.UseRegister(mright.right().node())); return; - } else if (kArchVariant == kMips64r6) { // Select Maddf.S(x, y, z). - Emit(kMips64MaddfS, g.DefineSameAsFirst(node), - g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), - g.UseRegister(mright.right().node())); - return; } } VisitRRR(this, kMips64AddS, node); @@ -1441,35 +1476,23 @@ void InstructionSelector::VisitFloat32Add(Node* node) { void InstructionSelector::VisitFloat64Add(Node* node) { Mips64OperandGenerator g(this); - Float64BinopMatcher m(node); - if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { - // For Add.D(Mul.D(x, y), z): - Float64BinopMatcher mleft(m.left().node()); - if (kArchVariant == kMips64r2) { // Select Madd.D(z, x, y). + if (kArchVariant == kMips64r2) { // Select Madd.S(z, x, y). + Float64BinopMatcher m(node); + if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { + // For Add.D(Mul.D(x, y), z): + Float64BinopMatcher mleft(m.left().node()); Emit(kMips64MaddD, g.DefineAsRegister(node), g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), g.UseRegister(mleft.right().node())); return; - } else if (kArchVariant == kMips64r6) { // Select Maddf.D(z, x, y). - Emit(kMips64MaddfD, g.DefineSameAsFirst(node), - g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), - g.UseRegister(mleft.right().node())); - return; } - } - if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) { - // For Add.D(x, Mul.D(y, z)): - Float64BinopMatcher mright(m.right().node()); - if (kArchVariant == kMips64r2) { // Select Madd.D(x, y, z). + if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) { + // For Add.D(x, Mul.D(y, z)): + Float64BinopMatcher mright(m.right().node()); Emit(kMips64MaddD, g.DefineAsRegister(node), g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), g.UseRegister(mright.right().node())); return; - } else if (kArchVariant == kMips64r6) { // Select Maddf.D(x, y, z). - Emit(kMips64MaddfD, g.DefineSameAsFirst(node), - g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), - g.UseRegister(mright.right().node())); - return; } } VisitRRR(this, kMips64AddD, node); @@ -1478,9 +1501,9 @@ void InstructionSelector::VisitFloat64Add(Node* node) { void InstructionSelector::VisitFloat32Sub(Node* node) { Mips64OperandGenerator g(this); - Float32BinopMatcher m(node); - if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) { - if (kArchVariant == kMips64r2) { + if (kArchVariant == kMips64r2) { // Select Madd.S(z, x, y). + Float32BinopMatcher m(node); + if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) { // For Sub.S(Mul.S(x,y), z) select Msub.S(z, x, y). Float32BinopMatcher mleft(m.left().node()); Emit(kMips64MsubS, g.DefineAsRegister(node), @@ -1488,24 +1511,15 @@ void InstructionSelector::VisitFloat32Sub(Node* node) { g.UseRegister(mleft.right().node())); return; } - } else if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) { - if (kArchVariant == kMips64r6) { - // For Sub.S(x,Mul.S(y,z)) select Msubf.S(x, y, z). - Float32BinopMatcher mright(m.right().node()); - Emit(kMips64MsubfS, g.DefineSameAsFirst(node), - g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), - g.UseRegister(mright.right().node())); - return; - } } VisitRRR(this, kMips64SubS, node); } void InstructionSelector::VisitFloat64Sub(Node* node) { Mips64OperandGenerator g(this); - Float64BinopMatcher m(node); - if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { - if (kArchVariant == kMips64r2) { + if (kArchVariant == kMips64r2) { // Select Madd.S(z, x, y). + Float64BinopMatcher m(node); + if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { // For Sub.D(Mul.S(x,y), z) select Msub.D(z, x, y). Float64BinopMatcher mleft(m.left().node()); Emit(kMips64MsubD, g.DefineAsRegister(node), @@ -1513,15 +1527,6 @@ void InstructionSelector::VisitFloat64Sub(Node* node) { g.UseRegister(mleft.right().node())); return; } - } else if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) { - if (kArchVariant == kMips64r6) { - // For Sub.D(x,Mul.S(y,z)) select Msubf.D(x, y, z). - Float64BinopMatcher mright(m.right().node()); - Emit(kMips64MsubfD, g.DefineSameAsFirst(node), - g.UseRegister(m.left().node()), g.UseRegister(mright.left().node()), - g.UseRegister(mright.right().node())); - return; - } } VisitRRR(this, kMips64SubD, node); } @@ -1849,6 +1854,15 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { : g.UseRegister(length) : g.UseRegister(length); + if (length->opcode() == IrOpcode::kInt32Constant) { + Int32Matcher m(length); + if (m.IsPowerOf2()) { + Emit(opcode, g.DefineAsRegister(node), offset_operand, + g.UseImmediate(length), g.UseRegister(buffer)); + return; + } + } + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.DefineAsRegister(node), offset_operand, length_operand, g.UseRegister(buffer)); @@ -1901,6 +1915,15 @@ void InstructionSelector::VisitCheckedStore(Node* node) { : g.UseRegister(length) : g.UseRegister(length); + if (length->opcode() == IrOpcode::kInt32Constant) { + Int32Matcher m(length); + if (m.IsPowerOf2()) { + Emit(opcode, g.NoOutput(), offset_operand, g.UseImmediate(length), + g.UseRegisterOrImmediateZero(value), g.UseRegister(buffer)); + return; + } + } + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), offset_operand, length_operand, g.UseRegisterOrImmediateZero(value), g.UseRegister(buffer)); @@ -1921,9 +1944,12 @@ static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, } else if (cont->IsDeoptimize()) { selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), cont->frame_state()); - } else { - DCHECK(cont->IsSet()); + } else if (cont->IsSet()) { selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); + } else { + DCHECK(cont->IsTrap()); + selector->Emit(opcode, g.NoOutput(), left, right, + g.TempImmediate(cont->trap_id())); } } @@ -2135,6 +2161,9 @@ void EmitWordCompareZero(InstructionSelector* selector, Node* value, selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), cont->reason(), cont->frame_state()); + } else if (cont->IsTrap()) { + selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), + g.TempImmediate(cont->trap_id())); } else { selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, g.TempImmediate(0)); @@ -2280,6 +2309,19 @@ void InstructionSelector::VisitDeoptimizeUnless(Node* node) { VisitWordCompareZero(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)); + VisitWordCompareZero(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)); + VisitWordCompareZero(this, node, node->InputAt(0), &cont); +} + void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { Mips64OperandGenerator g(this); InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |