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
21namespace clang {
22namespace targets {
23
24// AVR Target
25class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
26public:
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();
61 }
62
63 void getTargetDefines(const LangOptions &Opts,
64 MacroBuilder &Builder) const override;
65
66 llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
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",
79 "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17",
80 "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26",
81 "r27", "r28", "r29", "r30", "r31", "__SP_L__", "__SP_H__"};
82 return llvm::ArrayRef(GCCRegNames);
83 }
84
85 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
86 return {};
87 }
88
89 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
90 static const TargetInfo::AddlRegName AddlRegNames[] = {
91 {.Names: {"xl", "X"}, .RegNum: 26}, {.Names: {"xh"}, .RegNum: 27}, {.Names: {"yl", "Y"}, .RegNum: 28},
92 {.Names: {"yh"}, .RegNum: 29}, {.Names: {"zl", "Z"}, .RegNum: 30}, {.Names: {"zh"}, .RegNum: 31}};
93 return llvm::ArrayRef(AddlRegNames);
94 }
95
96 bool validateAsmConstraint(const char *&Name,
97 TargetInfo::ConstraintInfo &Info) const override {
98 // There aren't any multi-character AVR specific constraints.
99 if (StringRef(Name).size() > 1)
100 return false;
101
102 switch (*Name) {
103 default:
104 return false;
105 case 'a': // Simple upper registers
106 case 'b': // Base pointer registers pairs
107 case 'd': // Upper register
108 case 'l': // Lower registers
109 case 'e': // Pointer register pairs
110 case 'q': // Stack pointer register
111 case 'r': // Any register
112 case 'w': // Special upper register pairs
113 case 't': // Temporary register
114 case 'x':
115 case 'X': // Pointer register pair X
116 case 'y':
117 case 'Y': // Pointer register pair Y
118 case 'z':
119 case 'Z': // Pointer register pair Z
120 Info.setAllowsRegister();
121 return true;
122 case 'I': // 6-bit positive integer constant
123 // Due to issue https://github.com/llvm/llvm-project/issues/51513, we
124 // allow value 64 in the frontend and let it be denied in the backend.
125 Info.setRequiresImmediate(Min: 0, Max: 64);
126 return true;
127 case 'J': // 6-bit negative integer constant
128 Info.setRequiresImmediate(Min: -63, Max: 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(Min: 0, Max: 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(Min: -6, Max: 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(StringRef 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(x: 32, y: 32);
182 }
183
184protected:
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