xref: /llvm-project/llvm/lib/TargetParser/ARMTargetParserCommon.cpp (revision d0756caedcf067860240bf31e8f9d371ba706757)
1f09cf34dSArchibald Elliott //===---------------- ARMTargetParserCommon ---------------------*- C++ -*-===//
2f09cf34dSArchibald Elliott //
3f09cf34dSArchibald Elliott // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f09cf34dSArchibald Elliott // See https://llvm.org/LICENSE.txt for license information.
5f09cf34dSArchibald Elliott // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f09cf34dSArchibald Elliott //
7f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===//
8f09cf34dSArchibald Elliott //
9f09cf34dSArchibald Elliott // Code that is common to ARMTargetParser and AArch64TargetParser.
10f09cf34dSArchibald Elliott //
11f09cf34dSArchibald Elliott //===----------------------------------------------------------------------===//
12f09cf34dSArchibald Elliott 
13f09cf34dSArchibald Elliott #include "llvm/TargetParser/ARMTargetParserCommon.h"
14f09cf34dSArchibald Elliott #include "llvm/ADT/SmallVector.h"
15f09cf34dSArchibald Elliott #include "llvm/ADT/StringSwitch.h"
16f09cf34dSArchibald Elliott 
17f09cf34dSArchibald Elliott using namespace llvm;
18f09cf34dSArchibald Elliott 
19f09cf34dSArchibald Elliott StringRef ARM::getArchSynonym(StringRef Arch) {
20f09cf34dSArchibald Elliott   return StringSwitch<StringRef>(Arch)
21f09cf34dSArchibald Elliott       .Case("v5", "v5t")
22f09cf34dSArchibald Elliott       .Case("v5e", "v5te")
23f09cf34dSArchibald Elliott       .Case("v6j", "v6")
24f09cf34dSArchibald Elliott       .Case("v6hl", "v6k")
25f09cf34dSArchibald Elliott       .Cases("v6m", "v6sm", "v6s-m", "v6-m")
26f09cf34dSArchibald Elliott       .Cases("v6z", "v6zk", "v6kz")
27f09cf34dSArchibald Elliott       .Cases("v7", "v7a", "v7hl", "v7l", "v7-a")
28f09cf34dSArchibald Elliott       .Case("v7r", "v7-r")
29f09cf34dSArchibald Elliott       .Case("v7m", "v7-m")
30f09cf34dSArchibald Elliott       .Case("v7em", "v7e-m")
31f09cf34dSArchibald Elliott       .Cases("v8", "v8a", "v8l", "aarch64", "arm64", "v8-a")
32f09cf34dSArchibald Elliott       .Case("v8.1a", "v8.1-a")
33f09cf34dSArchibald Elliott       .Case("v8.2a", "v8.2-a")
34f09cf34dSArchibald Elliott       .Case("v8.3a", "v8.3-a")
35f09cf34dSArchibald Elliott       .Case("v8.4a", "v8.4-a")
36f09cf34dSArchibald Elliott       .Case("v8.5a", "v8.5-a")
37f09cf34dSArchibald Elliott       .Case("v8.6a", "v8.6-a")
38f09cf34dSArchibald Elliott       .Case("v8.7a", "v8.7-a")
39f09cf34dSArchibald Elliott       .Case("v8.8a", "v8.8-a")
40f09cf34dSArchibald Elliott       .Case("v8.9a", "v8.9-a")
41f09cf34dSArchibald Elliott       .Case("v8r", "v8-r")
42f09cf34dSArchibald Elliott       .Cases("v9", "v9a", "v9-a")
43f09cf34dSArchibald Elliott       .Case("v9.1a", "v9.1-a")
44f09cf34dSArchibald Elliott       .Case("v9.2a", "v9.2-a")
45f09cf34dSArchibald Elliott       .Case("v9.3a", "v9.3-a")
46f09cf34dSArchibald Elliott       .Case("v9.4a", "v9.4-a")
4759b23015SLucas Duarte Prates       .Case("v9.5a", "v9.5-a")
48*d0756caeSJonathan Thackray       .Case("v9.6a", "v9.6-a")
49f09cf34dSArchibald Elliott       .Case("v8m.base", "v8-m.base")
50f09cf34dSArchibald Elliott       .Case("v8m.main", "v8-m.main")
51f09cf34dSArchibald Elliott       .Case("v8.1m.main", "v8.1-m.main")
52f09cf34dSArchibald Elliott       .Default(Arch);
53f09cf34dSArchibald Elliott }
54f09cf34dSArchibald Elliott 
55f09cf34dSArchibald Elliott StringRef ARM::getCanonicalArchName(StringRef Arch) {
56f09cf34dSArchibald Elliott   size_t offset = StringRef::npos;
57f09cf34dSArchibald Elliott   StringRef A = Arch;
58f09cf34dSArchibald Elliott   StringRef Error = "";
59f09cf34dSArchibald Elliott 
60f09cf34dSArchibald Elliott   // Begins with "arm" / "thumb", move past it.
61586ecdf2SKazu Hirata   if (A.starts_with("arm64_32"))
62f09cf34dSArchibald Elliott     offset = 8;
63586ecdf2SKazu Hirata   else if (A.starts_with("arm64e"))
64f09cf34dSArchibald Elliott     offset = 6;
65586ecdf2SKazu Hirata   else if (A.starts_with("arm64"))
66f09cf34dSArchibald Elliott     offset = 5;
67586ecdf2SKazu Hirata   else if (A.starts_with("aarch64_32"))
68f09cf34dSArchibald Elliott     offset = 10;
69586ecdf2SKazu Hirata   else if (A.starts_with("arm"))
70f09cf34dSArchibald Elliott     offset = 3;
71586ecdf2SKazu Hirata   else if (A.starts_with("thumb"))
72f09cf34dSArchibald Elliott     offset = 5;
73586ecdf2SKazu Hirata   else if (A.starts_with("aarch64")) {
74f09cf34dSArchibald Elliott     offset = 7;
75f09cf34dSArchibald Elliott     // AArch64 uses "_be", not "eb" suffix.
76f09cf34dSArchibald Elliott     if (A.contains("eb"))
77f09cf34dSArchibald Elliott       return Error;
78f09cf34dSArchibald Elliott     if (A.substr(offset, 3) == "_be")
79f09cf34dSArchibald Elliott       offset += 3;
80f09cf34dSArchibald Elliott   }
81f09cf34dSArchibald Elliott 
82f09cf34dSArchibald Elliott   // Ex. "armebv7", move past the "eb".
83f09cf34dSArchibald Elliott   if (offset != StringRef::npos && A.substr(offset, 2) == "eb")
84f09cf34dSArchibald Elliott     offset += 2;
85f09cf34dSArchibald Elliott   // Or, if it ends with eb ("armv7eb"), chop it off.
86586ecdf2SKazu Hirata   else if (A.ends_with("eb"))
87f09cf34dSArchibald Elliott     A = A.substr(0, A.size() - 2);
88f09cf34dSArchibald Elliott   // Trim the head
89f09cf34dSArchibald Elliott   if (offset != StringRef::npos)
90f09cf34dSArchibald Elliott     A = A.substr(offset);
91f09cf34dSArchibald Elliott 
92f09cf34dSArchibald Elliott   // Empty string means offset reached the end, which means it's valid.
93f09cf34dSArchibald Elliott   if (A.empty())
94f09cf34dSArchibald Elliott     return Arch;
95f09cf34dSArchibald Elliott 
96f09cf34dSArchibald Elliott   // Only match non-marketing names
97f09cf34dSArchibald Elliott   if (offset != StringRef::npos) {
98f09cf34dSArchibald Elliott     // Must start with 'vN'.
99f09cf34dSArchibald Elliott     if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1])))
100f09cf34dSArchibald Elliott       return Error;
101f09cf34dSArchibald Elliott     // Can't have an extra 'eb'.
102f09cf34dSArchibald Elliott     if (A.contains("eb"))
103f09cf34dSArchibald Elliott       return Error;
104f09cf34dSArchibald Elliott   }
105f09cf34dSArchibald Elliott 
106f09cf34dSArchibald Elliott   // Arch will either be a 'v' name (v7a) or a marketing name (xscale).
107f09cf34dSArchibald Elliott   return A;
108f09cf34dSArchibald Elliott }
109f09cf34dSArchibald Elliott 
110f09cf34dSArchibald Elliott ARM::ISAKind ARM::parseArchISA(StringRef Arch) {
111f09cf34dSArchibald Elliott   return StringSwitch<ISAKind>(Arch)
112f09cf34dSArchibald Elliott       .StartsWith("aarch64", ISAKind::AARCH64)
113f09cf34dSArchibald Elliott       .StartsWith("arm64", ISAKind::AARCH64)
114f09cf34dSArchibald Elliott       .StartsWith("thumb", ISAKind::THUMB)
115f09cf34dSArchibald Elliott       .StartsWith("arm", ISAKind::ARM)
116f09cf34dSArchibald Elliott       .Default(ISAKind::INVALID);
117f09cf34dSArchibald Elliott }
118f09cf34dSArchibald Elliott 
119f09cf34dSArchibald Elliott ARM::EndianKind ARM::parseArchEndian(StringRef Arch) {
120586ecdf2SKazu Hirata   if (Arch.starts_with("armeb") || Arch.starts_with("thumbeb") ||
121586ecdf2SKazu Hirata       Arch.starts_with("aarch64_be"))
122f09cf34dSArchibald Elliott     return EndianKind::BIG;
123f09cf34dSArchibald Elliott 
124586ecdf2SKazu Hirata   if (Arch.starts_with("arm") || Arch.starts_with("thumb")) {
125586ecdf2SKazu Hirata     if (Arch.ends_with("eb"))
126f09cf34dSArchibald Elliott       return EndianKind::BIG;
127f09cf34dSArchibald Elliott     else
128f09cf34dSArchibald Elliott       return EndianKind::LITTLE;
129f09cf34dSArchibald Elliott   }
130f09cf34dSArchibald Elliott 
131586ecdf2SKazu Hirata   if (Arch.starts_with("aarch64") || Arch.starts_with("aarch64_32"))
132f09cf34dSArchibald Elliott     return EndianKind::LITTLE;
133f09cf34dSArchibald Elliott 
134f09cf34dSArchibald Elliott   return EndianKind::INVALID;
135f09cf34dSArchibald Elliott }
136f09cf34dSArchibald Elliott 
137f09cf34dSArchibald Elliott // Parse a branch protection specification, which has the form
1387bd17212STomas Matheson //   standard | none | [bti,pac-ret[+b-key,+leaf,+pc]*]
139f09cf34dSArchibald Elliott // Returns true on success, with individual elements of the specification
140f09cf34dSArchibald Elliott // returned in `PBP`. Returns false in error, with `Err` containing
141f09cf34dSArchibald Elliott // an erroneous part of the spec.
142f09cf34dSArchibald Elliott bool ARM::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP,
1436aac30faSJack Styles                                 StringRef &Err, bool EnablePAuthLR) {
144d5539347SJie Fu   PBP = {"none", "a_key", false, false, false};
145f09cf34dSArchibald Elliott   if (Spec == "none")
146f09cf34dSArchibald Elliott     return true; // defaults are ok
147f09cf34dSArchibald Elliott 
148f09cf34dSArchibald Elliott   if (Spec == "standard") {
149f09cf34dSArchibald Elliott     PBP.Scope = "non-leaf";
150f09cf34dSArchibald Elliott     PBP.BranchTargetEnforcement = true;
15140d5c2bcSJohn Brawn     PBP.GuardedControlStack = true;
1526aac30faSJack Styles     PBP.BranchProtectionPAuthLR = EnablePAuthLR;
153f09cf34dSArchibald Elliott     return true;
154f09cf34dSArchibald Elliott   }
155f09cf34dSArchibald Elliott 
156f09cf34dSArchibald Elliott   SmallVector<StringRef, 4> Opts;
157f09cf34dSArchibald Elliott   Spec.split(Opts, "+");
158f09cf34dSArchibald Elliott   for (int I = 0, E = Opts.size(); I != E; ++I) {
159f09cf34dSArchibald Elliott     StringRef Opt = Opts[I].trim();
160f09cf34dSArchibald Elliott     if (Opt == "bti") {
161f09cf34dSArchibald Elliott       PBP.BranchTargetEnforcement = true;
162f09cf34dSArchibald Elliott       continue;
163f09cf34dSArchibald Elliott     }
164f09cf34dSArchibald Elliott     if (Opt == "pac-ret") {
165f09cf34dSArchibald Elliott       PBP.Scope = "non-leaf";
166f09cf34dSArchibald Elliott       for (; I + 1 != E; ++I) {
167f09cf34dSArchibald Elliott         StringRef PACOpt = Opts[I + 1].trim();
168f09cf34dSArchibald Elliott         if (PACOpt == "leaf")
169f09cf34dSArchibald Elliott           PBP.Scope = "all";
170f09cf34dSArchibald Elliott         else if (PACOpt == "b-key")
171f09cf34dSArchibald Elliott           PBP.Key = "b_key";
1727bd17212STomas Matheson         else if (PACOpt == "pc")
1737bd17212STomas Matheson           PBP.BranchProtectionPAuthLR = true;
174f09cf34dSArchibald Elliott         else
175f09cf34dSArchibald Elliott           break;
176f09cf34dSArchibald Elliott       }
177f09cf34dSArchibald Elliott       continue;
178f09cf34dSArchibald Elliott     }
17940d5c2bcSJohn Brawn     if (Opt == "gcs") {
18040d5c2bcSJohn Brawn       PBP.GuardedControlStack = true;
18140d5c2bcSJohn Brawn       continue;
18240d5c2bcSJohn Brawn     }
183f09cf34dSArchibald Elliott     if (Opt == "")
184f09cf34dSArchibald Elliott       Err = "<empty>";
185f09cf34dSArchibald Elliott     else
186f09cf34dSArchibald Elliott       Err = Opt;
187f09cf34dSArchibald Elliott     return false;
188f09cf34dSArchibald Elliott   }
189f09cf34dSArchibald Elliott 
190f09cf34dSArchibald Elliott   return true;
191f09cf34dSArchibald Elliott }
192