llvm.org GIT mirror llvm / 4afc509
Implement a !subst operation simmilar to $(subst) in GNU make to do def/var/string substitution on generic pattern templates. For example: def Type; def v4f32 : Type; def TYPE : Type; class GenType<Type t> { let type = !(subst TYPE, v4f32, t); } def TheType : GenType<TYPE>; git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71801 91177308-0d34-0410-b5e6-96231b3b80d8 David Greene 10 years ago
7 changed file(s) with 376 addition(s) and 353 deletion(s). Raw diff Collapse all Expand all
403403 aborts with an error.
404404
!nameconcat<type>(a, b)
405405
Shorthand for !cast(!strconcat(a, b))
406
!subst(a, b, c)
407
If 'a' and 'b' are of string type or are symbol references, substitute
408 'b' for 'a' in 'c.' This operation is analogous to $(subst) in GNU make.
406409
407410
408411

Note that all of the values have rules specifying how they convert to values

0 // RUN: tblgen %s | grep {Smith} | count 7
1 // RUN: tblgen %s | grep {Johnson} | count 2
2 // RUN: tblgen %s | grep {FIRST} | count 1
3 // RUN: tblgen %s | grep {LAST} | count 1
4 // RUN: tblgen %s | grep {TVAR} | count 2
5 // RUN: tblgen %s | grep {Bogus} | count 1
6
7 class Honorific {
8 string honorific = t;
9 }
10
11 def Mr : Honorific<"Mr.">;
12 def Ms : Honorific<"Ms.">;
13 def Mrs : Honorific<"Mrs.">;
14 def TVAR : Honorific<"Bogus">;
15
16 class Name {
17 string name = n;
18 Honorific honorific = t;
19 }
20
21 class AName :
22 Name
23 !subst(TVAR, Mr, honorific)>;
24
25 def JohnSmith : AName<"FIRST LAST", TVAR>;
26 def JaneSmith : AName<"Jane LAST", Ms>;
27 def JohnSmithJones : AName<"FIRST LAST-Jones", Mr>;
28 def JimmyJohnson : AName<"Jimmy Johnson", Mr>;
677677 return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
678678 }
679679
680 // Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
681 // switch (getOpcode()) {
682 // default: assert(0 && "Unknown binop");
683 // case SUBST: {
684 // DefInit *LHSd = dynamic_cast(LHS);
685 // VarInit *LHSv = dynamic_cast(LHS);
686 // StringInit *LHSs = dynamic_cast(LHS);
687
688 // DefInit *MHSd = dynamic_cast(MHS);
689 // VarInit *MHSv = dynamic_cast(MHS);
690 // StringInit *MHSs = dynamic_cast(MHS);
691
692 // DagInit *RHSd = dynamic_cast(RHS);
693 // ListInit *RHSl = dynamic_cast(RHS);
694
695 // DagRecTy *DagType = dynamic_cast(getType());
696 // ListRecTy *ListType = dynamic_cast(getType());
697
698 // if ((DagType && RHSd || ListType && RHSl)
699 // && (LHSd && MHSd || LHSv && MHSv || LHSs && MHSs)) {
700 // if (RHSd) {
701 // Init *Val = RHSd->getOperator();
702 // if (Val->getAsString() == LHS->getAsString()) {
703 // Val = MHS;
704 // }
705 // std::vector > args;
706 // for (int i = 0; i < RHSd->getNumArgs(); ++i) {
707 // Init *Arg;
708 // std::string ArgName;
709 // Arg = RHSd->getArg(i);
710 // ArgName = RHSd->getArgName(i);
711 // if (Arg->getAsString() == LHS->getAsString()) {
712 // Arg = MHS;
713 // }
714 // if (ArgName == LHS->getAsString()) {
715 // ArgName = MHS->getAsString();
716 // }
717 // args.push_back(std::make_pair(Arg, ArgName));
718 // }
719
720 // return new DagInit(Val, args);
721 // }
722 // if (RHSl) {
723 // std::vector NewList(RHSl->begin(), RHSl->end());
724
725 // for (ListInit::iterator i = NewList.begin(),
726 // iend = NewList.end();
727 // i != iend;
728 // ++i) {
729 // if ((*i)->getAsString() == LHS->getAsString()) {
730 // *i = MHS;
731 // }
732 // }
733 // return new ListInit(NewList);
734 // }
735 // }
736 // break;
737 // }
738
739 // case FOREACH: {
740 // DagInit *MHSd = dynamic_cast(MHS);
741 // ListInit *MHSl = dynamic_cast(MHS);
742
743 // DagRecTy *DagType = dynamic_cast(getType());
744 // ListRecTy *ListType = dynamic_cast(getType());
745
746 // OpInit *RHSo = dynamic_cast(RHS);
747
748 // if (!RHSo) {
749 // cerr << "!foreach requires an operator\n";
750 // assert(0 && "No operator for !foreach");
751 // }
752
753 // TypedInit *LHSt = dynamic_cast(LHS);
754
755 // if (!LHSt) {
756 // cerr << "!foreach requires typed variable\n";
757 // assert(0 && "No typed variable for !foreach");
758 // }
759
760 // if (MHSd && DagType || MHSl && ListType) {
761 // std::vector NewOperands;
762 // if (MHSd) {
763 // Init *Val = MHSd->getOperator();
764 // TypedInit *TVal = dynamic_cast(Val);
765
766 // if (TVal && TVal->getType()->typeIsConvertibleTo(LHSt->getType())) {
680 Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
681 switch (getOpcode()) {
682 default: assert(0 && "Unknown binop");
683 case SUBST: {
684 DefInit *LHSd = dynamic_cast(LHS);
685 VarInit *LHSv = dynamic_cast(LHS);
686 StringInit *LHSs = dynamic_cast(LHS);
687
688 DefInit *MHSd = dynamic_cast(MHS);
689 VarInit *MHSv = dynamic_cast(MHS);
690 StringInit *MHSs = dynamic_cast(MHS);
691
692 DefInit *RHSd = dynamic_cast(RHS);
693 VarInit *RHSv = dynamic_cast(RHS);
694 StringInit *RHSs = dynamic_cast(RHS);
695
696 if ((LHSd && MHSd && RHSd)
697 || (LHSv && MHSv && RHSv)
698 || (LHSs && MHSs && RHSs)) {
699 if (RHSd) {
700 Record *Val = RHSd->getDef();
701 if (LHSd->getAsString() == RHSd->getAsString()) {
702 Val = MHSd->getDef();
703 }
704 return new DefInit(Val);
705 }
706 if (RHSv) {
707 std::string Val = RHSv->getName();
708 if (LHSv->getAsString() == RHSv->getAsString()) {
709 Val = MHSv->getName();
710 }
711 return new VarInit(Val, getType());
712 }
713 if (RHSs) {
714 std::string Val = RHSs->getValue();
715
716 std::string::size_type found;
717 do {
718 found = Val.find(LHSs->getValue());
719 if (found != std::string::npos) {
720 Val.replace(found, LHSs->getValue().size(), MHSs->getValue());
721 }
722 } while (found != std::string::npos);
723
724 return new StringInit(Val);
725 }
726 }
727 break;
728 }
729
730 case FOREACH: {
731 DagInit *MHSd = dynamic_cast(MHS);
732 ListInit *MHSl = dynamic_cast(MHS);
733
734 DagRecTy *DagType = dynamic_cast(getType());
735 ListRecTy *ListType = dynamic_cast(getType());
736
737 OpInit *RHSo = dynamic_cast(RHS);
738
739 if (!RHSo) {
740 cerr << "!foreach requires an operator\n";
741 assert(0 && "No operator for !foreach");
742 }
743
744 TypedInit *LHSt = dynamic_cast(LHS);
745
746 if (!LHSt) {
747 cerr << "!foreach requires typed variable\n";
748 assert(0 && "No typed variable for !foreach");
749 }
750
751 if (MHSd && DagType || MHSl && ListType) {
752 std::vector NewOperands;
753 if (MHSd) {
754 Init *Val = MHSd->getOperator();
755 TypedInit *TVal = dynamic_cast(Val);
756
757 if (TVal && TVal->getType()->typeIsConvertibleTo(LHSt->getType())) {
767758
768 // // First, replace the foreach variable with the DAG leaf
769 // for (int i = 0; i < RHSo->getNumOperands(); ++i) {
770 // if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
771 // NewOperands.push_back(Val);
772 // }
773 // else {
774 // NewOperands.push_back(RHSo->getOperand(i));
775 // }
776 // }
777
778 // // Now run the operator and use its result as the new leaf
779 // OpInit *NewOp = RHSo->clone(NewOperands);
780 // Val = NewOp->Fold(CurRec, CurMultiClass);
781 // if (Val != NewOp) {
782 // delete NewOp;
783 // }
784 // }
785
786 // std::vector > args;
787 // for (int i = 0; i < MHSd->getNumArgs(); ++i) {
788 // Init *Arg;
789 // std::string ArgName;
790 // Arg = MHSd->getArg(i);
791 // ArgName = MHSd->getArgName(i);
792
793 // TypedInit *TArg = dynamic_cast(Arg);
794
795 // if (TArg && TArg->getType()->typeIsConvertibleTo(LHSt->getType())) {
796 // NewOperands.clear();
797
798 // // First, replace the foreach variable with the DAG leaf
799 // for (int i = 0; i < RHSo->getNumOperands(); ++i) {
800 // if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
801 // NewOperands.push_back(Arg);
802 // }
803 // else {
804 // NewOperands.push_back(RHSo->getOperand(i));
805 // }
806 // }
807
808 // // Now run the operator and use its result as the new leaf
809 // OpInit *NewOp = RHSo->clone(NewOperands);
810 // Arg = NewOp->Fold(CurRec, CurMultiClass);
811 // if (Arg != NewOp) {
812 // delete NewOp;
813 // }
814 // }
759 // First, replace the foreach variable with the DAG leaf
760 for (int i = 0; i < RHSo->getNumOperands(); ++i) {
761 if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
762 NewOperands.push_back(Val);
763 }
764 else {
765 NewOperands.push_back(RHSo->getOperand(i));
766 }
767 }
768
769 // Now run the operator and use its result as the new leaf
770 OpInit *NewOp = RHSo->clone(NewOperands);
771 Val = NewOp->Fold(CurRec, CurMultiClass);
772 if (Val != NewOp) {
773 delete NewOp;
774 }
775 }
776
777 std::vector > args;
778 for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
779 Init *Arg;
780 std::string ArgName;
781 Arg = MHSd->getArg(i);
782 ArgName = MHSd->getArgName(i);
783
784 TypedInit *TArg = dynamic_cast(Arg);
785
786 if (TArg && TArg->getType()->typeIsConvertibleTo(LHSt->getType())) {
787 NewOperands.clear();
788
789 // First, replace the foreach variable with the DAG leaf
790 for (int i = 0; i < RHSo->getNumOperands(); ++i) {
791 if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
792 NewOperands.push_back(Arg);
793 }
794 else {
795 NewOperands.push_back(RHSo->getOperand(i));
796 }
797 }
798
799 // Now run the operator and use its result as the new leaf
800 OpInit *NewOp = RHSo->clone(NewOperands);
801 Arg = NewOp->Fold(CurRec, CurMultiClass);
802 if (Arg != NewOp) {
803 delete NewOp;
804 }
805 }
815806
816 // if (LHSt->getType()->getAsString() == "string") {
817 // NewOperands.clear();
818
819 // // First, replace the foreach variable with the DAG leaf
820 // for (int i = 0; i < RHSo->getNumOperands(); ++i) {
821 // if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
822 // NewOperands.push_back(new StringInit(ArgName));
823 // }
824 // else {
825 // NewOperands.push_back(RHSo->getOperand(i));
826 // }
827 // }
828
829 // // Now run the operator and use its result as the new leaf
830 // OpInit *NewOp = RHSo->clone(NewOperands);
831 // Init *ArgNameInit = NewOp->Fold(CurRec, CurMultiClass);
832 // StringInit *SArgNameInit = dynamic_cast(ArgNameInit);
833 // if (SArgNameInit) {
834 // ArgName = SArgNameInit->getValue();
835 // }
836 // if (ArgNameInit != NewOp) {
837 // delete NewOp;
838 // }
839 // delete ArgNameInit;
840 // }
841
842 // args.push_back(std::make_pair(Arg, ArgName));
843 // }
844
845 // return new DagInit(Val, args);
846 // }
847 // if (MHSl) {
848 // std::vector NewList(MHSl->begin(), MHSl->end());
849
850 // for (ListInit::iterator li = NewList.begin(),
851 // liend = NewList.end();
852 // li != liend;
853 // ++li) {
854 // Init *Item = *li;
855 // TypedInit *TItem = dynamic_cast(Item);
856 // if (TItem && TItem->getType()->typeIsConvertibleTo(LHSt->getType())) {
857 // // First, replace the foreach variable with the list item
858 // for (int i = 0; i < RHSo->getNumOperands(); ++i) {
859 // if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
860 // NewOperands.push_back(Item);
861 // }
862 // else {
863 // NewOperands.push_back(RHSo->getOperand(i));
864 // }
865 // }
866
867 // // Now run the operator and use its result as the new list item
868 // OpInit *NewOp = RHSo->clone(NewOperands);
869 // *li = NewOp->Fold(CurRec, CurMultiClass);
870 // if (*li != NewOp) {
871 // delete NewOp;
872 // }
873 // }
874 // }
807 if (LHSt->getType()->getAsString() == "string") {
808 NewOperands.clear();
809
810 // First, replace the foreach variable with the DAG leaf
811 for (int i = 0; i < RHSo->getNumOperands(); ++i) {
812 if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
813 NewOperands.push_back(new StringInit(ArgName));
814 }
815 else {
816 NewOperands.push_back(RHSo->getOperand(i));
817 }
818 }
819
820 // Now run the operator and use its result as the new leaf
821 OpInit *NewOp = RHSo->clone(NewOperands);
822 Init *ArgNameInit = NewOp->Fold(CurRec, CurMultiClass);
823 StringInit *SArgNameInit = dynamic_cast(ArgNameInit);
824 if (SArgNameInit) {
825 ArgName = SArgNameInit->getValue();
826 }
827 if (ArgNameInit != NewOp) {
828 delete NewOp;
829 }
830 delete ArgNameInit;
831 }
832
833 args.push_back(std::make_pair(Arg, ArgName));
834 }
835
836 return new DagInit(Val, "", args);
837 }
838 if (MHSl) {
839 std::vector NewList(MHSl->begin(), MHSl->end());
840
841 for (ListInit::iterator li = NewList.begin(),
842 liend = NewList.end();
843 li != liend;
844 ++li) {
845 Init *Item = *li;
846 TypedInit *TItem = dynamic_cast(Item);
847 if (TItem && TItem->getType()->typeIsConvertibleTo(LHSt->getType())) {
848 // First, replace the foreach variable with the list item
849 for (int i = 0; i < RHSo->getNumOperands(); ++i) {
850 if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
851 NewOperands.push_back(Item);
852 }
853 else {
854 NewOperands.push_back(RHSo->getOperand(i));
855 }
856 }
857
858 // Now run the operator and use its result as the new list item
859 OpInit *NewOp = RHSo->clone(NewOperands);
860 *li = NewOp->Fold(CurRec, CurMultiClass);
861 if (*li != NewOp) {
862 delete NewOp;
863 }
864 }
865 }
875866
876 // return new ListInit(NewList);
877 // }
878 // }
879 // break;
880 // }
881 // }
882
883 // return this;
884 // }
885
886 // Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
887 // Init *lhs = LHS->resolveReferences(R, RV);
888 // Init *mhs = MHS->resolveReferences(R, RV);
889 // Init *rhs = RHS->resolveReferences(R, RV);
867 return new ListInit(NewList);
868 }
869 }
870 break;
871 }
872 }
873
874 return this;
875 }
876
877 Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
878 Init *lhs = LHS->resolveReferences(R, RV);
879 Init *mhs = MHS->resolveReferences(R, RV);
880 Init *rhs = RHS->resolveReferences(R, RV);
890881
891 // if (LHS != lhs || MHS != mhs || RHS != rhs)
892 // return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
893 // return Fold(&R, 0);
894 // }
895
896 // std::string TernOpInit::getAsString() const {
897 // std::string Result;
898 // switch (Opc) {
899 // case SUBST: Result = "!subst"; break;
900 // case FOREACH: Result = "!foreach"; break;
901 // }
902 // return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
903 // + RHS->getAsString() + ")";
904 // }
882 if (LHS != lhs || MHS != mhs || RHS != rhs)
883 return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
884 return Fold(&R, 0);
885 }
886
887 std::string TernOpInit::getAsString() const {
888 std::string Result;
889 switch (Opc) {
890 case SUBST: Result = "!subst"; break;
891 case FOREACH: Result = "!foreach"; break;
892 }
893 return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
894 + RHS->getAsString() + ")";
895 }
905896
906897 Init *TypedInit::convertInitializerBitRange(const std::vector &Bits) {
907898 BitsRecTy *T = dynamic_cast(getType());
4242 class ListInit;
4343 class UnOpInit;
4444 class BinOpInit;
45 //class TernOpInit;
45 class TernOpInit;
4646 class DefInit;
4747 class DagInit;
4848 class TypedInit;
8484 virtual Init *convertValue( BinOpInit *UI) {
8585 return convertValue((TypedInit*)UI);
8686 }
87 // virtual Init *convertValue( TernOpInit *UI) {
88 // return convertValue((TypedInit*)UI);
89 // }
87 virtual Init *convertValue( TernOpInit *UI) {
88 return convertValue((TypedInit*)UI);
89 }
9090 virtual Init *convertValue( CodeInit *CI) { return 0; }
9191 virtual Init *convertValue(VarBitInit *VB) { return 0; }
9292 virtual Init *convertValue( DefInit *DI) { return 0; }
134134 virtual Init *convertValue( DagInit *DI) { return 0; }
135135 virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
136136 virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
137 //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
137 virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
138138 virtual Init *convertValue( TypedInit *TI);
139139 virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
140140 virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
178178 virtual Init *convertValue( DagInit *DI) { return 0; }
179179 virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
180180 virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
181 //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
181 virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
182182 virtual Init *convertValue( TypedInit *TI);
183183 virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
184184 virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
218218 virtual Init *convertValue( DagInit *DI) { return 0; }
219219 virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
220220 virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
221 //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
221 virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
222222 virtual Init *convertValue( TypedInit *TI);
223223 virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
224224 virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
252252 virtual Init *convertValue( ListInit *LI) { return 0; }
253253 virtual Init *convertValue( UnOpInit *BO);
254254 virtual Init *convertValue( BinOpInit *BO);
255 //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
255 virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
256256
257257 virtual Init *convertValue( CodeInit *CI) { return 0; }
258258 virtual Init *convertValue(VarBitInit *VB) { return 0; }
302302 virtual Init *convertValue( DagInit *DI) { return 0; }
303303 virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
304304 virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
305 //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
305 virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
306306 virtual Init *convertValue( TypedInit *TI);
307307 virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
308308 virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
341341 virtual Init *convertValue( DagInit *DI) { return 0; }
342342 virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
343343 virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
344 //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
344 virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
345345 virtual Init *convertValue( TypedInit *TI);
346346 virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
347347 virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
376376 virtual Init *convertValue( DefInit *DI) { return 0; }
377377 virtual Init *convertValue( UnOpInit *BO);
378378 virtual Init *convertValue( BinOpInit *BO);
379 //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
379 virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
380380 virtual Init *convertValue( DagInit *CI) { return (Init*)CI; }
381381 virtual Init *convertValue( TypedInit *TI);
382382 virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
419419 virtual Init *convertValue(VarBitInit *VB) { return 0; }
420420 virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
421421 virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
422 //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
422 virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
423423 virtual Init *convertValue( DefInit *DI);
424424 virtual Init *convertValue( DagInit *DI) { return 0; }
425425 virtual Init *convertValue( TypedInit *VI);
819819
820820 /// TernOpInit - !op (X, Y, Z) - Combine two inits.
821821 ///
822 // class TernOpInit : public OpInit {
823 // public:
824 // enum TernaryOp { SUBST, FOREACH };
825 // private:
826 // TernaryOp Opc;
827 // Init *LHS, *MHS, *RHS;
828 // public:
829 // TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
830 // OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
831 // }
832
833 // // Clone - Clone this operator, replacing arguments with the new list
834 // virtual OpInit *clone(std::vector &Operands) {
835 // assert(Operands.size() == 3 && "Wrong number of operands for ternary operation");
836 // return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2], getType());
837 // }
838
839 // int getNumOperands(void) const { return 3; }
840 // Init *getOperand(int i) {
841 // assert(i == 0 || i == 1 || i == 2 && "Invalid operand id for ternary operator");
842 // if (i == 0) {
843 // return getLHS();
844 // }
845 // else if (i == 1) {
846 // return getMHS();
847 // }
848 // else {
849 // return getRHS();
850 // }
851 // }
852
853 // TernaryOp getOpcode() const { return Opc; }
854 // Init *getLHS() const { return LHS; }
855 // Init *getMHS() const { return MHS; }
856 // Init *getRHS() const { return RHS; }
857
858 // // Fold - If possible, fold this to a simpler init. Return this if not
859 // // possible to fold.
860 // Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
861
862 // virtual Init *resolveReferences(Record &R, const RecordVal *RV);
863
864 // virtual std::string getAsString() const;
865 // };
822 class TernOpInit : public OpInit {
823 public:
824 enum TernaryOp { SUBST, FOREACH };
825 private:
826 TernaryOp Opc;
827 Init *LHS, *MHS, *RHS;
828 public:
829 TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
830 OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
831 }
832
833 // Clone - Clone this operator, replacing arguments with the new list
834 virtual OpInit *clone(std::vector &Operands) {
835 assert(Operands.size() == 3 && "Wrong number of operands for ternary operation");
836 return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2], getType());
837 }
838
839 int getNumOperands(void) const { return 3; }
840 Init *getOperand(int i) {
841 assert(i == 0 || i == 1 || i == 2 && "Invalid operand id for ternary operator");
842 if (i == 0) {
843 return getLHS();
844 }
845 else if (i == 1) {
846 return getMHS();
847 }
848 else {
849 return getRHS();
850 }
851 }
852
853 TernaryOp getOpcode() const { return Opc; }
854 Init *getLHS() const { return LHS; }
855 Init *getMHS() const { return MHS; }
856 Init *getRHS() const { return RHS; }
857
858 // Fold - If possible, fold this to a simpler init. Return this if not
859 // possible to fold.
860 Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
861
862 virtual Init *resolveReferences(Record &R, const RecordVal *RV);
863
864 virtual std::string getAsString() const;
865 };
866866
867867
868868 /// VarInit - 'Opcode' - Represent a reference to an entire variable object.
446446 if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
447447 if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat;
448448 if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
449 // if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
449 if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
450450 // if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
451451 if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
452452
4444 MultiClass, String,
4545
4646 // !keywords.
47 XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, // XSubst,
47 XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst,
4848 //XForEach,
4949
5050 // Integer value.
792792 }
793793
794794 // case tgtok::XForEach:
795 // case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
796 // TernOpInit::TernaryOp Code;
797 // RecTy *Type = 0;
798
799
800 // tgtok::TokKind LexCode = Lex.getCode();
801 // Lex.Lex(); // eat the operation
802 // switch (LexCode) {
803 // default: assert(0 && "Unhandled code!");
804 // case tgtok::XForEach:
805 // Code = TernOpInit::FOREACH;
806 // break;
807 // case tgtok::XSubst:
808 // Code = TernOpInit::SUBST;
809 // break;
810 // }
811 // if (Lex.getCode() != tgtok::l_paren) {
812 // TokError("expected '(' after ternary operator");
813 // return 0;
814 // }
815 // Lex.Lex(); // eat the '('
816
817 // Init *LHS = ParseValue(CurRec);
818 // if (LHS == 0) return 0;
819
820 // if (Lex.getCode() != tgtok::comma) {
821 // TokError("expected ',' in ternary operator");
822 // return 0;
823 // }
824 // Lex.Lex(); // eat the ','
825
826 // Init *MHS = ParseValue(CurRec);
827 // if (MHS == 0) return 0;
828
829 // if (Lex.getCode() != tgtok::comma) {
830 // TokError("expected ',' in ternary operator");
831 // return 0;
832 // }
833 // Lex.Lex(); // eat the ','
834
835 // Init *RHS = ParseValue(CurRec);
836 // if (RHS == 0) return 0;
837
838 // if (Lex.getCode() != tgtok::r_paren) {
839 // TokError("expected ')' in binary operator");
840 // return 0;
841 // }
842 // Lex.Lex(); // eat the ')'
843
844 // switch (LexCode) {
845 // default: assert(0 && "Unhandled code!");
846 // case tgtok::XForEach: {
847 // TypedInit *MHSt = dynamic_cast(MHS);
848 // if (MHSt == 0) {
849 // TokError("could not get type for !foreach");
850 // return 0;
851 // }
852 // Type = MHSt->getType();
853 // break;
854 // }
855 // case tgtok::XSubst: {
856 // TypedInit *RHSt = dynamic_cast(RHS);
857 // if (RHSt == 0) {
858 // TokError("could not get type for !subst");
859 // return 0;
860 // }
861 // Type = RHSt->getType();
862 // break;
863 // }
864 // }
865 // return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
866 // }
795 case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
796 TernOpInit::TernaryOp Code;
797 RecTy *Type = 0;
798
799
800 tgtok::TokKind LexCode = Lex.getCode();
801 Lex.Lex(); // eat the operation
802 switch (LexCode) {
803 default: assert(0 && "Unhandled code!");
804 //case tgtok::XForEach:
805 //Code = TernOpInit::FOREACH;
806 //break;
807 case tgtok::XSubst:
808 Code = TernOpInit::SUBST;
809 break;
810 }
811 if (Lex.getCode() != tgtok::l_paren) {
812 TokError("expected '(' after ternary operator");
813 return 0;
814 }
815 Lex.Lex(); // eat the '('
816
817 Init *LHS = ParseValue(CurRec);
818 if (LHS == 0) return 0;
819
820 if (Lex.getCode() != tgtok::comma) {
821 TokError("expected ',' in ternary operator");
822 return 0;
823 }
824 Lex.Lex(); // eat the ','
825
826 Init *MHS = ParseValue(CurRec);
827 if (MHS == 0) return 0;
828
829 if (Lex.getCode() != tgtok::comma) {
830 TokError("expected ',' in ternary operator");
831 return 0;
832 }
833 Lex.Lex(); // eat the ','
834
835 Init *RHS = ParseValue(CurRec);
836 if (RHS == 0) return 0;
837
838 if (Lex.getCode() != tgtok::r_paren) {
839 TokError("expected ')' in binary operator");
840 return 0;
841 }
842 Lex.Lex(); // eat the ')'
843
844 switch (LexCode) {
845 default: assert(0 && "Unhandled code!");
846 //case tgtok::XForEach: {
847 //TypedInit *MHSt = dynamic_cast(MHS);
848 //if (MHSt == 0) {
849 // TokError("could not get type for !foreach");
850 // return 0;
851 //}
852 //Type = MHSt->getType();
853 //break;
854 //}
855 case tgtok::XSubst: {
856 TypedInit *RHSt = dynamic_cast(RHS);
857 if (RHSt == 0) {
858 TokError("could not get type for !subst");
859 return 0;
860 }
861 Type = RHSt->getType();
862 break;
863 }
864 }
865 return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
866 }
867867 }
868868 TokError("could not parse operation");
869869 return 0;
10771077 case tgtok::XSRL:
10781078 case tgtok::XSHL:
10791079 case tgtok::XStrConcat:
1080 case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')'
1080 case tgtok::XNameConcat: // Value ::= !binop '(' Value ',' Value ')'
10811081 // case tgtok::XForEach:
1082 // case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
1082 case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
10831083 return ParseOperation(CurRec);
10841084 break;
10851085 }