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