| //- 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)">; |