OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 #include "src/s390/frames-s390.h" | 9 #include "src/s390/frames-s390.h" |
10 | 10 |
(...skipping 25 matching lines...) Expand all Loading... |
36 kArithmeticCommonMode = kAllowRM | kAllowRI | 36 kArithmeticCommonMode = kAllowRM | kAllowRI |
37 }; | 37 }; |
38 | 38 |
39 typedef base::Flags<OperandMode, uint32_t> OperandModes; | 39 typedef base::Flags<OperandMode, uint32_t> OperandModes; |
40 DEFINE_OPERATORS_FOR_FLAGS(OperandModes); | 40 DEFINE_OPERATORS_FOR_FLAGS(OperandModes); |
41 OperandModes immediateModeMask = | 41 OperandModes immediateModeMask = |
42 OperandMode::kShift32Imm | OperandMode::kShift64Imm | | 42 OperandMode::kShift32Imm | OperandMode::kShift64Imm | |
43 OperandMode::kInt32Imm | OperandMode::kInt32Imm_Negate | | 43 OperandMode::kInt32Imm | OperandMode::kInt32Imm_Negate | |
44 OperandMode::kUint32Imm | OperandMode::kInt20Imm; | 44 OperandMode::kUint32Imm | OperandMode::kInt20Imm; |
45 | 45 |
46 #define AndOperandMode \ | 46 #define AndCommonMode \ |
47 ((OperandMode::kBitWiseCommonMode | OperandMode::kUint32Imm | \ | 47 ((OperandMode::kAllowRM | \ |
48 OperandMode::kAllowRM | (CpuFeatures::IsSupported(DISTINCT_OPS) \ | 48 (CpuFeatures::IsSupported(DISTINCT_OPS) ? OperandMode::kAllowRRR \ |
49 ? OperandMode::kAllowRRR \ | 49 : OperandMode::kNone))) |
50 : OperandMode::kBitWiseCommonMode))) | 50 #define And64OperandMode AndCommonMode |
| 51 #define Or64OperandMode And64OperandMode |
| 52 #define Xor64OperandMode And64OperandMode |
51 | 53 |
52 #define OrOperandMode AndOperandMode | 54 #define And32OperandMode \ |
53 #define XorOperandMode AndOperandMode | 55 (AndCommonMode | OperandMode::kAllowRI | OperandMode::kUint32Imm) |
| 56 #define Or32OperandMode And32OperandMode |
| 57 #define Xor32OperandMode And32OperandMode |
54 | 58 |
55 #define ShiftOperandMode \ | 59 #define Shift32OperandMode \ |
56 ((OperandMode::kBitWiseCommonMode | OperandMode::kShift64Imm | \ | 60 ((OperandMode::kAllowRI | OperandMode::kShift64Imm | \ |
57 (CpuFeatures::IsSupported(DISTINCT_OPS) \ | 61 (CpuFeatures::IsSupported(DISTINCT_OPS) \ |
58 ? OperandMode::kAllowRRR \ | 62 ? (OperandMode::kAllowRRR | OperandMode::kAllowRRI) \ |
59 : OperandMode::kBitWiseCommonMode))) | 63 : OperandMode::kNone))) |
| 64 |
| 65 #define Shift64OperandMode \ |
| 66 ((OperandMode::kAllowRI | OperandMode::kShift64Imm | \ |
| 67 OperandMode::kAllowRRR | OperandMode::kAllowRRI)) |
60 | 68 |
61 #define AddOperandMode \ | 69 #define AddOperandMode \ |
62 ((OperandMode::kArithmeticCommonMode | OperandMode::kInt32Imm | \ | 70 ((OperandMode::kArithmeticCommonMode | OperandMode::kInt32Imm | \ |
63 (CpuFeatures::IsSupported(DISTINCT_OPS) \ | 71 (CpuFeatures::IsSupported(DISTINCT_OPS) \ |
64 ? (OperandMode::kAllowRRR | OperandMode::kAllowRRI) \ | 72 ? (OperandMode::kAllowRRR | OperandMode::kAllowRRI) \ |
65 : OperandMode::kArithmeticCommonMode))) | 73 : OperandMode::kArithmeticCommonMode))) |
66 #define SubOperandMode \ | 74 #define SubOperandMode \ |
67 ((OperandMode::kArithmeticCommonMode | OperandMode::kInt32Imm_Negate | \ | 75 ((OperandMode::kArithmeticCommonMode | OperandMode::kInt32Imm_Negate | \ |
68 (CpuFeatures::IsSupported(DISTINCT_OPS) \ | 76 (CpuFeatures::IsSupported(DISTINCT_OPS) \ |
69 ? (OperandMode::kAllowRRR | OperandMode::kAllowRRI) \ | 77 ? (OperandMode::kAllowRRR | OperandMode::kAllowRRI) \ |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 242 |
235 bool Is64BitOperand(Node* node) { | 243 bool Is64BitOperand(Node* node) { |
236 return MachineRepresentation::kWord64 == GetRepresentation(node); | 244 return MachineRepresentation::kWord64 == GetRepresentation(node); |
237 } | 245 } |
238 }; | 246 }; |
239 | 247 |
240 namespace { | 248 namespace { |
241 | 249 |
242 bool S390OpcodeOnlySupport12BitDisp(ArchOpcode opcode) { | 250 bool S390OpcodeOnlySupport12BitDisp(ArchOpcode opcode) { |
243 switch (opcode) { | 251 switch (opcode) { |
| 252 case kS390_AddFloat: |
| 253 case kS390_AddDouble: |
244 case kS390_CmpFloat: | 254 case kS390_CmpFloat: |
245 case kS390_CmpDouble: | 255 case kS390_CmpDouble: |
| 256 case kS390_Float32ToDouble: |
246 return true; | 257 return true; |
247 default: | 258 default: |
248 return false; | 259 return false; |
249 } | 260 } |
250 } | 261 } |
251 | 262 |
252 bool S390OpcodeOnlySupport12BitDisp(InstructionCode op) { | 263 bool S390OpcodeOnlySupport12BitDisp(InstructionCode op) { |
253 ArchOpcode opcode = ArchOpcodeField::decode(op); | 264 ArchOpcode opcode = ArchOpcodeField::decode(op); |
254 return S390OpcodeOnlySupport12BitDisp(opcode); | 265 return S390OpcodeOnlySupport12BitDisp(opcode); |
255 } | 266 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 #else | 323 #else |
313 switch (node->opcode()) { | 324 switch (node->opcode()) { |
314 case IrOpcode::kInt32Div: | 325 case IrOpcode::kInt32Div: |
315 case IrOpcode::kUint32Div: | 326 case IrOpcode::kUint32Div: |
316 case IrOpcode::kInt32MulHigh: | 327 case IrOpcode::kInt32MulHigh: |
317 case IrOpcode::kUint32MulHigh: | 328 case IrOpcode::kUint32MulHigh: |
318 case IrOpcode::kInt32Mod: | 329 case IrOpcode::kInt32Mod: |
319 case IrOpcode::kUint32Mod: | 330 case IrOpcode::kUint32Mod: |
320 case IrOpcode::kWord32Clz: | 331 case IrOpcode::kWord32Clz: |
321 case IrOpcode::kWord32Popcnt: | 332 case IrOpcode::kWord32Popcnt: |
| 333 case IrOpcode::kChangeUint32ToUint64: |
322 return true; | 334 return true; |
323 default: | 335 default: |
324 return false; | 336 return false; |
325 } | 337 } |
326 return false; | 338 return false; |
327 #endif | 339 #endif |
328 } | 340 } |
329 | 341 |
330 bool ZeroExtendsWord32ToWord64(Node* node) { | 342 bool ZeroExtendsWord32ToWord64(Node* node) { |
331 #if !V8_TARGET_ARCH_S390X | 343 #if !V8_TARGET_ARCH_S390X |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 } | 397 } |
386 #endif | 398 #endif |
387 } | 399 } |
388 | 400 |
389 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { | 401 void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { |
390 S390OperandGenerator g(selector); | 402 S390OperandGenerator g(selector); |
391 selector->Emit(opcode, g.DefineAsRegister(node), | 403 selector->Emit(opcode, g.DefineAsRegister(node), |
392 g.UseRegister(node->InputAt(0))); | 404 g.UseRegister(node->InputAt(0))); |
393 } | 405 } |
394 | 406 |
395 void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) { | 407 // TODO(john.yan): Create VisiteShift to match dst = src shift (R+I) |
396 S390OperandGenerator g(selector); | 408 #if 0 |
397 selector->Emit(opcode, g.DefineAsRegister(node), | 409 void VisitShift() { } |
398 g.UseRegister(node->InputAt(0)), | 410 #endif |
399 g.UseRegister(node->InputAt(1))); | |
400 } | |
401 | 411 |
402 #if V8_TARGET_ARCH_S390X | 412 #if V8_TARGET_ARCH_S390X |
403 void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node, | |
404 OperandModes operand_mode) { | |
405 S390OperandGenerator g(selector); | |
406 selector->Emit(opcode, g.DefineAsRegister(node), | |
407 g.UseRegister(node->InputAt(0)), | |
408 g.UseOperand(node->InputAt(1), operand_mode)); | |
409 } | |
410 | |
411 void VisitTryTruncateDouble(InstructionSelector* selector, ArchOpcode opcode, | 413 void VisitTryTruncateDouble(InstructionSelector* selector, ArchOpcode opcode, |
412 Node* node) { | 414 Node* node) { |
413 S390OperandGenerator g(selector); | 415 S390OperandGenerator g(selector); |
414 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; | 416 InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))}; |
415 InstructionOperand outputs[2]; | 417 InstructionOperand outputs[2]; |
416 size_t output_count = 0; | 418 size_t output_count = 0; |
417 outputs[output_count++] = g.DefineAsRegister(node); | 419 outputs[output_count++] = g.DefineAsRegister(node); |
418 | 420 |
419 Node* success_output = NodeProperties::FindProjection(node, 1); | 421 Node* success_output = NodeProperties::FindProjection(node, 1); |
420 if (success_output) { | 422 if (success_output) { |
421 outputs[output_count++] = g.DefineAsRegister(success_output); | 423 outputs[output_count++] = g.DefineAsRegister(success_output); |
422 } | 424 } |
423 | 425 |
424 selector->Emit(opcode, output_count, outputs, 1, inputs); | 426 selector->Emit(opcode, output_count, outputs, 1, inputs); |
425 } | 427 } |
426 #endif | 428 #endif |
427 | 429 |
428 // Shared routine for multiple binary operations. | 430 template <class CanCombineWithLoad> |
429 template <typename Matcher> | 431 void GenerateRightOperands(InstructionSelector* selector, Node* node, |
430 void VisitBinop(InstructionSelector* selector, Node* node, | 432 Node* right, InstructionCode& opcode, |
| 433 OperandModes& operand_mode, |
| 434 InstructionOperand* inputs, size_t& input_count, |
| 435 CanCombineWithLoad canCombineWithLoad) { |
| 436 S390OperandGenerator g(selector); |
| 437 |
| 438 if ((operand_mode & OperandMode::kAllowImmediate) && |
| 439 g.CanBeImmediate(right, operand_mode)) { |
| 440 inputs[input_count++] = g.UseImmediate(right); |
| 441 // Can only be RI or RRI |
| 442 operand_mode &= OperandMode::kAllowImmediate; |
| 443 } else if (operand_mode & OperandMode::kAllowMemoryOperand) { |
| 444 NodeMatcher mright(right); |
| 445 if (mright.IsLoad() && selector->CanCover(node, right) && |
| 446 canCombineWithLoad(SelectLoadOpcode(right))) { |
| 447 AddressingMode mode = g.GetEffectiveAddressMemoryOperand( |
| 448 right, inputs, &input_count, OpcodeImmMode(opcode)); |
| 449 opcode |= AddressingModeField::encode(mode); |
| 450 operand_mode &= ~OperandMode::kAllowImmediate; |
| 451 if (operand_mode & OperandMode::kAllowRM) |
| 452 operand_mode &= ~OperandMode::kAllowDistinctOps; |
| 453 } else if (operand_mode & OperandMode::kAllowRM) { |
| 454 DCHECK(!(operand_mode & OperandMode::kAllowRRM)); |
| 455 inputs[input_count++] = g.UseAnyExceptImmediate(right); |
| 456 // Can not be Immediate |
| 457 operand_mode &= |
| 458 ~OperandMode::kAllowImmediate & ~OperandMode::kAllowDistinctOps; |
| 459 } else if (operand_mode & OperandMode::kAllowRRM) { |
| 460 DCHECK(!(operand_mode & OperandMode::kAllowRM)); |
| 461 inputs[input_count++] = g.UseAnyExceptImmediate(right); |
| 462 // Can not be Immediate |
| 463 operand_mode &= ~OperandMode::kAllowImmediate; |
| 464 } else { |
| 465 UNREACHABLE(); |
| 466 } |
| 467 } else { |
| 468 inputs[input_count++] = g.UseRegister(right); |
| 469 // Can only be RR or RRR |
| 470 operand_mode &= OperandMode::kAllowRRR; |
| 471 } |
| 472 } |
| 473 |
| 474 template <class CanCombineWithLoad> |
| 475 void GenerateBinOpOperands(InstructionSelector* selector, Node* node, |
| 476 Node* left, Node* right, InstructionCode& opcode, |
| 477 OperandModes& operand_mode, |
| 478 InstructionOperand* inputs, size_t& input_count, |
| 479 CanCombineWithLoad canCombineWithLoad) { |
| 480 S390OperandGenerator g(selector); |
| 481 // left is always register |
| 482 InstructionOperand const left_input = g.UseRegister(left); |
| 483 inputs[input_count++] = left_input; |
| 484 |
| 485 if (left == right) { |
| 486 inputs[input_count++] = left_input; |
| 487 // Can only be RR or RRR |
| 488 operand_mode &= OperandMode::kAllowRRR; |
| 489 } else { |
| 490 GenerateRightOperands(selector, node, right, opcode, operand_mode, inputs, |
| 491 input_count, canCombineWithLoad); |
| 492 } |
| 493 } |
| 494 |
| 495 template <class CanCombineWithLoad> |
| 496 void VisitUnaryOp(InstructionSelector* selector, Node* node, |
| 497 InstructionCode opcode, OperandModes operand_mode, |
| 498 FlagsContinuation* cont, |
| 499 CanCombineWithLoad canCombineWithLoad); |
| 500 |
| 501 template <class CanCombineWithLoad> |
| 502 void VisitBinOp(InstructionSelector* selector, Node* node, |
431 InstructionCode opcode, OperandModes operand_mode, | 503 InstructionCode opcode, OperandModes operand_mode, |
432 FlagsContinuation* cont) { | 504 FlagsContinuation* cont, CanCombineWithLoad canCombineWithLoad); |
| 505 |
| 506 #define VISIT_OP_LIST(V) \ |
| 507 V(Word64, Unary, \ |
| 508 [](ArchOpcode opcode) { return opcode == kS390_LoadWord64; }) \ |
| 509 V(Word64, Bin, [](ArchOpcode opcode) { return opcode == kS390_LoadWord64; }) \ |
| 510 V(Float32, Unary, \ |
| 511 [](ArchOpcode opcode) { return opcode == kS390_LoadFloat32; }) \ |
| 512 V(Float64, Unary, \ |
| 513 [](ArchOpcode opcode) { return opcode == kS390_LoadDouble; }) \ |
| 514 V(Float32, Bin, \ |
| 515 [](ArchOpcode opcode) { return opcode == kS390_LoadFloat32; }) \ |
| 516 V(Float64, Bin, [](ArchOpcode opcode) { return opcode == kS390_LoadDouble; }) |
| 517 |
| 518 #define DECLARE_VISIT_HELPER_FUNCTIONS(type1, type2, canCombineWithLoad) \ |
| 519 void Visit##type1##type2##Op( \ |
| 520 InstructionSelector* selector, Node* node, InstructionCode opcode, \ |
| 521 OperandModes operand_mode, FlagsContinuation* cont) { \ |
| 522 Visit##type2##Op(selector, node, opcode, operand_mode, cont, \ |
| 523 canCombineWithLoad); \ |
| 524 } \ |
| 525 void Visit##type1##type2##Op(InstructionSelector* selector, Node* node, \ |
| 526 InstructionCode opcode, \ |
| 527 OperandModes operand_mode) { \ |
| 528 FlagsContinuation cont; \ |
| 529 Visit##type1##type2##Op(selector, node, opcode, operand_mode, &cont); \ |
| 530 } |
| 531 VISIT_OP_LIST(DECLARE_VISIT_HELPER_FUNCTIONS); |
| 532 #undef DECLARE_VISIT_HELPER_FUNCTIONS |
| 533 |
| 534 template <class CanCombineWithLoad> |
| 535 void VisitUnaryOp(InstructionSelector* selector, Node* node, |
| 536 InstructionCode opcode, OperandModes operand_mode, |
| 537 FlagsContinuation* cont, |
| 538 CanCombineWithLoad canCombineWithLoad) { |
| 539 // Just to get rid of unused function warning |
| 540 #define USE_VISITOR(type1, type2, canCombineWithLoad) \ |
| 541 { \ |
| 542 VisiterType dummy = Visit##type1##type2##Op; \ |
| 543 USE(dummy); \ |
| 544 } |
| 545 typedef void (*VisiterType)(InstructionSelector * selector, Node * node, |
| 546 InstructionCode opcode, |
| 547 OperandModes operand_mode); |
| 548 VISIT_OP_LIST(USE_VISITOR); |
| 549 #undef USE_VISITOR |
| 550 |
433 S390OperandGenerator g(selector); | 551 S390OperandGenerator g(selector); |
434 Matcher m(node); | 552 InstructionOperand inputs[8]; |
435 Node* left = m.left().node(); | |
436 Node* right = m.right().node(); | |
437 InstructionOperand inputs[4]; | |
438 size_t input_count = 0; | 553 size_t input_count = 0; |
439 InstructionOperand outputs[2]; | 554 InstructionOperand outputs[2]; |
440 size_t output_count = 0; | 555 size_t output_count = 0; |
| 556 Node* input = node->InputAt(0); |
441 | 557 |
442 // TODO(turbofan): match complex addressing modes. | 558 GenerateRightOperands(selector, node, input, opcode, operand_mode, inputs, |
443 if (left == right) { | 559 input_count, canCombineWithLoad); |
444 // If both inputs refer to the same operand, enforce allocating a register | |
445 // for both of them to ensure that we don't end up generating code like | |
446 // this: | |
447 // | |
448 // mov rax, [rbp-0x10] | |
449 // add rax, [rbp-0x10] | |
450 // jo label | |
451 InstructionOperand const input = g.UseRegister(left); | |
452 inputs[input_count++] = input; | |
453 inputs[input_count++] = input; | |
454 } else if (g.CanBeImmediate(right, operand_mode)) { | |
455 inputs[input_count++] = g.UseRegister(left); | |
456 inputs[input_count++] = g.UseImmediate(right); | |
457 } else { | |
458 if (node->op()->HasProperty(Operator::kCommutative) && | |
459 g.CanBeBetterLeftOperand(right)) { | |
460 std::swap(left, right); | |
461 } | |
462 inputs[input_count++] = g.UseRegister(left); | |
463 inputs[input_count++] = g.UseRegister(right); | |
464 } | |
465 | 560 |
466 if (cont->IsBranch()) { | 561 if (cont->IsBranch()) { |
467 inputs[input_count++] = g.Label(cont->true_block()); | 562 inputs[input_count++] = g.Label(cont->true_block()); |
468 inputs[input_count++] = g.Label(cont->false_block()); | 563 inputs[input_count++] = g.Label(cont->false_block()); |
469 } | 564 } |
470 | 565 |
471 if (cont->IsDeoptimize()) { | 566 if (!cont->IsDeoptimize()) { |
472 // If we can deoptimize as a result of the binop, we need to make sure that | 567 // If we can deoptimize as a result of the binop, we need to make sure |
473 // the deopt inputs are not overwritten by the binop result. One way | 568 // that the deopt inputs are not overwritten by the binop result. One way |
474 // to achieve that is to declare the output register as same-as-first. | 569 // to achieve that is to declare the output register as same-as-first. |
| 570 outputs[output_count++] = g.DefineAsRegister(node); |
| 571 } else { |
475 outputs[output_count++] = g.DefineSameAsFirst(node); | 572 outputs[output_count++] = g.DefineSameAsFirst(node); |
476 } else { | |
477 outputs[output_count++] = g.DefineAsRegister(node); | |
478 } | 573 } |
| 574 |
479 if (cont->IsSet()) { | 575 if (cont->IsSet()) { |
480 outputs[output_count++] = g.DefineAsRegister(cont->result()); | 576 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
481 } | 577 } |
482 | 578 |
483 DCHECK_NE(0u, input_count); | 579 DCHECK_NE(0u, input_count); |
484 DCHECK_NE(0u, output_count); | 580 DCHECK_NE(0u, output_count); |
485 DCHECK_GE(arraysize(inputs), input_count); | 581 DCHECK_GE(arraysize(inputs), input_count); |
486 DCHECK_GE(arraysize(outputs), output_count); | 582 DCHECK_GE(arraysize(outputs), output_count); |
487 | 583 |
488 opcode = cont->Encode(opcode); | 584 opcode = cont->Encode(opcode); |
| 585 |
489 if (cont->IsDeoptimize()) { | 586 if (cont->IsDeoptimize()) { |
490 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, | 587 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
491 cont->kind(), cont->reason(), cont->frame_state()); | 588 cont->kind(), cont->reason(), cont->frame_state()); |
492 } else if (cont->IsTrap()) { | 589 } else if (cont->IsTrap()) { |
493 inputs[input_count++] = g.UseImmediate(cont->trap_id()); | 590 inputs[input_count++] = g.UseImmediate(cont->trap_id()); |
494 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 591 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
495 } else { | 592 } else { |
496 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 593 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
497 } | 594 } |
498 } | 595 } |
499 | 596 |
500 // Shared routine for multiple binary operations. | 597 template <class CanCombineWithLoad> |
501 template <typename Matcher> | 598 void VisitBinOp(InstructionSelector* selector, Node* node, |
502 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, | 599 InstructionCode opcode, OperandModes operand_mode, |
503 OperandModes operand_mode) { | 600 FlagsContinuation* cont, |
504 FlagsContinuation cont; | 601 CanCombineWithLoad canCombineWithLoad) { |
505 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); | 602 S390OperandGenerator g(selector); |
| 603 Int32BinopMatcher m(node); |
| 604 Node* left = m.left().node(); |
| 605 Node* right = m.right().node(); |
| 606 InstructionOperand inputs[8]; |
| 607 size_t input_count = 0; |
| 608 InstructionOperand outputs[2]; |
| 609 size_t output_count = 0; |
| 610 |
| 611 if (node->op()->HasProperty(Operator::kCommutative) && |
| 612 !g.CanBeImmediate(right, operand_mode) && |
| 613 (g.CanBeBetterLeftOperand(right))) { |
| 614 std::swap(left, right); |
| 615 } |
| 616 |
| 617 GenerateBinOpOperands(selector, node, left, right, opcode, operand_mode, |
| 618 inputs, input_count, canCombineWithLoad); |
| 619 |
| 620 if (cont->IsBranch()) { |
| 621 inputs[input_count++] = g.Label(cont->true_block()); |
| 622 inputs[input_count++] = g.Label(cont->false_block()); |
| 623 } |
| 624 |
| 625 if ((operand_mode & OperandMode::kAllowDistinctOps) && |
| 626 // If we can deoptimize as a result of the binop, we need to make sure |
| 627 // that the deopt inputs are not overwritten by the binop result. One way |
| 628 // to achieve that is to declare the output register as same-as-first. |
| 629 !cont->IsDeoptimize()) { |
| 630 outputs[output_count++] = g.DefineAsRegister(node); |
| 631 } else { |
| 632 outputs[output_count++] = g.DefineSameAsFirst(node); |
| 633 } |
| 634 |
| 635 if (cont->IsSet()) { |
| 636 outputs[output_count++] = g.DefineAsRegister(cont->result()); |
| 637 } |
| 638 |
| 639 DCHECK_NE(0u, input_count); |
| 640 DCHECK_NE(0u, output_count); |
| 641 DCHECK_GE(arraysize(inputs), input_count); |
| 642 DCHECK_GE(arraysize(outputs), output_count); |
| 643 |
| 644 opcode = cont->Encode(opcode); |
| 645 |
| 646 if (cont->IsDeoptimize()) { |
| 647 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs, |
| 648 cont->kind(), cont->reason(), cont->frame_state()); |
| 649 } else if (cont->IsTrap()) { |
| 650 inputs[input_count++] = g.UseImmediate(cont->trap_id()); |
| 651 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 652 } else { |
| 653 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
| 654 } |
506 } | 655 } |
507 | 656 |
508 void VisitBin32op(InstructionSelector* selector, Node* node, | 657 void VisitBin32op(InstructionSelector* selector, Node* node, |
509 InstructionCode opcode, OperandModes operand_mode, | 658 InstructionCode opcode, OperandModes operand_mode, |
510 FlagsContinuation* cont) { | 659 FlagsContinuation* cont) { |
511 S390OperandGenerator g(selector); | 660 S390OperandGenerator g(selector); |
512 Int32BinopMatcher m(node); | 661 Int32BinopMatcher m(node); |
513 Node* left = m.left().node(); | 662 Node* left = m.left().node(); |
514 Node* right = m.right().node(); | 663 Node* right = m.right().node(); |
515 InstructionOperand inputs[8]; | 664 InstructionOperand inputs[8]; |
(...skipping 17 matching lines...) Expand all Loading... |
533 std::swap(left, right); | 682 std::swap(left, right); |
534 } | 683 } |
535 #else | 684 #else |
536 if (node->op()->HasProperty(Operator::kCommutative) && | 685 if (node->op()->HasProperty(Operator::kCommutative) && |
537 !g.CanBeImmediate(right, operand_mode) && | 686 !g.CanBeImmediate(right, operand_mode) && |
538 (g.CanBeBetterLeftOperand(right))) { | 687 (g.CanBeBetterLeftOperand(right))) { |
539 std::swap(left, right); | 688 std::swap(left, right); |
540 } | 689 } |
541 #endif | 690 #endif |
542 | 691 |
543 // left is always register | 692 GenerateBinOpOperands(selector, node, left, right, opcode, operand_mode, |
544 InstructionOperand const left_input = g.UseRegister(left); | 693 inputs, input_count, [](ArchOpcode opcode) { |
545 inputs[input_count++] = left_input; | 694 return opcode == kS390_LoadWordU32 || |
546 | 695 opcode == kS390_LoadWordS32; |
547 // TODO(turbofan): match complex addressing modes. | 696 }); |
548 if (left == right) { | |
549 // If both inputs refer to the same operand, enforce allocating a register | |
550 // for both of them to ensure that we don't end up generating code like | |
551 // this: | |
552 // | |
553 // mov rax, [rbp-0x10] | |
554 // add rax, [rbp-0x10] | |
555 // jo label | |
556 inputs[input_count++] = left_input; | |
557 // Can only be RR or RRR | |
558 operand_mode &= OperandMode::kAllowRRR; | |
559 } else if ((operand_mode & OperandMode::kAllowImmediate) && | |
560 g.CanBeImmediate(right, operand_mode)) { | |
561 inputs[input_count++] = g.UseImmediate(right); | |
562 // Can only be RI or RRI | |
563 operand_mode &= OperandMode::kAllowImmediate; | |
564 } else if (operand_mode & OperandMode::kAllowMemoryOperand) { | |
565 NodeMatcher mright(right); | |
566 if (mright.IsLoad() && selector->CanCover(node, right) && | |
567 SelectLoadOpcode(right) == kS390_LoadWordU32) { | |
568 AddressingMode mode = | |
569 g.GetEffectiveAddressMemoryOperand(right, inputs, &input_count); | |
570 opcode |= AddressingModeField::encode(mode); | |
571 operand_mode &= ~OperandMode::kAllowImmediate; | |
572 if (operand_mode & OperandMode::kAllowRM) | |
573 operand_mode &= ~OperandMode::kAllowDistinctOps; | |
574 } else if (operand_mode & OperandMode::kAllowRM) { | |
575 DCHECK(!(operand_mode & OperandMode::kAllowRRM)); | |
576 inputs[input_count++] = g.Use(right); | |
577 // Can not be Immediate | |
578 operand_mode &= | |
579 ~OperandMode::kAllowImmediate & ~OperandMode::kAllowDistinctOps; | |
580 } else if (operand_mode & OperandMode::kAllowRRM) { | |
581 DCHECK(!(operand_mode & OperandMode::kAllowRM)); | |
582 inputs[input_count++] = g.Use(right); | |
583 // Can not be Immediate | |
584 operand_mode &= ~OperandMode::kAllowImmediate; | |
585 } else { | |
586 UNREACHABLE(); | |
587 } | |
588 } else { | |
589 inputs[input_count++] = g.UseRegister(right); | |
590 // Can only be RR or RRR | |
591 operand_mode &= OperandMode::kAllowRRR; | |
592 } | |
593 | 697 |
594 bool doZeroExt = | 698 bool doZeroExt = |
595 AutoZeroExtendsWord32ToWord64(node) || !ZeroExtendsWord32ToWord64(left); | 699 AutoZeroExtendsWord32ToWord64(node) || !ZeroExtendsWord32ToWord64(left); |
596 | 700 |
597 inputs[input_count++] = | 701 inputs[input_count++] = |
598 g.TempImmediate(doZeroExt && (!AutoZeroExtendsWord32ToWord64(node))); | 702 g.TempImmediate(doZeroExt && (!AutoZeroExtendsWord32ToWord64(node))); |
599 | 703 |
600 if (cont->IsBranch()) { | 704 if (cont->IsBranch()) { |
601 inputs[input_count++] = g.Label(cont->true_block()); | 705 inputs[input_count++] = g.Label(cont->true_block()); |
602 inputs[input_count++] = g.Label(cont->false_block()); | 706 inputs[input_count++] = g.Label(cont->false_block()); |
(...skipping 30 matching lines...) Expand all Loading... |
633 } else { | 737 } else { |
634 selector->Emit(opcode, output_count, outputs, input_count, inputs); | 738 selector->Emit(opcode, output_count, outputs, input_count, inputs); |
635 } | 739 } |
636 } | 740 } |
637 | 741 |
638 void VisitBin32op(InstructionSelector* selector, Node* node, ArchOpcode opcode, | 742 void VisitBin32op(InstructionSelector* selector, Node* node, ArchOpcode opcode, |
639 OperandModes operand_mode) { | 743 OperandModes operand_mode) { |
640 FlagsContinuation cont; | 744 FlagsContinuation cont; |
641 VisitBin32op(selector, node, opcode, operand_mode, &cont); | 745 VisitBin32op(selector, node, opcode, operand_mode, &cont); |
642 } | 746 } |
| 747 #undef VISIT_OP_LIST |
643 | 748 |
644 } // namespace | 749 } // namespace |
645 | 750 |
646 void InstructionSelector::VisitLoad(Node* node) { | 751 void InstructionSelector::VisitLoad(Node* node) { |
647 S390OperandGenerator g(this); | 752 S390OperandGenerator g(this); |
648 ArchOpcode opcode = SelectLoadOpcode(node); | 753 ArchOpcode opcode = SelectLoadOpcode(node); |
649 InstructionOperand outputs[1]; | 754 InstructionOperand outputs[1]; |
650 outputs[0] = g.DefineAsRegister(node); | 755 outputs[0] = g.DefineAsRegister(node); |
651 InstructionOperand inputs[3]; | 756 InstructionOperand inputs[3]; |
652 size_t input_count = 0; | 757 size_t input_count = 0; |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 int mask_msb = base::bits::CountLeadingZeros64(value); | 1006 int mask_msb = base::bits::CountLeadingZeros64(value); |
902 int mask_lsb = base::bits::CountTrailingZeros64(value); | 1007 int mask_lsb = base::bits::CountTrailingZeros64(value); |
903 if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 64)) | 1008 if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 64)) |
904 return false; | 1009 return false; |
905 *mb = mask_lsb + mask_width - 1; | 1010 *mb = mask_lsb + mask_width - 1; |
906 *me = mask_lsb; | 1011 *me = mask_lsb; |
907 return true; | 1012 return true; |
908 } | 1013 } |
909 #endif | 1014 #endif |
910 | 1015 |
911 void InstructionSelector::VisitWord32And(Node* node) { | 1016 // TODO(john.yan): use list to simplify general instructions |
912 VisitBin32op(this, node, kS390_And32, AndOperandMode); | 1017 #define WORD32_BIN_OP_LIST(V) \ |
913 } | 1018 /* V(name, ArchOpcode, OperandModes) */ \ |
| 1019 V(Word32And, kS390_And32, And32OperandMode) \ |
| 1020 V(Word32Or, kS390_Or32, Or32OperandMode) \ |
| 1021 V(Word32Xor, kS390_Xor32, Xor32OperandMode) \ |
| 1022 V(Word32Shl, kS390_ShiftLeft32, Shift32OperandMode) \ |
| 1023 V(Word32Shr, kS390_ShiftRight32, Shift32OperandMode) |
| 1024 |
| 1025 #define VISITOR(name, op, mode) \ |
| 1026 void InstructionSelector::Visit##name(Node* node) { \ |
| 1027 VisitBin32op(this, node, op, mode); \ |
| 1028 } |
| 1029 WORD32_BIN_OP_LIST(VISITOR); |
| 1030 #undef VISITOR |
| 1031 #undef WORD32_BIN_OP_LIST |
914 | 1032 |
915 #if V8_TARGET_ARCH_S390X | 1033 #if V8_TARGET_ARCH_S390X |
916 void InstructionSelector::VisitWord64And(Node* node) { | 1034 void InstructionSelector::VisitWord64And(Node* node) { |
917 S390OperandGenerator g(this); | 1035 S390OperandGenerator g(this); |
918 Int64BinopMatcher m(node); | 1036 Int64BinopMatcher m(node); |
919 int mb = 0; | 1037 int mb = 0; |
920 int me = 0; | 1038 int me = 0; |
921 if (m.right().HasValue() && IsContiguousMask64(m.right().Value(), &mb, &me)) { | 1039 if (m.right().HasValue() && IsContiguousMask64(m.right().Value(), &mb, &me)) { |
922 int sh = 0; | 1040 int sh = 0; |
923 Node* left = m.left().node(); | 1041 Node* left = m.left().node(); |
(...skipping 23 matching lines...) Expand all Loading... |
947 mask = mb; | 1065 mask = mb; |
948 } else if (mb == 63) { | 1066 } else if (mb == 63) { |
949 match = true; | 1067 match = true; |
950 opcode = kS390_RotLeftAndClearRight64; | 1068 opcode = kS390_RotLeftAndClearRight64; |
951 mask = me; | 1069 mask = me; |
952 } else if (sh && me <= sh && m.left().IsWord64Shl()) { | 1070 } else if (sh && me <= sh && m.left().IsWord64Shl()) { |
953 match = true; | 1071 match = true; |
954 opcode = kS390_RotLeftAndClear64; | 1072 opcode = kS390_RotLeftAndClear64; |
955 mask = mb; | 1073 mask = mb; |
956 } | 1074 } |
957 if (match) { | 1075 if (match && CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) { |
958 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), | 1076 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), |
959 g.TempImmediate(sh), g.TempImmediate(mask)); | 1077 g.TempImmediate(sh), g.TempImmediate(mask)); |
960 return; | 1078 return; |
961 } | 1079 } |
962 } | 1080 } |
963 } | 1081 } |
964 VisitBinop<Int64BinopMatcher>(this, node, kS390_And64, | 1082 VisitWord64BinOp(this, node, kS390_And64, And64OperandMode); |
965 OperandMode::kUint32Imm); | |
966 } | |
967 #endif | |
968 | |
969 void InstructionSelector::VisitWord32Or(Node* node) { | |
970 VisitBin32op(this, node, kS390_Or32, OrOperandMode); | |
971 } | 1083 } |
972 | 1084 |
973 #if V8_TARGET_ARCH_S390X | |
974 void InstructionSelector::VisitWord64Or(Node* node) { | 1085 void InstructionSelector::VisitWord64Or(Node* node) { |
975 Int64BinopMatcher m(node); | 1086 VisitWord64BinOp(this, node, kS390_Or64, Or64OperandMode); |
976 VisitBinop<Int64BinopMatcher>(this, node, kS390_Or64, | |
977 OperandMode::kUint32Imm); | |
978 } | |
979 #endif | |
980 | |
981 void InstructionSelector::VisitWord32Xor(Node* node) { | |
982 VisitBin32op(this, node, kS390_Xor32, XorOperandMode); | |
983 } | 1087 } |
984 | 1088 |
985 #if V8_TARGET_ARCH_S390X | |
986 void InstructionSelector::VisitWord64Xor(Node* node) { | 1089 void InstructionSelector::VisitWord64Xor(Node* node) { |
987 VisitBinop<Int64BinopMatcher>(this, node, kS390_Xor64, | 1090 VisitWord64BinOp(this, node, kS390_Xor64, Xor64OperandMode); |
988 OperandMode::kUint32Imm); | |
989 } | |
990 #endif | |
991 | |
992 void InstructionSelector::VisitWord32Shl(Node* node) { | |
993 VisitBin32op(this, node, kS390_ShiftLeft32, ShiftOperandMode); | |
994 } | 1091 } |
995 | 1092 |
996 #if V8_TARGET_ARCH_S390X | |
997 void InstructionSelector::VisitWord64Shl(Node* node) { | 1093 void InstructionSelector::VisitWord64Shl(Node* node) { |
998 S390OperandGenerator g(this); | 1094 S390OperandGenerator g(this); |
999 Int64BinopMatcher m(node); | 1095 Int64BinopMatcher m(node); |
1000 // TODO(mbrandy): eliminate left sign extension if right >= 32 | 1096 // TODO(mbrandy): eliminate left sign extension if right >= 32 |
1001 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 1097 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
1002 Int64BinopMatcher mleft(m.left().node()); | 1098 Int64BinopMatcher mleft(m.left().node()); |
1003 int sh = m.right().Value(); | 1099 int sh = m.right().Value(); |
1004 int mb; | 1100 int mb; |
1005 int me; | 1101 int me; |
1006 if (mleft.right().HasValue() && | 1102 if (mleft.right().HasValue() && |
(...skipping 10 matching lines...) Expand all Loading... |
1017 mask = mb; | 1113 mask = mb; |
1018 } else if (mb == 63) { | 1114 } else if (mb == 63) { |
1019 match = true; | 1115 match = true; |
1020 opcode = kS390_RotLeftAndClearRight64; | 1116 opcode = kS390_RotLeftAndClearRight64; |
1021 mask = me; | 1117 mask = me; |
1022 } else if (sh && me <= sh) { | 1118 } else if (sh && me <= sh) { |
1023 match = true; | 1119 match = true; |
1024 opcode = kS390_RotLeftAndClear64; | 1120 opcode = kS390_RotLeftAndClear64; |
1025 mask = mb; | 1121 mask = mb; |
1026 } | 1122 } |
1027 if (match) { | 1123 if (match && CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) { |
1028 Emit(opcode, g.DefineAsRegister(node), | 1124 Emit(opcode, g.DefineAsRegister(node), |
1029 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 1125 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
1030 g.TempImmediate(mask)); | 1126 g.TempImmediate(mask)); |
1031 return; | 1127 return; |
1032 } | 1128 } |
1033 } | 1129 } |
1034 } | 1130 } |
1035 } | 1131 } |
1036 VisitRRO(this, kS390_ShiftLeft64, node, OperandMode::kShift64Imm); | 1132 VisitWord64BinOp(this, node, kS390_ShiftLeft64, Shift64OperandMode); |
1037 } | |
1038 #endif | |
1039 | |
1040 void InstructionSelector::VisitWord32Shr(Node* node) { | |
1041 VisitBin32op(this, node, kS390_ShiftRight32, ShiftOperandMode); | |
1042 } | 1133 } |
1043 | 1134 |
1044 #if V8_TARGET_ARCH_S390X | |
1045 void InstructionSelector::VisitWord64Shr(Node* node) { | 1135 void InstructionSelector::VisitWord64Shr(Node* node) { |
1046 S390OperandGenerator g(this); | 1136 S390OperandGenerator g(this); |
1047 Int64BinopMatcher m(node); | 1137 Int64BinopMatcher m(node); |
1048 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { | 1138 if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) { |
1049 Int64BinopMatcher mleft(m.left().node()); | 1139 Int64BinopMatcher mleft(m.left().node()); |
1050 int sh = m.right().Value(); | 1140 int sh = m.right().Value(); |
1051 int mb; | 1141 int mb; |
1052 int me; | 1142 int me; |
1053 if (mleft.right().HasValue() && | 1143 if (mleft.right().HasValue() && |
1054 IsContiguousMask64((uint64_t)(mleft.right().Value()) >> sh, &mb, &me)) { | 1144 IsContiguousMask64((uint64_t)(mleft.right().Value()) >> sh, &mb, &me)) { |
(...skipping 15 matching lines...) Expand all Loading... |
1070 } | 1160 } |
1071 if (match) { | 1161 if (match) { |
1072 Emit(opcode, g.DefineAsRegister(node), | 1162 Emit(opcode, g.DefineAsRegister(node), |
1073 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), | 1163 g.UseRegister(mleft.left().node()), g.TempImmediate(sh), |
1074 g.TempImmediate(mask)); | 1164 g.TempImmediate(mask)); |
1075 return; | 1165 return; |
1076 } | 1166 } |
1077 } | 1167 } |
1078 } | 1168 } |
1079 } | 1169 } |
1080 VisitRRO(this, kS390_ShiftRight64, node, OperandMode::kShift64Imm); | 1170 VisitWord64BinOp(this, node, kS390_ShiftRight64, Shift64OperandMode); |
1081 } | 1171 } |
1082 #endif | 1172 #endif |
1083 | 1173 |
1084 void InstructionSelector::VisitWord32Sar(Node* node) { | 1174 void InstructionSelector::VisitWord32Sar(Node* node) { |
1085 S390OperandGenerator g(this); | 1175 S390OperandGenerator g(this); |
1086 Int32BinopMatcher m(node); | 1176 Int32BinopMatcher m(node); |
1087 // Replace with sign extension for (x << K) >> K where K is 16 or 24. | 1177 // Replace with sign extension for (x << K) >> K where K is 16 or 24. |
1088 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { | 1178 if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) { |
1089 Int32BinopMatcher mleft(m.left().node()); | 1179 Int32BinopMatcher mleft(m.left().node()); |
1090 if (mleft.right().Is(16) && m.right().Is(16)) { | 1180 if (mleft.right().Is(16) && m.right().Is(16)) { |
1091 bool doZeroExt = !ZeroExtendsWord32ToWord64(mleft.left().node()); | 1181 bool doZeroExt = !ZeroExtendsWord32ToWord64(mleft.left().node()); |
1092 Emit(kS390_ExtendSignWord16, | 1182 Emit(kS390_ExtendSignWord16, |
1093 doZeroExt ? g.DefineAsRegister(node) : g.DefineSameAsFirst(node), | 1183 doZeroExt ? g.DefineAsRegister(node) : g.DefineSameAsFirst(node), |
1094 g.UseRegister(mleft.left().node()), g.TempImmediate(doZeroExt)); | 1184 g.UseRegister(mleft.left().node()), g.TempImmediate(doZeroExt)); |
1095 return; | 1185 return; |
1096 } else if (mleft.right().Is(24) && m.right().Is(24)) { | 1186 } else if (mleft.right().Is(24) && m.right().Is(24)) { |
1097 bool doZeroExt = !ZeroExtendsWord32ToWord64(mleft.left().node()); | 1187 bool doZeroExt = !ZeroExtendsWord32ToWord64(mleft.left().node()); |
1098 Emit(kS390_ExtendSignWord8, | 1188 Emit(kS390_ExtendSignWord8, |
1099 doZeroExt ? g.DefineAsRegister(node) : g.DefineSameAsFirst(node), | 1189 doZeroExt ? g.DefineAsRegister(node) : g.DefineSameAsFirst(node), |
1100 g.UseRegister(mleft.left().node()), g.TempImmediate(doZeroExt)); | 1190 g.UseRegister(mleft.left().node()), g.TempImmediate(doZeroExt)); |
1101 return; | 1191 return; |
1102 } | 1192 } |
1103 } | 1193 } |
1104 VisitBin32op(this, node, kS390_ShiftRightArith32, ShiftOperandMode); | 1194 VisitBin32op(this, node, kS390_ShiftRightArith32, Shift32OperandMode); |
1105 } | 1195 } |
1106 | 1196 |
1107 #if !V8_TARGET_ARCH_S390X | 1197 #if !V8_TARGET_ARCH_S390X |
1108 void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode, | 1198 void VisitPairBinop(InstructionSelector* selector, InstructionCode opcode, |
1109 InstructionCode opcode2, Node* node) { | 1199 InstructionCode opcode2, Node* node) { |
1110 S390OperandGenerator g(selector); | 1200 S390OperandGenerator g(selector); |
1111 | 1201 |
1112 Node* projection1 = NodeProperties::FindProjection(node, 1); | 1202 Node* projection1 = NodeProperties::FindProjection(node, 1); |
1113 if (projection1) { | 1203 if (projection1) { |
1114 // We use UseUniqueRegister here to avoid register sharing with the output | 1204 // We use UseUniqueRegister here to avoid register sharing with the output |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 VisitPairShift(this, kS390_ShiftRightPair, node); | 1297 VisitPairShift(this, kS390_ShiftRightPair, node); |
1208 } | 1298 } |
1209 | 1299 |
1210 void InstructionSelector::VisitWord32PairSar(Node* node) { | 1300 void InstructionSelector::VisitWord32PairSar(Node* node) { |
1211 VisitPairShift(this, kS390_ShiftRightArithPair, node); | 1301 VisitPairShift(this, kS390_ShiftRightArithPair, node); |
1212 } | 1302 } |
1213 #endif | 1303 #endif |
1214 | 1304 |
1215 #if V8_TARGET_ARCH_S390X | 1305 #if V8_TARGET_ARCH_S390X |
1216 void InstructionSelector::VisitWord64Sar(Node* node) { | 1306 void InstructionSelector::VisitWord64Sar(Node* node) { |
1217 VisitRRO(this, kS390_ShiftRightArith64, node, OperandMode::kShift64Imm); | 1307 VisitWord64BinOp(this, node, kS390_ShiftRightArith64, Shift64OperandMode); |
1218 } | 1308 } |
1219 #endif | 1309 #endif |
1220 | 1310 |
1221 void InstructionSelector::VisitWord32Ror(Node* node) { | 1311 void InstructionSelector::VisitWord32Ror(Node* node) { |
1222 // TODO(john): match dst = ror(src1, src2 + imm) | 1312 // TODO(john): match dst = ror(src1, src2 + imm) |
1223 VisitBin32op(this, node, kS390_RotRight32, | 1313 VisitBin32op(this, node, kS390_RotRight32, |
1224 OperandMode::kAllowRI | OperandMode::kAllowRRR | | 1314 OperandMode::kAllowRI | OperandMode::kAllowRRR | |
1225 OperandMode::kAllowRRI | OperandMode::kShift32Imm); | 1315 OperandMode::kAllowRRI | OperandMode::kShift32Imm); |
1226 } | 1316 } |
1227 | 1317 |
1228 #if V8_TARGET_ARCH_S390X | 1318 #if V8_TARGET_ARCH_S390X |
1229 void InstructionSelector::VisitWord64Ror(Node* node) { | 1319 void InstructionSelector::VisitWord64Ror(Node* node) { |
1230 VisitRRO(this, kS390_RotRight64, node, OperandMode::kShift64Imm); | 1320 VisitWord64BinOp(this, node, kS390_RotRight64, Shift64OperandMode); |
1231 } | 1321 } |
1232 #endif | 1322 #endif |
1233 | 1323 |
1234 void InstructionSelector::VisitWord32Clz(Node* node) { | 1324 void InstructionSelector::VisitWord32Clz(Node* node) { |
1235 VisitRR(this, kS390_Cntlz32, node); | 1325 VisitRR(this, kS390_Cntlz32, node); |
1236 } | 1326 } |
1237 | 1327 |
1238 #if V8_TARGET_ARCH_S390X | 1328 #if V8_TARGET_ARCH_S390X |
1239 void InstructionSelector::VisitWord64Clz(Node* node) { | 1329 void InstructionSelector::VisitWord64Clz(Node* node) { |
1240 S390OperandGenerator g(this); | 1330 S390OperandGenerator g(this); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 Emit(kS390_LoadReverse32RR, g.DefineAsRegister(node), | 1383 Emit(kS390_LoadReverse32RR, g.DefineAsRegister(node), |
1294 g.UseRegister(node->InputAt(0))); | 1384 g.UseRegister(node->InputAt(0))); |
1295 } | 1385 } |
1296 | 1386 |
1297 void InstructionSelector::VisitInt32Add(Node* node) { | 1387 void InstructionSelector::VisitInt32Add(Node* node) { |
1298 VisitBin32op(this, node, kS390_Add32, AddOperandMode); | 1388 VisitBin32op(this, node, kS390_Add32, AddOperandMode); |
1299 } | 1389 } |
1300 | 1390 |
1301 #if V8_TARGET_ARCH_S390X | 1391 #if V8_TARGET_ARCH_S390X |
1302 void InstructionSelector::VisitInt64Add(Node* node) { | 1392 void InstructionSelector::VisitInt64Add(Node* node) { |
1303 VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, | 1393 VisitWord64BinOp(this, node, kS390_Add64, AddOperandMode); |
1304 OperandMode::kInt32Imm); | |
1305 } | 1394 } |
1306 #endif | 1395 #endif |
1307 | 1396 |
1308 void InstructionSelector::VisitInt32Sub(Node* node) { | 1397 void InstructionSelector::VisitInt32Sub(Node* node) { |
1309 S390OperandGenerator g(this); | 1398 S390OperandGenerator g(this); |
1310 Int32BinopMatcher m(node); | 1399 Int32BinopMatcher m(node); |
1311 if (m.left().Is(0)) { | 1400 if (m.left().Is(0)) { |
1312 Node* right = m.right().node(); | 1401 Node* right = m.right().node(); |
1313 bool doZeroExt = ZeroExtendsWord32ToWord64(right); | 1402 bool doZeroExt = ZeroExtendsWord32ToWord64(right); |
1314 Emit(kS390_Neg32, g.DefineAsRegister(node), g.UseRegister(right), | 1403 Emit(kS390_Neg32, g.DefineAsRegister(node), g.UseRegister(right), |
1315 g.TempImmediate(doZeroExt)); | 1404 g.TempImmediate(doZeroExt)); |
1316 } else { | 1405 } else { |
1317 VisitBin32op(this, node, kS390_Sub32, SubOperandMode); | 1406 VisitBin32op(this, node, kS390_Sub32, SubOperandMode); |
1318 } | 1407 } |
1319 } | 1408 } |
1320 | 1409 |
1321 #if V8_TARGET_ARCH_S390X | 1410 #if V8_TARGET_ARCH_S390X |
1322 void InstructionSelector::VisitInt64Sub(Node* node) { | 1411 void InstructionSelector::VisitInt64Sub(Node* node) { |
1323 S390OperandGenerator g(this); | 1412 S390OperandGenerator g(this); |
1324 Int64BinopMatcher m(node); | 1413 Int64BinopMatcher m(node); |
1325 if (m.left().Is(0)) { | 1414 if (m.left().Is(0)) { |
1326 Emit(kS390_Neg64, g.DefineAsRegister(node), | 1415 Emit(kS390_Neg64, g.DefineAsRegister(node), |
1327 g.UseRegister(m.right().node())); | 1416 g.UseRegister(m.right().node())); |
1328 } else { | 1417 } else { |
1329 VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64, | 1418 VisitWord64BinOp(this, node, kS390_Sub64, SubOperandMode); |
1330 OperandMode::kInt32Imm_Negate); | |
1331 } | 1419 } |
1332 } | 1420 } |
1333 #endif | 1421 #endif |
1334 | 1422 |
1335 namespace { | |
1336 | |
1337 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, | |
1338 InstructionOperand left, InstructionOperand right, | |
1339 FlagsContinuation* cont); | |
1340 | |
1341 #if V8_TARGET_ARCH_S390X | |
1342 void VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) { | |
1343 S390OperandGenerator g(selector); | |
1344 Int32BinopMatcher m(node); | |
1345 Node* left = m.left().node(); | |
1346 Node* right = m.right().node(); | |
1347 if (g.CanBeImmediate(right, OperandMode::kInt32Imm)) { | |
1348 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | |
1349 g.UseImmediate(right)); | |
1350 } else { | |
1351 if (g.CanBeBetterLeftOperand(right)) { | |
1352 std::swap(left, right); | |
1353 } | |
1354 selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left), | |
1355 g.Use(right)); | |
1356 } | |
1357 } | |
1358 #endif | |
1359 | |
1360 } // namespace | |
1361 | |
1362 void InstructionSelector::VisitInt32MulWithOverflow(Node* node) { | 1423 void InstructionSelector::VisitInt32MulWithOverflow(Node* node) { |
1363 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1424 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
1364 FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf); | 1425 FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf); |
1365 return VisitBin32op(this, node, kS390_Mul32WithOverflow, | 1426 return VisitBin32op(this, node, kS390_Mul32WithOverflow, |
1366 OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps, | 1427 OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps, |
1367 &cont); | 1428 &cont); |
1368 } | 1429 } |
1369 VisitBin32op(this, node, kS390_Mul32, MulOperandMode); | 1430 VisitBin32op(this, node, kS390_Mul32, MulOperandMode); |
1370 } | 1431 } |
1371 | 1432 |
(...skipping 24 matching lines...) Expand all Loading... |
1396 Int64BinopMatcher m(node); | 1457 Int64BinopMatcher m(node); |
1397 Node* left = m.left().node(); | 1458 Node* left = m.left().node(); |
1398 Node* right = m.right().node(); | 1459 Node* right = m.right().node(); |
1399 if (g.CanBeImmediate(right, OperandMode::kInt32Imm) && | 1460 if (g.CanBeImmediate(right, OperandMode::kInt32Imm) && |
1400 base::bits::IsPowerOfTwo64(g.GetImmediate(right))) { | 1461 base::bits::IsPowerOfTwo64(g.GetImmediate(right))) { |
1401 int power = 63 - base::bits::CountLeadingZeros64(g.GetImmediate(right)); | 1462 int power = 63 - base::bits::CountLeadingZeros64(g.GetImmediate(right)); |
1402 Emit(kS390_ShiftLeft64, g.DefineSameAsFirst(node), g.UseRegister(left), | 1463 Emit(kS390_ShiftLeft64, g.DefineSameAsFirst(node), g.UseRegister(left), |
1403 g.UseImmediate(power)); | 1464 g.UseImmediate(power)); |
1404 return; | 1465 return; |
1405 } | 1466 } |
1406 VisitMul(this, node, kS390_Mul64); | 1467 VisitWord64BinOp(this, node, kS390_Mul64, MulOperandMode); |
1407 } | 1468 } |
1408 #endif | 1469 #endif |
1409 | 1470 |
1410 void InstructionSelector::VisitInt32MulHigh(Node* node) { | 1471 void InstructionSelector::VisitInt32MulHigh(Node* node) { |
1411 VisitBin32op(this, node, kS390_MulHigh32, | 1472 VisitBin32op(this, node, kS390_MulHigh32, |
1412 OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps); | 1473 OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps); |
1413 } | 1474 } |
1414 | 1475 |
1415 void InstructionSelector::VisitUint32MulHigh(Node* node) { | 1476 void InstructionSelector::VisitUint32MulHigh(Node* node) { |
1416 VisitBin32op(this, node, kS390_MulHighU32, | 1477 VisitBin32op(this, node, kS390_MulHighU32, |
1417 OperandMode::kAllowRRM | OperandMode::kAllowRRR); | 1478 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1418 } | 1479 } |
1419 | 1480 |
1420 void InstructionSelector::VisitInt32Div(Node* node) { | 1481 void InstructionSelector::VisitInt32Div(Node* node) { |
1421 VisitBin32op(this, node, kS390_Div32, | 1482 VisitBin32op(this, node, kS390_Div32, |
1422 OperandMode::kAllowRRM | OperandMode::kAllowRRR); | 1483 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1423 } | 1484 } |
1424 | 1485 |
1425 #if V8_TARGET_ARCH_S390X | 1486 #if V8_TARGET_ARCH_S390X |
1426 void InstructionSelector::VisitInt64Div(Node* node) { | 1487 void InstructionSelector::VisitInt64Div(Node* node) { |
1427 VisitRRR(this, kS390_Div64, node); | 1488 VisitWord64BinOp(this, node, kS390_Div64, |
| 1489 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1428 } | 1490 } |
1429 #endif | 1491 #endif |
1430 | 1492 |
1431 void InstructionSelector::VisitUint32Div(Node* node) { | 1493 void InstructionSelector::VisitUint32Div(Node* node) { |
1432 VisitBin32op(this, node, kS390_DivU32, | 1494 VisitBin32op(this, node, kS390_DivU32, |
1433 OperandMode::kAllowRRM | OperandMode::kAllowRRR); | 1495 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1434 } | 1496 } |
1435 | 1497 |
1436 #if V8_TARGET_ARCH_S390X | 1498 #if V8_TARGET_ARCH_S390X |
1437 void InstructionSelector::VisitUint64Div(Node* node) { | 1499 void InstructionSelector::VisitUint64Div(Node* node) { |
1438 VisitRRR(this, kS390_DivU64, node); | 1500 VisitWord64BinOp(this, node, kS390_DivU64, |
| 1501 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1439 } | 1502 } |
1440 #endif | 1503 #endif |
1441 | 1504 |
1442 void InstructionSelector::VisitInt32Mod(Node* node) { | 1505 void InstructionSelector::VisitInt32Mod(Node* node) { |
1443 VisitBin32op(this, node, kS390_Mod32, | 1506 VisitBin32op(this, node, kS390_Mod32, |
1444 OperandMode::kAllowRRM | OperandMode::kAllowRRR); | 1507 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1445 } | 1508 } |
1446 | 1509 |
1447 #if V8_TARGET_ARCH_S390X | 1510 #if V8_TARGET_ARCH_S390X |
1448 void InstructionSelector::VisitInt64Mod(Node* node) { | 1511 void InstructionSelector::VisitInt64Mod(Node* node) { |
1449 VisitRRR(this, kS390_Mod64, node); | 1512 VisitWord64BinOp(this, node, kS390_Mod64, |
| 1513 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1450 } | 1514 } |
1451 #endif | 1515 #endif |
1452 | 1516 |
1453 void InstructionSelector::VisitUint32Mod(Node* node) { | 1517 void InstructionSelector::VisitUint32Mod(Node* node) { |
1454 VisitBin32op(this, node, kS390_ModU32, | 1518 VisitBin32op(this, node, kS390_ModU32, |
1455 OperandMode::kAllowRRM | OperandMode::kAllowRRR); | 1519 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1456 } | 1520 } |
1457 | 1521 |
1458 #if V8_TARGET_ARCH_S390X | 1522 #if V8_TARGET_ARCH_S390X |
1459 void InstructionSelector::VisitUint64Mod(Node* node) { | 1523 void InstructionSelector::VisitUint64Mod(Node* node) { |
1460 VisitRRR(this, kS390_ModU64, node); | 1524 VisitWord64BinOp(this, node, kS390_ModU64, |
| 1525 OperandMode::kAllowRRM | OperandMode::kAllowRRR); |
1461 } | 1526 } |
1462 #endif | 1527 #endif |
1463 | 1528 |
1464 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { | 1529 // TODO(john.yan): place kAllowRM where available |
1465 VisitRR(this, kS390_Float32ToDouble, node); | 1530 #define VISIT_FLOAT_UNARY_OP_LIST(V) \ |
1466 } | 1531 V(Float32, ChangeFloat32ToFloat64, kS390_Float32ToDouble, \ |
| 1532 OperandMode::kAllowRM) \ |
| 1533 V(Float32, BitcastFloat32ToInt32, kS390_BitcastFloat32ToInt32, \ |
| 1534 OperandMode::kNone) \ |
| 1535 V(Float64, TruncateFloat64ToFloat32, kS390_DoubleToFloat32, \ |
| 1536 OperandMode::kNone) \ |
| 1537 V(Float64, TruncateFloat64ToWord32, kArchTruncateDoubleToI, \ |
| 1538 OperandMode::kNone) \ |
| 1539 V(Float64, RoundFloat64ToInt32, kS390_DoubleToInt32, OperandMode::kNone) \ |
| 1540 V(Float32, TruncateFloat32ToInt32, kS390_Float32ToInt32, OperandMode::kNone) \ |
| 1541 V(Float32, TruncateFloat32ToUint32, kS390_Float32ToUint32, \ |
| 1542 OperandMode::kNone) \ |
| 1543 V(Float64, ChangeFloat64ToInt32, kS390_DoubleToInt32, OperandMode::kNone) \ |
| 1544 V(Float64, ChangeFloat64ToUint32, kS390_DoubleToUint32, OperandMode::kNone) \ |
| 1545 V(Float64, TruncateFloat64ToUint32, kS390_DoubleToUint32, \ |
| 1546 OperandMode::kNone) \ |
| 1547 V(Float64, Float64SilenceNaN, kS390_Float64SilenceNaN, OperandMode::kNone) \ |
| 1548 V(Float32, Float32Abs, kS390_AbsFloat, OperandMode::kNone) \ |
| 1549 V(Float64, Float64Abs, kS390_AbsDouble, OperandMode::kNone) \ |
| 1550 V(Float32, Float32Sqrt, kS390_SqrtFloat, OperandMode::kNone) \ |
| 1551 V(Float64, Float64Sqrt, kS390_SqrtDouble, OperandMode::kNone) \ |
| 1552 V(Float32, Float32RoundDown, kS390_FloorFloat, OperandMode::kNone) \ |
| 1553 V(Float64, Float64RoundDown, kS390_FloorDouble, OperandMode::kNone) \ |
| 1554 V(Float32, Float32RoundUp, kS390_CeilFloat, OperandMode::kNone) \ |
| 1555 V(Float64, Float64RoundUp, kS390_CeilDouble, OperandMode::kNone) \ |
| 1556 V(Float32, Float32RoundTruncate, kS390_TruncateFloat, OperandMode::kNone) \ |
| 1557 V(Float64, Float64RoundTruncate, kS390_TruncateDouble, OperandMode::kNone) \ |
| 1558 V(Float64, Float64RoundTiesAway, kS390_RoundDouble, OperandMode::kNone) \ |
| 1559 V(Float32, Float32Neg, kS390_NegFloat, OperandMode::kNone) \ |
| 1560 V(Float64, Float64Neg, kS390_NegDouble, OperandMode::kNone) |
| 1561 |
| 1562 #define VISIT_WORD64_UNARY_OP_LIST(V) \ |
| 1563 V(Word64, TruncateInt64ToInt32, kS390_Int64ToInt32, OperandMode::kNone) \ |
| 1564 V(Word64, RoundInt64ToFloat32, kS390_Int64ToFloat32, OperandMode::kNone) \ |
| 1565 V(Word64, RoundInt64ToFloat64, kS390_Int64ToDouble, OperandMode::kNone) \ |
| 1566 V(Word64, RoundUint64ToFloat32, kS390_Uint64ToFloat32, OperandMode::kNone) \ |
| 1567 V(Word64, RoundUint64ToFloat64, kS390_Uint64ToDouble, OperandMode::kNone) \ |
| 1568 V(Word64, BitcastInt64ToFloat64, kS390_BitcastInt64ToDouble, \ |
| 1569 OperandMode::kNone) \ |
| 1570 V(Float64, BitcastFloat64ToInt64, kS390_BitcastDoubleToInt64, \ |
| 1571 OperandMode::kNone) |
| 1572 |
| 1573 #define DECLARE_UNARY_OP(type, name, op, mode) \ |
| 1574 void InstructionSelector::Visit##name(Node* node) { \ |
| 1575 Visit##type##UnaryOp(this, node, op, mode); \ |
| 1576 } |
| 1577 |
| 1578 VISIT_FLOAT_UNARY_OP_LIST(DECLARE_UNARY_OP); |
| 1579 |
| 1580 #if V8_TARGET_ARCH_S390X |
| 1581 VISIT_WORD64_UNARY_OP_LIST(DECLARE_UNARY_OP) |
| 1582 #endif |
| 1583 |
| 1584 #undef DECLARE_UNARY_OP |
| 1585 #undef VISIT_WORD64_UNARY_OP_LIST |
| 1586 #undef VISIT_FLOAT_UNARY_OP_LIST |
1467 | 1587 |
1468 void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) { | 1588 void InstructionSelector::VisitRoundInt32ToFloat32(Node* node) { |
1469 VisitRR(this, kS390_Int32ToFloat32, node); | 1589 VisitRR(this, kS390_Int32ToFloat32, node); |
1470 } | 1590 } |
1471 | 1591 |
1472 void InstructionSelector::VisitRoundUint32ToFloat32(Node* node) { | 1592 void InstructionSelector::VisitRoundUint32ToFloat32(Node* node) { |
1473 VisitRR(this, kS390_Uint32ToFloat32, node); | 1593 VisitRR(this, kS390_Uint32ToFloat32, node); |
1474 } | 1594 } |
1475 | 1595 |
1476 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 1596 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
1477 VisitRR(this, kS390_Int32ToDouble, node); | 1597 VisitRR(this, kS390_Int32ToDouble, node); |
1478 } | 1598 } |
1479 | 1599 |
1480 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { | 1600 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
1481 VisitRR(this, kS390_Uint32ToDouble, node); | 1601 VisitRR(this, kS390_Uint32ToDouble, node); |
1482 } | 1602 } |
1483 | 1603 |
1484 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { | |
1485 VisitRR(this, kS390_DoubleToInt32, node); | |
1486 } | |
1487 | |
1488 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { | |
1489 VisitRR(this, kS390_DoubleToUint32, node); | |
1490 } | |
1491 | |
1492 void InstructionSelector::VisitTruncateFloat64ToUint32(Node* node) { | |
1493 VisitRR(this, kS390_DoubleToUint32, node); | |
1494 } | |
1495 | |
1496 #if V8_TARGET_ARCH_S390X | 1604 #if V8_TARGET_ARCH_S390X |
1497 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { | 1605 void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) { |
1498 VisitTryTruncateDouble(this, kS390_Float32ToInt64, node); | 1606 VisitTryTruncateDouble(this, kS390_Float32ToInt64, node); |
1499 } | 1607 } |
1500 | 1608 |
1501 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) { | 1609 void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) { |
1502 VisitTryTruncateDouble(this, kS390_DoubleToInt64, node); | 1610 VisitTryTruncateDouble(this, kS390_DoubleToInt64, node); |
1503 } | 1611 } |
1504 | 1612 |
1505 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) { | 1613 void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) { |
(...skipping 14 matching lines...) Expand all Loading... |
1520 Node* value = node->InputAt(0); | 1628 Node* value = node->InputAt(0); |
1521 if (ZeroExtendsWord32ToWord64(value)) { | 1629 if (ZeroExtendsWord32ToWord64(value)) { |
1522 // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the | 1630 // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the |
1523 // zero-extension is a no-op. | 1631 // zero-extension is a no-op. |
1524 return EmitIdentity(node); | 1632 return EmitIdentity(node); |
1525 } | 1633 } |
1526 VisitRR(this, kS390_Uint32ToUint64, node); | 1634 VisitRR(this, kS390_Uint32ToUint64, node); |
1527 } | 1635 } |
1528 #endif | 1636 #endif |
1529 | 1637 |
1530 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { | |
1531 VisitRR(this, kS390_DoubleToFloat32, node); | |
1532 } | |
1533 | |
1534 void InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) { | |
1535 VisitRR(this, kArchTruncateDoubleToI, node); | |
1536 } | |
1537 | |
1538 void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) { | |
1539 VisitRR(this, kS390_DoubleToInt32, node); | |
1540 } | |
1541 | |
1542 void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) { | |
1543 VisitRR(this, kS390_Float32ToInt32, node); | |
1544 } | |
1545 | |
1546 void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) { | |
1547 VisitRR(this, kS390_Float32ToUint32, node); | |
1548 } | |
1549 | |
1550 #if V8_TARGET_ARCH_S390X | |
1551 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | |
1552 // TODO(mbrandy): inspect input to see if nop is appropriate. | |
1553 VisitRR(this, kS390_Int64ToInt32, node); | |
1554 } | |
1555 | |
1556 void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) { | |
1557 VisitRR(this, kS390_Int64ToFloat32, node); | |
1558 } | |
1559 | |
1560 void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) { | |
1561 VisitRR(this, kS390_Int64ToDouble, node); | |
1562 } | |
1563 | |
1564 void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) { | |
1565 VisitRR(this, kS390_Uint64ToFloat32, node); | |
1566 } | |
1567 | |
1568 void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) { | |
1569 VisitRR(this, kS390_Uint64ToDouble, node); | |
1570 } | |
1571 #endif | |
1572 | |
1573 void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) { | |
1574 VisitRR(this, kS390_BitcastFloat32ToInt32, node); | |
1575 } | |
1576 | |
1577 #if V8_TARGET_ARCH_S390X | |
1578 void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) { | |
1579 VisitRR(this, kS390_BitcastDoubleToInt64, node); | |
1580 } | |
1581 #endif | |
1582 | |
1583 void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) { | 1638 void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) { |
1584 VisitRR(this, kS390_BitcastInt32ToFloat32, node); | 1639 VisitRR(this, kS390_BitcastInt32ToFloat32, node); |
1585 } | 1640 } |
1586 | 1641 |
1587 #if V8_TARGET_ARCH_S390X | |
1588 void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) { | |
1589 VisitRR(this, kS390_BitcastInt64ToDouble, node); | |
1590 } | |
1591 #endif | |
1592 | |
1593 void InstructionSelector::VisitFloat32Add(Node* node) { | 1642 void InstructionSelector::VisitFloat32Add(Node* node) { |
1594 VisitRRR(this, kS390_AddFloat, node); | 1643 return VisitFloat32BinOp(this, node, kS390_AddFloat, OperandMode::kAllowRM); |
1595 } | 1644 } |
1596 | 1645 |
1597 void InstructionSelector::VisitFloat64Add(Node* node) { | 1646 void InstructionSelector::VisitFloat64Add(Node* node) { |
1598 // TODO(mbrandy): detect multiply-add | 1647 // TODO(mbrandy): detect multiply-add |
1599 VisitRRR(this, kS390_AddDouble, node); | 1648 return VisitFloat64BinOp(this, node, kS390_AddDouble, OperandMode::kAllowRM); |
1600 } | 1649 } |
1601 | 1650 |
1602 void InstructionSelector::VisitFloat32Sub(Node* node) { | 1651 void InstructionSelector::VisitFloat32Sub(Node* node) { |
1603 VisitRRR(this, kS390_SubFloat, node); | 1652 return VisitFloat32BinOp(this, node, kS390_SubFloat, OperandMode::kAllowRM); |
1604 } | 1653 } |
1605 | 1654 |
1606 void InstructionSelector::VisitFloat64Sub(Node* node) { | 1655 void InstructionSelector::VisitFloat64Sub(Node* node) { |
1607 // TODO(mbrandy): detect multiply-subtract | 1656 // TODO(mbrandy): detect multiply-subtract |
1608 VisitRRR(this, kS390_SubDouble, node); | 1657 return VisitFloat64BinOp(this, node, kS390_SubDouble, OperandMode::kAllowRM); |
1609 } | 1658 } |
1610 | 1659 |
1611 void InstructionSelector::VisitFloat32Mul(Node* node) { | 1660 void InstructionSelector::VisitFloat32Mul(Node* node) { |
1612 VisitRRR(this, kS390_MulFloat, node); | 1661 return VisitFloat32BinOp(this, node, kS390_MulFloat, OperandMode::kAllowRM); |
1613 } | 1662 } |
1614 | 1663 |
1615 void InstructionSelector::VisitFloat64Mul(Node* node) { | 1664 void InstructionSelector::VisitFloat64Mul(Node* node) { |
1616 // TODO(mbrandy): detect negate | 1665 // TODO(mbrandy): detect negate |
1617 VisitRRR(this, kS390_MulDouble, node); | 1666 return VisitFloat64BinOp(this, node, kS390_MulDouble, OperandMode::kAllowRM); |
1618 } | 1667 } |
1619 | 1668 |
1620 void InstructionSelector::VisitFloat32Div(Node* node) { | 1669 void InstructionSelector::VisitFloat32Div(Node* node) { |
1621 VisitRRR(this, kS390_DivFloat, node); | 1670 return VisitFloat32BinOp(this, node, kS390_DivFloat, OperandMode::kAllowRM); |
1622 } | 1671 } |
1623 | 1672 |
1624 void InstructionSelector::VisitFloat64Div(Node* node) { | 1673 void InstructionSelector::VisitFloat64Div(Node* node) { |
1625 VisitRRR(this, kS390_DivDouble, node); | 1674 return VisitFloat64BinOp(this, node, kS390_DivDouble, OperandMode::kAllowRM); |
1626 } | 1675 } |
1627 | 1676 |
1628 void InstructionSelector::VisitFloat64Mod(Node* node) { | 1677 void InstructionSelector::VisitFloat64Mod(Node* node) { |
1629 S390OperandGenerator g(this); | 1678 S390OperandGenerator g(this); |
1630 Emit(kS390_ModDouble, g.DefineAsFixed(node, d1), | 1679 Emit(kS390_ModDouble, g.DefineAsFixed(node, d1), |
1631 g.UseFixed(node->InputAt(0), d1), g.UseFixed(node->InputAt(1), d2)) | 1680 g.UseFixed(node->InputAt(0), d1), g.UseFixed(node->InputAt(1), d2)) |
1632 ->MarkAsCall(); | 1681 ->MarkAsCall(); |
1633 } | 1682 } |
1634 | 1683 |
1635 void InstructionSelector::VisitFloat32Max(Node* node) { | 1684 void InstructionSelector::VisitFloat32Max(Node* node) { |
1636 VisitRRR(this, kS390_MaxFloat, node); | 1685 return VisitFloat32BinOp(this, node, kS390_MaxFloat, OperandMode::kNone); |
1637 } | 1686 } |
1638 | 1687 |
1639 void InstructionSelector::VisitFloat64Max(Node* node) { | 1688 void InstructionSelector::VisitFloat64Max(Node* node) { |
1640 VisitRRR(this, kS390_MaxDouble, node); | 1689 return VisitFloat64BinOp(this, node, kS390_MaxDouble, OperandMode::kNone); |
1641 } | |
1642 | |
1643 void InstructionSelector::VisitFloat64SilenceNaN(Node* node) { | |
1644 VisitRR(this, kS390_Float64SilenceNaN, node); | |
1645 } | 1690 } |
1646 | 1691 |
1647 void InstructionSelector::VisitFloat32Min(Node* node) { | 1692 void InstructionSelector::VisitFloat32Min(Node* node) { |
1648 VisitRRR(this, kS390_MinFloat, node); | 1693 return VisitFloat32BinOp(this, node, kS390_MinFloat, OperandMode::kNone); |
1649 } | 1694 } |
1650 | 1695 |
1651 void InstructionSelector::VisitFloat64Min(Node* node) { | 1696 void InstructionSelector::VisitFloat64Min(Node* node) { |
1652 VisitRRR(this, kS390_MinDouble, node); | 1697 return VisitFloat64BinOp(this, node, kS390_MinDouble, OperandMode::kNone); |
1653 } | |
1654 | |
1655 void InstructionSelector::VisitFloat32Abs(Node* node) { | |
1656 VisitRR(this, kS390_AbsFloat, node); | |
1657 } | |
1658 | |
1659 void InstructionSelector::VisitFloat64Abs(Node* node) { | |
1660 VisitRR(this, kS390_AbsDouble, node); | |
1661 } | |
1662 | |
1663 void InstructionSelector::VisitFloat32Sqrt(Node* node) { | |
1664 VisitRR(this, kS390_SqrtFloat, node); | |
1665 } | 1698 } |
1666 | 1699 |
1667 void InstructionSelector::VisitFloat64Ieee754Unop(Node* node, | 1700 void InstructionSelector::VisitFloat64Ieee754Unop(Node* node, |
1668 InstructionCode opcode) { | 1701 InstructionCode opcode) { |
1669 S390OperandGenerator g(this); | 1702 S390OperandGenerator g(this); |
1670 Emit(opcode, g.DefineAsFixed(node, d1), g.UseFixed(node->InputAt(0), d1)) | 1703 Emit(opcode, g.DefineAsFixed(node, d1), g.UseFixed(node->InputAt(0), d1)) |
1671 ->MarkAsCall(); | 1704 ->MarkAsCall(); |
1672 } | 1705 } |
1673 | 1706 |
1674 void InstructionSelector::VisitFloat64Ieee754Binop(Node* node, | 1707 void InstructionSelector::VisitFloat64Ieee754Binop(Node* node, |
1675 InstructionCode opcode) { | 1708 InstructionCode opcode) { |
1676 S390OperandGenerator g(this); | 1709 S390OperandGenerator g(this); |
1677 Emit(opcode, g.DefineAsFixed(node, d1), g.UseFixed(node->InputAt(0), d1), | 1710 Emit(opcode, g.DefineAsFixed(node, d1), g.UseFixed(node->InputAt(0), d1), |
1678 g.UseFixed(node->InputAt(1), d2)) | 1711 g.UseFixed(node->InputAt(1), d2)) |
1679 ->MarkAsCall(); | 1712 ->MarkAsCall(); |
1680 } | 1713 } |
1681 | 1714 |
1682 void InstructionSelector::VisitFloat64Sqrt(Node* node) { | |
1683 VisitRR(this, kS390_SqrtDouble, node); | |
1684 } | |
1685 | |
1686 void InstructionSelector::VisitFloat32RoundDown(Node* node) { | |
1687 VisitRR(this, kS390_FloorFloat, node); | |
1688 } | |
1689 | |
1690 void InstructionSelector::VisitFloat64RoundDown(Node* node) { | |
1691 VisitRR(this, kS390_FloorDouble, node); | |
1692 } | |
1693 | |
1694 void InstructionSelector::VisitFloat32RoundUp(Node* node) { | |
1695 VisitRR(this, kS390_CeilFloat, node); | |
1696 } | |
1697 | |
1698 void InstructionSelector::VisitFloat64RoundUp(Node* node) { | |
1699 VisitRR(this, kS390_CeilDouble, node); | |
1700 } | |
1701 | |
1702 void InstructionSelector::VisitFloat32RoundTruncate(Node* node) { | |
1703 VisitRR(this, kS390_TruncateFloat, node); | |
1704 } | |
1705 | |
1706 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) { | |
1707 VisitRR(this, kS390_TruncateDouble, node); | |
1708 } | |
1709 | |
1710 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) { | |
1711 VisitRR(this, kS390_RoundDouble, node); | |
1712 } | |
1713 | |
1714 void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) { | 1715 void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) { |
1715 UNREACHABLE(); | 1716 UNREACHABLE(); |
1716 } | 1717 } |
1717 | 1718 |
1718 void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) { | 1719 void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) { |
1719 UNREACHABLE(); | 1720 UNREACHABLE(); |
1720 } | 1721 } |
1721 | 1722 |
1722 void InstructionSelector::VisitFloat32Neg(Node* node) { | |
1723 VisitRR(this, kS390_NegFloat, node); | |
1724 } | |
1725 | |
1726 void InstructionSelector::VisitFloat64Neg(Node* node) { | |
1727 VisitRR(this, kS390_NegDouble, node); | |
1728 } | |
1729 | |
1730 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { | 1723 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
1731 OperandModes mode = AddOperandMode; | 1724 OperandModes mode = AddOperandMode; |
1732 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1725 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
1733 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 1726 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
1734 return VisitBin32op(this, node, kS390_Add32, mode, &cont); | 1727 return VisitBin32op(this, node, kS390_Add32, mode, &cont); |
1735 } | 1728 } |
1736 FlagsContinuation cont; | 1729 FlagsContinuation cont; |
1737 VisitBin32op(this, node, kS390_Add32, mode, &cont); | 1730 VisitBin32op(this, node, kS390_Add32, mode, &cont); |
1738 } | 1731 } |
1739 | 1732 |
1740 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { | 1733 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
1741 OperandModes mode = SubOperandMode; | 1734 OperandModes mode = SubOperandMode; |
1742 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1735 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
1743 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 1736 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
1744 return VisitBin32op(this, node, kS390_Sub32, mode, &cont); | 1737 return VisitBin32op(this, node, kS390_Sub32, mode, &cont); |
1745 } | 1738 } |
1746 FlagsContinuation cont; | 1739 FlagsContinuation cont; |
1747 VisitBin32op(this, node, kS390_Sub32, mode, &cont); | 1740 VisitBin32op(this, node, kS390_Sub32, mode, &cont); |
1748 } | 1741 } |
1749 | 1742 |
1750 #if V8_TARGET_ARCH_S390X | 1743 #if V8_TARGET_ARCH_S390X |
1751 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { | 1744 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { |
1752 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1745 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
1753 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 1746 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
1754 return VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, | 1747 return VisitWord64BinOp(this, node, kS390_Add64, AddOperandMode, &cont); |
1755 OperandMode::kInt32Imm, &cont); | |
1756 } | 1748 } |
1757 FlagsContinuation cont; | 1749 VisitWord64BinOp(this, node, kS390_Add64, AddOperandMode); |
1758 VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, OperandMode::kInt32Imm, | |
1759 &cont); | |
1760 } | 1750 } |
1761 | 1751 |
1762 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { | 1752 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { |
1763 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { | 1753 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
1764 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); | 1754 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
1765 return VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64, | 1755 return VisitWord64BinOp(this, node, kS390_Sub64, SubOperandMode, &cont); |
1766 OperandMode::kInt32Imm_Negate, &cont); | |
1767 } | 1756 } |
1768 FlagsContinuation cont; | 1757 VisitWord64BinOp(this, node, kS390_Sub64, SubOperandMode); |
1769 VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64, | |
1770 OperandMode::kInt32Imm_Negate, &cont); | |
1771 } | 1758 } |
1772 #endif | 1759 #endif |
1773 | 1760 |
1774 static bool CompareLogical(FlagsContinuation* cont) { | 1761 static bool CompareLogical(FlagsContinuation* cont) { |
1775 switch (cont->condition()) { | 1762 switch (cont->condition()) { |
1776 case kUnsignedLessThan: | 1763 case kUnsignedLessThan: |
1777 case kUnsignedGreaterThanOrEqual: | 1764 case kUnsignedGreaterThanOrEqual: |
1778 case kUnsignedLessThanOrEqual: | 1765 case kUnsignedLessThanOrEqual: |
1779 case kUnsignedGreaterThan: | 1766 case kUnsignedGreaterThan: |
1780 return true; | 1767 return true; |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2122 cont); | 2109 cont); |
2123 case IrOpcode::kInt32MulWithOverflow: | 2110 case IrOpcode::kInt32MulWithOverflow: |
2124 cont->OverwriteAndNegateIfEqual(kNotEqual); | 2111 cont->OverwriteAndNegateIfEqual(kNotEqual); |
2125 return VisitBin32op( | 2112 return VisitBin32op( |
2126 selector, node, kS390_Mul32WithOverflow, | 2113 selector, node, kS390_Mul32WithOverflow, |
2127 OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps, | 2114 OperandMode::kInt32Imm | OperandMode::kAllowDistinctOps, |
2128 cont); | 2115 cont); |
2129 #if V8_TARGET_ARCH_S390X | 2116 #if V8_TARGET_ARCH_S390X |
2130 case IrOpcode::kInt64AddWithOverflow: | 2117 case IrOpcode::kInt64AddWithOverflow: |
2131 cont->OverwriteAndNegateIfEqual(kOverflow); | 2118 cont->OverwriteAndNegateIfEqual(kOverflow); |
2132 return VisitBinop<Int64BinopMatcher>( | 2119 return VisitWord64BinOp(selector, node, kS390_Add64, |
2133 selector, node, kS390_Add64, OperandMode::kInt32Imm, cont); | 2120 AddOperandMode, cont); |
2134 case IrOpcode::kInt64SubWithOverflow: | 2121 case IrOpcode::kInt64SubWithOverflow: |
2135 cont->OverwriteAndNegateIfEqual(kOverflow); | 2122 cont->OverwriteAndNegateIfEqual(kOverflow); |
2136 return VisitBinop<Int64BinopMatcher>( | 2123 return VisitWord64BinOp(selector, node, kS390_Sub64, |
2137 selector, node, kS390_Sub64, OperandMode::kInt32Imm_Negate, | 2124 SubOperandMode, cont); |
2138 cont); | |
2139 #endif | 2125 #endif |
2140 default: | 2126 default: |
2141 break; | 2127 break; |
2142 } | 2128 } |
2143 } | 2129 } |
2144 } | 2130 } |
2145 break; | 2131 break; |
2146 case IrOpcode::kInt32Sub: | 2132 case IrOpcode::kInt32Sub: |
2147 if (fc == kNotEqual || fc == kEqual) | 2133 if (fc == kNotEqual || fc == kEqual) |
2148 return VisitWord32Compare(selector, value, cont); | 2134 return VisitWord32Compare(selector, value, cont); |
2149 break; | 2135 break; |
2150 case IrOpcode::kWord32And: | 2136 case IrOpcode::kWord32And: |
2151 return VisitTestUnderMask(selector, value, cont); | 2137 return VisitTestUnderMask(selector, value, cont); |
2152 case IrOpcode::kLoad: { | 2138 case IrOpcode::kLoad: { |
2153 LoadRepresentation load_rep = LoadRepresentationOf(value->op()); | 2139 LoadRepresentation load_rep = LoadRepresentationOf(value->op()); |
2154 switch (load_rep.representation()) { | 2140 switch (load_rep.representation()) { |
2155 case MachineRepresentation::kWord32: | 2141 case MachineRepresentation::kWord32: |
2156 if (opcode == kS390_LoadAndTestWord32) { | 2142 if (opcode == kS390_LoadAndTestWord32) { |
2157 return VisitLoadAndTest(selector, opcode, user, value, cont); | 2143 return VisitLoadAndTest(selector, opcode, user, value, cont); |
2158 } | 2144 } |
2159 default: | 2145 default: |
2160 break; | 2146 break; |
2161 } | 2147 } |
2162 break; | 2148 break; |
2163 } | 2149 } |
2164 case IrOpcode::kInt32Add: | 2150 case IrOpcode::kInt32Add: |
2165 // can't handle overflow case. | 2151 // can't handle overflow case. |
2166 break; | 2152 break; |
2167 case IrOpcode::kWord32Or: | 2153 case IrOpcode::kWord32Or: |
2168 return VisitBin32op(selector, value, kS390_Or32, OrOperandMode, cont); | 2154 if (fc == kNotEqual || fc == kEqual) |
| 2155 return VisitBin32op(selector, value, kS390_Or32, Or32OperandMode, |
| 2156 cont); |
| 2157 break; |
2169 case IrOpcode::kWord32Xor: | 2158 case IrOpcode::kWord32Xor: |
2170 return VisitBin32op(selector, value, kS390_Xor32, XorOperandMode, cont); | 2159 if (fc == kNotEqual || fc == kEqual) |
| 2160 return VisitBin32op(selector, value, kS390_Xor32, Xor32OperandMode, |
| 2161 cont); |
| 2162 break; |
2171 case IrOpcode::kWord32Sar: | 2163 case IrOpcode::kWord32Sar: |
2172 case IrOpcode::kWord32Shl: | 2164 case IrOpcode::kWord32Shl: |
2173 case IrOpcode::kWord32Shr: | 2165 case IrOpcode::kWord32Shr: |
2174 case IrOpcode::kWord32Ror: | 2166 case IrOpcode::kWord32Ror: |
2175 // doesn't generate cc, so ignore. | 2167 // doesn't generate cc, so ignore. |
2176 break; | 2168 break; |
2177 #if V8_TARGET_ARCH_S390X | 2169 #if V8_TARGET_ARCH_S390X |
2178 case IrOpcode::kInt64Sub: | 2170 case IrOpcode::kInt64Sub: |
2179 if (fc == kNotEqual || fc == kEqual) | 2171 if (fc == kNotEqual || fc == kEqual) |
2180 return VisitWord64Compare(selector, value, cont); | 2172 return VisitWord64Compare(selector, value, cont); |
2181 break; | 2173 break; |
2182 case IrOpcode::kWord64And: | 2174 case IrOpcode::kWord64And: |
2183 return VisitTestUnderMask(selector, value, cont); | 2175 return VisitTestUnderMask(selector, value, cont); |
2184 case IrOpcode::kInt64Add: | 2176 case IrOpcode::kInt64Add: |
2185 // can't handle overflow case. | 2177 // can't handle overflow case. |
2186 break; | 2178 break; |
2187 case IrOpcode::kWord64Or: | 2179 case IrOpcode::kWord64Or: |
2188 // TODO(john.yan): need to handle | 2180 if (fc == kNotEqual || fc == kEqual) |
| 2181 return VisitWord64BinOp(selector, value, kS390_Or64, Or64OperandMode, |
| 2182 cont); |
2189 break; | 2183 break; |
2190 case IrOpcode::kWord64Xor: | 2184 case IrOpcode::kWord64Xor: |
2191 // TODO(john.yan): need to handle | 2185 if (fc == kNotEqual || fc == kEqual) |
| 2186 return VisitWord64BinOp(selector, value, kS390_Xor64, |
| 2187 Xor64OperandMode, cont); |
2192 break; | 2188 break; |
2193 case IrOpcode::kWord64Sar: | 2189 case IrOpcode::kWord64Sar: |
2194 case IrOpcode::kWord64Shl: | 2190 case IrOpcode::kWord64Shl: |
2195 case IrOpcode::kWord64Shr: | 2191 case IrOpcode::kWord64Shr: |
2196 case IrOpcode::kWord64Ror: | 2192 case IrOpcode::kWord64Ror: |
2197 // doesn't generate cc, so ignore | 2193 // doesn't generate cc, so ignore |
2198 break; | 2194 break; |
2199 #endif | 2195 #endif |
2200 default: | 2196 default: |
2201 break; | 2197 break; |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 // static | 2536 // static |
2541 MachineOperatorBuilder::AlignmentRequirements | 2537 MachineOperatorBuilder::AlignmentRequirements |
2542 InstructionSelector::AlignmentRequirements() { | 2538 InstructionSelector::AlignmentRequirements() { |
2543 return MachineOperatorBuilder::AlignmentRequirements:: | 2539 return MachineOperatorBuilder::AlignmentRequirements:: |
2544 FullUnalignedAccessSupport(); | 2540 FullUnalignedAccessSupport(); |
2545 } | 2541 } |
2546 | 2542 |
2547 } // namespace compiler | 2543 } // namespace compiler |
2548 } // namespace internal | 2544 } // namespace internal |
2549 } // namespace v8 | 2545 } // namespace v8 |
OLD | NEW |