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