| OLD | NEW |
| 1 //===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstARM32.h - ARM32 machine 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 /// \file | 10 /// \file |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 static const char *getVecWidthString(Type Ty); | 442 static const char *getVecWidthString(Type Ty); |
| 443 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); | 443 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); |
| 444 | 444 |
| 445 /// Called inside derived methods emit() to communicate that multiple | 445 /// Called inside derived methods emit() to communicate that multiple |
| 446 /// instructions are being generated. Used by emitIAS() methods to | 446 /// instructions are being generated. Used by emitIAS() methods to |
| 447 /// generate textual fixups for instructions that are not yet | 447 /// generate textual fixups for instructions that are not yet |
| 448 /// implemented. | 448 /// implemented. |
| 449 void startNextInst(const Cfg *Func) const; | 449 void startNextInst(const Cfg *Func) const; |
| 450 | 450 |
| 451 /// Shared emit routines for common forms of instructions. | 451 /// Shared emit routines for common forms of instructions. |
| 452 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, | 452 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Instr, |
| 453 const Cfg *Func); | 453 const Cfg *Func); |
| 454 static void emitFourAddrFP(const char *Opcode, const InstARM32 *Inst, | 454 static void emitFourAddrFP(const char *Opcode, const InstARM32 *Instr, |
| 455 const Cfg *Func); | 455 const Cfg *Func); |
| 456 | 456 |
| 457 void dump(const Cfg *Func) const override; | 457 void dump(const Cfg *Func) const override; |
| 458 | 458 |
| 459 void emitIAS(const Cfg *Func) const override; | 459 void emitIAS(const Cfg *Func) const override; |
| 460 | 460 |
| 461 protected: | 461 protected: |
| 462 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) | 462 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) |
| 463 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 463 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
| 464 | 464 |
| 465 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { | 465 static bool isClassof(const Inst *Instr, InstKindARM32 MyKind) { |
| 466 return Inst->getKind() == static_cast<InstKind>(MyKind); | 466 return Instr->getKind() == static_cast<InstKind>(MyKind); |
| 467 } | 467 } |
| 468 | 468 |
| 469 // Generates text of assembly instruction using method emit(), and then adds | 469 // Generates text of assembly instruction using method emit(), and then adds |
| 470 // to the assembly buffer as a Fixup. | 470 // to the assembly buffer as a Fixup. |
| 471 void emitUsingTextFixup(const Cfg *Func) const; | 471 void emitUsingTextFixup(const Cfg *Func) const; |
| 472 }; | 472 }; |
| 473 | 473 |
| 474 /// A predicable ARM instruction. | 474 /// A predicable ARM instruction. |
| 475 class InstARM32Pred : public InstARM32 { | 475 class InstARM32Pred : public InstARM32 { |
| 476 InstARM32Pred() = delete; | 476 InstARM32Pred() = delete; |
| 477 InstARM32Pred(const InstARM32Pred &) = delete; | 477 InstARM32Pred(const InstARM32Pred &) = delete; |
| 478 InstARM32Pred &operator=(const InstARM32Pred &) = delete; | 478 InstARM32Pred &operator=(const InstARM32Pred &) = delete; |
| 479 | 479 |
| 480 public: | 480 public: |
| 481 InstARM32Pred(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest, | 481 InstARM32Pred(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest, |
| 482 CondARM32::Cond Predicate) | 482 CondARM32::Cond Predicate) |
| 483 : InstARM32(Func, Kind, Maxsrcs, Dest), Predicate(Predicate) {} | 483 : InstARM32(Func, Kind, Maxsrcs, Dest), Predicate(Predicate) {} |
| 484 | 484 |
| 485 CondARM32::Cond getPredicate() const { return Predicate; } | 485 CondARM32::Cond getPredicate() const { return Predicate; } |
| 486 void setPredicate(CondARM32::Cond Pred) { Predicate = Pred; } | 486 void setPredicate(CondARM32::Cond Pred) { Predicate = Pred; } |
| 487 | 487 |
| 488 static const char *predString(CondARM32::Cond Predicate); | 488 static const char *predString(CondARM32::Cond Predicate); |
| 489 void dumpOpcodePred(Ostream &Str, const char *Opcode, Type Ty) const; | 489 void dumpOpcodePred(Ostream &Str, const char *Opcode, Type Ty) const; |
| 490 | 490 |
| 491 /// Shared emit routines for common forms of instructions. | 491 /// Shared emit routines for common forms of instructions. |
| 492 static void emitUnaryopGPR(const char *Opcode, const InstARM32Pred *Inst, | 492 static void emitUnaryopGPR(const char *Opcode, const InstARM32Pred *Instr, |
| 493 const Cfg *Func, bool NeedsWidthSuffix); | 493 const Cfg *Func, bool NeedsWidthSuffix); |
| 494 static void emitUnaryopFP(const char *Opcode, const InstARM32Pred *Inst, | 494 static void emitUnaryopFP(const char *Opcode, const InstARM32Pred *Instr, |
| 495 const Cfg *Func); | 495 const Cfg *Func); |
| 496 static void emitTwoAddr(const char *Opcode, const InstARM32Pred *Inst, | 496 static void emitTwoAddr(const char *Opcode, const InstARM32Pred *Instr, |
| 497 const Cfg *Func); | 497 const Cfg *Func); |
| 498 static void emitThreeAddr(const char *Opcode, const InstARM32Pred *Inst, | 498 static void emitThreeAddr(const char *Opcode, const InstARM32Pred *Instr, |
| 499 const Cfg *Func, bool SetFlags); | 499 const Cfg *Func, bool SetFlags); |
| 500 static void emitFourAddr(const char *Opcode, const InstARM32Pred *Inst, | 500 static void emitFourAddr(const char *Opcode, const InstARM32Pred *Instr, |
| 501 const Cfg *Func); | 501 const Cfg *Func); |
| 502 static void emitCmpLike(const char *Opcode, const InstARM32Pred *Inst, | 502 static void emitCmpLike(const char *Opcode, const InstARM32Pred *Instr, |
| 503 const Cfg *Func); | 503 const Cfg *Func); |
| 504 | 504 |
| 505 protected: | 505 protected: |
| 506 CondARM32::Cond Predicate; | 506 CondARM32::Cond Predicate; |
| 507 }; | 507 }; |
| 508 | 508 |
| 509 template <typename StreamType> | 509 template <typename StreamType> |
| 510 inline StreamType &operator<<(StreamType &Stream, CondARM32::Cond Predicate) { | 510 inline StreamType &operator<<(StreamType &Stream, CondARM32::Cond Predicate) { |
| 511 Stream << InstARM32Pred::predString(Predicate); | 511 Stream << InstARM32Pred::predString(Predicate); |
| 512 return Stream; | 512 return Stream; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 534 void dump(const Cfg *Func) const override { | 534 void dump(const Cfg *Func) const override { |
| 535 if (!BuildDefs::dump()) | 535 if (!BuildDefs::dump()) |
| 536 return; | 536 return; |
| 537 Ostream &Str = Func->getContext()->getStrDump(); | 537 Ostream &Str = Func->getContext()->getStrDump(); |
| 538 dumpDest(Func); | 538 dumpDest(Func); |
| 539 Str << " = "; | 539 Str << " = "; |
| 540 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 540 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 541 Str << " "; | 541 Str << " "; |
| 542 dumpSources(Func); | 542 dumpSources(Func); |
| 543 } | 543 } |
| 544 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 544 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 545 | 545 |
| 546 private: | 546 private: |
| 547 InstARM32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src, | 547 InstARM32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src, |
| 548 CondARM32::Cond Predicate) | 548 CondARM32::Cond Predicate) |
| 549 : InstARM32Pred(Func, K, 1, Dest, Predicate) { | 549 : InstARM32Pred(Func, K, 1, Dest, Predicate) { |
| 550 addSource(Src); | 550 addSource(Src); |
| 551 } | 551 } |
| 552 | 552 |
| 553 static const char *Opcode; | 553 static const char *Opcode; |
| 554 }; | 554 }; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 575 void dump(const Cfg *Func) const override { | 575 void dump(const Cfg *Func) const override { |
| 576 if (!BuildDefs::dump()) | 576 if (!BuildDefs::dump()) |
| 577 return; | 577 return; |
| 578 Ostream &Str = Func->getContext()->getStrDump(); | 578 Ostream &Str = Func->getContext()->getStrDump(); |
| 579 dumpDest(Func); | 579 dumpDest(Func); |
| 580 Str << " = "; | 580 Str << " = "; |
| 581 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 581 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 582 Str << " "; | 582 Str << " "; |
| 583 dumpSources(Func); | 583 dumpSources(Func); |
| 584 } | 584 } |
| 585 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 585 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 586 | 586 |
| 587 private: | 587 private: |
| 588 InstARM32UnaryopFP(Cfg *Func, Variable *Dest, Operand *Src, | 588 InstARM32UnaryopFP(Cfg *Func, Variable *Dest, Operand *Src, |
| 589 CondARM32::Cond Predicate) | 589 CondARM32::Cond Predicate) |
| 590 : InstARM32Pred(Func, K, 1, Dest, Predicate) { | 590 : InstARM32Pred(Func, K, 1, Dest, Predicate) { |
| 591 addSource(Src); | 591 addSource(Src); |
| 592 } | 592 } |
| 593 | 593 |
| 594 static const char *Opcode; | 594 static const char *Opcode; |
| 595 }; | 595 }; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 617 void dump(const Cfg *Func) const override { | 617 void dump(const Cfg *Func) const override { |
| 618 if (!BuildDefs::dump()) | 618 if (!BuildDefs::dump()) |
| 619 return; | 619 return; |
| 620 Ostream &Str = Func->getContext()->getStrDump(); | 620 Ostream &Str = Func->getContext()->getStrDump(); |
| 621 dumpDest(Func); | 621 dumpDest(Func); |
| 622 Str << " = "; | 622 Str << " = "; |
| 623 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 623 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 624 Str << " "; | 624 Str << " "; |
| 625 dumpSources(Func); | 625 dumpSources(Func); |
| 626 } | 626 } |
| 627 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 627 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 628 | 628 |
| 629 private: | 629 private: |
| 630 InstARM32TwoAddrGPR(Cfg *Func, Variable *Dest, Operand *Src, | 630 InstARM32TwoAddrGPR(Cfg *Func, Variable *Dest, Operand *Src, |
| 631 CondARM32::Cond Predicate) | 631 CondARM32::Cond Predicate) |
| 632 : InstARM32Pred(Func, K, 2, Dest, Predicate) { | 632 : InstARM32Pred(Func, K, 2, Dest, Predicate) { |
| 633 addSource(Dest); | 633 addSource(Dest); |
| 634 addSource(Src); | 634 addSource(Src); |
| 635 } | 635 } |
| 636 | 636 |
| 637 static const char *Opcode; | 637 static const char *Opcode; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 655 void dump(const Cfg *Func) const override { | 655 void dump(const Cfg *Func) const override { |
| 656 if (!BuildDefs::dump()) | 656 if (!BuildDefs::dump()) |
| 657 return; | 657 return; |
| 658 Ostream &Str = Func->getContext()->getStrDump(); | 658 Ostream &Str = Func->getContext()->getStrDump(); |
| 659 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 659 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 660 Str << " "; | 660 Str << " "; |
| 661 dumpDest(Func); | 661 dumpDest(Func); |
| 662 Str << ", "; | 662 Str << ", "; |
| 663 dumpSources(Func); | 663 dumpSources(Func); |
| 664 } | 664 } |
| 665 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 665 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 666 | 666 |
| 667 private: | 667 private: |
| 668 InstARM32LoadBase(Cfg *Func, Variable *Dest, Operand *Source, | 668 InstARM32LoadBase(Cfg *Func, Variable *Dest, Operand *Source, |
| 669 CondARM32::Cond Predicate) | 669 CondARM32::Cond Predicate) |
| 670 : InstARM32Pred(Func, K, 1, Dest, Predicate) { | 670 : InstARM32Pred(Func, K, 1, Dest, Predicate) { |
| 671 addSource(Source); | 671 addSource(Source); |
| 672 } | 672 } |
| 673 | 673 |
| 674 static const char *Opcode; | 674 static const char *Opcode; |
| 675 }; | 675 }; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 701 void dump(const Cfg *Func) const override { | 701 void dump(const Cfg *Func) const override { |
| 702 if (!BuildDefs::dump()) | 702 if (!BuildDefs::dump()) |
| 703 return; | 703 return; |
| 704 Ostream &Str = Func->getContext()->getStrDump(); | 704 Ostream &Str = Func->getContext()->getStrDump(); |
| 705 dumpDest(Func); | 705 dumpDest(Func); |
| 706 Str << " = "; | 706 Str << " = "; |
| 707 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 707 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 708 Str << (SetFlags ? ".s " : " "); | 708 Str << (SetFlags ? ".s " : " "); |
| 709 dumpSources(Func); | 709 dumpSources(Func); |
| 710 } | 710 } |
| 711 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 711 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 712 | 712 |
| 713 private: | 713 private: |
| 714 InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0, | 714 InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0, |
| 715 Operand *Src1, CondARM32::Cond Predicate, bool SetFlags) | 715 Operand *Src1, CondARM32::Cond Predicate, bool SetFlags) |
| 716 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { | 716 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { |
| 717 HasSideEffects = SetFlags; | 717 HasSideEffects = SetFlags; |
| 718 addSource(Src0); | 718 addSource(Src0); |
| 719 addSource(Src1); | 719 addSource(Src1); |
| 720 } | 720 } |
| 721 | 721 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 749 void emitIAS(const Cfg *Func) const override; | 749 void emitIAS(const Cfg *Func) const override; |
| 750 void dump(const Cfg *Func) const override { | 750 void dump(const Cfg *Func) const override { |
| 751 if (!BuildDefs::dump()) | 751 if (!BuildDefs::dump()) |
| 752 return; | 752 return; |
| 753 Ostream &Str = Func->getContext()->getStrDump(); | 753 Ostream &Str = Func->getContext()->getStrDump(); |
| 754 dumpDest(Func); | 754 dumpDest(Func); |
| 755 Str << " = "; | 755 Str << " = "; |
| 756 Str << Opcode << "." << getDest()->getType() << " "; | 756 Str << Opcode << "." << getDest()->getType() << " "; |
| 757 dumpSources(Func); | 757 dumpSources(Func); |
| 758 } | 758 } |
| 759 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 759 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 760 | 760 |
| 761 private: | 761 private: |
| 762 InstARM32ThreeAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, | 762 InstARM32ThreeAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, |
| 763 Variable *Src1) | 763 Variable *Src1) |
| 764 : InstARM32(Func, K, 2, Dest) { | 764 : InstARM32(Func, K, 2, Dest) { |
| 765 addSource(Src0); | 765 addSource(Src0); |
| 766 addSource(Src1); | 766 addSource(Src1); |
| 767 } | 767 } |
| 768 | 768 |
| 769 static const char *Opcode; | 769 static const char *Opcode; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 793 void dump(const Cfg *Func) const override { | 793 void dump(const Cfg *Func) const override { |
| 794 if (!BuildDefs::dump()) | 794 if (!BuildDefs::dump()) |
| 795 return; | 795 return; |
| 796 Ostream &Str = Func->getContext()->getStrDump(); | 796 Ostream &Str = Func->getContext()->getStrDump(); |
| 797 dumpDest(Func); | 797 dumpDest(Func); |
| 798 Str << " = "; | 798 Str << " = "; |
| 799 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 799 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
| 800 Str << " "; | 800 Str << " "; |
| 801 dumpSources(Func); | 801 dumpSources(Func); |
| 802 } | 802 } |
| 803 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 803 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 804 | 804 |
| 805 private: | 805 private: |
| 806 InstARM32FourAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0, | 806 InstARM32FourAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0, |
| 807 Variable *Src1, Variable *Src2, | 807 Variable *Src1, Variable *Src2, |
| 808 CondARM32::Cond Predicate) | 808 CondARM32::Cond Predicate) |
| 809 : InstARM32Pred(Func, K, 3, Dest, Predicate) { | 809 : InstARM32Pred(Func, K, 3, Dest, Predicate) { |
| 810 addSource(Src0); | 810 addSource(Src0); |
| 811 addSource(Src1); | 811 addSource(Src1); |
| 812 addSource(Src2); | 812 addSource(Src2); |
| 813 } | 813 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 843 if (!BuildDefs::dump()) | 843 if (!BuildDefs::dump()) |
| 844 return; | 844 return; |
| 845 Ostream &Str = Func->getContext()->getStrDump(); | 845 Ostream &Str = Func->getContext()->getStrDump(); |
| 846 dumpDest(Func); | 846 dumpDest(Func); |
| 847 Str << " = "; | 847 Str << " = "; |
| 848 Str << Opcode << "." << getDest()->getType() << " "; | 848 Str << Opcode << "." << getDest()->getType() << " "; |
| 849 dumpDest(Func); | 849 dumpDest(Func); |
| 850 Str << ", "; | 850 Str << ", "; |
| 851 dumpSources(Func); | 851 dumpSources(Func); |
| 852 } | 852 } |
| 853 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 853 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 854 | 854 |
| 855 private: | 855 private: |
| 856 InstARM32FourAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1) | 856 InstARM32FourAddrFP(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1) |
| 857 : InstARM32(Func, K, 3, Dest) { | 857 : InstARM32(Func, K, 3, Dest) { |
| 858 addSource(Dest); | 858 addSource(Dest); |
| 859 addSource(Src0); | 859 addSource(Src0); |
| 860 addSource(Src1); | 860 addSource(Src1); |
| 861 } | 861 } |
| 862 | 862 |
| 863 static const char *Opcode; | 863 static const char *Opcode; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 883 } | 883 } |
| 884 void emitIAS(const Cfg *Func) const override; | 884 void emitIAS(const Cfg *Func) const override; |
| 885 void dump(const Cfg *Func) const override { | 885 void dump(const Cfg *Func) const override { |
| 886 if (!BuildDefs::dump()) | 886 if (!BuildDefs::dump()) |
| 887 return; | 887 return; |
| 888 Ostream &Str = Func->getContext()->getStrDump(); | 888 Ostream &Str = Func->getContext()->getStrDump(); |
| 889 dumpOpcodePred(Str, Opcode, getSrc(0)->getType()); | 889 dumpOpcodePred(Str, Opcode, getSrc(0)->getType()); |
| 890 Str << " "; | 890 Str << " "; |
| 891 dumpSources(Func); | 891 dumpSources(Func); |
| 892 } | 892 } |
| 893 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 893 static bool classof(const Inst *Instr) { return isClassof(Instr, K); } |
| 894 | 894 |
| 895 private: | 895 private: |
| 896 InstARM32CmpLike(Cfg *Func, Variable *Src0, Operand *Src1, | 896 InstARM32CmpLike(Cfg *Func, Variable *Src0, Operand *Src1, |
| 897 CondARM32::Cond Predicate) | 897 CondARM32::Cond Predicate) |
| 898 : InstARM32Pred(Func, K, 2, nullptr, Predicate) { | 898 : InstARM32Pred(Func, K, 2, nullptr, Predicate) { |
| 899 HasSideEffects = true; | 899 HasSideEffects = true; |
| 900 addSource(Src0); | 900 addSource(Src0); |
| 901 addSource(Src1); | 901 addSource(Src1); |
| 902 } | 902 } |
| 903 | 903 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 ++Sum; | 1031 ++Sum; |
| 1032 return Sum; | 1032 return Sum; |
| 1033 } | 1033 } |
| 1034 bool isUnconditionalBranch() const override { | 1034 bool isUnconditionalBranch() const override { |
| 1035 return getPredicate() == CondARM32::AL; | 1035 return getPredicate() == CondARM32::AL; |
| 1036 } | 1036 } |
| 1037 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; | 1037 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; |
| 1038 void emit(const Cfg *Func) const override; | 1038 void emit(const Cfg *Func) const override; |
| 1039 void emitIAS(const Cfg *Func) const override; | 1039 void emitIAS(const Cfg *Func) const override; |
| 1040 void dump(const Cfg *Func) const override; | 1040 void dump(const Cfg *Func) const override; |
| 1041 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } | 1041 static bool classof(const Inst *Instr) { return isClassof(Instr, Br); } |
| 1042 | 1042 |
| 1043 private: | 1043 private: |
| 1044 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, | 1044 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, |
| 1045 const InstARM32Label *Label, CondARM32::Cond Predicate); | 1045 const InstARM32Label *Label, CondARM32::Cond Predicate); |
| 1046 | 1046 |
| 1047 const CfgNode *TargetTrue; | 1047 const CfgNode *TargetTrue; |
| 1048 const CfgNode *TargetFalse; | 1048 const CfgNode *TargetFalse; |
| 1049 const InstARM32Label *Label; // Intra-block branch target | 1049 const InstARM32Label *Label; // Intra-block branch target |
| 1050 }; | 1050 }; |
| 1051 | 1051 |
| 1052 /// Call instruction (bl/blx). Arguments should have already been pushed. | 1052 /// Call instruction (bl/blx). Arguments should have already been pushed. |
| 1053 /// Technically bl and the register form of blx can be predicated, but we'll | 1053 /// Technically bl and the register form of blx can be predicated, but we'll |
| 1054 /// leave that out until needed. | 1054 /// leave that out until needed. |
| 1055 class InstARM32Call : public InstARM32 { | 1055 class InstARM32Call : public InstARM32 { |
| 1056 InstARM32Call() = delete; | 1056 InstARM32Call() = delete; |
| 1057 InstARM32Call(const InstARM32Call &) = delete; | 1057 InstARM32Call(const InstARM32Call &) = delete; |
| 1058 InstARM32Call &operator=(const InstARM32Call &) = delete; | 1058 InstARM32Call &operator=(const InstARM32Call &) = delete; |
| 1059 | 1059 |
| 1060 public: | 1060 public: |
| 1061 static InstARM32Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { | 1061 static InstARM32Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { |
| 1062 return new (Func->allocate<InstARM32Call>()) | 1062 return new (Func->allocate<InstARM32Call>()) |
| 1063 InstARM32Call(Func, Dest, CallTarget); | 1063 InstARM32Call(Func, Dest, CallTarget); |
| 1064 } | 1064 } |
| 1065 Operand *getCallTarget() const { return getSrc(0); } | 1065 Operand *getCallTarget() const { return getSrc(0); } |
| 1066 void emit(const Cfg *Func) const override; | 1066 void emit(const Cfg *Func) const override; |
| 1067 void emitIAS(const Cfg *Func) const override; | 1067 void emitIAS(const Cfg *Func) const override; |
| 1068 void dump(const Cfg *Func) const override; | 1068 void dump(const Cfg *Func) const override; |
| 1069 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 1069 static bool classof(const Inst *Instr) { return isClassof(Instr, Call); } |
| 1070 | 1070 |
| 1071 private: | 1071 private: |
| 1072 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 1072 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 1073 }; | 1073 }; |
| 1074 | 1074 |
| 1075 class InstARM32RegisterStackOp : public InstARM32 { | 1075 class InstARM32RegisterStackOp : public InstARM32 { |
| 1076 InstARM32RegisterStackOp() = delete; | 1076 InstARM32RegisterStackOp() = delete; |
| 1077 InstARM32RegisterStackOp(const InstARM32RegisterStackOp &) = delete; | 1077 InstARM32RegisterStackOp(const InstARM32RegisterStackOp &) = delete; |
| 1078 InstARM32RegisterStackOp & | 1078 InstARM32RegisterStackOp & |
| 1079 operator=(const InstARM32RegisterStackOp &) = delete; | 1079 operator=(const InstARM32RegisterStackOp &) = delete; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1108 /// regs, but not both. In any case, the list must be sorted. | 1108 /// regs, but not both. In any case, the list must be sorted. |
| 1109 class InstARM32Pop : public InstARM32RegisterStackOp { | 1109 class InstARM32Pop : public InstARM32RegisterStackOp { |
| 1110 InstARM32Pop() = delete; | 1110 InstARM32Pop() = delete; |
| 1111 InstARM32Pop(const InstARM32Pop &) = delete; | 1111 InstARM32Pop(const InstARM32Pop &) = delete; |
| 1112 InstARM32Pop &operator=(const InstARM32Pop &) = delete; | 1112 InstARM32Pop &operator=(const InstARM32Pop &) = delete; |
| 1113 | 1113 |
| 1114 public: | 1114 public: |
| 1115 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { | 1115 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { |
| 1116 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); | 1116 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); |
| 1117 } | 1117 } |
| 1118 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } | 1118 static bool classof(const Inst *Instr) { return isClassof(Instr, Pop); } |
| 1119 | 1119 |
| 1120 private: | 1120 private: |
| 1121 InstARM32Pop(Cfg *Func, const VarList &Dests); | 1121 InstARM32Pop(Cfg *Func, const VarList &Dests); |
| 1122 virtual const char *getGPROpcode() const final; | 1122 virtual const char *getGPROpcode() const final; |
| 1123 virtual const char *getSRegOpcode() const final; | 1123 virtual const char *getSRegOpcode() const final; |
| 1124 Variable *getStackReg(SizeT Index) const final; | 1124 Variable *getStackReg(SizeT Index) const final; |
| 1125 SizeT getNumStackRegs() const final; | 1125 SizeT getNumStackRegs() const final; |
| 1126 void emitSingleGPR(const Cfg *Func, const EmitForm Form, | 1126 void emitSingleGPR(const Cfg *Func, const EmitForm Form, |
| 1127 const Variable *Reg) const final; | 1127 const Variable *Reg) const final; |
| 1128 void emitMultipleGPRs(const Cfg *Func, const EmitForm Form, | 1128 void emitMultipleGPRs(const Cfg *Func, const EmitForm Form, |
| 1129 IValueT Registers) const final; | 1129 IValueT Registers) const final; |
| 1130 void emitSRegs(const Cfg *Func, const EmitForm Form, const Variable *BaseReg, | 1130 void emitSRegs(const Cfg *Func, const EmitForm Form, const Variable *BaseReg, |
| 1131 SizeT RegCount) const final; | 1131 SizeT RegCount) const final; |
| 1132 | 1132 |
| 1133 VarList Dests; | 1133 VarList Dests; |
| 1134 }; | 1134 }; |
| 1135 | 1135 |
| 1136 /// Pushes a list of registers. Just like Pop (see above), the list may be of | 1136 /// Pushes a list of registers. Just like Pop (see above), the list may be of |
| 1137 /// GPRs, or VFP "s" registers, but not both. | 1137 /// GPRs, or VFP "s" registers, but not both. |
| 1138 class InstARM32Push : public InstARM32RegisterStackOp { | 1138 class InstARM32Push : public InstARM32RegisterStackOp { |
| 1139 InstARM32Push() = delete; | 1139 InstARM32Push() = delete; |
| 1140 InstARM32Push(const InstARM32Push &) = delete; | 1140 InstARM32Push(const InstARM32Push &) = delete; |
| 1141 InstARM32Push &operator=(const InstARM32Push &) = delete; | 1141 InstARM32Push &operator=(const InstARM32Push &) = delete; |
| 1142 | 1142 |
| 1143 public: | 1143 public: |
| 1144 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { | 1144 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { |
| 1145 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); | 1145 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); |
| 1146 } | 1146 } |
| 1147 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } | 1147 static bool classof(const Inst *Instr) { return isClassof(Instr, Push); } |
| 1148 | 1148 |
| 1149 private: | 1149 private: |
| 1150 InstARM32Push(Cfg *Func, const VarList &Srcs); | 1150 InstARM32Push(Cfg *Func, const VarList &Srcs); |
| 1151 const char *getGPROpcode() const final; | 1151 const char *getGPROpcode() const final; |
| 1152 const char *getSRegOpcode() const final; | 1152 const char *getSRegOpcode() const final; |
| 1153 Variable *getStackReg(SizeT Index) const final; | 1153 Variable *getStackReg(SizeT Index) const final; |
| 1154 SizeT getNumStackRegs() const final; | 1154 SizeT getNumStackRegs() const final; |
| 1155 void emitSingleGPR(const Cfg *Func, const EmitForm Form, | 1155 void emitSingleGPR(const Cfg *Func, const EmitForm Form, |
| 1156 const Variable *Reg) const final; | 1156 const Variable *Reg) const final; |
| 1157 void emitMultipleGPRs(const Cfg *Func, const EmitForm Form, | 1157 void emitMultipleGPRs(const Cfg *Func, const EmitForm Form, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1175 InstARM32Ret &operator=(const InstARM32Ret &) = delete; | 1175 InstARM32Ret &operator=(const InstARM32Ret &) = delete; |
| 1176 | 1176 |
| 1177 public: | 1177 public: |
| 1178 static InstARM32Ret *create(Cfg *Func, Variable *LR, | 1178 static InstARM32Ret *create(Cfg *Func, Variable *LR, |
| 1179 Variable *Source = nullptr) { | 1179 Variable *Source = nullptr) { |
| 1180 return new (Func->allocate<InstARM32Ret>()) InstARM32Ret(Func, LR, Source); | 1180 return new (Func->allocate<InstARM32Ret>()) InstARM32Ret(Func, LR, Source); |
| 1181 } | 1181 } |
| 1182 void emit(const Cfg *Func) const override; | 1182 void emit(const Cfg *Func) const override; |
| 1183 void emitIAS(const Cfg *Func) const override; | 1183 void emitIAS(const Cfg *Func) const override; |
| 1184 void dump(const Cfg *Func) const override; | 1184 void dump(const Cfg *Func) const override; |
| 1185 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } | 1185 static bool classof(const Inst *Instr) { return isClassof(Instr, Ret); } |
| 1186 | 1186 |
| 1187 private: | 1187 private: |
| 1188 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source); | 1188 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source); |
| 1189 }; | 1189 }; |
| 1190 | 1190 |
| 1191 /// Store instruction. It's important for liveness that there is no Dest operand | 1191 /// Store instruction. It's important for liveness that there is no Dest operand |
| 1192 /// (OperandARM32Mem instead of Dest Variable). | 1192 /// (OperandARM32Mem instead of Dest Variable). |
| 1193 class InstARM32Str final : public InstARM32Pred { | 1193 class InstARM32Str final : public InstARM32Pred { |
| 1194 InstARM32Str() = delete; | 1194 InstARM32Str() = delete; |
| 1195 InstARM32Str(const InstARM32Str &) = delete; | 1195 InstARM32Str(const InstARM32Str &) = delete; |
| 1196 InstARM32Str &operator=(const InstARM32Str &) = delete; | 1196 InstARM32Str &operator=(const InstARM32Str &) = delete; |
| 1197 | 1197 |
| 1198 public: | 1198 public: |
| 1199 /// Value must be a register. | 1199 /// Value must be a register. |
| 1200 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 1200 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 1201 CondARM32::Cond Predicate) { | 1201 CondARM32::Cond Predicate) { |
| 1202 return new (Func->allocate<InstARM32Str>()) | 1202 return new (Func->allocate<InstARM32Str>()) |
| 1203 InstARM32Str(Func, Value, Mem, Predicate); | 1203 InstARM32Str(Func, Value, Mem, Predicate); |
| 1204 } | 1204 } |
| 1205 void emit(const Cfg *Func) const override; | 1205 void emit(const Cfg *Func) const override; |
| 1206 void emitIAS(const Cfg *Func) const override; | 1206 void emitIAS(const Cfg *Func) const override; |
| 1207 void dump(const Cfg *Func) const override; | 1207 void dump(const Cfg *Func) const override; |
| 1208 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } | 1208 static bool classof(const Inst *Instr) { return isClassof(Instr, Str); } |
| 1209 | 1209 |
| 1210 private: | 1210 private: |
| 1211 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, | 1211 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, |
| 1212 CondARM32::Cond Predicate); | 1212 CondARM32::Cond Predicate); |
| 1213 }; | 1213 }; |
| 1214 | 1214 |
| 1215 /// Exclusive Store instruction. Like its non-exclusive sibling, it's important | 1215 /// Exclusive Store instruction. Like its non-exclusive sibling, it's important |
| 1216 /// for liveness that there is no Dest operand (OperandARM32Mem instead of Dest | 1216 /// for liveness that there is no Dest operand (OperandARM32Mem instead of Dest |
| 1217 /// Variable). | 1217 /// Variable). |
| 1218 class InstARM32Strex final : public InstARM32Pred { | 1218 class InstARM32Strex final : public InstARM32Pred { |
| 1219 InstARM32Strex() = delete; | 1219 InstARM32Strex() = delete; |
| 1220 InstARM32Strex(const InstARM32Strex &) = delete; | 1220 InstARM32Strex(const InstARM32Strex &) = delete; |
| 1221 InstARM32Strex &operator=(const InstARM32Strex &) = delete; | 1221 InstARM32Strex &operator=(const InstARM32Strex &) = delete; |
| 1222 | 1222 |
| 1223 public: | 1223 public: |
| 1224 /// Value must be a register. | 1224 /// Value must be a register. |
| 1225 static InstARM32Strex *create(Cfg *Func, Variable *Dest, Variable *Value, | 1225 static InstARM32Strex *create(Cfg *Func, Variable *Dest, Variable *Value, |
| 1226 OperandARM32Mem *Mem, | 1226 OperandARM32Mem *Mem, |
| 1227 CondARM32::Cond Predicate) { | 1227 CondARM32::Cond Predicate) { |
| 1228 return new (Func->allocate<InstARM32Strex>()) | 1228 return new (Func->allocate<InstARM32Strex>()) |
| 1229 InstARM32Strex(Func, Dest, Value, Mem, Predicate); | 1229 InstARM32Strex(Func, Dest, Value, Mem, Predicate); |
| 1230 } | 1230 } |
| 1231 void emit(const Cfg *Func) const override; | 1231 void emit(const Cfg *Func) const override; |
| 1232 void emitIAS(const Cfg *Func) const override; | 1232 void emitIAS(const Cfg *Func) const override; |
| 1233 void dump(const Cfg *Func) const override; | 1233 void dump(const Cfg *Func) const override; |
| 1234 static bool classof(const Inst *Inst) { return isClassof(Inst, Strex); } | 1234 static bool classof(const Inst *Instr) { return isClassof(Instr, Strex); } |
| 1235 | 1235 |
| 1236 private: | 1236 private: |
| 1237 InstARM32Strex(Cfg *Func, Variable *Dest, Variable *Value, | 1237 InstARM32Strex(Cfg *Func, Variable *Dest, Variable *Value, |
| 1238 OperandARM32Mem *Mem, CondARM32::Cond Predicate); | 1238 OperandARM32Mem *Mem, CondARM32::Cond Predicate); |
| 1239 }; | 1239 }; |
| 1240 | 1240 |
| 1241 class InstARM32Trap : public InstARM32 { | 1241 class InstARM32Trap : public InstARM32 { |
| 1242 InstARM32Trap() = delete; | 1242 InstARM32Trap() = delete; |
| 1243 InstARM32Trap(const InstARM32Trap &) = delete; | 1243 InstARM32Trap(const InstARM32Trap &) = delete; |
| 1244 InstARM32Trap &operator=(const InstARM32Trap &) = delete; | 1244 InstARM32Trap &operator=(const InstARM32Trap &) = delete; |
| 1245 | 1245 |
| 1246 public: | 1246 public: |
| 1247 static InstARM32Trap *create(Cfg *Func) { | 1247 static InstARM32Trap *create(Cfg *Func) { |
| 1248 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func); | 1248 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func); |
| 1249 } | 1249 } |
| 1250 void emit(const Cfg *Func) const override; | 1250 void emit(const Cfg *Func) const override; |
| 1251 void emitIAS(const Cfg *Func) const override; | 1251 void emitIAS(const Cfg *Func) const override; |
| 1252 void dump(const Cfg *Func) const override; | 1252 void dump(const Cfg *Func) const override; |
| 1253 static bool classof(const Inst *Inst) { return isClassof(Inst, Trap); } | 1253 static bool classof(const Inst *Instr) { return isClassof(Instr, Trap); } |
| 1254 | 1254 |
| 1255 private: | 1255 private: |
| 1256 explicit InstARM32Trap(Cfg *Func); | 1256 explicit InstARM32Trap(Cfg *Func); |
| 1257 }; | 1257 }; |
| 1258 | 1258 |
| 1259 /// Unsigned Multiply Long: d.lo, d.hi := x * y | 1259 /// Unsigned Multiply Long: d.lo, d.hi := x * y |
| 1260 class InstARM32Umull : public InstARM32Pred { | 1260 class InstARM32Umull : public InstARM32Pred { |
| 1261 InstARM32Umull() = delete; | 1261 InstARM32Umull() = delete; |
| 1262 InstARM32Umull(const InstARM32Umull &) = delete; | 1262 InstARM32Umull(const InstARM32Umull &) = delete; |
| 1263 InstARM32Umull &operator=(const InstARM32Umull &) = delete; | 1263 InstARM32Umull &operator=(const InstARM32Umull &) = delete; |
| 1264 | 1264 |
| 1265 public: | 1265 public: |
| 1266 /// Everything must be a register. | 1266 /// Everything must be a register. |
| 1267 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi, | 1267 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi, |
| 1268 Variable *Src0, Variable *Src1, | 1268 Variable *Src0, Variable *Src1, |
| 1269 CondARM32::Cond Predicate) { | 1269 CondARM32::Cond Predicate) { |
| 1270 return new (Func->allocate<InstARM32Umull>()) | 1270 return new (Func->allocate<InstARM32Umull>()) |
| 1271 InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate); | 1271 InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate); |
| 1272 } | 1272 } |
| 1273 void emit(const Cfg *Func) const override; | 1273 void emit(const Cfg *Func) const override; |
| 1274 void emitIAS(const Cfg *Func) const override; | 1274 void emitIAS(const Cfg *Func) const override; |
| 1275 void dump(const Cfg *Func) const override; | 1275 void dump(const Cfg *Func) const override; |
| 1276 static bool classof(const Inst *Inst) { return isClassof(Inst, Umull); } | 1276 static bool classof(const Inst *Instr) { return isClassof(Instr, Umull); } |
| 1277 | 1277 |
| 1278 private: | 1278 private: |
| 1279 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0, | 1279 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0, |
| 1280 Variable *Src1, CondARM32::Cond Predicate); | 1280 Variable *Src1, CondARM32::Cond Predicate); |
| 1281 | 1281 |
| 1282 Variable *DestHi; | 1282 Variable *DestHi; |
| 1283 }; | 1283 }; |
| 1284 | 1284 |
| 1285 /// Handles fp2int, int2fp, and fp2fp conversions. | 1285 /// Handles fp2int, int2fp, and fp2fp conversions. |
| 1286 class InstARM32Vcvt final : public InstARM32Pred { | 1286 class InstARM32Vcvt final : public InstARM32Pred { |
| 1287 InstARM32Vcvt() = delete; | 1287 InstARM32Vcvt() = delete; |
| 1288 InstARM32Vcvt(const InstARM32Vcvt &) = delete; | 1288 InstARM32Vcvt(const InstARM32Vcvt &) = delete; |
| 1289 InstARM32Vcvt &operator=(const InstARM32Vcvt &) = delete; | 1289 InstARM32Vcvt &operator=(const InstARM32Vcvt &) = delete; |
| 1290 | 1290 |
| 1291 public: | 1291 public: |
| 1292 enum VcvtVariant { S2si, S2ui, Si2s, Ui2s, D2si, D2ui, Si2d, Ui2d, S2d, D2s }; | 1292 enum VcvtVariant { S2si, S2ui, Si2s, Ui2s, D2si, D2ui, Si2d, Ui2d, S2d, D2s }; |
| 1293 static InstARM32Vcvt *create(Cfg *Func, Variable *Dest, Variable *Src, | 1293 static InstARM32Vcvt *create(Cfg *Func, Variable *Dest, Variable *Src, |
| 1294 VcvtVariant Variant, CondARM32::Cond Predicate) { | 1294 VcvtVariant Variant, CondARM32::Cond Predicate) { |
| 1295 return new (Func->allocate<InstARM32Vcvt>()) | 1295 return new (Func->allocate<InstARM32Vcvt>()) |
| 1296 InstARM32Vcvt(Func, Dest, Src, Variant, Predicate); | 1296 InstARM32Vcvt(Func, Dest, Src, Variant, Predicate); |
| 1297 } | 1297 } |
| 1298 void emit(const Cfg *Func) const override; | 1298 void emit(const Cfg *Func) const override; |
| 1299 void emitIAS(const Cfg *Func) const override; | 1299 void emitIAS(const Cfg *Func) const override; |
| 1300 void dump(const Cfg *Func) const override; | 1300 void dump(const Cfg *Func) const override; |
| 1301 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcvt); } | 1301 static bool classof(const Inst *Instr) { return isClassof(Instr, Vcvt); } |
| 1302 | 1302 |
| 1303 private: | 1303 private: |
| 1304 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant, | 1304 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant, |
| 1305 CondARM32::Cond Predicate); | 1305 CondARM32::Cond Predicate); |
| 1306 | 1306 |
| 1307 const VcvtVariant Variant; | 1307 const VcvtVariant Variant; |
| 1308 }; | 1308 }; |
| 1309 | 1309 |
| 1310 /// Handles (some of) vmov's various formats. | 1310 /// Handles (some of) vmov's various formats. |
| 1311 class InstARM32Mov final : public InstARM32Pred { | 1311 class InstARM32Mov final : public InstARM32Pred { |
| 1312 InstARM32Mov() = delete; | 1312 InstARM32Mov() = delete; |
| 1313 InstARM32Mov(const InstARM32Mov &) = delete; | 1313 InstARM32Mov(const InstARM32Mov &) = delete; |
| 1314 InstARM32Mov &operator=(const InstARM32Mov &) = delete; | 1314 InstARM32Mov &operator=(const InstARM32Mov &) = delete; |
| 1315 | 1315 |
| 1316 public: | 1316 public: |
| 1317 static InstARM32Mov *create(Cfg *Func, Variable *Dest, Operand *Src, | 1317 static InstARM32Mov *create(Cfg *Func, Variable *Dest, Operand *Src, |
| 1318 CondARM32::Cond Predicate) { | 1318 CondARM32::Cond Predicate) { |
| 1319 return new (Func->allocate<InstARM32Mov>()) | 1319 return new (Func->allocate<InstARM32Mov>()) |
| 1320 InstARM32Mov(Func, Dest, Src, Predicate); | 1320 InstARM32Mov(Func, Dest, Src, Predicate); |
| 1321 } | 1321 } |
| 1322 bool isRedundantAssign() const override { | 1322 bool isRedundantAssign() const override { |
| 1323 return !isMultiDest() && !isMultiSource() && | 1323 return !isMultiDest() && !isMultiSource() && |
| 1324 getPredicate() == CondARM32::AL && | 1324 getPredicate() == CondARM32::AL && |
| 1325 checkForRedundantAssign(getDest(), getSrc(0)); | 1325 checkForRedundantAssign(getDest(), getSrc(0)); |
| 1326 } | 1326 } |
| 1327 bool isVarAssign() const override { return llvm::isa<Variable>(getSrc(0)); } | 1327 bool isVarAssign() const override { return llvm::isa<Variable>(getSrc(0)); } |
| 1328 void emit(const Cfg *Func) const override; | 1328 void emit(const Cfg *Func) const override; |
| 1329 void emitIAS(const Cfg *Func) const override; | 1329 void emitIAS(const Cfg *Func) const override; |
| 1330 void dump(const Cfg *Func) const override; | 1330 void dump(const Cfg *Func) const override; |
| 1331 static bool classof(const Inst *Inst) { return isClassof(Inst, Mov); } | 1331 static bool classof(const Inst *Instr) { return isClassof(Instr, Mov); } |
| 1332 | 1332 |
| 1333 bool isMultiDest() const { return DestHi != nullptr; } | 1333 bool isMultiDest() const { return DestHi != nullptr; } |
| 1334 | 1334 |
| 1335 bool isMultiSource() const { | 1335 bool isMultiSource() const { |
| 1336 assert(getSrcSize() == 1 || getSrcSize() == 2); | 1336 assert(getSrcSize() == 1 || getSrcSize() == 2); |
| 1337 return getSrcSize() == 2; | 1337 return getSrcSize() == 2; |
| 1338 } | 1338 } |
| 1339 | 1339 |
| 1340 Variable *getDestHi() const { return DestHi; } | 1340 Variable *getDestHi() const { return DestHi; } |
| 1341 | 1341 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1367 } | 1367 } |
| 1368 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, | 1368 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, |
| 1369 OperandARM32FlexFpZero *Src1, | 1369 OperandARM32FlexFpZero *Src1, |
| 1370 CondARM32::Cond Predicate) { | 1370 CondARM32::Cond Predicate) { |
| 1371 return new (Func->allocate<InstARM32Vcmp>()) | 1371 return new (Func->allocate<InstARM32Vcmp>()) |
| 1372 InstARM32Vcmp(Func, Src0, Src1, Predicate); | 1372 InstARM32Vcmp(Func, Src0, Src1, Predicate); |
| 1373 } | 1373 } |
| 1374 void emit(const Cfg *Func) const override; | 1374 void emit(const Cfg *Func) const override; |
| 1375 void emitIAS(const Cfg *Func) const override; | 1375 void emitIAS(const Cfg *Func) const override; |
| 1376 void dump(const Cfg *Func) const override; | 1376 void dump(const Cfg *Func) const override; |
| 1377 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcmp); } | 1377 static bool classof(const Inst *Instr) { return isClassof(Instr, Vcmp); } |
| 1378 | 1378 |
| 1379 private: | 1379 private: |
| 1380 InstARM32Vcmp(Cfg *Func, Variable *Src0, Operand *Src1, | 1380 InstARM32Vcmp(Cfg *Func, Variable *Src0, Operand *Src1, |
| 1381 CondARM32::Cond Predicate); | 1381 CondARM32::Cond Predicate); |
| 1382 }; | 1382 }; |
| 1383 | 1383 |
| 1384 /// Copies the FP Status and Control Register the core flags. | 1384 /// Copies the FP Status and Control Register the core flags. |
| 1385 class InstARM32Vmrs final : public InstARM32Pred { | 1385 class InstARM32Vmrs final : public InstARM32Pred { |
| 1386 InstARM32Vmrs() = delete; | 1386 InstARM32Vmrs() = delete; |
| 1387 InstARM32Vmrs(const InstARM32Vmrs &) = delete; | 1387 InstARM32Vmrs(const InstARM32Vmrs &) = delete; |
| 1388 InstARM32Vmrs &operator=(const InstARM32Vmrs &) = delete; | 1388 InstARM32Vmrs &operator=(const InstARM32Vmrs &) = delete; |
| 1389 | 1389 |
| 1390 public: | 1390 public: |
| 1391 static InstARM32Vmrs *create(Cfg *Func, CondARM32::Cond Predicate) { | 1391 static InstARM32Vmrs *create(Cfg *Func, CondARM32::Cond Predicate) { |
| 1392 return new (Func->allocate<InstARM32Vmrs>()) InstARM32Vmrs(Func, Predicate); | 1392 return new (Func->allocate<InstARM32Vmrs>()) InstARM32Vmrs(Func, Predicate); |
| 1393 } | 1393 } |
| 1394 void emit(const Cfg *Func) const override; | 1394 void emit(const Cfg *Func) const override; |
| 1395 void emitIAS(const Cfg *Func) const override; | 1395 void emitIAS(const Cfg *Func) const override; |
| 1396 void dump(const Cfg *Func) const override; | 1396 void dump(const Cfg *Func) const override; |
| 1397 static bool classof(const Inst *Inst) { return isClassof(Inst, Vmrs); } | 1397 static bool classof(const Inst *Instr) { return isClassof(Instr, Vmrs); } |
| 1398 | 1398 |
| 1399 private: | 1399 private: |
| 1400 InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate); | 1400 InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate); |
| 1401 }; | 1401 }; |
| 1402 | 1402 |
| 1403 class InstARM32Vabs final : public InstARM32Pred { | 1403 class InstARM32Vabs final : public InstARM32Pred { |
| 1404 InstARM32Vabs() = delete; | 1404 InstARM32Vabs() = delete; |
| 1405 InstARM32Vabs(const InstARM32Vabs &) = delete; | 1405 InstARM32Vabs(const InstARM32Vabs &) = delete; |
| 1406 InstARM32Vabs &operator=(const InstARM32Vabs &) = delete; | 1406 InstARM32Vabs &operator=(const InstARM32Vabs &) = delete; |
| 1407 | 1407 |
| 1408 public: | 1408 public: |
| 1409 static InstARM32Vabs *create(Cfg *Func, Variable *Dest, Variable *Src, | 1409 static InstARM32Vabs *create(Cfg *Func, Variable *Dest, Variable *Src, |
| 1410 CondARM32::Cond Predicate) { | 1410 CondARM32::Cond Predicate) { |
| 1411 return new (Func->allocate<InstARM32Vabs>()) | 1411 return new (Func->allocate<InstARM32Vabs>()) |
| 1412 InstARM32Vabs(Func, Dest, Src, Predicate); | 1412 InstARM32Vabs(Func, Dest, Src, Predicate); |
| 1413 } | 1413 } |
| 1414 void emit(const Cfg *Func) const override; | 1414 void emit(const Cfg *Func) const override; |
| 1415 void emitIAS(const Cfg *Func) const override; | 1415 void emitIAS(const Cfg *Func) const override; |
| 1416 void dump(const Cfg *Func) const override; | 1416 void dump(const Cfg *Func) const override; |
| 1417 static bool classof(const Inst *Inst) { return isClassof(Inst, Vabs); } | 1417 static bool classof(const Inst *Instr) { return isClassof(Instr, Vabs); } |
| 1418 | 1418 |
| 1419 private: | 1419 private: |
| 1420 InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src, | 1420 InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src, |
| 1421 CondARM32::Cond Predicate); | 1421 CondARM32::Cond Predicate); |
| 1422 }; | 1422 }; |
| 1423 | 1423 |
| 1424 class InstARM32Dmb final : public InstARM32Pred { | 1424 class InstARM32Dmb final : public InstARM32Pred { |
| 1425 InstARM32Dmb() = delete; | 1425 InstARM32Dmb() = delete; |
| 1426 InstARM32Dmb(const InstARM32Dmb &) = delete; | 1426 InstARM32Dmb(const InstARM32Dmb &) = delete; |
| 1427 InstARM32Dmb &operator=(const InstARM32Dmb &) = delete; | 1427 InstARM32Dmb &operator=(const InstARM32Dmb &) = delete; |
| 1428 | 1428 |
| 1429 public: | 1429 public: |
| 1430 static InstARM32Dmb *create(Cfg *Func) { | 1430 static InstARM32Dmb *create(Cfg *Func) { |
| 1431 return new (Func->allocate<InstARM32Dmb>()) InstARM32Dmb(Func); | 1431 return new (Func->allocate<InstARM32Dmb>()) InstARM32Dmb(Func); |
| 1432 } | 1432 } |
| 1433 void emit(const Cfg *Func) const override; | 1433 void emit(const Cfg *Func) const override; |
| 1434 void emitIAS(const Cfg *Func) const override; | 1434 void emitIAS(const Cfg *Func) const override; |
| 1435 void dump(const Cfg *Func) const override; | 1435 void dump(const Cfg *Func) const override; |
| 1436 static bool classof(const Inst *Inst) { return isClassof(Inst, Dmb); } | 1436 static bool classof(const Inst *Instr) { return isClassof(Instr, Dmb); } |
| 1437 | 1437 |
| 1438 private: | 1438 private: |
| 1439 explicit InstARM32Dmb(Cfg *Func); | 1439 explicit InstARM32Dmb(Cfg *Func); |
| 1440 }; | 1440 }; |
| 1441 | 1441 |
| 1442 // Declare partial template specializations of emit() methods that already have | 1442 // Declare partial template specializations of emit() methods that already have |
| 1443 // default implementations. Without this, there is the possibility of ODR | 1443 // default implementations. Without this, there is the possibility of ODR |
| 1444 // violations and link errors. | 1444 // violations and link errors. |
| 1445 | 1445 |
| 1446 template <> void InstARM32Ldr::emit(const Cfg *Func) const; | 1446 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
| 1447 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1447 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
| 1448 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1448 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
| 1449 | 1449 |
| 1450 } // end of namespace ARM32 | 1450 } // end of namespace ARM32 |
| 1451 } // end of namespace Ice | 1451 } // end of namespace Ice |
| 1452 | 1452 |
| 1453 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1453 #endif // SUBZERO_SRC_ICEINSTARM32_H |
| OLD | NEW |