LLVM 17.0.0git
ARMTargetParserCommon.cpp
Go to the documentation of this file.
1//===---------------- ARMTargetParserCommon ---------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// Code that is common to ARMTargetParser and AArch64TargetParser.
10//
11//===----------------------------------------------------------------------===//
12
16
17using namespace llvm;
18
20 return StringSwitch<StringRef>(Arch)
21 .Case("v5", "v5t")
22 .Case("v5e", "v5te")
23 .Case("v6j", "v6")
24 .Case("v6hl", "v6k")
25 .Cases("v6m", "v6sm", "v6s-m", "v6-m")
26 .Cases("v6z", "v6zk", "v6kz")
27 .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
28 .Case("v7r", "v7-r")
29 .Case("v7m", "v7-m")
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")
41 .Case("v8r", "v8-r")
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("v8m.base", "v8-m.base")
48 .Case("v8m.main", "v8-m.main")
49 .Case("v8.1m.main", "v8.1-m.main")
50 .Default(Arch);
51}
52
54 size_t offset = StringRef::npos;
55 StringRef A = Arch;
56 StringRef Error = "";
57
58 // Begins with "arm" / "thumb", move past it.
59 if (A.startswith("arm64_32"))
60 offset = 8;
61 else if (A.startswith("arm64e"))
62 offset = 6;
63 else if (A.startswith("arm64"))
64 offset = 5;
65 else if (A.startswith("aarch64_32"))
66 offset = 10;
67 else if (A.startswith("arm"))
68 offset = 3;
69 else if (A.startswith("thumb"))
70 offset = 5;
71 else if (A.startswith("aarch64")) {
72 offset = 7;
73 // AArch64 uses "_be", not "eb" suffix.
74 if (A.contains("eb"))
75 return Error;
76 if (A.substr(offset, 3) == "_be")
77 offset += 3;
78 }
79
80 // Ex. "armebv7", move past the "eb".
81 if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
82 offset += 2;
83 // Or, if it ends with eb ("armv7eb"), chop it off.
84 else if (A.endswith("eb"))
85 A = A.substr(0, A.size() - 2);
86 // Trim the head
87 if (offset != StringRef::npos)
88 A = A.substr(offset);
89
90 // Empty string means offset reached the end, which means it's valid.
91 if (A.empty())
92 return Arch;
93
94 // Only match non-marketing names
95 if (offset != StringRef::npos) {
96 // Must start with 'vN'.
97 if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
98 return Error;
99 // Can't have an extra 'eb'.
100 if (A.contains("eb"))
101 return Error;
102 }
103
104 // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
105 return A;
106}
107
109 return StringSwitch<ISAKind>(Arch)
110 .StartsWith("aarch64", ISAKind::AARCH64)
111 .StartsWith("arm64", ISAKind::AARCH64)
112 .StartsWith("thumb", ISAKind::THUMB)
113 .StartsWith("arm", ISAKind::ARM)
114 .Default(ISAKind::INVALID);
115}
116
118 if (Arch.startswith("armeb") || Arch.startswith("thumbeb") ||
119 Arch.startswith("aarch64_be"))
120 return EndianKind::BIG;
121
122 if (Arch.startswith("arm") || Arch.startswith("thumb")) {
123 if (Arch.endswith("eb"))
124 return EndianKind::BIG;
125 else
126 return EndianKind::LITTLE;
127 }
128
129 if (Arch.startswith("aarch64") || Arch.startswith("aarch64_32"))
130 return EndianKind::LITTLE;
131
132 return EndianKind::INVALID;
133}
134
135// Parse a branch protection specification, which has the form
136// standard | none | [bti,pac-ret[+b-key,+leaf]*]
137// Returns true on success, with individual elements of the specification
138// returned in `PBP`. Returns false in error, with `Err` containing
139// an erroneous part of the spec.
141 StringRef &Err) {
142 PBP = {"none", "a_key", false};
143 if (Spec == "none")
144 return true; // defaults are ok
145
146 if (Spec == "standard") {
147 PBP.Scope = "non-leaf";
148 PBP.BranchTargetEnforcement = true;
149 return true;
150 }
151
153 Spec.split(Opts, "+");
154 for (int I = 0, E = Opts.size(); I != E; ++I) {
155 StringRef Opt = Opts[I].trim();
156 if (Opt == "bti") {
157 PBP.BranchTargetEnforcement = true;
158 continue;
159 }
160 if (Opt == "pac-ret") {
161 PBP.Scope = "non-leaf";
162 for (; I + 1 != E; ++I) {
163 StringRef PACOpt = Opts[I + 1].trim();
164 if (PACOpt == "leaf")
165 PBP.Scope = "all";
166 else if (PACOpt == "b-key")
167 PBP.Key = "b_key";
168 else
169 break;
170 }
171 continue;
172 }
173 if (Opt == "")
174 Err = "<empty>";
175 else
176 Err = Opt;
177 return false;
178 }
179
180 return true;
181}
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define I(x, y, z)
Definition: MD5.cpp:58
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
size_t size() const
Definition: SmallVector.h:91
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
bool endswith(StringRef Suffix) const
Definition: StringRef.h:277
static constexpr size_t npos
Definition: StringRef.h:52
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:83
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:90
StringRef getCanonicalArchName(StringRef Arch)
MArch is expected to be of the form (arm|thumb)?(eb)?(v.
ISAKind parseArchISA(StringRef Arch)
StringRef getArchSynonym(StringRef Arch)
Converts e.g. "armv8" -> "armv8-a".
bool parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, StringRef &Err)
EndianKind parseArchEndian(StringRef Arch)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18