200 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares AVR TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H14#define LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H15 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 Target25class 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("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8:16-a:8");61 }62 63 void getTargetDefines(const LangOptions &Opts,64 MacroBuilder &Builder) const override;65 66 llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {67 return {};68 }69 70 bool allowsLargerPreferedTypeAlignment() const override { return false; }71 72 BuiltinVaListKind getBuiltinVaListKind() const override {73 return TargetInfo::VoidPtrBuiltinVaList;74 }75 76 std::string_view getClobbers() const override { return ""; }77 78 ArrayRef<const char *> getGCCRegNames() const override {79 static const char *const GCCRegNames[] = {80 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",81 "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",82 "r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP"};83 return llvm::ArrayRef(GCCRegNames);84 }85 86 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {87 return {};88 }89 90 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override {91 static const TargetInfo::AddlRegName AddlRegNames[] = {92 {{"r26", "r27"}, 26},93 {{"r28", "r29"}, 27},94 {{"r30", "r31"}, 28},95 {{"SPL", "SPH"}, 29},96 };97 return llvm::ArrayRef(AddlRegNames);98 }99 100 bool validateAsmConstraint(const char *&Name,101 TargetInfo::ConstraintInfo &Info) const override {102 // There aren't any multi-character AVR specific constraints.103 if (StringRef(Name).size() > 1)104 return false;105 106 switch (*Name) {107 default:108 return false;109 case 'a': // Simple upper registers110 case 'b': // Base pointer registers pairs111 case 'd': // Upper register112 case 'l': // Lower registers113 case 'e': // Pointer register pairs114 case 'q': // Stack pointer register115 case 'r': // Any register116 case 'w': // Special upper register pairs117 case 't': // Temporary register118 case 'x':119 case 'X': // Pointer register pair X120 case 'y':121 case 'Y': // Pointer register pair Y122 case 'z':123 case 'Z': // Pointer register pair Z124 Info.setAllowsRegister();125 return true;126 case 'I': // 6-bit positive integer constant127 // Due to issue https://github.com/llvm/llvm-project/issues/51513, we128 // allow value 64 in the frontend and let it be denied in the backend.129 Info.setRequiresImmediate(0, 64);130 return true;131 case 'J': // 6-bit negative integer constant132 Info.setRequiresImmediate(-63, 0);133 return true;134 case 'K': // Integer constant (Range: 2)135 Info.setRequiresImmediate(2);136 return true;137 case 'L': // Integer constant (Range: 0)138 Info.setRequiresImmediate(0);139 return true;140 case 'M': // 8-bit integer constant141 Info.setRequiresImmediate(0, 0xff);142 return true;143 case 'N': // Integer constant (Range: -1)144 Info.setRequiresImmediate(-1);145 return true;146 case 'O': // Integer constant (Range: 8, 16, 24)147 Info.setRequiresImmediate({8, 16, 24});148 return true;149 case 'P': // Integer constant (Range: 1)150 Info.setRequiresImmediate(1);151 return true;152 case 'R': // Integer constant (Range: -6 to 5)153 Info.setRequiresImmediate(-6, 5);154 return true;155 case 'G': // Floating point constant 0.0156 Info.setRequiresImmediate(0);157 return true;158 case 'Q': // A memory address based on Y or Z pointer with displacement.159 return true;160 }161 162 return false;163 }164 165 IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {166 // AVR prefers int for 16-bit integers.167 return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt)168 : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned);169 }170 171 IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final {172 // AVR uses int for int_least16_t and int_fast16_t.173 return BitWidth == 16174 ? (IsSigned ? SignedInt : UnsignedInt)175 : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned);176 }177 178 bool isValidCPUName(StringRef Name) const override;179 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;180 bool setCPU(const std::string &Name) override;181 std::optional<std::string> handleAsmEscapedChar(char EscChar) const override;182 StringRef getABI() const override { return ABI; }183 184 std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {185 return std::make_pair(32, 32);186 }187 188protected:189 std::string CPU;190 StringRef ABI;191 StringRef DefineName;192 StringRef Arch;193 int NumFlashBanks = 0;194};195 196} // namespace targets197} // namespace clang198 199#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H200