forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			185 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--- 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
 |