forked from OSchip/llvm-project
Revert "[SVE] Auto-generate builtins and header for svld1."
This reverts commit 8b409eabaf
.
Reverting this patch for now because it breaks some buildbots.
This commit is contained in:
parent
5c261c9c45
commit
6ce537ccfc
|
@ -1,67 +0,0 @@
|
||||||
//===- AArch64SVETypeFlags.h - Flags used to generate ACLE builtins- 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
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef LLVM_CLANG_BASIC_AARCH64SVETYPEFLAGS_H
|
|
||||||
#define LLVM_CLANG_BASIC_AARCH64SVETYPEFLAGS_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
namespace clang {
|
|
||||||
|
|
||||||
/// Flags to identify the types for overloaded SVE builtins.
|
|
||||||
class SVETypeFlags {
|
|
||||||
uint64_t Flags;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// These must be kept in sync with the flags in
|
|
||||||
/// include/clang/Basic/arm_sve.td.
|
|
||||||
static const uint64_t MemEltTypeOffset = 4; // Bit offset of MemEltTypeMask
|
|
||||||
static const uint64_t EltTypeMask = 0x00000000000f;
|
|
||||||
static const uint64_t MemEltTypeMask = 0x000000000070;
|
|
||||||
static const uint64_t IsLoad = 0x000000000080;
|
|
||||||
|
|
||||||
enum EltType {
|
|
||||||
Invalid,
|
|
||||||
Int8,
|
|
||||||
Int16,
|
|
||||||
Int32,
|
|
||||||
Int64,
|
|
||||||
Float16,
|
|
||||||
Float32,
|
|
||||||
Float64,
|
|
||||||
Bool8,
|
|
||||||
Bool16,
|
|
||||||
Bool32,
|
|
||||||
Bool64
|
|
||||||
};
|
|
||||||
|
|
||||||
enum MemEltTy {
|
|
||||||
MemEltTyDefault,
|
|
||||||
MemEltTyInt8,
|
|
||||||
MemEltTyInt16,
|
|
||||||
MemEltTyInt32,
|
|
||||||
MemEltTyInt64
|
|
||||||
};
|
|
||||||
|
|
||||||
SVETypeFlags(uint64_t F) : Flags(F) { }
|
|
||||||
SVETypeFlags(EltType ET, bool IsUnsigned) : Flags(ET) { }
|
|
||||||
|
|
||||||
EltType getEltType() const { return (EltType)(Flags & EltTypeMask); }
|
|
||||||
MemEltTy getMemEltType() const {
|
|
||||||
return (MemEltTy)((Flags & MemEltTypeMask) >> MemEltTypeOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLoad() const { return Flags & IsLoad; }
|
|
||||||
|
|
||||||
uint64_t getBits() const { return Flags; }
|
|
||||||
bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // end namespace clang
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -99,6 +99,19 @@ BUILTIN(__builtin_arm_tcommit, "v", "n")
|
||||||
BUILTIN(__builtin_arm_tcancel, "vWUIi", "n")
|
BUILTIN(__builtin_arm_tcancel, "vWUIi", "n")
|
||||||
BUILTIN(__builtin_arm_ttest, "WUi", "nc")
|
BUILTIN(__builtin_arm_ttest, "WUi", "nc")
|
||||||
|
|
||||||
|
// SVE
|
||||||
|
BUILTIN(__builtin_sve_svld1_s16, "q8sq16bSsC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_s32, "q4iq16bSiC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_s64, "q2Wiq16bSWiC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_s8, "q16Scq16bScC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_u16, "q8Usq16bUsC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_u32, "q4Uiq16bUiC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_u64, "q2UWiq16bUWiC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_u8, "q16Ucq16bUcC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_f64, "q2dq16bdC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_f32, "q4fq16bfC*", "n")
|
||||||
|
BUILTIN(__builtin_sve_svld1_f16, "q8hq16bhC*", "n")
|
||||||
|
|
||||||
TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||||
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||||
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
//===--- BuiltinsSVE.def - SVE Builtin function database --------*- 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 defines the SVE-specific builtin function database. Users of
|
|
||||||
// this file must define the BUILTIN macro to make use of this information.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
// The format of this database matches clang/Basic/Builtins.def.
|
|
||||||
|
|
||||||
#define GET_SVE_BUILTINS
|
|
||||||
#include "clang/Basic/arm_sve_builtins.inc"
|
|
||||||
#undef GET_SVE_BUILTINS
|
|
||||||
|
|
||||||
#undef BUILTIN
|
|
|
@ -60,12 +60,7 @@ clang_tablegen(arm_mve_builtin_sema.inc -gen-arm-mve-builtin-sema
|
||||||
clang_tablegen(arm_mve_builtin_aliases.inc -gen-arm-mve-builtin-aliases
|
clang_tablegen(arm_mve_builtin_aliases.inc -gen-arm-mve-builtin-aliases
|
||||||
SOURCE arm_mve.td
|
SOURCE arm_mve.td
|
||||||
TARGET ClangARMMveBuiltinAliases)
|
TARGET ClangARMMveBuiltinAliases)
|
||||||
clang_tablegen(arm_sve_builtins.inc -gen-arm-sve-builtins
|
|
||||||
SOURCE arm_sve.td
|
|
||||||
TARGET ClangARMSveBuiltins)
|
|
||||||
clang_tablegen(arm_sve_codegenmap.inc -gen-arm-sve-codegenmap
|
|
||||||
SOURCE arm_sve.td
|
|
||||||
TARGET ClangARMSveCodeGenMap)
|
|
||||||
clang_tablegen(arm_cde_builtins.inc -gen-arm-cde-builtin-def
|
clang_tablegen(arm_cde_builtins.inc -gen-arm-cde-builtin-def
|
||||||
SOURCE arm_cde.td
|
SOURCE arm_cde.td
|
||||||
TARGET ClangARMCdeBuiltinsDef)
|
TARGET ClangARMCdeBuiltinsDef)
|
||||||
|
|
|
@ -41,22 +41,11 @@ namespace clang {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace SVE {
|
|
||||||
enum {
|
|
||||||
LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
|
|
||||||
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
|
|
||||||
#include "clang/Basic/BuiltinsSVE.def"
|
|
||||||
FirstTSBuiltin,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// AArch64 builtins
|
/// AArch64 builtins
|
||||||
namespace AArch64 {
|
namespace AArch64 {
|
||||||
enum {
|
enum {
|
||||||
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
|
LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
|
||||||
LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
|
LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
|
||||||
FirstSVEBuiltin = NEON::FirstTSBuiltin,
|
|
||||||
LastSVEBuiltin = SVE::FirstTSBuiltin - 1,
|
|
||||||
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
|
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
|
||||||
#include "clang/Basic/BuiltinsAArch64.def"
|
#include "clang/Basic/BuiltinsAArch64.def"
|
||||||
LastTSBuiltin
|
LastTSBuiltin
|
||||||
|
|
|
@ -12,110 +12,3 @@
|
||||||
// https://developer.arm.com/architectures/system-architectures/software-standards/acle
|
// https://developer.arm.com/architectures/system-architectures/software-standards/acle
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Instruction definitions
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
|
|
||||||
// a sequence of typespecs.
|
|
||||||
//
|
|
||||||
// The name is the base name of the intrinsic, for example "svld1". This is
|
|
||||||
// then mangled by the tblgen backend to add type information ("svld1_s16").
|
|
||||||
//
|
|
||||||
// A typespec is a sequence of uppercase characters (modifiers) followed by one
|
|
||||||
// lowercase character. A typespec encodes a particular "base type" of the
|
|
||||||
// intrinsic.
|
|
||||||
//
|
|
||||||
// An example typespec is "Us" - unsigned short - svuint16_t. The available
|
|
||||||
// typespec codes are given below.
|
|
||||||
//
|
|
||||||
// The string given to an Inst class is a sequence of typespecs. The intrinsic
|
|
||||||
// is instantiated for every typespec in the sequence. For example "sdUsUd".
|
|
||||||
//
|
|
||||||
// The prototype is a string that defines the return type of the intrinsic
|
|
||||||
// and the type of each argument. The return type and every argument gets a
|
|
||||||
// "modifier" that can change in some way the "base type" of the intrinsic.
|
|
||||||
//
|
|
||||||
// The modifier 'd' means "default" and does not modify the base type in any
|
|
||||||
// way. The available modifiers are given below.
|
|
||||||
//
|
|
||||||
// Typespecs
|
|
||||||
// ---------
|
|
||||||
// c: char
|
|
||||||
// s: short
|
|
||||||
// i: int
|
|
||||||
// l: long
|
|
||||||
// f: float
|
|
||||||
// h: half-float
|
|
||||||
// d: double
|
|
||||||
|
|
||||||
// Typespec modifiers
|
|
||||||
// ------------------
|
|
||||||
// P: boolean
|
|
||||||
// U: unsigned
|
|
||||||
|
|
||||||
// Prototype modifiers
|
|
||||||
// -------------------
|
|
||||||
// prototype: return (arg, arg, ...)
|
|
||||||
//
|
|
||||||
// d: default
|
|
||||||
// c: const pointer type
|
|
||||||
// P: predicate type
|
|
||||||
|
|
||||||
class MergeType<int val> {
|
|
||||||
int Value = val;
|
|
||||||
}
|
|
||||||
def MergeNone : MergeType<0>;
|
|
||||||
def MergeAny : MergeType<1>;
|
|
||||||
def MergeOp1 : MergeType<2>;
|
|
||||||
def MergeZero : MergeType<3>;
|
|
||||||
def MergeAnyExp : MergeType<4>; // Use merged builtin with explicit
|
|
||||||
def MergeZeroExp : MergeType<5>; // generation of its inactive argument.
|
|
||||||
|
|
||||||
class MemEltTy<int val> {
|
|
||||||
int Value = val;
|
|
||||||
}
|
|
||||||
def MemEltTyDefault : MemEltTy<0>;
|
|
||||||
def MemEltTyInt8 : MemEltTy<1>;
|
|
||||||
def MemEltTyInt16 : MemEltTy<2>;
|
|
||||||
def MemEltTyInt32 : MemEltTy<3>;
|
|
||||||
def MemEltTyInt64 : MemEltTy<4>;
|
|
||||||
|
|
||||||
class FlagType<int val> {
|
|
||||||
int Value = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// These must be kept in sync with the flags in utils/TableGen/SveEmitter.h
|
|
||||||
// and include/clang/Basic/TargetBuiltins.h
|
|
||||||
def NoFlags : FlagType<0x00000000>;
|
|
||||||
// 0x00000001 => EltType
|
|
||||||
// ...
|
|
||||||
// 0x0000000f => EltType
|
|
||||||
// 0x00000010 => MemEltType
|
|
||||||
// ...
|
|
||||||
// 0x00000070 => MemEltType
|
|
||||||
def IsLoad : FlagType<0x00000080>;
|
|
||||||
|
|
||||||
// Every intrinsic subclasses Inst.
|
|
||||||
class Inst<string n, string p, string t, MergeType mt, string i,
|
|
||||||
list<FlagType> ft, MemEltTy met> {
|
|
||||||
string Name = n;
|
|
||||||
string Prototype = p;
|
|
||||||
string Types = t;
|
|
||||||
string ArchGuard = "";
|
|
||||||
int Merge = mt.Value;
|
|
||||||
string LLVMIntrinsic = i;
|
|
||||||
list<FlagType> Flags = ft;
|
|
||||||
int MemEltType = met.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MInst: Instructions which access memory
|
|
||||||
class MInst<string n, string p, string t, list<FlagType> f,
|
|
||||||
MemEltTy met=MemEltTyDefault, string i="">
|
|
||||||
: Inst<n, p, t, MergeNone, i, f, met> {}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Loads
|
|
||||||
|
|
||||||
// Load one vector (scalar base)
|
|
||||||
def SVLD1 : MInst<"svld1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad]>;
|
|
||||||
|
|
|
@ -26,10 +26,6 @@ const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
|
||||||
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
|
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
|
||||||
#include "clang/Basic/BuiltinsNEON.def"
|
#include "clang/Basic/BuiltinsNEON.def"
|
||||||
|
|
||||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
|
||||||
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
|
|
||||||
#include "clang/Basic/BuiltinsSVE.def"
|
|
||||||
|
|
||||||
#define BUILTIN(ID, TYPE, ATTRS) \
|
#define BUILTIN(ID, TYPE, ATTRS) \
|
||||||
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
|
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
|
||||||
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
|
#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "clang/AST/Attr.h"
|
#include "clang/AST/Attr.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/OSLog.h"
|
#include "clang/AST/OSLog.h"
|
||||||
#include "clang/Basic/AArch64SVETypeFlags.h"
|
|
||||||
#include "clang/Basic/TargetBuiltins.h"
|
#include "clang/Basic/TargetBuiltins.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
#include "clang/CodeGen/CGFunctionInfo.h"
|
#include "clang/CodeGen/CGFunctionInfo.h"
|
||||||
|
@ -4577,7 +4576,7 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct ARMVectorIntrinsicInfo {
|
struct NeonIntrinsicInfo {
|
||||||
const char *NameHint;
|
const char *NameHint;
|
||||||
unsigned BuiltinID;
|
unsigned BuiltinID;
|
||||||
unsigned LLVMIntrinsic;
|
unsigned LLVMIntrinsic;
|
||||||
|
@ -4587,7 +4586,7 @@ struct ARMVectorIntrinsicInfo {
|
||||||
bool operator<(unsigned RHSBuiltinID) const {
|
bool operator<(unsigned RHSBuiltinID) const {
|
||||||
return BuiltinID < RHSBuiltinID;
|
return BuiltinID < RHSBuiltinID;
|
||||||
}
|
}
|
||||||
bool operator<(const ARMVectorIntrinsicInfo &TE) const {
|
bool operator<(const NeonIntrinsicInfo &TE) const {
|
||||||
return BuiltinID < TE.BuiltinID;
|
return BuiltinID < TE.BuiltinID;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4605,7 +4604,7 @@ struct ARMVectorIntrinsicInfo {
|
||||||
Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \
|
Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \
|
||||||
TypeModifier }
|
TypeModifier }
|
||||||
|
|
||||||
static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = {
|
static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = {
|
||||||
NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
|
NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
|
||||||
NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
|
NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
|
||||||
NEONMAP1(vabs_v, arm_neon_vabs, 0),
|
NEONMAP1(vabs_v, arm_neon_vabs, 0),
|
||||||
|
@ -4886,7 +4885,7 @@ static const ARMVectorIntrinsicInfo ARMSIMDIntrinsicMap [] = {
|
||||||
NEONMAP0(vzipq_v)
|
NEONMAP0(vzipq_v)
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ARMVectorIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
|
static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
|
||||||
NEONMAP1(vabs_v, aarch64_neon_abs, 0),
|
NEONMAP1(vabs_v, aarch64_neon_abs, 0),
|
||||||
NEONMAP1(vabsq_v, aarch64_neon_abs, 0),
|
NEONMAP1(vabsq_v, aarch64_neon_abs, 0),
|
||||||
NEONMAP0(vaddhn_v),
|
NEONMAP0(vaddhn_v),
|
||||||
|
@ -5055,7 +5054,7 @@ static const ARMVectorIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
|
||||||
NEONMAP0(vtstq_v),
|
NEONMAP0(vtstq_v),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ARMVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = {
|
static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = {
|
||||||
NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType),
|
NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType),
|
||||||
NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType),
|
NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType),
|
||||||
NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType),
|
NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType),
|
||||||
|
@ -5285,32 +5284,15 @@ static const ARMVectorIntrinsicInfo AArch64SISDIntrinsicMap[] = {
|
||||||
#undef NEONMAP1
|
#undef NEONMAP1
|
||||||
#undef NEONMAP2
|
#undef NEONMAP2
|
||||||
|
|
||||||
#define SVEMAP1(NameBase, LLVMIntrinsic, TypeModifier) \
|
|
||||||
{ \
|
|
||||||
#NameBase, SVE::BI__builtin_sve_##NameBase, Intrinsic::LLVMIntrinsic, 0, \
|
|
||||||
TypeModifier \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SVEMAP2(NameBase, TypeModifier) \
|
|
||||||
{ #NameBase, SVE::BI__builtin_sve_##NameBase, 0, 0, TypeModifier }
|
|
||||||
static const ARMVectorIntrinsicInfo AArch64SVEIntrinsicMap[] = {
|
|
||||||
#define GET_SVE_LLVM_INTRINSIC_MAP
|
|
||||||
#include "clang/Basic/arm_sve_codegenmap.inc"
|
|
||||||
#undef GET_SVE_LLVM_INTRINSIC_MAP
|
|
||||||
};
|
|
||||||
|
|
||||||
#undef SVEMAP1
|
|
||||||
#undef SVEMAP2
|
|
||||||
|
|
||||||
static bool NEONSIMDIntrinsicsProvenSorted = false;
|
static bool NEONSIMDIntrinsicsProvenSorted = false;
|
||||||
|
|
||||||
static bool AArch64SIMDIntrinsicsProvenSorted = false;
|
static bool AArch64SIMDIntrinsicsProvenSorted = false;
|
||||||
static bool AArch64SISDIntrinsicsProvenSorted = false;
|
static bool AArch64SISDIntrinsicsProvenSorted = false;
|
||||||
static bool AArch64SVEIntrinsicsProvenSorted = false;
|
|
||||||
|
|
||||||
static const ARMVectorIntrinsicInfo *
|
|
||||||
findARMVectorIntrinsicInMap(ArrayRef<ARMVectorIntrinsicInfo> IntrinsicMap,
|
static const NeonIntrinsicInfo *
|
||||||
unsigned BuiltinID, bool &MapProvenSorted) {
|
findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
|
||||||
|
unsigned BuiltinID, bool &MapProvenSorted) {
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (!MapProvenSorted) {
|
if (!MapProvenSorted) {
|
||||||
|
@ -5319,8 +5301,7 @@ findARMVectorIntrinsicInMap(ArrayRef<ARMVectorIntrinsicInfo> IntrinsicMap,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const ARMVectorIntrinsicInfo *Builtin =
|
const NeonIntrinsicInfo *Builtin = llvm::lower_bound(IntrinsicMap, BuiltinID);
|
||||||
llvm::lower_bound(IntrinsicMap, BuiltinID);
|
|
||||||
|
|
||||||
if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID)
|
if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID)
|
||||||
return Builtin;
|
return Builtin;
|
||||||
|
@ -5367,9 +5348,10 @@ Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
|
||||||
return CGM.getIntrinsic(IntrinsicID, Tys);
|
return CGM.getIntrinsic(IntrinsicID, Tys);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Value *EmitCommonNeonSISDBuiltinExpr(
|
static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF,
|
||||||
CodeGenFunction &CGF, const ARMVectorIntrinsicInfo &SISDInfo,
|
const NeonIntrinsicInfo &SISDInfo,
|
||||||
SmallVectorImpl<Value *> &Ops, const CallExpr *E) {
|
SmallVectorImpl<Value *> &Ops,
|
||||||
|
const CallExpr *E) {
|
||||||
unsigned BuiltinID = SISDInfo.BuiltinID;
|
unsigned BuiltinID = SISDInfo.BuiltinID;
|
||||||
unsigned int Int = SISDInfo.LLVMIntrinsic;
|
unsigned int Int = SISDInfo.LLVMIntrinsic;
|
||||||
unsigned Modifier = SISDInfo.TypeModifier;
|
unsigned Modifier = SISDInfo.TypeModifier;
|
||||||
|
@ -6882,7 +6864,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
|
||||||
// Many NEON builtins have identical semantics and uses in ARM and
|
// Many NEON builtins have identical semantics and uses in ARM and
|
||||||
// AArch64. Emit these in a single function.
|
// AArch64. Emit these in a single function.
|
||||||
auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap);
|
auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap);
|
||||||
const ARMVectorIntrinsicInfo *Builtin = findARMVectorIntrinsicInMap(
|
const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
|
||||||
IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
|
IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
|
||||||
if (Builtin)
|
if (Builtin)
|
||||||
return EmitCommonNeonBuiltinExpr(
|
return EmitCommonNeonBuiltinExpr(
|
||||||
|
@ -7454,40 +7436,9 @@ Value *CodeGenFunction::EmitSVEMaskedLoad(llvm::Type *ReturnTy,
|
||||||
return Builder.CreateMaskedLoad(BasePtr, Align(1), Predicate, Splat0);
|
return Builder.CreateMaskedLoad(BasePtr, Align(1), Predicate, Splat0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
|
|
||||||
const CallExpr *E) {
|
|
||||||
// Find out if any arguments are required to be integer constant expressions.
|
|
||||||
unsigned ICEArguments = 0;
|
|
||||||
ASTContext::GetBuiltinTypeError Error;
|
|
||||||
getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
|
|
||||||
assert(Error == ASTContext::GE_None && "Should not codegen an error");
|
|
||||||
|
|
||||||
llvm::SmallVector<Value *, 4> Ops;
|
|
||||||
for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
|
|
||||||
if ((ICEArguments & (1 << i)) == 0)
|
|
||||||
Ops.push_back(EmitScalarExpr(E->getArg(i)));
|
|
||||||
else
|
|
||||||
llvm_unreachable("Not yet implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *Builtin = findARMVectorIntrinsicInMap(AArch64SVEIntrinsicMap, BuiltinID,
|
|
||||||
AArch64SVEIntrinsicsProvenSorted);
|
|
||||||
SVETypeFlags TypeFlags(Builtin->TypeModifier);
|
|
||||||
llvm::Type *Ty = ConvertType(E->getType());
|
|
||||||
if (TypeFlags.isLoad())
|
|
||||||
return EmitSVEMaskedLoad(Ty, Ops);
|
|
||||||
|
|
||||||
/// Should not happen
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||||
const CallExpr *E,
|
const CallExpr *E,
|
||||||
llvm::Triple::ArchType Arch) {
|
llvm::Triple::ArchType Arch) {
|
||||||
if (BuiltinID >= AArch64::FirstSVEBuiltin &&
|
|
||||||
BuiltinID <= AArch64::LastSVEBuiltin)
|
|
||||||
return EmitAArch64SVEBuiltinExpr(BuiltinID, E);
|
|
||||||
|
|
||||||
unsigned HintID = static_cast<unsigned>(-1);
|
unsigned HintID = static_cast<unsigned>(-1);
|
||||||
switch (BuiltinID) {
|
switch (BuiltinID) {
|
||||||
default: break;
|
default: break;
|
||||||
|
@ -7521,6 +7472,27 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||||
return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
|
return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (BuiltinID) {
|
||||||
|
case AArch64::BI__builtin_sve_svld1_u8:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_u16:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_u32:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_u64:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_s8:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_s16:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_s32:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_s64:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_f16:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_f32:
|
||||||
|
case AArch64::BI__builtin_sve_svld1_f64: {
|
||||||
|
llvm::SmallVector<Value *, 4> Ops = {EmitScalarExpr(E->getArg(0)),
|
||||||
|
EmitScalarExpr(E->getArg(1))};
|
||||||
|
llvm::Type *Ty = ConvertType(E->getType());
|
||||||
|
return EmitSVEMaskedLoad(Ty, Ops);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
|
if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
|
||||||
Value *Address = EmitScalarExpr(E->getArg(0));
|
Value *Address = EmitScalarExpr(E->getArg(0));
|
||||||
Value *RW = EmitScalarExpr(E->getArg(1));
|
Value *RW = EmitScalarExpr(E->getArg(1));
|
||||||
|
@ -7919,7 +7891,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
|
auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
|
||||||
const ARMVectorIntrinsicInfo *Builtin = findARMVectorIntrinsicInMap(
|
const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
|
||||||
SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
|
SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
|
||||||
|
|
||||||
if (Builtin) {
|
if (Builtin) {
|
||||||
|
@ -8759,8 +8731,8 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||||
|
|
||||||
// Not all intrinsics handled by the common case work for AArch64 yet, so only
|
// Not all intrinsics handled by the common case work for AArch64 yet, so only
|
||||||
// defer to common code if it's been added to our special map.
|
// defer to common code if it's been added to our special map.
|
||||||
Builtin = findARMVectorIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID,
|
Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID,
|
||||||
AArch64SIMDIntrinsicsProvenSorted);
|
AArch64SIMDIntrinsicsProvenSorted);
|
||||||
|
|
||||||
if (Builtin)
|
if (Builtin)
|
||||||
return EmitCommonNeonBuiltinExpr(
|
return EmitCommonNeonBuiltinExpr(
|
||||||
|
|
|
@ -3904,7 +3904,6 @@ public:
|
||||||
llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred, llvm::VectorType *VTy);
|
llvm::Value *EmitSVEPredicateCast(llvm::Value *Pred, llvm::VectorType *VTy);
|
||||||
llvm::Value *EmitSVEMaskedLoad(llvm::Type *ReturnTy,
|
llvm::Value *EmitSVEMaskedLoad(llvm::Type *ReturnTy,
|
||||||
SmallVectorImpl<llvm::Value *> &Ops);
|
SmallVectorImpl<llvm::Value *> &Ops);
|
||||||
llvm::Value *EmitAArch64SVEBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
|
|
||||||
|
|
||||||
llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
|
llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E,
|
||||||
llvm::Triple::ArchType Arch);
|
llvm::Triple::ArchType Arch);
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/TableGen/Record.h"
|
#include "llvm/TableGen/Record.h"
|
||||||
#include "llvm/TableGen/Error.h"
|
#include "llvm/TableGen/Error.h"
|
||||||
#include "clang/Basic/AArch64SVETypeFlags.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -37,535 +36,26 @@
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
enum ClassKind {
|
//===----------------------------------------------------------------------===//
|
||||||
ClassNone,
|
// SVEEmitter
|
||||||
ClassS, // signed/unsigned, e.g., "_s8", "_u8" suffix
|
//===----------------------------------------------------------------------===//
|
||||||
ClassG, // Overloaded name without type suffix
|
|
||||||
};
|
|
||||||
|
|
||||||
using TypeSpec = std::string;
|
|
||||||
using SVETypeFlags = clang::SVETypeFlags;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class SVEType {
|
|
||||||
TypeSpec TS;
|
|
||||||
bool Float, Signed, Immediate, Void, Constant, Pointer;
|
|
||||||
bool DefaultType, IsScalable, Predicate, PredicatePattern, PrefetchOp;
|
|
||||||
unsigned Bitwidth, ElementBitwidth, NumVectors;
|
|
||||||
|
|
||||||
public:
|
|
||||||
SVEType() : SVEType(TypeSpec(), 'v') {}
|
|
||||||
|
|
||||||
SVEType(TypeSpec TS, char CharMod)
|
|
||||||
: TS(TS), Float(false), Signed(true), Immediate(false), Void(false),
|
|
||||||
Constant(false), Pointer(false), DefaultType(false), IsScalable(true),
|
|
||||||
Predicate(false), PredicatePattern(false), PrefetchOp(false),
|
|
||||||
Bitwidth(128), ElementBitwidth(~0U), NumVectors(1) {
|
|
||||||
if (!TS.empty())
|
|
||||||
applyTypespec();
|
|
||||||
applyModifier(CharMod);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the value in SVETypeFlags for this type.
|
|
||||||
unsigned getTypeFlags() const;
|
|
||||||
|
|
||||||
bool isPointer() const { return Pointer; }
|
|
||||||
bool isVoidPointer() const { return Pointer && Void; }
|
|
||||||
bool isSigned() const { return Signed; }
|
|
||||||
bool isImmediate() const { return Immediate; }
|
|
||||||
bool isScalar() const { return NumVectors == 0; }
|
|
||||||
bool isVector() const { return NumVectors > 0; }
|
|
||||||
bool isScalableVector() const { return isVector() && IsScalable; }
|
|
||||||
bool isChar() const { return ElementBitwidth == 8; }
|
|
||||||
bool isVoid() const { return Void & !Pointer; }
|
|
||||||
bool isDefault() const { return DefaultType; }
|
|
||||||
bool isFloat() const { return Float; }
|
|
||||||
bool isInteger() const { return !Float && !Predicate; }
|
|
||||||
bool isScalarPredicate() const { return !Float && ElementBitwidth == 1; }
|
|
||||||
bool isPredicateVector() const { return Predicate; }
|
|
||||||
bool isPredicatePattern() const { return PredicatePattern; }
|
|
||||||
bool isPrefetchOp() const { return PrefetchOp; }
|
|
||||||
bool isConstant() const { return Constant; }
|
|
||||||
unsigned getElementSizeInBits() const { return ElementBitwidth; }
|
|
||||||
unsigned getNumVectors() const { return NumVectors; }
|
|
||||||
|
|
||||||
unsigned getNumElements() const {
|
|
||||||
assert(ElementBitwidth != ~0U);
|
|
||||||
return Bitwidth / ElementBitwidth;
|
|
||||||
}
|
|
||||||
unsigned getSizeInBits() const {
|
|
||||||
return Bitwidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the string representation of a type, which is an encoded
|
|
||||||
/// string for passing to the BUILTIN() macro in Builtins.def.
|
|
||||||
std::string builtin_str() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/// Creates the type based on the typespec string in TS.
|
|
||||||
void applyTypespec();
|
|
||||||
|
|
||||||
/// Applies a prototype modifier to the type.
|
|
||||||
void applyModifier(char Mod);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class SVEEmitter;
|
|
||||||
|
|
||||||
/// The main grunt class. This represents an instantiation of an intrinsic with
|
|
||||||
/// a particular typespec and prototype.
|
|
||||||
class Intrinsic {
|
|
||||||
/// The unmangled name.
|
|
||||||
std::string Name;
|
|
||||||
|
|
||||||
/// The name of the corresponding LLVM IR intrinsic.
|
|
||||||
std::string LLVMName;
|
|
||||||
|
|
||||||
/// Intrinsic prototype.
|
|
||||||
std::string Proto;
|
|
||||||
|
|
||||||
/// The base type spec for this intrinsic.
|
|
||||||
TypeSpec BaseTypeSpec;
|
|
||||||
|
|
||||||
/// The base class kind. Most intrinsics use ClassS, which has full type
|
|
||||||
/// info for integers (_s32/_u32), or ClassG which is used for overloaded
|
|
||||||
/// intrinsics.
|
|
||||||
ClassKind Class;
|
|
||||||
|
|
||||||
/// The architectural #ifdef guard.
|
|
||||||
std::string Guard;
|
|
||||||
|
|
||||||
/// The types of return value [0] and parameters [1..].
|
|
||||||
std::vector<SVEType> Types;
|
|
||||||
|
|
||||||
/// The "base type", which is VarType('d', BaseTypeSpec).
|
|
||||||
SVEType BaseType;
|
|
||||||
|
|
||||||
/// The type of the memory element
|
|
||||||
enum MemEltType {
|
|
||||||
MemEltTypeDefault,
|
|
||||||
MemEltTypeInt8,
|
|
||||||
MemEltTypeInt16,
|
|
||||||
MemEltTypeInt32,
|
|
||||||
MemEltTypeInt64,
|
|
||||||
MemEltTypeInvalid
|
|
||||||
} MemEltTy;
|
|
||||||
|
|
||||||
SVETypeFlags Flags;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// The type of predication.
|
|
||||||
enum MergeType {
|
|
||||||
MergeNone,
|
|
||||||
MergeAny,
|
|
||||||
MergeOp1,
|
|
||||||
MergeZero,
|
|
||||||
MergeAnyExp,
|
|
||||||
MergeZeroExp,
|
|
||||||
MergeInvalid
|
|
||||||
} Merge;
|
|
||||||
|
|
||||||
Intrinsic(StringRef Name, StringRef Proto, int64_t MT, int64_t MET,
|
|
||||||
StringRef LLVMName, SVETypeFlags Flags, TypeSpec BT, ClassKind Class,
|
|
||||||
SVEEmitter &Emitter, StringRef Guard)
|
|
||||||
: Name(Name.str()), LLVMName(LLVMName), Proto(Proto.str()),
|
|
||||||
BaseTypeSpec(BT), Class(Class), Guard(Guard.str()), BaseType(BT, 'd'),
|
|
||||||
MemEltTy(MemEltType(MET)), Flags(Flags), Merge(MergeType(MT)) {
|
|
||||||
// Types[0] is the return value.
|
|
||||||
for (unsigned I = 0; I < Proto.size(); ++I)
|
|
||||||
Types.emplace_back(BaseTypeSpec, Proto[I]);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Intrinsic()=default;
|
|
||||||
|
|
||||||
std::string getName() const { return Name; }
|
|
||||||
std::string getLLVMName() const { return LLVMName; }
|
|
||||||
std::string getProto() const { return Proto; }
|
|
||||||
TypeSpec getBaseTypeSpec() const { return BaseTypeSpec; }
|
|
||||||
SVEType getBaseType() const { return BaseType; }
|
|
||||||
|
|
||||||
StringRef getGuard() const { return Guard; }
|
|
||||||
ClassKind getClassKind() const { return Class; }
|
|
||||||
MergeType getMergeType() const { return Merge; }
|
|
||||||
|
|
||||||
SVEType getReturnType() const { return Types[0]; }
|
|
||||||
ArrayRef<SVEType> getTypes() const { return Types; }
|
|
||||||
SVEType getParamType(unsigned I) const { return Types[I + 1]; }
|
|
||||||
unsigned getNumParams() const { return Proto.size() - 1; }
|
|
||||||
|
|
||||||
SVETypeFlags getFlags() const { return Flags; }
|
|
||||||
bool isFlagSet(uint64_t Flag) const { return Flags.isFlagSet(Flag);}
|
|
||||||
|
|
||||||
int64_t getMemEltTypeEnum() const {
|
|
||||||
int64_t METEnum = (MemEltTy << SVETypeFlags::MemEltTypeOffset);
|
|
||||||
assert((METEnum &~ SVETypeFlags::MemEltTypeMask) == 0 && "Bad MemEltTy");
|
|
||||||
return METEnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the type string for a BUILTIN() macro in Builtins.def.
|
|
||||||
std::string getBuiltinTypeStr();
|
|
||||||
|
|
||||||
/// Return the name, mangled with type information. The name is mangled for
|
|
||||||
/// ClassS, so will add type suffixes such as _u32/_s32.
|
|
||||||
std::string getMangledName() const { return mangleName(ClassS); }
|
|
||||||
|
|
||||||
/// Returns true if the intrinsic is overloaded, in that it should also generate
|
|
||||||
/// a short form without the type-specifiers, e.g. 'svld1(..)' instead of
|
|
||||||
/// 'svld1_u32(..)'.
|
|
||||||
static bool isOverloadedIntrinsic(StringRef Name) {
|
|
||||||
auto BrOpen = Name.find("[");
|
|
||||||
auto BrClose = Name.find(']');
|
|
||||||
return BrOpen != std::string::npos && BrClose != std::string::npos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Emits the intrinsic declaration to the ostream.
|
|
||||||
void emitIntrinsic(raw_ostream &OS) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string getMergeSuffix() const;
|
|
||||||
std::string mangleName(ClassKind LocalCK) const;
|
|
||||||
std::string replaceTemplatedArgs(std::string Name, TypeSpec TS,
|
|
||||||
std::string Proto) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SVEEmitter {
|
class SVEEmitter {
|
||||||
private:
|
|
||||||
RecordKeeper &Records;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SVEEmitter(RecordKeeper &R) : Records(R) {}
|
// run - Emit arm_sve.h
|
||||||
|
void run(raw_ostream &o);
|
||||||
/// Emit arm_sve.h.
|
|
||||||
void createHeader(raw_ostream &o);
|
|
||||||
|
|
||||||
/// Emit all the __builtin prototypes and code needed by Sema.
|
|
||||||
void createBuiltins(raw_ostream &o);
|
|
||||||
|
|
||||||
/// Emit all the information needed to map builtin -> LLVM IR intrinsic.
|
|
||||||
void createCodeGenMap(raw_ostream &o);
|
|
||||||
|
|
||||||
/// Create intrinsic and add it to \p Out
|
|
||||||
void createIntrinsic(Record *R, SmallVectorImpl<std::unique_ptr<Intrinsic>> &Out);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Type implementation
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
unsigned SVEType::getTypeFlags() const {
|
|
||||||
if (isFloat()) {
|
|
||||||
switch (ElementBitwidth) {
|
|
||||||
case 16: return SVETypeFlags::Float16;
|
|
||||||
case 32: return SVETypeFlags::Float32;
|
|
||||||
case 64: return SVETypeFlags::Float64;
|
|
||||||
default: llvm_unreachable("Unhandled float element bitwidth!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isPredicateVector()) {
|
|
||||||
switch (ElementBitwidth) {
|
|
||||||
case 8: return SVETypeFlags::Bool8;
|
|
||||||
case 16: return SVETypeFlags::Bool16;
|
|
||||||
case 32: return SVETypeFlags::Bool32;
|
|
||||||
case 64: return SVETypeFlags::Bool64;
|
|
||||||
default: llvm_unreachable("Unhandled predicate element bitwidth!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ElementBitwidth) {
|
|
||||||
case 8: return SVETypeFlags::Int8;
|
|
||||||
case 16: return SVETypeFlags::Int16;
|
|
||||||
case 32: return SVETypeFlags::Int32;
|
|
||||||
case 64: return SVETypeFlags::Int64;
|
|
||||||
default: llvm_unreachable("Unhandled integer element bitwidth!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string SVEType::builtin_str() const {
|
|
||||||
std::string S;
|
|
||||||
if (isVoid())
|
|
||||||
return "v";
|
|
||||||
|
|
||||||
if (isVoidPointer())
|
|
||||||
S += "v";
|
|
||||||
else if (!Float)
|
|
||||||
switch (ElementBitwidth) {
|
|
||||||
case 1: S += "b"; break;
|
|
||||||
case 8: S += "c"; break;
|
|
||||||
case 16: S += "s"; break;
|
|
||||||
case 32: S += "i"; break;
|
|
||||||
case 64: S += "Wi"; break;
|
|
||||||
case 128: S += "LLLi"; break;
|
|
||||||
default: llvm_unreachable("Unhandled case!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
switch (ElementBitwidth) {
|
|
||||||
case 16: S += "h"; break;
|
|
||||||
case 32: S += "f"; break;
|
|
||||||
case 64: S += "d"; break;
|
|
||||||
default: llvm_unreachable("Unhandled case!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isFloat()) {
|
|
||||||
if ((isChar() || isPointer()) && !isVoidPointer()) {
|
|
||||||
// Make chars and typed pointers explicitly signed.
|
|
||||||
if (Signed)
|
|
||||||
S = "S" + S;
|
|
||||||
else if (!Signed)
|
|
||||||
S = "U" + S;
|
|
||||||
} else if (!isVoidPointer() && !Signed) {
|
|
||||||
S = "U" + S;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constant indices are "int", but have the "constant expression" modifier.
|
|
||||||
if (isImmediate()) {
|
|
||||||
assert(!isFloat() && "fp immediates are not supported");
|
|
||||||
S = "I" + S;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isScalar()) {
|
|
||||||
if (Constant) S += "C";
|
|
||||||
if (Pointer) S += "*";
|
|
||||||
return S;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(isScalableVector() && "Unsupported type");
|
|
||||||
return "q" + utostr(getNumElements() * NumVectors) + S;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SVEType::applyTypespec() {
|
|
||||||
for (char I : TS) {
|
|
||||||
switch (I) {
|
|
||||||
case 'P':
|
|
||||||
Predicate = true;
|
|
||||||
ElementBitwidth = 1;
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
Signed = false;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
ElementBitwidth = 8;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
ElementBitwidth = 16;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
ElementBitwidth = 32;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
ElementBitwidth = 64;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
Float = true;
|
|
||||||
ElementBitwidth = 16;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
Float = true;
|
|
||||||
ElementBitwidth = 32;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
Float = true;
|
|
||||||
ElementBitwidth = 64;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
llvm_unreachable("Unhandled type code!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert(ElementBitwidth != ~0U && "Bad element bitwidth!");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SVEType::applyModifier(char Mod) {
|
|
||||||
switch (Mod) {
|
|
||||||
case 'v':
|
|
||||||
Void = true;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
DefaultType = true;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
Constant = true;
|
|
||||||
LLVM_FALLTHROUGH;
|
|
||||||
case 'p':
|
|
||||||
Pointer = true;
|
|
||||||
Bitwidth = ElementBitwidth;
|
|
||||||
NumVectors = 0;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
Signed = true;
|
|
||||||
Float = false;
|
|
||||||
Predicate = true;
|
|
||||||
Bitwidth = 16;
|
|
||||||
ElementBitwidth = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
llvm_unreachable("Unhandled character!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// Intrinsic implementation
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
std::string Intrinsic::getBuiltinTypeStr() {
|
|
||||||
std::string S;
|
|
||||||
|
|
||||||
SVEType RetT = getReturnType();
|
|
||||||
// Since the return value must be one type, return a vector type of the
|
|
||||||
// appropriate width which we will bitcast. An exception is made for
|
|
||||||
// returning structs of 2, 3, or 4 vectors which are returned in a sret-like
|
|
||||||
// fashion, storing them to a pointer arg.
|
|
||||||
if (RetT.getNumVectors() > 1) {
|
|
||||||
S += "vv*"; // void result with void* first argument
|
|
||||||
} else
|
|
||||||
S += RetT.builtin_str();
|
|
||||||
|
|
||||||
for (unsigned I = 0; I < getNumParams(); ++I)
|
|
||||||
S += getParamType(I).builtin_str();
|
|
||||||
|
|
||||||
return S;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Intrinsic::replaceTemplatedArgs(std::string Name, TypeSpec TS,
|
|
||||||
std::string Proto) const {
|
|
||||||
std::string Ret = Name;
|
|
||||||
while (Ret.find('{') != std::string::npos) {
|
|
||||||
size_t Pos = Ret.find('{');
|
|
||||||
size_t End = Ret.find('}');
|
|
||||||
unsigned NumChars = End - Pos + 1;
|
|
||||||
assert(NumChars == 3 && "Unexpected template argument");
|
|
||||||
|
|
||||||
SVEType T;
|
|
||||||
char C = Ret[Pos+1];
|
|
||||||
switch(C) {
|
|
||||||
default:
|
|
||||||
llvm_unreachable("Unknown predication specifier");
|
|
||||||
case 'd':
|
|
||||||
T = SVEType(TS, 'd');
|
|
||||||
break;
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
T = SVEType(TS, Proto[C - '0']);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace templated arg with the right suffix (e.g. u32)
|
|
||||||
std::string TypeCode;
|
|
||||||
if (T.isInteger())
|
|
||||||
TypeCode = T.isSigned() ? 's' : 'u';
|
|
||||||
else if (T.isPredicateVector())
|
|
||||||
TypeCode = 'b';
|
|
||||||
else
|
|
||||||
TypeCode = 'f';
|
|
||||||
Ret.replace(Pos, NumChars, TypeCode + utostr(T.getElementSizeInBits()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ACLE function names have a merge style postfix.
|
|
||||||
std::string Intrinsic::getMergeSuffix() const {
|
|
||||||
switch (getMergeType()) {
|
|
||||||
default:
|
|
||||||
llvm_unreachable("Unknown predication specifier");
|
|
||||||
case MergeNone: return "";
|
|
||||||
case MergeAny:
|
|
||||||
case MergeAnyExp: return "_x";
|
|
||||||
case MergeOp1: return "_m";
|
|
||||||
case MergeZero:
|
|
||||||
case MergeZeroExp: return "_z";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Intrinsic::mangleName(ClassKind LocalCK) const {
|
|
||||||
std::string S = getName();
|
|
||||||
|
|
||||||
if (LocalCK == ClassG) {
|
|
||||||
// Remove the square brackets and everything in between.
|
|
||||||
while (S.find("[") != std::string::npos) {
|
|
||||||
auto Start = S.find("[");
|
|
||||||
auto End = S.find(']');
|
|
||||||
S.erase(Start, (End-Start)+1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Remove the square brackets.
|
|
||||||
while (S.find("[") != std::string::npos) {
|
|
||||||
auto BrPos = S.find('[');
|
|
||||||
if (BrPos != std::string::npos)
|
|
||||||
S.erase(BrPos, 1);
|
|
||||||
BrPos = S.find(']');
|
|
||||||
if (BrPos != std::string::npos)
|
|
||||||
S.erase(BrPos, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace all {d} like expressions with e.g. 'u32'
|
|
||||||
return replaceTemplatedArgs(S, getBaseTypeSpec(), getProto()) +
|
|
||||||
getMergeSuffix();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Intrinsic::emitIntrinsic(raw_ostream &OS) const {
|
|
||||||
// Use the preprocessor to enable the non-overloaded builtins.
|
|
||||||
if (getClassKind() != ClassG || getProto().size() <= 1) {
|
|
||||||
OS << "#define " << mangleName(getClassKind())
|
|
||||||
<< "(...) __builtin_sve_" << mangleName(ClassS)
|
|
||||||
<< "(__VA_ARGS__)\n";
|
|
||||||
} else {
|
|
||||||
llvm_unreachable("Not yet implemented. Overloaded intrinsics will follow "
|
|
||||||
"in a future patch");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// SVEEmitter implementation
|
// SVEEmitter implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
void SVEEmitter::createIntrinsic(
|
|
||||||
Record *R, SmallVectorImpl<std::unique_ptr<Intrinsic>> &Out) {
|
|
||||||
StringRef Name = R->getValueAsString("Name");
|
|
||||||
StringRef Proto = R->getValueAsString("Prototype");
|
|
||||||
StringRef Types = R->getValueAsString("Types");
|
|
||||||
StringRef Guard = R->getValueAsString("ArchGuard");
|
|
||||||
StringRef LLVMName = R->getValueAsString("LLVMIntrinsic");
|
|
||||||
int64_t Merge = R->getValueAsInt("Merge");
|
|
||||||
std::vector<Record*> FlagsList = R->getValueAsListOfDefs("Flags");
|
|
||||||
int64_t MemEltType = R->getValueAsInt("MemEltType");
|
|
||||||
|
|
||||||
int64_t Flags = 0;
|
void SVEEmitter::run(raw_ostream &OS) {
|
||||||
for (auto FlagRec : FlagsList)
|
|
||||||
Flags |= FlagRec->getValueAsInt("Value");
|
|
||||||
|
|
||||||
// Extract type specs from string
|
|
||||||
SmallVector<TypeSpec, 8> TypeSpecs;
|
|
||||||
TypeSpec Acc;
|
|
||||||
for (char I : Types) {
|
|
||||||
Acc.push_back(I);
|
|
||||||
if (islower(I)) {
|
|
||||||
TypeSpecs.push_back(TypeSpec(Acc));
|
|
||||||
Acc.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove duplicate type specs.
|
|
||||||
std::sort(TypeSpecs.begin(), TypeSpecs.end());
|
|
||||||
TypeSpecs.erase(std::unique(TypeSpecs.begin(), TypeSpecs.end()),
|
|
||||||
TypeSpecs.end());
|
|
||||||
|
|
||||||
// Create an Intrinsic for each type spec.
|
|
||||||
for (auto TS : TypeSpecs) {
|
|
||||||
Out.push_back(std::make_unique<Intrinsic>(Name, Proto, Merge, MemEltType,
|
|
||||||
LLVMName, Flags, TS, ClassS,
|
|
||||||
*this, Guard));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SVEEmitter::createHeader(raw_ostream &OS) {
|
|
||||||
OS << "/*===---- arm_sve.h - ARM SVE intrinsics "
|
OS << "/*===---- arm_sve.h - ARM SVE intrinsics "
|
||||||
"-----------------------------------===\n"
|
"-----------------------------------===\n"
|
||||||
" *\n"
|
" *\n"
|
||||||
|
@ -587,9 +77,7 @@ void SVEEmitter::createHeader(raw_ostream &OS) {
|
||||||
OS << "#else\n\n";
|
OS << "#else\n\n";
|
||||||
|
|
||||||
OS << "#include <stdint.h>\n\n";
|
OS << "#include <stdint.h>\n\n";
|
||||||
OS << "#ifdef __cplusplus\n";
|
OS << "#ifndef __cplusplus\n";
|
||||||
OS << "extern \"C\" {\n";
|
|
||||||
OS << "#else\n";
|
|
||||||
OS << "#include <stdbool.h>\n";
|
OS << "#include <stdbool.h>\n";
|
||||||
OS << "#endif\n\n";
|
OS << "#endif\n\n";
|
||||||
|
|
||||||
|
@ -611,120 +99,25 @@ void SVEEmitter::createHeader(raw_ostream &OS) {
|
||||||
OS << "typedef __SVFloat64_t svfloat64_t;\n";
|
OS << "typedef __SVFloat64_t svfloat64_t;\n";
|
||||||
OS << "typedef __SVBool_t svbool_t;\n\n";
|
OS << "typedef __SVBool_t svbool_t;\n\n";
|
||||||
|
|
||||||
SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
|
OS << "#define svld1_u8(...) __builtin_sve_svld1_u8(__VA_ARGS__)\n";
|
||||||
std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
|
OS << "#define svld1_u16(...) __builtin_sve_svld1_u16(__VA_ARGS__)\n";
|
||||||
for (auto *R : RV)
|
OS << "#define svld1_u32(...) __builtin_sve_svld1_u32(__VA_ARGS__)\n";
|
||||||
createIntrinsic(R, Defs);
|
OS << "#define svld1_u64(...) __builtin_sve_svld1_u64(__VA_ARGS__)\n";
|
||||||
|
OS << "#define svld1_s8(...) __builtin_sve_svld1_s8(__VA_ARGS__)\n";
|
||||||
|
OS << "#define svld1_s16(...) __builtin_sve_svld1_s16(__VA_ARGS__)\n";
|
||||||
|
OS << "#define svld1_s32(...) __builtin_sve_svld1_s32(__VA_ARGS__)\n";
|
||||||
|
OS << "#define svld1_s64(...) __builtin_sve_svld1_s64(__VA_ARGS__)\n";
|
||||||
|
OS << "#define svld1_f16(...) __builtin_sve_svld1_f16(__VA_ARGS__)\n";
|
||||||
|
OS << "#define svld1_f32(...) __builtin_sve_svld1_f32(__VA_ARGS__)\n";
|
||||||
|
OS << "#define svld1_f64(...) __builtin_sve_svld1_f64(__VA_ARGS__)\n";
|
||||||
|
|
||||||
// Sort intrinsics in header file by following order/priority:
|
OS << "#endif /*__ARM_FEATURE_SVE */\n";
|
||||||
// - Architectural guard (i.e. does it require SVE2 or SVE2_AES)
|
|
||||||
// - Class (is intrinsic overloaded or not)
|
|
||||||
// - Intrinsic name
|
|
||||||
std::stable_sort(
|
|
||||||
Defs.begin(), Defs.end(), [](const std::unique_ptr<Intrinsic> &A,
|
|
||||||
const std::unique_ptr<Intrinsic> &B) {
|
|
||||||
return A->getGuard() < B->getGuard() ||
|
|
||||||
(unsigned)A->getClassKind() < (unsigned)B->getClassKind() ||
|
|
||||||
A->getName() < B->getName();
|
|
||||||
});
|
|
||||||
|
|
||||||
StringRef InGuard = "";
|
|
||||||
for (auto &I : Defs) {
|
|
||||||
// Emit #endif/#if pair if needed.
|
|
||||||
if (I->getGuard() != InGuard) {
|
|
||||||
if (!InGuard.empty())
|
|
||||||
OS << "#endif //" << InGuard << "\n";
|
|
||||||
InGuard = I->getGuard();
|
|
||||||
if (!InGuard.empty())
|
|
||||||
OS << "\n#if " << InGuard << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually emit the intrinsic declaration.
|
|
||||||
I->emitIntrinsic(OS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!InGuard.empty())
|
|
||||||
OS << "#endif //" << InGuard << "\n";
|
|
||||||
|
|
||||||
OS << "#ifdef __cplusplus\n";
|
|
||||||
OS << "} // extern \"C\"\n";
|
|
||||||
OS << "#endif\n\n";
|
|
||||||
OS << "#endif /*__ARM_FEATURE_SVE */\n\n";
|
|
||||||
OS << "#endif /* __ARM_SVE_H */\n";
|
OS << "#endif /* __ARM_SVE_H */\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVEEmitter::createBuiltins(raw_ostream &OS) {
|
|
||||||
std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
|
|
||||||
SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
|
|
||||||
for (auto *R : RV)
|
|
||||||
createIntrinsic(R, Defs);
|
|
||||||
|
|
||||||
// The mappings must be sorted based on BuiltinID.
|
|
||||||
llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
|
|
||||||
const std::unique_ptr<Intrinsic> &B) {
|
|
||||||
return A->getMangledName() < B->getMangledName();
|
|
||||||
});
|
|
||||||
|
|
||||||
OS << "#ifdef GET_SVE_BUILTINS\n";
|
|
||||||
for (auto &Def : Defs) {
|
|
||||||
// Only create BUILTINs for non-overloaded intrinsics, as overloaded
|
|
||||||
// declarations only live in the header file.
|
|
||||||
if (Def->getClassKind() != ClassG)
|
|
||||||
OS << "BUILTIN(__builtin_sve_" << Def->getMangledName() << ", \""
|
|
||||||
<< Def->getBuiltinTypeStr() << "\", \"n\")\n";
|
|
||||||
}
|
|
||||||
OS << "#endif\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void SVEEmitter::createCodeGenMap(raw_ostream &OS) {
|
|
||||||
std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
|
|
||||||
SmallVector<std::unique_ptr<Intrinsic>, 128> Defs;
|
|
||||||
for (auto *R : RV)
|
|
||||||
createIntrinsic(R, Defs);
|
|
||||||
|
|
||||||
// The mappings must be sorted based on BuiltinID.
|
|
||||||
llvm::sort(Defs, [](const std::unique_ptr<Intrinsic> &A,
|
|
||||||
const std::unique_ptr<Intrinsic> &B) {
|
|
||||||
return A->getMangledName() < B->getMangledName();
|
|
||||||
});
|
|
||||||
|
|
||||||
OS << "#ifdef GET_SVE_LLVM_INTRINSIC_MAP\n";
|
|
||||||
for (auto &Def : Defs) {
|
|
||||||
// Builtins only exist for non-overloaded intrinsics, overloaded
|
|
||||||
// declarations only live in the header file.
|
|
||||||
if (Def->getClassKind() == ClassG)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
assert(!Def->isFlagSet(SVETypeFlags::EltTypeMask) &&
|
|
||||||
!Def->isFlagSet(SVETypeFlags::MemEltTypeMask) &&
|
|
||||||
"Unexpected mask value");
|
|
||||||
uint64_t Flags = Def->getFlags().getBits() |
|
|
||||||
Def->getBaseType().getTypeFlags() |
|
|
||||||
Def->getMemEltTypeEnum();
|
|
||||||
auto FlagString = std::to_string(Flags);
|
|
||||||
|
|
||||||
std::string LLVMName = Def->getLLVMName();
|
|
||||||
std::string Builtin = Def->getMangledName();
|
|
||||||
if (!LLVMName.empty())
|
|
||||||
OS << "SVEMAP1(" << Builtin << ", " << LLVMName << ", " << FlagString
|
|
||||||
<< "),\n";
|
|
||||||
else
|
|
||||||
OS << "SVEMAP2(" << Builtin << ", " << FlagString << "),\n";
|
|
||||||
}
|
|
||||||
OS << "#endif\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) {
|
void EmitSveHeader(RecordKeeper &Records, raw_ostream &OS) {
|
||||||
SVEEmitter(Records).createHeader(OS);
|
SVEEmitter().run(OS);
|
||||||
}
|
|
||||||
|
|
||||||
void EmitSveBuiltins(RecordKeeper &Records, raw_ostream &OS) {
|
|
||||||
SVEEmitter(Records).createBuiltins(OS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitSveCodeGenMap(RecordKeeper &Records, raw_ostream &OS) {
|
|
||||||
SVEEmitter(Records).createCodeGenMap(OS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End namespace clang
|
} // End namespace clang
|
||||||
|
|
|
@ -71,8 +71,6 @@ enum ActionType {
|
||||||
GenArmMveBuiltinCG,
|
GenArmMveBuiltinCG,
|
||||||
GenArmMveBuiltinAliases,
|
GenArmMveBuiltinAliases,
|
||||||
GenArmSveHeader,
|
GenArmSveHeader,
|
||||||
GenArmSveBuiltins,
|
|
||||||
GenArmSveCodeGenMap,
|
|
||||||
GenArmCdeHeader,
|
GenArmCdeHeader,
|
||||||
GenArmCdeBuiltinDef,
|
GenArmCdeBuiltinDef,
|
||||||
GenArmCdeBuiltinSema,
|
GenArmCdeBuiltinSema,
|
||||||
|
@ -190,10 +188,6 @@ cl::opt<ActionType> Action(
|
||||||
"Generate ARM NEON tests for clang"),
|
"Generate ARM NEON tests for clang"),
|
||||||
clEnumValN(GenArmSveHeader, "gen-arm-sve-header",
|
clEnumValN(GenArmSveHeader, "gen-arm-sve-header",
|
||||||
"Generate arm_sve.h for clang"),
|
"Generate arm_sve.h for clang"),
|
||||||
clEnumValN(GenArmSveBuiltins, "gen-arm-sve-builtins",
|
|
||||||
"Generate arm_sve_builtins.inc for clang"),
|
|
||||||
clEnumValN(GenArmSveCodeGenMap, "gen-arm-sve-codegenmap",
|
|
||||||
"Generate arm_sve_codegenmap.inc for clang"),
|
|
||||||
clEnumValN(GenArmMveHeader, "gen-arm-mve-header",
|
clEnumValN(GenArmMveHeader, "gen-arm-mve-header",
|
||||||
"Generate arm_mve.h for clang"),
|
"Generate arm_mve.h for clang"),
|
||||||
clEnumValN(GenArmMveBuiltinDef, "gen-arm-mve-builtin-def",
|
clEnumValN(GenArmMveBuiltinDef, "gen-arm-mve-builtin-def",
|
||||||
|
@ -378,12 +372,6 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
|
||||||
case GenArmSveHeader:
|
case GenArmSveHeader:
|
||||||
EmitSveHeader(Records, OS);
|
EmitSveHeader(Records, OS);
|
||||||
break;
|
break;
|
||||||
case GenArmSveBuiltins:
|
|
||||||
EmitSveBuiltins(Records, OS);
|
|
||||||
break;
|
|
||||||
case GenArmSveCodeGenMap:
|
|
||||||
EmitSveCodeGenMap(Records, OS);
|
|
||||||
break;
|
|
||||||
case GenArmCdeHeader:
|
case GenArmCdeHeader:
|
||||||
EmitCdeHeader(Records, OS);
|
EmitCdeHeader(Records, OS);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -92,8 +92,6 @@ void EmitNeonSema2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
||||||
void EmitNeonTest2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
void EmitNeonTest2(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
||||||
|
|
||||||
void EmitSveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
void EmitSveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
||||||
void EmitSveBuiltins(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
|
||||||
void EmitSveCodeGenMap(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
|
||||||
|
|
||||||
void EmitMveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
void EmitMveHeader(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
||||||
void EmitMveBuiltinDef(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
void EmitMveBuiltinDef(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
|
||||||
|
|
Loading…
Reference in New Issue