summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/int64-lowering.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/int64-lowering.cc')
-rw-r--r--deps/v8/src/compiler/int64-lowering.cc198
1 files changed, 127 insertions, 71 deletions
diff --git a/deps/v8/src/compiler/int64-lowering.cc b/deps/v8/src/compiler/int64-lowering.cc
index 8824a03dc9..737947aad0 100644
--- a/deps/v8/src/compiler/int64-lowering.cc
+++ b/deps/v8/src/compiler/int64-lowering.cc
@@ -32,6 +32,8 @@ Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine,
signature_(signature),
placeholder_(graph->NewNode(common->Parameter(-2, "placeholder"),
graph->start())) {
+ DCHECK_NOT_NULL(graph);
+ DCHECK_NOT_NULL(graph->end());
replacements_ = zone->NewArray<Replacement>(graph->NodeCount());
memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount());
}
@@ -79,8 +81,10 @@ static int GetParameterIndexAfterLowering(
return result;
}
-static int GetParameterCountAfterLowering(
+int Int64Lowering::GetParameterCountAfterLowering(
Signature<MachineRepresentation>* signature) {
+ // GetParameterIndexAfterLowering(parameter_count) returns the parameter count
+ // after lowering.
return GetParameterIndexAfterLowering(
signature, static_cast<int>(signature->parameter_count()));
}
@@ -96,6 +100,27 @@ static int GetReturnCountAfterLowering(
return result;
}
+void Int64Lowering::GetIndexNodes(Node* index, Node*& index_low,
+ Node*& index_high) {
+#if defined(V8_TARGET_LITTLE_ENDIAN)
+ index_low = index;
+ index_high = graph()->NewNode(machine()->Int32Add(), index,
+ graph()->NewNode(common()->Int32Constant(4)));
+#elif defined(V8_TARGET_BIG_ENDIAN)
+ index_low = graph()->NewNode(machine()->Int32Add(), index,
+ graph()->NewNode(common()->Int32Constant(4)));
+ index_high = index;
+#endif
+}
+
+#if defined(V8_TARGET_LITTLE_ENDIAN)
+const int Int64Lowering::kLowerWordOffset = 0;
+const int Int64Lowering::kHigherWordOffset = 4;
+#elif defined(V8_TARGET_BIG_ENDIAN)
+const int Int64Lowering::kLowerWordOffset = 4;
+const int Int64Lowering::kHigherWordOffset = 0;
+#endif
+
void Int64Lowering::LowerNode(Node* node) {
switch (node->opcode()) {
case IrOpcode::kInt64Constant: {
@@ -107,17 +132,31 @@ void Int64Lowering::LowerNode(Node* node) {
ReplaceNode(node, low_node, high_node);
break;
}
- case IrOpcode::kLoad: {
- LoadRepresentation load_rep = LoadRepresentationOf(node->op());
+ case IrOpcode::kLoad:
+ case IrOpcode::kUnalignedLoad: {
+ MachineRepresentation rep;
+ if (node->opcode() == IrOpcode::kLoad) {
+ rep = LoadRepresentationOf(node->op()).representation();
+ } else {
+ DCHECK(node->opcode() == IrOpcode::kUnalignedLoad);
+ rep = UnalignedLoadRepresentationOf(node->op()).representation();
+ }
- if (load_rep.representation() == MachineRepresentation::kWord64) {
+ if (rep == MachineRepresentation::kWord64) {
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
- Node* index_high =
- graph()->NewNode(machine()->Int32Add(), index,
- graph()->NewNode(common()->Int32Constant(4)));
+ Node* index_low;
+ Node* index_high;
+ GetIndexNodes(index, index_low, index_high);
+ const Operator* load_op;
+
+ if (node->opcode() == IrOpcode::kLoad) {
+ load_op = machine()->Load(MachineType::Int32());
+ } else {
+ DCHECK(node->opcode() == IrOpcode::kUnalignedLoad);
+ load_op = machine()->UnalignedLoad(MachineType::Int32());
+ }
- const Operator* load_op = machine()->Load(MachineType::Int32());
Node* high_node;
if (node->InputCount() > 2) {
Node* effect_high = node->InputAt(2);
@@ -130,6 +169,7 @@ void Int64Lowering::LowerNode(Node* node) {
} else {
high_node = graph()->NewNode(load_op, base, index_high);
}
+ node->ReplaceInput(1, index_low);
NodeProperties::ChangeOp(node, load_op);
ReplaceNode(node, node, high_node);
} else {
@@ -137,27 +177,40 @@ void Int64Lowering::LowerNode(Node* node) {
}
break;
}
- case IrOpcode::kStore: {
- StoreRepresentation store_rep = StoreRepresentationOf(node->op());
- if (store_rep.representation() == MachineRepresentation::kWord64) {
+ case IrOpcode::kStore:
+ case IrOpcode::kUnalignedStore: {
+ MachineRepresentation rep;
+ if (node->opcode() == IrOpcode::kStore) {
+ rep = StoreRepresentationOf(node->op()).representation();
+ } else {
+ DCHECK(node->opcode() == IrOpcode::kUnalignedStore);
+ rep = UnalignedStoreRepresentationOf(node->op());
+ }
+
+ if (rep == MachineRepresentation::kWord64) {
// We change the original store node to store the low word, and create
// a new store node to store the high word. The effect and control edges
// are copied from the original store to the new store node, the effect
// edge of the original store is redirected to the new store.
- WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
-
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
- Node* index_high =
- graph()->NewNode(machine()->Int32Add(), index,
- graph()->NewNode(common()->Int32Constant(4)));
-
+ Node* index_low;
+ Node* index_high;
+ GetIndexNodes(index, index_low, index_high);
Node* value = node->InputAt(2);
DCHECK(HasReplacementLow(value));
DCHECK(HasReplacementHigh(value));
- const Operator* store_op = machine()->Store(StoreRepresentation(
- MachineRepresentation::kWord32, write_barrier_kind));
+ const Operator* store_op;
+ if (node->opcode() == IrOpcode::kStore) {
+ WriteBarrierKind write_barrier_kind =
+ StoreRepresentationOf(node->op()).write_barrier_kind();
+ store_op = machine()->Store(StoreRepresentation(
+ MachineRepresentation::kWord32, write_barrier_kind));
+ } else {
+ DCHECK(node->opcode() == IrOpcode::kUnalignedStore);
+ store_op = machine()->UnalignedStore(MachineRepresentation::kWord32);
+ }
Node* high_node;
if (node->InputCount() > 3) {
@@ -173,11 +226,14 @@ void Int64Lowering::LowerNode(Node* node) {
GetReplacementHigh(value));
}
+ node->ReplaceInput(1, index_low);
node->ReplaceInput(2, GetReplacementLow(value));
NodeProperties::ChangeOp(node, store_op);
ReplaceNode(node, node, high_node);
} else {
- DefaultLowering(node);
+ if (HasReplacementLow(node->InputAt(2))) {
+ node->ReplaceInput(2, GetReplacementLow(node->InputAt(2)));
+ }
}
break;
}
@@ -223,7 +279,9 @@ void Int64Lowering::LowerNode(Node* node) {
break;
}
case IrOpcode::kCall: {
- CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node);
+ // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor.
+ CallDescriptor* descriptor =
+ const_cast<CallDescriptor*>(CallDescriptorOf(node->op()));
if (DefaultLowering(node) ||
(descriptor->ReturnCount() == 1 &&
descriptor->GetReturnType(0) == MachineType::Int64())) {
@@ -235,8 +293,10 @@ void Int64Lowering::LowerNode(Node* node) {
if (descriptor->ReturnCount() == 1 &&
descriptor->GetReturnType(0) == MachineType::Int64()) {
// We access the additional return values through projections.
- Node* low_node = graph()->NewNode(common()->Projection(0), node);
- Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ Node* low_node =
+ graph()->NewNode(common()->Projection(0), node, graph()->start());
+ Node* high_node =
+ graph()->NewNode(common()->Projection(1), node, graph()->start());
ReplaceNode(node, low_node, high_node);
}
break;
@@ -262,9 +322,6 @@ void Int64Lowering::LowerNode(Node* node) {
node->NullAllInputs();
break;
}
- // todo(ahaas): I added a list of missing instructions here to make merging
- // easier when I do them one by one.
- // kExprI64Add:
case IrOpcode::kInt64Add: {
DCHECK(node->InputCount() == 2);
@@ -278,13 +335,13 @@ void Int64Lowering::LowerNode(Node* node) {
NodeProperties::ChangeOp(node, machine()->Int32PairAdd());
// We access the additional return values through projections.
- Node* low_node = graph()->NewNode(common()->Projection(0), node);
- Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ Node* low_node =
+ graph()->NewNode(common()->Projection(0), node, graph()->start());
+ Node* high_node =
+ graph()->NewNode(common()->Projection(1), node, graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
-
- // kExprI64Sub:
case IrOpcode::kInt64Sub: {
DCHECK(node->InputCount() == 2);
@@ -298,12 +355,13 @@ void Int64Lowering::LowerNode(Node* node) {
NodeProperties::ChangeOp(node, machine()->Int32PairSub());
// We access the additional return values through projections.
- Node* low_node = graph()->NewNode(common()->Projection(0), node);
- Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ Node* low_node =
+ graph()->NewNode(common()->Projection(0), node, graph()->start());
+ Node* high_node =
+ graph()->NewNode(common()->Projection(1), node, graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
- // kExprI64Mul:
case IrOpcode::kInt64Mul: {
DCHECK(node->InputCount() == 2);
@@ -317,16 +375,13 @@ void Int64Lowering::LowerNode(Node* node) {
NodeProperties::ChangeOp(node, machine()->Int32PairMul());
// We access the additional return values through projections.
- Node* low_node = graph()->NewNode(common()->Projection(0), node);
- Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ Node* low_node =
+ graph()->NewNode(common()->Projection(0), node, graph()->start());
+ Node* high_node =
+ graph()->NewNode(common()->Projection(1), node, graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
- // kExprI64DivS:
- // kExprI64DivU:
- // kExprI64RemS:
- // kExprI64RemU:
- // kExprI64Ior:
case IrOpcode::kWord64Or: {
DCHECK(node->InputCount() == 2);
Node* left = node->InputAt(0);
@@ -341,8 +396,6 @@ void Int64Lowering::LowerNode(Node* node) {
ReplaceNode(node, low_node, high_node);
break;
}
-
- // kExprI64Xor:
case IrOpcode::kWord64Xor: {
DCHECK(node->InputCount() == 2);
Node* left = node->InputAt(0);
@@ -357,7 +410,6 @@ void Int64Lowering::LowerNode(Node* node) {
ReplaceNode(node, low_node, high_node);
break;
}
- // kExprI64Shl:
case IrOpcode::kWord64Shl: {
// TODO(turbofan): if the shift count >= 32, then we can set the low word
// of the output to 0 and just calculate the high word.
@@ -375,12 +427,13 @@ void Int64Lowering::LowerNode(Node* node) {
NodeProperties::ChangeOp(node, machine()->Word32PairShl());
// We access the additional return values through projections.
- Node* low_node = graph()->NewNode(common()->Projection(0), node);
- Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ Node* low_node =
+ graph()->NewNode(common()->Projection(0), node, graph()->start());
+ Node* high_node =
+ graph()->NewNode(common()->Projection(1), node, graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
- // kExprI64ShrU:
case IrOpcode::kWord64Shr: {
// TODO(turbofan): if the shift count >= 32, then we can set the low word
// of the output to 0 and just calculate the high word.
@@ -398,12 +451,13 @@ void Int64Lowering::LowerNode(Node* node) {
NodeProperties::ChangeOp(node, machine()->Word32PairShr());
// We access the additional return values through projections.
- Node* low_node = graph()->NewNode(common()->Projection(0), node);
- Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ Node* low_node =
+ graph()->NewNode(common()->Projection(0), node, graph()->start());
+ Node* high_node =
+ graph()->NewNode(common()->Projection(1), node, graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
- // kExprI64ShrS:
case IrOpcode::kWord64Sar: {
// TODO(turbofan): if the shift count >= 32, then we can set the low word
// of the output to 0 and just calculate the high word.
@@ -421,12 +475,13 @@ void Int64Lowering::LowerNode(Node* node) {
NodeProperties::ChangeOp(node, machine()->Word32PairSar());
// We access the additional return values through projections.
- Node* low_node = graph()->NewNode(common()->Projection(0), node);
- Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ Node* low_node =
+ graph()->NewNode(common()->Projection(0), node, graph()->start());
+ Node* high_node =
+ graph()->NewNode(common()->Projection(1), node, graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
- // kExprI64Eq:
case IrOpcode::kWord64Equal: {
DCHECK(node->InputCount() == 2);
Node* left = node->InputAt(0);
@@ -446,7 +501,6 @@ void Int64Lowering::LowerNode(Node* node) {
ReplaceNode(node, replacement, nullptr);
break;
}
- // kExprI64LtS:
case IrOpcode::kInt64LessThan: {
LowerComparison(node, machine()->Int32LessThan(),
machine()->Uint32LessThan());
@@ -467,8 +521,6 @@ void Int64Lowering::LowerNode(Node* node) {
machine()->Uint32LessThanOrEqual());
break;
}
-
- // kExprI64SConvertI32:
case IrOpcode::kChangeInt32ToInt64: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
@@ -483,7 +535,6 @@ void Int64Lowering::LowerNode(Node* node) {
node->NullAllInputs();
break;
}
- // kExprI64UConvertI32: {
case IrOpcode::kChangeUint32ToUint64: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
@@ -494,7 +545,6 @@ void Int64Lowering::LowerNode(Node* node) {
node->NullAllInputs();
break;
}
- // kExprF64ReinterpretI64:
case IrOpcode::kBitcastInt64ToFloat64: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
@@ -505,14 +555,16 @@ void Int64Lowering::LowerNode(Node* node) {
machine()->Store(
StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier)),
- stack_slot, graph()->NewNode(common()->Int32Constant(4)),
+ stack_slot,
+ graph()->NewNode(common()->Int32Constant(kHigherWordOffset)),
GetReplacementHigh(input), graph()->start(), graph()->start());
Node* store_low_word = graph()->NewNode(
machine()->Store(
StoreRepresentation(MachineRepresentation::kWord32,
WriteBarrierKind::kNoWriteBarrier)),
- stack_slot, graph()->NewNode(common()->Int32Constant(0)),
+ stack_slot,
+ graph()->NewNode(common()->Int32Constant(kLowerWordOffset)),
GetReplacementLow(input), store_high_word, graph()->start());
Node* load =
@@ -523,7 +575,6 @@ void Int64Lowering::LowerNode(Node* node) {
ReplaceNode(node, load, nullptr);
break;
}
- // kExprI64ReinterpretF64:
case IrOpcode::kBitcastFloat64ToInt64: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
@@ -539,15 +590,15 @@ void Int64Lowering::LowerNode(Node* node) {
stack_slot, graph()->NewNode(common()->Int32Constant(0)), input,
graph()->start(), graph()->start());
- Node* high_node =
- graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot,
- graph()->NewNode(common()->Int32Constant(4)), store,
- graph()->start());
+ Node* high_node = graph()->NewNode(
+ machine()->Load(MachineType::Int32()), stack_slot,
+ graph()->NewNode(common()->Int32Constant(kHigherWordOffset)), store,
+ graph()->start());
- Node* low_node =
- graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot,
- graph()->NewNode(common()->Int32Constant(0)), store,
- graph()->start());
+ Node* low_node = graph()->NewNode(
+ machine()->Load(MachineType::Int32()), stack_slot,
+ graph()->NewNode(common()->Int32Constant(kLowerWordOffset)), store,
+ graph()->start());
ReplaceNode(node, low_node, high_node);
break;
}
@@ -659,7 +710,6 @@ void Int64Lowering::LowerNode(Node* node) {
}
break;
}
- // kExprI64Clz:
case IrOpcode::kWord64Clz: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
@@ -678,7 +728,6 @@ void Int64Lowering::LowerNode(Node* node) {
ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0)));
break;
}
- // kExprI64Ctz:
case IrOpcode::kWord64Ctz: {
DCHECK(node->InputCount() == 1);
DCHECK(machine()->Word32Ctz().IsSupported());
@@ -698,7 +747,6 @@ void Int64Lowering::LowerNode(Node* node) {
ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0)));
break;
}
- // kExprI64Popcnt:
case IrOpcode::kWord64Popcnt: {
DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
@@ -730,6 +778,14 @@ void Int64Lowering::LowerNode(Node* node) {
}
break;
}
+ case IrOpcode::kWord64ReverseBytes: {
+ Node* input = node->InputAt(0);
+ ReplaceNode(node, graph()->NewNode(machine()->Word32ReverseBytes().op(),
+ GetReplacementHigh(input)),
+ graph()->NewNode(machine()->Word32ReverseBytes().op(),
+ GetReplacementLow(input)));
+ break;
+ }
default: { DefaultLowering(node); }
}