| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file declares the InstX8632 and OperandX8632 classes and | 10 // This file declares the InstX8632 and OperandX8632 classes and |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 OperandX8632 &operator=(const OperandX8632 &) = delete; | 34 OperandX8632 &operator=(const OperandX8632 &) = delete; |
| 35 | 35 |
| 36 public: | 36 public: |
| 37 enum OperandKindX8632 { | 37 enum OperandKindX8632 { |
| 38 k__Start = Operand::kTarget, | 38 k__Start = Operand::kTarget, |
| 39 kMem, | 39 kMem, |
| 40 kSplit | 40 kSplit |
| 41 }; | 41 }; |
| 42 using Operand::dump; | 42 using Operand::dump; |
| 43 void dump(const Cfg *, Ostream &Str) const override { | 43 void dump(const Cfg *, Ostream &Str) const override { |
| 44 Str << "<OperandX8632>"; | 44 if (ALLOW_DUMP) |
| 45 Str << "<OperandX8632>"; |
| 45 } | 46 } |
| 46 | 47 |
| 47 protected: | 48 protected: |
| 48 OperandX8632(OperandKindX8632 Kind, Type Ty) | 49 OperandX8632(OperandKindX8632 Kind, Type Ty) |
| 49 : Operand(static_cast<OperandKind>(Kind), Ty) {} | 50 : Operand(static_cast<OperandKind>(Kind), Ty) {} |
| 50 ~OperandX8632() override {} | 51 ~OperandX8632() override {} |
| 51 }; | 52 }; |
| 52 | 53 |
| 53 // OperandX8632Mem represents the m32 addressing mode, with optional | 54 // OperandX8632Mem represents the m32 addressing mode, with optional |
| 54 // base and index registers, a constant offset, and a fixed shift | 55 // base and index registers, a constant offset, and a fixed shift |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 class InstX8632InplaceopGPR : public InstX8632 { | 459 class InstX8632InplaceopGPR : public InstX8632 { |
| 459 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; | 460 InstX8632InplaceopGPR(const InstX8632InplaceopGPR &) = delete; |
| 460 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; | 461 InstX8632InplaceopGPR &operator=(const InstX8632InplaceopGPR &) = delete; |
| 461 | 462 |
| 462 public: | 463 public: |
| 463 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { | 464 static InstX8632InplaceopGPR *create(Cfg *Func, Operand *SrcDest) { |
| 464 return new (Func->allocate<InstX8632InplaceopGPR>()) | 465 return new (Func->allocate<InstX8632InplaceopGPR>()) |
| 465 InstX8632InplaceopGPR(Func, SrcDest); | 466 InstX8632InplaceopGPR(Func, SrcDest); |
| 466 } | 467 } |
| 467 void emit(const Cfg *Func) const override { | 468 void emit(const Cfg *Func) const override { |
| 469 if (!ALLOW_DUMP) |
| 470 return; |
| 468 Ostream &Str = Func->getContext()->getStrEmit(); | 471 Ostream &Str = Func->getContext()->getStrEmit(); |
| 469 assert(getSrcSize() == 1); | 472 assert(getSrcSize() == 1); |
| 470 Str << "\t" << Opcode << "\t"; | 473 Str << "\t" << Opcode << "\t"; |
| 471 getSrc(0)->emit(Func); | 474 getSrc(0)->emit(Func); |
| 472 } | 475 } |
| 473 void emitIAS(const Cfg *Func) const override { | 476 void emitIAS(const Cfg *Func) const override { |
| 474 assert(getSrcSize() == 1); | 477 assert(getSrcSize() == 1); |
| 475 const Variable *Var = getDest(); | 478 const Variable *Var = getDest(); |
| 476 Type Ty = Var->getType(); | 479 Type Ty = Var->getType(); |
| 477 emitIASOpTyGPR(Func, Ty, Var, Emitter); | 480 emitIASOpTyGPR(Func, Ty, Var, Emitter); |
| 478 } | 481 } |
| 479 void dump(const Cfg *Func) const override { | 482 void dump(const Cfg *Func) const override { |
| 483 if (!ALLOW_DUMP) |
| 484 return; |
| 480 Ostream &Str = Func->getContext()->getStrDump(); | 485 Ostream &Str = Func->getContext()->getStrDump(); |
| 481 dumpDest(Func); | 486 dumpDest(Func); |
| 482 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 487 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 483 dumpSources(Func); | 488 dumpSources(Func); |
| 484 } | 489 } |
| 485 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 490 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 486 | 491 |
| 487 private: | 492 private: |
| 488 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) | 493 InstX8632InplaceopGPR(Cfg *Func, Operand *SrcDest) |
| 489 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { | 494 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 506 class InstX8632UnaryopGPR : public InstX8632 { | 511 class InstX8632UnaryopGPR : public InstX8632 { |
| 507 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete; | 512 InstX8632UnaryopGPR(const InstX8632UnaryopGPR &) = delete; |
| 508 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete; | 513 InstX8632UnaryopGPR &operator=(const InstX8632UnaryopGPR &) = delete; |
| 509 | 514 |
| 510 public: | 515 public: |
| 511 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { | 516 static InstX8632UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 512 return new (Func->allocate<InstX8632UnaryopGPR>()) | 517 return new (Func->allocate<InstX8632UnaryopGPR>()) |
| 513 InstX8632UnaryopGPR(Func, Dest, Src); | 518 InstX8632UnaryopGPR(Func, Dest, Src); |
| 514 } | 519 } |
| 515 void emit(const Cfg *Func) const override { | 520 void emit(const Cfg *Func) const override { |
| 521 if (!ALLOW_DUMP) |
| 522 return; |
| 516 Ostream &Str = Func->getContext()->getStrEmit(); | 523 Ostream &Str = Func->getContext()->getStrEmit(); |
| 517 assert(getSrcSize() == 1); | 524 assert(getSrcSize() == 1); |
| 518 Type SrcTy = getSrc(0)->getType(); | 525 Type SrcTy = getSrc(0)->getType(); |
| 519 Type DestTy = getDest()->getType(); | 526 Type DestTy = getDest()->getType(); |
| 520 Str << "\t" << Opcode << getWidthString(SrcTy); | 527 Str << "\t" << Opcode << getWidthString(SrcTy); |
| 521 // Movsx and movzx need both the source and dest type width letter | 528 // Movsx and movzx need both the source and dest type width letter |
| 522 // to define the operation. The other unary operations have the | 529 // to define the operation. The other unary operations have the |
| 523 // same source and dest type and as a result need only one letter. | 530 // same source and dest type and as a result need only one letter. |
| 524 if (SrcTy != DestTy) | 531 if (SrcTy != DestTy) |
| 525 Str << getWidthString(DestTy); | 532 Str << getWidthString(DestTy); |
| 526 Str << "\t"; | 533 Str << "\t"; |
| 527 getSrc(0)->emit(Func); | 534 getSrc(0)->emit(Func); |
| 528 Str << ", "; | 535 Str << ", "; |
| 529 getDest()->emit(Func); | 536 getDest()->emit(Func); |
| 530 } | 537 } |
| 531 void emitIAS(const Cfg *Func) const override { | 538 void emitIAS(const Cfg *Func) const override { |
| 532 assert(getSrcSize() == 1); | 539 assert(getSrcSize() == 1); |
| 533 const Variable *Var = getDest(); | 540 const Variable *Var = getDest(); |
| 534 Type Ty = Var->getType(); | 541 Type Ty = Var->getType(); |
| 535 const Operand *Src = getSrc(0); | 542 const Operand *Src = getSrc(0); |
| 536 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 543 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
| 537 } | 544 } |
| 538 void dump(const Cfg *Func) const override { | 545 void dump(const Cfg *Func) const override { |
| 546 if (!ALLOW_DUMP) |
| 547 return; |
| 539 Ostream &Str = Func->getContext()->getStrDump(); | 548 Ostream &Str = Func->getContext()->getStrDump(); |
| 540 dumpDest(Func); | 549 dumpDest(Func); |
| 541 Str << " = " << Opcode << "." << getSrc(0)->getType() << " "; | 550 Str << " = " << Opcode << "." << getSrc(0)->getType() << " "; |
| 542 dumpSources(Func); | 551 dumpSources(Func); |
| 543 } | 552 } |
| 544 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 553 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 545 | 554 |
| 546 private: | 555 private: |
| 547 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) | 556 InstX8632UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src) |
| 548 : InstX8632(Func, K, 1, Dest) { | 557 : InstX8632(Func, K, 1, Dest) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 561 class InstX8632UnaryopXmm : public InstX8632 { | 570 class InstX8632UnaryopXmm : public InstX8632 { |
| 562 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete; | 571 InstX8632UnaryopXmm(const InstX8632UnaryopXmm &) = delete; |
| 563 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete; | 572 InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete; |
| 564 | 573 |
| 565 public: | 574 public: |
| 566 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { | 575 static InstX8632UnaryopXmm *create(Cfg *Func, Variable *Dest, Operand *Src) { |
| 567 return new (Func->allocate<InstX8632UnaryopXmm>()) | 576 return new (Func->allocate<InstX8632UnaryopXmm>()) |
| 568 InstX8632UnaryopXmm(Func, Dest, Src); | 577 InstX8632UnaryopXmm(Func, Dest, Src); |
| 569 } | 578 } |
| 570 void emit(const Cfg *Func) const override { | 579 void emit(const Cfg *Func) const override { |
| 580 if (!ALLOW_DUMP) |
| 581 return; |
| 571 Ostream &Str = Func->getContext()->getStrEmit(); | 582 Ostream &Str = Func->getContext()->getStrEmit(); |
| 572 assert(getSrcSize() == 1); | 583 assert(getSrcSize() == 1); |
| 573 Str << "\t" << Opcode << "\t"; | 584 Str << "\t" << Opcode << "\t"; |
| 574 getSrc(0)->emit(Func); | 585 getSrc(0)->emit(Func); |
| 575 Str << ", "; | 586 Str << ", "; |
| 576 getDest()->emit(Func); | 587 getDest()->emit(Func); |
| 577 } | 588 } |
| 578 void emitIAS(const Cfg *Func) const override { | 589 void emitIAS(const Cfg *Func) const override { |
| 579 Type Ty = getDest()->getType(); | 590 Type Ty = getDest()->getType(); |
| 580 assert(getSrcSize() == 1); | 591 assert(getSrcSize() == 1); |
| 581 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(0), Emitter); | 592 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(0), Emitter); |
| 582 } | 593 } |
| 583 void dump(const Cfg *Func) const override { | 594 void dump(const Cfg *Func) const override { |
| 595 if (!ALLOW_DUMP) |
| 596 return; |
| 584 Ostream &Str = Func->getContext()->getStrDump(); | 597 Ostream &Str = Func->getContext()->getStrDump(); |
| 585 dumpDest(Func); | 598 dumpDest(Func); |
| 586 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 599 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 587 dumpSources(Func); | 600 dumpSources(Func); |
| 588 } | 601 } |
| 589 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 602 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 590 | 603 |
| 591 private: | 604 private: |
| 592 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) | 605 InstX8632UnaryopXmm(Cfg *Func, Variable *Dest, Operand *Src) |
| 593 : InstX8632(Func, K, 1, Dest) { | 606 : InstX8632(Func, K, 1, Dest) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 613 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; | 626 InstX8632BinopGPRShift &operator=(const InstX8632BinopGPRShift &) = delete; |
| 614 | 627 |
| 615 public: | 628 public: |
| 616 // Create a binary-op GPR shift instruction. | 629 // Create a binary-op GPR shift instruction. |
| 617 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, | 630 static InstX8632BinopGPRShift *create(Cfg *Func, Variable *Dest, |
| 618 Operand *Source) { | 631 Operand *Source) { |
| 619 return new (Func->allocate<InstX8632BinopGPRShift>()) | 632 return new (Func->allocate<InstX8632BinopGPRShift>()) |
| 620 InstX8632BinopGPRShift(Func, Dest, Source); | 633 InstX8632BinopGPRShift(Func, Dest, Source); |
| 621 } | 634 } |
| 622 void emit(const Cfg *Func) const override { | 635 void emit(const Cfg *Func) const override { |
| 636 if (!ALLOW_DUMP) |
| 637 return; |
| 623 const bool ShiftHack = true; | 638 const bool ShiftHack = true; |
| 624 emitTwoAddress(Opcode, this, Func, ShiftHack); | 639 emitTwoAddress(Opcode, this, Func, ShiftHack); |
| 625 } | 640 } |
| 626 void emitIAS(const Cfg *Func) const override { | 641 void emitIAS(const Cfg *Func) const override { |
| 627 Type Ty = getDest()->getType(); | 642 Type Ty = getDest()->getType(); |
| 628 assert(getSrcSize() == 2); | 643 assert(getSrcSize() == 2); |
| 629 emitIASGPRShift(Func, Ty, getDest(), getSrc(1), Emitter); | 644 emitIASGPRShift(Func, Ty, getDest(), getSrc(1), Emitter); |
| 630 } | 645 } |
| 631 void dump(const Cfg *Func) const override { | 646 void dump(const Cfg *Func) const override { |
| 647 if (!ALLOW_DUMP) |
| 648 return; |
| 632 Ostream &Str = Func->getContext()->getStrDump(); | 649 Ostream &Str = Func->getContext()->getStrDump(); |
| 633 dumpDest(Func); | 650 dumpDest(Func); |
| 634 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 651 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 635 dumpSources(Func); | 652 dumpSources(Func); |
| 636 } | 653 } |
| 637 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 654 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 638 | 655 |
| 639 private: | 656 private: |
| 640 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) | 657 InstX8632BinopGPRShift(Cfg *Func, Variable *Dest, Operand *Source) |
| 641 : InstX8632(Func, K, 2, Dest) { | 658 : InstX8632(Func, K, 2, Dest) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 652 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete; | 669 InstX8632BinopGPR(const InstX8632BinopGPR &) = delete; |
| 653 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete; | 670 InstX8632BinopGPR &operator=(const InstX8632BinopGPR &) = delete; |
| 654 | 671 |
| 655 public: | 672 public: |
| 656 // Create an ordinary binary-op instruction like add or sub. | 673 // Create an ordinary binary-op instruction like add or sub. |
| 657 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { | 674 static InstX8632BinopGPR *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 658 return new (Func->allocate<InstX8632BinopGPR>()) | 675 return new (Func->allocate<InstX8632BinopGPR>()) |
| 659 InstX8632BinopGPR(Func, Dest, Source); | 676 InstX8632BinopGPR(Func, Dest, Source); |
| 660 } | 677 } |
| 661 void emit(const Cfg *Func) const override { | 678 void emit(const Cfg *Func) const override { |
| 679 if (!ALLOW_DUMP) |
| 680 return; |
| 662 const bool ShiftHack = false; | 681 const bool ShiftHack = false; |
| 663 emitTwoAddress(Opcode, this, Func, ShiftHack); | 682 emitTwoAddress(Opcode, this, Func, ShiftHack); |
| 664 } | 683 } |
| 665 void emitIAS(const Cfg *Func) const override { | 684 void emitIAS(const Cfg *Func) const override { |
| 666 Type Ty = getDest()->getType(); | 685 Type Ty = getDest()->getType(); |
| 667 assert(getSrcSize() == 2); | 686 assert(getSrcSize() == 2); |
| 668 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter); | 687 emitIASRegOpTyGPR(Func, Ty, getDest(), getSrc(1), Emitter); |
| 669 } | 688 } |
| 670 void dump(const Cfg *Func) const override { | 689 void dump(const Cfg *Func) const override { |
| 690 if (!ALLOW_DUMP) |
| 691 return; |
| 671 Ostream &Str = Func->getContext()->getStrDump(); | 692 Ostream &Str = Func->getContext()->getStrDump(); |
| 672 dumpDest(Func); | 693 dumpDest(Func); |
| 673 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 694 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 674 dumpSources(Func); | 695 dumpSources(Func); |
| 675 } | 696 } |
| 676 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 697 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 677 | 698 |
| 678 private: | 699 private: |
| 679 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source) | 700 InstX8632BinopGPR(Cfg *Func, Variable *Dest, Operand *Source) |
| 680 : InstX8632(Func, K, 2, Dest) { | 701 : InstX8632(Func, K, 2, Dest) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 691 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; | 712 InstX8632BinopXmm(const InstX8632BinopXmm &) = delete; |
| 692 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; | 713 InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; |
| 693 | 714 |
| 694 public: | 715 public: |
| 695 // Create an XMM binary-op instruction like addss or addps. | 716 // Create an XMM binary-op instruction like addss or addps. |
| 696 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { | 717 static InstX8632BinopXmm *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 697 return new (Func->allocate<InstX8632BinopXmm>()) | 718 return new (Func->allocate<InstX8632BinopXmm>()) |
| 698 InstX8632BinopXmm(Func, Dest, Source); | 719 InstX8632BinopXmm(Func, Dest, Source); |
| 699 } | 720 } |
| 700 void emit(const Cfg *Func) const override { | 721 void emit(const Cfg *Func) const override { |
| 722 if (!ALLOW_DUMP) |
| 723 return; |
| 701 const bool ShiftHack = false; | 724 const bool ShiftHack = false; |
| 702 emitTwoAddress(Opcode, this, Func, ShiftHack); | 725 emitTwoAddress(Opcode, this, Func, ShiftHack); |
| 703 } | 726 } |
| 704 void emitIAS(const Cfg *Func) const override { | 727 void emitIAS(const Cfg *Func) const override { |
| 705 Type Ty = getDest()->getType(); | 728 Type Ty = getDest()->getType(); |
| 706 if (NeedsElementType) | 729 if (NeedsElementType) |
| 707 Ty = typeElementType(Ty); | 730 Ty = typeElementType(Ty); |
| 708 assert(getSrcSize() == 2); | 731 assert(getSrcSize() == 2); |
| 709 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); | 732 emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); |
| 710 } | 733 } |
| 711 void dump(const Cfg *Func) const override { | 734 void dump(const Cfg *Func) const override { |
| 735 if (!ALLOW_DUMP) |
| 736 return; |
| 712 Ostream &Str = Func->getContext()->getStrDump(); | 737 Ostream &Str = Func->getContext()->getStrDump(); |
| 713 dumpDest(Func); | 738 dumpDest(Func); |
| 714 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 739 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 715 dumpSources(Func); | 740 dumpSources(Func); |
| 716 } | 741 } |
| 717 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 742 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 718 | 743 |
| 719 private: | 744 private: |
| 720 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) | 745 InstX8632BinopXmm(Cfg *Func, Variable *Dest, Operand *Source) |
| 721 : InstX8632(Func, K, 2, Dest) { | 746 : InstX8632(Func, K, 2, Dest) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 737 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete; | 762 InstX8632BinopXmmShift &operator=(const InstX8632BinopXmmShift &) = delete; |
| 738 | 763 |
| 739 public: | 764 public: |
| 740 // Create an XMM binary-op shift operation. | 765 // Create an XMM binary-op shift operation. |
| 741 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, | 766 static InstX8632BinopXmmShift *create(Cfg *Func, Variable *Dest, |
| 742 Operand *Source) { | 767 Operand *Source) { |
| 743 return new (Func->allocate<InstX8632BinopXmmShift>()) | 768 return new (Func->allocate<InstX8632BinopXmmShift>()) |
| 744 InstX8632BinopXmmShift(Func, Dest, Source); | 769 InstX8632BinopXmmShift(Func, Dest, Source); |
| 745 } | 770 } |
| 746 void emit(const Cfg *Func) const override { | 771 void emit(const Cfg *Func) const override { |
| 772 if (!ALLOW_DUMP) |
| 773 return; |
| 747 const bool ShiftHack = false; | 774 const bool ShiftHack = false; |
| 748 emitTwoAddress(Opcode, this, Func, ShiftHack); | 775 emitTwoAddress(Opcode, this, Func, ShiftHack); |
| 749 } | 776 } |
| 750 void emitIAS(const Cfg *Func) const override { | 777 void emitIAS(const Cfg *Func) const override { |
| 751 Type Ty = getDest()->getType(); | 778 Type Ty = getDest()->getType(); |
| 752 assert(Ty == IceType_v8i16 || Ty == IceType_v8i1 || Ty == IceType_v4i32 || | 779 assert(Ty == IceType_v8i16 || Ty == IceType_v8i1 || Ty == IceType_v4i32 || |
| 753 Ty == IceType_v4i1); | 780 Ty == IceType_v4i1); |
| 754 Type ElementTy = typeElementType(Ty); | 781 Type ElementTy = typeElementType(Ty); |
| 755 assert(getSrcSize() == 2); | 782 assert(getSrcSize() == 2); |
| 756 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter); | 783 emitIASXmmShift(Func, ElementTy, getDest(), getSrc(1), Emitter); |
| 757 } | 784 } |
| 758 void dump(const Cfg *Func) const override { | 785 void dump(const Cfg *Func) const override { |
| 786 if (!ALLOW_DUMP) |
| 787 return; |
| 759 Ostream &Str = Func->getContext()->getStrDump(); | 788 Ostream &Str = Func->getContext()->getStrDump(); |
| 760 dumpDest(Func); | 789 dumpDest(Func); |
| 761 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 790 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 762 dumpSources(Func); | 791 dumpSources(Func); |
| 763 } | 792 } |
| 764 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 793 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 765 | 794 |
| 766 private: | 795 private: |
| 767 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) | 796 InstX8632BinopXmmShift(Cfg *Func, Variable *Dest, Operand *Source) |
| 768 : InstX8632(Func, K, 2, Dest) { | 797 : InstX8632(Func, K, 2, Dest) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 779 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete; | 808 InstX8632Ternop &operator=(const InstX8632Ternop &) = delete; |
| 780 | 809 |
| 781 public: | 810 public: |
| 782 // Create a ternary-op instruction like div or idiv. | 811 // Create a ternary-op instruction like div or idiv. |
| 783 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, | 812 static InstX8632Ternop *create(Cfg *Func, Variable *Dest, Operand *Source1, |
| 784 Operand *Source2) { | 813 Operand *Source2) { |
| 785 return new (Func->allocate<InstX8632Ternop>()) | 814 return new (Func->allocate<InstX8632Ternop>()) |
| 786 InstX8632Ternop(Func, Dest, Source1, Source2); | 815 InstX8632Ternop(Func, Dest, Source1, Source2); |
| 787 } | 816 } |
| 788 void emit(const Cfg *Func) const override { | 817 void emit(const Cfg *Func) const override { |
| 818 if (!ALLOW_DUMP) |
| 819 return; |
| 789 Ostream &Str = Func->getContext()->getStrEmit(); | 820 Ostream &Str = Func->getContext()->getStrEmit(); |
| 790 assert(getSrcSize() == 3); | 821 assert(getSrcSize() == 3); |
| 791 Str << "\t" << Opcode << "\t"; | 822 Str << "\t" << Opcode << "\t"; |
| 792 getSrc(2)->emit(Func); | 823 getSrc(2)->emit(Func); |
| 793 Str << ", "; | 824 Str << ", "; |
| 794 getSrc(1)->emit(Func); | 825 getSrc(1)->emit(Func); |
| 795 Str << ", "; | 826 Str << ", "; |
| 796 getDest()->emit(Func); | 827 getDest()->emit(Func); |
| 797 } | 828 } |
| 798 void emitIAS(const Cfg *Func) const override; | 829 void emitIAS(const Cfg *Func) const override; |
| 799 void dump(const Cfg *Func) const override { | 830 void dump(const Cfg *Func) const override { |
| 831 if (!ALLOW_DUMP) |
| 832 return; |
| 800 Ostream &Str = Func->getContext()->getStrDump(); | 833 Ostream &Str = Func->getContext()->getStrDump(); |
| 801 dumpDest(Func); | 834 dumpDest(Func); |
| 802 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 835 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 803 dumpSources(Func); | 836 dumpSources(Func); |
| 804 } | 837 } |
| 805 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 838 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 806 | 839 |
| 807 private: | 840 private: |
| 808 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) | 841 InstX8632Ternop(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) |
| 809 : InstX8632(Func, K, 3, Dest) { | 842 : InstX8632(Func, K, 3, Dest) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 821 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete; | 854 InstX8632ThreeAddressop(const InstX8632ThreeAddressop &) = delete; |
| 822 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete; | 855 InstX8632ThreeAddressop &operator=(const InstX8632ThreeAddressop &) = delete; |
| 823 | 856 |
| 824 public: | 857 public: |
| 825 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, | 858 static InstX8632ThreeAddressop *create(Cfg *Func, Variable *Dest, |
| 826 Operand *Source0, Operand *Source1) { | 859 Operand *Source0, Operand *Source1) { |
| 827 return new (Func->allocate<InstX8632ThreeAddressop>()) | 860 return new (Func->allocate<InstX8632ThreeAddressop>()) |
| 828 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); | 861 InstX8632ThreeAddressop(Func, Dest, Source0, Source1); |
| 829 } | 862 } |
| 830 void emit(const Cfg *Func) const override { | 863 void emit(const Cfg *Func) const override { |
| 864 if (!ALLOW_DUMP) |
| 865 return; |
| 831 Ostream &Str = Func->getContext()->getStrEmit(); | 866 Ostream &Str = Func->getContext()->getStrEmit(); |
| 832 assert(getSrcSize() == 2); | 867 assert(getSrcSize() == 2); |
| 833 Str << "\t" << Opcode << "\t"; | 868 Str << "\t" << Opcode << "\t"; |
| 834 getSrc(1)->emit(Func); | 869 getSrc(1)->emit(Func); |
| 835 Str << ", "; | 870 Str << ", "; |
| 836 getSrc(0)->emit(Func); | 871 getSrc(0)->emit(Func); |
| 837 Str << ", "; | 872 Str << ", "; |
| 838 getDest()->emit(Func); | 873 getDest()->emit(Func); |
| 839 } | 874 } |
| 840 void emitIAS(const Cfg *Func) const override; | 875 void emitIAS(const Cfg *Func) const override; |
| 841 void dump(const Cfg *Func) const override { | 876 void dump(const Cfg *Func) const override { |
| 877 if (!ALLOW_DUMP) |
| 878 return; |
| 842 Ostream &Str = Func->getContext()->getStrDump(); | 879 Ostream &Str = Func->getContext()->getStrDump(); |
| 843 dumpDest(Func); | 880 dumpDest(Func); |
| 844 Str << " = " << Opcode << "." << getDest()->getType() << " "; | 881 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 845 dumpSources(Func); | 882 dumpSources(Func); |
| 846 } | 883 } |
| 847 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 884 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 848 | 885 |
| 849 private: | 886 private: |
| 850 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, | 887 InstX8632ThreeAddressop(Cfg *Func, Variable *Dest, Operand *Source0, |
| 851 Operand *Source1) | 888 Operand *Source1) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 870 return new (Func->allocate<InstX8632Movlike>()) | 907 return new (Func->allocate<InstX8632Movlike>()) |
| 871 InstX8632Movlike(Func, Dest, Source); | 908 InstX8632Movlike(Func, Dest, Source); |
| 872 } | 909 } |
| 873 bool isRedundantAssign() const override { | 910 bool isRedundantAssign() const override { |
| 874 return checkForRedundantAssign(getDest(), getSrc(0)); | 911 return checkForRedundantAssign(getDest(), getSrc(0)); |
| 875 } | 912 } |
| 876 bool isSimpleAssign() const override { return true; } | 913 bool isSimpleAssign() const override { return true; } |
| 877 void emit(const Cfg *Func) const override; | 914 void emit(const Cfg *Func) const override; |
| 878 void emitIAS(const Cfg *Func) const override; | 915 void emitIAS(const Cfg *Func) const override; |
| 879 void dump(const Cfg *Func) const override { | 916 void dump(const Cfg *Func) const override { |
| 917 if (!ALLOW_DUMP) |
| 918 return; |
| 880 Ostream &Str = Func->getContext()->getStrDump(); | 919 Ostream &Str = Func->getContext()->getStrDump(); |
| 881 Str << Opcode << "." << getDest()->getType() << " "; | 920 Str << Opcode << "." << getDest()->getType() << " "; |
| 882 dumpDest(Func); | 921 dumpDest(Func); |
| 883 Str << ", "; | 922 Str << ", "; |
| 884 dumpSources(Func); | 923 dumpSources(Func); |
| 885 } | 924 } |
| 886 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 925 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 887 | 926 |
| 888 private: | 927 private: |
| 889 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source) | 928 InstX8632Movlike(Cfg *Func, Variable *Dest, Operand *Source) |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; | 1591 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const; |
| 1553 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; | 1592 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const; |
| 1554 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; | 1593 template <> void InstX8632Movzx::emitIAS(const Cfg *Func) const; |
| 1555 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; | 1594 template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; |
| 1556 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; | 1595 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const; |
| 1557 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; | 1596 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const; |
| 1558 | 1597 |
| 1559 } // end of namespace Ice | 1598 } // end of namespace Ice |
| 1560 | 1599 |
| 1561 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1600 #endif // SUBZERO_SRC_ICEINSTX8632_H |
| OLD | NEW |