Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Side by Side Diff: src/IceInstARM32.h

Issue 1418523002: Add hybrid assembler concept to ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 static const char *getWidthString(Type Ty); 337 static const char *getWidthString(Type Ty);
338 static const char *getVecWidthString(Type Ty); 338 static const char *getVecWidthString(Type Ty);
339 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); 339 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond);
340 340
341 /// Shared emit routines for common forms of instructions. 341 /// Shared emit routines for common forms of instructions.
342 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, 342 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst,
343 const Cfg *Func); 343 const Cfg *Func);
344 344
345 void dump(const Cfg *Func) const override; 345 void dump(const Cfg *Func) const override;
346 346
347 void emitIAS(const Cfg *Func) const override;
348
347 protected: 349 protected:
348 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) 350 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest)
349 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 351 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
350 352
351 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { 353 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) {
352 return Inst->getKind() == static_cast<InstKind>(MyKind); 354 return Inst->getKind() == static_cast<InstKind>(MyKind);
353 } 355 }
356
357 // Generates text of assembly instruction using method emit(), and then adds
358 // to the assembly buffer as a Fixup.
359 void emitUsingTextFixup(const Cfg *Func) const;
354 }; 360 };
355 361
356 /// A predicable ARM instruction. 362 /// A predicable ARM instruction.
357 class InstARM32Pred : public InstARM32 { 363 class InstARM32Pred : public InstARM32 {
358 InstARM32Pred() = delete; 364 InstARM32Pred() = delete;
359 InstARM32Pred(const InstARM32Pred &) = delete; 365 InstARM32Pred(const InstARM32Pred &) = delete;
360 InstARM32Pred &operator=(const InstARM32Pred &) = delete; 366 InstARM32Pred &operator=(const InstARM32Pred &) = delete;
361 367
362 public: 368 public:
363 InstARM32Pred(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest, 369 InstARM32Pred(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 static InstARM32UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src, 411 static InstARM32UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src,
406 CondARM32::Cond Predicate) { 412 CondARM32::Cond Predicate) {
407 return new (Func->allocate<InstARM32UnaryopGPR>()) 413 return new (Func->allocate<InstARM32UnaryopGPR>())
408 InstARM32UnaryopGPR(Func, Dest, Src, Predicate); 414 InstARM32UnaryopGPR(Func, Dest, Src, Predicate);
409 } 415 }
410 void emit(const Cfg *Func) const override { 416 void emit(const Cfg *Func) const override {
411 if (!BuildDefs::dump()) 417 if (!BuildDefs::dump())
412 return; 418 return;
413 emitUnaryopGPR(Opcode, this, Func, NeedsWidthSuffix); 419 emitUnaryopGPR(Opcode, this, Func, NeedsWidthSuffix);
414 } 420 }
415 void emitIAS(const Cfg *Func) const override {
416 (void)Func;
417 llvm_unreachable("Not yet implemented");
418 }
419 void dump(const Cfg *Func) const override { 421 void dump(const Cfg *Func) const override {
420 if (!BuildDefs::dump()) 422 if (!BuildDefs::dump())
421 return; 423 return;
422 Ostream &Str = Func->getContext()->getStrDump(); 424 Ostream &Str = Func->getContext()->getStrDump();
423 dumpDest(Func); 425 dumpDest(Func);
424 Str << " = "; 426 Str << " = ";
425 dumpOpcodePred(Str, Opcode, getDest()->getType()); 427 dumpOpcodePred(Str, Opcode, getDest()->getType());
426 Str << " "; 428 Str << " ";
427 dumpSources(Func); 429 dumpSources(Func);
428 } 430 }
(...skipping 20 matching lines...) Expand all
449 static InstARM32UnaryopFP *create(Cfg *Func, Variable *Dest, Variable *Src, 451 static InstARM32UnaryopFP *create(Cfg *Func, Variable *Dest, Variable *Src,
450 CondARM32::Cond Predicate) { 452 CondARM32::Cond Predicate) {
451 return new (Func->allocate<InstARM32UnaryopFP>()) 453 return new (Func->allocate<InstARM32UnaryopFP>())
452 InstARM32UnaryopFP(Func, Dest, Src, Predicate); 454 InstARM32UnaryopFP(Func, Dest, Src, Predicate);
453 } 455 }
454 void emit(const Cfg *Func) const override { 456 void emit(const Cfg *Func) const override {
455 if (!BuildDefs::dump()) 457 if (!BuildDefs::dump())
456 return; 458 return;
457 emitUnaryopFP(Opcode, this, Func); 459 emitUnaryopFP(Opcode, this, Func);
458 } 460 }
459 void emitIAS(const Cfg *Func) const override {
460 (void)Func;
461 llvm::report_fatal_error("Not yet implemented");
462 }
463 void dump(const Cfg *Func) const override { 461 void dump(const Cfg *Func) const override {
464 if (!BuildDefs::dump()) 462 if (!BuildDefs::dump())
465 return; 463 return;
466 Ostream &Str = Func->getContext()->getStrDump(); 464 Ostream &Str = Func->getContext()->getStrDump();
467 dumpDest(Func); 465 dumpDest(Func);
468 Str << " = "; 466 Str << " = ";
469 dumpOpcodePred(Str, Opcode, getDest()->getType()); 467 dumpOpcodePred(Str, Opcode, getDest()->getType());
470 Str << " "; 468 Str << " ";
471 dumpSources(Func); 469 dumpSources(Func);
472 } 470 }
(...skipping 21 matching lines...) Expand all
494 static InstARM32TwoAddrGPR *create(Cfg *Func, Variable *Dest, Operand *Src, 492 static InstARM32TwoAddrGPR *create(Cfg *Func, Variable *Dest, Operand *Src,
495 CondARM32::Cond Predicate) { 493 CondARM32::Cond Predicate) {
496 return new (Func->allocate<InstARM32TwoAddrGPR>()) 494 return new (Func->allocate<InstARM32TwoAddrGPR>())
497 InstARM32TwoAddrGPR(Func, Dest, Src, Predicate); 495 InstARM32TwoAddrGPR(Func, Dest, Src, Predicate);
498 } 496 }
499 void emit(const Cfg *Func) const override { 497 void emit(const Cfg *Func) const override {
500 if (!BuildDefs::dump()) 498 if (!BuildDefs::dump())
501 return; 499 return;
502 emitTwoAddr(Opcode, this, Func); 500 emitTwoAddr(Opcode, this, Func);
503 } 501 }
504 void emitIAS(const Cfg *Func) const override { 502 void emitIAS(const Cfg *Func) const override;
505 (void)Func;
506 llvm::report_fatal_error("Not yet implemented");
507 }
508 void dump(const Cfg *Func) const override { 503 void dump(const Cfg *Func) const override {
509 if (!BuildDefs::dump()) 504 if (!BuildDefs::dump())
510 return; 505 return;
511 Ostream &Str = Func->getContext()->getStrDump(); 506 Ostream &Str = Func->getContext()->getStrDump();
512 dumpDest(Func); 507 dumpDest(Func);
513 Str << " = "; 508 Str << " = ";
514 dumpOpcodePred(Str, Opcode, getDest()->getType()); 509 dumpOpcodePred(Str, Opcode, getDest()->getType());
515 Str << " "; 510 Str << " ";
516 dumpSources(Func); 511 dumpSources(Func);
517 } 512 }
(...skipping 17 matching lines...) Expand all
535 InstARM32LoadBase(const InstARM32LoadBase &) = delete; 530 InstARM32LoadBase(const InstARM32LoadBase &) = delete;
536 InstARM32LoadBase &operator=(const InstARM32LoadBase &) = delete; 531 InstARM32LoadBase &operator=(const InstARM32LoadBase &) = delete;
537 532
538 public: 533 public:
539 static InstARM32LoadBase *create(Cfg *Func, Variable *Dest, Operand *Source, 534 static InstARM32LoadBase *create(Cfg *Func, Variable *Dest, Operand *Source,
540 CondARM32::Cond Predicate) { 535 CondARM32::Cond Predicate) {
541 return new (Func->allocate<InstARM32LoadBase>()) 536 return new (Func->allocate<InstARM32LoadBase>())
542 InstARM32LoadBase(Func, Dest, Source, Predicate); 537 InstARM32LoadBase(Func, Dest, Source, Predicate);
543 } 538 }
544 void emit(const Cfg *Func) const override; 539 void emit(const Cfg *Func) const override;
545 void emitIAS(const Cfg *Func) const override;
546 void dump(const Cfg *Func) const override { 540 void dump(const Cfg *Func) const override {
547 if (!BuildDefs::dump()) 541 if (!BuildDefs::dump())
548 return; 542 return;
549 Ostream &Str = Func->getContext()->getStrDump(); 543 Ostream &Str = Func->getContext()->getStrDump();
550 dumpOpcodePred(Str, Opcode, getDest()->getType()); 544 dumpOpcodePred(Str, Opcode, getDest()->getType());
551 Str << " "; 545 Str << " ";
552 dumpDest(Func); 546 dumpDest(Func);
553 Str << ", "; 547 Str << ", ";
554 dumpSources(Func); 548 dumpSources(Func);
555 } 549 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0, 623 static InstARM32ThreeAddrFP *create(Cfg *Func, Variable *Dest, Variable *Src0,
630 Variable *Src1) { 624 Variable *Src1) {
631 return new (Func->allocate<InstARM32ThreeAddrFP>()) 625 return new (Func->allocate<InstARM32ThreeAddrFP>())
632 InstARM32ThreeAddrFP(Func, Dest, Src0, Src1); 626 InstARM32ThreeAddrFP(Func, Dest, Src0, Src1);
633 } 627 }
634 void emit(const Cfg *Func) const override { 628 void emit(const Cfg *Func) const override {
635 if (!BuildDefs::dump()) 629 if (!BuildDefs::dump())
636 return; 630 return;
637 emitThreeAddrFP(Opcode, this, Func); 631 emitThreeAddrFP(Opcode, this, Func);
638 } 632 }
639 void emitIAS(const Cfg *Func) const override {
640 (void)Func;
641 llvm::report_fatal_error("Not yet implemented");
642 }
643 void dump(const Cfg *Func) const override { 633 void dump(const Cfg *Func) const override {
644 if (!BuildDefs::dump()) 634 if (!BuildDefs::dump())
645 return; 635 return;
646 Ostream &Str = Func->getContext()->getStrDump(); 636 Ostream &Str = Func->getContext()->getStrDump();
647 dumpDest(Func); 637 dumpDest(Func);
648 Str << " = "; 638 Str << " = ";
649 Str << Opcode << "." << getDest()->getType() << " "; 639 Str << Opcode << "." << getDest()->getType() << " ";
650 dumpSources(Func); 640 dumpSources(Func);
651 } 641 }
652 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 642 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
(...skipping 22 matching lines...) Expand all
675 Variable *Src1, Variable *Src2, 665 Variable *Src1, Variable *Src2,
676 CondARM32::Cond Predicate) { 666 CondARM32::Cond Predicate) {
677 return new (Func->allocate<InstARM32FourAddrGPR>()) 667 return new (Func->allocate<InstARM32FourAddrGPR>())
678 InstARM32FourAddrGPR(Func, Dest, Src0, Src1, Src2, Predicate); 668 InstARM32FourAddrGPR(Func, Dest, Src0, Src1, Src2, Predicate);
679 } 669 }
680 void emit(const Cfg *Func) const override { 670 void emit(const Cfg *Func) const override {
681 if (!BuildDefs::dump()) 671 if (!BuildDefs::dump())
682 return; 672 return;
683 emitFourAddr(Opcode, this, Func); 673 emitFourAddr(Opcode, this, Func);
684 } 674 }
685 void emitIAS(const Cfg *Func) const override {
686 (void)Func;
687 llvm::report_fatal_error("Not yet implemented");
688 }
689 void dump(const Cfg *Func) const override { 675 void dump(const Cfg *Func) const override {
690 if (!BuildDefs::dump()) 676 if (!BuildDefs::dump())
691 return; 677 return;
692 Ostream &Str = Func->getContext()->getStrDump(); 678 Ostream &Str = Func->getContext()->getStrDump();
693 dumpDest(Func); 679 dumpDest(Func);
694 Str << " = "; 680 Str << " = ";
695 dumpOpcodePred(Str, Opcode, getDest()->getType()); 681 dumpOpcodePred(Str, Opcode, getDest()->getType());
696 Str << " "; 682 Str << " ";
697 dumpSources(Func); 683 dumpSources(Func);
698 } 684 }
(...skipping 23 matching lines...) Expand all
722 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1, 708 static InstARM32CmpLike *create(Cfg *Func, Variable *Src0, Operand *Src1,
723 CondARM32::Cond Predicate) { 709 CondARM32::Cond Predicate) {
724 return new (Func->allocate<InstARM32CmpLike>()) 710 return new (Func->allocate<InstARM32CmpLike>())
725 InstARM32CmpLike(Func, Src0, Src1, Predicate); 711 InstARM32CmpLike(Func, Src0, Src1, Predicate);
726 } 712 }
727 void emit(const Cfg *Func) const override { 713 void emit(const Cfg *Func) const override {
728 if (!BuildDefs::dump()) 714 if (!BuildDefs::dump())
729 return; 715 return;
730 emitCmpLike(Opcode, this, Func); 716 emitCmpLike(Opcode, this, Func);
731 } 717 }
732 void emitIAS(const Cfg *Func) const override {
733 (void)Func;
734 llvm_unreachable("Not yet implemented");
735 }
736 void dump(const Cfg *Func) const override { 718 void dump(const Cfg *Func) const override {
737 if (!BuildDefs::dump()) 719 if (!BuildDefs::dump())
738 return; 720 return;
739 Ostream &Str = Func->getContext()->getStrDump(); 721 Ostream &Str = Func->getContext()->getStrDump();
740 dumpOpcodePred(Str, Opcode, getSrc(0)->getType()); 722 dumpOpcodePred(Str, Opcode, getSrc(0)->getType());
741 Str << " "; 723 Str << " ";
742 dumpSources(Func); 724 dumpSources(Func);
743 } 725 }
744 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 726 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
745 727
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 InstARM32Label &operator=(const InstARM32Label &) = delete; 785 InstARM32Label &operator=(const InstARM32Label &) = delete;
804 786
805 public: 787 public:
806 static InstARM32Label *create(Cfg *Func, TargetARM32 *Target) { 788 static InstARM32Label *create(Cfg *Func, TargetARM32 *Target) {
807 return new (Func->allocate<InstARM32Label>()) InstARM32Label(Func, Target); 789 return new (Func->allocate<InstARM32Label>()) InstARM32Label(Func, Target);
808 } 790 }
809 uint32_t getEmitInstCount() const override { return 0; } 791 uint32_t getEmitInstCount() const override { return 0; }
810 IceString getName(const Cfg *Func) const; 792 IceString getName(const Cfg *Func) const;
811 SizeT getNumber() const { return Number; } 793 SizeT getNumber() const { return Number; }
812 void emit(const Cfg *Func) const override; 794 void emit(const Cfg *Func) const override;
813 void emitIAS(const Cfg *Func) const override;
814 void dump(const Cfg *Func) const override; 795 void dump(const Cfg *Func) const override;
815 796
816 private: 797 private:
817 InstARM32Label(Cfg *Func, TargetARM32 *Target); 798 InstARM32Label(Cfg *Func, TargetARM32 *Target);
818 799
819 SizeT Number; // used for unique label generation. 800 SizeT Number; // used for unique label generation.
820 }; 801 };
821 802
822 /// Direct branch instruction. 803 /// Direct branch instruction.
823 class InstARM32Br : public InstARM32Pred { 804 class InstARM32Br : public InstARM32Pred {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 ++Sum; 853 ++Sum;
873 if (getTargetFalse()) 854 if (getTargetFalse())
874 ++Sum; 855 ++Sum;
875 return Sum; 856 return Sum;
876 } 857 }
877 bool isUnconditionalBranch() const override { 858 bool isUnconditionalBranch() const override {
878 return getPredicate() == CondARM32::AL; 859 return getPredicate() == CondARM32::AL;
879 } 860 }
880 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override; 861 bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override;
881 void emit(const Cfg *Func) const override; 862 void emit(const Cfg *Func) const override;
882 void emitIAS(const Cfg *Func) const override;
883 void dump(const Cfg *Func) const override; 863 void dump(const Cfg *Func) const override;
884 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } 864 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
885 865
886 private: 866 private:
887 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 867 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
888 const InstARM32Label *Label, CondARM32::Cond Predicate); 868 const InstARM32Label *Label, CondARM32::Cond Predicate);
889 869
890 const CfgNode *TargetTrue; 870 const CfgNode *TargetTrue;
891 const CfgNode *TargetFalse; 871 const CfgNode *TargetFalse;
892 const InstARM32Label *Label; // Intra-block branch target 872 const InstARM32Label *Label; // Intra-block branch target
(...skipping 10 matching lines...) Expand all
903 /// Note: We need both Amount and SrcAmount. If Amount is too large then it 883 /// Note: We need both Amount and SrcAmount. If Amount is too large then it
904 /// needs to be copied to a register (so SrcAmount could be a register). 884 /// needs to be copied to a register (so SrcAmount could be a register).
905 /// However, we also need the numeric Amount for bookkeeping, and it's hard to 885 /// However, we also need the numeric Amount for bookkeeping, and it's hard to
906 /// pull that from the generic SrcAmount operand. 886 /// pull that from the generic SrcAmount operand.
907 static InstARM32AdjustStack *create(Cfg *Func, Variable *SP, SizeT Amount, 887 static InstARM32AdjustStack *create(Cfg *Func, Variable *SP, SizeT Amount,
908 Operand *SrcAmount) { 888 Operand *SrcAmount) {
909 return new (Func->allocate<InstARM32AdjustStack>()) 889 return new (Func->allocate<InstARM32AdjustStack>())
910 InstARM32AdjustStack(Func, SP, Amount, SrcAmount); 890 InstARM32AdjustStack(Func, SP, Amount, SrcAmount);
911 } 891 }
912 void emit(const Cfg *Func) const override; 892 void emit(const Cfg *Func) const override;
913 void emitIAS(const Cfg *Func) const override;
914 void dump(const Cfg *Func) const override; 893 void dump(const Cfg *Func) const override;
915 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); } 894 static bool classof(const Inst *Inst) { return isClassof(Inst, Adjuststack); }
916 SizeT getAmount() const { return Amount; } 895 SizeT getAmount() const { return Amount; }
917 896
918 private: 897 private:
919 InstARM32AdjustStack(Cfg *Func, Variable *SP, SizeT Amount, 898 InstARM32AdjustStack(Cfg *Func, Variable *SP, SizeT Amount,
920 Operand *SrcAmount); 899 Operand *SrcAmount);
921 const SizeT Amount; 900 const SizeT Amount;
922 }; 901 };
923 902
924 /// Call instruction (bl/blx). Arguments should have already been pushed. 903 /// Call instruction (bl/blx). Arguments should have already been pushed.
925 /// Technically bl and the register form of blx can be predicated, but we'll 904 /// Technically bl and the register form of blx can be predicated, but we'll
926 /// leave that out until needed. 905 /// leave that out until needed.
927 class InstARM32Call : public InstARM32 { 906 class InstARM32Call : public InstARM32 {
928 InstARM32Call() = delete; 907 InstARM32Call() = delete;
929 InstARM32Call(const InstARM32Call &) = delete; 908 InstARM32Call(const InstARM32Call &) = delete;
930 InstARM32Call &operator=(const InstARM32Call &) = delete; 909 InstARM32Call &operator=(const InstARM32Call &) = delete;
931 910
932 public: 911 public:
933 static InstARM32Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 912 static InstARM32Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
934 return new (Func->allocate<InstARM32Call>()) 913 return new (Func->allocate<InstARM32Call>())
935 InstARM32Call(Func, Dest, CallTarget); 914 InstARM32Call(Func, Dest, CallTarget);
936 } 915 }
937 Operand *getCallTarget() const { return getSrc(0); } 916 Operand *getCallTarget() const { return getSrc(0); }
938 void emit(const Cfg *Func) const override; 917 void emit(const Cfg *Func) const override;
939 void emitIAS(const Cfg *Func) const override;
940 void dump(const Cfg *Func) const override; 918 void dump(const Cfg *Func) const override;
941 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 919 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
942 920
943 private: 921 private:
944 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 922 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
945 }; 923 };
946 924
947 /// Pop into a list of GPRs. Technically this can be predicated, but we don't 925 /// Pop into a list of GPRs. Technically this can be predicated, but we don't
948 /// need that functionality. 926 /// need that functionality.
949 class InstARM32Pop : public InstARM32 { 927 class InstARM32Pop : public InstARM32 {
950 InstARM32Pop() = delete; 928 InstARM32Pop() = delete;
951 InstARM32Pop(const InstARM32Pop &) = delete; 929 InstARM32Pop(const InstARM32Pop &) = delete;
952 InstARM32Pop &operator=(const InstARM32Pop &) = delete; 930 InstARM32Pop &operator=(const InstARM32Pop &) = delete;
953 931
954 public: 932 public:
955 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { 933 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) {
956 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); 934 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests);
957 } 935 }
958 void emit(const Cfg *Func) const override; 936 void emit(const Cfg *Func) const override;
959 void emitIAS(const Cfg *Func) const override;
960 void dump(const Cfg *Func) const override; 937 void dump(const Cfg *Func) const override;
961 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } 938 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
962 939
963 private: 940 private:
964 InstARM32Pop(Cfg *Func, const VarList &Dests); 941 InstARM32Pop(Cfg *Func, const VarList &Dests);
965 942
966 VarList Dests; 943 VarList Dests;
967 }; 944 };
968 945
969 /// Push a list of GPRs. Technically this can be predicated, but we don't need 946 /// Push a list of GPRs. Technically this can be predicated, but we don't need
970 /// that functionality. 947 /// that functionality.
971 class InstARM32Push : public InstARM32 { 948 class InstARM32Push : public InstARM32 {
972 InstARM32Push() = delete; 949 InstARM32Push() = delete;
973 InstARM32Push(const InstARM32Push &) = delete; 950 InstARM32Push(const InstARM32Push &) = delete;
974 InstARM32Push &operator=(const InstARM32Push &) = delete; 951 InstARM32Push &operator=(const InstARM32Push &) = delete;
975 952
976 public: 953 public:
977 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { 954 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) {
978 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); 955 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs);
979 } 956 }
980 void emit(const Cfg *Func) const override; 957 void emit(const Cfg *Func) const override;
981 void emitIAS(const Cfg *Func) const override;
982 void dump(const Cfg *Func) const override; 958 void dump(const Cfg *Func) const override;
983 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } 959 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
984 960
985 private: 961 private:
986 InstARM32Push(Cfg *Func, const VarList &Srcs); 962 InstARM32Push(Cfg *Func, const VarList &Srcs);
987 }; 963 };
988 964
989 /// Ret pseudo-instruction. This is actually a "bx" instruction with an "lr" 965 /// Ret pseudo-instruction. This is actually a "bx" instruction with an "lr"
990 /// register operand, but epilogue lowering will search for a Ret instead of a 966 /// register operand, but epilogue lowering will search for a Ret instead of a
991 /// generic "bx". This instruction also takes a Source operand (for non-void 967 /// generic "bx". This instruction also takes a Source operand (for non-void
(...skipping 30 matching lines...) Expand all
1022 InstARM32Str &operator=(const InstARM32Str &) = delete; 998 InstARM32Str &operator=(const InstARM32Str &) = delete;
1023 999
1024 public: 1000 public:
1025 /// Value must be a register. 1001 /// Value must be a register.
1026 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, 1002 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
1027 CondARM32::Cond Predicate) { 1003 CondARM32::Cond Predicate) {
1028 return new (Func->allocate<InstARM32Str>()) 1004 return new (Func->allocate<InstARM32Str>())
1029 InstARM32Str(Func, Value, Mem, Predicate); 1005 InstARM32Str(Func, Value, Mem, Predicate);
1030 } 1006 }
1031 void emit(const Cfg *Func) const override; 1007 void emit(const Cfg *Func) const override;
1032 void emitIAS(const Cfg *Func) const override;
1033 void dump(const Cfg *Func) const override; 1008 void dump(const Cfg *Func) const override;
1034 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } 1009 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); }
1035 1010
1036 private: 1011 private:
1037 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, 1012 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
1038 CondARM32::Cond Predicate); 1013 CondARM32::Cond Predicate);
1039 }; 1014 };
1040 1015
1041 /// Exclusive Store instruction. Like its non-exclusive sibling, it's important 1016 /// Exclusive Store instruction. Like its non-exclusive sibling, it's important
1042 /// for liveness that there is no Dest operand (OperandARM32Mem instead of Dest 1017 /// for liveness that there is no Dest operand (OperandARM32Mem instead of Dest
1043 /// Variable). 1018 /// Variable).
1044 class InstARM32Strex final : public InstARM32Pred { 1019 class InstARM32Strex final : public InstARM32Pred {
1045 InstARM32Strex() = delete; 1020 InstARM32Strex() = delete;
1046 InstARM32Strex(const InstARM32Strex &) = delete; 1021 InstARM32Strex(const InstARM32Strex &) = delete;
1047 InstARM32Strex &operator=(const InstARM32Strex &) = delete; 1022 InstARM32Strex &operator=(const InstARM32Strex &) = delete;
1048 1023
1049 public: 1024 public:
1050 /// Value must be a register. 1025 /// Value must be a register.
1051 static InstARM32Strex *create(Cfg *Func, Variable *Dest, Variable *Value, 1026 static InstARM32Strex *create(Cfg *Func, Variable *Dest, Variable *Value,
1052 OperandARM32Mem *Mem, 1027 OperandARM32Mem *Mem,
1053 CondARM32::Cond Predicate) { 1028 CondARM32::Cond Predicate) {
1054 return new (Func->allocate<InstARM32Strex>()) 1029 return new (Func->allocate<InstARM32Strex>())
1055 InstARM32Strex(Func, Dest, Value, Mem, Predicate); 1030 InstARM32Strex(Func, Dest, Value, Mem, Predicate);
1056 } 1031 }
1057 void emit(const Cfg *Func) const override; 1032 void emit(const Cfg *Func) const override;
1058 void emitIAS(const Cfg *Func) const override;
1059 void dump(const Cfg *Func) const override; 1033 void dump(const Cfg *Func) const override;
1060 static bool classof(const Inst *Inst) { return isClassof(Inst, Strex); } 1034 static bool classof(const Inst *Inst) { return isClassof(Inst, Strex); }
1061 1035
1062 private: 1036 private:
1063 InstARM32Strex(Cfg *Func, Variable *Dest, Variable *Value, 1037 InstARM32Strex(Cfg *Func, Variable *Dest, Variable *Value,
1064 OperandARM32Mem *Mem, CondARM32::Cond Predicate); 1038 OperandARM32Mem *Mem, CondARM32::Cond Predicate);
1065 }; 1039 };
1066 1040
1067 class InstARM32Trap : public InstARM32 { 1041 class InstARM32Trap : public InstARM32 {
1068 InstARM32Trap() = delete; 1042 InstARM32Trap() = delete;
1069 InstARM32Trap(const InstARM32Trap &) = delete; 1043 InstARM32Trap(const InstARM32Trap &) = delete;
1070 InstARM32Trap &operator=(const InstARM32Trap &) = delete; 1044 InstARM32Trap &operator=(const InstARM32Trap &) = delete;
1071 1045
1072 public: 1046 public:
1073 static InstARM32Trap *create(Cfg *Func) { 1047 static InstARM32Trap *create(Cfg *Func) {
1074 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func); 1048 return new (Func->allocate<InstARM32Trap>()) InstARM32Trap(Func);
1075 } 1049 }
1076 void emit(const Cfg *Func) const override; 1050 void emit(const Cfg *Func) const override;
1077 void emitIAS(const Cfg *Func) const override;
1078 void dump(const Cfg *Func) const override; 1051 void dump(const Cfg *Func) const override;
1079 static bool classof(const Inst *Inst) { return isClassof(Inst, Trap); } 1052 static bool classof(const Inst *Inst) { return isClassof(Inst, Trap); }
1080 1053
1081 private: 1054 private:
1082 explicit InstARM32Trap(Cfg *Func); 1055 explicit InstARM32Trap(Cfg *Func);
1083 }; 1056 };
1084 1057
1085 /// Unsigned Multiply Long: d.lo, d.hi := x * y 1058 /// Unsigned Multiply Long: d.lo, d.hi := x * y
1086 class InstARM32Umull : public InstARM32Pred { 1059 class InstARM32Umull : public InstARM32Pred {
1087 InstARM32Umull() = delete; 1060 InstARM32Umull() = delete;
1088 InstARM32Umull(const InstARM32Umull &) = delete; 1061 InstARM32Umull(const InstARM32Umull &) = delete;
1089 InstARM32Umull &operator=(const InstARM32Umull &) = delete; 1062 InstARM32Umull &operator=(const InstARM32Umull &) = delete;
1090 1063
1091 public: 1064 public:
1092 /// Everything must be a register. 1065 /// Everything must be a register.
1093 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi, 1066 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi,
1094 Variable *Src0, Variable *Src1, 1067 Variable *Src0, Variable *Src1,
1095 CondARM32::Cond Predicate) { 1068 CondARM32::Cond Predicate) {
1096 return new (Func->allocate<InstARM32Umull>()) 1069 return new (Func->allocate<InstARM32Umull>())
1097 InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate); 1070 InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate);
1098 } 1071 }
1099 void emit(const Cfg *Func) const override; 1072 void emit(const Cfg *Func) const override;
1100 void emitIAS(const Cfg *Func) const override;
1101 void dump(const Cfg *Func) const override; 1073 void dump(const Cfg *Func) const override;
1102 static bool classof(const Inst *Inst) { return isClassof(Inst, Umull); } 1074 static bool classof(const Inst *Inst) { return isClassof(Inst, Umull); }
1103 1075
1104 private: 1076 private:
1105 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0, 1077 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0,
1106 Variable *Src1, CondARM32::Cond Predicate); 1078 Variable *Src1, CondARM32::Cond Predicate);
1107 1079
1108 Variable *DestHi; 1080 Variable *DestHi;
1109 }; 1081 };
1110 1082
1111 /// Handles fp2int, int2fp, and fp2fp conversions. 1083 /// Handles fp2int, int2fp, and fp2fp conversions.
1112 class InstARM32Vcvt final : public InstARM32Pred { 1084 class InstARM32Vcvt final : public InstARM32Pred {
1113 InstARM32Vcvt() = delete; 1085 InstARM32Vcvt() = delete;
1114 InstARM32Vcvt(const InstARM32Vcvt &) = delete; 1086 InstARM32Vcvt(const InstARM32Vcvt &) = delete;
1115 InstARM32Vcvt &operator=(const InstARM32Vcvt &) = delete; 1087 InstARM32Vcvt &operator=(const InstARM32Vcvt &) = delete;
1116 1088
1117 public: 1089 public:
1118 enum VcvtVariant { S2si, S2ui, Si2s, Ui2s, D2si, D2ui, Si2d, Ui2d, S2d, D2s }; 1090 enum VcvtVariant { S2si, S2ui, Si2s, Ui2s, D2si, D2ui, Si2d, Ui2d, S2d, D2s };
1119 static InstARM32Vcvt *create(Cfg *Func, Variable *Dest, Variable *Src, 1091 static InstARM32Vcvt *create(Cfg *Func, Variable *Dest, Variable *Src,
1120 VcvtVariant Variant, CondARM32::Cond Predicate) { 1092 VcvtVariant Variant, CondARM32::Cond Predicate) {
1121 return new (Func->allocate<InstARM32Vcvt>()) 1093 return new (Func->allocate<InstARM32Vcvt>())
1122 InstARM32Vcvt(Func, Dest, Src, Variant, Predicate); 1094 InstARM32Vcvt(Func, Dest, Src, Variant, Predicate);
1123 } 1095 }
1124 void emit(const Cfg *Func) const override; 1096 void emit(const Cfg *Func) const override;
1125 void emitIAS(const Cfg *Func) const override;
1126 void dump(const Cfg *Func) const override; 1097 void dump(const Cfg *Func) const override;
1127 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcvt); } 1098 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcvt); }
1128 1099
1129 private: 1100 private:
1130 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant, 1101 InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, VcvtVariant Variant,
1131 CondARM32::Cond Predicate); 1102 CondARM32::Cond Predicate);
1132 1103
1133 const VcvtVariant Variant; 1104 const VcvtVariant Variant;
1134 }; 1105 };
1135 1106
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 InstARM32Vcmp(const InstARM32Vcmp &) = delete; 1153 InstARM32Vcmp(const InstARM32Vcmp &) = delete;
1183 InstARM32Vcmp &operator=(const InstARM32Vcmp &) = delete; 1154 InstARM32Vcmp &operator=(const InstARM32Vcmp &) = delete;
1184 1155
1185 public: 1156 public:
1186 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, Variable *Src1, 1157 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, Variable *Src1,
1187 CondARM32::Cond Predicate) { 1158 CondARM32::Cond Predicate) {
1188 return new (Func->allocate<InstARM32Vcmp>()) 1159 return new (Func->allocate<InstARM32Vcmp>())
1189 InstARM32Vcmp(Func, Src0, Src1, Predicate); 1160 InstARM32Vcmp(Func, Src0, Src1, Predicate);
1190 } 1161 }
1191 void emit(const Cfg *Func) const override; 1162 void emit(const Cfg *Func) const override;
1192 void emitIAS(const Cfg *Func) const override;
1193 void dump(const Cfg *Func) const override; 1163 void dump(const Cfg *Func) const override;
1194 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcmp); } 1164 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcmp); }
1195 1165
1196 private: 1166 private:
1197 InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1, 1167 InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1,
1198 CondARM32::Cond Predicate); 1168 CondARM32::Cond Predicate);
1199 }; 1169 };
1200 1170
1201 /// Copies the FP Status and Control Register the core flags. 1171 /// Copies the FP Status and Control Register the core flags.
1202 class InstARM32Vmrs final : public InstARM32Pred { 1172 class InstARM32Vmrs final : public InstARM32Pred {
1203 InstARM32Vmrs() = delete; 1173 InstARM32Vmrs() = delete;
1204 InstARM32Vmrs(const InstARM32Vmrs &) = delete; 1174 InstARM32Vmrs(const InstARM32Vmrs &) = delete;
1205 InstARM32Vmrs &operator=(const InstARM32Vmrs &) = delete; 1175 InstARM32Vmrs &operator=(const InstARM32Vmrs &) = delete;
1206 1176
1207 public: 1177 public:
1208 static InstARM32Vmrs *create(Cfg *Func, CondARM32::Cond Predicate) { 1178 static InstARM32Vmrs *create(Cfg *Func, CondARM32::Cond Predicate) {
1209 return new (Func->allocate<InstARM32Vmrs>()) InstARM32Vmrs(Func, Predicate); 1179 return new (Func->allocate<InstARM32Vmrs>()) InstARM32Vmrs(Func, Predicate);
1210 } 1180 }
1211 void emit(const Cfg *Func) const override; 1181 void emit(const Cfg *Func) const override;
1212 void emitIAS(const Cfg *Func) const override;
1213 void dump(const Cfg *Func) const override; 1182 void dump(const Cfg *Func) const override;
1214 static bool classof(const Inst *Inst) { return isClassof(Inst, Vmrs); } 1183 static bool classof(const Inst *Inst) { return isClassof(Inst, Vmrs); }
1215 1184
1216 private: 1185 private:
1217 InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate); 1186 InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate);
1218 }; 1187 };
1219 1188
1220 class InstARM32Vabs final : public InstARM32Pred { 1189 class InstARM32Vabs final : public InstARM32Pred {
1221 InstARM32Vabs() = delete; 1190 InstARM32Vabs() = delete;
1222 InstARM32Vabs(const InstARM32Vabs &) = delete; 1191 InstARM32Vabs(const InstARM32Vabs &) = delete;
1223 InstARM32Vabs &operator=(const InstARM32Vabs &) = delete; 1192 InstARM32Vabs &operator=(const InstARM32Vabs &) = delete;
1224 1193
1225 public: 1194 public:
1226 static InstARM32Vabs *create(Cfg *Func, Variable *Dest, Variable *Src, 1195 static InstARM32Vabs *create(Cfg *Func, Variable *Dest, Variable *Src,
1227 CondARM32::Cond Predicate) { 1196 CondARM32::Cond Predicate) {
1228 return new (Func->allocate<InstARM32Vabs>()) 1197 return new (Func->allocate<InstARM32Vabs>())
1229 InstARM32Vabs(Func, Dest, Src, Predicate); 1198 InstARM32Vabs(Func, Dest, Src, Predicate);
1230 } 1199 }
1231 void emit(const Cfg *Func) const override; 1200 void emit(const Cfg *Func) const override;
1232 void emitIAS(const Cfg *Func) const override;
1233 void dump(const Cfg *Func) const override; 1201 void dump(const Cfg *Func) const override;
1234 static bool classof(const Inst *Inst) { return isClassof(Inst, Vabs); } 1202 static bool classof(const Inst *Inst) { return isClassof(Inst, Vabs); }
1235 1203
1236 private: 1204 private:
1237 InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src, 1205 InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src,
1238 CondARM32::Cond Predicate); 1206 CondARM32::Cond Predicate);
1239 }; 1207 };
1240 1208
1241 class InstARM32Dmb final : public InstARM32Pred { 1209 class InstARM32Dmb final : public InstARM32Pred {
1242 InstARM32Dmb() = delete; 1210 InstARM32Dmb() = delete;
1243 InstARM32Dmb(const InstARM32Dmb &) = delete; 1211 InstARM32Dmb(const InstARM32Dmb &) = delete;
1244 InstARM32Dmb &operator=(const InstARM32Dmb &) = delete; 1212 InstARM32Dmb &operator=(const InstARM32Dmb &) = delete;
1245 1213
1246 public: 1214 public:
1247 static InstARM32Dmb *create(Cfg *Func) { 1215 static InstARM32Dmb *create(Cfg *Func) {
1248 return new (Func->allocate<InstARM32Dmb>()) InstARM32Dmb(Func); 1216 return new (Func->allocate<InstARM32Dmb>()) InstARM32Dmb(Func);
1249 } 1217 }
1250 void emit(const Cfg *Func) const override; 1218 void emit(const Cfg *Func) const override;
1251 void emitIAS(const Cfg *Func) const override;
1252 void dump(const Cfg *Func) const override; 1219 void dump(const Cfg *Func) const override;
1253 static bool classof(const Inst *Inst) { return isClassof(Inst, Dmb); } 1220 static bool classof(const Inst *Inst) { return isClassof(Inst, Dmb); }
1254 1221
1255 private: 1222 private:
1256 explicit InstARM32Dmb(Cfg *Func); 1223 explicit InstARM32Dmb(Cfg *Func);
1257 }; 1224 };
1258 1225
1259 // Declare partial template specializations of emit() methods that already have 1226 // Declare partial template specializations of emit() methods that already have
1260 // default implementations. Without this, there is the possibility of ODR 1227 // default implementations. Without this, there is the possibility of ODR
1261 // violations and link errors. 1228 // violations and link errors.
1262 1229
1263 template <> void InstARM32Ldr::emit(const Cfg *Func) const; 1230 template <> void InstARM32Ldr::emit(const Cfg *Func) const;
1264 template <> void InstARM32Movw::emit(const Cfg *Func) const; 1231 template <> void InstARM32Movw::emit(const Cfg *Func) const;
1265 template <> void InstARM32Movt::emit(const Cfg *Func) const; 1232 template <> void InstARM32Movt::emit(const Cfg *Func) const;
1266 1233
1267 } // end of namespace Ice 1234 } // end of namespace Ice
1268 1235
1269 #endif // SUBZERO_SRC_ICEINSTARM32_H 1236 #endif // SUBZERO_SRC_ICEINSTARM32_H
OLDNEW
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698