106f32e7eSjoerg //===--- Hexagon.h - Declare Hexagon target feature support -----*- C++ -*-===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file declares Hexagon TargetInfo objects.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H
1406f32e7eSjoerg #define LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H
1506f32e7eSjoerg 
1606f32e7eSjoerg #include "clang/Basic/TargetInfo.h"
1706f32e7eSjoerg #include "clang/Basic/TargetOptions.h"
1806f32e7eSjoerg #include "llvm/ADT/Triple.h"
1906f32e7eSjoerg #include "llvm/Support/Compiler.h"
2006f32e7eSjoerg 
2106f32e7eSjoerg namespace clang {
2206f32e7eSjoerg namespace targets {
2306f32e7eSjoerg 
2406f32e7eSjoerg // Hexagon abstract base class
2506f32e7eSjoerg class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo {
2606f32e7eSjoerg 
2706f32e7eSjoerg   static const Builtin::Info BuiltinInfo[];
2806f32e7eSjoerg   static const char *const GCCRegNames[];
2906f32e7eSjoerg   static const TargetInfo::GCCRegAlias GCCRegAliases[];
3006f32e7eSjoerg   std::string CPU;
3106f32e7eSjoerg   std::string HVXVersion;
3206f32e7eSjoerg   bool HasHVX = false;
3306f32e7eSjoerg   bool HasHVX64B = false;
3406f32e7eSjoerg   bool HasHVX128B = false;
35*13fbcb42Sjoerg   bool HasAudio = false;
3606f32e7eSjoerg   bool UseLongCalls = false;
3706f32e7eSjoerg 
3806f32e7eSjoerg public:
HexagonTargetInfo(const llvm::Triple & Triple,const TargetOptions &)3906f32e7eSjoerg   HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
4006f32e7eSjoerg       : TargetInfo(Triple) {
4106f32e7eSjoerg     // Specify the vector alignment explicitly. For v512x1, the calculated
4206f32e7eSjoerg     // alignment would be 512*alignment(i1), which is 512 bytes, instead of
4306f32e7eSjoerg     // the required minimum of 64 bytes.
4406f32e7eSjoerg     resetDataLayout(
4506f32e7eSjoerg         "e-m:e-p:32:32:32-a:0-n16:32-"
4606f32e7eSjoerg         "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-"
4706f32e7eSjoerg         "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048");
4806f32e7eSjoerg     SizeType = UnsignedInt;
4906f32e7eSjoerg     PtrDiffType = SignedInt;
5006f32e7eSjoerg     IntPtrType = SignedInt;
5106f32e7eSjoerg 
5206f32e7eSjoerg     // {} in inline assembly are packet specifiers, not assembly variant
5306f32e7eSjoerg     // specifiers.
5406f32e7eSjoerg     NoAsmVariants = true;
5506f32e7eSjoerg 
5606f32e7eSjoerg     LargeArrayMinWidth = 64;
5706f32e7eSjoerg     LargeArrayAlign = 64;
5806f32e7eSjoerg     UseBitFieldTypeAlignment = true;
5906f32e7eSjoerg     ZeroLengthBitfieldBoundary = 32;
60*13fbcb42Sjoerg     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
61*13fbcb42Sjoerg 
62*13fbcb42Sjoerg     // These are the default values anyway, but explicitly make sure
63*13fbcb42Sjoerg     // that the size of the boolean type is 8 bits. Bool vectors are used
64*13fbcb42Sjoerg     // for modeling predicate registers in HVX, and the bool -> byte
65*13fbcb42Sjoerg     // correspondence matches the HVX architecture.
66*13fbcb42Sjoerg     BoolWidth = BoolAlign = 8;
6706f32e7eSjoerg   }
6806f32e7eSjoerg 
6906f32e7eSjoerg   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
7006f32e7eSjoerg 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info)7106f32e7eSjoerg   bool validateAsmConstraint(const char *&Name,
7206f32e7eSjoerg                              TargetInfo::ConstraintInfo &Info) const override {
7306f32e7eSjoerg     switch (*Name) {
7406f32e7eSjoerg     case 'v':
7506f32e7eSjoerg     case 'q':
7606f32e7eSjoerg       if (HasHVX) {
7706f32e7eSjoerg         Info.setAllowsRegister();
7806f32e7eSjoerg         return true;
7906f32e7eSjoerg       }
8006f32e7eSjoerg       break;
8106f32e7eSjoerg     case 'a': // Modifier register m0-m1.
8206f32e7eSjoerg       Info.setAllowsRegister();
8306f32e7eSjoerg       return true;
8406f32e7eSjoerg     case 's':
8506f32e7eSjoerg       // Relocatable constant.
8606f32e7eSjoerg       return true;
8706f32e7eSjoerg     }
8806f32e7eSjoerg     return false;
8906f32e7eSjoerg   }
9006f32e7eSjoerg 
9106f32e7eSjoerg   void getTargetDefines(const LangOptions &Opts,
9206f32e7eSjoerg                         MacroBuilder &Builder) const override;
9306f32e7eSjoerg 
isCLZForZeroUndef()9406f32e7eSjoerg   bool isCLZForZeroUndef() const override { return false; }
9506f32e7eSjoerg 
9606f32e7eSjoerg   bool hasFeature(StringRef Feature) const override;
9706f32e7eSjoerg 
9806f32e7eSjoerg   bool
9906f32e7eSjoerg   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
10006f32e7eSjoerg                  StringRef CPU,
10106f32e7eSjoerg                  const std::vector<std::string> &FeaturesVec) const override;
10206f32e7eSjoerg 
10306f32e7eSjoerg   bool handleTargetFeatures(std::vector<std::string> &Features,
10406f32e7eSjoerg                             DiagnosticsEngine &Diags) override;
10506f32e7eSjoerg 
getBuiltinVaListKind()10606f32e7eSjoerg   BuiltinVaListKind getBuiltinVaListKind() const override {
107*13fbcb42Sjoerg     if (getTriple().isMusl())
108*13fbcb42Sjoerg       return TargetInfo::HexagonBuiltinVaList;
10906f32e7eSjoerg     return TargetInfo::CharPtrBuiltinVaList;
11006f32e7eSjoerg   }
11106f32e7eSjoerg 
11206f32e7eSjoerg   ArrayRef<const char *> getGCCRegNames() const override;
11306f32e7eSjoerg 
11406f32e7eSjoerg   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
11506f32e7eSjoerg 
getClobbers()11606f32e7eSjoerg   const char *getClobbers() const override { return ""; }
11706f32e7eSjoerg 
11806f32e7eSjoerg   static const char *getHexagonCPUSuffix(StringRef Name);
11906f32e7eSjoerg 
isValidCPUName(StringRef Name)12006f32e7eSjoerg   bool isValidCPUName(StringRef Name) const override {
12106f32e7eSjoerg     return getHexagonCPUSuffix(Name);
12206f32e7eSjoerg   }
12306f32e7eSjoerg 
12406f32e7eSjoerg   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
12506f32e7eSjoerg 
setCPU(const std::string & Name)12606f32e7eSjoerg   bool setCPU(const std::string &Name) override {
12706f32e7eSjoerg     if (!isValidCPUName(Name))
12806f32e7eSjoerg       return false;
12906f32e7eSjoerg     CPU = Name;
13006f32e7eSjoerg     return true;
13106f32e7eSjoerg   }
13206f32e7eSjoerg 
getEHDataRegisterNumber(unsigned RegNo)13306f32e7eSjoerg   int getEHDataRegisterNumber(unsigned RegNo) const override {
13406f32e7eSjoerg     return RegNo < 2 ? RegNo : -1;
13506f32e7eSjoerg   }
136*13fbcb42Sjoerg 
isTinyCore()137*13fbcb42Sjoerg   bool isTinyCore() const {
138*13fbcb42Sjoerg     // We can write more stricter checks later.
139*13fbcb42Sjoerg     return CPU.find('t') != std::string::npos;
140*13fbcb42Sjoerg   }
141*13fbcb42Sjoerg 
hasExtIntType()142*13fbcb42Sjoerg   bool hasExtIntType() const override { return true; }
14306f32e7eSjoerg };
14406f32e7eSjoerg } // namespace targets
14506f32e7eSjoerg } // namespace clang
14606f32e7eSjoerg #endif // LLVM_CLANG_LIB_BASIC_TARGETS_HEXAGON_H
147