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