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