AVR.h revision 353358
1218585Sjkim//===--- AVR.h - Declare AVR target feature support -------------*- C++ -*-===//
2218585Sjkim//
3218585Sjkim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4218585Sjkim// See https://llvm.org/LICENSE.txt for license information.
5218585Sjkim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6218585Sjkim//
7218585Sjkim//===----------------------------------------------------------------------===//
8306536Sjkim//
9218585Sjkim// This file declares AVR TargetInfo objects.
10218585Sjkim//
11218585Sjkim//===----------------------------------------------------------------------===//
12218585Sjkim
13218585Sjkim#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H
14218585Sjkim#define LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H
15218585Sjkim
16218585Sjkim#include "clang/Basic/TargetInfo.h"
17218585Sjkim#include "clang/Basic/TargetOptions.h"
18218585Sjkim#include "llvm/ADT/Triple.h"
19218585Sjkim#include "llvm/Support/Compiler.h"
20218585Sjkim
21218585Sjkimnamespace clang {
22218585Sjkimnamespace targets {
23218585Sjkim
24218585Sjkim// AVR Target
25218585Sjkimclass LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
26218585Sjkimpublic:
27218585Sjkim  AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
28218585Sjkim      : TargetInfo(Triple) {
29218585Sjkim    TLSSupported = false;
30218585Sjkim    PointerWidth = 16;
31218585Sjkim    PointerAlign = 8;
32218585Sjkim    IntWidth = 16;
33218585Sjkim    IntAlign = 8;
34218585Sjkim    LongWidth = 32;
35218585Sjkim    LongAlign = 8;
36218585Sjkim    LongLongWidth = 64;
37218585Sjkim    LongLongAlign = 8;
38218585Sjkim    SuitableAlign = 8;
39218585Sjkim    DefaultAlignForAttributeAligned = 8;
40218585Sjkim    HalfWidth = 16;
41218585Sjkim    HalfAlign = 8;
42218585Sjkim    FloatWidth = 32;
43218585Sjkim    FloatAlign = 8;
44218590Sjkim    DoubleWidth = 32;
45218590Sjkim    DoubleAlign = 8;
46218590Sjkim    DoubleFormat = &llvm::APFloat::IEEEsingle();
47218585Sjkim    LongDoubleWidth = 32;
48218585Sjkim    LongDoubleAlign = 8;
49218585Sjkim    LongDoubleFormat = &llvm::APFloat::IEEEsingle();
50218585Sjkim    SizeType = UnsignedInt;
51218585Sjkim    PtrDiffType = SignedInt;
52218585Sjkim    IntPtrType = SignedInt;
53218585Sjkim    Char16Type = UnsignedInt;
54218585Sjkim    WIntType = SignedInt;
55218585Sjkim    Char32Type = UnsignedLong;
56218585Sjkim    SigAtomicType = SignedChar;
57218585Sjkim    resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8");
58218585Sjkim  }
59218585Sjkim
60218585Sjkim  void getTargetDefines(const LangOptions &Opts,
61218585Sjkim                        MacroBuilder &Builder) const override;
62218585Sjkim
63218585Sjkim  ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
64218585Sjkim
65218585Sjkim  BuiltinVaListKind getBuiltinVaListKind() const override {
66218585Sjkim    return TargetInfo::VoidPtrBuiltinVaList;
67218585Sjkim  }
68218585Sjkim
69218585Sjkim  const char *getClobbers() const override { return ""; }
70218585Sjkim
71218585Sjkim  ArrayRef<const char *> getGCCRegNames() const override {
72218585Sjkim    static const char *const GCCRegNames[] = {
73218585Sjkim        "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",
74218585Sjkim        "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
75218585Sjkim        "r20", "r21", "r22", "r23", "r24", "r25", "X",   "Y",   "Z",   "SP"
76218585Sjkim    };
77218585Sjkim    return llvm::makeArrayRef(GCCRegNames);
78218585Sjkim  }
79218585Sjkim
80218585Sjkim  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
81218585Sjkim    return None;
82218585Sjkim  }
83218585Sjkim
84218585Sjkim  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {
85218585Sjkim    static const TargetInfo::AddlRegName AddlRegNames[] = {
86218585Sjkim        {{"r26", "r27"}, 26},
87218585Sjkim        {{"r28", "r29"}, 27},
88218585Sjkim        {{"r30", "r31"}, 28},
89218585Sjkim        {{"SPL", "SPH"}, 29},
90218585Sjkim    };
91218585Sjkim    return llvm::makeArrayRef(AddlRegNames);
92218585Sjkim  }
93218585Sjkim
94218585Sjkim  bool validateAsmConstraint(const char *&Name,
95218585Sjkim                             TargetInfo::ConstraintInfo &Info) const override {
96218585Sjkim    // There aren't any multi-character AVR specific constraints.
97218585Sjkim    if (StringRef(Name).size() > 1)
98218585Sjkim      return false;
99218585Sjkim
100218585Sjkim    switch (*Name) {
101218585Sjkim    default:
102218585Sjkim      return false;
103218585Sjkim    case 'a': // Simple upper registers
104218585Sjkim    case 'b': // Base pointer registers pairs
105218585Sjkim    case 'd': // Upper register
106218585Sjkim    case 'l': // Lower registers
107218585Sjkim    case 'e': // Pointer register pairs
108238381Sjkim    case 'q': // Stack pointer register
109238381Sjkim    case 'r': // Any register
110238381Sjkim    case 'w': // Special upper register pairs
111238381Sjkim    case 't': // Temporary register
112238381Sjkim    case 'x':
113238381Sjkim    case 'X': // Pointer register pair X
114238381Sjkim    case 'y':
115238381Sjkim    case 'Y': // Pointer register pair Y
116238381Sjkim    case 'z':
117238381Sjkim    case 'Z': // Pointer register pair Z
118238381Sjkim      Info.setAllowsRegister();
119218585Sjkim      return true;
120218585Sjkim    case 'I': // 6-bit positive integer constant
121218585Sjkim      Info.setRequiresImmediate(0, 63);
122306536Sjkim      return true;
123218585Sjkim    case 'J': // 6-bit negative integer constant
124218585Sjkim      Info.setRequiresImmediate(-63, 0);
125218585Sjkim      return true;
126218585Sjkim    case 'K': // Integer constant (Range: 2)
127218585Sjkim      Info.setRequiresImmediate(2);
128218585Sjkim      return true;
129218585Sjkim    case 'L': // Integer constant (Range: 0)
130218585Sjkim      Info.setRequiresImmediate(0);
131220663Sjkim      return true;
132220663Sjkim    case 'M': // 8-bit integer constant
133220663Sjkim      Info.setRequiresImmediate(0, 0xff);
134220663Sjkim      return true;
135218585Sjkim    case 'N': // Integer constant (Range: -1)
136218585Sjkim      Info.setRequiresImmediate(-1);
137218585Sjkim      return true;
138218585Sjkim    case 'O': // Integer constant (Range: 8, 16, 24)
139218585Sjkim      Info.setRequiresImmediate({8, 16, 24});
140218585Sjkim      return true;
141218585Sjkim    case 'P': // Integer constant (Range: 1)
142218585Sjkim      Info.setRequiresImmediate(1);
143218585Sjkim      return true;
144306536Sjkim    case 'R': // Integer constant (Range: -6 to 5)
145218585Sjkim      Info.setRequiresImmediate(-6, 5);
146218585Sjkim      return true;
147218585Sjkim    case 'G': // Floating point constant
148218585Sjkim    case 'Q': // A memory address based on Y or Z pointer with displacement.
149218585Sjkim      return true;
150218585Sjkim    }
151218585Sjkim
152218585Sjkim    return false;
153218585Sjkim  }
154218585Sjkim
155218585Sjkim  IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
156218585Sjkim    // AVR prefers int for 16-bit integers.
157218585Sjkim    return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt)
158218585Sjkim                          : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);
159218585Sjkim  }
160218585Sjkim
161218585Sjkim  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {
162218585Sjkim    // AVR uses int for int_least16_t and int_fast16_t.
163218585Sjkim    return BitWidth == 16
164218585Sjkim               ? (IsSigned ? SignedInt : UnsignedInt)
165218585Sjkim               : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);
166218585Sjkim  }
167218585Sjkim
168218585Sjkim  bool isValidCPUName(StringRef Name) const override;
169218585Sjkim  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
170218585Sjkim  bool setCPU(const std::string &Name) override {
171218585Sjkim    bool isValid = isValidCPUName(Name);
172306536Sjkim    if (isValid)
173218585Sjkim      CPU = Name;
174218585Sjkim    return isValid;
175218585Sjkim  }
176218585Sjkim
177218585Sjkimprotected:
178218585Sjkim  std::string CPU;
179218585Sjkim};
180218585Sjkim
181218585Sjkim} // namespace targets
182306536Sjkim} // namespace clang
183218585Sjkim
184218585Sjkim#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H
185218585Sjkim