Index: src/compiler/simd-scalar-lowering.cc |
diff --git a/src/compiler/simd-scalar-lowering.cc b/src/compiler/simd-scalar-lowering.cc |
index 10c43f1aa38f1b077f7fe042478b51532b5577c0..5cc6eebfb557d6db8a347d3e7394c48a30e8ba45 100644 |
--- a/src/compiler/simd-scalar-lowering.cc |
+++ b/src/compiler/simd-scalar-lowering.cc |
@@ -16,6 +16,13 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
+namespace { |
+static const int kNumLanes32 = 4; |
+static const int kNumLanes16 = 8; |
+static const int32_t kMask16 = 0xffff; |
+static const int32_t kShift16 = 16; |
+} // anonymous |
+ |
SimdScalarLowering::SimdScalarLowering( |
JSGraph* jsgraph, Signature<MachineRepresentation>* signature) |
: jsgraph_(jsgraph), |
@@ -35,7 +42,7 @@ SimdScalarLowering::SimdScalarLowering( |
void SimdScalarLowering::LowerGraph() { |
stack_.push_back({graph()->end(), 0}); |
state_.Set(graph()->end(), State::kOnStack); |
- replacements_[graph()->end()->id()].type = SimdType::kInt32; |
+ replacements_[graph()->end()->id()].type = SimdType::kInt32x4; |
while (!stack_.empty()) { |
NodeState& top = stack_.back(); |
@@ -73,11 +80,14 @@ void SimdScalarLowering::LowerGraph() { |
V(I32x4SConvertF32x4) \ |
V(I32x4UConvertF32x4) \ |
V(I32x4Neg) \ |
+ V(I32x4Shl) \ |
+ V(I32x4ShrS) \ |
V(I32x4Add) \ |
V(I32x4Sub) \ |
V(I32x4Mul) \ |
V(I32x4MinS) \ |
V(I32x4MaxS) \ |
+ V(I32x4ShrU) \ |
V(I32x4MinU) \ |
V(I32x4MaxU) \ |
V(S128And) \ |
@@ -119,6 +129,44 @@ void SimdScalarLowering::LowerGraph() { |
V(I32x4GtU) \ |
V(I32x4GeU) |
+#define FOREACH_INT16X8_OPCODE(V) \ |
+ V(I16x8Splat) \ |
+ V(I16x8ExtractLane) \ |
+ V(I16x8ReplaceLane) \ |
+ V(I16x8Neg) \ |
+ V(I16x8Shl) \ |
+ V(I16x8ShrS) \ |
+ V(I16x8Add) \ |
+ V(I16x8AddSaturateS) \ |
+ V(I16x8Sub) \ |
+ V(I16x8SubSaturateS) \ |
+ V(I16x8Mul) \ |
+ V(I16x8MinS) \ |
+ V(I16x8MaxS) \ |
+ V(I16x8ShrU) \ |
+ V(I16x8AddSaturateU) \ |
+ V(I16x8SubSaturateU) \ |
+ V(I16x8MinU) \ |
+ V(I16x8MaxU) |
+ |
+#define FOREACH_INT16X8_TO_SIMD1X8OPCODE(V) \ |
+ V(I16x8Eq) \ |
+ V(I16x8Ne) \ |
+ V(I16x8LtS) \ |
+ V(I16x8LeS) \ |
+ V(I16x8LtU) \ |
+ V(I16x8LeU) |
+ |
+#define FOREACH_SIMD_TYPE_TO_MACHINE_TYPE(V) \ |
+ V(Float32x4, Float32) \ |
+ V(Int32x4, Int32) \ |
+ V(Int16x8, Int16) |
+ |
+#define FOREACH_SIMD_TYPE_TO_MACHINE_REP(V) \ |
+ V(Float32x4, Float32) \ |
+ V(Int32x4, Word32) \ |
+ V(Int16x8, Word16) |
+ |
void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { |
switch (node->opcode()) { |
#define CASE_STMT(name) case IrOpcode::k##name: |
@@ -126,11 +174,11 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { |
case IrOpcode::kReturn: |
case IrOpcode::kParameter: |
case IrOpcode::kCall: { |
- replacements_[node->id()].type = SimdType::kInt32; |
+ replacements_[node->id()].type = SimdType::kInt32x4; |
break; |
} |
FOREACH_FLOAT32X4_OPCODE(CASE_STMT) { |
- replacements_[node->id()].type = SimdType::kFloat32; |
+ replacements_[node->id()].type = SimdType::kFloat32x4; |
break; |
} |
FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) |
@@ -138,24 +186,40 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { |
replacements_[node->id()].type = SimdType::kSimd1x4; |
break; |
} |
+ FOREACH_INT16X8_OPCODE(CASE_STMT) { |
+ replacements_[node->id()].type = SimdType::kInt16x8; |
+ break; |
+ } |
+ FOREACH_INT16X8_TO_SIMD1X8OPCODE(CASE_STMT) { |
+ replacements_[node->id()].type = SimdType::kSimd1x8; |
+ break; |
+ } |
default: { |
switch (output->opcode()) { |
FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) |
case IrOpcode::kF32x4SConvertI32x4: |
case IrOpcode::kF32x4UConvertI32x4: { |
- replacements_[node->id()].type = SimdType::kInt32; |
+ replacements_[node->id()].type = SimdType::kInt32x4; |
break; |
} |
FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) |
case IrOpcode::kI32x4SConvertF32x4: |
case IrOpcode::kI32x4UConvertF32x4: { |
- replacements_[node->id()].type = SimdType::kFloat32; |
+ replacements_[node->id()].type = SimdType::kFloat32x4; |
break; |
} |
case IrOpcode::kS32x4Select: { |
replacements_[node->id()].type = SimdType::kSimd1x4; |
break; |
} |
+ FOREACH_INT16X8_TO_SIMD1X8OPCODE(CASE_STMT) { |
+ replacements_[node->id()].type = SimdType::kInt16x8; |
+ break; |
+ } |
+ case IrOpcode::kS16x8Select: { |
+ replacements_[node->id()].type = SimdType::kSimd1x8; |
+ break; |
+ } |
default: { |
replacements_[node->id()].type = replacements_[output->id()].type; |
} |
@@ -199,42 +263,58 @@ static int GetReturnCountAfterLowering( |
return result; |
} |
-void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices) { |
+int SimdScalarLowering::NumLanes(SimdType type) { |
+ int num_lanes = 0; |
+ if (type == SimdType::kFloat32x4 || type == SimdType::kInt32x4 || |
+ type == SimdType::kSimd1x4) { |
+ num_lanes = kNumLanes32; |
+ } else if (type == SimdType::kInt16x8 || type == SimdType::kSimd1x8) { |
+ num_lanes = kNumLanes16; |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ return num_lanes; |
+} |
+ |
+void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices, |
+ SimdType type) { |
new_indices[0] = index; |
- for (size_t i = 1; i < kMaxLanes; ++i) { |
+ int num_lanes = NumLanes(type); |
+ int lane_width = kSimd128Size / num_lanes; |
+ for (int i = 1; i < num_lanes; ++i) { |
new_indices[i] = graph()->NewNode(machine()->Int32Add(), index, |
graph()->NewNode(common()->Int32Constant( |
- static_cast<int>(i) * kLaneWidth))); |
+ static_cast<int>(i) * lane_width))); |
} |
} |
void SimdScalarLowering::LowerLoadOp(MachineRepresentation rep, Node* node, |
- const Operator* load_op) { |
+ const Operator* load_op, SimdType type) { |
if (rep == MachineRepresentation::kSimd128) { |
Node* base = node->InputAt(0); |
Node* index = node->InputAt(1); |
- Node* indices[kMaxLanes]; |
- GetIndexNodes(index, indices); |
- Node* rep_nodes[kMaxLanes]; |
+ int num_lanes = NumLanes(type); |
+ Node** indices = zone()->NewArray<Node*>(num_lanes); |
+ GetIndexNodes(index, indices, type); |
+ Node** rep_nodes = zone()->NewArray<Node*>(num_lanes); |
rep_nodes[0] = node; |
NodeProperties::ChangeOp(rep_nodes[0], load_op); |
if (node->InputCount() > 2) { |
DCHECK(node->InputCount() > 3); |
Node* effect_input = node->InputAt(2); |
Node* control_input = node->InputAt(3); |
- rep_nodes[3] = graph()->NewNode(load_op, base, indices[3], effect_input, |
- control_input); |
- rep_nodes[2] = graph()->NewNode(load_op, base, indices[2], rep_nodes[3], |
- control_input); |
- rep_nodes[1] = graph()->NewNode(load_op, base, indices[1], rep_nodes[2], |
- control_input); |
+ for (int i = num_lanes - 1; i > 0; --i) { |
+ rep_nodes[i] = graph()->NewNode(load_op, base, indices[i], effect_input, |
+ control_input); |
+ effect_input = rep_nodes[i]; |
+ } |
rep_nodes[0]->ReplaceInput(2, rep_nodes[1]); |
} else { |
- for (size_t i = 1; i < kMaxLanes; ++i) { |
+ for (int i = 1; i < num_lanes; ++i) { |
rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]); |
} |
} |
- ReplaceNode(node, rep_nodes); |
+ ReplaceNode(node, rep_nodes, num_lanes); |
} else { |
DefaultLowering(node); |
} |
@@ -246,12 +326,13 @@ void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node, |
if (rep == MachineRepresentation::kSimd128) { |
Node* base = node->InputAt(0); |
Node* index = node->InputAt(1); |
- Node* indices[kMaxLanes]; |
- GetIndexNodes(index, indices); |
+ int num_lanes = NumLanes(rep_type); |
+ Node** indices = zone()->NewArray<Node*>(num_lanes); |
+ GetIndexNodes(index, indices, rep_type); |
DCHECK(node->InputCount() > 2); |
Node* value = node->InputAt(2); |
DCHECK(HasReplacement(1, value)); |
- Node* rep_nodes[kMaxLanes]; |
+ Node** rep_nodes = zone()->NewArray<Node*>(num_lanes); |
rep_nodes[0] = node; |
Node** rep_inputs = GetReplacementsWithType(value, rep_type); |
rep_nodes[0]->ReplaceInput(2, rep_inputs[0]); |
@@ -260,22 +341,22 @@ void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node, |
DCHECK(node->InputCount() > 4); |
Node* effect_input = node->InputAt(3); |
Node* control_input = node->InputAt(4); |
- rep_nodes[3] = graph()->NewNode(store_op, base, indices[3], rep_inputs[3], |
- effect_input, control_input); |
- rep_nodes[2] = graph()->NewNode(store_op, base, indices[2], rep_inputs[2], |
- rep_nodes[3], control_input); |
- rep_nodes[1] = graph()->NewNode(store_op, base, indices[1], rep_inputs[1], |
- rep_nodes[2], control_input); |
+ for (int i = num_lanes - 1; i > 0; --i) { |
+ rep_nodes[i] = |
+ graph()->NewNode(store_op, base, indices[i], rep_inputs[i], |
+ effect_input, control_input); |
+ effect_input = rep_nodes[i]; |
+ } |
rep_nodes[0]->ReplaceInput(3, rep_nodes[1]); |
} else { |
- for (size_t i = 1; i < kMaxLanes; ++i) { |
+ for (int i = 1; i < num_lanes; ++i) { |
rep_nodes[i] = |
graph()->NewNode(store_op, base, indices[i], rep_inputs[i]); |
} |
} |
- ReplaceNode(node, rep_nodes); |
+ ReplaceNode(node, rep_nodes, num_lanes); |
} else { |
DefaultLowering(node); |
} |
@@ -286,47 +367,120 @@ void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type, |
DCHECK(node->InputCount() == 2); |
Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); |
Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ int num_lanes = NumLanes(input_rep_type); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
if (invert_inputs) { |
rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]); |
} else { |
rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]); |
} |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
+} |
+ |
+Node* SimdScalarLowering::FixUpperBits(Node* input, int32_t shift) { |
+ return graph()->NewNode(machine()->Word32Sar(), |
+ graph()->NewNode(machine()->Word32Shl(), input, |
+ jsgraph_->Int32Constant(shift)), |
+ jsgraph_->Int32Constant(shift)); |
+} |
+ |
+void SimdScalarLowering::LowerBinaryOpForSmallInt(Node* node, |
+ SimdType input_rep_type, |
+ const Operator* op) { |
+ DCHECK(node->InputCount() == 2); |
+ Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); |
+ Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); |
+ int num_lanes = NumLanes(input_rep_type); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
+ rep_node[i] = |
+ FixUpperBits(graph()->NewNode(op, rep_left[i], rep_right[i]), kShift16); |
+ } |
+ ReplaceNode(node, rep_node, num_lanes); |
+} |
+ |
+Node* SimdScalarLowering::Mask(Node* input, int32_t mask) { |
+ return graph()->NewNode(machine()->Word32And(), input, |
+ jsgraph_->Int32Constant(mask)); |
+} |
+ |
+void SimdScalarLowering::LowerSaturateBinaryOp(Node* node, |
+ SimdType input_rep_type, |
+ const Operator* op, |
+ bool is_signed) { |
+ DCHECK(node->InputCount() == 2); |
+ Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); |
+ Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); |
+ int32_t min = 0; |
+ int32_t max = 0; |
+ if (is_signed) { |
+ min = std::numeric_limits<int16_t>::min(); |
+ max = std::numeric_limits<int16_t>::max(); |
+ } else { |
+ min = std::numeric_limits<uint16_t>::min(); |
+ max = std::numeric_limits<uint16_t>::max(); |
+ } |
+ int num_lanes = NumLanes(input_rep_type); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
+ Node* op_result = nullptr; |
+ Node* left = is_signed ? rep_left[i] : Mask(rep_left[i], kMask16); |
+ Node* right = is_signed ? rep_right[i] : Mask(rep_right[i], kMask16); |
+ op_result = graph()->NewNode(op, left, right); |
+ Diamond d_min(graph(), common(), |
+ graph()->NewNode(machine()->Int32LessThan(), op_result, |
+ jsgraph_->Int32Constant(min))); |
+ rep_node[i] = d_min.Phi(MachineRepresentation::kWord16, |
+ jsgraph_->Int32Constant(min), op_result); |
+ Diamond d_max(graph(), common(), |
+ graph()->NewNode(machine()->Int32LessThan(), |
+ jsgraph_->Int32Constant(max), rep_node[i])); |
+ rep_node[i] = d_max.Phi(MachineRepresentation::kWord16, |
+ jsgraph_->Int32Constant(max), rep_node[i]); |
+ rep_node[i] = is_signed ? rep_node[i] : FixUpperBits(rep_node[i], kShift16); |
+ } |
+ ReplaceNode(node, rep_node, num_lanes); |
} |
void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type, |
const Operator* op) { |
DCHECK(node->InputCount() == 1); |
Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type); |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ int num_lanes = NumLanes(input_rep_type); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
rep_node[i] = graph()->NewNode(op, rep[i]); |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
} |
void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op, |
- bool is_max) { |
+ bool is_max, SimdType type) { |
DCHECK(node->InputCount() == 2); |
- Node** rep_left = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); |
- Node** rep_right = |
- GetReplacementsWithType(node->InputAt(1), SimdType::kInt32); |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ Node** rep_left = GetReplacementsWithType(node->InputAt(0), type); |
+ Node** rep_right = GetReplacementsWithType(node->InputAt(1), type); |
+ int num_lanes = NumLanes(type); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ MachineRepresentation rep = MachineRepresentation::kNone; |
+ if (type == SimdType::kInt32x4) { |
+ rep = MachineRepresentation::kWord32; |
+ } else if (type == SimdType::kInt16x8) { |
+ rep = MachineRepresentation::kWord16; |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ for (int i = 0; i < num_lanes; ++i) { |
Diamond d(graph(), common(), |
graph()->NewNode(op, rep_left[i], rep_right[i])); |
if (is_max) { |
- rep_node[i] = |
- d.Phi(MachineRepresentation::kWord32, rep_right[i], rep_left[i]); |
+ rep_node[i] = d.Phi(rep, rep_right[i], rep_left[i]); |
} else { |
- rep_node[i] = |
- d.Phi(MachineRepresentation::kWord32, rep_left[i], rep_right[i]); |
+ rep_node[i] = d.Phi(rep, rep_left[i], rep_right[i]); |
} |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
} |
Node* SimdScalarLowering::BuildF64Trunc(Node* input) { |
@@ -361,14 +515,14 @@ Node* SimdScalarLowering::BuildF64Trunc(Node* input) { |
void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) { |
DCHECK(node->InputCount() == 1); |
- Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32); |
- Node* rep_node[kMaxLanes]; |
+ Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32x4); |
+ Node* rep_node[kNumLanes32]; |
Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0)); |
Node* min = graph()->NewNode( |
common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0))); |
Node* max = graph()->NewNode(common()->Float64Constant( |
static_cast<double>(is_signed ? kMaxInt : 0xffffffffu))); |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ for (int i = 0; i < kNumLanes32; ++i) { |
Node* double_rep = |
graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]); |
Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(), |
@@ -389,21 +543,44 @@ void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) { |
graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc); |
} |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, kNumLanes32); |
} |
-void SimdScalarLowering::LowerShiftOp(Node* node, const Operator* op) { |
- static int32_t shift_mask = 0x1f; |
+void SimdScalarLowering::LowerShiftOp(Node* node, SimdType type) { |
DCHECK_EQ(1, node->InputCount()); |
int32_t shift_amount = OpParameter<int32_t>(node); |
- Node* shift_node = |
- graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask)); |
- Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
- rep_node[i] = graph()->NewNode(op, rep[i], shift_node); |
+ Node* shift_node = graph()->NewNode(common()->Int32Constant(shift_amount)); |
+ Node** rep = GetReplacementsWithType(node->InputAt(0), type); |
+ int num_lanes = NumLanes(type); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
+ rep_node[i] = rep[i]; |
+ switch (node->opcode()) { |
+ case IrOpcode::kI16x8ShrU: |
+ rep_node[i] = Mask(rep_node[i], kMask16); // Fall through. |
+ case IrOpcode::kI32x4ShrU: |
+ rep_node[i] = |
+ graph()->NewNode(machine()->Word32Shr(), rep_node[i], shift_node); |
+ break; |
+ case IrOpcode::kI32x4Shl: |
+ rep_node[i] = |
+ graph()->NewNode(machine()->Word32Shl(), rep_node[i], shift_node); |
+ break; |
+ case IrOpcode::kI16x8Shl: |
+ rep_node[i] = |
+ graph()->NewNode(machine()->Word32Shl(), rep_node[i], shift_node); |
+ rep_node[i] = FixUpperBits(rep_node[i], kShift16); |
+ break; |
+ case IrOpcode::kI32x4ShrS: |
+ case IrOpcode::kI16x8ShrS: |
+ rep_node[i] = |
+ graph()->NewNode(machine()->Word32Sar(), rep_node[i], shift_node); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ } |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
} |
void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type, |
@@ -411,18 +588,20 @@ void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type, |
DCHECK(node->InputCount() == 2); |
Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); |
Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ int num_lanes = NumLanes(input_rep_type); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
Diamond d(graph(), common(), |
graph()->NewNode(op, rep_left[i], rep_right[i])); |
rep_node[i] = d.Phi(MachineRepresentation::kWord32, |
jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1)); |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
} |
void SimdScalarLowering::LowerNode(Node* node) { |
SimdType rep_type = ReplacementType(node); |
+ int num_lanes = NumLanes(rep_type); |
switch (node->opcode()) { |
case IrOpcode::kStart: { |
int parameter_count = GetParameterCountAfterLowering(); |
@@ -448,19 +627,19 @@ void SimdScalarLowering::LowerNode(Node* node) { |
if (old_index == new_index) { |
NodeProperties::ChangeOp(node, common()->Parameter(new_index)); |
- Node* new_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ Node* new_node[kNumLanes32]; |
+ for (int i = 0; i < kNumLanes32; ++i) { |
new_node[i] = nullptr; |
} |
new_node[0] = node; |
if (signature()->GetParam(old_index) == |
MachineRepresentation::kSimd128) { |
- for (int i = 1; i < kMaxLanes; ++i) { |
+ for (int i = 1; i < kNumLanes32; ++i) { |
new_node[i] = graph()->NewNode(common()->Parameter(new_index + i), |
graph()->start()); |
} |
} |
- ReplaceNode(node, new_node); |
+ ReplaceNode(node, new_node, kNumLanes32); |
} |
} |
break; |
@@ -469,24 +648,36 @@ void SimdScalarLowering::LowerNode(Node* node) { |
MachineRepresentation rep = |
LoadRepresentationOf(node->op()).representation(); |
const Operator* load_op; |
- if (rep_type == SimdType::kInt32) { |
- load_op = machine()->Load(MachineType::Int32()); |
- } else if (rep_type == SimdType::kFloat32) { |
- load_op = machine()->Load(MachineType::Float32()); |
+#define LOAD_CASE(sType, mType) \ |
+ case SimdType::k##sType: \ |
+ load_op = machine()->Load(MachineType::mType()); \ |
+ break; |
+ |
+ switch (rep_type) { |
+ FOREACH_SIMD_TYPE_TO_MACHINE_TYPE(LOAD_CASE) |
+ default: |
+ UNREACHABLE(); |
} |
- LowerLoadOp(rep, node, load_op); |
+#undef LOAD_CASE |
+ LowerLoadOp(rep, node, load_op, rep_type); |
break; |
} |
case IrOpcode::kUnalignedLoad: { |
MachineRepresentation rep = |
UnalignedLoadRepresentationOf(node->op()).representation(); |
const Operator* load_op; |
- if (rep_type == SimdType::kInt32) { |
- load_op = machine()->UnalignedLoad(MachineType::Int32()); |
- } else if (rep_type == SimdType::kFloat32) { |
- load_op = machine()->UnalignedLoad(MachineType::Float32()); |
+#define UNALIGNED_LOAD_CASE(sType, mType) \ |
+ case SimdType::k##sType: \ |
+ load_op = machine()->UnalignedLoad(MachineType::mType()); \ |
+ break; |
+ |
+ switch (rep_type) { |
+ FOREACH_SIMD_TYPE_TO_MACHINE_TYPE(UNALIGNED_LOAD_CASE) |
+ default: |
+ UNREACHABLE(); |
} |
- LowerLoadOp(rep, node, load_op); |
+#undef UNALIGHNED_LOAD_CASE |
+ LowerLoadOp(rep, node, load_op, rep_type); |
break; |
} |
case IrOpcode::kStore: { |
@@ -495,24 +686,35 @@ void SimdScalarLowering::LowerNode(Node* node) { |
WriteBarrierKind write_barrier_kind = |
StoreRepresentationOf(node->op()).write_barrier_kind(); |
const Operator* store_op; |
- if (rep_type == SimdType::kInt32) { |
- store_op = machine()->Store(StoreRepresentation( |
- MachineRepresentation::kWord32, write_barrier_kind)); |
- } else { |
- store_op = machine()->Store(StoreRepresentation( |
- MachineRepresentation::kFloat32, write_barrier_kind)); |
+#define STORE_CASE(sType, mType) \ |
+ case SimdType::k##sType: \ |
+ store_op = machine()->Store(StoreRepresentation( \ |
+ MachineRepresentation::k##mType, write_barrier_kind)); \ |
+ break; |
+ |
+ switch (rep_type) { |
+ FOREACH_SIMD_TYPE_TO_MACHINE_REP(STORE_CASE) |
+ default: |
+ UNREACHABLE(); |
} |
+#undef STORE_CASE |
LowerStoreOp(rep, node, store_op, rep_type); |
break; |
} |
case IrOpcode::kUnalignedStore: { |
MachineRepresentation rep = UnalignedStoreRepresentationOf(node->op()); |
const Operator* store_op; |
- if (rep_type == SimdType::kInt32) { |
- store_op = machine()->UnalignedStore(MachineRepresentation::kWord32); |
- } else { |
- store_op = machine()->UnalignedStore(MachineRepresentation::kFloat32); |
+#define UNALIGNED_STORE_CASE(sType, mType) \ |
+ case SimdType::k##sType: \ |
+ store_op = machine()->UnalignedStore(MachineRepresentation::k##mType); \ |
+ break; |
+ |
+ switch (rep_type) { |
+ FOREACH_SIMD_TYPE_TO_MACHINE_REP(UNALIGNED_STORE_CASE) |
+ default: |
+ UNREACHABLE(); |
} |
+#undef UNALIGNED_STORE_CASE |
LowerStoreOp(rep, node, store_op, rep_type); |
break; |
} |
@@ -540,12 +742,12 @@ void SimdScalarLowering::LowerNode(Node* node) { |
if (descriptor->ReturnCount() == 1 && |
descriptor->GetReturnType(0) == MachineType::Simd128()) { |
// We access the additional return values through projections. |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ Node* rep_node[kNumLanes32]; |
+ for (int i = 0; i < kNumLanes32; ++i) { |
rep_node[i] = |
graph()->NewNode(common()->Projection(i), node, graph()->start()); |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, kNumLanes32); |
} |
break; |
} |
@@ -558,7 +760,7 @@ void SimdScalarLowering::LowerNode(Node* node) { |
for (int i = 0; i < node->op()->ValueInputCount(); ++i) { |
Node** rep_input = |
GetReplacementsWithType(node->InputAt(i), rep_type); |
- for (int j = 0; j < kMaxLanes; j++) { |
+ for (int j = 0; j < num_lanes; j++) { |
rep_node[j]->ReplaceInput(i, rep_input[j]); |
} |
} |
@@ -579,42 +781,74 @@ void SimdScalarLowering::LowerNode(Node* node) { |
I32X4_BINOP_CASE(kS128Or, Word32Or) |
I32X4_BINOP_CASE(kS128Xor, Word32Xor) |
#undef I32X4_BINOP_CASE |
- case IrOpcode::kI32x4MaxS: { |
- LowerIntMinMax(node, machine()->Int32LessThan(), true); |
+ case IrOpcode::kI16x8Add: { |
+ LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Add()); |
+ break; |
+ } |
+ case IrOpcode::kI16x8Sub: { |
+ LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Sub()); |
+ break; |
+ } |
+ case IrOpcode::kI16x8Mul: { |
+ LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Mul()); |
+ break; |
+ } |
+ case IrOpcode::kI16x8AddSaturateS: { |
+ LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), true); |
+ break; |
+ } |
+ case IrOpcode::kI16x8SubSaturateS: { |
+ LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), true); |
+ break; |
+ } |
+ case IrOpcode::kI16x8AddSaturateU: { |
+ LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), false); |
break; |
} |
- case IrOpcode::kI32x4MinS: { |
- LowerIntMinMax(node, machine()->Int32LessThan(), false); |
+ case IrOpcode::kI16x8SubSaturateU: { |
+ LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), false); |
break; |
} |
- case IrOpcode::kI32x4MaxU: { |
- LowerIntMinMax(node, machine()->Uint32LessThan(), true); |
+ case IrOpcode::kI32x4MaxS: |
+ case IrOpcode::kI16x8MaxS: { |
+ LowerIntMinMax(node, machine()->Int32LessThan(), true, rep_type); |
break; |
} |
- case IrOpcode::kI32x4MinU: { |
- LowerIntMinMax(node, machine()->Uint32LessThan(), false); |
+ case IrOpcode::kI32x4MinS: |
+ case IrOpcode::kI16x8MinS: { |
+ LowerIntMinMax(node, machine()->Int32LessThan(), false, rep_type); |
+ break; |
+ } |
+ case IrOpcode::kI32x4MaxU: |
+ case IrOpcode::kI16x8MaxU: { |
+ LowerIntMinMax(node, machine()->Uint32LessThan(), true, rep_type); |
+ break; |
+ } |
+ case IrOpcode::kI32x4MinU: |
+ case IrOpcode::kI16x8MinU: { |
+ LowerIntMinMax(node, machine()->Uint32LessThan(), false, rep_type); |
break; |
} |
case IrOpcode::kI32x4Neg: { |
DCHECK(node->InputCount() == 1); |
Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); |
- Node* rep_node[kMaxLanes]; |
+ Node* rep_node[kNumLanes32]; |
Node* zero = graph()->NewNode(common()->Int32Constant(0)); |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ for (int i = 0; i < kNumLanes32; ++i) { |
rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]); |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, kNumLanes32); |
break; |
} |
case IrOpcode::kS128Not: { |
DCHECK(node->InputCount() == 1); |
Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); |
- Node* rep_node[kMaxLanes]; |
+ Node* rep_node[kNumLanes32]; |
Node* mask = graph()->NewNode(common()->Int32Constant(0xffffffff)); |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ for (int i = 0; i < kNumLanes32; ++i) { |
rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask); |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, kNumLanes32); |
break; |
} |
case IrOpcode::kI32x4SConvertF32x4: { |
@@ -625,16 +859,13 @@ void SimdScalarLowering::LowerNode(Node* node) { |
LowerConvertFromFloat(node, false); |
break; |
} |
- case IrOpcode::kI32x4Shl: { |
- LowerShiftOp(node, machine()->Word32Shl()); |
- break; |
- } |
- case IrOpcode::kI32x4ShrS: { |
- LowerShiftOp(node, machine()->Word32Sar()); |
- break; |
- } |
- case IrOpcode::kI32x4ShrU: { |
- LowerShiftOp(node, machine()->Word32Shr()); |
+ case IrOpcode::kI32x4Shl: |
+ case IrOpcode::kI16x8Shl: |
+ case IrOpcode::kI32x4ShrS: |
+ case IrOpcode::kI16x8ShrS: |
+ case IrOpcode::kI32x4ShrU: |
+ case IrOpcode::kI16x8ShrU: { |
+ LowerShiftOp(node, rep_type); |
break; |
} |
#define F32X4_BINOP_CASE(name) \ |
@@ -657,48 +888,52 @@ void SimdScalarLowering::LowerNode(Node* node) { |
F32X4_UNOP_CASE(Neg) |
#undef F32x4_UNOP_CASE |
case IrOpcode::kF32x4SConvertI32x4: { |
- LowerUnaryOp(node, SimdType::kInt32, machine()->RoundInt32ToFloat32()); |
+ LowerUnaryOp(node, SimdType::kInt32x4, machine()->RoundInt32ToFloat32()); |
break; |
} |
case IrOpcode::kF32x4UConvertI32x4: { |
- LowerUnaryOp(node, SimdType::kInt32, machine()->RoundUint32ToFloat32()); |
+ LowerUnaryOp(node, SimdType::kInt32x4, machine()->RoundUint32ToFloat32()); |
break; |
} |
case IrOpcode::kI32x4Splat: |
- case IrOpcode::kF32x4Splat: { |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ case IrOpcode::kF32x4Splat: |
+ case IrOpcode::kI16x8Splat: { |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
if (HasReplacement(0, node->InputAt(0))) { |
rep_node[i] = GetReplacements(node->InputAt(0))[0]; |
} else { |
rep_node[i] = node->InputAt(0); |
} |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
break; |
} |
case IrOpcode::kI32x4ExtractLane: |
- case IrOpcode::kF32x4ExtractLane: { |
+ case IrOpcode::kF32x4ExtractLane: |
+ case IrOpcode::kI16x8ExtractLane: { |
int32_t lane = OpParameter<int32_t>(node); |
- Node* rep_node[kMaxLanes] = { |
- GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr, |
- nullptr, nullptr}; |
- ReplaceNode(node, rep_node); |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ rep_node[0] = GetReplacementsWithType(node->InputAt(0), rep_type)[lane]; |
+ for (int i = 1; i < num_lanes; ++i) { |
+ rep_node[i] = nullptr; |
+ } |
+ ReplaceNode(node, rep_node, num_lanes); |
break; |
} |
case IrOpcode::kI32x4ReplaceLane: |
- case IrOpcode::kF32x4ReplaceLane: { |
+ case IrOpcode::kF32x4ReplaceLane: |
+ case IrOpcode::kI16x8ReplaceLane: { |
DCHECK_EQ(2, node->InputCount()); |
Node* repNode = node->InputAt(1); |
int32_t lane = OpParameter<int32_t>(node); |
- DCHECK(lane >= 0 && lane <= 3); |
Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type); |
if (HasReplacement(0, repNode)) { |
rep_node[lane] = GetReplacements(repNode)[0]; |
} else { |
rep_node[lane] = repNode; |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
break; |
} |
#define COMPARISON_CASE(type, simd_op, lowering_op, invert) \ |
@@ -706,51 +941,69 @@ void SimdScalarLowering::LowerNode(Node* node) { |
LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \ |
break; \ |
} |
- COMPARISON_CASE(Float32, kF32x4Eq, Float32Equal, false) |
- COMPARISON_CASE(Float32, kF32x4Lt, Float32LessThan, false) |
- COMPARISON_CASE(Float32, kF32x4Le, Float32LessThanOrEqual, false) |
- COMPARISON_CASE(Float32, kF32x4Gt, Float32LessThan, true) |
- COMPARISON_CASE(Float32, kF32x4Ge, Float32LessThanOrEqual, true) |
- COMPARISON_CASE(Int32, kI32x4Eq, Word32Equal, false) |
- COMPARISON_CASE(Int32, kI32x4LtS, Int32LessThan, false) |
- COMPARISON_CASE(Int32, kI32x4LeS, Int32LessThanOrEqual, false) |
- COMPARISON_CASE(Int32, kI32x4GtS, Int32LessThan, true) |
- COMPARISON_CASE(Int32, kI32x4GeS, Int32LessThanOrEqual, true) |
- COMPARISON_CASE(Int32, kI32x4LtU, Uint32LessThan, false) |
- COMPARISON_CASE(Int32, kI32x4LeU, Uint32LessThanOrEqual, false) |
- COMPARISON_CASE(Int32, kI32x4GtU, Uint32LessThan, true) |
- COMPARISON_CASE(Int32, kI32x4GeU, Uint32LessThanOrEqual, true) |
+ COMPARISON_CASE(Float32x4, kF32x4Eq, Float32Equal, false) |
+ COMPARISON_CASE(Float32x4, kF32x4Lt, Float32LessThan, false) |
+ COMPARISON_CASE(Float32x4, kF32x4Le, Float32LessThanOrEqual, false) |
+ COMPARISON_CASE(Float32x4, kF32x4Gt, Float32LessThan, true) |
+ COMPARISON_CASE(Float32x4, kF32x4Ge, Float32LessThanOrEqual, true) |
+ COMPARISON_CASE(Int32x4, kI32x4Eq, Word32Equal, false) |
+ COMPARISON_CASE(Int32x4, kI32x4LtS, Int32LessThan, false) |
+ COMPARISON_CASE(Int32x4, kI32x4LeS, Int32LessThanOrEqual, false) |
+ COMPARISON_CASE(Int32x4, kI32x4GtS, Int32LessThan, true) |
+ COMPARISON_CASE(Int32x4, kI32x4GeS, Int32LessThanOrEqual, true) |
+ COMPARISON_CASE(Int32x4, kI32x4LtU, Uint32LessThan, false) |
+ COMPARISON_CASE(Int32x4, kI32x4LeU, Uint32LessThanOrEqual, false) |
+ COMPARISON_CASE(Int32x4, kI32x4GtU, Uint32LessThan, true) |
+ COMPARISON_CASE(Int32x4, kI32x4GeU, Uint32LessThanOrEqual, true) |
+ COMPARISON_CASE(Int16x8, kI16x8Eq, Word32Equal, false) |
+ COMPARISON_CASE(Int16x8, kI16x8LtS, Int32LessThan, false) |
+ COMPARISON_CASE(Int16x8, kI16x8LeS, Int32LessThanOrEqual, false) |
+ COMPARISON_CASE(Int16x8, kI16x8GtS, Int32LessThan, true) |
+ COMPARISON_CASE(Int16x8, kI16x8GeS, Int32LessThanOrEqual, true) |
+ COMPARISON_CASE(Int16x8, kI16x8LtU, Uint32LessThan, false) |
+ COMPARISON_CASE(Int16x8, kI16x8LeU, Uint32LessThanOrEqual, false) |
+ COMPARISON_CASE(Int16x8, kI16x8GtU, Uint32LessThan, true) |
+ COMPARISON_CASE(Int16x8, kI16x8GeU, Uint32LessThanOrEqual, true) |
#undef COMPARISON_CASE |
case IrOpcode::kF32x4Ne: { |
- LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal()); |
+ LowerNotEqual(node, SimdType::kFloat32x4, machine()->Float32Equal()); |
break; |
} |
case IrOpcode::kI32x4Ne: { |
- LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal()); |
+ LowerNotEqual(node, SimdType::kInt32x4, machine()->Word32Equal()); |
+ break; |
+ } |
+ case IrOpcode::kI16x8Ne: { |
+ LowerNotEqual(node, SimdType::kInt16x8, machine()->Word32Equal()); |
break; |
} |
- case IrOpcode::kS32x4Select: { |
+ case IrOpcode::kS32x4Select: |
+ case IrOpcode::kS16x8Select: { |
DCHECK(node->InputCount() == 3); |
- DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4); |
+ DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4 || |
+ ReplacementType(node->InputAt(0)) == SimdType::kSimd1x8); |
Node** boolean_input = GetReplacements(node->InputAt(0)); |
Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type); |
Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type); |
- Node* rep_node[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ Node** rep_node = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
Diamond d(graph(), common(), |
graph()->NewNode(machine()->Word32Equal(), boolean_input[i], |
jsgraph_->Int32Constant(0))); |
- if (rep_type == SimdType::kFloat32) { |
- rep_node[i] = |
- d.Phi(MachineRepresentation::kFloat32, rep_right[1], rep_left[0]); |
- } else if (rep_type == SimdType::kInt32) { |
- rep_node[i] = |
- d.Phi(MachineRepresentation::kWord32, rep_right[1], rep_left[0]); |
- } else { |
- UNREACHABLE(); |
+#define SELECT_CASE(sType, mType) \ |
+ case SimdType::k##sType: \ |
+ rep_node[i] = \ |
+ d.Phi(MachineRepresentation::k##mType, rep_right[1], rep_left[0]); \ |
+ break; |
+ |
+ switch (rep_type) { |
+ FOREACH_SIMD_TYPE_TO_MACHINE_REP(SELECT_CASE) |
+ default: |
+ UNREACHABLE(); |
} |
+#undef SELECT_CASE |
} |
- ReplaceNode(node, rep_node); |
+ ReplaceNode(node, rep_node, num_lanes); |
break; |
} |
default: { DefaultLowering(node); } |
@@ -767,7 +1020,7 @@ bool SimdScalarLowering::DefaultLowering(Node* node) { |
} |
if (HasReplacement(1, input)) { |
something_changed = true; |
- for (int j = 1; j < kMaxLanes; j++) { |
+ for (int j = 1; j < ReplacementCount(input); ++j) { |
node->InsertInput(zone(), i + j, GetReplacements(input)[j]); |
} |
} |
@@ -775,18 +1028,17 @@ bool SimdScalarLowering::DefaultLowering(Node* node) { |
return something_changed; |
} |
-void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node) { |
- // if new_low == nullptr, then also new_high == nullptr. |
- DCHECK(new_node[0] != nullptr || |
- (new_node[1] == nullptr && new_node[2] == nullptr && |
- new_node[3] == nullptr)); |
- for (int i = 0; i < kMaxLanes; ++i) { |
- replacements_[old->id()].node[i] = new_node[i]; |
+void SimdScalarLowering::ReplaceNode(Node* old, Node** new_nodes, int count) { |
+ replacements_[old->id()].node = zone()->NewArray<Node*>(count); |
+ for (int i = 0; i < count; ++i) { |
+ replacements_[old->id()].node[i] = new_nodes[i]; |
} |
+ replacements_[old->id()].num_replacements = count; |
} |
bool SimdScalarLowering::HasReplacement(size_t index, Node* node) { |
- return replacements_[node->id()].node[index] != nullptr; |
+ return replacements_[node->id()].node != nullptr && |
+ replacements_[node->id()].node[index] != nullptr; |
} |
SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) { |
@@ -799,30 +1051,61 @@ Node** SimdScalarLowering::GetReplacements(Node* node) { |
return result; |
} |
+int SimdScalarLowering::ReplacementCount(Node* node) { |
+ return replacements_[node->id()].num_replacements; |
+} |
+ |
+void SimdScalarLowering::Int32ToFloat32(Node** replacements, Node** result) { |
+ for (int i = 0; i < kNumLanes32; ++i) { |
+ if (replacements[i] != nullptr) { |
+ result[i] = |
+ graph()->NewNode(machine()->BitcastInt32ToFloat32(), replacements[i]); |
+ } else { |
+ result[i] = nullptr; |
+ } |
+ } |
+} |
+ |
+void SimdScalarLowering::Float32ToInt32(Node** replacements, Node** result) { |
+ for (int i = 0; i < kNumLanes32; ++i) { |
+ if (replacements[i] != nullptr) { |
+ result[i] = |
+ graph()->NewNode(machine()->BitcastFloat32ToInt32(), replacements[i]); |
+ } else { |
+ result[i] = nullptr; |
+ } |
+ } |
+} |
+ |
Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) { |
Node** replacements = GetReplacements(node); |
if (ReplacementType(node) == type) { |
return GetReplacements(node); |
} |
- Node** result = zone()->NewArray<Node*>(kMaxLanes); |
- if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) { |
- for (int i = 0; i < kMaxLanes; ++i) { |
- if (replacements[i] != nullptr) { |
- result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(), |
- replacements[i]); |
- } else { |
- result[i] = nullptr; |
- } |
+ int num_lanes = NumLanes(type); |
+ Node** result = zone()->NewArray<Node*>(num_lanes); |
+ if (type == SimdType::kInt32x4) { |
+ if (ReplacementType(node) == SimdType::kFloat32x4) { |
+ Float32ToInt32(replacements, result); |
+ } else if (ReplacementType(node) == SimdType::kInt16x8) { |
+ UNIMPLEMENTED(); |
+ } else { |
+ UNREACHABLE(); |
} |
- } else if (ReplacementType(node) == SimdType::kFloat32 && |
- type == SimdType::kInt32) { |
- for (int i = 0; i < kMaxLanes; ++i) { |
- if (replacements[i] != nullptr) { |
- result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(), |
- replacements[i]); |
- } else { |
- result[i] = nullptr; |
- } |
+ } else if (type == SimdType::kFloat32x4) { |
+ if (ReplacementType(node) == SimdType::kInt32x4) { |
+ Int32ToFloat32(replacements, result); |
+ } else if (ReplacementType(node) == SimdType::kInt16x8) { |
+ UNIMPLEMENTED(); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ } else if (type == SimdType::kInt16x8) { |
+ if (ReplacementType(node) == SimdType::kInt32x4 || |
+ ReplacementType(node) == SimdType::kFloat32x4) { |
+ UNIMPLEMENTED(); |
+ } else { |
+ UNREACHABLE(); |
} |
} else { |
UNREACHABLE(); |
@@ -839,31 +1122,34 @@ void SimdScalarLowering::PreparePhiReplacement(Node* phi) { |
// graph verifier. |
int value_count = phi->op()->ValueInputCount(); |
SimdType type = ReplacementType(phi); |
- Node** inputs_rep[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
+ int num_lanes = NumLanes(type); |
+ Node*** inputs_rep = zone()->NewArray<Node**>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1); |
inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0); |
} |
for (int i = 0; i < value_count; ++i) { |
- for (int j = 0; j < kMaxLanes; j++) { |
+ for (int j = 0; j < num_lanes; ++j) { |
inputs_rep[j][i] = placeholder_; |
} |
} |
- Node* rep_nodes[kMaxLanes]; |
- for (int i = 0; i < kMaxLanes; ++i) { |
- if (type == SimdType::kInt32) { |
- rep_nodes[i] = graph()->NewNode( |
- common()->Phi(MachineRepresentation::kWord32, value_count), |
- value_count + 1, inputs_rep[i], false); |
- } else if (type == SimdType::kFloat32) { |
- rep_nodes[i] = graph()->NewNode( |
- common()->Phi(MachineRepresentation::kFloat32, value_count), |
- value_count + 1, inputs_rep[i], false); |
- } else { |
- UNREACHABLE(); |
+ Node** rep_nodes = zone()->NewArray<Node*>(num_lanes); |
+ for (int i = 0; i < num_lanes; ++i) { |
+#define PHI_CASE(sType, mType) \ |
+ case SimdType::k##sType: \ |
+ rep_nodes[i] = graph()->NewNode( \ |
+ common()->Phi(MachineRepresentation::k##mType, value_count), \ |
+ value_count + 1, inputs_rep[i], false); \ |
+ break; |
+ |
+ switch (type) { |
+ FOREACH_SIMD_TYPE_TO_MACHINE_REP(PHI_CASE) |
+ default: |
+ UNREACHABLE(); |
} |
+#undef PHI_CASE |
} |
- ReplaceNode(phi, rep_nodes); |
+ ReplaceNode(phi, rep_nodes, num_lanes); |
} |
} |
} // namespace compiler |