diff options
Diffstat (limited to 'clang/lib/Basic/Targets/AVR.h')
| -rw-r--r-- | clang/lib/Basic/Targets/AVR.h | 184 | 
1 files changed, 184 insertions, 0 deletions
| diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h new file mode 100644 index 000000000000..94f006ee1b8a --- /dev/null +++ b/clang/lib/Basic/Targets/AVR.h @@ -0,0 +1,184 @@ +//===--- AVR.h - Declare AVR target feature support -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares AVR TargetInfo objects. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H +#define LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H + +#include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" + +namespace clang { +namespace targets { + +// AVR Target +class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo { +public: +  AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) +      : TargetInfo(Triple) { +    TLSSupported = false; +    PointerWidth = 16; +    PointerAlign = 8; +    IntWidth = 16; +    IntAlign = 8; +    LongWidth = 32; +    LongAlign = 8; +    LongLongWidth = 64; +    LongLongAlign = 8; +    SuitableAlign = 8; +    DefaultAlignForAttributeAligned = 8; +    HalfWidth = 16; +    HalfAlign = 8; +    FloatWidth = 32; +    FloatAlign = 8; +    DoubleWidth = 32; +    DoubleAlign = 8; +    DoubleFormat = &llvm::APFloat::IEEEsingle(); +    LongDoubleWidth = 32; +    LongDoubleAlign = 8; +    LongDoubleFormat = &llvm::APFloat::IEEEsingle(); +    SizeType = UnsignedInt; +    PtrDiffType = SignedInt; +    IntPtrType = SignedInt; +    Char16Type = UnsignedInt; +    WIntType = SignedInt; +    Char32Type = UnsignedLong; +    SigAtomicType = SignedChar; +    resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"); +  } + +  void getTargetDefines(const LangOptions &Opts, +                        MacroBuilder &Builder) const override; + +  ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + +  BuiltinVaListKind getBuiltinVaListKind() const override { +    return TargetInfo::VoidPtrBuiltinVaList; +  } + +  const char *getClobbers() const override { return ""; } + +  ArrayRef<const char *> getGCCRegNames() const override { +    static const char *const GCCRegNames[] = { +        "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9", +        "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", +        "r20", "r21", "r22", "r23", "r24", "r25", "X",   "Y",   "Z",   "SP" +    }; +    return llvm::makeArrayRef(GCCRegNames); +  } + +  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { +    return None; +  } + +  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override { +    static const TargetInfo::AddlRegName AddlRegNames[] = { +        {{"r26", "r27"}, 26}, +        {{"r28", "r29"}, 27}, +        {{"r30", "r31"}, 28}, +        {{"SPL", "SPH"}, 29}, +    }; +    return llvm::makeArrayRef(AddlRegNames); +  } + +  bool validateAsmConstraint(const char *&Name, +                             TargetInfo::ConstraintInfo &Info) const override { +    // There aren't any multi-character AVR specific constraints. +    if (StringRef(Name).size() > 1) +      return false; + +    switch (*Name) { +    default: +      return false; +    case 'a': // Simple upper registers +    case 'b': // Base pointer registers pairs +    case 'd': // Upper register +    case 'l': // Lower registers +    case 'e': // Pointer register pairs +    case 'q': // Stack pointer register +    case 'r': // Any register +    case 'w': // Special upper register pairs +    case 't': // Temporary register +    case 'x': +    case 'X': // Pointer register pair X +    case 'y': +    case 'Y': // Pointer register pair Y +    case 'z': +    case 'Z': // Pointer register pair Z +      Info.setAllowsRegister(); +      return true; +    case 'I': // 6-bit positive integer constant +      Info.setRequiresImmediate(0, 63); +      return true; +    case 'J': // 6-bit negative integer constant +      Info.setRequiresImmediate(-63, 0); +      return true; +    case 'K': // Integer constant (Range: 2) +      Info.setRequiresImmediate(2); +      return true; +    case 'L': // Integer constant (Range: 0) +      Info.setRequiresImmediate(0); +      return true; +    case 'M': // 8-bit integer constant +      Info.setRequiresImmediate(0, 0xff); +      return true; +    case 'N': // Integer constant (Range: -1) +      Info.setRequiresImmediate(-1); +      return true; +    case 'O': // Integer constant (Range: 8, 16, 24) +      Info.setRequiresImmediate({8, 16, 24}); +      return true; +    case 'P': // Integer constant (Range: 1) +      Info.setRequiresImmediate(1); +      return true; +    case 'R': // Integer constant (Range: -6 to 5) +      Info.setRequiresImmediate(-6, 5); +      return true; +    case 'G': // Floating point constant +    case 'Q': // A memory address based on Y or Z pointer with displacement. +      return true; +    } + +    return false; +  } + +  IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { +    // AVR prefers int for 16-bit integers. +    return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt) +                          : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned); +  } + +  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const final { +    // AVR uses int for int_least16_t and int_fast16_t. +    return BitWidth == 16 +               ? (IsSigned ? SignedInt : UnsignedInt) +               : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); +  } + +  bool isValidCPUName(StringRef Name) const override; +  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; +  bool setCPU(const std::string &Name) override { +    bool isValid = isValidCPUName(Name); +    if (isValid) +      CPU = Name; +    return isValid; +  } + +protected: +  std::string CPU; +}; + +} // namespace targets +} // namespace clang + +#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AVR_H | 
