summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/ppc/instruction-selector-ppc.cc')
-rw-r--r--deps/v8/src/compiler/ppc/instruction-selector-ppc.cc217
1 files changed, 171 insertions, 46 deletions
diff --git a/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc b/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc
index 244e6f44c5..5abb5f1476 100644
--- a/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc
+++ b/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc
@@ -71,22 +71,22 @@ class PPCOperandGenerator final : public OperandGenerator {
namespace {
-void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
+void VisitRR(InstructionSelector* selector, InstructionCode opcode,
+ Node* node) {
PPCOperandGenerator g(selector);
selector->Emit(opcode, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)));
}
-
-void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
+void VisitRRR(InstructionSelector* selector, InstructionCode opcode,
+ Node* node) {
PPCOperandGenerator g(selector);
selector->Emit(opcode, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(1)));
}
-
-void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
+void VisitRRO(InstructionSelector* selector, InstructionCode opcode, Node* node,
ImmediateMode operand_mode) {
PPCOperandGenerator g(selector);
selector->Emit(opcode, g.DefineAsRegister(node),
@@ -96,8 +96,8 @@ void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
#if V8_TARGET_ARCH_PPC64
-void VisitTryTruncateDouble(InstructionSelector* selector, ArchOpcode opcode,
- Node* node) {
+void VisitTryTruncateDouble(InstructionSelector* selector,
+ InstructionCode opcode, Node* node) {
PPCOperandGenerator g(selector);
InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
InstructionOperand outputs[2];
@@ -144,15 +144,20 @@ void VisitBinop(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);
+ }
}
// Shared routine for multiple binary operations.
template <typename Matcher>
-void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode,
- ImmediateMode operand_mode) {
+void VisitBinop(InstructionSelector* selector, Node* node,
+ InstructionCode opcode, ImmediateMode operand_mode) {
FlagsContinuation cont;
VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
}
@@ -247,9 +252,7 @@ void InstructionSelector::VisitStore(Node* node) {
inputs[input_count++] = g.UseUniqueRegister(offset);
addressing_mode = kMode_MRR;
}
- 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:
@@ -720,7 +723,6 @@ void InstructionSelector::VisitWord32Shr(Node* node) {
VisitRRO(this, kPPC_ShiftRight32, node, kShift32Imm);
}
-
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitWord64Shr(Node* node) {
PPCOperandGenerator g(this);
@@ -782,9 +784,109 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm);
}
+#if !V8_TARGET_ARCH_PPC64
+void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode,
+ Node* node) {
+ PPCOperandGenerator g(selector);
+
+ // 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))};
+
+ selector->Emit(opcode, 2, outputs, 4, inputs);
+}
+
+void InstructionSelector::VisitInt32PairAdd(Node* node) {
+ VisitPairBinop(this, kPPC_AddPair, node);
+}
+
+void InstructionSelector::VisitInt32PairSub(Node* node) {
+ VisitPairBinop(this, kPPC_SubPair, node);
+}
+
+void InstructionSelector::VisitInt32PairMul(Node* node) {
+ PPCOperandGenerator g(this);
+ InstructionOperand inputs[] = {g.UseUniqueRegister(node->InputAt(0)),
+ g.UseUniqueRegister(node->InputAt(1)),
+ g.UseUniqueRegister(node->InputAt(2)),
+ g.UseRegister(node->InputAt(3))};
+
+ InstructionOperand outputs[] = {
+ g.DefineAsRegister(node),
+ g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
+
+ InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+
+ Emit(kPPC_MulPair, 2, outputs, 4, inputs, 2, temps);
+}
+
+void VisitPairShift(InstructionSelector* selector, InstructionCode opcode,
+ Node* node) {
+ PPCOperandGenerator g(selector);
+ 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.UseRegister(node->InputAt(1)),
+ shift_operand};
+
+ InstructionOperand outputs[] = {
+ g.DefineSameAsFirst(node),
+ g.DefineAsRegister(NodeProperties::FindProjection(node, 1))};
+
+ selector->Emit(opcode, 2, outputs, 3, inputs);
+}
+
+void InstructionSelector::VisitWord32PairShl(Node* node) {
+ VisitPairShift(this, kPPC_ShiftLeftPair, node);
+}
+
+void InstructionSelector::VisitWord32PairShr(Node* node) {
+ VisitPairShift(this, kPPC_ShiftRightPair, node);
+}
+
+void InstructionSelector::VisitWord32PairSar(Node* node) {
+ VisitPairShift(this, kPPC_ShiftRightAlgPair, node);
+}
+#endif
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitWord64Sar(Node* node) {
+ PPCOperandGenerator g(this);
+ Int64BinopMatcher m(node);
+ if (CanCover(m.node(), m.left().node()) && m.left().IsLoad() &&
+ m.right().Is(32)) {
+ // Just load and sign-extend the interesting 4 bytes instead. This happens,
+ // for example, when we're loading and untagging SMIs.
+ BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(), true);
+ if (mleft.matches() && mleft.index() == nullptr) {
+ int64_t offset = 0;
+ Node* displacement = mleft.displacement();
+ if (displacement != nullptr) {
+ Int64Matcher mdisplacement(displacement);
+ DCHECK(mdisplacement.HasValue());
+ offset = mdisplacement.Value();
+ }
+ offset = SmiWordOffset(offset);
+ if (g.CanBeImmediate(offset, kInt16Imm_4ByteAligned)) {
+ Emit(kPPC_LoadWordS32 | AddressingModeField::encode(kMode_MRI),
+ g.DefineAsRegister(node), g.UseRegister(mleft.base()),
+ g.TempImmediate(offset));
+ return;
+ }
+ }
+ }
VisitRRO(this, kPPC_ShiftRightAlg64, node, kShift64Imm);
}
#endif
@@ -861,7 +963,6 @@ void InstructionSelector::VisitInt64Add(Node* node) {
}
#endif
-
void InstructionSelector::VisitInt32Sub(Node* node) {
PPCOperandGenerator g(this);
Int32BinopMatcher m(node);
@@ -994,6 +1095,9 @@ void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
VisitRR(this, kPPC_DoubleToUint32, node);
}
+void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) {
+ VisitRR(this, kPPC_DoubleToUint32, node);
+}
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
@@ -1108,7 +1212,7 @@ void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
void InstructionSelector::VisitFloat32Add(Node* node) {
- VisitRRR(this, kPPC_AddDouble, node);
+ VisitRRR(this, kPPC_AddDouble | MiscField::encode(1), node);
}
@@ -1122,11 +1226,11 @@ void InstructionSelector::VisitFloat32Sub(Node* node) {
PPCOperandGenerator g(this);
Float32BinopMatcher m(node);
if (m.left().IsMinusZero()) {
- Emit(kPPC_NegDouble, g.DefineAsRegister(node),
+ Emit(kPPC_NegDouble | MiscField::encode(1), g.DefineAsRegister(node),
g.UseRegister(m.right().node()));
return;
}
- VisitRRR(this, kPPC_SubDouble, node);
+ VisitRRR(this, kPPC_SubDouble | MiscField::encode(1), node);
}
@@ -1157,7 +1261,7 @@ void InstructionSelector::VisitFloat64Sub(Node* node) {
void InstructionSelector::VisitFloat32Mul(Node* node) {
- VisitRRR(this, kPPC_MulDouble, node);
+ VisitRRR(this, kPPC_MulDouble | MiscField::encode(1), node);
}
@@ -1168,7 +1272,7 @@ void InstructionSelector::VisitFloat64Mul(Node* node) {
void InstructionSelector::VisitFloat32Div(Node* node) {
- VisitRRR(this, kPPC_DivDouble, node);
+ VisitRRR(this, kPPC_DivDouble | MiscField::encode(1), node);
}
@@ -1198,7 +1302,7 @@ void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); }
void InstructionSelector::VisitFloat32Abs(Node* node) {
- VisitRR(this, kPPC_AbsDouble, node);
+ VisitRR(this, kPPC_AbsDouble | MiscField::encode(1), node);
}
@@ -1208,7 +1312,7 @@ void InstructionSelector::VisitFloat64Abs(Node* node) {
void InstructionSelector::VisitFloat32Sqrt(Node* node) {
- VisitRR(this, kPPC_SqrtDouble, node);
+ VisitRR(this, kPPC_SqrtDouble | MiscField::encode(1), node);
}
@@ -1218,7 +1322,7 @@ void InstructionSelector::VisitFloat64Sqrt(Node* node) {
void InstructionSelector::VisitFloat32RoundDown(Node* node) {
- VisitRR(this, kPPC_FloorDouble, node);
+ VisitRR(this, kPPC_FloorDouble | MiscField::encode(1), node);
}
@@ -1228,7 +1332,7 @@ void InstructionSelector::VisitFloat64RoundDown(Node* node) {
void InstructionSelector::VisitFloat32RoundUp(Node* node) {
- VisitRR(this, kPPC_CeilDouble, node);
+ VisitRR(this, kPPC_CeilDouble | MiscField::encode(1), node);
}
@@ -1238,7 +1342,7 @@ void InstructionSelector::VisitFloat64RoundUp(Node* node) {
void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
- VisitRR(this, kPPC_TruncateDouble, node);
+ VisitRR(this, kPPC_TruncateDouble | MiscField::encode(1), node);
}
@@ -1264,7 +1368,7 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
- FlagsContinuation cont(kOverflow, ovf);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32,
kInt16Imm, &cont);
}
@@ -1276,7 +1380,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<Int32BinopMatcher>(this, node, kPPC_SubWithOverflow32,
kInt16Imm_Negate, &cont);
}
@@ -1289,7 +1393,7 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
- FlagsContinuation cont(kOverflow, ovf);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm,
&cont);
}
@@ -1300,7 +1404,7 @@ void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
- FlagsContinuation cont(kOverflow, ovf);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate,
&cont);
}
@@ -1336,6 +1440,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);
@@ -1573,6 +1680,17 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont);
}
+void InstructionSelector::VisitDeoptimizeIf(Node* node) {
+ FlagsContinuation cont =
+ FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
+ VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
+}
+
+void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
+ FlagsContinuation cont =
+ FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
+ VisitWord32CompareZero(this, node, node->InputAt(0), &cont);
+}
void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
PPCOperandGenerator g(this);
@@ -1603,7 +1721,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 VisitWord32CompareZero(this, m.node(), m.left().node(), &cont);
@@ -1613,32 +1731,34 @@ void InstructionSelector::VisitWord32Equal(Node* const node) {
void InstructionSelector::VisitInt32LessThan(Node* node) {
- FlagsContinuation cont(kSignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
VisitWord32Compare(this, node, &cont);
}
void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kSignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
VisitWord32Compare(this, node, &cont);
}
void InstructionSelector::VisitUint32LessThan(Node* node) {
- FlagsContinuation cont(kUnsignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitWord32Compare(this, node, &cont);
}
void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitWord32Compare(this, node, &cont);
}
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitWord64Equal(Node* const node) {
- FlagsContinuation cont(kEqual, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
Int64BinopMatcher m(node);
if (m.right().Is(0)) {
return VisitWord64CompareZero(this, m.node(), m.left().node(), &cont);
@@ -1648,62 +1768,66 @@ void InstructionSelector::VisitWord64Equal(Node* const node) {
void InstructionSelector::VisitInt64LessThan(Node* node) {
- FlagsContinuation cont(kSignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
VisitWord64Compare(this, node, &cont);
}
void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kSignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
VisitWord64Compare(this, node, &cont);
}
void InstructionSelector::VisitUint64LessThan(Node* node) {
- FlagsContinuation cont(kUnsignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitWord64Compare(this, node, &cont);
}
void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitWord64Compare(this, node, &cont);
}
#endif
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(kUnsignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitFloat32Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, 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(kUnsignedLessThan, node);
+ FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitFloat64Compare(this, node, &cont);
}
void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
- FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+ FlagsContinuation cont =
+ FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitFloat64Compare(this, node, &cont);
}
@@ -1750,6 +1874,7 @@ void InstructionSelector::EmitPrepareArguments(
bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
+int InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
PPCOperandGenerator g(this);