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 |