Ties Stuij ecd682bbf5 [ARM] Add __bf16 as new Bfloat16 C Type
Summary:
This patch upstreams support for a new storage only bfloat16 C type.
This type is used to implement primitive support for bfloat16 data, in
line with the Bfloat16 extension of the Armv8.6-a architecture, as
detailed here:

https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/arm-architecture-developments-armv8-6-a

The bfloat type, and its properties are specified in the Arm Architecture
Reference Manual:

https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile

In detail this patch:
- introduces an opaque, storage-only C-type __bf16, which introduces a new bfloat IR type.

This is part of a patch series, starting with command-line and Bfloat16
assembly support. The subsequent patches will upstream intrinsics
support for BFloat16, followed by Matrix Multiplication and the
remaining Virtualization features of the armv8.6-a architecture.

The following people contributed to this patch:
- Luke Cheeseman
- Momchil Velikov
- Alexandros Lamprineas
- Luke Geeson
- Simon Tatham
- Ties Stuij

Reviewers: SjoerdMeijer, rjmccall, rsmith, liutianle, RKSimon, craig.topper, jfb, LukeGeeson, fpetrogalli

Reviewed By: SjoerdMeijer

Subscribers: labrinea, majnemer, asmith, dexonsmith, kristof.beyls, arphaman, danielkiss, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D76077
2020-06-05 10:32:43 +01:00

287 lines
8.7 KiB
C++

//===--- ARM.h - Declare ARM target feature support -------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares 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)
};
enum MVEMode {
MVE_INT = (1 << 0),
MVE_FP = (1 << 1)
};
// 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;
llvm::ARM::ISAKind ArchISA;
llvm::ARM::ArchKind ArchKind = llvm::ARM::ArchKind::ARMV4T;
llvm::ARM::ProfileKind ArchProfile;
unsigned ArchVersion;
unsigned FPU : 5;
unsigned MVE : 2;
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;
unsigned DotProd : 1;
unsigned HasMatMul : 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[];
void setABIAAPCS();
void setABIAPCS(bool IsAAPCS16);
void setArchInfo();
void setArchInfo(llvm::ARM::ArchKind Kind);
void setAtomic();
bool isThumb() const;
bool supportsThumb() const;
bool supportsThumb2() const;
bool hasMVE() const;
bool hasMVEFloat() const;
bool hasCDE() const;
StringRef getCPUAttr() const;
StringRef getCPUProfile() const;
public:
ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
StringRef getABI() const override;
bool setABI(const std::string &Name) override;
// FIXME: This should be based on Arch attributes, not CPU names.
bool
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
StringRef CPU,
const std::vector<std::string> &FeaturesVec) const override;
bool isValidFeatureName(StringRef Feature) const override {
// We pass soft-float-abi in as a -target-feature, but the backend figures
// this out through other means.
return Feature != "soft-float-abi";
}
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
bool hasFeature(StringRef Feature) const override;
bool hasBFloat16Type() const override;
bool isValidCPUName(StringRef Name) const override;
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool setCPU(const std::string &Name) override;
bool setFPMath(StringRef Name) override;
bool useFP16ConversionIntrinsics() const override {
return false;
}
void getTargetDefinesARMV81A(const LangOptions &Opts,
MacroBuilder &Builder) const;
void getTargetDefinesARMV82A(const LangOptions &Opts,
MacroBuilder &Builder) const;
void getTargetDefinesARMV83A(const LangOptions &Opts,
MacroBuilder &Builder) const;
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
bool isCLZForZeroUndef() const override;
BuiltinVaListKind getBuiltinVaListKind() const override;
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const override;
std::string convertConstraint(const char *&Constraint) const override;
bool
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
std::string &SuggestedModifier) const override;
const char *getClobbers() const override;
StringRef getConstraintRegister(StringRef Constraint,
StringRef Expression) const override {
return Expression;
}
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
int getEHDataRegisterNumber(unsigned RegNo) const override;
bool hasSjLjLowering() const override;
bool hasExtIntType() const override { return true; }
const char *getBFloat16Mangling() const override { return "u6__bf16"; };
};
class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
public:
ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
class LLVM_LIBRARY_VISIBILITY ARMbeTargetInfo : public ARMTargetInfo {
public:
ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
class LLVM_LIBRARY_VISIBILITY WindowsARMTargetInfo
: public WindowsTargetInfo<ARMleTargetInfo> {
const llvm::Triple Triple;
public:
WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
void getVisualStudioDefines(const LangOptions &Opts,
MacroBuilder &Builder) const;
BuiltinVaListKind getBuiltinVaListKind() const override;
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
};
// Windows ARM + Itanium C++ ABI Target
class LLVM_LIBRARY_VISIBILITY ItaniumWindowsARMleTargetInfo
: public WindowsARMTargetInfo {
public:
ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts);
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
// Windows ARM, MS (C++) ABI
class LLVM_LIBRARY_VISIBILITY MicrosoftARMleTargetInfo
: public WindowsARMTargetInfo {
public:
MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts);
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
// ARM MinGW target
class LLVM_LIBRARY_VISIBILITY MinGWARMTargetInfo : public WindowsARMTargetInfo {
public:
MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
// ARM Cygwin target
class LLVM_LIBRARY_VISIBILITY CygwinARMTargetInfo : public ARMleTargetInfo {
public:
CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
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,
MacroBuilder &Builder) const override;
public:
DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
};
// 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,
const TargetOptions &Opts);
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};
} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_ARM_H