blob: cd388ed3e3191b193cd8771646345961092deb9b [file] [log] [blame]
//- DXIL.td - Describe DXIL operation -------------------------*- tablegen -*-//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This is a target description file for DXIL operations.
///
//===----------------------------------------------------------------------===//
include "llvm/IR/Intrinsics.td"
class DXILOpClass;
// Following is a set of DXIL Operation classes whose names appear to be
// arbitrary, yet need to be a substring of the function name used during
// lowering to DXIL Operation calls. These class name strings are specified
// as the third argument of add_dixil_op in utils/hct/hctdb.py and case converted
// in utils/hct/hctdb_instrhelp.py of DirectXShaderCompiler repo. The function
// name has the format "dx.op.<class-name>.<return-type>".
defset list<DXILOpClass> OpClasses = {
def acceptHitAndEndSearch : DXILOpClass;
def allocateNodeOutputRecords : DXILOpClass;
def allocateRayQuery : DXILOpClass;
def annotateHandle : DXILOpClass;
def annotateNodeHandle : DXILOpClass;
def annotateNodeRecordHandle : DXILOpClass;
def atomicBinOp : DXILOpClass;
def atomicCompareExchange : DXILOpClass;
def attributeAtVertex : DXILOpClass;
def barrier : DXILOpClass;
def barrierByMemoryHandle : DXILOpClass;
def barrierByMemoryType : DXILOpClass;
def barrierByNodeRecordHandle : DXILOpClass;
def binary : DXILOpClass;
def binaryWithCarryOrBorrow : DXILOpClass;
def binaryWithTwoOuts : DXILOpClass;
def bitcastF16toI16 : DXILOpClass;
def bitcastF32toI32 : DXILOpClass;
def bitcastF64toI64 : DXILOpClass;
def bitcastI16toF16 : DXILOpClass;
def bitcastI32toF32 : DXILOpClass;
def bitcastI64toF64 : DXILOpClass;
def bufferLoad : DXILOpClass;
def bufferStore : DXILOpClass;
def bufferUpdateCounter : DXILOpClass;
def calculateLOD : DXILOpClass;
def callShader : DXILOpClass;
def cbufferLoad : DXILOpClass;
def cbufferLoadLegacy : DXILOpClass;
def checkAccessFullyMapped : DXILOpClass;
def coverage : DXILOpClass;
def createHandle : DXILOpClass;
def createHandleForLib : DXILOpClass;
def createHandleFromBinding : DXILOpClass;
def createHandleFromHeap : DXILOpClass;
def createNodeInputRecordHandle : DXILOpClass;
def createNodeOutputHandle : DXILOpClass;
def cutStream : DXILOpClass;
def cycleCounterLegacy : DXILOpClass;
def discard : DXILOpClass;
def dispatchMesh : DXILOpClass;
def dispatchRaysDimensions : DXILOpClass;
def dispatchRaysIndex : DXILOpClass;
def domainLocation : DXILOpClass;
def dot2 : DXILOpClass;
def dot2AddHalf : DXILOpClass;
def dot3 : DXILOpClass;
def dot4 : DXILOpClass;
def dot4AddPacked : DXILOpClass;
def emitIndices : DXILOpClass;
def emitStream : DXILOpClass;
def emitThenCutStream : DXILOpClass;
def evalCentroid : DXILOpClass;
def evalSampleIndex : DXILOpClass;
def evalSnapped : DXILOpClass;
def finishedCrossGroupSharing : DXILOpClass;
def flattenedThreadIdInGroup : DXILOpClass;
def geometryIndex : DXILOpClass;
def getDimensions : DXILOpClass;
def getInputRecordCount : DXILOpClass;
def getMeshPayload : DXILOpClass;
def getNodeRecordPtr : DXILOpClass;
def getRemainingRecursionLevels : DXILOpClass;
def groupId : DXILOpClass;
def gsInstanceID : DXILOpClass;
def hitKind : DXILOpClass;
def ignoreHit : DXILOpClass;
def incrementOutputCount : DXILOpClass;
def indexNodeHandle : DXILOpClass;
def innerCoverage : DXILOpClass;
def instanceID : DXILOpClass;
def instanceIndex : DXILOpClass;
def isHelperLane : DXILOpClass;
def isSpecialFloat : DXILOpClass;
def legacyDoubleToFloat : DXILOpClass;
def legacyDoubleToSInt32 : DXILOpClass;
def legacyDoubleToUInt32 : DXILOpClass;
def legacyF16ToF32 : DXILOpClass;
def legacyF32ToF16 : DXILOpClass;
def loadInput : DXILOpClass;
def loadOutputControlPoint : DXILOpClass;
def loadPatchConstant : DXILOpClass;
def makeDouble : DXILOpClass;
def minPrecXRegLoad : DXILOpClass;
def minPrecXRegStore : DXILOpClass;
def nodeOutputIsValid : DXILOpClass;
def objectRayDirection : DXILOpClass;
def objectRayOrigin : DXILOpClass;
def objectToWorld : DXILOpClass;
def outputComplete : DXILOpClass;
def outputControlPointID : DXILOpClass;
def pack4x8 : DXILOpClass;
def primitiveID : DXILOpClass;
def primitiveIndex : DXILOpClass;
def quadOp : DXILOpClass;
def quadReadLaneAt : DXILOpClass;
def quadVote : DXILOpClass;
def quaternary : DXILOpClass;
def rawBufferLoad : DXILOpClass;
def rawBufferStore : DXILOpClass;
def rayFlags : DXILOpClass;
def rayQuery_Abort : DXILOpClass;
def rayQuery_CommitNonOpaqueTriangleHit : DXILOpClass;
def rayQuery_CommitProceduralPrimitiveHit : DXILOpClass;
def rayQuery_Proceed : DXILOpClass;
def rayQuery_StateMatrix : DXILOpClass;
def rayQuery_StateScalar : DXILOpClass;
def rayQuery_StateVector : DXILOpClass;
def rayQuery_TraceRayInline : DXILOpClass;
def rayTCurrent : DXILOpClass;
def rayTMin : DXILOpClass;
def renderTargetGetSampleCount : DXILOpClass;
def renderTargetGetSamplePosition : DXILOpClass;
def reportHit : DXILOpClass;
def sample : DXILOpClass;
def sampleBias : DXILOpClass;
def sampleCmp : DXILOpClass;
def sampleCmpBias : DXILOpClass;
def sampleCmpGrad : DXILOpClass;
def sampleCmpLevel : DXILOpClass;
def sampleCmpLevelZero : DXILOpClass;
def sampleGrad : DXILOpClass;
def sampleIndex : DXILOpClass;
def sampleLevel : DXILOpClass;
def setMeshOutputCounts : DXILOpClass;
def splitDouble : DXILOpClass;
def startInstanceLocation : DXILOpClass;
def startVertexLocation : DXILOpClass;
def storeOutput : DXILOpClass;
def storePatchConstant : DXILOpClass;
def storePrimitiveOutput : DXILOpClass;
def storeVertexOutput : DXILOpClass;
def tempRegLoad : DXILOpClass;
def tempRegStore : DXILOpClass;
def tertiary : DXILOpClass;
def texture2DMSGetSamplePosition : DXILOpClass;
def textureGather : DXILOpClass;
def textureGatherCmp : DXILOpClass;
def textureGatherRaw : DXILOpClass;
def textureLoad : DXILOpClass;
def textureStore : DXILOpClass;
def textureStoreSample : DXILOpClass;
def threadId : DXILOpClass;
def threadIdInGroup : DXILOpClass;
def traceRay : DXILOpClass;
def unary : DXILOpClass;
def unaryBits : DXILOpClass;
def unpack4x8 : DXILOpClass;
def viewID : DXILOpClass;
def waveActiveAllEqual : DXILOpClass;
def waveActiveBallot : DXILOpClass;
def waveActiveBit : DXILOpClass;
def waveActiveOp : DXILOpClass;
def waveAllOp : DXILOpClass;
def waveAllTrue : DXILOpClass;
def waveAnyTrue : DXILOpClass;
def waveGetLaneCount : DXILOpClass;
def waveGetLaneIndex : DXILOpClass;
def waveIsFirstLane : DXILOpClass;
def waveMatch : DXILOpClass;
def waveMatrix_Accumulate : DXILOpClass;
def waveMatrix_Annotate : DXILOpClass;
def waveMatrix_Depth : DXILOpClass;
def waveMatrix_Fill : DXILOpClass;
def waveMatrix_LoadGroupShared : DXILOpClass;
def waveMatrix_LoadRawBuf : DXILOpClass;
def waveMatrix_Multiply : DXILOpClass;
def waveMatrix_ScalarOp : DXILOpClass;
def waveMatrix_StoreGroupShared : DXILOpClass;
def waveMatrix_StoreRawBuf : DXILOpClass;
def waveMultiPrefixBitCount : DXILOpClass;
def waveMultiPrefixOp : DXILOpClass;
def wavePrefixOp : DXILOpClass;
def waveReadLaneAt : DXILOpClass;
def waveReadLaneFirst : DXILOpClass;
def worldRayDirection : DXILOpClass;
def worldRayOrigin : DXILOpClass;
def worldToObject : DXILOpClass;
def writeSamplerFeedback : DXILOpClass;
def writeSamplerFeedbackBias : DXILOpClass;
def writeSamplerFeedbackGrad : DXILOpClass;
def writeSamplerFeedbackLevel: DXILOpClass;
// This is a sentinel definition. Hence placed at the end of the list
// and not as part of the above alphabetically sorted valid definitions.
// Additionally it is capitalized unlike all the others.
def UnknownOpClass: DXILOpClass;
}
// Several of the overloaded DXIL Operations support for data types
// that are a subset of the overloaded LLVM intrinsics that they map to.
// For e.g., llvm.sin.* intrinsic operates on any floating-point type and
// maps for lowering to DXIL Op Sin. However, valid overloads of DXIL Sin
// operation overloads are half (f16) and float (f32) only.
//
// The following abstracts overload types specific to DXIL operations.
class DXILType : LLVMType<OtherVT> {
let isAny = 1;
int isI16OrI32 = 0;
int isHalfOrFloat = 0;
}
// Concrete records for various overload types supported specifically by
// DXIL Operations.
let isI16OrI32 = 1 in
def llvm_i16ori32_ty : DXILType;
let isHalfOrFloat = 1 in
def llvm_halforfloat_ty : DXILType;
// Abstraction DXIL Operation to LLVM intrinsic
class DXILOpMappingBase {
int OpCode = 0; // Opcode of DXIL Operation
DXILOpClass OpClass = UnknownOpClass;// Class of DXIL Operation.
Intrinsic LLVMIntrinsic = ?; // LLVM Intrinsic DXIL Operation maps to
string Doc = ""; // A short description of the operation
list<LLVMType> OpTypes = ?; // Valid types of DXIL Operation in the
// format [returnTy, param1ty, ...]
}
class DXILOpMapping<int opCode, DXILOpClass opClass,
Intrinsic intrinsic, string doc,
list<LLVMType> opTys = []> : DXILOpMappingBase {
int OpCode = opCode; // Opcode corresponding to DXIL Operation
DXILOpClass OpClass = opClass; // Class of DXIL Operation.
Intrinsic LLVMIntrinsic = intrinsic; // LLVM Intrinsic the DXIL Operation maps
string Doc = doc; // to a short description of the operation
list<LLVMType> OpTypes = !if(!eq(!size(opTys), 0), LLVMIntrinsic.Types, opTys);
}
// Concrete definition of DXIL Operation mapping to corresponding LLVM intrinsic
def Abs : DXILOpMapping<6, unary, int_fabs,
"Returns the absolute value of the input.">;
def IsInf : DXILOpMapping<9, isSpecialFloat, int_dx_isinf,
"Determines if the specified value is infinite.",
[llvm_i1_ty, llvm_halforfloat_ty]>;
def Cos : DXILOpMapping<12, unary, int_cos,
"Returns cosine(theta) for theta in radians.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Sin : DXILOpMapping<13, unary, int_sin,
"Returns sine(theta) for theta in radians.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Exp2 : DXILOpMapping<21, unary, int_exp2,
"Returns the base 2 exponential, or 2**x, of the specified value."
"exp2(x) = 2**x.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Frac : DXILOpMapping<22, unary, int_dx_frac,
"Returns a fraction from 0 to 1 that represents the "
"decimal part of the input.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Log2 : DXILOpMapping<23, unary, int_log2,
"Returns the base-2 logarithm of the specified value.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Sqrt : DXILOpMapping<24, unary, int_sqrt,
"Returns the square root of the specified floating-point"
"value, per component.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def RSqrt : DXILOpMapping<25, unary, int_dx_rsqrt,
"Returns the reciprocal of the square root of the specified value."
"rsqrt(x) = 1 / sqrt(x).",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Round : DXILOpMapping<26, unary, int_roundeven,
"Returns the input rounded to the nearest integer"
"within a floating-point type.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Floor : DXILOpMapping<27, unary, int_floor,
"Returns the largest integer that is less than or equal to the input.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Ceil : DXILOpMapping<28, unary, int_ceil,
"Returns the smallest integer that is greater than or equal to the input.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Trunc : DXILOpMapping<29, unary, int_trunc,
"Returns the specified value truncated to the integer component.",
[llvm_halforfloat_ty, LLVMMatchType<0>]>;
def Rbits : DXILOpMapping<30, unary, int_bitreverse,
"Returns the specified value with its bits reversed.",
[llvm_anyint_ty, LLVMMatchType<0>]>;
def FMax : DXILOpMapping<35, binary, int_maxnum,
"Float maximum. FMax(a,b) = a > b ? a : b">;
def FMin : DXILOpMapping<36, binary, int_minnum,
"Float minimum. FMin(a,b) = a < b ? a : b">;
def SMax : DXILOpMapping<37, binary, int_smax,
"Signed integer maximum. SMax(a,b) = a > b ? a : b">;
def SMin : DXILOpMapping<38, binary, int_smin,
"Signed integer minimum. SMin(a,b) = a < b ? a : b">;
def UMax : DXILOpMapping<39, binary, int_umax,
"Unsigned integer maximum. UMax(a,b) = a > b ? a : b">;
def UMin : DXILOpMapping<40, binary, int_umin,
"Unsigned integer minimum. UMin(a,b) = a < b ? a : b">;
def FMad : DXILOpMapping<46, tertiary, int_fmuladd,
"Floating point arithmetic multiply/add operation. fmad(m,a,b) = m * a + b.">;
def IMad : DXILOpMapping<48, tertiary, int_dx_imad,
"Signed integer arithmetic multiply/add operation. imad(m,a,b) = m * a + b.">;
def UMad : DXILOpMapping<49, tertiary, int_dx_umad,
"Unsigned integer arithmetic multiply/add operation. umad(m,a,b) = m * a + b.">;
let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, 4)) in
def Dot2 : DXILOpMapping<54, dot2, int_dx_dot2,
"dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + a[n]*b[n] where n is between 0 and 1">;
let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, 6)) in
def Dot3 : DXILOpMapping<55, dot3, int_dx_dot3,
"dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + a[n]*b[n] where n is between 0 and 2">;
let OpTypes = !listconcat([llvm_halforfloat_ty], !listsplat(llvm_halforfloat_ty, 8)) in
def Dot4 : DXILOpMapping<56, dot4, int_dx_dot4,
"dot product of two float vectors Dot(a,b) = a[0]*b[0] + ... + a[n]*b[n] where n is between 0 and 3">;
def ThreadId : DXILOpMapping<93, threadId, int_dx_thread_id,
"Reads the thread ID">;
def GroupId : DXILOpMapping<94, groupId, int_dx_group_id,
"Reads the group ID (SV_GroupID)">;
def ThreadIdInGroup : DXILOpMapping<95, threadIdInGroup,
int_dx_thread_id_in_group,
"Reads the thread ID within the group "
"(SV_GroupThreadID)">;
def FlattenedThreadIdInGroup : DXILOpMapping<96, flattenedThreadIdInGroup,
int_dx_flattened_thread_id_in_group,
"Provides a flattened index for a "
"given thread within a given "
"group (SV_GroupIndex)">;