10b57cec5SDimitry Andric //===--- ARM.cpp - Implement ARM target feature support -------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements ARM TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "ARM.h" 140b57cec5SDimitry Andric #include "clang/Basic/Builtins.h" 150b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h" 160b57cec5SDimitry Andric #include "clang/Basic/TargetBuiltins.h" 170b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h" 201db9f3b2SDimitry Andric #include "llvm/TargetParser/ARMTargetParser.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric using namespace clang; 230b57cec5SDimitry Andric using namespace clang::targets; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric void ARMTargetInfo::setABIAAPCS() { 260b57cec5SDimitry Andric IsAAPCS = true; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 295ffd83dbSDimitry Andric BFloat16Width = BFloat16Align = 16; 305ffd83dbSDimitry Andric BFloat16Format = &llvm::APFloat::BFloat(); 315ffd83dbSDimitry Andric 320b57cec5SDimitry Andric const llvm::Triple &T = getTriple(); 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric bool IsNetBSD = T.isOSNetBSD(); 350b57cec5SDimitry Andric bool IsOpenBSD = T.isOSOpenBSD(); 360b57cec5SDimitry Andric if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD) 370b57cec5SDimitry Andric WCharType = UnsignedInt; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric UseBitFieldTypeAlignment = true; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric ZeroLengthBitfieldBoundary = 0; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric // Thumb1 add sp, #imm requires the immediate value be multiple of 4, 440b57cec5SDimitry Andric // so set preferred for small types to 32. 450b57cec5SDimitry Andric if (T.isOSBinFormatMachO()) { 460b57cec5SDimitry Andric resetDataLayout(BigEndian 470b57cec5SDimitry Andric ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 48fe6060f1SDimitry Andric : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", 49fe6060f1SDimitry Andric "_"); 500b57cec5SDimitry Andric } else if (T.isOSWindows()) { 510b57cec5SDimitry Andric assert(!BigEndian && "Windows on ARM does not support big endian"); 520b57cec5SDimitry Andric resetDataLayout("e" 530b57cec5SDimitry Andric "-m:w" 540b57cec5SDimitry Andric "-p:32:32" 550b57cec5SDimitry Andric "-Fi8" 560b57cec5SDimitry Andric "-i64:64" 570b57cec5SDimitry Andric "-v128:64:128" 580b57cec5SDimitry Andric "-a:0:32" 590b57cec5SDimitry Andric "-n32" 600b57cec5SDimitry Andric "-S64"); 610b57cec5SDimitry Andric } else if (T.isOSNaCl()) { 620b57cec5SDimitry Andric assert(!BigEndian && "NaCl on ARM does not support big endian"); 630b57cec5SDimitry Andric resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128"); 640b57cec5SDimitry Andric } else { 650b57cec5SDimitry Andric resetDataLayout(BigEndian 660b57cec5SDimitry Andric ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 670b57cec5SDimitry Andric : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric // FIXME: Enumerated types are variable width in straight AAPCS. 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) { 740b57cec5SDimitry Andric const llvm::Triple &T = getTriple(); 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric IsAAPCS = false; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric if (IsAAPCS16) 790b57cec5SDimitry Andric DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 800b57cec5SDimitry Andric else 810b57cec5SDimitry Andric DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; 825ffd83dbSDimitry Andric BFloat16Width = BFloat16Align = 16; 835ffd83dbSDimitry Andric BFloat16Format = &llvm::APFloat::BFloat(); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric WCharType = SignedInt; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric // Do not respect the alignment of bit-field types when laying out 880b57cec5SDimitry Andric // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. 890b57cec5SDimitry Andric UseBitFieldTypeAlignment = false; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// gcc forces the alignment to 4 bytes, regardless of the type of the 920b57cec5SDimitry Andric /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in 930b57cec5SDimitry Andric /// gcc. 940b57cec5SDimitry Andric ZeroLengthBitfieldBoundary = 32; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric if (T.isOSBinFormatMachO() && IsAAPCS16) { 970b57cec5SDimitry Andric assert(!BigEndian && "AAPCS16 does not support big-endian"); 98fe6060f1SDimitry Andric resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_"); 990b57cec5SDimitry Andric } else if (T.isOSBinFormatMachO()) 1000b57cec5SDimitry Andric resetDataLayout( 1010b57cec5SDimitry Andric BigEndian 1020b57cec5SDimitry Andric ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 103fe6060f1SDimitry Andric : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32", 104fe6060f1SDimitry Andric "_"); 1050b57cec5SDimitry Andric else 1060b57cec5SDimitry Andric resetDataLayout( 1070b57cec5SDimitry Andric BigEndian 1080b57cec5SDimitry Andric ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 1090b57cec5SDimitry Andric : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // FIXME: Override "preferred align" for double and long long. 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric void ARMTargetInfo::setArchInfo() { 1150b57cec5SDimitry Andric StringRef ArchName = getTriple().getArchName(); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric ArchISA = llvm::ARM::parseArchISA(ArchName); 1185ffd83dbSDimitry Andric CPU = std::string(llvm::ARM::getDefaultCPU(ArchName)); 1190b57cec5SDimitry Andric llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName); 1200b57cec5SDimitry Andric if (AK != llvm::ARM::ArchKind::INVALID) 1210b57cec5SDimitry Andric ArchKind = AK; 1220b57cec5SDimitry Andric setArchInfo(ArchKind); 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) { 1260b57cec5SDimitry Andric StringRef SubArch; 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric // cache TargetParser info 1290b57cec5SDimitry Andric ArchKind = Kind; 1300b57cec5SDimitry Andric SubArch = llvm::ARM::getSubArch(ArchKind); 1310b57cec5SDimitry Andric ArchProfile = llvm::ARM::parseArchProfile(SubArch); 1320b57cec5SDimitry Andric ArchVersion = llvm::ARM::parseArchVersion(SubArch); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric // cache CPU related strings 1350b57cec5SDimitry Andric CPUAttr = getCPUAttr(); 1360b57cec5SDimitry Andric CPUProfile = getCPUProfile(); 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric void ARMTargetInfo::setAtomic() { 1400b57cec5SDimitry Andric // when triple does not specify a sub arch, 1410b57cec5SDimitry Andric // then we are not using inline atomics 1420b57cec5SDimitry Andric bool ShouldUseInlineAtomic = 1430b57cec5SDimitry Andric (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) || 1440b57cec5SDimitry Andric (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7); 1450b57cec5SDimitry Andric // Cortex M does not support 8 byte atomics, while general Thumb2 does. 1460b57cec5SDimitry Andric if (ArchProfile == llvm::ARM::ProfileKind::M) { 1470b57cec5SDimitry Andric MaxAtomicPromoteWidth = 32; 1480b57cec5SDimitry Andric if (ShouldUseInlineAtomic) 1490b57cec5SDimitry Andric MaxAtomicInlineWidth = 32; 1500b57cec5SDimitry Andric } else { 1510b57cec5SDimitry Andric MaxAtomicPromoteWidth = 64; 1520b57cec5SDimitry Andric if (ShouldUseInlineAtomic) 1530b57cec5SDimitry Andric MaxAtomicInlineWidth = 64; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric bool ARMTargetInfo::hasMVE() const { 1580b57cec5SDimitry Andric return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0; 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric bool ARMTargetInfo::hasMVEFloat() const { 1620b57cec5SDimitry Andric return hasMVE() && (MVE & MVE_FP); 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1655ffd83dbSDimitry Andric bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; } 1665ffd83dbSDimitry Andric 1670b57cec5SDimitry Andric bool ARMTargetInfo::isThumb() const { 1680b57cec5SDimitry Andric return ArchISA == llvm::ARM::ISAKind::THUMB; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric bool ARMTargetInfo::supportsThumb() const { 1720b57cec5SDimitry Andric return CPUAttr.count('T') || ArchVersion >= 6; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric bool ARMTargetInfo::supportsThumb2() const { 1760fca6ea1SDimitry Andric return CPUAttr == "6T2" || (ArchVersion >= 7 && CPUAttr != "8M_BASE"); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric StringRef ARMTargetInfo::getCPUAttr() const { 1800b57cec5SDimitry Andric // For most sub-arches, the build attribute CPU name is enough. 1810b57cec5SDimitry Andric // For Cortex variants, it's slightly different. 1820b57cec5SDimitry Andric switch (ArchKind) { 1830b57cec5SDimitry Andric default: 1840b57cec5SDimitry Andric return llvm::ARM::getCPUAttr(ArchKind); 1850b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV6M: 1860b57cec5SDimitry Andric return "6M"; 1870b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV7S: 1880b57cec5SDimitry Andric return "7S"; 1890b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV7A: 1900b57cec5SDimitry Andric return "7A"; 1910b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV7R: 1920b57cec5SDimitry Andric return "7R"; 1930b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV7M: 1940b57cec5SDimitry Andric return "7M"; 1950b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV7EM: 1960b57cec5SDimitry Andric return "7EM"; 1970b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV7VE: 1980b57cec5SDimitry Andric return "7VE"; 1990b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8A: 2000b57cec5SDimitry Andric return "8A"; 2010b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_1A: 2020b57cec5SDimitry Andric return "8_1A"; 2030b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_2A: 2040b57cec5SDimitry Andric return "8_2A"; 2050b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_3A: 2060b57cec5SDimitry Andric return "8_3A"; 2070b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_4A: 2080b57cec5SDimitry Andric return "8_4A"; 2090b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_5A: 2100b57cec5SDimitry Andric return "8_5A"; 2115ffd83dbSDimitry Andric case llvm::ARM::ArchKind::ARMV8_6A: 2125ffd83dbSDimitry Andric return "8_6A"; 213e8d8bef9SDimitry Andric case llvm::ARM::ArchKind::ARMV8_7A: 214e8d8bef9SDimitry Andric return "8_7A"; 21504eeddc0SDimitry Andric case llvm::ARM::ArchKind::ARMV8_8A: 21604eeddc0SDimitry Andric return "8_8A"; 217bdd1243dSDimitry Andric case llvm::ARM::ArchKind::ARMV8_9A: 218bdd1243dSDimitry Andric return "8_9A"; 219349cc55cSDimitry Andric case llvm::ARM::ArchKind::ARMV9A: 220349cc55cSDimitry Andric return "9A"; 221349cc55cSDimitry Andric case llvm::ARM::ArchKind::ARMV9_1A: 222349cc55cSDimitry Andric return "9_1A"; 223349cc55cSDimitry Andric case llvm::ARM::ArchKind::ARMV9_2A: 224349cc55cSDimitry Andric return "9_2A"; 22504eeddc0SDimitry Andric case llvm::ARM::ArchKind::ARMV9_3A: 22604eeddc0SDimitry Andric return "9_3A"; 227bdd1243dSDimitry Andric case llvm::ARM::ArchKind::ARMV9_4A: 228bdd1243dSDimitry Andric return "9_4A"; 2297a6dacacSDimitry Andric case llvm::ARM::ArchKind::ARMV9_5A: 2307a6dacacSDimitry Andric return "9_5A"; 2310b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8MBaseline: 2320b57cec5SDimitry Andric return "8M_BASE"; 2330b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8MMainline: 2340b57cec5SDimitry Andric return "8M_MAIN"; 2350b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8R: 2360b57cec5SDimitry Andric return "8R"; 2370b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_1MMainline: 2380b57cec5SDimitry Andric return "8_1M_MAIN"; 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric StringRef ARMTargetInfo::getCPUProfile() const { 2430b57cec5SDimitry Andric switch (ArchProfile) { 2440b57cec5SDimitry Andric case llvm::ARM::ProfileKind::A: 2450b57cec5SDimitry Andric return "A"; 2460b57cec5SDimitry Andric case llvm::ARM::ProfileKind::R: 2470b57cec5SDimitry Andric return "R"; 2480b57cec5SDimitry Andric case llvm::ARM::ProfileKind::M: 2490b57cec5SDimitry Andric return "M"; 2500b57cec5SDimitry Andric default: 2510b57cec5SDimitry Andric return ""; 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, 2560b57cec5SDimitry Andric const TargetOptions &Opts) 2570b57cec5SDimitry Andric : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), 2580b57cec5SDimitry Andric HW_FP(0) { 2591ac55f4cSDimitry Andric bool IsFreeBSD = Triple.isOSFreeBSD(); 2600b57cec5SDimitry Andric bool IsOpenBSD = Triple.isOSOpenBSD(); 2610b57cec5SDimitry Andric bool IsNetBSD = Triple.isOSNetBSD(); 2625f757f3fSDimitry Andric bool IsHaiku = Triple.isOSHaiku(); 2635f757f3fSDimitry Andric bool IsOHOS = Triple.isOHOSFamily(); 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like 2660b57cec5SDimitry Andric // environment where size_t is `unsigned long` rather than `unsigned int` 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric PtrDiffType = IntPtrType = 2690b57cec5SDimitry Andric (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 2700b57cec5SDimitry Andric IsNetBSD) 2710b57cec5SDimitry Andric ? SignedLong 2720b57cec5SDimitry Andric : SignedInt; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 2750b57cec5SDimitry Andric IsNetBSD) 2760b57cec5SDimitry Andric ? UnsignedLong 2770b57cec5SDimitry Andric : UnsignedInt; 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric // ptrdiff_t is inconsistent on Darwin 2800b57cec5SDimitry Andric if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) && 2810b57cec5SDimitry Andric !Triple.isWatchABI()) 2820b57cec5SDimitry Andric PtrDiffType = SignedInt; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric // Cache arch related info. 2850b57cec5SDimitry Andric setArchInfo(); 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric // {} in inline assembly are neon specifiers, not assembly variant 2880b57cec5SDimitry Andric // specifiers. 2890b57cec5SDimitry Andric NoAsmVariants = true; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric // FIXME: This duplicates code from the driver that sets the -target-abi 2920b57cec5SDimitry Andric // option - this code is used if -target-abi isn't passed and should 2930b57cec5SDimitry Andric // be unified in some way. 2940b57cec5SDimitry Andric if (Triple.isOSBinFormatMachO()) { 2950b57cec5SDimitry Andric // The backend is hardwired to assume AAPCS for M-class processors, ensure 2960b57cec5SDimitry Andric // the frontend matches that. 2970b57cec5SDimitry Andric if (Triple.getEnvironment() == llvm::Triple::EABI || 2980b57cec5SDimitry Andric Triple.getOS() == llvm::Triple::UnknownOS || 2990b57cec5SDimitry Andric ArchProfile == llvm::ARM::ProfileKind::M) { 3000b57cec5SDimitry Andric setABI("aapcs"); 3010b57cec5SDimitry Andric } else if (Triple.isWatchABI()) { 3020b57cec5SDimitry Andric setABI("aapcs16"); 3030b57cec5SDimitry Andric } else { 3040b57cec5SDimitry Andric setABI("apcs-gnu"); 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric } else if (Triple.isOSWindows()) { 3070b57cec5SDimitry Andric // FIXME: this is invalid for WindowsCE 3080b57cec5SDimitry Andric setABI("aapcs"); 3090b57cec5SDimitry Andric } else { 3100b57cec5SDimitry Andric // Select the default based on the platform. 3110b57cec5SDimitry Andric switch (Triple.getEnvironment()) { 3120b57cec5SDimitry Andric case llvm::Triple::Android: 3130b57cec5SDimitry Andric case llvm::Triple::GNUEABI: 314*d686ce93SDimitry Andric case llvm::Triple::GNUEABIT64: 3150b57cec5SDimitry Andric case llvm::Triple::GNUEABIHF: 316*d686ce93SDimitry Andric case llvm::Triple::GNUEABIHFT64: 3170b57cec5SDimitry Andric case llvm::Triple::MuslEABI: 3180b57cec5SDimitry Andric case llvm::Triple::MuslEABIHF: 31906c3fb27SDimitry Andric case llvm::Triple::OpenHOS: 3200b57cec5SDimitry Andric setABI("aapcs-linux"); 3210b57cec5SDimitry Andric break; 3220b57cec5SDimitry Andric case llvm::Triple::EABIHF: 3230b57cec5SDimitry Andric case llvm::Triple::EABI: 3240b57cec5SDimitry Andric setABI("aapcs"); 3250b57cec5SDimitry Andric break; 3260b57cec5SDimitry Andric case llvm::Triple::GNU: 3270b57cec5SDimitry Andric setABI("apcs-gnu"); 3280b57cec5SDimitry Andric break; 3290b57cec5SDimitry Andric default: 3300b57cec5SDimitry Andric if (IsNetBSD) 3310b57cec5SDimitry Andric setABI("apcs-gnu"); 3325f757f3fSDimitry Andric else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS) 3330b57cec5SDimitry Andric setABI("aapcs-linux"); 3340b57cec5SDimitry Andric else 3350b57cec5SDimitry Andric setABI("aapcs"); 3360b57cec5SDimitry Andric break; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric // ARM targets default to using the ARM C++ ABI. 3410b57cec5SDimitry Andric TheCXXABI.set(TargetCXXABI::GenericARM); 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric // ARM has atomics up to 8 bytes 3440b57cec5SDimitry Andric setAtomic(); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS) 347a7dea167SDimitry Andric // as well the default alignment 3485ffd83dbSDimitry Andric if (IsAAPCS && !Triple.isAndroid()) 349a7dea167SDimitry Andric DefaultAlignForAttributeAligned = MaxVectorAlign = 64; 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric // Do force alignment of members that follow zero length bitfields. If 3520b57cec5SDimitry Andric // the alignment of the zero-length bitfield is greater than the member 3530b57cec5SDimitry Andric // that follows it, `bar', `bar' will be aligned as the type of the 3540b57cec5SDimitry Andric // zero length bitfield. 3550b57cec5SDimitry Andric UseZeroLengthBitfieldAlignment = true; 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric if (Triple.getOS() == llvm::Triple::Linux || 3580b57cec5SDimitry Andric Triple.getOS() == llvm::Triple::UnknownOS) 3590b57cec5SDimitry Andric this->MCountName = Opts.EABIVersion == llvm::EABI::GNU 360a7dea167SDimitry Andric ? "llvm.arm.gnu.eabi.mcount" 3610b57cec5SDimitry Andric : "\01mcount"; 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi"); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric StringRef ARMTargetInfo::getABI() const { return ABI; } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric bool ARMTargetInfo::setABI(const std::string &Name) { 3690b57cec5SDimitry Andric ABI = Name; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric // The defaults (above) are for AAPCS, check if we need to change them. 3720b57cec5SDimitry Andric // 3730b57cec5SDimitry Andric // FIXME: We need support for -meabi... we could just mangle it into the 3740b57cec5SDimitry Andric // name. 3750b57cec5SDimitry Andric if (Name == "apcs-gnu" || Name == "aapcs16") { 3760b57cec5SDimitry Andric setABIAPCS(Name == "aapcs16"); 3770b57cec5SDimitry Andric return true; 3780b57cec5SDimitry Andric } 3790b57cec5SDimitry Andric if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") { 3800b57cec5SDimitry Andric setABIAAPCS(); 3810b57cec5SDimitry Andric return true; 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric return false; 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3861fd87a68SDimitry Andric bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const { 3871fd87a68SDimitry Andric llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch); 3881fd87a68SDimitry Andric if (CPUArch == llvm::ARM::ArchKind::INVALID) 3891fd87a68SDimitry Andric CPUArch = llvm::ARM::parseArch(getTriple().getArchName()); 3901fd87a68SDimitry Andric 3911fd87a68SDimitry Andric if (CPUArch == llvm::ARM::ArchKind::INVALID) 3921fd87a68SDimitry Andric return false; 3931fd87a68SDimitry Andric 3941fd87a68SDimitry Andric StringRef ArchFeature = llvm::ARM::getArchName(CPUArch); 3951fd87a68SDimitry Andric auto a = 3961fd87a68SDimitry Andric llvm::Triple(ArchFeature, getTriple().getVendorName(), 3971fd87a68SDimitry Andric getTriple().getOSName(), getTriple().getEnvironmentName()); 3981fd87a68SDimitry Andric 3991fd87a68SDimitry Andric StringRef SubArch = llvm::ARM::getSubArch(CPUArch); 4001fd87a68SDimitry Andric llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch); 4011fd87a68SDimitry Andric return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M); 4021fd87a68SDimitry Andric } 4031fd87a68SDimitry Andric 4041fd87a68SDimitry Andric bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch, 4054824e7fdSDimitry Andric BranchProtectionInfo &BPI, 4064824e7fdSDimitry Andric StringRef &Err) const { 4074824e7fdSDimitry Andric llvm::ARM::ParsedBranchProtection PBP; 4084824e7fdSDimitry Andric if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) 4094824e7fdSDimitry Andric return false; 4104824e7fdSDimitry Andric 4111fd87a68SDimitry Andric if (!isBranchProtectionSupportedArch(Arch)) 4121fd87a68SDimitry Andric return false; 4131fd87a68SDimitry Andric 4144824e7fdSDimitry Andric BPI.SignReturnAddr = 4154824e7fdSDimitry Andric llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope) 4164824e7fdSDimitry Andric .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) 4174824e7fdSDimitry Andric .Case("all", LangOptions::SignReturnAddressScopeKind::All) 4184824e7fdSDimitry Andric .Default(LangOptions::SignReturnAddressScopeKind::None); 4194824e7fdSDimitry Andric 4204824e7fdSDimitry Andric // Don't care for the sign key, beyond issuing a warning. 4214824e7fdSDimitry Andric if (PBP.Key == "b_key") 4224824e7fdSDimitry Andric Err = "b-key"; 4234824e7fdSDimitry Andric BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; 4244824e7fdSDimitry Andric 4254824e7fdSDimitry Andric BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; 426cb14a3feSDimitry Andric BPI.BranchProtectionPAuthLR = PBP.BranchProtectionPAuthLR; 4274824e7fdSDimitry Andric return true; 4284824e7fdSDimitry Andric } 4294824e7fdSDimitry Andric 4300b57cec5SDimitry Andric // FIXME: This should be based on Arch attributes, not CPU names. 4310b57cec5SDimitry Andric bool ARMTargetInfo::initFeatureMap( 4320b57cec5SDimitry Andric llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, 4330b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const { 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric std::string ArchFeature; 4360b57cec5SDimitry Andric std::vector<StringRef> TargetFeatures; 4370b57cec5SDimitry Andric llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName()); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric // Map the base architecture to an appropriate target feature, so we don't 4400b57cec5SDimitry Andric // rely on the target triple. 4410b57cec5SDimitry Andric llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU); 4420b57cec5SDimitry Andric if (CPUArch == llvm::ARM::ArchKind::INVALID) 4430b57cec5SDimitry Andric CPUArch = Arch; 4440b57cec5SDimitry Andric if (CPUArch != llvm::ARM::ArchKind::INVALID) { 4450b57cec5SDimitry Andric ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str(); 4460b57cec5SDimitry Andric TargetFeatures.push_back(ArchFeature); 447bdd1243dSDimitry Andric 448bdd1243dSDimitry Andric // These features are added to allow arm_neon.h target(..) attributes to 449bdd1243dSDimitry Andric // match with both arm and aarch64. We need to add all previous architecture 450bdd1243dSDimitry Andric // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the 451bdd1243dSDimitry Andric // v8.x counterparts are added too. We only need these for anything > 8.0-A. 452bdd1243dSDimitry Andric for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch); 453bdd1243dSDimitry Andric I != llvm::ARM::ArchKind::INVALID; --I) 454bdd1243dSDimitry Andric Features[llvm::ARM::getSubArch(I)] = true; 455bdd1243dSDimitry Andric if (CPUArch > llvm::ARM::ArchKind::ARMV8A && 456bdd1243dSDimitry Andric CPUArch <= llvm::ARM::ArchKind::ARMV9_3A) 457bdd1243dSDimitry Andric for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID; 458bdd1243dSDimitry Andric --I) 459bdd1243dSDimitry Andric Features[llvm::ARM::getSubArch(I)] = true; 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric // get default FPU features 46306c3fb27SDimitry Andric llvm::ARM::FPUKind FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch); 4640b57cec5SDimitry Andric llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures); 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric // get default Extension features 4675ffd83dbSDimitry Andric uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch); 4680b57cec5SDimitry Andric llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures); 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric for (auto Feature : TargetFeatures) 4710b57cec5SDimitry Andric if (Feature[0] == '+') 4720b57cec5SDimitry Andric Features[Feature.drop_front(1)] = true; 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric // Enable or disable thumb-mode explicitly per function to enable mixed 4750b57cec5SDimitry Andric // ARM and Thumb code generation. 4760b57cec5SDimitry Andric if (isThumb()) 4770b57cec5SDimitry Andric Features["thumb-mode"] = true; 4780b57cec5SDimitry Andric else 4790b57cec5SDimitry Andric Features["thumb-mode"] = false; 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric // Convert user-provided arm and thumb GNU target attributes to 4820b57cec5SDimitry Andric // [-|+]thumb-mode target features respectively. 4830b57cec5SDimitry Andric std::vector<std::string> UpdatedFeaturesVec; 4840b57cec5SDimitry Andric for (const auto &Feature : FeaturesVec) { 4850b57cec5SDimitry Andric // Skip soft-float-abi; it's something we only use to initialize a bit of 4860b57cec5SDimitry Andric // class state, and is otherwise unrecognized. 4870b57cec5SDimitry Andric if (Feature == "+soft-float-abi") 4880b57cec5SDimitry Andric continue; 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric StringRef FixedFeature; 4910b57cec5SDimitry Andric if (Feature == "+arm") 4920b57cec5SDimitry Andric FixedFeature = "-thumb-mode"; 4930b57cec5SDimitry Andric else if (Feature == "+thumb") 4940b57cec5SDimitry Andric FixedFeature = "+thumb-mode"; 4950b57cec5SDimitry Andric else 4960b57cec5SDimitry Andric FixedFeature = Feature; 4970b57cec5SDimitry Andric UpdatedFeaturesVec.push_back(FixedFeature.str()); 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec); 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, 5050b57cec5SDimitry Andric DiagnosticsEngine &Diags) { 5060b57cec5SDimitry Andric FPU = 0; 5070b57cec5SDimitry Andric MVE = 0; 5080b57cec5SDimitry Andric CRC = 0; 5090b57cec5SDimitry Andric Crypto = 0; 510fe6060f1SDimitry Andric SHA2 = 0; 511fe6060f1SDimitry Andric AES = 0; 5120b57cec5SDimitry Andric DSP = 0; 5130fca6ea1SDimitry Andric HasUnalignedAccess = true; 5140b57cec5SDimitry Andric SoftFloat = false; 5150b57cec5SDimitry Andric // Note that SoftFloatABI is initialized in our constructor. 5160b57cec5SDimitry Andric HWDiv = 0; 5170b57cec5SDimitry Andric DotProd = 0; 5185ffd83dbSDimitry Andric HasMatMul = 0; 5190eae32dcSDimitry Andric HasPAC = 0; 5200eae32dcSDimitry Andric HasBTI = 0; 5210b57cec5SDimitry Andric HasFloat16 = true; 5225ffd83dbSDimitry Andric ARMCDECoprocMask = 0; 5235ffd83dbSDimitry Andric HasBFloat16 = false; 52406c3fb27SDimitry Andric HasFullBFloat16 = false; 525349cc55cSDimitry Andric FPRegsDisabled = false; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric // This does not diagnose illegal cases like having both 5280b57cec5SDimitry Andric // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64". 5290b57cec5SDimitry Andric for (const auto &Feature : Features) { 5300b57cec5SDimitry Andric if (Feature == "+soft-float") { 5310b57cec5SDimitry Andric SoftFloat = true; 532a7dea167SDimitry Andric } else if (Feature == "+vfp2sp" || Feature == "+vfp2") { 5330b57cec5SDimitry Andric FPU |= VFP2FPU; 5340b57cec5SDimitry Andric HW_FP |= HW_FP_SP; 535a7dea167SDimitry Andric if (Feature == "+vfp2") 5360b57cec5SDimitry Andric HW_FP |= HW_FP_DP; 5370b57cec5SDimitry Andric } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" || 5380b57cec5SDimitry Andric Feature == "+vfp3" || Feature == "+vfp3d16") { 5390b57cec5SDimitry Andric FPU |= VFP3FPU; 5400b57cec5SDimitry Andric HW_FP |= HW_FP_SP; 5410b57cec5SDimitry Andric if (Feature == "+vfp3" || Feature == "+vfp3d16") 5420b57cec5SDimitry Andric HW_FP |= HW_FP_DP; 5430b57cec5SDimitry Andric } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" || 5440b57cec5SDimitry Andric Feature == "+vfp4" || Feature == "+vfp4d16") { 5450b57cec5SDimitry Andric FPU |= VFP4FPU; 5460b57cec5SDimitry Andric HW_FP |= HW_FP_SP | HW_FP_HP; 5470b57cec5SDimitry Andric if (Feature == "+vfp4" || Feature == "+vfp4d16") 5480b57cec5SDimitry Andric HW_FP |= HW_FP_DP; 5490b57cec5SDimitry Andric } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" || 5500b57cec5SDimitry Andric Feature == "+fp-armv8" || Feature == "+fp-armv8d16") { 5510b57cec5SDimitry Andric FPU |= FPARMV8; 5520b57cec5SDimitry Andric HW_FP |= HW_FP_SP | HW_FP_HP; 5530b57cec5SDimitry Andric if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16") 5540b57cec5SDimitry Andric HW_FP |= HW_FP_DP; 5550b57cec5SDimitry Andric } else if (Feature == "+neon") { 5560b57cec5SDimitry Andric FPU |= NeonFPU; 5570b57cec5SDimitry Andric HW_FP |= HW_FP_SP; 5580b57cec5SDimitry Andric } else if (Feature == "+hwdiv") { 5590b57cec5SDimitry Andric HWDiv |= HWDivThumb; 5600b57cec5SDimitry Andric } else if (Feature == "+hwdiv-arm") { 5610b57cec5SDimitry Andric HWDiv |= HWDivARM; 5620b57cec5SDimitry Andric } else if (Feature == "+crc") { 5630b57cec5SDimitry Andric CRC = 1; 5640b57cec5SDimitry Andric } else if (Feature == "+crypto") { 5650b57cec5SDimitry Andric Crypto = 1; 566fe6060f1SDimitry Andric } else if (Feature == "+sha2") { 567fe6060f1SDimitry Andric SHA2 = 1; 568fe6060f1SDimitry Andric } else if (Feature == "+aes") { 569fe6060f1SDimitry Andric AES = 1; 5700b57cec5SDimitry Andric } else if (Feature == "+dsp") { 5710b57cec5SDimitry Andric DSP = 1; 5720b57cec5SDimitry Andric } else if (Feature == "+fp64") { 5730b57cec5SDimitry Andric HW_FP |= HW_FP_DP; 5740b57cec5SDimitry Andric } else if (Feature == "+8msecext") { 5750b57cec5SDimitry Andric if (CPUProfile != "M" || ArchVersion != 8) { 5760b57cec5SDimitry Andric Diags.Report(diag::err_target_unsupported_mcmse) << CPU; 5770b57cec5SDimitry Andric return false; 5780b57cec5SDimitry Andric } 5790b57cec5SDimitry Andric } else if (Feature == "+strict-align") { 5800fca6ea1SDimitry Andric HasUnalignedAccess = false; 5810b57cec5SDimitry Andric } else if (Feature == "+fp16") { 5820b57cec5SDimitry Andric HW_FP |= HW_FP_HP; 5830b57cec5SDimitry Andric } else if (Feature == "+fullfp16") { 5840b57cec5SDimitry Andric HasLegalHalfType = true; 5850b57cec5SDimitry Andric } else if (Feature == "+dotprod") { 5860b57cec5SDimitry Andric DotProd = true; 5870b57cec5SDimitry Andric } else if (Feature == "+mve") { 5880b57cec5SDimitry Andric MVE |= MVE_INT; 5890b57cec5SDimitry Andric } else if (Feature == "+mve.fp") { 5900b57cec5SDimitry Andric HasLegalHalfType = true; 5910b57cec5SDimitry Andric FPU |= FPARMV8; 5920b57cec5SDimitry Andric MVE |= MVE_INT | MVE_FP; 5930b57cec5SDimitry Andric HW_FP |= HW_FP_SP | HW_FP_HP; 5945ffd83dbSDimitry Andric } else if (Feature == "+i8mm") { 5955ffd83dbSDimitry Andric HasMatMul = 1; 5965ffd83dbSDimitry Andric } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" && 5975ffd83dbSDimitry Andric Feature <= "+cdecp7") { 5985ffd83dbSDimitry Andric unsigned Coproc = Feature.back() - '0'; 5995ffd83dbSDimitry Andric ARMCDECoprocMask |= (1U << Coproc); 6005ffd83dbSDimitry Andric } else if (Feature == "+bf16") { 6015ffd83dbSDimitry Andric HasBFloat16 = true; 602349cc55cSDimitry Andric } else if (Feature == "-fpregs") { 603349cc55cSDimitry Andric FPRegsDisabled = true; 6040eae32dcSDimitry Andric } else if (Feature == "+pacbti") { 6050eae32dcSDimitry Andric HasPAC = 1; 6060eae32dcSDimitry Andric HasBTI = 1; 60706c3fb27SDimitry Andric } else if (Feature == "+fullbf16") { 60806c3fb27SDimitry Andric HasFullBFloat16 = true; 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric 612bdd1243dSDimitry Andric HalfArgsAndReturns = true; 613bdd1243dSDimitry Andric 6140b57cec5SDimitry Andric switch (ArchVersion) { 6150b57cec5SDimitry Andric case 6: 6160b57cec5SDimitry Andric if (ArchProfile == llvm::ARM::ProfileKind::M) 6170b57cec5SDimitry Andric LDREX = 0; 6180b57cec5SDimitry Andric else if (ArchKind == llvm::ARM::ArchKind::ARMV6K) 6190b57cec5SDimitry Andric LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 6200b57cec5SDimitry Andric else 6210b57cec5SDimitry Andric LDREX = LDREX_W; 6220b57cec5SDimitry Andric break; 6230b57cec5SDimitry Andric case 7: 6240b57cec5SDimitry Andric if (ArchProfile == llvm::ARM::ProfileKind::M) 6250b57cec5SDimitry Andric LDREX = LDREX_W | LDREX_H | LDREX_B; 6260b57cec5SDimitry Andric else 6270b57cec5SDimitry Andric LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 6280b57cec5SDimitry Andric break; 6290b57cec5SDimitry Andric case 8: 630349cc55cSDimitry Andric case 9: 6310b57cec5SDimitry Andric LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B; 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric if (!(FPU & NeonFPU) && FPMath == FP_Neon) { 6350b57cec5SDimitry Andric Diags.Report(diag::err_target_unsupported_fpmath) << "neon"; 6360b57cec5SDimitry Andric return false; 6370b57cec5SDimitry Andric } 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric if (FPMath == FP_Neon) 6400b57cec5SDimitry Andric Features.push_back("+neonfp"); 6410b57cec5SDimitry Andric else if (FPMath == FP_VFP) 6420b57cec5SDimitry Andric Features.push_back("-neonfp"); 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric return true; 6450b57cec5SDimitry Andric } 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric bool ARMTargetInfo::hasFeature(StringRef Feature) const { 6480b57cec5SDimitry Andric return llvm::StringSwitch<bool>(Feature) 6490b57cec5SDimitry Andric .Case("arm", true) 6500b57cec5SDimitry Andric .Case("aarch32", true) 6510b57cec5SDimitry Andric .Case("softfloat", SoftFloat) 6520b57cec5SDimitry Andric .Case("thumb", isThumb()) 6530b57cec5SDimitry Andric .Case("neon", (FPU & NeonFPU) && !SoftFloat) 6540b57cec5SDimitry Andric .Case("vfp", FPU && !SoftFloat) 6550b57cec5SDimitry Andric .Case("hwdiv", HWDiv & HWDivThumb) 6560b57cec5SDimitry Andric .Case("hwdiv-arm", HWDiv & HWDivARM) 6570b57cec5SDimitry Andric .Case("mve", hasMVE()) 6580b57cec5SDimitry Andric .Default(false); 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6615ffd83dbSDimitry Andric bool ARMTargetInfo::hasBFloat16Type() const { 662bdd1243dSDimitry Andric // The __bf16 type is generally available so long as we have any fp registers. 663bdd1243dSDimitry Andric return HasBFloat16 || (FPU && !SoftFloat); 6645ffd83dbSDimitry Andric } 6655ffd83dbSDimitry Andric 6660b57cec5SDimitry Andric bool ARMTargetInfo::isValidCPUName(StringRef Name) const { 6670b57cec5SDimitry Andric return Name == "generic" || 6680b57cec5SDimitry Andric llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID; 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const { 6720b57cec5SDimitry Andric llvm::ARM::fillValidCPUArchList(Values); 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric bool ARMTargetInfo::setCPU(const std::string &Name) { 6760b57cec5SDimitry Andric if (Name != "generic") 6770b57cec5SDimitry Andric setArchInfo(llvm::ARM::parseCPUArch(Name)); 6780b57cec5SDimitry Andric 6790b57cec5SDimitry Andric if (ArchKind == llvm::ARM::ArchKind::INVALID) 6800b57cec5SDimitry Andric return false; 6810b57cec5SDimitry Andric setAtomic(); 6820b57cec5SDimitry Andric CPU = Name; 6830b57cec5SDimitry Andric return true; 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric bool ARMTargetInfo::setFPMath(StringRef Name) { 6870b57cec5SDimitry Andric if (Name == "neon") { 6880b57cec5SDimitry Andric FPMath = FP_Neon; 6890b57cec5SDimitry Andric return true; 6900b57cec5SDimitry Andric } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" || 6910b57cec5SDimitry Andric Name == "vfp4") { 6920b57cec5SDimitry Andric FPMath = FP_VFP; 6930b57cec5SDimitry Andric return true; 6940b57cec5SDimitry Andric } 6950b57cec5SDimitry Andric return false; 6960b57cec5SDimitry Andric } 6970b57cec5SDimitry Andric 6980b57cec5SDimitry Andric void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, 6990b57cec5SDimitry Andric MacroBuilder &Builder) const { 7000b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric 7030b57cec5SDimitry Andric void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, 7040b57cec5SDimitry Andric MacroBuilder &Builder) const { 7050b57cec5SDimitry Andric // Also include the ARMv8.1-A defines 7060b57cec5SDimitry Andric getTargetDefinesARMV81A(Opts, Builder); 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric 709480093f4SDimitry Andric void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, 710480093f4SDimitry Andric MacroBuilder &Builder) const { 711480093f4SDimitry Andric // Also include the ARMv8.2-A defines 712480093f4SDimitry Andric Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1"); 713480093f4SDimitry Andric getTargetDefinesARMV82A(Opts, Builder); 714480093f4SDimitry Andric } 715480093f4SDimitry Andric 7160b57cec5SDimitry Andric void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, 7170b57cec5SDimitry Andric MacroBuilder &Builder) const { 7180b57cec5SDimitry Andric // Target identification. 7190b57cec5SDimitry Andric Builder.defineMacro("__arm"); 7200b57cec5SDimitry Andric Builder.defineMacro("__arm__"); 7210b57cec5SDimitry Andric // For bare-metal none-eabi. 7220b57cec5SDimitry Andric if (getTriple().getOS() == llvm::Triple::UnknownOS && 7230b57cec5SDimitry Andric (getTriple().getEnvironment() == llvm::Triple::EABI || 72406c3fb27SDimitry Andric getTriple().getEnvironment() == llvm::Triple::EABIHF) && 72506c3fb27SDimitry Andric Opts.CPlusPlus) { 726bdd1243dSDimitry Andric Builder.defineMacro("_GNU_SOURCE"); 727bdd1243dSDimitry Andric } 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric // Target properties. 7300b57cec5SDimitry Andric Builder.defineMacro("__REGISTER_PREFIX__", ""); 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU 7330b57cec5SDimitry Andric // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__. 7340b57cec5SDimitry Andric if (getTriple().isWatchABI()) 7350b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH_7K__", "2"); 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric if (!CPUAttr.empty()) 7380b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__"); 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric // ACLE 6.4.1 ARM/Thumb instruction set architecture 7410b57cec5SDimitry Andric // __ARM_ARCH is defined as an integer value indicating the current ARM ISA 7420b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion)); 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric if (ArchVersion >= 8) { 7450b57cec5SDimitry Andric // ACLE 6.5.7 Crypto Extension 746fe6060f1SDimitry Andric // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained 747fe6060f1SDimitry Andric // feature macros for AES and SHA2 748fe6060f1SDimitry Andric if (SHA2 && AES) 7490b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); 750fe6060f1SDimitry Andric if (SHA2) 751fe6060f1SDimitry Andric Builder.defineMacro("__ARM_FEATURE_SHA2", "1"); 752fe6060f1SDimitry Andric if (AES) 753fe6060f1SDimitry Andric Builder.defineMacro("__ARM_FEATURE_AES", "1"); 7540b57cec5SDimitry Andric // ACLE 6.5.8 CRC32 Extension 7550b57cec5SDimitry Andric if (CRC) 7560b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); 7570b57cec5SDimitry Andric // ACLE 6.5.10 Numeric Maximum and Minimum 7580b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); 7590b57cec5SDimitry Andric // ACLE 6.5.9 Directed Rounding 7600b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It 7640b57cec5SDimitry Andric // is not defined for the M-profile. 7650b57cec5SDimitry Andric // NOTE that the default profile is assumed to be 'A' 7660b57cec5SDimitry Andric if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M) 7670b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1"); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original 7700b57cec5SDimitry Andric // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the 7710b57cec5SDimitry Andric // core supports the Thumb-2 ISA as found in the v6T2 architecture and all 7720b57cec5SDimitry Andric // v7 and v8 architectures excluding v8-M Baseline. 7730b57cec5SDimitry Andric if (supportsThumb2()) 7740b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2"); 7750b57cec5SDimitry Andric else if (supportsThumb()) 7760b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1"); 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit 7790b57cec5SDimitry Andric // instruction set such as ARM or Thumb. 7800b57cec5SDimitry Andric Builder.defineMacro("__ARM_32BIT_STATE", "1"); 7810b57cec5SDimitry Andric 7820b57cec5SDimitry Andric // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex) 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset. 7850b57cec5SDimitry Andric if (!CPUProfile.empty()) 7860b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'"); 7870b57cec5SDimitry Andric 7880b57cec5SDimitry Andric // ACLE 6.4.3 Unaligned access supported in hardware 7890fca6ea1SDimitry Andric if (HasUnalignedAccess) 7900b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric // ACLE 6.4.4 LDREX/STREX 7930b57cec5SDimitry Andric if (LDREX) 7940b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX)); 7950b57cec5SDimitry Andric 7960b57cec5SDimitry Andric // ACLE 6.4.5 CLZ 7970b57cec5SDimitry Andric if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") || 7980b57cec5SDimitry Andric ArchVersion > 6) 7990b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); 8000b57cec5SDimitry Andric 8010b57cec5SDimitry Andric // ACLE 6.5.1 Hardware Floating Point 8020b57cec5SDimitry Andric if (HW_FP) 8030b57cec5SDimitry Andric Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP)); 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andric // ACLE predefines. 8060b57cec5SDimitry Andric Builder.defineMacro("__ARM_ACLE", "200"); 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric // FP16 support (we currently only support IEEE format). 8090b57cec5SDimitry Andric Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); 8100b57cec5SDimitry Andric Builder.defineMacro("__ARM_FP16_ARGS", "1"); 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric // ACLE 6.5.3 Fused multiply-accumulate (FMA) 8130b57cec5SDimitry Andric if (ArchVersion >= 7 && (FPU & VFP4FPU)) 8140b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_FMA", "1"); 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric // Subtarget options. 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric // FIXME: It's more complicated than this and we don't really support 8190b57cec5SDimitry Andric // interworking. 8200b57cec5SDimitry Andric // Windows on ARM does not "support" interworking 8210b57cec5SDimitry Andric if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows()) 8220b57cec5SDimitry Andric Builder.defineMacro("__THUMB_INTERWORK__"); 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { 8250b57cec5SDimitry Andric // Embedded targets on Darwin follow AAPCS, but not EABI. 8260b57cec5SDimitry Andric // Windows on ARM follows AAPCS VFP, but does not conform to EABI. 8270b57cec5SDimitry Andric if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows()) 8280b57cec5SDimitry Andric Builder.defineMacro("__ARM_EABI__"); 8290b57cec5SDimitry Andric Builder.defineMacro("__ARM_PCS", "1"); 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16") 8330b57cec5SDimitry Andric Builder.defineMacro("__ARM_PCS_VFP", "1"); 8340b57cec5SDimitry Andric 835bdd1243dSDimitry Andric if (SoftFloat || (SoftFloatABI && !FPU)) 8360b57cec5SDimitry Andric Builder.defineMacro("__SOFTFP__"); 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric // ACLE position independent code macros. 8390b57cec5SDimitry Andric if (Opts.ROPI) 8400b57cec5SDimitry Andric Builder.defineMacro("__ARM_ROPI", "1"); 8410b57cec5SDimitry Andric if (Opts.RWPI) 8420b57cec5SDimitry Andric Builder.defineMacro("__ARM_RWPI", "1"); 8430b57cec5SDimitry Andric 8441db9f3b2SDimitry Andric // Macros for enabling co-proc intrinsics 8451db9f3b2SDimitry Andric uint64_t FeatureCoprocBF = 0; 8461db9f3b2SDimitry Andric switch (ArchKind) { 8471db9f3b2SDimitry Andric default: 8481db9f3b2SDimitry Andric break; 8491db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV4: 8501db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV4T: 8511db9f3b2SDimitry Andric // Filter __arm_ldcl and __arm_stcl in acle.h 8521db9f3b2SDimitry Andric FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1; 8531db9f3b2SDimitry Andric break; 8541db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV5T: 8551db9f3b2SDimitry Andric FeatureCoprocBF = isThumb() ? 0 : FEATURE_COPROC_B1 | FEATURE_COPROC_B2; 8561db9f3b2SDimitry Andric break; 8571db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV5TE: 8581db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV5TEJ: 8591db9f3b2SDimitry Andric if (!isThumb()) 8601db9f3b2SDimitry Andric FeatureCoprocBF = 8611db9f3b2SDimitry Andric FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | FEATURE_COPROC_B3; 8621db9f3b2SDimitry Andric break; 8631db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV6: 8641db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV6K: 8651db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV6KZ: 8661db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV6T2: 8671db9f3b2SDimitry Andric if (!isThumb() || ArchKind == llvm::ARM::ArchKind::ARMV6T2) 8681db9f3b2SDimitry Andric FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | 8691db9f3b2SDimitry Andric FEATURE_COPROC_B3 | FEATURE_COPROC_B4; 8701db9f3b2SDimitry Andric break; 8711db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV7A: 8721db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV7R: 8731db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV7M: 8741db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV7S: 8751db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV7EM: 8761db9f3b2SDimitry Andric FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | 8771db9f3b2SDimitry Andric FEATURE_COPROC_B3 | FEATURE_COPROC_B4; 8781db9f3b2SDimitry Andric break; 8791db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8A: 8801db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8R: 8811db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_1A: 8821db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_2A: 8831db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_3A: 8841db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_4A: 8851db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_5A: 8861db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_6A: 8871db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_7A: 8881db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_8A: 8891db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_9A: 8901db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV9A: 8911db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV9_1A: 8921db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV9_2A: 8931db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV9_3A: 8941db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV9_4A: 8957a6dacacSDimitry Andric case llvm::ARM::ArchKind::ARMV9_5A: 8961db9f3b2SDimitry Andric // Filter __arm_cdp, __arm_ldcl, __arm_stcl in arm_acle.h 8971db9f3b2SDimitry Andric FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B3; 8981db9f3b2SDimitry Andric break; 8991db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8MMainline: 9001db9f3b2SDimitry Andric case llvm::ARM::ArchKind::ARMV8_1MMainline: 9011db9f3b2SDimitry Andric FeatureCoprocBF = FEATURE_COPROC_B1 | FEATURE_COPROC_B2 | 9021db9f3b2SDimitry Andric FEATURE_COPROC_B3 | FEATURE_COPROC_B4; 9031db9f3b2SDimitry Andric break; 9041db9f3b2SDimitry Andric } 9051db9f3b2SDimitry Andric Builder.defineMacro("__ARM_FEATURE_COPROC", 9061db9f3b2SDimitry Andric "0x" + Twine::utohexstr(FeatureCoprocBF)); 9071db9f3b2SDimitry Andric 9080b57cec5SDimitry Andric if (ArchKind == llvm::ARM::ArchKind::XSCALE) 9090b57cec5SDimitry Andric Builder.defineMacro("__XSCALE__"); 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric if (isThumb()) { 9120b57cec5SDimitry Andric Builder.defineMacro("__THUMBEL__"); 9130b57cec5SDimitry Andric Builder.defineMacro("__thumb__"); 9140b57cec5SDimitry Andric if (supportsThumb2()) 9150b57cec5SDimitry Andric Builder.defineMacro("__thumb2__"); 9160b57cec5SDimitry Andric } 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric // ACLE 6.4.9 32-bit SIMD instructions 9190b57cec5SDimitry Andric if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP)) 9200b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_SIMD32", "1"); 9210b57cec5SDimitry Andric 9220b57cec5SDimitry Andric // ACLE 6.4.10 Hardware Integer Divide 9230b57cec5SDimitry Andric if (((HWDiv & HWDivThumb) && isThumb()) || 9240b57cec5SDimitry Andric ((HWDiv & HWDivARM) && !isThumb())) { 9250b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); 9260b57cec5SDimitry Andric Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1"); 9270b57cec5SDimitry Andric } 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric // Note, this is always on in gcc, even though it doesn't make sense. 9300b57cec5SDimitry Andric Builder.defineMacro("__APCS_32__"); 9310b57cec5SDimitry Andric 932fe6060f1SDimitry Andric // __VFP_FP__ means that the floating-point format is VFP, not that a hardware 933fe6060f1SDimitry Andric // FPU is present. Moreover, the VFP format is the only one supported by 934fe6060f1SDimitry Andric // clang. For these reasons, this macro is always defined. 9350b57cec5SDimitry Andric Builder.defineMacro("__VFP_FP__"); 936fe6060f1SDimitry Andric 937fe6060f1SDimitry Andric if (FPUModeIsVFP((FPUMode)FPU)) { 9380b57cec5SDimitry Andric if (FPU & VFP2FPU) 9390b57cec5SDimitry Andric Builder.defineMacro("__ARM_VFPV2__"); 9400b57cec5SDimitry Andric if (FPU & VFP3FPU) 9410b57cec5SDimitry Andric Builder.defineMacro("__ARM_VFPV3__"); 9420b57cec5SDimitry Andric if (FPU & VFP4FPU) 9430b57cec5SDimitry Andric Builder.defineMacro("__ARM_VFPV4__"); 9440b57cec5SDimitry Andric if (FPU & FPARMV8) 9450b57cec5SDimitry Andric Builder.defineMacro("__ARM_FPV5__"); 9460b57cec5SDimitry Andric } 9470b57cec5SDimitry Andric 9480b57cec5SDimitry Andric // This only gets set when Neon instructions are actually available, unlike 9490b57cec5SDimitry Andric // the VFP define, hence the soft float and arch check. This is subtly 9500b57cec5SDimitry Andric // different from gcc, we follow the intent which was that it should be set 9510b57cec5SDimitry Andric // when Neon instructions are actually available. 9520b57cec5SDimitry Andric if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) { 9530b57cec5SDimitry Andric Builder.defineMacro("__ARM_NEON", "1"); 9540b57cec5SDimitry Andric Builder.defineMacro("__ARM_NEON__"); 9550b57cec5SDimitry Andric // current AArch32 NEON implementations do not support double-precision 9560b57cec5SDimitry Andric // floating-point even when it is present in VFP. 9570b57cec5SDimitry Andric Builder.defineMacro("__ARM_NEON_FP", 9580b57cec5SDimitry Andric "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP)); 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric if (hasMVE()) { 9620b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1"); 9630b57cec5SDimitry Andric } 9640b57cec5SDimitry Andric 9655ffd83dbSDimitry Andric if (hasCDE()) { 9665ffd83dbSDimitry Andric Builder.defineMacro("__ARM_FEATURE_CDE", "1"); 9675ffd83dbSDimitry Andric Builder.defineMacro("__ARM_FEATURE_CDE_COPROC", 9685ffd83dbSDimitry Andric "0x" + Twine::utohexstr(getARMCDECoprocMask())); 9695ffd83dbSDimitry Andric } 9705ffd83dbSDimitry Andric 9710b57cec5SDimitry Andric Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", 9720b57cec5SDimitry Andric Twine(Opts.WCharSize ? Opts.WCharSize : 4)); 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); 9750b57cec5SDimitry Andric 9760b57cec5SDimitry Andric // CMSE 9770b57cec5SDimitry Andric if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M) 9780b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1"); 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andric if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") { 9810b57cec5SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); 9820b57cec5SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); 9830b57cec5SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); 9840b57cec5SDimitry Andric Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric // ACLE 6.4.7 DSP instructions 9880b57cec5SDimitry Andric if (DSP) { 9890b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_DSP", "1"); 9900b57cec5SDimitry Andric } 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric // ACLE 6.4.8 Saturation instructions 9930b57cec5SDimitry Andric bool SAT = false; 9940b57cec5SDimitry Andric if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) { 9950b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_SAT", "1"); 9960b57cec5SDimitry Andric SAT = true; 9970b57cec5SDimitry Andric } 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric // ACLE 6.4.6 Q (saturation) flag 10000b57cec5SDimitry Andric if (DSP || SAT) 10010b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_QBIT", "1"); 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric if (Opts.UnsafeFPMath) 10040b57cec5SDimitry Andric Builder.defineMacro("__ARM_FP_FAST", "1"); 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric // Armv8.2-A FP16 vector intrinsic 10070b57cec5SDimitry Andric if ((FPU & NeonFPU) && HasLegalHalfType) 10080b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric // Armv8.2-A FP16 scalar intrinsics 10110b57cec5SDimitry Andric if (HasLegalHalfType) 10120b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andric // Armv8.2-A dot product intrinsics 10150b57cec5SDimitry Andric if (DotProd) 10160b57cec5SDimitry Andric Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); 10170b57cec5SDimitry Andric 10185ffd83dbSDimitry Andric if (HasMatMul) 10195ffd83dbSDimitry Andric Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); 10205ffd83dbSDimitry Andric 10210eae32dcSDimitry Andric if (HasPAC) 10220eae32dcSDimitry Andric Builder.defineMacro("__ARM_FEATURE_PAUTH", "1"); 10230eae32dcSDimitry Andric 10240eae32dcSDimitry Andric if (HasBTI) 10250eae32dcSDimitry Andric Builder.defineMacro("__ARM_FEATURE_BTI", "1"); 10260eae32dcSDimitry Andric 10275ffd83dbSDimitry Andric if (HasBFloat16) { 10285ffd83dbSDimitry Andric Builder.defineMacro("__ARM_FEATURE_BF16", "1"); 10295ffd83dbSDimitry Andric Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); 10305ffd83dbSDimitry Andric Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); 10315ffd83dbSDimitry Andric } 10325ffd83dbSDimitry Andric 10334824e7fdSDimitry Andric if (Opts.BranchTargetEnforcement) 10344824e7fdSDimitry Andric Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); 10354824e7fdSDimitry Andric 10364824e7fdSDimitry Andric if (Opts.hasSignReturnAddress()) { 10370eae32dcSDimitry Andric unsigned Value = 1; 10384824e7fdSDimitry Andric if (Opts.isSignReturnAddressScopeAll()) 10394824e7fdSDimitry Andric Value |= 1 << 2; 10404824e7fdSDimitry Andric Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value)); 10414824e7fdSDimitry Andric } 10424824e7fdSDimitry Andric 10430b57cec5SDimitry Andric switch (ArchKind) { 10440b57cec5SDimitry Andric default: 10450b57cec5SDimitry Andric break; 10460b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_1A: 10470b57cec5SDimitry Andric getTargetDefinesARMV81A(Opts, Builder); 10480b57cec5SDimitry Andric break; 10490b57cec5SDimitry Andric case llvm::ARM::ArchKind::ARMV8_2A: 10500b57cec5SDimitry Andric getTargetDefinesARMV82A(Opts, Builder); 10510b57cec5SDimitry Andric break; 1052480093f4SDimitry Andric case llvm::ARM::ArchKind::ARMV8_3A: 1053480093f4SDimitry Andric case llvm::ARM::ArchKind::ARMV8_4A: 1054480093f4SDimitry Andric case llvm::ARM::ArchKind::ARMV8_5A: 10555ffd83dbSDimitry Andric case llvm::ARM::ArchKind::ARMV8_6A: 105681ad6265SDimitry Andric case llvm::ARM::ArchKind::ARMV8_7A: 105704eeddc0SDimitry Andric case llvm::ARM::ArchKind::ARMV8_8A: 1058bdd1243dSDimitry Andric case llvm::ARM::ArchKind::ARMV8_9A: 1059349cc55cSDimitry Andric case llvm::ARM::ArchKind::ARMV9A: 1060349cc55cSDimitry Andric case llvm::ARM::ArchKind::ARMV9_1A: 1061349cc55cSDimitry Andric case llvm::ARM::ArchKind::ARMV9_2A: 106204eeddc0SDimitry Andric case llvm::ARM::ArchKind::ARMV9_3A: 1063bdd1243dSDimitry Andric case llvm::ARM::ArchKind::ARMV9_4A: 10647a6dacacSDimitry Andric case llvm::ARM::ArchKind::ARMV9_5A: 1065480093f4SDimitry Andric getTargetDefinesARMV83A(Opts, Builder); 1066480093f4SDimitry Andric break; 10670b57cec5SDimitry Andric } 10680b57cec5SDimitry Andric } 10690b57cec5SDimitry Andric 1070bdd1243dSDimitry Andric static constexpr Builtin::Info BuiltinInfo[] = { 10710b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS) \ 1072bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 10730b57cec5SDimitry Andric #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 1074bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, 1075bdd1243dSDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 1076bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 10770b57cec5SDimitry Andric #include "clang/Basic/BuiltinsNEON.def" 10780b57cec5SDimitry Andric 10790b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS) \ 1080bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 10810b57cec5SDimitry Andric #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 1082bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, 10830b57cec5SDimitry Andric #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 1084bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, 10858792c038SDimitry Andric #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 1086bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 10870b57cec5SDimitry Andric #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 1088bdd1243dSDimitry Andric {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, 10890b57cec5SDimitry Andric #include "clang/Basic/BuiltinsARM.def" 10900b57cec5SDimitry Andric }; 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { 1093bdd1243dSDimitry Andric return llvm::ArrayRef(BuiltinInfo, 1094bdd1243dSDimitry Andric clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin); 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } 10980b57cec5SDimitry Andric TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const { 10990b57cec5SDimitry Andric return IsAAPCS 11000b57cec5SDimitry Andric ? AAPCSABIBuiltinVaList 11010b57cec5SDimitry Andric : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList 11020b57cec5SDimitry Andric : TargetInfo::VoidPtrBuiltinVaList); 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric 11050b57cec5SDimitry Andric const char *const ARMTargetInfo::GCCRegNames[] = { 11060b57cec5SDimitry Andric // Integer registers 11070b57cec5SDimitry Andric "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", 11080b57cec5SDimitry Andric "r12", "sp", "lr", "pc", 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric // Float registers 11110b57cec5SDimitry Andric "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 11120b57cec5SDimitry Andric "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 11130b57cec5SDimitry Andric "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric // Double registers 11160b57cec5SDimitry Andric "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 11170b57cec5SDimitry Andric "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 11180b57cec5SDimitry Andric "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric // Quad registers 11210b57cec5SDimitry Andric "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", 11220b57cec5SDimitry Andric "q12", "q13", "q14", "q15"}; 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andric ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { 1125bdd1243dSDimitry Andric return llvm::ArrayRef(GCCRegNames); 11260b57cec5SDimitry Andric } 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 11290b57cec5SDimitry Andric {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"}, 11300b57cec5SDimitry Andric {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"}, 11310b57cec5SDimitry Andric {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"}, 11320b57cec5SDimitry Andric {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"}, 11330b57cec5SDimitry Andric // The S, D and Q registers overlap, but aren't really aliases; we 11340b57cec5SDimitry Andric // don't want to substitute one of these for a different-sized one. 11350b57cec5SDimitry Andric }; 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { 1138bdd1243dSDimitry Andric return llvm::ArrayRef(GCCRegAliases); 11390b57cec5SDimitry Andric } 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric bool ARMTargetInfo::validateAsmConstraint( 11420b57cec5SDimitry Andric const char *&Name, TargetInfo::ConstraintInfo &Info) const { 11430b57cec5SDimitry Andric switch (*Name) { 11440b57cec5SDimitry Andric default: 11450b57cec5SDimitry Andric break; 1146a7dea167SDimitry Andric case 'l': // r0-r7 if thumb, r0-r15 if ARM 11470b57cec5SDimitry Andric Info.setAllowsRegister(); 11480b57cec5SDimitry Andric return true; 1149a7dea167SDimitry Andric case 'h': // r8-r15, thumb only 1150a7dea167SDimitry Andric if (isThumb()) { 1151a7dea167SDimitry Andric Info.setAllowsRegister(); 11520b57cec5SDimitry Andric return true; 1153a7dea167SDimitry Andric } 1154a7dea167SDimitry Andric break; 1155a7dea167SDimitry Andric case 's': // An integer constant, but allowing only relocatable values. 1156a7dea167SDimitry Andric return true; 1157a7dea167SDimitry Andric case 't': // s0-s31, d0-d31, or q0-q15 1158a7dea167SDimitry Andric case 'w': // s0-s15, d0-d7, or q0-q3 1159a7dea167SDimitry Andric case 'x': // s0-s31, d0-d15, or q0-q7 1160349cc55cSDimitry Andric if (FPRegsDisabled) 1161349cc55cSDimitry Andric return false; 1162a7dea167SDimitry Andric Info.setAllowsRegister(); 1163a7dea167SDimitry Andric return true; 1164a7dea167SDimitry Andric case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) 1165a7dea167SDimitry Andric // only available in ARMv6T2 and above 11660fca6ea1SDimitry Andric if (CPUAttr == "6T2" || ArchVersion >= 7) { 1167a7dea167SDimitry Andric Info.setRequiresImmediate(0, 65535); 1168a7dea167SDimitry Andric return true; 1169a7dea167SDimitry Andric } 1170a7dea167SDimitry Andric break; 1171a7dea167SDimitry Andric case 'I': 1172a7dea167SDimitry Andric if (isThumb()) { 1173a7dea167SDimitry Andric if (!supportsThumb2()) 1174a7dea167SDimitry Andric Info.setRequiresImmediate(0, 255); 1175a7dea167SDimitry Andric else 1176a7dea167SDimitry Andric // FIXME: should check if immediate value would be valid for a Thumb2 1177a7dea167SDimitry Andric // data-processing instruction 1178a7dea167SDimitry Andric Info.setRequiresImmediate(); 1179a7dea167SDimitry Andric } else 1180a7dea167SDimitry Andric // FIXME: should check if immediate value would be valid for an ARM 1181a7dea167SDimitry Andric // data-processing instruction 1182a7dea167SDimitry Andric Info.setRequiresImmediate(); 1183a7dea167SDimitry Andric return true; 1184a7dea167SDimitry Andric case 'J': 1185a7dea167SDimitry Andric if (isThumb() && !supportsThumb2()) 1186a7dea167SDimitry Andric Info.setRequiresImmediate(-255, -1); 1187a7dea167SDimitry Andric else 1188a7dea167SDimitry Andric Info.setRequiresImmediate(-4095, 4095); 1189a7dea167SDimitry Andric return true; 1190a7dea167SDimitry Andric case 'K': 1191a7dea167SDimitry Andric if (isThumb()) { 1192a7dea167SDimitry Andric if (!supportsThumb2()) 1193a7dea167SDimitry Andric // FIXME: should check if immediate value can be obtained from shifting 1194a7dea167SDimitry Andric // a value between 0 and 255 left by any amount 1195a7dea167SDimitry Andric Info.setRequiresImmediate(); 1196a7dea167SDimitry Andric else 1197a7dea167SDimitry Andric // FIXME: should check if immediate value would be valid for a Thumb2 1198a7dea167SDimitry Andric // data-processing instruction when inverted 1199a7dea167SDimitry Andric Info.setRequiresImmediate(); 1200a7dea167SDimitry Andric } else 1201a7dea167SDimitry Andric // FIXME: should check if immediate value would be valid for an ARM 1202a7dea167SDimitry Andric // data-processing instruction when inverted 1203a7dea167SDimitry Andric Info.setRequiresImmediate(); 1204a7dea167SDimitry Andric return true; 1205a7dea167SDimitry Andric case 'L': 1206a7dea167SDimitry Andric if (isThumb()) { 1207a7dea167SDimitry Andric if (!supportsThumb2()) 1208a7dea167SDimitry Andric Info.setRequiresImmediate(-7, 7); 1209a7dea167SDimitry Andric else 1210a7dea167SDimitry Andric // FIXME: should check if immediate value would be valid for a Thumb2 1211a7dea167SDimitry Andric // data-processing instruction when negated 1212a7dea167SDimitry Andric Info.setRequiresImmediate(); 1213a7dea167SDimitry Andric } else 1214a7dea167SDimitry Andric // FIXME: should check if immediate value would be valid for an ARM 1215a7dea167SDimitry Andric // data-processing instruction when negated 1216a7dea167SDimitry Andric Info.setRequiresImmediate(); 1217a7dea167SDimitry Andric return true; 1218a7dea167SDimitry Andric case 'M': 1219a7dea167SDimitry Andric if (isThumb() && !supportsThumb2()) 1220a7dea167SDimitry Andric // FIXME: should check if immediate value is a multiple of 4 between 0 and 1221a7dea167SDimitry Andric // 1020 1222a7dea167SDimitry Andric Info.setRequiresImmediate(); 1223a7dea167SDimitry Andric else 1224a7dea167SDimitry Andric // FIXME: should check if immediate value is a power of two or a integer 1225a7dea167SDimitry Andric // between 0 and 32 1226a7dea167SDimitry Andric Info.setRequiresImmediate(); 1227a7dea167SDimitry Andric return true; 1228a7dea167SDimitry Andric case 'N': 1229a7dea167SDimitry Andric // Thumb1 only 1230a7dea167SDimitry Andric if (isThumb() && !supportsThumb2()) { 1231a7dea167SDimitry Andric Info.setRequiresImmediate(0, 31); 1232a7dea167SDimitry Andric return true; 1233a7dea167SDimitry Andric } 1234a7dea167SDimitry Andric break; 1235a7dea167SDimitry Andric case 'O': 1236a7dea167SDimitry Andric // Thumb1 only 1237a7dea167SDimitry Andric if (isThumb() && !supportsThumb2()) { 1238a7dea167SDimitry Andric // FIXME: should check if immediate value is a multiple of 4 between -508 1239a7dea167SDimitry Andric // and 508 1240a7dea167SDimitry Andric Info.setRequiresImmediate(); 1241a7dea167SDimitry Andric return true; 1242a7dea167SDimitry Andric } 1243a7dea167SDimitry Andric break; 12440b57cec5SDimitry Andric case 'Q': // A memory address that is a single base register. 12450b57cec5SDimitry Andric Info.setAllowsMemory(); 12460b57cec5SDimitry Andric return true; 12470b57cec5SDimitry Andric case 'T': 12480b57cec5SDimitry Andric switch (Name[1]) { 12490b57cec5SDimitry Andric default: 12500b57cec5SDimitry Andric break; 12510b57cec5SDimitry Andric case 'e': // Even general-purpose register 12520b57cec5SDimitry Andric case 'o': // Odd general-purpose register 12530b57cec5SDimitry Andric Info.setAllowsRegister(); 12540b57cec5SDimitry Andric Name++; 12550b57cec5SDimitry Andric return true; 12560b57cec5SDimitry Andric } 12570b57cec5SDimitry Andric break; 12580b57cec5SDimitry Andric case 'U': // a memory reference... 12590b57cec5SDimitry Andric switch (Name[1]) { 12600b57cec5SDimitry Andric case 'q': // ...ARMV4 ldrsb 12610b57cec5SDimitry Andric case 'v': // ...VFP load/store (reg+constant offset) 12620b57cec5SDimitry Andric case 'y': // ...iWMMXt load/store 12630b57cec5SDimitry Andric case 't': // address valid for load/store opaque types wider 12640b57cec5SDimitry Andric // than 128-bits 12650b57cec5SDimitry Andric case 'n': // valid address for Neon doubleword vector load/store 12660b57cec5SDimitry Andric case 'm': // valid address for Neon element and structure load/store 12670b57cec5SDimitry Andric case 's': // valid address for non-offset loads/stores of quad-word 12680b57cec5SDimitry Andric // values in four ARM registers 12690b57cec5SDimitry Andric Info.setAllowsMemory(); 12700b57cec5SDimitry Andric Name++; 12710b57cec5SDimitry Andric return true; 12720b57cec5SDimitry Andric } 12730b57cec5SDimitry Andric break; 12740b57cec5SDimitry Andric } 12750b57cec5SDimitry Andric return false; 12760b57cec5SDimitry Andric } 12770b57cec5SDimitry Andric 12780b57cec5SDimitry Andric std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { 12790b57cec5SDimitry Andric std::string R; 12800b57cec5SDimitry Andric switch (*Constraint) { 12810b57cec5SDimitry Andric case 'U': // Two-character constraint; add "^" hint for later parsing. 12820b57cec5SDimitry Andric case 'T': 12830b57cec5SDimitry Andric R = std::string("^") + std::string(Constraint, 2); 12840b57cec5SDimitry Andric Constraint++; 12850b57cec5SDimitry Andric break; 12860b57cec5SDimitry Andric case 'p': // 'p' should be translated to 'r' by default. 12870b57cec5SDimitry Andric R = std::string("r"); 12880b57cec5SDimitry Andric break; 12890b57cec5SDimitry Andric default: 12900b57cec5SDimitry Andric return std::string(1, *Constraint); 12910b57cec5SDimitry Andric } 12920b57cec5SDimitry Andric return R; 12930b57cec5SDimitry Andric } 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andric bool ARMTargetInfo::validateConstraintModifier( 12960b57cec5SDimitry Andric StringRef Constraint, char Modifier, unsigned Size, 12970b57cec5SDimitry Andric std::string &SuggestedModifier) const { 12980b57cec5SDimitry Andric bool isOutput = (Constraint[0] == '='); 12990b57cec5SDimitry Andric bool isInOut = (Constraint[0] == '+'); 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andric // Strip off constraint modifiers. 1302647cbc5dSDimitry Andric Constraint = Constraint.ltrim("=+&"); 13030b57cec5SDimitry Andric 13040b57cec5SDimitry Andric switch (Constraint[0]) { 13050b57cec5SDimitry Andric default: 13060b57cec5SDimitry Andric break; 13070b57cec5SDimitry Andric case 'r': { 13080b57cec5SDimitry Andric switch (Modifier) { 13090b57cec5SDimitry Andric default: 13100b57cec5SDimitry Andric return (isInOut || isOutput || Size <= 64); 13110b57cec5SDimitry Andric case 'q': 13120b57cec5SDimitry Andric // A register of size 32 cannot fit a vector type. 13130b57cec5SDimitry Andric return false; 13140b57cec5SDimitry Andric } 13150b57cec5SDimitry Andric } 13160b57cec5SDimitry Andric } 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andric return true; 13190b57cec5SDimitry Andric } 132006c3fb27SDimitry Andric std::string_view ARMTargetInfo::getClobbers() const { 13210b57cec5SDimitry Andric // FIXME: Is this really right? 13220b57cec5SDimitry Andric return ""; 13230b57cec5SDimitry Andric } 13240b57cec5SDimitry Andric 13250b57cec5SDimitry Andric TargetInfo::CallingConvCheckResult 13260b57cec5SDimitry Andric ARMTargetInfo::checkCallingConvention(CallingConv CC) const { 13270b57cec5SDimitry Andric switch (CC) { 13280b57cec5SDimitry Andric case CC_AAPCS: 13290b57cec5SDimitry Andric case CC_AAPCS_VFP: 13300b57cec5SDimitry Andric case CC_Swift: 1331fe6060f1SDimitry Andric case CC_SwiftAsync: 13320b57cec5SDimitry Andric case CC_OpenCLKernel: 13330b57cec5SDimitry Andric return CCCR_OK; 13340b57cec5SDimitry Andric default: 13350b57cec5SDimitry Andric return CCCR_Warning; 13360b57cec5SDimitry Andric } 13370b57cec5SDimitry Andric } 13380b57cec5SDimitry Andric 13390b57cec5SDimitry Andric int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 13400b57cec5SDimitry Andric if (RegNo == 0) 13410b57cec5SDimitry Andric return 0; 13420b57cec5SDimitry Andric if (RegNo == 1) 13430b57cec5SDimitry Andric return 1; 13440b57cec5SDimitry Andric return -1; 13450b57cec5SDimitry Andric } 13460b57cec5SDimitry Andric 13470b57cec5SDimitry Andric bool ARMTargetInfo::hasSjLjLowering() const { return true; } 13480b57cec5SDimitry Andric 13490b57cec5SDimitry Andric ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple, 13500b57cec5SDimitry Andric const TargetOptions &Opts) 13510b57cec5SDimitry Andric : ARMTargetInfo(Triple, Opts) {} 13520b57cec5SDimitry Andric 13530b57cec5SDimitry Andric void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 13540b57cec5SDimitry Andric MacroBuilder &Builder) const { 13550b57cec5SDimitry Andric Builder.defineMacro("__ARMEL__"); 13560b57cec5SDimitry Andric ARMTargetInfo::getTargetDefines(Opts, Builder); 13570b57cec5SDimitry Andric } 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple, 13600b57cec5SDimitry Andric const TargetOptions &Opts) 13610b57cec5SDimitry Andric : ARMTargetInfo(Triple, Opts) {} 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts, 13640b57cec5SDimitry Andric MacroBuilder &Builder) const { 13650b57cec5SDimitry Andric Builder.defineMacro("__ARMEB__"); 13660b57cec5SDimitry Andric Builder.defineMacro("__ARM_BIG_ENDIAN"); 13670b57cec5SDimitry Andric ARMTargetInfo::getTargetDefines(Opts, Builder); 13680b57cec5SDimitry Andric } 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andric WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, 13710b57cec5SDimitry Andric const TargetOptions &Opts) 13720b57cec5SDimitry Andric : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { 13730b57cec5SDimitry Andric } 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, 13760b57cec5SDimitry Andric MacroBuilder &Builder) const { 13770b57cec5SDimitry Andric // FIXME: this is invalid for WindowsCE 13780b57cec5SDimitry Andric Builder.defineMacro("_M_ARM_NT", "1"); 13790b57cec5SDimitry Andric Builder.defineMacro("_M_ARMT", "_M_ARM"); 13800b57cec5SDimitry Andric Builder.defineMacro("_M_THUMB", "_M_ARM"); 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andric assert((Triple.getArch() == llvm::Triple::arm || 13830b57cec5SDimitry Andric Triple.getArch() == llvm::Triple::thumb) && 13840b57cec5SDimitry Andric "invalid architecture for Windows ARM target info"); 13850b57cec5SDimitry Andric unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; 13860b57cec5SDimitry Andric Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); 13870b57cec5SDimitry Andric 13880b57cec5SDimitry Andric // TODO map the complete set of values 13890b57cec5SDimitry Andric // 31: VFPv3 40: VFPv4 13900b57cec5SDimitry Andric Builder.defineMacro("_M_ARM_FP", "31"); 13910b57cec5SDimitry Andric } 13920b57cec5SDimitry Andric 13930b57cec5SDimitry Andric TargetInfo::BuiltinVaListKind 13940b57cec5SDimitry Andric WindowsARMTargetInfo::getBuiltinVaListKind() const { 13950b57cec5SDimitry Andric return TargetInfo::CharPtrBuiltinVaList; 13960b57cec5SDimitry Andric } 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric TargetInfo::CallingConvCheckResult 13990b57cec5SDimitry Andric WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { 14000b57cec5SDimitry Andric switch (CC) { 14010b57cec5SDimitry Andric case CC_X86StdCall: 14020b57cec5SDimitry Andric case CC_X86ThisCall: 14030b57cec5SDimitry Andric case CC_X86FastCall: 14040b57cec5SDimitry Andric case CC_X86VectorCall: 14050b57cec5SDimitry Andric return CCCR_Ignore; 14060b57cec5SDimitry Andric case CC_C: 14070b57cec5SDimitry Andric case CC_OpenCLKernel: 14080b57cec5SDimitry Andric case CC_PreserveMost: 14090b57cec5SDimitry Andric case CC_PreserveAll: 14100b57cec5SDimitry Andric case CC_Swift: 1411fe6060f1SDimitry Andric case CC_SwiftAsync: 14120b57cec5SDimitry Andric return CCCR_OK; 14130b57cec5SDimitry Andric default: 14140b57cec5SDimitry Andric return CCCR_Warning; 14150b57cec5SDimitry Andric } 14160b57cec5SDimitry Andric } 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric // Windows ARM + Itanium C++ ABI Target 14190b57cec5SDimitry Andric ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo( 14200b57cec5SDimitry Andric const llvm::Triple &Triple, const TargetOptions &Opts) 14210b57cec5SDimitry Andric : WindowsARMTargetInfo(Triple, Opts) { 14220b57cec5SDimitry Andric TheCXXABI.set(TargetCXXABI::GenericARM); 14230b57cec5SDimitry Andric } 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric void ItaniumWindowsARMleTargetInfo::getTargetDefines( 14260b57cec5SDimitry Andric const LangOptions &Opts, MacroBuilder &Builder) const { 14270b57cec5SDimitry Andric WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 14280b57cec5SDimitry Andric 14290b57cec5SDimitry Andric if (Opts.MSVCCompat) 14300b57cec5SDimitry Andric WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 14310b57cec5SDimitry Andric } 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andric // Windows ARM, MS (C++) ABI 14340b57cec5SDimitry Andric MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 14350b57cec5SDimitry Andric const TargetOptions &Opts) 14360b57cec5SDimitry Andric : WindowsARMTargetInfo(Triple, Opts) { 14370b57cec5SDimitry Andric TheCXXABI.set(TargetCXXABI::Microsoft); 14380b57cec5SDimitry Andric } 14390b57cec5SDimitry Andric 14400b57cec5SDimitry Andric void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 14410b57cec5SDimitry Andric MacroBuilder &Builder) const { 14420b57cec5SDimitry Andric WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 14430b57cec5SDimitry Andric WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 14440b57cec5SDimitry Andric } 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple, 14470b57cec5SDimitry Andric const TargetOptions &Opts) 14480b57cec5SDimitry Andric : WindowsARMTargetInfo(Triple, Opts) { 14490b57cec5SDimitry Andric TheCXXABI.set(TargetCXXABI::GenericARM); 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric 14520b57cec5SDimitry Andric void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts, 14530b57cec5SDimitry Andric MacroBuilder &Builder) const { 14540b57cec5SDimitry Andric WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 14550b57cec5SDimitry Andric Builder.defineMacro("_ARM_"); 14560b57cec5SDimitry Andric } 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andric CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, 14590b57cec5SDimitry Andric const TargetOptions &Opts) 14600b57cec5SDimitry Andric : ARMleTargetInfo(Triple, Opts) { 14610b57cec5SDimitry Andric this->WCharType = TargetInfo::UnsignedShort; 14620b57cec5SDimitry Andric TLSSupported = false; 14630b57cec5SDimitry Andric DoubleAlign = LongLongAlign = 64; 14640b57cec5SDimitry Andric resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 14650b57cec5SDimitry Andric } 14660b57cec5SDimitry Andric 14670b57cec5SDimitry Andric void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, 14680b57cec5SDimitry Andric MacroBuilder &Builder) const { 14690b57cec5SDimitry Andric ARMleTargetInfo::getTargetDefines(Opts, Builder); 14700b57cec5SDimitry Andric Builder.defineMacro("_ARM_"); 14710b57cec5SDimitry Andric Builder.defineMacro("__CYGWIN__"); 14720b57cec5SDimitry Andric Builder.defineMacro("__CYGWIN32__"); 14730b57cec5SDimitry Andric DefineStd(Builder, "unix", Opts); 14740b57cec5SDimitry Andric if (Opts.CPlusPlus) 14750b57cec5SDimitry Andric Builder.defineMacro("_GNU_SOURCE"); 14760b57cec5SDimitry Andric } 14770b57cec5SDimitry Andric 14780b57cec5SDimitry Andric DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, 14790b57cec5SDimitry Andric const TargetOptions &Opts) 14800b57cec5SDimitry Andric : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { 14810b57cec5SDimitry Andric HasAlignMac68kSupport = true; 14820b57cec5SDimitry Andric if (Triple.isWatchABI()) { 14830b57cec5SDimitry Andric // Darwin on iOS uses a variant of the ARM C++ ABI. 14840b57cec5SDimitry Andric TheCXXABI.set(TargetCXXABI::WatchOS); 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric // BOOL should be a real boolean on the new ABI 14870b57cec5SDimitry Andric UseSignedCharForObjCBool = false; 14880b57cec5SDimitry Andric } else 14890b57cec5SDimitry Andric TheCXXABI.set(TargetCXXABI::iOS); 14900b57cec5SDimitry Andric } 14910b57cec5SDimitry Andric 14920b57cec5SDimitry Andric void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts, 14930b57cec5SDimitry Andric const llvm::Triple &Triple, 14940b57cec5SDimitry Andric MacroBuilder &Builder) const { 14950b57cec5SDimitry Andric getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 14960b57cec5SDimitry Andric } 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple, 14990b57cec5SDimitry Andric const TargetOptions &Opts) 15000b57cec5SDimitry Andric : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(), 15010b57cec5SDimitry Andric Triple.getOSName(), 15020b57cec5SDimitry Andric Triple.getEnvironmentName()), 15030b57cec5SDimitry Andric Opts) { 15040b57cec5SDimitry Andric IsRenderScriptTarget = true; 15050b57cec5SDimitry Andric LongWidth = LongAlign = 64; 15060b57cec5SDimitry Andric } 15070b57cec5SDimitry Andric 15080b57cec5SDimitry Andric void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts, 15090b57cec5SDimitry Andric MacroBuilder &Builder) const { 15100b57cec5SDimitry Andric Builder.defineMacro("__RENDERSCRIPT__"); 15110b57cec5SDimitry Andric ARMleTargetInfo::getTargetDefines(Opts, Builder); 15120b57cec5SDimitry Andric } 1513