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