1326941Sdim//===--- AVR.h - Declare AVR target feature support -------------*- C++ -*-===// 2326941Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6326941Sdim// 7326941Sdim//===----------------------------------------------------------------------===// 8326941Sdim// 9326941Sdim// This file declares AVR TargetInfo objects. 10326941Sdim// 11326941Sdim//===----------------------------------------------------------------------===// 12326941Sdim 13326941Sdim#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H 14326941Sdim#define LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H 15326941Sdim 16326941Sdim#include "clang/Basic/TargetInfo.h" 17326941Sdim#include "clang/Basic/TargetOptions.h" 18326941Sdim#include "llvm/ADT/Triple.h" 19326941Sdim#include "llvm/Support/Compiler.h" 20326941Sdim 21326941Sdimnamespace clang { 22326941Sdimnamespace targets { 23326941Sdim 24326941Sdim// AVR Target 25326941Sdimclass LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo { 26326941Sdimpublic: 27326941Sdim AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 28326941Sdim : TargetInfo(Triple) { 29326941Sdim TLSSupported = false; 30326941Sdim PointerWidth = 16; 31326941Sdim PointerAlign = 8; 32326941Sdim IntWidth = 16; 33326941Sdim IntAlign = 8; 34326941Sdim LongWidth = 32; 35326941Sdim LongAlign = 8; 36326941Sdim LongLongWidth = 64; 37326941Sdim LongLongAlign = 8; 38326941Sdim SuitableAlign = 8; 39326941Sdim DefaultAlignForAttributeAligned = 8; 40326941Sdim HalfWidth = 16; 41326941Sdim HalfAlign = 8; 42326941Sdim FloatWidth = 32; 43326941Sdim FloatAlign = 8; 44326941Sdim DoubleWidth = 32; 45326941Sdim DoubleAlign = 8; 46326941Sdim DoubleFormat = &llvm::APFloat::IEEEsingle(); 47326941Sdim LongDoubleWidth = 32; 48326941Sdim LongDoubleAlign = 8; 49326941Sdim LongDoubleFormat = &llvm::APFloat::IEEEsingle(); 50326941Sdim SizeType = UnsignedInt; 51326941Sdim PtrDiffType = SignedInt; 52326941Sdim IntPtrType = SignedInt; 53326941Sdim Char16Type = UnsignedInt; 54326941Sdim WIntType = SignedInt; 55326941Sdim Char32Type = UnsignedLong; 56326941Sdim SigAtomicType = SignedChar; 57341825Sdim resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"); 58326941Sdim } 59326941Sdim 60326941Sdim void getTargetDefines(const LangOptions &Opts, 61326941Sdim MacroBuilder &Builder) const override; 62326941Sdim 63326941Sdim ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } 64326941Sdim 65326941Sdim BuiltinVaListKind getBuiltinVaListKind() const override { 66326941Sdim return TargetInfo::VoidPtrBuiltinVaList; 67326941Sdim } 68326941Sdim 69326941Sdim const char *getClobbers() const override { return ""; } 70326941Sdim 71326941Sdim ArrayRef<const char *> getGCCRegNames() const override { 72326941Sdim static const char *const GCCRegNames[] = { 73326941Sdim "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", 74326941Sdim "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", 75326941Sdim "r20", "r21", "r22", "r23", "r24", "r25", "X", "Y", "Z", "SP" 76326941Sdim }; 77326941Sdim return llvm::makeArrayRef(GCCRegNames); 78326941Sdim } 79326941Sdim 80326941Sdim ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 81326941Sdim return None; 82326941Sdim } 83326941Sdim 84326941Sdim ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override { 85326941Sdim static const TargetInfo::AddlRegName AddlRegNames[] = { 86326941Sdim {{"r26", "r27"}, 26}, 87326941Sdim {{"r28", "r29"}, 27}, 88326941Sdim {{"r30", "r31"}, 28}, 89326941Sdim {{"SPL", "SPH"}, 29}, 90326941Sdim }; 91326941Sdim return llvm::makeArrayRef(AddlRegNames); 92326941Sdim } 93326941Sdim 94326941Sdim bool validateAsmConstraint(const char *&Name, 95326941Sdim TargetInfo::ConstraintInfo &Info) const override { 96326941Sdim // There aren't any multi-character AVR specific constraints. 97326941Sdim if (StringRef(Name).size() > 1) 98326941Sdim return false; 99326941Sdim 100326941Sdim switch (*Name) { 101326941Sdim default: 102326941Sdim return false; 103326941Sdim case 'a': // Simple upper registers 104326941Sdim case 'b': // Base pointer registers pairs 105326941Sdim case 'd': // Upper register 106326941Sdim case 'l': // Lower registers 107326941Sdim case 'e': // Pointer register pairs 108326941Sdim case 'q': // Stack pointer register 109326941Sdim case 'r': // Any register 110326941Sdim case 'w': // Special upper register pairs 111326941Sdim case 't': // Temporary register 112326941Sdim case 'x': 113326941Sdim case 'X': // Pointer register pair X 114326941Sdim case 'y': 115326941Sdim case 'Y': // Pointer register pair Y 116326941Sdim case 'z': 117326941Sdim case 'Z': // Pointer register pair Z 118326941Sdim Info.setAllowsRegister(); 119326941Sdim return true; 120326941Sdim case 'I': // 6-bit positive integer constant 121326941Sdim Info.setRequiresImmediate(0, 63); 122326941Sdim return true; 123326941Sdim case 'J': // 6-bit negative integer constant 124326941Sdim Info.setRequiresImmediate(-63, 0); 125326941Sdim return true; 126326941Sdim case 'K': // Integer constant (Range: 2) 127326941Sdim Info.setRequiresImmediate(2); 128326941Sdim return true; 129326941Sdim case 'L': // Integer constant (Range: 0) 130326941Sdim Info.setRequiresImmediate(0); 131326941Sdim return true; 132326941Sdim case 'M': // 8-bit integer constant 133326941Sdim Info.setRequiresImmediate(0, 0xff); 134326941Sdim return true; 135326941Sdim case 'N': // Integer constant (Range: -1) 136326941Sdim Info.setRequiresImmediate(-1); 137326941Sdim return true; 138326941Sdim case 'O': // Integer constant (Range: 8, 16, 24) 139326941Sdim Info.setRequiresImmediate({8, 16, 24}); 140326941Sdim return true; 141326941Sdim case 'P': // Integer constant (Range: 1) 142326941Sdim Info.setRequiresImmediate(1); 143326941Sdim return true; 144326941Sdim case 'R': // Integer constant (Range: -6 to 5) 145326941Sdim Info.setRequiresImmediate(-6, 5); 146326941Sdim return true; 147326941Sdim case 'G': // Floating point constant 148326941Sdim case 'Q': // A memory address based on Y or Z pointer with displacement. 149326941Sdim return true; 150326941Sdim } 151326941Sdim 152326941Sdim return false; 153326941Sdim } 154326941Sdim 155326941Sdim IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { 156326941Sdim // AVR prefers int for 16-bit integers. 157326941Sdim return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt) 158326941Sdim : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned); 159326941Sdim } 160326941Sdim 161326941Sdim IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { 162326941Sdim // AVR uses int for int_least16_t and int_fast16_t. 163326941Sdim return BitWidth == 16 164326941Sdim ? (IsSigned ? SignedInt : UnsignedInt) 165326941Sdim : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); 166326941Sdim } 167326941Sdim 168326941Sdim bool isValidCPUName(StringRef Name) const override; 169341825Sdim void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 170326941Sdim bool setCPU(const std::string &Name) override { 171326941Sdim bool isValid = isValidCPUName(Name); 172326941Sdim if (isValid) 173326941Sdim CPU = Name; 174326941Sdim return isValid; 175326941Sdim } 176326941Sdim 177326941Sdimprotected: 178326941Sdim std::string CPU; 179326941Sdim}; 180326941Sdim 181326941Sdim} // namespace targets 182326941Sdim} // namespace clang 183326941Sdim 184326941Sdim#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H 185