| Index: src/compiler/int64-lowering.cc
|
| diff --git a/src/compiler/int64-lowering.cc b/src/compiler/int64-lowering.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c2952319be24a4345a4095bb6a2e221f6b7a9edf
|
| --- /dev/null
|
| +++ b/src/compiler/int64-lowering.cc
|
| @@ -0,0 +1,103 @@
|
| +// Copyright 2014 the V8 project authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "src/compiler/int64-lowering.h"
|
| +#include "src/compiler/common-operator.h"
|
| +#include "src/compiler/graph.h"
|
| +#include "src/compiler/machine-operator.h"
|
| +#include "src/compiler/node.h"
|
| +#include "src/zone.h"
|
| +
|
| +namespace v8 {
|
| +namespace internal {
|
| +namespace compiler {
|
| +
|
| +Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine,
|
| + CommonOperatorBuilder* common, Zone* zone)
|
| + : graph_(graph),
|
| + machine_(machine),
|
| + common_(common),
|
| + state_(graph, 4),
|
| + stack_(zone),
|
| + replacements_(zone->NewArray<Replacement>(graph->NodeCount())) {
|
| + memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount());
|
| +}
|
| +
|
| +void Int64Lowering::ReduceGraph() {
|
| + stack_.push(graph()->end());
|
| + state_.Set(graph()->end(), State::kOnStack);
|
| +
|
| + while (!stack_.empty()) {
|
| + Node* top = stack_.top();
|
| + if (state_.Get(top) == State::kInputsPushed) {
|
| + stack_.pop();
|
| + state_.Set(top, State::kVisited);
|
| + // All inputs of top have already been reduced, now reduce top.
|
| + ReduceNode(top);
|
| + } else {
|
| + // Push all children onto the stack.
|
| + for (Node* input : top->inputs()) {
|
| + if (state_.Get(input) == State::kUnvisited) {
|
| + stack_.push(input);
|
| + state_.Set(input, State::kOnStack);
|
| + }
|
| + }
|
| + state_.Set(top, State::kInputsPushed);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void Int64Lowering::ReduceNode(Node* node) {
|
| + switch (node->opcode()) {
|
| + case IrOpcode::kInt64Constant: {
|
| + int64_t value = OpParameter<int64_t>(node);
|
| + Node* low_node = graph()->NewNode(
|
| + common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF)));
|
| + Node* high_node = graph()->NewNode(
|
| + common()->Int32Constant(static_cast<int32_t>(value >> 32)));
|
| + replacements_[node->id()].low = low_node;
|
| + replacements_[node->id()].high = high_node;
|
| + break;
|
| + }
|
| + case IrOpcode::kWord64And: {
|
| + Node* left = node->InputAt(0);
|
| + DCHECK(replacements_[left->id()].low);
|
| + Node* left_low = replacements_[left->id()].low;
|
| + Node* left_high = replacements_[left->id()].high;
|
| +
|
| + Node* right = node->InputAt(1);
|
| + DCHECK(replacements_[right->id()].low);
|
| + Node* right_low = replacements_[right->id()].low;
|
| + Node* right_high = replacements_[right->id()].high;
|
| +
|
| + replacements_[node->id()].low =
|
| + graph()->NewNode(machine()->Word32And(), left_low, right_low);
|
| + replacements_[node->id()].high =
|
| + graph()->NewNode(machine()->Word32And(), left_high, right_high);
|
| + break;
|
| + }
|
| + case IrOpcode::kTruncateInt64ToInt32: {
|
| + Node* input = node->InputAt(0);
|
| + DCHECK(replacements_[input->id()].low);
|
| + replacements_[node->id()].low = replacements_[input->id()].low;
|
| + break;
|
| + }
|
| + default: {
|
| + // Also the inputs of nodes can change which do not expect int64 inputs.
|
| + for (int i = 0; i < node->InputCount(); i++) {
|
| + Node* input = node->InputAt(i);
|
| + // The input has changed altough it was not an int64 input. This can
|
| + // happen e.g. if the input node is IrOpcode::kTruncateInt64ToInt32. We
|
| + // use the low word replacement as the new input.
|
| + if (replacements_[input->id()].low) {
|
| + node->ReplaceInput(i, replacements_[input->id()].low);
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace compiler
|
| +} // namespace internal
|
| +} // namespace v8
|
|
|