1//===--- arm_sve_sme_incl.td - ARM SVE/SME compiler interface -------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file defines common properites of TableGen definitions use for both 10// SVE and SME intrinsics. 11// 12// https://developer.arm.com/architectures/system-architectures/software-standards/acle 13// 14//===----------------------------------------------------------------------===// 15 16//===----------------------------------------------------------------------===// 17// Instruction definitions 18//===----------------------------------------------------------------------===// 19// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and 20// a sequence of typespecs. 21// 22// The name is the base name of the intrinsic, for example "svld1". This is 23// then mangled by the tblgen backend to add type information ("svld1_s16"). 24// 25// A typespec is a sequence of uppercase characters (modifiers) followed by one 26// lowercase character. A typespec encodes a particular "base type" of the 27// intrinsic. 28// 29// An example typespec is "Us" - unsigned short - svuint16_t. The available 30// typespec codes are given below. 31// 32// The string given to an Inst class is a sequence of typespecs. The intrinsic 33// is instantiated for every typespec in the sequence. For example "sdUsUd". 34// 35// The prototype is a string that defines the return type of the intrinsic 36// and the type of each argument. The return type and every argument gets a 37// "modifier" that can change in some way the "base type" of the intrinsic. 38// 39// The modifier 'd' means "default" and does not modify the base type in any 40// way. The available modifiers are given below. 41// 42// Typespecs 43// --------- 44// c: char 45// s: short 46// i: int 47// l: long 48// q: int128_t 49// f: float 50// h: half-float 51// d: double 52// b: bfloat 53 54// Typespec modifiers 55// ------------------ 56// P: boolean 57// U: unsigned 58// Q: svcount 59 60// Prototype modifiers 61// ------------------- 62// prototype: return (arg, arg, ...) 63// 64// 2,3,4: array of default vectors 65// v: void 66// x: vector of signed integers 67// u: vector of unsigned integers 68// d: default 69// c: const pointer type 70// P: predicate type 71// s: scalar of element type 72// a: scalar of element type (splat to vector type) 73// R: scalar of 1/2 width element type (splat to vector type) 74// r: scalar of 1/4 width element type (splat to vector type) 75// @: unsigned scalar of 1/4 width element type (splat to vector type) 76// e: 1/2 width unsigned elements, 2x element count 77// b: 1/4 width unsigned elements, 4x element count 78// h: 1/2 width elements, 2x element count 79// q: 1/4 width elements, 4x element count 80// o: 4x width elements, 1/4 element count 81// 82// w: vector of element type promoted to 64bits, vector maintains 83// signedness of its element type. 84// f: element type promoted to uint64_t (splat to vector type) 85// j: element type promoted to 64bits (splat to vector type) 86// K: element type bitcast to a signed integer (splat to vector type) 87// L: element type bitcast to an unsigned integer (splat to vector type) 88// 89// i: constant uint64_t 90// k: int32_t 91// l: int64_t 92// m: uint32_t 93// n: uint64_t 94 95// t: svint32_t 96// z: svuint32_t 97// g: svuint64_t 98// O: svfloat16_t 99// M: svfloat32_t 100// N: svfloat64_t 101 102// J: Prefetch type (sv_prfop) 103 104// %: pointer to void 105 106// A: pointer to int8_t 107// B: pointer to int16_t 108// C: pointer to int32_t 109// D: pointer to int64_t 110 111// E: pointer to uint8_t 112// F: pointer to uint16_t 113// G: pointer to uint32_t 114// H: pointer to uint64_t 115 116// Q: const pointer to void 117 118// S: const pointer to int8_t 119// T: const pointer to int16_t 120// U: const pointer to int32_t 121// V: const pointer to int64_t 122// 123// W: const pointer to uint8_t 124// X: const pointer to uint16_t 125// Y: const pointer to uint32_t 126// Z: const pointer to uint64_t 127 128// Prototype modifiers added for SVE2p1 129// }: svcount_t 130 131class MergeType<int val, string suffix=""> { 132 int Value = val; 133 string Suffix = suffix; 134} 135def MergeNone : MergeType<0>; 136def MergeAny : MergeType<1, "_x">; 137def MergeOp1 : MergeType<2, "_m">; 138def MergeZero : MergeType<3, "_z">; 139def MergeAnyExp : MergeType<4, "_x">; // Use merged builtin with explicit 140def MergeZeroExp : MergeType<5, "_z">; // generation of its inactive argument. 141 142class EltType<int val> { 143 int Value = val; 144} 145def EltTyInvalid : EltType<0>; 146def EltTyInt8 : EltType<1>; 147def EltTyInt16 : EltType<2>; 148def EltTyInt32 : EltType<3>; 149def EltTyInt64 : EltType<4>; 150def EltTyInt128 : EltType<5>; 151def EltTyFloat16 : EltType<6>; 152def EltTyFloat32 : EltType<7>; 153def EltTyFloat64 : EltType<8>; 154def EltTyBool8 : EltType<9>; 155def EltTyBool16 : EltType<10>; 156def EltTyBool32 : EltType<11>; 157def EltTyBool64 : EltType<12>; 158def EltTyBFloat16 : EltType<13>; 159 160class MemEltType<int val> { 161 int Value = val; 162} 163def MemEltTyDefault : MemEltType<0>; 164def MemEltTyInt8 : MemEltType<1>; 165def MemEltTyInt16 : MemEltType<2>; 166def MemEltTyInt32 : MemEltType<3>; 167def MemEltTyInt64 : MemEltType<4>; 168 169class FlagType<int val> { 170 int Value = val; 171} 172 173// These must be kept in sync with the flags in utils/TableGen/SveEmitter.h 174// and include/clang/Basic/TargetBuiltins.h 175def NoFlags : FlagType<0x00000000>; 176def FirstEltType : FlagType<0x00000001>; 177// : : 178// : : 179def EltTypeMask : FlagType<0x0000000f>; 180def FirstMemEltType : FlagType<0x00000010>; 181// : : 182// : : 183def MemEltTypeMask : FlagType<0x00000070>; 184def FirstMergeTypeMask : FlagType<0x00000080>; 185// : : 186// : : 187def MergeTypeMask : FlagType<0x00000380>; 188def FirstSplatOperand : FlagType<0x00000400>; 189// : : 190// These flags are used to specify which scalar operand 191// needs to be duplicated/splatted into a vector. 192// : : 193def SplatOperandMask : FlagType<0x00001C00>; 194def IsLoad : FlagType<0x00002000>; 195def IsStore : FlagType<0x00004000>; 196def IsGatherLoad : FlagType<0x00008000>; 197def IsScatterStore : FlagType<0x00010000>; 198def IsStructLoad : FlagType<0x00020000>; 199def IsStructStore : FlagType<0x00040000>; 200def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default 201def IsOverloadNone : FlagType<0x00100000>; // Intrinsic does not take any overloaded types. 202def IsOverloadWhile : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types. 203def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types. 204def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types. 205def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type. 206def IsByteIndexed : FlagType<0x01000000>; 207def IsAppendSVALL : FlagType<0x02000000>; // Appends SV_ALL as the last operand. 208def IsInsertOp1SVALL : FlagType<0x04000000>; // Inserts SV_ALL as the second operand. 209def IsPrefetch : FlagType<0x08000000>; // Contiguous prefetches. 210def IsGatherPrefetch : FlagType<0x10000000>; 211def ReverseCompare : FlagType<0x20000000>; // Compare operands must be swapped. 212def ReverseUSDOT : FlagType<0x40000000>; // Unsigned/signed operands must be swapped. 213def IsUndef : FlagType<0x80000000>; // Codegen `undef` of given type. 214def IsTupleCreate : FlagType<0x100000000>; 215def IsTupleGet : FlagType<0x200000000>; 216def IsTupleSet : FlagType<0x400000000>; 217def ReverseMergeAnyBinOp : FlagType<0x800000000>; // e.g. Implement SUBR_X using SUB_X. 218def ReverseMergeAnyAccOp : FlagType<0x1000000000>; // e.g. Implement MSB_X using MLS_X. 219def IsStreaming : FlagType<0x2000000000>; 220def IsStreamingCompatible : FlagType<0x4000000000>; 221def IsSharedZA : FlagType<0x8000000000>; 222def IsPreservesZA : FlagType<0x10000000000>; 223def IsReadZA : FlagType<0x20000000000>; 224def IsWriteZA : FlagType<0x40000000000>; 225 226// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h 227class ImmCheckType<int val> { 228 int Value = val; 229} 230def ImmCheck0_31 : ImmCheckType<0>; // 0..31 (used for e.g. predicate patterns) 231def ImmCheck1_16 : ImmCheckType<1>; // 1..16 232def ImmCheckExtract : ImmCheckType<2>; // 0..(2048/sizeinbits(elt) - 1) 233def ImmCheckShiftRight : ImmCheckType<3>; // 1..sizeinbits(elt) 234def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2 235def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1) 236def ImmCheck0_7 : ImmCheckType<6>; // 0..7 237def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(128/(1*sizeinbits(elt)) - 1) 238def ImmCheckLaneIndexCompRotate : ImmCheckType<8>; // 0..(128/(2*sizeinbits(elt)) - 1) 239def ImmCheckLaneIndexDot : ImmCheckType<9>; // 0..(128/(4*sizeinbits(elt)) - 1) 240def ImmCheckComplexRot90_270 : ImmCheckType<10>; // [90,270] 241def ImmCheckComplexRotAll90 : ImmCheckType<11>; // [0, 90, 180,270] 242def ImmCheck0_13 : ImmCheckType<12>; // 0..13 243def ImmCheck0_1 : ImmCheckType<13>; // 0..1 244def ImmCheck0_2 : ImmCheckType<14>; // 0..2 245def ImmCheck0_3 : ImmCheckType<15>; // 0..3 246def ImmCheck0_0 : ImmCheckType<16>; // 0..0 247def ImmCheck0_15 : ImmCheckType<17>; // 0..15 248def ImmCheck0_255 : ImmCheckType<18>; // 0..255 249 250class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> { 251 int Arg = arg; 252 int EltSizeArg = eltSizeArg; 253 ImmCheckType Kind = kind; 254} 255 256class Inst<string n, string p, string t, MergeType mt, string i, 257 list<FlagType> ft, list<ImmCheck> ch, MemEltType met> { 258 string Name = n; 259 string Prototype = p; 260 string Types = t; 261 string TargetGuard = "sve"; 262 int Merge = mt.Value; 263 string MergeSuffix = mt.Suffix; 264 string LLVMIntrinsic = i; 265 list<FlagType> Flags = ft; 266 list<ImmCheck> ImmChecks = ch; 267 int MemEltType = met.Value; 268} 269 270// SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8") 271class SInst<string n, string p, string t, MergeType mt, string i = "", 272 list<FlagType> ft = [], list<ImmCheck> ch = []> 273 : Inst<n, p, t, mt, i, ft, ch, MemEltTyDefault> { 274} 275 276// MInst: Instructions which access memory 277class MInst<string n, string p, string t, list<FlagType> f, 278 MemEltType met = MemEltTyDefault, string i = "", 279 list<ImmCheck> ch = []> 280 : Inst<n, p, t, MergeNone, i, f, ch, met> { 281} 282