Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: src/compiler/simd-scalar-lowering.cc

Issue 2843523002: [wasm] Implement simd lowering for I16x8 (Closed)
Patch Set: [wasm] Implement simd lowering for I16x8 Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/simd-scalar-lowering.h" 5 #include "src/compiler/simd-scalar-lowering.h"
6 #include "src/compiler/diamond.h" 6 #include "src/compiler/diamond.h"
7 #include "src/compiler/linkage.h" 7 #include "src/compiler/linkage.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 V(I32x4SConvertF32x4) \ 73 V(I32x4SConvertF32x4) \
74 V(I32x4UConvertF32x4) \ 74 V(I32x4UConvertF32x4) \
75 V(I32x4Neg) \ 75 V(I32x4Neg) \
76 V(I32x4Add) \ 76 V(I32x4Add) \
77 V(I32x4Sub) \ 77 V(I32x4Sub) \
78 V(I32x4Mul) \ 78 V(I32x4Mul) \
79 V(I32x4MinS) \ 79 V(I32x4MinS) \
80 V(I32x4MaxS) \ 80 V(I32x4MaxS) \
81 V(I32x4MinU) \ 81 V(I32x4MinU) \
82 V(I32x4MaxU) \ 82 V(I32x4MaxU) \
83 V(I32x4Shl) \
84 V(I32x4ShrS) \
85 V(I32x4ShrU) \
gdeepti 2017/04/25 20:29:57 Reorder so shifts are with other Unary ops to be c
aseemgarg 2017/04/26 23:02:01 Done.
83 V(S128And) \ 86 V(S128And) \
84 V(S128Or) \ 87 V(S128Or) \
85 V(S128Xor) \ 88 V(S128Xor) \
86 V(S128Not) 89 V(S128Not)
87 90
88 #define FOREACH_FLOAT32X4_OPCODE(V) \ 91 #define FOREACH_FLOAT32X4_OPCODE(V) \
89 V(F32x4Splat) \ 92 V(F32x4Splat) \
90 V(F32x4ExtractLane) \ 93 V(F32x4ExtractLane) \
91 V(F32x4ReplaceLane) \ 94 V(F32x4ReplaceLane) \
92 V(F32x4SConvertI32x4) \ 95 V(F32x4SConvertI32x4) \
(...skipping 19 matching lines...) Expand all
112 V(I32x4Ne) \ 115 V(I32x4Ne) \
113 V(I32x4LtS) \ 116 V(I32x4LtS) \
114 V(I32x4LeS) \ 117 V(I32x4LeS) \
115 V(I32x4GtS) \ 118 V(I32x4GtS) \
116 V(I32x4GeS) \ 119 V(I32x4GeS) \
117 V(I32x4LtU) \ 120 V(I32x4LtU) \
118 V(I32x4LeU) \ 121 V(I32x4LeU) \
119 V(I32x4GtU) \ 122 V(I32x4GtU) \
120 V(I32x4GeU) 123 V(I32x4GeU)
121 124
125 #define FOREACH_INT16X8_OPCODE(V) \
126 V(I16x8Splat) \
127 V(I16x8ExtractLane) \
128 V(I16x8ReplaceLane) \
129 V(I16x8Neg) \
130 V(I16x8Shl) \
131 V(I16x8ShrS) \
132 V(I16x8Add) \
133 V(I16x8AddSaturateS) \
134 V(I16x8Sub) \
135 V(I16x8SubSaturateS) \
136 V(I16x8Mul) \
137 V(I16x8MinS) \
138 V(I16x8MaxS) \
139 V(I16x8ShrU) \
140 V(I16x8AddSaturateU) \
141 V(I16x8SubSaturateU) \
142 V(I16x8MinU) \
143 V(I16x8MaxU)
144
145 #define FOREACH_INT16X8_TO_SIMD1X8OPCODE(V) \
146 V(I16x8Eq) \
147 V(I16x8Ne) \
148 V(I16x8LtS) \
149 V(I16x8LeS) \
150 V(I16x8LtU) \
151 V(I16x8LeU)
152
122 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { 153 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
123 switch (node->opcode()) { 154 switch (node->opcode()) {
124 #define CASE_STMT(name) case IrOpcode::k##name: 155 #define CASE_STMT(name) case IrOpcode::k##name:
125 FOREACH_INT32X4_OPCODE(CASE_STMT) 156 FOREACH_INT32X4_OPCODE(CASE_STMT)
126 case IrOpcode::kReturn: 157 case IrOpcode::kReturn:
127 case IrOpcode::kParameter: 158 case IrOpcode::kParameter:
128 case IrOpcode::kCall: { 159 case IrOpcode::kCall: {
129 replacements_[node->id()].type = SimdType::kInt32; 160 replacements_[node->id()].type = SimdType::kInt32;
130 break; 161 break;
131 } 162 }
132 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) { 163 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) {
133 replacements_[node->id()].type = SimdType::kFloat32; 164 replacements_[node->id()].type = SimdType::kFloat32;
134 break; 165 break;
135 } 166 }
136 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) 167 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
137 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) { 168 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) {
138 replacements_[node->id()].type = SimdType::kSimd1x4; 169 replacements_[node->id()].type = SimdType::kSimd1x4;
139 break; 170 break;
140 } 171 }
172 FOREACH_INT16X8_OPCODE(CASE_STMT) {
173 replacements_[node->id()].type = SimdType::kInt16;
174 break;
175 }
176 FOREACH_INT16X8_TO_SIMD1X8OPCODE(CASE_STMT) {
177 replacements_[node->id()].type = SimdType::kSimd1x8;
178 break;
179 }
141 default: { 180 default: {
142 switch (output->opcode()) { 181 switch (output->opcode()) {
143 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) 182 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
144 case IrOpcode::kF32x4SConvertI32x4: 183 case IrOpcode::kF32x4SConvertI32x4:
145 case IrOpcode::kF32x4UConvertI32x4: { 184 case IrOpcode::kF32x4UConvertI32x4: {
146 replacements_[node->id()].type = SimdType::kInt32; 185 replacements_[node->id()].type = SimdType::kInt32;
147 break; 186 break;
148 } 187 }
149 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) 188 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
150 case IrOpcode::kI32x4SConvertF32x4: 189 case IrOpcode::kI32x4SConvertF32x4:
151 case IrOpcode::kI32x4UConvertF32x4: { 190 case IrOpcode::kI32x4UConvertF32x4: {
152 replacements_[node->id()].type = SimdType::kFloat32; 191 replacements_[node->id()].type = SimdType::kFloat32;
153 break; 192 break;
154 } 193 }
155 case IrOpcode::kS32x4Select: { 194 case IrOpcode::kS32x4Select: {
156 replacements_[node->id()].type = SimdType::kSimd1x4; 195 replacements_[node->id()].type = SimdType::kSimd1x4;
157 break; 196 break;
158 } 197 }
198 FOREACH_INT16X8_TO_SIMD1X8OPCODE(CASE_STMT) {
199 replacements_[node->id()].type = SimdType::kInt16;
200 break;
201 }
202 case IrOpcode::kS16x8Select: {
203 replacements_[node->id()].type = SimdType::kSimd1x8;
204 break;
205 }
159 default: { 206 default: {
160 replacements_[node->id()].type = replacements_[output->id()].type; 207 replacements_[node->id()].type = replacements_[output->id()].type;
161 } 208 }
162 } 209 }
163 } 210 }
164 #undef CASE_STMT 211 #undef CASE_STMT
165 } 212 }
166 } 213 }
167 214
168 static int GetParameterIndexAfterLowering( 215 static int GetParameterIndexAfterLowering(
(...skipping 23 matching lines...) Expand all
192 Signature<MachineRepresentation>* signature) { 239 Signature<MachineRepresentation>* signature) {
193 int result = static_cast<int>(signature->return_count()); 240 int result = static_cast<int>(signature->return_count());
194 for (int i = 0; i < static_cast<int>(signature->return_count()); ++i) { 241 for (int i = 0; i < static_cast<int>(signature->return_count()); ++i) {
195 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) { 242 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) {
196 result += 3; 243 result += 3;
197 } 244 }
198 } 245 }
199 return result; 246 return result;
200 } 247 }
201 248
202 void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices) { 249 int SimdScalarLowering::NumLanes(SimdType type) {
250 int num_lanes = 0;
251 if (type == SimdType::kFloat32 || type == SimdType::kInt32 ||
252 type == SimdType::kSimd1x4) {
253 num_lanes = kNumLanes32;
254 } else if (type == SimdType::kInt16 || type == SimdType::kSimd1x8) {
255 num_lanes = kNumLanes16;
256 } else {
257 UNREACHABLE();
258 }
259 return num_lanes;
260 }
261
262 void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices,
263 SimdType type) {
203 new_indices[0] = index; 264 new_indices[0] = index;
204 for (size_t i = 1; i < kMaxLanes; ++i) { 265 int num_lanes = NumLanes(type);
266 int lane_width = kSimd128Size / num_lanes;
267 for (int i = 1; i < num_lanes; ++i) {
205 new_indices[i] = graph()->NewNode(machine()->Int32Add(), index, 268 new_indices[i] = graph()->NewNode(machine()->Int32Add(), index,
206 graph()->NewNode(common()->Int32Constant( 269 graph()->NewNode(common()->Int32Constant(
207 static_cast<int>(i) * kLaneWidth))); 270 static_cast<int>(i) * lane_width)));
208 } 271 }
209 } 272 }
210 273
211 void SimdScalarLowering::LowerLoadOp(MachineRepresentation rep, Node* node, 274 void SimdScalarLowering::LowerLoadOp(MachineRepresentation rep, Node* node,
212 const Operator* load_op) { 275 const Operator* load_op, SimdType type) {
213 if (rep == MachineRepresentation::kSimd128) { 276 if (rep == MachineRepresentation::kSimd128) {
214 Node* base = node->InputAt(0); 277 Node* base = node->InputAt(0);
215 Node* index = node->InputAt(1); 278 Node* index = node->InputAt(1);
216 Node* indices[kMaxLanes]; 279 int num_lanes = NumLanes(type);
217 GetIndexNodes(index, indices); 280 Node** indices = zone()->NewArray<Node*>(num_lanes);
218 Node* rep_nodes[kMaxLanes]; 281 GetIndexNodes(index, indices, type);
282 Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
219 rep_nodes[0] = node; 283 rep_nodes[0] = node;
220 NodeProperties::ChangeOp(rep_nodes[0], load_op); 284 NodeProperties::ChangeOp(rep_nodes[0], load_op);
221 if (node->InputCount() > 2) { 285 if (node->InputCount() > 2) {
222 DCHECK(node->InputCount() > 3); 286 DCHECK(node->InputCount() > 3);
223 Node* effect_input = node->InputAt(2); 287 Node* effect_input = node->InputAt(2);
224 Node* control_input = node->InputAt(3); 288 Node* control_input = node->InputAt(3);
225 rep_nodes[3] = graph()->NewNode(load_op, base, indices[3], effect_input, 289 for (int i = num_lanes - 1; i > 0; --i) {
226 control_input); 290 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i], effect_input,
227 rep_nodes[2] = graph()->NewNode(load_op, base, indices[2], rep_nodes[3], 291 control_input);
228 control_input); 292 effect_input = rep_nodes[i];
229 rep_nodes[1] = graph()->NewNode(load_op, base, indices[1], rep_nodes[2], 293 }
230 control_input);
231 rep_nodes[0]->ReplaceInput(2, rep_nodes[1]); 294 rep_nodes[0]->ReplaceInput(2, rep_nodes[1]);
232 } else { 295 } else {
233 for (size_t i = 1; i < kMaxLanes; ++i) { 296 for (int i = 1; i < num_lanes; ++i) {
234 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]); 297 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]);
235 } 298 }
236 } 299 }
237 ReplaceNode(node, rep_nodes); 300 ReplaceNode(node, rep_nodes, num_lanes);
238 } else { 301 } else {
239 DefaultLowering(node); 302 DefaultLowering(node);
240 } 303 }
241 } 304 }
242 305
243 void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node, 306 void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node,
244 const Operator* store_op, 307 const Operator* store_op,
245 SimdType rep_type) { 308 SimdType rep_type) {
246 if (rep == MachineRepresentation::kSimd128) { 309 if (rep == MachineRepresentation::kSimd128) {
247 Node* base = node->InputAt(0); 310 Node* base = node->InputAt(0);
248 Node* index = node->InputAt(1); 311 Node* index = node->InputAt(1);
249 Node* indices[kMaxLanes]; 312 int num_lanes = NumLanes(rep_type);
250 GetIndexNodes(index, indices); 313 Node** indices = zone()->NewArray<Node*>(num_lanes);
314 GetIndexNodes(index, indices, rep_type);
251 DCHECK(node->InputCount() > 2); 315 DCHECK(node->InputCount() > 2);
252 Node* value = node->InputAt(2); 316 Node* value = node->InputAt(2);
253 DCHECK(HasReplacement(1, value)); 317 DCHECK(HasReplacement(1, value));
254 Node* rep_nodes[kMaxLanes]; 318 Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
255 rep_nodes[0] = node; 319 rep_nodes[0] = node;
256 Node** rep_inputs = GetReplacementsWithType(value, rep_type); 320 Node** rep_inputs = GetReplacementsWithType(value, rep_type);
257 rep_nodes[0]->ReplaceInput(2, rep_inputs[0]); 321 rep_nodes[0]->ReplaceInput(2, rep_inputs[0]);
258 NodeProperties::ChangeOp(node, store_op); 322 NodeProperties::ChangeOp(node, store_op);
259 if (node->InputCount() > 3) { 323 if (node->InputCount() > 3) {
260 DCHECK(node->InputCount() > 4); 324 DCHECK(node->InputCount() > 4);
261 Node* effect_input = node->InputAt(3); 325 Node* effect_input = node->InputAt(3);
262 Node* control_input = node->InputAt(4); 326 Node* control_input = node->InputAt(4);
263 rep_nodes[3] = graph()->NewNode(store_op, base, indices[3], rep_inputs[3], 327 for (int i = num_lanes - 1; i > 0; --i) {
264 effect_input, control_input); 328 rep_nodes[i] =
265 rep_nodes[2] = graph()->NewNode(store_op, base, indices[2], rep_inputs[2], 329 graph()->NewNode(store_op, base, indices[i], rep_inputs[i],
266 rep_nodes[3], control_input); 330 effect_input, control_input);
267 rep_nodes[1] = graph()->NewNode(store_op, base, indices[1], rep_inputs[1], 331 effect_input = rep_nodes[i];
268 rep_nodes[2], control_input); 332 }
269 rep_nodes[0]->ReplaceInput(3, rep_nodes[1]); 333 rep_nodes[0]->ReplaceInput(3, rep_nodes[1]);
270 334
271 } else { 335 } else {
272 for (size_t i = 1; i < kMaxLanes; ++i) { 336 for (int i = 1; i < num_lanes; ++i) {
273 rep_nodes[i] = 337 rep_nodes[i] =
274 graph()->NewNode(store_op, base, indices[i], rep_inputs[i]); 338 graph()->NewNode(store_op, base, indices[i], rep_inputs[i]);
275 } 339 }
276 } 340 }
277 341
278 ReplaceNode(node, rep_nodes); 342 ReplaceNode(node, rep_nodes, num_lanes);
279 } else { 343 } else {
280 DefaultLowering(node); 344 DefaultLowering(node);
281 } 345 }
282 } 346 }
283 347
284 void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type, 348 void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type,
285 const Operator* op, bool invert_inputs) { 349 const Operator* op, bool invert_inputs) {
286 DCHECK(node->InputCount() == 2); 350 DCHECK(node->InputCount() == 2);
287 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); 351 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
288 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); 352 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
289 Node* rep_node[kMaxLanes]; 353 int num_lanes = NumLanes(input_rep_type);
290 for (int i = 0; i < kMaxLanes; ++i) { 354 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
355 for (int i = 0; i < num_lanes; ++i) {
291 if (invert_inputs) { 356 if (invert_inputs) {
292 rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]); 357 rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]);
293 } else { 358 } else {
294 rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]); 359 rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
295 } 360 }
296 } 361 }
297 ReplaceNode(node, rep_node); 362 ReplaceNode(node, rep_node, num_lanes);
363 }
364
365 Node* SimdScalarLowering::FixUpperBits(Node* input, int32_t shift) {
366 return graph()->NewNode(machine()->Word32Sar(),
367 graph()->NewNode(machine()->Word32Shl(), input,
368 jsgraph_->Int32Constant(shift)),
369 jsgraph_->Int32Constant(shift));
370 }
371
372 void SimdScalarLowering::LowerBinaryOpForSmallInt(Node* node,
373 SimdType input_rep_type,
374 const Operator* op) {
375 DCHECK(node->InputCount() == 2);
376 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
377 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
378 int num_lanes = NumLanes(input_rep_type);
379 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
380 for (int i = 0; i < num_lanes; ++i) {
381 rep_node[i] =
382 FixUpperBits(graph()->NewNode(op, rep_left[i], rep_right[i]), kShift16);
383 }
384 ReplaceNode(node, rep_node, num_lanes);
385 }
386
387 Node* SimdScalarLowering::Mask(Node* input, int32_t mask) {
388 return graph()->NewNode(machine()->Word32And(), input,
389 jsgraph_->Int32Constant(mask));
390 }
391
392 void SimdScalarLowering::LowerSaturateBinaryOp(Node* node,
393 SimdType input_rep_type,
394 const Operator* op,
395 bool is_signed) {
396 DCHECK(node->InputCount() == 2);
397 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
398 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
399 int32_t min = 0;
400 int32_t max = 0;
401 if (is_signed) {
402 min = std::numeric_limits<int16_t>::min();
403 max = std::numeric_limits<int16_t>::max();
404 } else {
405 min = std::numeric_limits<uint16_t>::min();
406 max = std::numeric_limits<uint16_t>::max();
407 }
408 int num_lanes = NumLanes(input_rep_type);
409 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
410 for (int i = 0; i < num_lanes; ++i) {
411 Node* op_result = nullptr;
412 Node* left = is_signed ? rep_left[i] : Mask(rep_left[i], kMask16);
413 Node* right = is_signed ? rep_right[i] : Mask(rep_right[i], kMask16);
414 op_result = graph()->NewNode(op, left, right);
415 Diamond d_min(graph(), common(),
416 graph()->NewNode(machine()->Int32LessThan(), op_result,
417 jsgraph_->Int32Constant(min)));
418 rep_node[i] = d_min.Phi(MachineRepresentation::kWord16,
419 jsgraph_->Int32Constant(min), op_result);
420 Diamond d_max(graph(), common(),
421 graph()->NewNode(machine()->Int32LessThan(),
422 jsgraph_->Int32Constant(max), rep_node[i]));
423 rep_node[i] = d_max.Phi(MachineRepresentation::kWord16,
424 jsgraph_->Int32Constant(max), rep_node[i]);
425 rep_node[i] = is_signed ? rep_node[i] : FixUpperBits(rep_node[i], kShift16);
426 }
427 ReplaceNode(node, rep_node, num_lanes);
298 } 428 }
299 429
300 void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type, 430 void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type,
301 const Operator* op) { 431 const Operator* op) {
302 DCHECK(node->InputCount() == 1); 432 DCHECK(node->InputCount() == 1);
303 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type); 433 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type);
304 Node* rep_node[kMaxLanes]; 434 int num_lanes = NumLanes(input_rep_type);
305 for (int i = 0; i < kMaxLanes; ++i) { 435 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
436 for (int i = 0; i < num_lanes; ++i) {
306 rep_node[i] = graph()->NewNode(op, rep[i]); 437 rep_node[i] = graph()->NewNode(op, rep[i]);
307 } 438 }
308 ReplaceNode(node, rep_node); 439 ReplaceNode(node, rep_node, num_lanes);
309 } 440 }
310 441
311 void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op, 442 void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op,
312 bool is_max) { 443 bool is_max, SimdType type) {
313 DCHECK(node->InputCount() == 2); 444 DCHECK(node->InputCount() == 2);
314 Node** rep_left = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); 445 Node** rep_left = GetReplacementsWithType(node->InputAt(0), type);
315 Node** rep_right = 446 Node** rep_right = GetReplacementsWithType(node->InputAt(1), type);
316 GetReplacementsWithType(node->InputAt(1), SimdType::kInt32); 447 int num_lanes = NumLanes(type);
317 Node* rep_node[kMaxLanes]; 448 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
318 for (int i = 0; i < kMaxLanes; ++i) { 449 MachineRepresentation rep = MachineRepresentation::kNone;
450 if (type == SimdType::kInt32) {
451 rep = MachineRepresentation::kWord32;
452 } else if (type == SimdType::kInt16) {
453 rep = MachineRepresentation::kWord16;
454 } else {
455 UNREACHABLE();
456 }
457 for (int i = 0; i < num_lanes; ++i) {
319 Diamond d(graph(), common(), 458 Diamond d(graph(), common(),
320 graph()->NewNode(op, rep_left[i], rep_right[i])); 459 graph()->NewNode(op, rep_left[i], rep_right[i]));
321 if (is_max) { 460 if (is_max) {
322 rep_node[i] = 461 rep_node[i] = d.Phi(rep, rep_right[i], rep_left[i]);
323 d.Phi(MachineRepresentation::kWord32, rep_right[i], rep_left[i]);
324 } else { 462 } else {
325 rep_node[i] = 463 rep_node[i] = d.Phi(rep, rep_left[i], rep_right[i]);
326 d.Phi(MachineRepresentation::kWord32, rep_left[i], rep_right[i]);
327 } 464 }
328 } 465 }
329 ReplaceNode(node, rep_node); 466 ReplaceNode(node, rep_node, num_lanes);
330 } 467 }
331 468
332 Node* SimdScalarLowering::BuildF64Trunc(Node* input) { 469 Node* SimdScalarLowering::BuildF64Trunc(Node* input) {
333 if (machine()->Float64RoundTruncate().IsSupported()) { 470 if (machine()->Float64RoundTruncate().IsSupported()) {
334 return graph()->NewNode(machine()->Float64RoundTruncate().op(), input); 471 return graph()->NewNode(machine()->Float64RoundTruncate().op(), input);
335 } else { 472 } else {
336 ExternalReference ref = 473 ExternalReference ref =
337 ExternalReference::wasm_f64_trunc(jsgraph_->isolate()); 474 ExternalReference::wasm_f64_trunc(jsgraph_->isolate());
338 Node* stack_slot = 475 Node* stack_slot =
339 graph()->NewNode(machine()->StackSlot(MachineRepresentation::kFloat64)); 476 graph()->NewNode(machine()->StackSlot(MachineRepresentation::kFloat64));
(...skipping 15 matching lines...) Expand all
355 Node* call = graph()->NewNode(common()->Call(desc), 4, args); 492 Node* call = graph()->NewNode(common()->Call(desc), 4, args);
356 return graph()->NewNode(machine()->Load(LoadRepresentation::Float64()), 493 return graph()->NewNode(machine()->Load(LoadRepresentation::Float64()),
357 stack_slot, jsgraph_->Int32Constant(0), call, 494 stack_slot, jsgraph_->Int32Constant(0), call,
358 graph()->start()); 495 graph()->start());
359 } 496 }
360 } 497 }
361 498
362 void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) { 499 void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) {
363 DCHECK(node->InputCount() == 1); 500 DCHECK(node->InputCount() == 1);
364 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32); 501 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32);
365 Node* rep_node[kMaxLanes]; 502 Node* rep_node[kNumLanes32];
366 Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0)); 503 Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0));
367 Node* min = graph()->NewNode( 504 Node* min = graph()->NewNode(
368 common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0))); 505 common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0)));
369 Node* max = graph()->NewNode(common()->Float64Constant( 506 Node* max = graph()->NewNode(common()->Float64Constant(
370 static_cast<double>(is_signed ? kMaxInt : 0xffffffffu))); 507 static_cast<double>(is_signed ? kMaxInt : 0xffffffffu)));
371 for (int i = 0; i < kMaxLanes; ++i) { 508 for (int i = 0; i < kNumLanes32; ++i) {
372 Node* double_rep = 509 Node* double_rep =
373 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]); 510 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]);
374 Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(), 511 Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(),
375 double_rep, double_rep)); 512 double_rep, double_rep));
376 Node* temp = 513 Node* temp =
377 nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero); 514 nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero);
378 Diamond min_d(graph(), common(), 515 Diamond min_d(graph(), common(),
379 graph()->NewNode(machine()->Float64LessThan(), temp, min)); 516 graph()->NewNode(machine()->Float64LessThan(), temp, min));
380 temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp); 517 temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp);
381 Diamond max_d(graph(), common(), 518 Diamond max_d(graph(), common(),
382 graph()->NewNode(machine()->Float64LessThan(), max, temp)); 519 graph()->NewNode(machine()->Float64LessThan(), max, temp));
383 temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp); 520 temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp);
384 Node* trunc = BuildF64Trunc(temp); 521 Node* trunc = BuildF64Trunc(temp);
385 if (is_signed) { 522 if (is_signed) {
386 rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc); 523 rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc);
387 } else { 524 } else {
388 rep_node[i] = 525 rep_node[i] =
389 graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc); 526 graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc);
390 } 527 }
391 } 528 }
392 ReplaceNode(node, rep_node); 529 ReplaceNode(node, rep_node, kNumLanes32);
393 } 530 }
394 531
395 void SimdScalarLowering::LowerShiftOp(Node* node, const Operator* op) { 532 void SimdScalarLowering::LowerShiftOp(Node* node, SimdType type) {
396 static int32_t shift_mask = 0x1f;
397 DCHECK_EQ(1, node->InputCount()); 533 DCHECK_EQ(1, node->InputCount());
398 int32_t shift_amount = OpParameter<int32_t>(node); 534 int32_t shift_amount = OpParameter<int32_t>(node);
399 Node* shift_node = 535 Node* shift_node = graph()->NewNode(common()->Int32Constant(shift_amount));
400 graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask)); 536 Node** rep = GetReplacementsWithType(node->InputAt(0), type);
401 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); 537 int num_lanes = NumLanes(type);
402 Node* rep_node[kMaxLanes]; 538 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
403 for (int i = 0; i < kMaxLanes; ++i) { 539 for (int i = 0; i < num_lanes; ++i) {
404 rep_node[i] = graph()->NewNode(op, rep[i], shift_node); 540 rep_node[i] = rep[i];
541 switch (node->opcode()) {
542 case IrOpcode::kI16x8ShrU:
543 rep_node[i] = Mask(rep_node[i], kMask16);
544 case IrOpcode::kI32x4ShrU:
545 rep_node[i] =
546 graph()->NewNode(machine()->Word32Shr(), rep_node[i], shift_node);
547 break;
548 case IrOpcode::kI32x4Shl:
549 case IrOpcode::kI16x8Shl:
550 rep_node[i] =
551 graph()->NewNode(machine()->Word32Shl(), rep_node[i], shift_node);
552 break;
553 case IrOpcode::kI32x4ShrS:
554 case IrOpcode::kI16x8ShrS:
555 rep_node[i] =
556 graph()->NewNode(machine()->Word32Sar(), rep_node[i], shift_node);
557 break;
558 default:
559 UNREACHABLE();
560 }
561 if (node->opcode() == IrOpcode::kI16x8Shl) {
562 rep_node[i] = FixUpperBits(rep_node[i], kShift16);
563 }
405 } 564 }
406 ReplaceNode(node, rep_node); 565 ReplaceNode(node, rep_node, num_lanes);
407 } 566 }
408 567
409 void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type, 568 void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
410 const Operator* op) { 569 const Operator* op) {
411 DCHECK(node->InputCount() == 2); 570 DCHECK(node->InputCount() == 2);
412 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); 571 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
413 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); 572 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
414 Node* rep_node[kMaxLanes]; 573 int num_lanes = NumLanes(input_rep_type);
415 for (int i = 0; i < kMaxLanes; ++i) { 574 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
575 for (int i = 0; i < num_lanes; ++i) {
416 Diamond d(graph(), common(), 576 Diamond d(graph(), common(),
417 graph()->NewNode(op, rep_left[i], rep_right[i])); 577 graph()->NewNode(op, rep_left[i], rep_right[i]));
418 rep_node[i] = d.Phi(MachineRepresentation::kWord32, 578 rep_node[i] = d.Phi(MachineRepresentation::kWord32,
419 jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1)); 579 jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1));
420 } 580 }
421 ReplaceNode(node, rep_node); 581 ReplaceNode(node, rep_node, num_lanes);
422 } 582 }
423 583
424 void SimdScalarLowering::LowerNode(Node* node) { 584 void SimdScalarLowering::LowerNode(Node* node) {
425 SimdType rep_type = ReplacementType(node); 585 SimdType rep_type = ReplacementType(node);
586 int num_lanes = NumLanes(rep_type);
426 switch (node->opcode()) { 587 switch (node->opcode()) {
427 case IrOpcode::kStart: { 588 case IrOpcode::kStart: {
428 int parameter_count = GetParameterCountAfterLowering(); 589 int parameter_count = GetParameterCountAfterLowering();
429 // Only exchange the node if the parameter count actually changed. 590 // Only exchange the node if the parameter count actually changed.
430 if (parameter_count != static_cast<int>(signature()->parameter_count())) { 591 if (parameter_count != static_cast<int>(signature()->parameter_count())) {
431 int delta = 592 int delta =
432 parameter_count - static_cast<int>(signature()->parameter_count()); 593 parameter_count - static_cast<int>(signature()->parameter_count());
433 int new_output_count = node->op()->ValueOutputCount() + delta; 594 int new_output_count = node->op()->ValueOutputCount() + delta;
434 NodeProperties::ChangeOp(node, common()->Start(new_output_count)); 595 NodeProperties::ChangeOp(node, common()->Start(new_output_count));
435 } 596 }
436 break; 597 break;
437 } 598 }
438 case IrOpcode::kParameter: { 599 case IrOpcode::kParameter: {
439 DCHECK(node->InputCount() == 1); 600 DCHECK(node->InputCount() == 1);
440 // Only exchange the node if the parameter count actually changed. We do 601 // Only exchange the node if the parameter count actually changed. We do
441 // not even have to do the default lowering because the the start node, 602 // not even have to do the default lowering because the the start node,
442 // the only input of a parameter node, only changes if the parameter count 603 // the only input of a parameter node, only changes if the parameter count
443 // changes. 604 // changes.
444 if (GetParameterCountAfterLowering() != 605 if (GetParameterCountAfterLowering() !=
445 static_cast<int>(signature()->parameter_count())) { 606 static_cast<int>(signature()->parameter_count())) {
446 int old_index = ParameterIndexOf(node->op()); 607 int old_index = ParameterIndexOf(node->op());
447 int new_index = GetParameterIndexAfterLowering(signature(), old_index); 608 int new_index = GetParameterIndexAfterLowering(signature(), old_index);
448 if (old_index == new_index) { 609 if (old_index == new_index) {
449 NodeProperties::ChangeOp(node, common()->Parameter(new_index)); 610 NodeProperties::ChangeOp(node, common()->Parameter(new_index));
450 611
451 Node* new_node[kMaxLanes]; 612 Node* new_node[kNumLanes32];
452 for (int i = 0; i < kMaxLanes; ++i) { 613 for (int i = 0; i < kNumLanes32; ++i) {
453 new_node[i] = nullptr; 614 new_node[i] = nullptr;
454 } 615 }
455 new_node[0] = node; 616 new_node[0] = node;
456 if (signature()->GetParam(old_index) == 617 if (signature()->GetParam(old_index) ==
457 MachineRepresentation::kSimd128) { 618 MachineRepresentation::kSimd128) {
458 for (int i = 1; i < kMaxLanes; ++i) { 619 for (int i = 1; i < kNumLanes32; ++i) {
459 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i), 620 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i),
460 graph()->start()); 621 graph()->start());
461 } 622 }
462 } 623 }
463 ReplaceNode(node, new_node); 624 ReplaceNode(node, new_node, kNumLanes32);
464 } 625 }
465 } 626 }
466 break; 627 break;
467 } 628 }
468 case IrOpcode::kLoad: { 629 case IrOpcode::kLoad: {
469 MachineRepresentation rep = 630 MachineRepresentation rep =
470 LoadRepresentationOf(node->op()).representation(); 631 LoadRepresentationOf(node->op()).representation();
471 const Operator* load_op; 632 const Operator* load_op;
472 if (rep_type == SimdType::kInt32) { 633 if (rep_type == SimdType::kInt32) {
473 load_op = machine()->Load(MachineType::Int32()); 634 load_op = machine()->Load(MachineType::Int32());
474 } else if (rep_type == SimdType::kFloat32) { 635 } else if (rep_type == SimdType::kFloat32) {
475 load_op = machine()->Load(MachineType::Float32()); 636 load_op = machine()->Load(MachineType::Float32());
637 } else if (rep_type == SimdType::kInt16) {
638 load_op = machine()->Load(MachineType::Int16());
gdeepti 2017/04/25 20:29:57 Might be useful here to have a macro with SimdType
aseemgarg 2017/04/26 23:02:01 Done.
639 } else {
640 UNREACHABLE();
476 } 641 }
477 LowerLoadOp(rep, node, load_op); 642 LowerLoadOp(rep, node, load_op, rep_type);
478 break; 643 break;
479 } 644 }
480 case IrOpcode::kUnalignedLoad: { 645 case IrOpcode::kUnalignedLoad: {
481 MachineRepresentation rep = 646 MachineRepresentation rep =
482 UnalignedLoadRepresentationOf(node->op()).representation(); 647 UnalignedLoadRepresentationOf(node->op()).representation();
483 const Operator* load_op; 648 const Operator* load_op;
484 if (rep_type == SimdType::kInt32) { 649 if (rep_type == SimdType::kInt32) {
485 load_op = machine()->UnalignedLoad(MachineType::Int32()); 650 load_op = machine()->UnalignedLoad(MachineType::Int32());
486 } else if (rep_type == SimdType::kFloat32) { 651 } else if (rep_type == SimdType::kFloat32) {
487 load_op = machine()->UnalignedLoad(MachineType::Float32()); 652 load_op = machine()->UnalignedLoad(MachineType::Float32());
653 } else if (rep_type == SimdType::kInt16) {
654 load_op = machine()->UnalignedLoad(MachineType::Int16());
655 } else {
656 UNREACHABLE();
488 } 657 }
489 LowerLoadOp(rep, node, load_op); 658 LowerLoadOp(rep, node, load_op, rep_type);
490 break; 659 break;
491 } 660 }
492 case IrOpcode::kStore: { 661 case IrOpcode::kStore: {
493 MachineRepresentation rep = 662 MachineRepresentation rep =
494 StoreRepresentationOf(node->op()).representation(); 663 StoreRepresentationOf(node->op()).representation();
495 WriteBarrierKind write_barrier_kind = 664 WriteBarrierKind write_barrier_kind =
496 StoreRepresentationOf(node->op()).write_barrier_kind(); 665 StoreRepresentationOf(node->op()).write_barrier_kind();
497 const Operator* store_op; 666 const Operator* store_op;
498 if (rep_type == SimdType::kInt32) { 667 if (rep_type == SimdType::kInt32) {
499 store_op = machine()->Store(StoreRepresentation( 668 store_op = machine()->Store(StoreRepresentation(
500 MachineRepresentation::kWord32, write_barrier_kind)); 669 MachineRepresentation::kWord32, write_barrier_kind));
501 } else { 670 } else if (rep_type == SimdType::kFloat32) {
502 store_op = machine()->Store(StoreRepresentation( 671 store_op = machine()->Store(StoreRepresentation(
503 MachineRepresentation::kFloat32, write_barrier_kind)); 672 MachineRepresentation::kFloat32, write_barrier_kind));
673 } else if (rep_type == SimdType::kInt16) {
674 store_op = machine()->Store(StoreRepresentation(
675 MachineRepresentation::kWord16, write_barrier_kind));
676 } else {
677 UNREACHABLE();
504 } 678 }
505 LowerStoreOp(rep, node, store_op, rep_type); 679 LowerStoreOp(rep, node, store_op, rep_type);
506 break; 680 break;
507 } 681 }
508 case IrOpcode::kUnalignedStore: { 682 case IrOpcode::kUnalignedStore: {
509 MachineRepresentation rep = UnalignedStoreRepresentationOf(node->op()); 683 MachineRepresentation rep = UnalignedStoreRepresentationOf(node->op());
510 const Operator* store_op; 684 const Operator* store_op;
511 if (rep_type == SimdType::kInt32) { 685 if (rep_type == SimdType::kInt32) {
512 store_op = machine()->UnalignedStore(MachineRepresentation::kWord32); 686 store_op = machine()->UnalignedStore(MachineRepresentation::kWord32);
687 } else if (rep_type == SimdType::kFloat32) {
688 store_op = machine()->UnalignedStore(MachineRepresentation::kFloat32);
689 } else if (rep_type == SimdType::kInt16) {
690 store_op = machine()->UnalignedStore(MachineRepresentation::kWord16);
513 } else { 691 } else {
514 store_op = machine()->UnalignedStore(MachineRepresentation::kFloat32); 692 UNREACHABLE();
515 } 693 }
516 LowerStoreOp(rep, node, store_op, rep_type); 694 LowerStoreOp(rep, node, store_op, rep_type);
517 break; 695 break;
518 } 696 }
519 case IrOpcode::kReturn: { 697 case IrOpcode::kReturn: {
520 DefaultLowering(node); 698 DefaultLowering(node);
521 int new_return_count = GetReturnCountAfterLowering(signature()); 699 int new_return_count = GetReturnCountAfterLowering(signature());
522 if (static_cast<int>(signature()->return_count()) != new_return_count) { 700 if (static_cast<int>(signature()->return_count()) != new_return_count) {
523 NodeProperties::ChangeOp(node, common()->Return(new_return_count)); 701 NodeProperties::ChangeOp(node, common()->Return(new_return_count));
524 } 702 }
525 break; 703 break;
526 } 704 }
527 case IrOpcode::kCall: { 705 case IrOpcode::kCall: {
528 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor. 706 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor.
529 CallDescriptor* descriptor = 707 CallDescriptor* descriptor =
530 const_cast<CallDescriptor*>(CallDescriptorOf(node->op())); 708 const_cast<CallDescriptor*>(CallDescriptorOf(node->op()));
531 if (DefaultLowering(node) || 709 if (DefaultLowering(node) ||
532 (descriptor->ReturnCount() == 1 && 710 (descriptor->ReturnCount() == 1 &&
533 descriptor->GetReturnType(0) == MachineType::Simd128())) { 711 descriptor->GetReturnType(0) == MachineType::Simd128())) {
534 // We have to adjust the call descriptor. 712 // We have to adjust the call descriptor.
535 const Operator* op = 713 const Operator* op =
536 common()->Call(wasm::ModuleEnv::GetI32WasmCallDescriptorForSimd( 714 common()->Call(wasm::ModuleEnv::GetI32WasmCallDescriptorForSimd(
537 zone(), descriptor)); 715 zone(), descriptor));
538 NodeProperties::ChangeOp(node, op); 716 NodeProperties::ChangeOp(node, op);
539 } 717 }
540 if (descriptor->ReturnCount() == 1 && 718 if (descriptor->ReturnCount() == 1 &&
541 descriptor->GetReturnType(0) == MachineType::Simd128()) { 719 descriptor->GetReturnType(0) == MachineType::Simd128()) {
542 // We access the additional return values through projections. 720 // We access the additional return values through projections.
543 Node* rep_node[kMaxLanes]; 721 Node* rep_node[kNumLanes32];
544 for (int i = 0; i < kMaxLanes; ++i) { 722 for (int i = 0; i < kNumLanes32; ++i) {
545 rep_node[i] = 723 rep_node[i] =
546 graph()->NewNode(common()->Projection(i), node, graph()->start()); 724 graph()->NewNode(common()->Projection(i), node, graph()->start());
547 } 725 }
548 ReplaceNode(node, rep_node); 726 ReplaceNode(node, rep_node, kNumLanes32);
549 } 727 }
550 break; 728 break;
551 } 729 }
552 case IrOpcode::kPhi: { 730 case IrOpcode::kPhi: {
553 MachineRepresentation rep = PhiRepresentationOf(node->op()); 731 MachineRepresentation rep = PhiRepresentationOf(node->op());
554 if (rep == MachineRepresentation::kSimd128) { 732 if (rep == MachineRepresentation::kSimd128) {
555 // The replacement nodes have already been created, we only have to 733 // The replacement nodes have already been created, we only have to
556 // replace placeholder nodes. 734 // replace placeholder nodes.
557 Node** rep_node = GetReplacements(node); 735 Node** rep_node = GetReplacements(node);
558 for (int i = 0; i < node->op()->ValueInputCount(); ++i) { 736 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
559 Node** rep_input = 737 Node** rep_input =
560 GetReplacementsWithType(node->InputAt(i), rep_type); 738 GetReplacementsWithType(node->InputAt(i), rep_type);
561 for (int j = 0; j < kMaxLanes; j++) { 739 for (int j = 0; j < num_lanes; j++) {
562 rep_node[j]->ReplaceInput(i, rep_input[j]); 740 rep_node[j]->ReplaceInput(i, rep_input[j]);
563 } 741 }
564 } 742 }
565 } else { 743 } else {
566 DefaultLowering(node); 744 DefaultLowering(node);
567 } 745 }
568 break; 746 break;
569 } 747 }
570 #define I32X4_BINOP_CASE(opcode, instruction) \ 748 #define I32X4_BINOP_CASE(opcode, instruction) \
571 case IrOpcode::opcode: { \ 749 case IrOpcode::opcode: { \
572 LowerBinaryOp(node, rep_type, machine()->instruction()); \ 750 LowerBinaryOp(node, rep_type, machine()->instruction()); \
573 break; \ 751 break; \
574 } 752 }
575 I32X4_BINOP_CASE(kI32x4Add, Int32Add) 753 I32X4_BINOP_CASE(kI32x4Add, Int32Add)
576 I32X4_BINOP_CASE(kI32x4Sub, Int32Sub) 754 I32X4_BINOP_CASE(kI32x4Sub, Int32Sub)
577 I32X4_BINOP_CASE(kI32x4Mul, Int32Mul) 755 I32X4_BINOP_CASE(kI32x4Mul, Int32Mul)
578 I32X4_BINOP_CASE(kS128And, Word32And) 756 I32X4_BINOP_CASE(kS128And, Word32And)
579 I32X4_BINOP_CASE(kS128Or, Word32Or) 757 I32X4_BINOP_CASE(kS128Or, Word32Or)
580 I32X4_BINOP_CASE(kS128Xor, Word32Xor) 758 I32X4_BINOP_CASE(kS128Xor, Word32Xor)
581 #undef I32X4_BINOP_CASE 759 #undef I32X4_BINOP_CASE
582 case IrOpcode::kI32x4MaxS: { 760 case IrOpcode::kI16x8Add: {
583 LowerIntMinMax(node, machine()->Int32LessThan(), true); 761 LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Add());
584 break; 762 break;
585 } 763 }
586 case IrOpcode::kI32x4MinS: { 764 case IrOpcode::kI16x8Sub: {
587 LowerIntMinMax(node, machine()->Int32LessThan(), false); 765 LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Sub());
588 break; 766 break;
589 } 767 }
590 case IrOpcode::kI32x4MaxU: { 768 case IrOpcode::kI16x8Mul: {
591 LowerIntMinMax(node, machine()->Uint32LessThan(), true); 769 LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Mul());
592 break; 770 break;
593 } 771 }
594 case IrOpcode::kI32x4MinU: { 772 case IrOpcode::kI16x8AddSaturateS: {
595 LowerIntMinMax(node, machine()->Uint32LessThan(), false); 773 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), true);
774 break;
775 }
776 case IrOpcode::kI16x8SubSaturateS: {
777 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), true);
778 break;
779 }
780 case IrOpcode::kI16x8AddSaturateU: {
781 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), false);
782 break;
783 }
784 case IrOpcode::kI16x8SubSaturateU: {
785 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), false);
786 break;
787 }
788 case IrOpcode::kI32x4MaxS:
789 case IrOpcode::kI16x8MaxS: {
790 LowerIntMinMax(node, machine()->Int32LessThan(), true, rep_type);
791 break;
792 }
793 case IrOpcode::kI32x4MinS:
794 case IrOpcode::kI16x8MinS: {
795 LowerIntMinMax(node, machine()->Int32LessThan(), false, rep_type);
796 break;
797 }
798 case IrOpcode::kI32x4MaxU:
799 case IrOpcode::kI16x8MaxU: {
800 LowerIntMinMax(node, machine()->Uint32LessThan(), true, rep_type);
801 break;
802 }
803 case IrOpcode::kI32x4MinU:
804 case IrOpcode::kI16x8MinU: {
805 LowerIntMinMax(node, machine()->Uint32LessThan(), false, rep_type);
596 break; 806 break;
597 } 807 }
598 case IrOpcode::kI32x4Neg: { 808 case IrOpcode::kI32x4Neg: {
599 DCHECK(node->InputCount() == 1); 809 DCHECK(node->InputCount() == 1);
600 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); 810 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
601 Node* rep_node[kMaxLanes]; 811 Node* rep_node[kNumLanes32];
602 Node* zero = graph()->NewNode(common()->Int32Constant(0)); 812 Node* zero = graph()->NewNode(common()->Int32Constant(0));
603 for (int i = 0; i < kMaxLanes; ++i) { 813 for (int i = 0; i < kNumLanes32; ++i) {
604 rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]); 814 rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]);
605 } 815 }
606 ReplaceNode(node, rep_node); 816 ReplaceNode(node, rep_node, kNumLanes32);
607 break; 817 break;
608 } 818 }
609 case IrOpcode::kS128Not: { 819 case IrOpcode::kS128Not: {
610 DCHECK(node->InputCount() == 1); 820 DCHECK(node->InputCount() == 1);
611 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); 821 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
612 Node* rep_node[kMaxLanes]; 822 Node* rep_node[kNumLanes32];
613 Node* mask = graph()->NewNode(common()->Int32Constant(0xffffffff)); 823 Node* mask = graph()->NewNode(common()->Int32Constant(0xffffffff));
614 for (int i = 0; i < kMaxLanes; ++i) { 824 for (int i = 0; i < kNumLanes32; ++i) {
615 rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask); 825 rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask);
616 } 826 }
617 ReplaceNode(node, rep_node); 827 ReplaceNode(node, rep_node, kNumLanes32);
618 break; 828 break;
619 } 829 }
620 case IrOpcode::kI32x4SConvertF32x4: { 830 case IrOpcode::kI32x4SConvertF32x4: {
621 LowerConvertFromFloat(node, true); 831 LowerConvertFromFloat(node, true);
622 break; 832 break;
623 } 833 }
624 case IrOpcode::kI32x4UConvertF32x4: { 834 case IrOpcode::kI32x4UConvertF32x4: {
625 LowerConvertFromFloat(node, false); 835 LowerConvertFromFloat(node, false);
626 break; 836 break;
627 } 837 }
628 case IrOpcode::kI32x4Shl: { 838 case IrOpcode::kI32x4Shl:
629 LowerShiftOp(node, machine()->Word32Shl()); 839 case IrOpcode::kI16x8Shl:
630 break; 840 case IrOpcode::kI32x4ShrS:
631 } 841 case IrOpcode::kI16x8ShrS:
632 case IrOpcode::kI32x4ShrS: { 842 case IrOpcode::kI32x4ShrU:
633 LowerShiftOp(node, machine()->Word32Sar()); 843 case IrOpcode::kI16x8ShrU: {
634 break; 844 LowerShiftOp(node, rep_type);
635 }
636 case IrOpcode::kI32x4ShrU: {
637 LowerShiftOp(node, machine()->Word32Shr());
638 break; 845 break;
639 } 846 }
640 #define F32X4_BINOP_CASE(name) \ 847 #define F32X4_BINOP_CASE(name) \
641 case IrOpcode::kF32x4##name: { \ 848 case IrOpcode::kF32x4##name: { \
642 LowerBinaryOp(node, rep_type, machine()->Float32##name()); \ 849 LowerBinaryOp(node, rep_type, machine()->Float32##name()); \
643 break; \ 850 break; \
644 } 851 }
645 F32X4_BINOP_CASE(Add) 852 F32X4_BINOP_CASE(Add)
646 F32X4_BINOP_CASE(Sub) 853 F32X4_BINOP_CASE(Sub)
647 F32X4_BINOP_CASE(Mul) 854 F32X4_BINOP_CASE(Mul)
(...skipping 10 matching lines...) Expand all
658 #undef F32x4_UNOP_CASE 865 #undef F32x4_UNOP_CASE
659 case IrOpcode::kF32x4SConvertI32x4: { 866 case IrOpcode::kF32x4SConvertI32x4: {
660 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundInt32ToFloat32()); 867 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundInt32ToFloat32());
661 break; 868 break;
662 } 869 }
663 case IrOpcode::kF32x4UConvertI32x4: { 870 case IrOpcode::kF32x4UConvertI32x4: {
664 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundUint32ToFloat32()); 871 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundUint32ToFloat32());
665 break; 872 break;
666 } 873 }
667 case IrOpcode::kI32x4Splat: 874 case IrOpcode::kI32x4Splat:
668 case IrOpcode::kF32x4Splat: { 875 case IrOpcode::kF32x4Splat:
669 Node* rep_node[kMaxLanes]; 876 case IrOpcode::kI16x8Splat: {
670 for (int i = 0; i < kMaxLanes; ++i) { 877 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
878 for (int i = 0; i < num_lanes; ++i) {
671 if (HasReplacement(0, node->InputAt(0))) { 879 if (HasReplacement(0, node->InputAt(0))) {
672 rep_node[i] = GetReplacements(node->InputAt(0))[0]; 880 rep_node[i] = GetReplacements(node->InputAt(0))[0];
673 } else { 881 } else {
674 rep_node[i] = node->InputAt(0); 882 rep_node[i] = node->InputAt(0);
675 } 883 }
676 } 884 }
677 ReplaceNode(node, rep_node); 885 ReplaceNode(node, rep_node, num_lanes);
678 break; 886 break;
679 } 887 }
680 case IrOpcode::kI32x4ExtractLane: 888 case IrOpcode::kI32x4ExtractLane:
681 case IrOpcode::kF32x4ExtractLane: { 889 case IrOpcode::kF32x4ExtractLane:
890 case IrOpcode::kI16x8ExtractLane: {
682 int32_t lane = OpParameter<int32_t>(node); 891 int32_t lane = OpParameter<int32_t>(node);
683 Node* rep_node[kMaxLanes] = { 892 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
684 GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr, 893 rep_node[0] = GetReplacementsWithType(node->InputAt(0), rep_type)[lane];
685 nullptr, nullptr}; 894 for (int i = 1; i < num_lanes; ++i) {
686 ReplaceNode(node, rep_node); 895 rep_node[i] = nullptr;
896 }
897 ReplaceNode(node, rep_node, num_lanes);
687 break; 898 break;
688 } 899 }
689 case IrOpcode::kI32x4ReplaceLane: 900 case IrOpcode::kI32x4ReplaceLane:
690 case IrOpcode::kF32x4ReplaceLane: { 901 case IrOpcode::kF32x4ReplaceLane:
902 case IrOpcode::kI16x8ReplaceLane: {
691 DCHECK_EQ(2, node->InputCount()); 903 DCHECK_EQ(2, node->InputCount());
692 Node* repNode = node->InputAt(1); 904 Node* repNode = node->InputAt(1);
693 int32_t lane = OpParameter<int32_t>(node); 905 int32_t lane = OpParameter<int32_t>(node);
694 DCHECK(lane >= 0 && lane <= 3);
695 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type); 906 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type);
696 if (HasReplacement(0, repNode)) { 907 if (HasReplacement(0, repNode)) {
697 rep_node[lane] = GetReplacements(repNode)[0]; 908 rep_node[lane] = GetReplacements(repNode)[0];
698 } else { 909 } else {
699 rep_node[lane] = repNode; 910 rep_node[lane] = repNode;
700 } 911 }
701 ReplaceNode(node, rep_node); 912 ReplaceNode(node, rep_node, num_lanes);
702 break; 913 break;
703 } 914 }
704 #define COMPARISON_CASE(type, simd_op, lowering_op, invert) \ 915 #define COMPARISON_CASE(type, simd_op, lowering_op, invert) \
705 case IrOpcode::simd_op: { \ 916 case IrOpcode::simd_op: { \
706 LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \ 917 LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \
707 break; \ 918 break; \
708 } 919 }
709 COMPARISON_CASE(Float32, kF32x4Eq, Float32Equal, false) 920 COMPARISON_CASE(Float32, kF32x4Eq, Float32Equal, false)
710 COMPARISON_CASE(Float32, kF32x4Lt, Float32LessThan, false) 921 COMPARISON_CASE(Float32, kF32x4Lt, Float32LessThan, false)
711 COMPARISON_CASE(Float32, kF32x4Le, Float32LessThanOrEqual, false) 922 COMPARISON_CASE(Float32, kF32x4Le, Float32LessThanOrEqual, false)
712 COMPARISON_CASE(Float32, kF32x4Gt, Float32LessThan, true) 923 COMPARISON_CASE(Float32, kF32x4Gt, Float32LessThan, true)
713 COMPARISON_CASE(Float32, kF32x4Ge, Float32LessThanOrEqual, true) 924 COMPARISON_CASE(Float32, kF32x4Ge, Float32LessThanOrEqual, true)
714 COMPARISON_CASE(Int32, kI32x4Eq, Word32Equal, false) 925 COMPARISON_CASE(Int32, kI32x4Eq, Word32Equal, false)
715 COMPARISON_CASE(Int32, kI32x4LtS, Int32LessThan, false) 926 COMPARISON_CASE(Int32, kI32x4LtS, Int32LessThan, false)
716 COMPARISON_CASE(Int32, kI32x4LeS, Int32LessThanOrEqual, false) 927 COMPARISON_CASE(Int32, kI32x4LeS, Int32LessThanOrEqual, false)
717 COMPARISON_CASE(Int32, kI32x4GtS, Int32LessThan, true) 928 COMPARISON_CASE(Int32, kI32x4GtS, Int32LessThan, true)
718 COMPARISON_CASE(Int32, kI32x4GeS, Int32LessThanOrEqual, true) 929 COMPARISON_CASE(Int32, kI32x4GeS, Int32LessThanOrEqual, true)
719 COMPARISON_CASE(Int32, kI32x4LtU, Uint32LessThan, false) 930 COMPARISON_CASE(Int32, kI32x4LtU, Uint32LessThan, false)
720 COMPARISON_CASE(Int32, kI32x4LeU, Uint32LessThanOrEqual, false) 931 COMPARISON_CASE(Int32, kI32x4LeU, Uint32LessThanOrEqual, false)
721 COMPARISON_CASE(Int32, kI32x4GtU, Uint32LessThan, true) 932 COMPARISON_CASE(Int32, kI32x4GtU, Uint32LessThan, true)
722 COMPARISON_CASE(Int32, kI32x4GeU, Uint32LessThanOrEqual, true) 933 COMPARISON_CASE(Int32, kI32x4GeU, Uint32LessThanOrEqual, true)
934 COMPARISON_CASE(Int16, kI16x8Eq, Word32Equal, false)
935 COMPARISON_CASE(Int16, kI16x8LtS, Int32LessThan, false)
936 COMPARISON_CASE(Int16, kI16x8LeS, Int32LessThanOrEqual, false)
937 COMPARISON_CASE(Int16, kI16x8GtS, Int32LessThan, true)
938 COMPARISON_CASE(Int16, kI16x8GeS, Int32LessThanOrEqual, true)
939 COMPARISON_CASE(Int16, kI16x8LtU, Uint32LessThan, false)
940 COMPARISON_CASE(Int16, kI16x8LeU, Uint32LessThanOrEqual, false)
941 COMPARISON_CASE(Int16, kI16x8GtU, Uint32LessThan, true)
942 COMPARISON_CASE(Int16, kI16x8GeU, Uint32LessThanOrEqual, true)
723 #undef COMPARISON_CASE 943 #undef COMPARISON_CASE
724 case IrOpcode::kF32x4Ne: { 944 case IrOpcode::kF32x4Ne: {
725 LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal()); 945 LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal());
726 break; 946 break;
727 } 947 }
728 case IrOpcode::kI32x4Ne: { 948 case IrOpcode::kI32x4Ne: {
729 LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal()); 949 LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal());
730 break; 950 break;
731 } 951 }
732 case IrOpcode::kS32x4Select: { 952 case IrOpcode::kI16x8Ne: {
953 LowerNotEqual(node, SimdType::kInt16, machine()->Word32Equal());
954 break;
955 }
956 case IrOpcode::kS32x4Select:
957 case IrOpcode::kS16x8Select: {
733 DCHECK(node->InputCount() == 3); 958 DCHECK(node->InputCount() == 3);
734 DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4); 959 DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4 ||
960 ReplacementType(node->InputAt(0)) == SimdType::kSimd1x8);
735 Node** boolean_input = GetReplacements(node->InputAt(0)); 961 Node** boolean_input = GetReplacements(node->InputAt(0));
736 Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type); 962 Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type);
737 Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type); 963 Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type);
738 Node* rep_node[kMaxLanes]; 964 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
739 for (int i = 0; i < kMaxLanes; ++i) { 965 for (int i = 0; i < num_lanes; ++i) {
740 Diamond d(graph(), common(), 966 Diamond d(graph(), common(),
741 graph()->NewNode(machine()->Word32Equal(), boolean_input[i], 967 graph()->NewNode(machine()->Word32Equal(), boolean_input[i],
742 jsgraph_->Int32Constant(0))); 968 jsgraph_->Int32Constant(0)));
743 if (rep_type == SimdType::kFloat32) { 969 if (rep_type == SimdType::kFloat32) {
744 rep_node[i] = 970 rep_node[i] =
745 d.Phi(MachineRepresentation::kFloat32, rep_right[1], rep_left[0]); 971 d.Phi(MachineRepresentation::kFloat32, rep_right[1], rep_left[0]);
746 } else if (rep_type == SimdType::kInt32) { 972 } else if (rep_type == SimdType::kInt32) {
747 rep_node[i] = 973 rep_node[i] =
748 d.Phi(MachineRepresentation::kWord32, rep_right[1], rep_left[0]); 974 d.Phi(MachineRepresentation::kWord32, rep_right[1], rep_left[0]);
975 } else if (rep_type == SimdType::kInt16) {
976 rep_node[i] =
977 d.Phi(MachineRepresentation::kWord16, rep_right[1], rep_left[0]);
749 } else { 978 } else {
750 UNREACHABLE(); 979 UNREACHABLE();
751 } 980 }
752 } 981 }
753 ReplaceNode(node, rep_node); 982 ReplaceNode(node, rep_node, num_lanes);
754 break; 983 break;
755 } 984 }
756 default: { DefaultLowering(node); } 985 default: { DefaultLowering(node); }
757 } 986 }
758 } 987 }
759 988
760 bool SimdScalarLowering::DefaultLowering(Node* node) { 989 bool SimdScalarLowering::DefaultLowering(Node* node) {
761 bool something_changed = false; 990 bool something_changed = false;
762 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) { 991 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
763 Node* input = node->InputAt(i); 992 Node* input = node->InputAt(i);
764 if (HasReplacement(0, input)) { 993 if (HasReplacement(0, input)) {
765 something_changed = true; 994 something_changed = true;
766 node->ReplaceInput(i, GetReplacements(input)[0]); 995 node->ReplaceInput(i, GetReplacements(input)[0]);
767 } 996 }
768 if (HasReplacement(1, input)) { 997 if (HasReplacement(1, input)) {
769 something_changed = true; 998 something_changed = true;
770 for (int j = 1; j < kMaxLanes; j++) { 999 for (int j = 1; j < ReplacementCount(input); ++j) {
771 node->InsertInput(zone(), i + j, GetReplacements(input)[j]); 1000 node->InsertInput(zone(), i + j, GetReplacements(input)[j]);
772 } 1001 }
773 } 1002 }
774 } 1003 }
775 return something_changed; 1004 return something_changed;
776 } 1005 }
777 1006
778 void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node) { 1007 void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node, int count) {
779 // if new_low == nullptr, then also new_high == nullptr. 1008 replacements_[old->id()].node = zone()->NewArray<Node*>(count);
780 DCHECK(new_node[0] != nullptr || 1009 for (int i = 0; i < count; ++i) {
781 (new_node[1] == nullptr && new_node[2] == nullptr &&
782 new_node[3] == nullptr));
783 for (int i = 0; i < kMaxLanes; ++i) {
784 replacements_[old->id()].node[i] = new_node[i]; 1010 replacements_[old->id()].node[i] = new_node[i];
785 } 1011 }
1012 replacements_[old->id()].num_replacements = count;
786 } 1013 }
787 1014
788 bool SimdScalarLowering::HasReplacement(size_t index, Node* node) { 1015 bool SimdScalarLowering::HasReplacement(size_t index, Node* node) {
789 return replacements_[node->id()].node[index] != nullptr; 1016 return replacements_[node->id()].node != nullptr &&
1017 replacements_[node->id()].node[index] != nullptr;
790 } 1018 }
791 1019
792 SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) { 1020 SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) {
793 return replacements_[node->id()].type; 1021 return replacements_[node->id()].type;
794 } 1022 }
795 1023
796 Node** SimdScalarLowering::GetReplacements(Node* node) { 1024 Node** SimdScalarLowering::GetReplacements(Node* node) {
797 Node** result = replacements_[node->id()].node; 1025 Node** result = replacements_[node->id()].node;
798 DCHECK(result); 1026 DCHECK(result);
799 return result; 1027 return result;
800 } 1028 }
801 1029
1030 int SimdScalarLowering::ReplacementCount(Node* node) {
1031 return replacements_[node->id()].num_replacements;
1032 }
1033
1034 void SimdScalarLowering::Int32ToFloat32(Node** replacements, Node** result) {
1035 for (int i = 0; i < kNumLanes32; ++i) {
1036 if (replacements[i] != nullptr) {
1037 result[i] =
1038 graph()->NewNode(machine()->BitcastInt32ToFloat32(), replacements[i]);
1039 } else {
1040 result[i] = nullptr;
1041 }
1042 }
1043 }
1044
1045 void SimdScalarLowering::Float32ToInt32(Node** replacements, Node** result) {
1046 for (int i = 0; i < kNumLanes32; ++i) {
1047 if (replacements[i] != nullptr) {
1048 result[i] =
1049 graph()->NewNode(machine()->BitcastFloat32ToInt32(), replacements[i]);
1050 } else {
1051 result[i] = nullptr;
1052 }
1053 }
1054 }
1055
1056 void SimdScalarLowering::Int16ToInt32(Node** replacements, Node** result) {
1057 UNIMPLEMENTED();
1058 }
1059
1060 void SimdScalarLowering::Int32ToInt16(Node** replacements, Node** result) {
1061 UNIMPLEMENTED();
1062 }
1063
802 Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) { 1064 Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
803 Node** replacements = GetReplacements(node); 1065 Node** replacements = GetReplacements(node);
804 if (ReplacementType(node) == type) { 1066 if (ReplacementType(node) == type) {
805 return GetReplacements(node); 1067 return GetReplacements(node);
806 } 1068 }
807 Node** result = zone()->NewArray<Node*>(kMaxLanes); 1069 int num_lanes = NumLanes(type);
808 if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) { 1070 Node** result = zone()->NewArray<Node*>(num_lanes);
809 for (int i = 0; i < kMaxLanes; ++i) { 1071 if (type == SimdType::kInt32) {
810 if (replacements[i] != nullptr) { 1072 if (ReplacementType(node) == SimdType::kFloat32) {
811 result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(), 1073 Float32ToInt32(replacements, result);
812 replacements[i]); 1074 } else if (ReplacementType(node) == SimdType::kInt16) {
813 } else { 1075 Int16ToInt32(replacements, result);
814 result[i] = nullptr; 1076 } else {
815 } 1077 UNREACHABLE();
816 } 1078 }
817 } else if (ReplacementType(node) == SimdType::kFloat32 && 1079 } else if (type == SimdType::kFloat32) {
818 type == SimdType::kInt32) { 1080 if (ReplacementType(node) == SimdType::kInt32) {
819 for (int i = 0; i < kMaxLanes; ++i) { 1081 Int32ToFloat32(replacements, result);
820 if (replacements[i] != nullptr) { 1082 } else if (ReplacementType(node) == SimdType::kInt16) {
821 result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(), 1083 Node** temp_result = zone()->NewArray<Node*>(kNumLanes32);
822 replacements[i]); 1084 Int16ToInt32(replacements, temp_result);
823 } else { 1085 Int32ToFloat32(temp_result, result);
824 result[i] = nullptr; 1086 } else {
825 } 1087 UNREACHABLE();
1088 }
1089 } else if (type == SimdType::kInt16) {
1090 if (ReplacementType(node) == SimdType::kInt32) {
1091 Int32ToInt16(replacements, result);
1092 } else if (ReplacementType(node) == SimdType::kFloat32) {
1093 Node** temp_result = zone()->NewArray<Node*>(kNumLanes32);
1094 Float32ToInt32(replacements, temp_result);
1095 Int32ToInt16(temp_result, result);
1096 } else {
1097 UNREACHABLE();
826 } 1098 }
827 } else { 1099 } else {
828 UNREACHABLE(); 1100 UNREACHABLE();
829 } 1101 }
830 return result; 1102 return result;
831 } 1103 }
832 1104
833 void SimdScalarLowering::PreparePhiReplacement(Node* phi) { 1105 void SimdScalarLowering::PreparePhiReplacement(Node* phi) {
834 MachineRepresentation rep = PhiRepresentationOf(phi->op()); 1106 MachineRepresentation rep = PhiRepresentationOf(phi->op());
835 if (rep == MachineRepresentation::kSimd128) { 1107 if (rep == MachineRepresentation::kSimd128) {
836 // We have to create the replacements for a phi node before we actually 1108 // We have to create the replacements for a phi node before we actually
837 // lower the phi to break potential cycles in the graph. The replacements of 1109 // lower the phi to break potential cycles in the graph. The replacements of
838 // input nodes do not exist yet, so we use a placeholder node to pass the 1110 // input nodes do not exist yet, so we use a placeholder node to pass the
839 // graph verifier. 1111 // graph verifier.
840 int value_count = phi->op()->ValueInputCount(); 1112 int value_count = phi->op()->ValueInputCount();
841 SimdType type = ReplacementType(phi); 1113 SimdType type = ReplacementType(phi);
842 Node** inputs_rep[kMaxLanes]; 1114 int num_lanes = NumLanes(type);
843 for (int i = 0; i < kMaxLanes; ++i) { 1115 Node*** inputs_rep = zone()->NewArray<Node**>(num_lanes);
1116 for (int i = 0; i < num_lanes; ++i) {
844 inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1); 1117 inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1);
845 inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0); 1118 inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0);
846 } 1119 }
847 for (int i = 0; i < value_count; ++i) { 1120 for (int i = 0; i < value_count; ++i) {
848 for (int j = 0; j < kMaxLanes; j++) { 1121 for (int j = 0; j < num_lanes; ++j) {
849 inputs_rep[j][i] = placeholder_; 1122 inputs_rep[j][i] = placeholder_;
850 } 1123 }
851 } 1124 }
852 Node* rep_nodes[kMaxLanes]; 1125 Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
853 for (int i = 0; i < kMaxLanes; ++i) { 1126 for (int i = 0; i < num_lanes; ++i) {
854 if (type == SimdType::kInt32) { 1127 if (type == SimdType::kInt32) {
855 rep_nodes[i] = graph()->NewNode( 1128 rep_nodes[i] = graph()->NewNode(
856 common()->Phi(MachineRepresentation::kWord32, value_count), 1129 common()->Phi(MachineRepresentation::kWord32, value_count),
857 value_count + 1, inputs_rep[i], false); 1130 value_count + 1, inputs_rep[i], false);
858 } else if (type == SimdType::kFloat32) { 1131 } else if (type == SimdType::kFloat32) {
859 rep_nodes[i] = graph()->NewNode( 1132 rep_nodes[i] = graph()->NewNode(
860 common()->Phi(MachineRepresentation::kFloat32, value_count), 1133 common()->Phi(MachineRepresentation::kFloat32, value_count),
861 value_count + 1, inputs_rep[i], false); 1134 value_count + 1, inputs_rep[i], false);
1135 } else if (type == SimdType::kInt16) {
1136 rep_nodes[i] = graph()->NewNode(
1137 common()->Phi(MachineRepresentation::kWord16, value_count),
1138 value_count + 1, inputs_rep[i], false);
862 } else { 1139 } else {
863 UNREACHABLE(); 1140 UNREACHABLE();
864 } 1141 }
865 } 1142 }
866 ReplaceNode(phi, rep_nodes); 1143 ReplaceNode(phi, rep_nodes, num_lanes);
867 } 1144 }
868 } 1145 }
869 } // namespace compiler 1146 } // namespace compiler
870 } // namespace internal 1147 } // namespace internal
871 } // namespace v8 1148 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698