2017-07-22 06:37:03 +08:00
|
|
|
//===--- ARM.h - Declare ARM target feature support -------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file declares ARM TargetInfo objects.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
|
|
|
|
#define LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
|
|
|
|
|
|
|
|
#include "OSTargets.h"
|
|
|
|
#include "clang/Basic/TargetInfo.h"
|
|
|
|
#include "clang/Basic/TargetOptions.h"
|
|
|
|
#include "llvm/ADT/Triple.h"
|
|
|
|
#include "llvm/Support/Compiler.h"
|
|
|
|
#include "llvm/Support/TargetParser.h"
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace targets {
|
|
|
|
|
|
|
|
class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
|
|
|
|
// Possible FPU choices.
|
|
|
|
enum FPUMode {
|
|
|
|
VFP2FPU = (1 << 0),
|
|
|
|
VFP3FPU = (1 << 1),
|
|
|
|
VFP4FPU = (1 << 2),
|
|
|
|
NeonFPU = (1 << 3),
|
|
|
|
FPARMV8 = (1 << 4)
|
|
|
|
};
|
|
|
|
|
|
|
|
// Possible HWDiv features.
|
|
|
|
enum HWDivMode { HWDivThumb = (1 << 0), HWDivARM = (1 << 1) };
|
|
|
|
|
|
|
|
static bool FPUModeIsVFP(FPUMode Mode) {
|
|
|
|
return Mode & (VFP2FPU | VFP3FPU | VFP4FPU | NeonFPU | FPARMV8);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const TargetInfo::GCCRegAlias GCCRegAliases[];
|
|
|
|
static const char *const GCCRegNames[];
|
|
|
|
|
|
|
|
std::string ABI, CPU;
|
|
|
|
|
|
|
|
StringRef CPUProfile;
|
|
|
|
StringRef CPUAttr;
|
|
|
|
|
|
|
|
enum { FP_Default, FP_VFP, FP_Neon } FPMath;
|
|
|
|
|
2017-07-28 00:28:39 +08:00
|
|
|
llvm::ARM::ISAKind ArchISA;
|
|
|
|
llvm::ARM::ArchKind ArchKind = llvm::ARM::ArchKind::ARMV4T;
|
|
|
|
llvm::ARM::ProfileKind ArchProfile;
|
2017-07-22 06:37:03 +08:00
|
|
|
unsigned ArchVersion;
|
|
|
|
|
|
|
|
unsigned FPU : 5;
|
|
|
|
|
|
|
|
unsigned IsAAPCS : 1;
|
|
|
|
unsigned HWDiv : 2;
|
|
|
|
|
|
|
|
// Initialized via features.
|
|
|
|
unsigned SoftFloat : 1;
|
|
|
|
unsigned SoftFloatABI : 1;
|
|
|
|
|
|
|
|
unsigned CRC : 1;
|
|
|
|
unsigned Crypto : 1;
|
|
|
|
unsigned DSP : 1;
|
|
|
|
unsigned Unaligned : 1;
|
|
|
|
|
|
|
|
enum {
|
|
|
|
LDREX_B = (1 << 0), /// byte (8-bit)
|
|
|
|
LDREX_H = (1 << 1), /// half (16-bit)
|
|
|
|
LDREX_W = (1 << 2), /// word (32-bit)
|
|
|
|
LDREX_D = (1 << 3), /// double (64-bit)
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32_t LDREX;
|
|
|
|
|
|
|
|
// ACLE 6.5.1 Hardware floating point
|
|
|
|
enum {
|
|
|
|
HW_FP_HP = (1 << 1), /// half (16-bit)
|
|
|
|
HW_FP_SP = (1 << 2), /// single (32-bit)
|
|
|
|
HW_FP_DP = (1 << 3), /// double (64-bit)
|
|
|
|
};
|
|
|
|
uint32_t HW_FP;
|
|
|
|
|
|
|
|
static const Builtin::Info BuiltinInfo[];
|
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
void setABIAAPCS();
|
|
|
|
void setABIAPCS(bool IsAAPCS16);
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
void setArchInfo();
|
2017-07-28 00:28:39 +08:00
|
|
|
void setArchInfo(llvm::ARM::ArchKind Kind);
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
void setAtomic();
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
bool isThumb() const;
|
|
|
|
bool supportsThumb() const;
|
|
|
|
bool supportsThumb2() const;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
StringRef getCPUAttr() const;
|
|
|
|
StringRef getCPUProfile() const;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
public:
|
2017-07-25 01:06:23 +08:00
|
|
|
ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
StringRef getABI() const override;
|
|
|
|
bool setABI(const std::string &Name) override;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
// FIXME: This should be based on Arch attributes, not CPU names.
|
|
|
|
bool
|
|
|
|
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
|
|
|
|
StringRef CPU,
|
2017-07-25 01:06:23 +08:00
|
|
|
const std::vector<std::string> &FeaturesVec) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
bool handleTargetFeatures(std::vector<std::string> &Features,
|
|
|
|
DiagnosticsEngine &Diags) override;
|
|
|
|
|
|
|
|
bool hasFeature(StringRef Feature) const override;
|
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
bool isValidCPUName(StringRef Name) const override;
|
2018-02-09 07:14:15 +08:00
|
|
|
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
|
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
bool setCPU(const std::string &Name) override;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
bool setFPMath(StringRef Name) override;
|
|
|
|
|
[CodeGen][X86] Fix handling of __fp16 vectors.
This commit fixes a bug in IRGen where it generates completely broken
code for __fp16 vectors on X86. For example when the following code is
compiled:
half4 hv0, hv1, hv2; // these are vectors of __fp16.
void foo221() {
hv0 = hv1 + hv2;
}
clang generates the following IR, in which two i16 vectors are added:
@hv1 = common global <4 x i16> zeroinitializer, align 8
@hv2 = common global <4 x i16> zeroinitializer, align 8
@hv0 = common global <4 x i16> zeroinitializer, align 8
define void @foo221() {
%0 = load <4 x i16>, <4 x i16>* @hv1, align 8
%1 = load <4 x i16>, <4 x i16>* @hv2, align 8
%add = add <4 x i16> %0, %1
store <4 x i16> %add, <4 x i16>* @hv0, align 8
ret void
}
To fix the bug, this commit uses the code committed in r314056, which
modified clang to promote and truncate __fp16 vectors to and from float
vectors in the AST. It also fixes another IRGen bug where a short value
is assigned to an __fp16 variable without any integer-to-floating-point
conversion, as shown in the following example:
__fp16 a;
short b;
void foo1() {
a = b;
}
@b = common global i16 0, align 2
@a = common global i16 0, align 2
define void @foo1() #0 {
%0 = load i16, i16* @b, align 2
store i16 %0, i16* @a, align 2
ret void
}
rdar://problem/20625184
Differential Revision: https://reviews.llvm.org/D40112
llvm-svn: 320215
2017-12-09 08:02:37 +08:00
|
|
|
bool useFP16ConversionIntrinsics() const override {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-07-22 06:37:03 +08:00
|
|
|
void getTargetDefinesARMV81A(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const;
|
|
|
|
|
|
|
|
void getTargetDefinesARMV82A(const LangOptions &Opts,
|
2017-07-25 01:06:23 +08:00
|
|
|
MacroBuilder &Builder) const;
|
2017-07-22 06:37:03 +08:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
2017-07-25 01:06:23 +08:00
|
|
|
|
2017-07-22 06:37:03 +08:00
|
|
|
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
|
2017-07-25 01:06:23 +08:00
|
|
|
|
|
|
|
bool isCLZForZeroUndef() const override;
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override;
|
|
|
|
|
2017-07-22 06:37:03 +08:00
|
|
|
ArrayRef<const char *> getGCCRegNames() const override;
|
|
|
|
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
|
|
|
|
bool validateAsmConstraint(const char *&Name,
|
2017-07-25 01:06:23 +08:00
|
|
|
TargetInfo::ConstraintInfo &Info) const override;
|
|
|
|
std::string convertConstraint(const char *&Constraint) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
bool
|
|
|
|
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
|
2017-07-25 01:06:23 +08:00
|
|
|
std::string &SuggestedModifier) const override;
|
|
|
|
const char *getClobbers() const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
int getEHDataRegisterNumber(unsigned RegNo) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
2017-07-25 01:06:23 +08:00
|
|
|
bool hasSjLjLowering() const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
|
|
|
|
public:
|
2017-07-25 01:06:23 +08:00
|
|
|
ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
|
2017-07-22 06:37:03 +08:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo {
|
|
|
|
public:
|
2017-07-25 01:06:23 +08:00
|
|
|
ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
|
2017-07-22 06:37:03 +08:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo
|
|
|
|
: public WindowsTargetInfo<ARMleTargetInfo> {
|
|
|
|
const llvm::Triple Triple;
|
|
|
|
|
|
|
|
public:
|
2017-07-25 01:06:23 +08:00
|
|
|
WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
|
|
|
|
|
2017-07-22 06:37:03 +08:00
|
|
|
void getVisualStudioDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const;
|
2017-07-25 01:06:23 +08:00
|
|
|
|
|
|
|
BuiltinVaListKind getBuiltinVaListKind() const override;
|
|
|
|
|
|
|
|
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// Windows ARM + Itanium C++ ABI Target
|
|
|
|
class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo
|
|
|
|
: public WindowsARMTargetInfo {
|
|
|
|
public:
|
|
|
|
ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple,
|
2017-07-25 01:06:23 +08:00
|
|
|
const TargetOptions &Opts);
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
2017-07-25 01:06:23 +08:00
|
|
|
MacroBuilder &Builder) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// Windows ARM, MS (C++) ABI
|
|
|
|
class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo
|
|
|
|
: public WindowsARMTargetInfo {
|
|
|
|
public:
|
|
|
|
MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
|
2017-07-25 01:06:23 +08:00
|
|
|
const TargetOptions &Opts);
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
2017-07-25 01:06:23 +08:00
|
|
|
MacroBuilder &Builder) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
// ARM MinGW target
|
|
|
|
class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo {
|
|
|
|
public:
|
2017-07-25 01:06:23 +08:00
|
|
|
MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
// ARM Cygwin target
|
|
|
|
class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo {
|
|
|
|
public:
|
2017-07-25 01:06:23 +08:00
|
|
|
CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
|
|
|
|
|
2017-07-22 06:37:03 +08:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class LLVM_LIBRARY_VISIBILITY DarwinARMTargetInfo
|
|
|
|
: public DarwinTargetInfo<ARMleTargetInfo> {
|
|
|
|
protected:
|
|
|
|
void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
|
2017-07-25 01:06:23 +08:00
|
|
|
MacroBuilder &Builder) const override;
|
2017-07-22 06:37:03 +08:00
|
|
|
|
|
|
|
public:
|
2017-07-25 01:06:23 +08:00
|
|
|
DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
|
2017-07-22 06:37:03 +08:00
|
|
|
};
|
2017-07-25 01:06:23 +08:00
|
|
|
|
2017-07-22 06:37:03 +08:00
|
|
|
// 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes
|
|
|
|
class LLVM_LIBRARY_VISIBILITY RenderScript32TargetInfo
|
|
|
|
: public ARMleTargetInfo {
|
|
|
|
public:
|
|
|
|
RenderScript32TargetInfo(const llvm::Triple &Triple,
|
2017-07-25 01:06:23 +08:00
|
|
|
const TargetOptions &Opts);
|
|
|
|
|
2017-07-22 06:37:03 +08:00
|
|
|
void getTargetDefines(const LangOptions &Opts,
|
|
|
|
MacroBuilder &Builder) const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace targets
|
|
|
|
} // namespace clang
|
|
|
|
|
|
|
|
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H
|