| 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 |