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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 case MachineRepresentation::kNone: | 415 case MachineRepresentation::kNone: |
416 UNREACHABLE(); | 416 UNREACHABLE(); |
417 return; | 417 return; |
418 } | 418 } |
419 AddressingMode addressingMode = kMode_MRR; | 419 AddressingMode addressingMode = kMode_MRR; |
420 Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(), | 420 Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(), |
421 g.UseRegister(base), g.UseRegister(offset), | 421 g.UseRegister(base), g.UseRegister(offset), |
422 g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value)); | 422 g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value)); |
423 } | 423 } |
424 | 424 |
425 template <typename Matcher> | |
426 static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m, | |
427 ArchOpcode opcode, bool left_can_cover, | |
428 bool right_can_cover, ImmediateMode imm_mode) { | |
429 S390OperandGenerator g(selector); | |
430 | |
431 // Map instruction to equivalent operation with inverted right input. | |
432 ArchOpcode inv_opcode = opcode; | |
433 switch (opcode) { | |
434 case kS390_And: | |
435 inv_opcode = kS390_AndComplement; | |
436 break; | |
437 case kS390_Or: | |
438 inv_opcode = kS390_OrComplement; | |
439 break; | |
440 default: | |
441 UNREACHABLE(); | |
442 } | |
443 | |
444 // Select Logical(y, ~x) for Logical(Xor(x, -1), y). | |
445 if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) { | |
446 Matcher mleft(m->left().node()); | |
447 if (mleft.right().Is(-1)) { | |
448 selector->Emit(inv_opcode, g.DefineAsRegister(node), | |
449 g.UseRegister(m->right().node()), | |
450 g.UseRegister(mleft.left().node())); | |
451 return; | |
452 } | |
453 } | |
454 | |
455 // Select Logical(x, ~y) for Logical(x, Xor(y, -1)). | |
456 if ((m->right().IsWord32Xor() || m->right().IsWord64Xor()) && | |
457 right_can_cover) { | |
458 Matcher mright(m->right().node()); | |
459 if (mright.right().Is(-1)) { | |
460 // TODO(all): support shifted operand on right. | |
461 selector->Emit(inv_opcode, g.DefineAsRegister(node), | |
462 g.UseRegister(m->left().node()), | |
463 g.UseRegister(mright.left().node())); | |
464 return; | |
465 } | |
466 } | |
467 | |
468 VisitBinop<Matcher>(selector, node, opcode, imm_mode); | |
469 } | |
470 | |
471 static inline bool IsContiguousMask32(uint32_t value, int* mb, int* me) { | 425 static inline bool IsContiguousMask32(uint32_t value, int* mb, int* me) { |
472 int mask_width = base::bits::CountPopulation32(value); | 426 int mask_width = base::bits::CountPopulation32(value); |
473 int mask_msb = base::bits::CountLeadingZeros32(value); | 427 int mask_msb = base::bits::CountLeadingZeros32(value); |
474 int mask_lsb = base::bits::CountTrailingZeros32(value); | 428 int mask_lsb = base::bits::CountTrailingZeros32(value); |
475 if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 32)) | 429 if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 32)) |
476 return false; | 430 return false; |
477 *mb = mask_lsb + mask_width - 1; | 431 *mb = mask_lsb + mask_width - 1; |
478 *me = mask_lsb; | 432 *me = mask_lsb; |
479 return true; | 433 return true; |
480 } | 434 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 } | 470 } |
517 } | 471 } |
518 } | 472 } |
519 if (mb >= me) { | 473 if (mb >= me) { |
520 Emit(kS390_RotLeftAndMask32, g.DefineAsRegister(node), | 474 Emit(kS390_RotLeftAndMask32, g.DefineAsRegister(node), |
521 g.UseRegister(left), g.TempImmediate(sh), g.TempImmediate(mb), | 475 g.UseRegister(left), g.TempImmediate(sh), g.TempImmediate(mb), |
522 g.TempImmediate(me)); | 476 g.TempImmediate(me)); |
523 return; | 477 return; |
524 } | 478 } |
525 } | 479 } |
526 VisitLogical<Int32BinopMatcher>( | 480 VisitBinop<Int32BinopMatcher>(this, node, kS390_And, kInt16Imm_Unsigned); |
527 this, node, &m, kS390_And, CanCover(node, m.left().node()), | |
528 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | |
529 } | 481 } |
530 | 482 |
531 #if V8_TARGET_ARCH_S390X | 483 #if V8_TARGET_ARCH_S390X |
532 void InstructionSelector::VisitWord64And(Node* node) { | 484 void InstructionSelector::VisitWord64And(Node* node) { |
533 S390OperandGenerator g(this); | 485 S390OperandGenerator g(this); |
534 Int64BinopMatcher m(node); | 486 Int64BinopMatcher m(node); |
535 int mb = 0; | 487 int mb = 0; |
536 int me = 0; | 488 int me = 0; |
537 if (m.right().HasValue() && IsContiguousMask64(m.right().Value(), &mb, &me)) { | 489 if (m.right().HasValue() && IsContiguousMask64(m.right().Value(), &mb, &me)) { |
538 int sh = 0; | 490 int sh = 0; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 opcode = kS390_RotLeftAndClear64; | 522 opcode = kS390_RotLeftAndClear64; |
571 mask = mb; | 523 mask = mb; |
572 } | 524 } |
573 if (match) { | 525 if (match) { |
574 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), | 526 Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), |
575 g.TempImmediate(sh), g.TempImmediate(mask)); | 527 g.TempImmediate(sh), g.TempImmediate(mask)); |
576 return; | 528 return; |
577 } | 529 } |
578 } | 530 } |
579 } | 531 } |
580 VisitLogical<Int64BinopMatcher>( | 532 VisitBinop<Int64BinopMatcher>(this, node, kS390_And, kInt16Imm_Unsigned); |
581 this, node, &m, kS390_And, CanCover(node, m.left().node()), | |
582 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | |
583 } | 533 } |
584 #endif | 534 #endif |
585 | 535 |
586 void InstructionSelector::VisitWord32Or(Node* node) { | 536 void InstructionSelector::VisitWord32Or(Node* node) { |
587 Int32BinopMatcher m(node); | 537 Int32BinopMatcher m(node); |
588 VisitLogical<Int32BinopMatcher>( | 538 VisitBinop<Int32BinopMatcher>(this, node, kS390_Or, kInt16Imm_Unsigned); |
589 this, node, &m, kS390_Or, CanCover(node, m.left().node()), | |
590 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | |
591 } | 539 } |
592 | 540 |
593 #if V8_TARGET_ARCH_S390X | 541 #if V8_TARGET_ARCH_S390X |
594 void InstructionSelector::VisitWord64Or(Node* node) { | 542 void InstructionSelector::VisitWord64Or(Node* node) { |
595 Int64BinopMatcher m(node); | 543 Int64BinopMatcher m(node); |
596 VisitLogical<Int64BinopMatcher>( | 544 VisitBinop<Int64BinopMatcher>(this, node, kS390_Or, kInt16Imm_Unsigned); |
597 this, node, &m, kS390_Or, CanCover(node, m.left().node()), | |
598 CanCover(node, m.right().node()), kInt16Imm_Unsigned); | |
599 } | 545 } |
600 #endif | 546 #endif |
601 | 547 |
602 void InstructionSelector::VisitWord32Xor(Node* node) { | 548 void InstructionSelector::VisitWord32Xor(Node* node) { |
603 S390OperandGenerator g(this); | 549 S390OperandGenerator g(this); |
604 Int32BinopMatcher m(node); | 550 Int32BinopMatcher m(node); |
605 if (m.right().Is(-1)) { | 551 if (m.right().Is(-1)) { |
606 Emit(kS390_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node())); | 552 Emit(kS390_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node())); |
607 } else { | 553 } else { |
608 VisitBinop<Int32BinopMatcher>(this, node, kS390_Xor, kInt16Imm_Unsigned); | 554 VisitBinop<Int32BinopMatcher>(this, node, kS390_Xor, kInt16Imm_Unsigned); |
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1939 // static | 1885 // static |
1940 MachineOperatorBuilder::AlignmentRequirements | 1886 MachineOperatorBuilder::AlignmentRequirements |
1941 InstructionSelector::AlignmentRequirements() { | 1887 InstructionSelector::AlignmentRequirements() { |
1942 return MachineOperatorBuilder::AlignmentRequirements:: | 1888 return MachineOperatorBuilder::AlignmentRequirements:: |
1943 FullUnalignedAccessSupport(); | 1889 FullUnalignedAccessSupport(); |
1944 } | 1890 } |
1945 | 1891 |
1946 } // namespace compiler | 1892 } // namespace compiler |
1947 } // namespace internal | 1893 } // namespace internal |
1948 } // namespace v8 | 1894 } // namespace v8 |
OLD | NEW |