1 //===---------------- ARMTargetParserCommon ---------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Code that is common to ARMTargetParser and AArch64TargetParser.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/TargetParser/ARMTargetParserCommon.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringSwitch.h"
19 StringRef
ARM::getArchSynonym(StringRef Arch
) {
20 return StringSwitch
<StringRef
>(Arch
)
25 .Cases("v6m", "v6sm", "v6s-m", "v6-m")
26 .Cases("v6z", "v6zk", "v6kz")
27 .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
30 .Case("v7em", "v7e-m")
31 .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
32 .Case("v8.1a", "v8.1-a")
33 .Case("v8.2a", "v8.2-a")
34 .Case("v8.3a", "v8.3-a")
35 .Case("v8.4a", "v8.4-a")
36 .Case("v8.5a", "v8.5-a")
37 .Case("v8.6a", "v8.6-a")
38 .Case("v8.7a", "v8.7-a")
39 .Case("v8.8a", "v8.8-a")
40 .Case("v8.9a", "v8.9-a")
42 .Cases("v9", "v9a", "v9-a")
43 .Case("v9.1a", "v9.1-a")
44 .Case("v9.2a", "v9.2-a")
45 .Case("v9.3a", "v9.3-a")
46 .Case("v9.4a", "v9.4-a")
47 .Case("v9.5a", "v9.5-a")
48 .Case("v9.6a", "v9.6-a")
49 .Case("v8m.base", "v8-m.base")
50 .Case("v8m.main", "v8-m.main")
51 .Case("v8.1m.main", "v8.1-m.main")
55 StringRef
ARM::getCanonicalArchName(StringRef Arch
) {
56 size_t offset
= StringRef::npos
;
60 // Begins with "arm" / "thumb", move past it.
61 if (A
.starts_with("arm64_32"))
63 else if (A
.starts_with("arm64e"))
65 else if (A
.starts_with("arm64"))
67 else if (A
.starts_with("aarch64_32"))
69 else if (A
.starts_with("arm"))
71 else if (A
.starts_with("thumb"))
73 else if (A
.starts_with("aarch64")) {
75 // AArch64 uses "_be", not "eb" suffix.
78 if (A
.substr(offset
, 3) == "_be")
82 // Ex. "armebv7", move past the "eb".
83 if (offset
!= StringRef::npos
&& A
.substr(offset
, 2) == "eb")
85 // Or, if it ends with eb ("armv7eb"), chop it off.
86 else if (A
.ends_with("eb"))
87 A
= A
.substr(0, A
.size() - 2);
89 if (offset
!= StringRef::npos
)
92 // Empty string means offset reached the end, which means it's valid.
96 // Only match non-marketing names
97 if (offset
!= StringRef::npos
) {
98 // Must start with 'vN'.
99 if (A
.size() >= 2 && (A
[0] != 'v' || !std::isdigit(A
[1])))
101 // Can't have an extra 'eb'.
102 if (A
.contains("eb"))
106 // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
110 ARM::ISAKind
ARM::parseArchISA(StringRef Arch
) {
111 return StringSwitch
<ISAKind
>(Arch
)
112 .StartsWith("aarch64", ISAKind::AARCH64
)
113 .StartsWith("arm64", ISAKind::AARCH64
)
114 .StartsWith("thumb", ISAKind::THUMB
)
115 .StartsWith("arm", ISAKind::ARM
)
116 .Default(ISAKind::INVALID
);
119 ARM::EndianKind
ARM::parseArchEndian(StringRef Arch
) {
120 if (Arch
.starts_with("armeb") || Arch
.starts_with("thumbeb") ||
121 Arch
.starts_with("aarch64_be"))
122 return EndianKind::BIG
;
124 if (Arch
.starts_with("arm") || Arch
.starts_with("thumb")) {
125 if (Arch
.ends_with("eb"))
126 return EndianKind::BIG
;
128 return EndianKind::LITTLE
;
131 if (Arch
.starts_with("aarch64") || Arch
.starts_with("aarch64_32"))
132 return EndianKind::LITTLE
;
134 return EndianKind::INVALID
;
137 // Parse a branch protection specification, which has the form
138 // standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*]
139 // Returns true on success, with individual elements of the specification
140 // returned in `PBP`. Returns false in error, with `Err` containing
141 // an erroneous part of the spec.
142 bool ARM::parseBranchProtection(StringRef Spec
, ParsedBranchProtection
&PBP
,
143 StringRef
&Err
, bool EnablePAuthLR
) {
144 PBP
= {"none", "a_key", false, false, false};
146 return true; // defaults are ok
148 if (Spec
== "standard") {
149 PBP
.Scope
= "non-leaf";
150 PBP
.BranchTargetEnforcement
= true;
151 PBP
.GuardedControlStack
= true;
152 PBP
.BranchProtectionPAuthLR
= EnablePAuthLR
;
156 SmallVector
<StringRef
, 4> Opts
;
157 Spec
.split(Opts
, "+");
158 for (int I
= 0, E
= Opts
.size(); I
!= E
; ++I
) {
159 StringRef Opt
= Opts
[I
].trim();
161 PBP
.BranchTargetEnforcement
= true;
164 if (Opt
== "pac-ret") {
165 PBP
.Scope
= "non-leaf";
166 for (; I
+ 1 != E
; ++I
) {
167 StringRef PACOpt
= Opts
[I
+ 1].trim();
168 if (PACOpt
== "leaf")
170 else if (PACOpt
== "b-key")
172 else if (PACOpt
== "pc")
173 PBP
.BranchProtectionPAuthLR
= true;
180 PBP
.GuardedControlStack
= true;