AVR.h revision 326941
1//===--- 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    WIntType = SignedInt;
56    Char32Type = UnsignedLong;
57    SigAtomicType = SignedChar;
58    resetDataLayout("e-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
59  }
60
61  void getTargetDefines(const LangOptions &Opts,
62                        MacroBuilder &Builder) const override;
63
64  ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
65
66  BuiltinVaListKind getBuiltinVaListKind() const override {
67    return TargetInfo::VoidPtrBuiltinVaList;
68  }
69
70  const char *getClobbers() const override { return ""; }
71
72  ArrayRef<const char *> getGCCRegNames() const override {
73    static const char *const GCCRegNames[] = {
74        "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",
75        "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
76        "r20", "r21", "r22", "r23", "r24", "r25", "X",   "Y",   "Z",   "SP"
77    };
78    return llvm::makeArrayRef(GCCRegNames);
79  }
80
81  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
82    return None;
83  }
84
85  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
86    static const TargetInfo::AddlRegName AddlRegNames[] = {
87        {{"r26", "r27"}, 26},
88        {{"r28", "r29"}, 27},
89        {{"r30", "r31"}, 28},
90        {{"SPL", "SPH"}, 29},
91    };
92    return llvm::makeArrayRef(AddlRegNames);
93  }
94
95  bool validateAsmConstraint(const char *&Name,
96                             TargetInfo::ConstraintInfo &Info) const override {
97    // There aren't any multi-character AVR specific constraints.
98    if (StringRef(Name).size() > 1)
99      return false;
100
101    switch (*Name) {
102    default:
103      return false;
104    case 'a': // Simple upper registers
105    case 'b': // Base pointer registers pairs
106    case 'd': // Upper register
107    case 'l': // Lower registers
108    case 'e': // Pointer register pairs
109    case 'q': // Stack pointer register
110    case 'r': // Any register
111    case 'w': // Special upper register pairs
112    case 't': // Temporary register
113    case 'x':
114    case 'X': // Pointer register pair X
115    case 'y':
116    case 'Y': // Pointer register pair Y
117    case 'z':
118    case 'Z': // Pointer register pair Z
119      Info.setAllowsRegister();
120      return true;
121    case 'I': // 6-bit positive integer constant
122      Info.setRequiresImmediate(0, 63);
123      return true;
124    case 'J': // 6-bit negative integer constant
125      Info.setRequiresImmediate(-63, 0);
126      return true;
127    case 'K': // Integer constant (Range: 2)
128      Info.setRequiresImmediate(2);
129      return true;
130    case 'L': // Integer constant (Range: 0)
131      Info.setRequiresImmediate(0);
132      return true;
133    case 'M': // 8-bit integer constant
134      Info.setRequiresImmediate(0, 0xff);
135      return true;
136    case 'N': // Integer constant (Range: -1)
137      Info.setRequiresImmediate(-1);
138      return true;
139    case 'O': // Integer constant (Range: 8, 16, 24)
140      Info.setRequiresImmediate({8, 16, 24});
141      return true;
142    case 'P': // Integer constant (Range: 1)
143      Info.setRequiresImmediate(1);
144      return true;
145    case 'R': // Integer constant (Range: -6 to 5)
146      Info.setRequiresImmediate(-6, 5);
147      return true;
148    case 'G': // Floating point constant
149    case 'Q': // A memory address based on Y or Z pointer with displacement.
150      return true;
151    }
152
153    return false;
154  }
155
156  IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
157    // AVR prefers int for 16-bit integers.
158    return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt)
159                          : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
160  }
161
162  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
163    // AVR uses int for int_least16_t and int_fast16_t.
164    return BitWidth == 16
165               ? (IsSigned ? SignedInt : UnsignedInt)
166               : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
167  }
168
169  bool isValidCPUName(StringRef Name) const override;
170  bool setCPU(const std::string &Name) override {
171    bool isValid = isValidCPUName(Name);
172    if (isValid)
173      CPU = Name;
174    return isValid;
175  }
176
177protected:
178  std::string CPU;
179};
180
181} // namespace targets
182} // namespace clang
183
184#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H
185