xref: /llvm-project/clang/lib/Basic/Targets/AVR.h (revision ca79ff07d8ae7a0c2531bfdb1cb623e25e5bd486)
1 //===--- AVR.h - Declare AVR target feature support -------------*- 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 // This file declares AVR TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H
15 
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/TargetParser/Triple.h"
20 
21 namespace clang {
22 namespace targets {
23 
24 // AVR Target
25 class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
26 public:
27   AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
28       : TargetInfo(Triple) {
29     TLSSupported = false;
30     PointerWidth = 16;
31     PointerAlign = 8;
32     ShortWidth = 16;
33     ShortAlign = 8;
34     IntWidth = 16;
35     IntAlign = 8;
36     LongWidth = 32;
37     LongAlign = 8;
38     LongLongWidth = 64;
39     LongLongAlign = 8;
40     SuitableAlign = 8;
41     DefaultAlignForAttributeAligned = 8;
42     HalfWidth = 16;
43     HalfAlign = 8;
44     FloatWidth = 32;
45     FloatAlign = 8;
46     DoubleWidth = 32;
47     DoubleAlign = 8;
48     DoubleFormat = &llvm::APFloat::IEEEsingle();
49     LongDoubleWidth = 32;
50     LongDoubleAlign = 8;
51     LongDoubleFormat = &llvm::APFloat::IEEEsingle();
52     SizeType = UnsignedInt;
53     PtrDiffType = SignedInt;
54     IntPtrType = SignedInt;
55     Char16Type = UnsignedInt;
56     WIntType = SignedInt;
57     Int16Type = SignedInt;
58     Char32Type = UnsignedLong;
59     SigAtomicType = SignedChar;
60     resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
61   }
62 
63   void getTargetDefines(const LangOptions &Opts,
64                         MacroBuilder &Builder) const override;
65 
66   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
67 
68   bool allowsLargerPreferedTypeAlignment() const override { return false; }
69 
70   BuiltinVaListKind getBuiltinVaListKind() const override {
71     return TargetInfo::VoidPtrBuiltinVaList;
72   }
73 
74   std::string_view getClobbers() const override { return ""; }
75 
76   ArrayRef<const char *> getGCCRegNames() const override {
77     static const char *const GCCRegNames[] = {
78         "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",
79         "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
80         "r20", "r21", "r22", "r23", "r24", "r25", "X",   "Y",   "Z",   "SP"};
81     return llvm::ArrayRef(GCCRegNames);
82   }
83 
84   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
85     return {};
86   }
87 
88   ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
89     static const TargetInfo::AddlRegName AddlRegNames[] = {
90         {{"r26", "r27"}, 26},
91         {{"r28", "r29"}, 27},
92         {{"r30", "r31"}, 28},
93         {{"SPL", "SPH"}, 29},
94     };
95     return llvm::ArrayRef(AddlRegNames);
96   }
97 
98   bool validateAsmConstraint(const char *&Name,
99                              TargetInfo::ConstraintInfo &Info) const override {
100     // There aren't any multi-character AVR specific constraints.
101     if (StringRef(Name).size() > 1)
102       return false;
103 
104     switch (*Name) {
105     default:
106       return false;
107     case 'a': // Simple upper registers
108     case 'b': // Base pointer registers pairs
109     case 'd': // Upper register
110     case 'l': // Lower registers
111     case 'e': // Pointer register pairs
112     case 'q': // Stack pointer register
113     case 'r': // Any register
114     case 'w': // Special upper register pairs
115     case 't': // Temporary register
116     case 'x':
117     case 'X': // Pointer register pair X
118     case 'y':
119     case 'Y': // Pointer register pair Y
120     case 'z':
121     case 'Z': // Pointer register pair Z
122       Info.setAllowsRegister();
123       return true;
124     case 'I': // 6-bit positive integer constant
125       Info.setRequiresImmediate(0, 63);
126       return true;
127     case 'J': // 6-bit negative integer constant
128       Info.setRequiresImmediate(-63, 0);
129       return true;
130     case 'K': // Integer constant (Range: 2)
131       Info.setRequiresImmediate(2);
132       return true;
133     case 'L': // Integer constant (Range: 0)
134       Info.setRequiresImmediate(0);
135       return true;
136     case 'M': // 8-bit integer constant
137       Info.setRequiresImmediate(0, 0xff);
138       return true;
139     case 'N': // Integer constant (Range: -1)
140       Info.setRequiresImmediate(-1);
141       return true;
142     case 'O': // Integer constant (Range: 8, 16, 24)
143       Info.setRequiresImmediate({8, 16, 24});
144       return true;
145     case 'P': // Integer constant (Range: 1)
146       Info.setRequiresImmediate(1);
147       return true;
148     case 'R': // Integer constant (Range: -6 to 5)
149       Info.setRequiresImmediate(-6, 5);
150       return true;
151     case 'G': // Floating point constant 0.0
152       Info.setRequiresImmediate(0);
153       return true;
154     case 'Q': // A memory address based on Y or Z pointer with displacement.
155       return true;
156     }
157 
158     return false;
159   }
160 
161   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
162     // AVR prefers int for 16-bit integers.
163     return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt)
164                           : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
165   }
166 
167   IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
168     // AVR uses int for int_least16_t and int_fast16_t.
169     return BitWidth == 16
170                ? (IsSigned ? SignedInt : UnsignedInt)
171                : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
172   }
173 
174   bool isValidCPUName(StringRef Name) const override;
175   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
176   bool setCPU(const std::string &Name) override;
177   std::optional<std::string> handleAsmEscapedChar(char EscChar) const override;
178   StringRef getABI() const override { return ABI; }
179 
180   std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
181     return std::make_pair(32, 32);
182   }
183 
184 protected:
185   std::string CPU;
186   StringRef ABI;
187   StringRef DefineName;
188   StringRef Arch;
189   int NumFlashBanks = 0;
190 };
191 
192 } // namespace targets
193 } // namespace clang
194 
195 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H
196