@@ -703,6 +703,106 @@ RISCVISAInfo::parseNormalizedArchString(StringRef Arch) {
703
703
return std::move (ISAInfo);
704
704
}
705
705
706
+ static Error splitExtsByUnderscore (StringRef Exts,
707
+ std::vector<std::string> &SplitedExts) {
708
+ SmallVector<StringRef, 8 > Split;
709
+ if (Exts.empty ())
710
+ return Error::success ();
711
+
712
+ Exts.split (Split, " _" );
713
+
714
+ for (auto Ext : Split) {
715
+ if (Ext.empty ())
716
+ return createStringError (errc::invalid_argument,
717
+ " extension name missing after separator '_'" );
718
+
719
+ SplitedExts.push_back (Ext.str ());
720
+ }
721
+ return Error::success ();
722
+ }
723
+
724
+ static Error processMultiLetterExtension (
725
+ StringRef RawExt, SmallVector<std::string, 8 > &SeenExts,
726
+ SmallVector<RISCVISAInfo::ExtensionVersion, 8 > &ExtsVersion,
727
+ bool IgnoreUnknown, bool EnableExperimentalExtension,
728
+ bool ExperimentalExtensionVersionCheck) {
729
+ StringRef Type = getExtensionType (RawExt);
730
+ StringRef Desc = getExtensionTypeDesc (RawExt);
731
+ auto Pos = findLastNonVersionCharacter (RawExt) + 1 ;
732
+ StringRef Name (RawExt.substr (0 , Pos));
733
+ StringRef Vers (RawExt.substr (Pos));
734
+
735
+ if (Type.empty ()) {
736
+ if (IgnoreUnknown)
737
+ return Error::success ();
738
+ return createStringError (errc::invalid_argument,
739
+ " invalid extension prefix '" + RawExt + " '" );
740
+ }
741
+
742
+ if (!IgnoreUnknown && Name.size () == Type.size ())
743
+ return createStringError (errc::invalid_argument,
744
+ " %s name missing after '%s'" , Desc.str ().c_str (),
745
+ Type.str ().c_str ());
746
+
747
+ unsigned Major, Minor, ConsumeLength;
748
+ if (auto E = getExtensionVersion (Name, Vers, Major, Minor, ConsumeLength,
749
+ EnableExperimentalExtension,
750
+ ExperimentalExtensionVersionCheck)) {
751
+ if (IgnoreUnknown) {
752
+ consumeError (std::move (E));
753
+ return Error::success ();
754
+ }
755
+ return E;
756
+ }
757
+
758
+ // Check if duplicated extension.
759
+ if (!IgnoreUnknown && llvm::is_contained (SeenExts, Name))
760
+ return createStringError (errc::invalid_argument, " duplicated %s '%s'" ,
761
+ Desc.str ().c_str (), Name.str ().c_str ());
762
+
763
+ if (IgnoreUnknown && !RISCVISAInfo::isSupportedExtension (Name))
764
+ return Error::success ();
765
+
766
+ SeenExts.push_back (Name.str ());
767
+ ExtsVersion.push_back ({Major, Minor});
768
+ return Error::success ();
769
+ }
770
+
771
+ static Error processSingleLetterExtension (
772
+ StringRef &RawExt, SmallVector<std::string, 8 > &SeenExts,
773
+ SmallVector<RISCVISAInfo::ExtensionVersion, 8 > &ExtsVersion,
774
+ bool IgnoreUnknown, bool EnableExperimentalExtension,
775
+ bool ExperimentalExtensionVersionCheck) {
776
+ unsigned Major, Minor, ConsumeLength;
777
+ StringRef Name = RawExt.take_front (1 );
778
+ RawExt.consume_front (Name);
779
+ if (auto E = getExtensionVersion (Name, RawExt, Major, Minor, ConsumeLength,
780
+ EnableExperimentalExtension,
781
+ ExperimentalExtensionVersionCheck)) {
782
+ if (IgnoreUnknown) {
783
+ consumeError (std::move (E));
784
+ RawExt = RawExt.substr (ConsumeLength);
785
+ return Error::success ();
786
+ }
787
+ return E;
788
+ }
789
+
790
+ RawExt = RawExt.substr (ConsumeLength);
791
+
792
+ // Check if duplicated extension.
793
+ if (!IgnoreUnknown && llvm::is_contained (SeenExts, Name))
794
+ return createStringError (errc::invalid_argument,
795
+ " duplicated standard user-level extension '%s'" ,
796
+ Name.str ().c_str ());
797
+
798
+ if (IgnoreUnknown && !RISCVISAInfo::isSupportedExtension (Name))
799
+ return Error::success ();
800
+
801
+ SeenExts.push_back (Name.str ());
802
+ ExtsVersion.push_back ({Major, Minor});
803
+ return Error::success ();
804
+ }
805
+
706
806
llvm::Expected<std::unique_ptr<RISCVISAInfo>>
707
807
RISCVISAInfo::parseArchString (StringRef Arch, bool EnableExperimentalExtension,
708
808
bool ExperimentalExtensionVersionCheck,
@@ -723,6 +823,8 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
723
823
724
824
unsigned XLen = HasRV64 ? 64 : 32 ;
725
825
std::unique_ptr<RISCVISAInfo> ISAInfo (new RISCVISAInfo (XLen));
826
+ SmallVector<std::string, 8 > SeenExts;
827
+ SmallVector<RISCVISAInfo::ExtensionVersion, 8 > ExtsVersion;
726
828
727
829
// The canonical order specified in ISA manual.
728
830
// Ref: Table 22.1 in RISC-V User-Level ISA V2.2
@@ -753,17 +855,6 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
753
855
// Skip rvxxx
754
856
StringRef Exts = Arch.substr (5 );
755
857
756
- // Remove multi-letter standard extensions, non-standard extensions and
757
- // supervisor-level extensions. They have 'z', 'x', 's' prefixes.
758
- // Parse them at the end.
759
- // Find the very first occurrence of 's', 'x' or 'z'.
760
- StringRef OtherExts;
761
- size_t Pos = Exts.find_first_of (" zsx" );
762
- if (Pos != StringRef::npos) {
763
- OtherExts = Exts.substr (Pos);
764
- Exts = Exts.substr (0 , Pos);
765
- }
766
-
767
858
unsigned Major, Minor, ConsumeLength;
768
859
if (Baseline == ' g' ) {
769
860
// Versions for g are disallowed, and this was checked for previously.
@@ -773,9 +864,11 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
773
864
// version since the we don't have clear version scheme for that on
774
865
// ISA spec.
775
866
for (const auto *Ext : RISCVGImplications) {
776
- if (auto Version = findDefaultVersion (Ext))
777
- ISAInfo->addExtension (Ext, *Version);
778
- else
867
+ if (auto Version = findDefaultVersion (Ext)) {
868
+ // Postpone AddExtension until end of this function
869
+ SeenExts.push_back (Ext);
870
+ ExtsVersion.push_back ({Version->Major , Version->Minor });
871
+ } else
779
872
llvm_unreachable (" Default extension version not found?" );
780
873
}
781
874
} else {
@@ -793,153 +886,61 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
793
886
Minor = Version->Minor ;
794
887
}
795
888
796
- ISAInfo->addExtension (StringRef (&Baseline, 1 ), {Major, Minor});
889
+ // Postpone AddExtension until end of this function
890
+ SeenExts.push_back (StringRef (&Baseline, 1 ).str ());
891
+ ExtsVersion.push_back ({Major, Minor});
797
892
}
798
893
799
894
// Consume the base ISA version number and any '_' between rvxxx and the
800
895
// first extension
801
896
Exts = Exts.drop_front (ConsumeLength);
802
897
Exts.consume_front (" _" );
803
898
804
- auto StdExtsItr = StdExts.begin ();
805
- auto StdExtsEnd = StdExts.end ();
806
- auto GoToNextExt = [](StringRef::iterator &I, unsigned ConsumeLength,
807
- StringRef::iterator E) {
808
- I += 1 + ConsumeLength;
809
- if (I != E && *I == ' _' )
810
- ++I;
811
- };
812
- for (auto I = Exts.begin (), E = Exts.end (); I != E;) {
813
- char C = *I;
814
-
815
- // Check ISA extensions are specified in the canonical order.
816
- while (StdExtsItr != StdExtsEnd && *StdExtsItr != C)
817
- ++StdExtsItr;
818
-
819
- if (StdExtsItr == StdExtsEnd) {
820
- // Either c contains a valid extension but it was not given in
821
- // canonical order or it is an invalid extension.
822
- if (StdExts.contains (C)) {
823
- return createStringError (
824
- errc::invalid_argument,
825
- " standard user-level extension not given in canonical order '%c'" ,
826
- C);
827
- }
828
-
829
- return createStringError (errc::invalid_argument,
830
- " invalid standard user-level extension '%c'" , C);
831
- }
832
-
833
- // Move to next char to prevent repeated letter.
834
- ++StdExtsItr;
835
-
836
- StringRef Next;
837
- unsigned Major, Minor, ConsumeLength;
838
- if (std::next (I) != E)
839
- Next = StringRef (std::next (I), E - std::next (I));
840
- if (auto E = getExtensionVersion (StringRef (&C, 1 ), Next, Major, Minor,
841
- ConsumeLength, EnableExperimentalExtension,
842
- ExperimentalExtensionVersionCheck)) {
843
- if (IgnoreUnknown) {
844
- consumeError (std::move (E));
845
- GoToNextExt (I, ConsumeLength, Exts.end ());
846
- continue ;
847
- }
848
- return std::move (E);
849
- }
850
-
851
- // The order is OK, then push it into features.
852
- // Currently LLVM supports only "mafdcvh".
853
- if (!isSupportedExtension (StringRef (&C, 1 ))) {
854
- if (IgnoreUnknown) {
855
- GoToNextExt (I, ConsumeLength, Exts.end ());
856
- continue ;
857
- }
858
- return createStringError (errc::invalid_argument,
859
- " unsupported standard user-level extension '%c'" ,
860
- C);
861
- }
862
- ISAInfo->addExtension (StringRef (&C, 1 ), {Major, Minor});
863
-
864
- // Consume full extension name and version, including any optional '_'
865
- // between this extension and the next
866
- GoToNextExt (I, ConsumeLength, Exts.end ());
867
- }
868
-
869
- // Handle other types of extensions other than the standard
870
- // general purpose and standard user-level extensions.
871
- // Parse the ISA string containing non-standard user-level
872
- // extensions, standard supervisor-level extensions and
873
- // non-standard supervisor-level extensions.
874
- // These extensions start with 'z', 's', 'x' prefixes, might have a version
875
- // number (major, minor) and are separated by a single underscore '_'. We do
876
- // not enforce a canonical order for them.
877
- // Set the hardware features for the extensions that are supported.
878
-
879
- // Multi-letter extensions are seperated by a single underscore
880
- // as described in RISC-V User-Level ISA V2.2.
881
- SmallVector<StringRef, 8 > Split;
882
- OtherExts.split (Split, ' _' );
883
-
884
- SmallVector<StringRef, 8 > AllExts;
885
- if (Split.size () > 1 || Split[0 ] != " " ) {
886
- for (StringRef Ext : Split) {
887
- if (Ext.empty ())
888
- return createStringError (errc::invalid_argument,
889
- " extension name missing after separator '_'" );
890
-
891
- StringRef Type = getExtensionType (Ext);
892
- StringRef Desc = getExtensionTypeDesc (Ext);
893
- auto Pos = findLastNonVersionCharacter (Ext) + 1 ;
894
- StringRef Name (Ext.substr (0 , Pos));
895
- StringRef Vers (Ext.substr (Pos));
896
-
897
- if (Type.empty ()) {
898
- if (IgnoreUnknown)
899
- continue ;
900
- return createStringError (errc::invalid_argument,
901
- " invalid extension prefix '" + Ext + " '" );
902
- }
903
-
904
- if (!IgnoreUnknown && Name.size () == Type.size ()) {
899
+ std::vector<std::string> SplitedExts;
900
+ if (auto E = splitExtsByUnderscore (Exts, SplitedExts))
901
+ return std::move (E);
902
+
903
+ for (auto Ext : SplitedExts) {
904
+ StringRef CurrExt = Ext;
905
+ while (!CurrExt.empty ()) {
906
+ if (AllStdExts.contains (CurrExt.front ())) {
907
+ if (auto E = processSingleLetterExtension (
908
+ CurrExt, SeenExts, ExtsVersion, IgnoreUnknown,
909
+ EnableExperimentalExtension, ExperimentalExtensionVersionCheck))
910
+ return E;
911
+ } else if (CurrExt.front () == ' z' || CurrExt.front () == ' s' ||
912
+ CurrExt.front () == ' x' ) {
913
+ if (auto E = processMultiLetterExtension (
914
+ CurrExt, SeenExts, ExtsVersion, IgnoreUnknown,
915
+ EnableExperimentalExtension, ExperimentalExtensionVersionCheck))
916
+ return E;
917
+ // Multi-letter extension must be seperate following extension with
918
+ // underscore
919
+ break ;
920
+ } else {
921
+ // FIXME: Could it be ignored by IgnoreUnknown?
905
922
return createStringError (errc::invalid_argument,
906
- " %s name missing after '%s'" ,
907
- Desc.str ().c_str (), Type.str ().c_str ());
908
- }
909
-
910
- unsigned Major, Minor, ConsumeLength;
911
- if (auto E = getExtensionVersion (Name, Vers, Major, Minor, ConsumeLength,
912
- EnableExperimentalExtension,
913
- ExperimentalExtensionVersionCheck)) {
914
- if (IgnoreUnknown) {
915
- consumeError (std::move (E));
916
- continue ;
917
- }
918
- return std::move (E);
919
- }
920
-
921
- // Check if duplicated extension.
922
- if (!IgnoreUnknown && llvm::is_contained (AllExts, Name)) {
923
- return createStringError (errc::invalid_argument, " duplicated %s '%s'" ,
924
- Desc.str ().c_str (), Name.str ().c_str ());
923
+ " invalid standard user-level extension '%c'" ,
924
+ CurrExt.front ());
925
925
}
926
-
927
- if (IgnoreUnknown && !isSupportedExtension (Name))
928
- continue ;
929
-
930
- ISAInfo->addExtension (Name, {Major, Minor});
931
- // Extension format is correct, keep parsing the extensions.
932
- // TODO: Save Type, Name, Major, Minor to avoid parsing them later.
933
- AllExts.push_back (Name);
934
926
}
935
927
}
936
928
937
- for (auto Ext : AllExts) {
938
- if (!isSupportedExtension (Ext)) {
939
- StringRef Desc = getExtensionTypeDesc (getExtensionType (Ext));
940
- return createStringError (errc::invalid_argument, " unsupported %s '%s'" ,
941
- Desc.str ().c_str (), Ext.str ().c_str ());
929
+ // Check all Extensions are supported.
930
+ for (size_t Idx = 0 ; Idx < SeenExts.size (); Idx++) {
931
+ if (!RISCVISAInfo::isSupportedExtension (SeenExts[Idx])) {
932
+ if (SeenExts[Idx].size () == 1 ) {
933
+ return createStringError (
934
+ errc::invalid_argument,
935
+ " unsupported standard user-level extension '%s'" ,
936
+ SeenExts[Idx].c_str ());
937
+ }
938
+ return createStringError (
939
+ errc::invalid_argument, " unsupported %s '%s'" ,
940
+ getExtensionTypeDesc (SeenExts[Idx]).str ().c_str (),
941
+ SeenExts[Idx].c_str ());
942
942
}
943
+ ISAInfo->addExtension (SeenExts[Idx], ExtsVersion[Idx]);
943
944
}
944
945
945
946
return RISCVISAInfo::postProcessAndChecking (std::move (ISAInfo));
0 commit comments