@@ -603,13 +603,41 @@ extension Triple {
603
603
}
604
604
}
605
605
606
+ enum ARMProfile {
607
+ case a, r, m
608
+
609
+ init ? < S: StringProtocol > ( _ archName: S ) {
610
+ switch Triple . SubArch. parse ( Substring ( Triple . Arch. cannonicalARMArchName ( from: archName) ) ) {
611
+ case . armSubArch_v6m, . armSubArch_v7m, . armSubArch_v7em,
612
+ . armSubArch_v8m_mainline, . armSubArch_v8m_baseline,
613
+ . armSubArch_v8_1m_mainline:
614
+ self = . m
615
+ case . armSubArch_v7r, . armSubArch_v8r:
616
+ self = . r
617
+ case . armSubArch_v7, . armSubArch_v7ve, . armSubArch_v7k,
618
+ . armSubArch_v8, . armSubArch_v8_1a, . armSubArch_v8_2a,
619
+ . armSubArch_v8_3a, . armSubArch_v8_4a, . armSubArch_v8_5a:
620
+ self = . a
621
+ case . armSubArch_v2, . armSubArch_v2a, . armSubArch_v3, . armSubArch_v3m,
622
+ . armSubArch_v4, . armSubArch_v4t, . armSubArch_v5, . armSubArch_v5e,
623
+ . armSubArch_v6, . armSubArch_v6k, . armSubArch_v6kz, . armSubArch_v6t2,
624
+ . armSubArch_v7s,
625
+ . kalimbaSubArch_v3, . kalimbaSubArch_v4, . kalimbaSubArch_v5,
626
+ . mipsSubArch_r6,
627
+ nil :
628
+ return nil
629
+ }
630
+ }
631
+ }
632
+
606
633
// Parse ARM architectures not handled by `parse`. On its own, this is not
607
634
// enough to correctly parse an ARM architecture.
608
635
private static func parseARMArch< S: StringProtocol > ( _ archName: S ) -> Triple . Arch ? {
636
+
609
637
let ISA = ARMISA ( archName: archName)
610
638
let endianness = Endianness ( armArchName: archName)
611
639
612
- var arch : Triple . Arch ? = nil
640
+ let arch : Triple . Arch ?
613
641
switch ( endianness, ISA) {
614
642
case ( . little, . arm) :
615
643
arch = . arm
@@ -623,15 +651,98 @@ extension Triple {
623
651
arch = . thumbeb
624
652
case ( . big, . aarch64) :
625
653
arch = . aarch64_be
626
- default :
627
- break
654
+ case ( nil , _ ) , ( _ , nil ) :
655
+ arch = nil
628
656
}
629
657
630
- // FIXME: thumb architectures require additional validation. See LLVM's [parseARMArch](https://llvm.org/doxygen/Triple_8cpp.html#a721eb5bffb57cea96d7a9b45cbe302cf)
658
+ let cannonicalArchName = cannonicalARMArchName ( from: archName)
659
+
660
+ if cannonicalArchName. isEmpty {
661
+ return nil
662
+ }
663
+
664
+ // Thumb only exists in v4+
665
+ if ISA == . thumb && ( cannonicalArchName. hasPrefix ( " v2 " ) || cannonicalArchName. hasPrefix ( " v3 " ) ) {
666
+ return nil
667
+ }
668
+
669
+ let subArch = Triple . SubArch. parse ( archName)
670
+ let profile = subArch? . armProfile
671
+ let version = subArch? . armVersion
672
+
673
+ // Thumb only for v6m
674
+ if profile == . m && version == 6 {
675
+ if endianness == . big {
676
+ return . thumbeb
677
+ } else {
678
+ return . thumb
679
+ }
680
+ }
631
681
632
682
return arch
633
683
}
634
684
685
+ // Based on LLVM's ARM::getCanonicalArchName
686
+ //
687
+ // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but
688
+ // (iwmmxt|xscale)(eb)? is also permitted. If the former, return
689
+ // "v.+", if the latter, return unmodified string, minus 'eb'.
690
+ // If invalid, return empty string.
691
+ fileprivate static func cannonicalARMArchName< S: StringProtocol > ( from arch: S ) -> String {
692
+ var name = Substring ( arch)
693
+
694
+ func dropPrefix( _ prefix: String ) {
695
+ if name. hasPrefix ( prefix) {
696
+ name = name. dropFirst ( prefix. count)
697
+ }
698
+ }
699
+
700
+ let possiblePrefixes = [ " arm64_32 " , " arm64 " , " aarch64_32 " , " arm " , " thumb " , " aarch64 " ]
701
+
702
+ if let prefix = possiblePrefixes. first ( where: name. hasPrefix) {
703
+ dropPrefix ( prefix)
704
+
705
+ if prefix == " aarch64 " {
706
+ // AArch64 uses "_be", not "eb" suffix.
707
+ if name. contains ( " eb " ) {
708
+ return " "
709
+ }
710
+
711
+ dropPrefix ( " _be " )
712
+ }
713
+ }
714
+
715
+ // Ex. "armebv7", move past the "eb".
716
+ if name != arch {
717
+ dropPrefix ( " eb " )
718
+ }
719
+ // Or, if it ends with eb ("armv7eb"), chop it off.
720
+ else if name. hasSuffix ( " eb " ) {
721
+ name = name. dropLast ( 2 )
722
+ }
723
+
724
+ // Reached the end - arch is valid.
725
+ if name. isEmpty {
726
+ return String ( arch)
727
+ }
728
+
729
+ // Only match non-marketing names
730
+ if name != arch {
731
+ // Must start with 'vN'.
732
+ if name. count >= 2 && ( name. first != " v " || !name. dropFirst ( ) . first!. isNumber) {
733
+ return " "
734
+ }
735
+
736
+ // Can't have an extra 'eb'.
737
+ if name. hasPrefix ( " eb " ) {
738
+ return " "
739
+ }
740
+ }
741
+
742
+ // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
743
+ return String ( name)
744
+ }
745
+
635
746
private static func parseBPFArch< S: StringProtocol > ( _ archName: S ) -> Triple . Arch ? {
636
747
637
748
let isLittleEndianHost = 1 . littleEndian == 1
@@ -682,8 +793,174 @@ extension Triple {
682
793
683
794
extension Triple {
684
795
public enum SubArch : Hashable {
685
- fileprivate static func parse( _ component: Substring ) -> Triple . SubArch ? {
686
- return nil
796
+ case armSubArch_v2
797
+ case armSubArch_v2a
798
+ case armSubArch_v3
799
+ case armSubArch_v3m
800
+ case armSubArch_v4
801
+ case armSubArch_v4t
802
+ case armSubArch_v5
803
+ case armSubArch_v5e
804
+ case armSubArch_v6
805
+ case armSubArch_v6k
806
+ case armSubArch_v6kz
807
+ case armSubArch_v6m
808
+ case armSubArch_v6t2
809
+ case armSubArch_v7
810
+ case armSubArch_v7em
811
+ case armSubArch_v7k
812
+ case armSubArch_v7m
813
+ case armSubArch_v7r
814
+ case armSubArch_v7s
815
+ case armSubArch_v7ve
816
+ case armSubArch_v8
817
+ case armSubArch_v8_1a
818
+ case armSubArch_v8_1m_mainline
819
+ case armSubArch_v8_2a
820
+ case armSubArch_v8_3a
821
+ case armSubArch_v8_4a
822
+ case armSubArch_v8_5a
823
+ case armSubArch_v8m_baseline
824
+ case armSubArch_v8m_mainline
825
+ case armSubArch_v8r
826
+
827
+ case kalimbaSubArch_v3
828
+ case kalimbaSubArch_v4
829
+ case kalimbaSubArch_v5
830
+
831
+ case mipsSubArch_r6
832
+
833
+ fileprivate static func parse< S: StringProtocol > ( _ component: S ) -> Triple . SubArch ? {
834
+
835
+ if component. hasPrefix ( " mips " ) && ( component. hasSuffix ( " r6el " ) || component. hasSuffix ( " r6 " ) ) {
836
+ return . mipsSubArch_r6
837
+ }
838
+
839
+ let armSubArch = Triple . Arch. cannonicalARMArchName ( from: component)
840
+
841
+ if armSubArch. isEmpty {
842
+ switch component {
843
+ case _ where component. hasSuffix ( " kalimba3 " ) :
844
+ return . kalimbaSubArch_v3
845
+ case _ where component. hasSuffix ( " kalimba4 " ) :
846
+ return . kalimbaSubArch_v4
847
+ case _ where component. hasSuffix ( " kalimba5 " ) :
848
+ return . kalimbaSubArch_v5
849
+ default :
850
+ return nil
851
+ }
852
+ }
853
+
854
+ switch armSubArch {
855
+ case " v2 " :
856
+ return . armSubArch_v2
857
+ case " v2a " :
858
+ return . armSubArch_v2a
859
+ case " v3 " :
860
+ return . armSubArch_v3
861
+ case " v3m " :
862
+ return . armSubArch_v3m
863
+ case " v4 " :
864
+ return . armSubArch_v4
865
+ case " v4t " :
866
+ return . armSubArch_v4t
867
+ case " v5t " :
868
+ return . armSubArch_v5
869
+ case " v5te " , " v5tej " , " xscale " :
870
+ return . armSubArch_v5e
871
+ case " v6 " :
872
+ return . armSubArch_v6
873
+ case " v6k " :
874
+ return . armSubArch_v6k
875
+ case " v6kz " :
876
+ return . armSubArch_v6kz
877
+ case " v6-m " :
878
+ return . armSubArch_v6m
879
+ case " v6t2 " :
880
+ return . armSubArch_v6t2
881
+ case " v7-a " :
882
+ return . armSubArch_v7
883
+ case " v7k " :
884
+ return . armSubArch_v7k
885
+ case " v7-m " :
886
+ return . armSubArch_v7m
887
+ case " v7e-m " :
888
+ return . armSubArch_v7em
889
+ case " v7-r " :
890
+ return . armSubArch_v7r
891
+ case " v7s " :
892
+ return . armSubArch_v7s
893
+ case " v7ve " :
894
+ return . armSubArch_v7ve
895
+ case " v8-a " :
896
+ return . armSubArch_v8
897
+ case " v8-m.main " :
898
+ return . armSubArch_v8m_mainline
899
+ case " v8-m.base " :
900
+ return . armSubArch_v8m_baseline
901
+ case " v8-r " :
902
+ return . armSubArch_v8r
903
+ case " v8.1-m.main " :
904
+ return . armSubArch_v8_1m_mainline
905
+ case " v8.1-a " :
906
+ return . armSubArch_v8_1a
907
+ case " v8.2-a " :
908
+ return . armSubArch_v8_2a
909
+ case " v8.3-a " :
910
+ return . armSubArch_v8_3a
911
+ case " v8.4-a " :
912
+ return . armSubArch_v8_4a
913
+ case " v8.5-a " :
914
+ return . armSubArch_v8_5a
915
+ default :
916
+ return nil
917
+ }
918
+ }
919
+
920
+ var armProfile : Triple . Arch . ARMProfile ? {
921
+ switch self {
922
+ case . armSubArch_v6m, . armSubArch_v7m, . armSubArch_v7em,
923
+ . armSubArch_v8m_mainline, . armSubArch_v8m_baseline,
924
+ . armSubArch_v8_1m_mainline:
925
+ return . m
926
+ case . armSubArch_v7r, . armSubArch_v8r:
927
+ return . r
928
+ case . armSubArch_v7, . armSubArch_v7ve, . armSubArch_v7k,
929
+ . armSubArch_v8, . armSubArch_v8_1a, . armSubArch_v8_2a,
930
+ . armSubArch_v8_3a, . armSubArch_v8_4a, . armSubArch_v8_5a:
931
+ return . a
932
+ case . armSubArch_v2, . armSubArch_v2a, . armSubArch_v3, . armSubArch_v3m,
933
+ . armSubArch_v4, . armSubArch_v4t, . armSubArch_v5, . armSubArch_v5e,
934
+ . armSubArch_v6, . armSubArch_v6k, . armSubArch_v6kz, . armSubArch_v6t2,
935
+ . armSubArch_v7s,
936
+ . kalimbaSubArch_v3, . kalimbaSubArch_v4, . kalimbaSubArch_v5,
937
+ . mipsSubArch_r6:
938
+ return nil
939
+ }
940
+ }
941
+
942
+ var armVersion : Int ? {
943
+ switch self {
944
+ case . armSubArch_v2, . armSubArch_v2a:
945
+ return 2
946
+ case . armSubArch_v3, . armSubArch_v3m:
947
+ return 3
948
+ case . armSubArch_v4, . armSubArch_v4t:
949
+ return 4
950
+ case . armSubArch_v5, . armSubArch_v5e:
951
+ return 5
952
+ case . armSubArch_v6, . armSubArch_v6k, . armSubArch_v6kz, . armSubArch_v6m, . armSubArch_v6t2:
953
+ return 6
954
+ case . armSubArch_v7, . armSubArch_v7em, . armSubArch_v7k, . armSubArch_v7m, . armSubArch_v7r,
955
+ . armSubArch_v7s, . armSubArch_v7ve:
956
+ return 7
957
+ case . armSubArch_v8, . armSubArch_v8_1a, . armSubArch_v8_1m_mainline, . armSubArch_v8_2a,
958
+ . armSubArch_v8_3a, . armSubArch_v8_4a, . armSubArch_v8_5a, . armSubArch_v8m_baseline,
959
+ . armSubArch_v8m_mainline, . armSubArch_v8r:
960
+ return 8
961
+ case . kalimbaSubArch_v3, . kalimbaSubArch_v4, . kalimbaSubArch_v5, . mipsSubArch_r6:
962
+ return nil
963
+ }
687
964
}
688
965
}
689
966
}
0 commit comments