From abc8dba07f34711b28880005a171edfd3d2ef742 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Wed, 4 Feb 2026 14:20:20 -0800 Subject: [PATCH 1/3] Auto-name reserved DXIL ops with stable hex opcode Switching DXIL ops to reserved will become common when they are retired from experimental. This change makes it trivial to do so without depending on or changing other reserved op names or numbers elsewhere. --- docs/DXIL.rst | 62 ++++---- include/dxc/DXIL/DxilConstants.h | 74 ++++----- lib/DXIL/DxilOperations.cpp | 248 +++++++++++++++---------------- utils/hct/hctdb.py | 34 ++--- 4 files changed, 209 insertions(+), 209 deletions(-) diff --git a/docs/DXIL.rst b/docs/DXIL.rst index 8871d3d8c9..1dfc79369a 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -2342,18 +2342,18 @@ ID Name Description 223 TextureGatherRaw Gather raw elements from 4 texels with no type conversions (SRV type is constrained) 224 SampleCmpLevel samples a texture and compares a single component against the specified comparison value 225 TextureStoreSample stores texel data at specified sample index -226 Reserved0 reserved -227 Reserved1 reserved -228 Reserved2 reserved -229 Reserved3 reserved -230 Reserved4 reserved -231 Reserved5 reserved -232 Reserved6 reserved -233 Reserved7 reserved -234 Reserved8 reserved -235 Reserved9 reserved -236 Reserved10 reserved -237 Reserved11 reserved +226 Reserved_0x000000E2 reserved +227 Reserved_0x000000E3 reserved +228 Reserved_0x000000E4 reserved +229 Reserved_0x000000E5 reserved +230 Reserved_0x000000E6 reserved +231 Reserved_0x000000E7 reserved +232 Reserved_0x000000E8 reserved +233 Reserved_0x000000E9 reserved +234 Reserved_0x000000EA reserved +235 Reserved_0x000000EB reserved +236 Reserved_0x000000EC reserved +237 Reserved_0x000000ED reserved 238 AllocateNodeOutputRecords returns a handle for the output records 239 GetNodeRecordPtr retrieve node input/output record pointer in address space 6 240 IncrementOutputCount Select the next logical output count for an EmptyNodeOutput for the whole group or per thread. @@ -2375,9 +2375,9 @@ ID Name Description 256 StartVertexLocation returns the BaseVertexLocation from DrawIndexedInstanced or StartVertexLocation from DrawInstanced 257 StartInstanceLocation returns the StartInstanceLocation from Draw*Instanced 258 AllocateRayQuery2 allocates space for RayQuery and return handle -259 ReservedA0 reserved -260 ReservedA1 reserved -261 ReservedA2 reserved +259 Reserved_0x00000103 reserved +260 Reserved_0x00000104 reserved +261 Reserved_0x00000105 reserved 262 HitObject_TraceRay Analogous to TraceRay but without invoking CH/MS and returns the intermediate state as a HitObject 263 HitObject_FromRayQuery Creates a new HitObject representing a committed hit from a RayQuery 264 HitObject_FromRayQueryWithAttrs Creates a new HitObject representing a committed hit from a RayQuery and committed attributes @@ -2406,19 +2406,19 @@ ID Name Description 287 HitObject_SetShaderTableIndex Returns a HitObject with updated shader table index 288 HitObject_LoadLocalRootTableConstant Returns the root table constant for this HitObject and offset 289 HitObject_Attributes Returns the attributes set for this HitObject -290 ReservedB28 reserved -291 ReservedB29 reserved -292 ReservedB30 reserved -293 ReservedC0 reserved -294 ReservedC1 reserved -295 ReservedC2 reserved -296 ReservedC3 reserved -297 ReservedC4 reserved -298 ReservedC5 reserved -299 ReservedC6 reserved -300 ReservedC7 reserved -301 ReservedC8 reserved -302 ReservedC9 reserved +290 Reserved_0x00000122 reserved +291 Reserved_0x00000123 reserved +292 Reserved_0x00000124 reserved +293 Reserved_0x00000125 reserved +294 Reserved_0x00000126 reserved +295 Reserved_0x00000127 reserved +296 Reserved_0x00000128 reserved +297 Reserved_0x00000129 reserved +298 Reserved_0x0000012A reserved +299 Reserved_0x0000012B reserved +300 Reserved_0x0000012C reserved +301 Reserved_0x0000012D reserved +302 Reserved_0x0000012E reserved 303 RawBufferVectorLoad reads from a raw buffer and structured buffer 304 RawBufferVectorStore writes to a RWByteAddressBuffer or RWStructuredBuffer 305 MatVecMul Multiplies a MxK dimension matrix and a K sized input vector @@ -3095,9 +3095,9 @@ ID Name Description 2147483675 MatrixAccumulateToDescriptor accumulates a matrix to a RWByteAddressBuffer 2147483676 MatrixAccumulateToMemory accumulates a matrix to groupshared memory 2147483677 MatrixOuterProduct Outer products an M sized vector and a K sized vector producing an MxK matrix -2147483678 LinAlgMatrixReserved0 reserved -2147483679 LinAlgMatrixReserved1 reserved -2147483680 LinAlgMatrixReserved2 reserved +2147483678 Reserved_0x8000001E reserved +2147483679 Reserved_0x8000001F reserved +2147483680 Reserved_0x80000020 reserved 2147483681 DebugBreak triggers a breakpoint if a debugger is attached 2147483682 IsDebuggerPresent returns true if a debugger is attached ========== ======================================== =================================================================================================================== diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h index eb5f6ac1dd..29c29e27c7 100644 --- a/include/dxc/DXIL/DxilConstants.h +++ b/include/dxc/DXIL/DxilConstants.h @@ -512,9 +512,9 @@ static const OpCodeTableID TableID = OpCodeTableID::ExperimentalOps; // Enumeration for ExperimentalOps DXIL operations enum class OpCode : unsigned { // - LinAlgMatrixReserved0 = 30, // reserved - LinAlgMatrixReserved1 = 31, // reserved - LinAlgMatrixReserved2 = 32, // reserved + Reserved_0x8000001E = 30, // reserved + Reserved_0x8000001F = 31, // reserved + Reserved_0x80000020 = 32, // reserved // Debugging DebugBreak = 33, // triggers a breakpoint if a debugger is attached @@ -600,34 +600,34 @@ static const unsigned NumOpCodeTables = 2; // Enumeration for CoreOps DXIL operations enum class OpCode : unsigned { // - Reserved0 = 226, // reserved - Reserved1 = 227, // reserved - Reserved10 = 236, // reserved - Reserved11 = 237, // reserved - Reserved2 = 228, // reserved - Reserved3 = 229, // reserved - Reserved4 = 230, // reserved - Reserved5 = 231, // reserved - Reserved6 = 232, // reserved - Reserved7 = 233, // reserved - Reserved8 = 234, // reserved - Reserved9 = 235, // reserved - ReservedA0 = 259, // reserved - ReservedA1 = 260, // reserved - ReservedA2 = 261, // reserved - ReservedB28 = 290, // reserved - ReservedB29 = 291, // reserved - ReservedB30 = 292, // reserved - ReservedC0 = 293, // reserved - ReservedC1 = 294, // reserved - ReservedC2 = 295, // reserved - ReservedC3 = 296, // reserved - ReservedC4 = 297, // reserved - ReservedC5 = 298, // reserved - ReservedC6 = 299, // reserved - ReservedC7 = 300, // reserved - ReservedC8 = 301, // reserved - ReservedC9 = 302, // reserved + Reserved_0x000000E2 = 226, // reserved + Reserved_0x000000E3 = 227, // reserved + Reserved_0x000000E4 = 228, // reserved + Reserved_0x000000E5 = 229, // reserved + Reserved_0x000000E6 = 230, // reserved + Reserved_0x000000E7 = 231, // reserved + Reserved_0x000000E8 = 232, // reserved + Reserved_0x000000E9 = 233, // reserved + Reserved_0x000000EA = 234, // reserved + Reserved_0x000000EB = 235, // reserved + Reserved_0x000000EC = 236, // reserved + Reserved_0x000000ED = 237, // reserved + Reserved_0x00000103 = 259, // reserved + Reserved_0x00000104 = 260, // reserved + Reserved_0x00000105 = 261, // reserved + Reserved_0x00000122 = 290, // reserved + Reserved_0x00000123 = 291, // reserved + Reserved_0x00000124 = 292, // reserved + Reserved_0x00000125 = 293, // reserved + Reserved_0x00000126 = 294, // reserved + Reserved_0x00000127 = 295, // reserved + Reserved_0x00000128 = 296, // reserved + Reserved_0x00000129 = 297, // reserved + Reserved_0x0000012A = 298, // reserved + Reserved_0x0000012B = 299, // reserved + Reserved_0x0000012C = 300, // reserved + Reserved_0x0000012D = 301, // reserved + Reserved_0x0000012E = 302, // reserved // Amplification shader instructions DispatchMesh = 173, // Amplification shader intrinsic DispatchMesh @@ -1322,12 +1322,12 @@ enum class OpCode : unsigned { EXP_OPCODE(ExperimentalOps, MatrixOuterProduct), // Outer products an M sized vector and a K // sized vector producing an MxK matrix - // LinAlgMatrixReserved0 = 0x8000001E, 2147483678U, -2147483618 - EXP_OPCODE(ExperimentalOps, LinAlgMatrixReserved0), // reserved - // LinAlgMatrixReserved1 = 0x8000001F, 2147483679U, -2147483617 - EXP_OPCODE(ExperimentalOps, LinAlgMatrixReserved1), // reserved - // LinAlgMatrixReserved2 = 0x80000020, 2147483680U, -2147483616 - EXP_OPCODE(ExperimentalOps, LinAlgMatrixReserved2), // reserved + // Reserved_0x8000001E = 0x8000001E, 2147483678U, -2147483618 + EXP_OPCODE(ExperimentalOps, Reserved_0x8000001E), // reserved + // Reserved_0x8000001F = 0x8000001F, 2147483679U, -2147483617 + EXP_OPCODE(ExperimentalOps, Reserved_0x8000001F), // reserved + // Reserved_0x80000020 = 0x80000020, 2147483680U, -2147483616 + EXP_OPCODE(ExperimentalOps, Reserved_0x80000020), // reserved // DebugBreak = 0x80000021, 2147483681U, -2147483615 EXP_OPCODE(ExperimentalOps, DebugBreak), // triggers a breakpoint if a debugger is attached diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index eb5b2a2ceb..e88a684f21 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -1996,96 +1996,96 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = { {{0x63}}, {{0x0}}}, // Overloads: hfwi - {OC::Reserved0, - "Reserved0", + {OC::Reserved_0x000000E2, + "Reserved_0x000000E2", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved1, - "Reserved1", + {OC::Reserved_0x000000E3, + "Reserved_0x000000E3", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved2, - "Reserved2", + {OC::Reserved_0x000000E4, + "Reserved_0x000000E4", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved3, - "Reserved3", + {OC::Reserved_0x000000E5, + "Reserved_0x000000E5", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved4, - "Reserved4", + {OC::Reserved_0x000000E6, + "Reserved_0x000000E6", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved5, - "Reserved5", + {OC::Reserved_0x000000E7, + "Reserved_0x000000E7", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved6, - "Reserved6", + {OC::Reserved_0x000000E8, + "Reserved_0x000000E8", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved7, - "Reserved7", + {OC::Reserved_0x000000E9, + "Reserved_0x000000E9", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved8, - "Reserved8", + {OC::Reserved_0x000000EA, + "Reserved_0x000000EA", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved9, - "Reserved9", + {OC::Reserved_0x000000EB, + "Reserved_0x000000EB", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved10, - "Reserved10", + {OC::Reserved_0x000000EC, + "Reserved_0x000000EC", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::Reserved11, - "Reserved11", + {OC::Reserved_0x000000ED, + "Reserved_0x000000ED", OCC::Reserved, "reserved", Attribute::None, @@ -2279,24 +2279,24 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = { {}, {}}, // Overloads: v - {OC::ReservedA0, - "ReservedA0", + {OC::Reserved_0x00000103, + "Reserved_0x00000103", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedA1, - "ReservedA1", + {OC::Reserved_0x00000104, + "Reserved_0x00000104", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedA2, - "ReservedA2", + {OC::Reserved_0x00000105, + "Reserved_0x00000105", OCC::Reserved, "reserved", Attribute::None, @@ -2530,104 +2530,104 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = { {{0x100}}, {{0x0}}}, // Overloads: u - {OC::ReservedB28, - "ReservedB28", + {OC::Reserved_0x00000122, + "Reserved_0x00000122", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedB29, - "ReservedB29", + {OC::Reserved_0x00000123, + "Reserved_0x00000123", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedB30, - "ReservedB30", + {OC::Reserved_0x00000124, + "Reserved_0x00000124", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC0, - "ReservedC0", + {OC::Reserved_0x00000125, + "Reserved_0x00000125", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC1, - "ReservedC1", + {OC::Reserved_0x00000126, + "Reserved_0x00000126", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC2, - "ReservedC2", + {OC::Reserved_0x00000127, + "Reserved_0x00000127", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC3, - "ReservedC3", + {OC::Reserved_0x00000128, + "Reserved_0x00000128", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC4, - "ReservedC4", + {OC::Reserved_0x00000129, + "Reserved_0x00000129", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC5, - "ReservedC5", + {OC::Reserved_0x0000012A, + "Reserved_0x0000012A", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC6, - "ReservedC6", + {OC::Reserved_0x0000012B, + "Reserved_0x0000012B", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC7, - "ReservedC7", + {OC::Reserved_0x0000012C, + "Reserved_0x0000012C", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC8, - "ReservedC8", + {OC::Reserved_0x0000012D, + "Reserved_0x0000012D", OCC::Reserved, "reserved", Attribute::None, 0, {}, {}}, // Overloads: v - {OC::ReservedC9, - "ReservedC9", + {OC::Reserved_0x0000012E, + "Reserved_0x0000012E", OCC::Reserved, "reserved", Attribute::None, @@ -2977,24 +2977,24 @@ static const OP::OpCodeProperty ExperimentalOps_OpCodeProps[] = { {{0x400}, {0x400}}, {{0x63}, {0x63}}}, // Overloads: Date: Wed, 4 Feb 2026 16:59:53 -0800 Subject: [PATCH 2/3] Omit reserved DXIL ops from OpCode enum This change excludes reserved ops from DXIL::OpCode enum, so they don't need a unique name. They should never be referenced, so this makes that using them basically impossible. The reserved values will be listed in a comment at the end of the enum, before NumOpCodes. Catch and reject reserved opcodes during validation. Since the OpCodeProperty table entries corresponding to their opcode must still be occupied due to the way ops are looked up by indexing the table, there's a new single ReservedOpCodeProps value, with opcode set to OpCode::Invalid, supplied for each reserved slot. This way the slot is occupied (reserved), but not valid for use. For instance, for a reserved opcode, now: - DecodeOpCode will return false (for invalid) - IsValidOpCode will return false - IsOverloadLegal will return false - getOpCode on instruction will return OpCode::Invalid - GetDxilOpFuncCallInst on instruction will return OpCode::Invalid - new IsReservedOpCode function will return true Added a validation test. Previously, it would have incorrectly accepted the reserved opcode as valid. --- docs/DXIL.rst | 31 -- include/dxc/DXIL/DxilConstants.h | 48 +- include/dxc/DXIL/DxilOperations.h | 1 + lib/DXIL/DxilOperations.cpp | 479 +++--------------- lib/DxilValidation/DxilValidation.cpp | 5 +- .../test/LitDXILValidation/reservedDXILOp.ll | 39 ++ utils/hct/hctdb.py | 37 +- utils/hct/hctdb_instrhelp.py | 20 +- 8 files changed, 148 insertions(+), 512 deletions(-) create mode 100644 tools/clang/test/LitDXILValidation/reservedDXILOp.ll diff --git a/docs/DXIL.rst b/docs/DXIL.rst index 1dfc79369a..68fe0882bc 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -2342,18 +2342,6 @@ ID Name Description 223 TextureGatherRaw Gather raw elements from 4 texels with no type conversions (SRV type is constrained) 224 SampleCmpLevel samples a texture and compares a single component against the specified comparison value 225 TextureStoreSample stores texel data at specified sample index -226 Reserved_0x000000E2 reserved -227 Reserved_0x000000E3 reserved -228 Reserved_0x000000E4 reserved -229 Reserved_0x000000E5 reserved -230 Reserved_0x000000E6 reserved -231 Reserved_0x000000E7 reserved -232 Reserved_0x000000E8 reserved -233 Reserved_0x000000E9 reserved -234 Reserved_0x000000EA reserved -235 Reserved_0x000000EB reserved -236 Reserved_0x000000EC reserved -237 Reserved_0x000000ED reserved 238 AllocateNodeOutputRecords returns a handle for the output records 239 GetNodeRecordPtr retrieve node input/output record pointer in address space 6 240 IncrementOutputCount Select the next logical output count for an EmptyNodeOutput for the whole group or per thread. @@ -2375,9 +2363,6 @@ ID Name Description 256 StartVertexLocation returns the BaseVertexLocation from DrawIndexedInstanced or StartVertexLocation from DrawInstanced 257 StartInstanceLocation returns the StartInstanceLocation from Draw*Instanced 258 AllocateRayQuery2 allocates space for RayQuery and return handle -259 Reserved_0x00000103 reserved -260 Reserved_0x00000104 reserved -261 Reserved_0x00000105 reserved 262 HitObject_TraceRay Analogous to TraceRay but without invoking CH/MS and returns the intermediate state as a HitObject 263 HitObject_FromRayQuery Creates a new HitObject representing a committed hit from a RayQuery 264 HitObject_FromRayQueryWithAttrs Creates a new HitObject representing a committed hit from a RayQuery and committed attributes @@ -2406,19 +2391,6 @@ ID Name Description 287 HitObject_SetShaderTableIndex Returns a HitObject with updated shader table index 288 HitObject_LoadLocalRootTableConstant Returns the root table constant for this HitObject and offset 289 HitObject_Attributes Returns the attributes set for this HitObject -290 Reserved_0x00000122 reserved -291 Reserved_0x00000123 reserved -292 Reserved_0x00000124 reserved -293 Reserved_0x00000125 reserved -294 Reserved_0x00000126 reserved -295 Reserved_0x00000127 reserved -296 Reserved_0x00000128 reserved -297 Reserved_0x00000129 reserved -298 Reserved_0x0000012A reserved -299 Reserved_0x0000012B reserved -300 Reserved_0x0000012C reserved -301 Reserved_0x0000012D reserved -302 Reserved_0x0000012E reserved 303 RawBufferVectorLoad reads from a raw buffer and structured buffer 304 RawBufferVectorStore writes to a RWByteAddressBuffer or RWStructuredBuffer 305 MatVecMul Multiplies a MxK dimension matrix and a K sized input vector @@ -3095,9 +3067,6 @@ ID Name Description 2147483675 MatrixAccumulateToDescriptor accumulates a matrix to a RWByteAddressBuffer 2147483676 MatrixAccumulateToMemory accumulates a matrix to groupshared memory 2147483677 MatrixOuterProduct Outer products an M sized vector and a K sized vector producing an MxK matrix -2147483678 Reserved_0x8000001E reserved -2147483679 Reserved_0x8000001F reserved -2147483680 Reserved_0x80000020 reserved 2147483681 DebugBreak triggers a breakpoint if a debugger is attached 2147483682 IsDebuggerPresent returns true if a debugger is attached ========== ======================================== =================================================================================================================== diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h index 29c29e27c7..d9c678b0d1 100644 --- a/include/dxc/DXIL/DxilConstants.h +++ b/include/dxc/DXIL/DxilConstants.h @@ -511,11 +511,6 @@ namespace ExperimentalOps { static const OpCodeTableID TableID = OpCodeTableID::ExperimentalOps; // Enumeration for ExperimentalOps DXIL operations enum class OpCode : unsigned { - // - Reserved_0x8000001E = 30, // reserved - Reserved_0x8000001F = 31, // reserved - Reserved_0x80000020 = 32, // reserved - // Debugging DebugBreak = 33, // triggers a breakpoint if a debugger is attached IsDebuggerPresent = 34, // returns true if a debugger is attached @@ -584,6 +579,9 @@ enum class OpCode : unsigned { HitObject_TriangleObjectPosition = 10, // returns triangle vertices in object space as <9 x float> + // Reserved values: + // 30, 31, 32 + NumOpCodes = 35, // exclusive last value of enumeration }; } // namespace ExperimentalOps @@ -599,36 +597,6 @@ static const unsigned NumOpCodeTables = 2; // OPCODE-ENUM:BEGIN // Enumeration for CoreOps DXIL operations enum class OpCode : unsigned { - // - Reserved_0x000000E2 = 226, // reserved - Reserved_0x000000E3 = 227, // reserved - Reserved_0x000000E4 = 228, // reserved - Reserved_0x000000E5 = 229, // reserved - Reserved_0x000000E6 = 230, // reserved - Reserved_0x000000E7 = 231, // reserved - Reserved_0x000000E8 = 232, // reserved - Reserved_0x000000E9 = 233, // reserved - Reserved_0x000000EA = 234, // reserved - Reserved_0x000000EB = 235, // reserved - Reserved_0x000000EC = 236, // reserved - Reserved_0x000000ED = 237, // reserved - Reserved_0x00000103 = 259, // reserved - Reserved_0x00000104 = 260, // reserved - Reserved_0x00000105 = 261, // reserved - Reserved_0x00000122 = 290, // reserved - Reserved_0x00000123 = 291, // reserved - Reserved_0x00000124 = 292, // reserved - Reserved_0x00000125 = 293, // reserved - Reserved_0x00000126 = 294, // reserved - Reserved_0x00000127 = 295, // reserved - Reserved_0x00000128 = 296, // reserved - Reserved_0x00000129 = 297, // reserved - Reserved_0x0000012A = 298, // reserved - Reserved_0x0000012B = 299, // reserved - Reserved_0x0000012C = 300, // reserved - Reserved_0x0000012D = 301, // reserved - Reserved_0x0000012E = 302, // reserved - // Amplification shader instructions DispatchMesh = 173, // Amplification shader intrinsic DispatchMesh @@ -1182,6 +1150,10 @@ enum class OpCode : unsigned { OutputComplete = 241, // indicates all outputs for a given records are complete + // Reserved values: + // 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 259, 260, 261, + // 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302 + NumOpCodes_Dxil_1_0 = 137, NumOpCodes_Dxil_1_1 = 139, NumOpCodes_Dxil_1_2 = 141, @@ -1322,12 +1294,6 @@ enum class OpCode : unsigned { EXP_OPCODE(ExperimentalOps, MatrixOuterProduct), // Outer products an M sized vector and a K // sized vector producing an MxK matrix - // Reserved_0x8000001E = 0x8000001E, 2147483678U, -2147483618 - EXP_OPCODE(ExperimentalOps, Reserved_0x8000001E), // reserved - // Reserved_0x8000001F = 0x8000001F, 2147483679U, -2147483617 - EXP_OPCODE(ExperimentalOps, Reserved_0x8000001F), // reserved - // Reserved_0x80000020 = 0x80000020, 2147483680U, -2147483616 - EXP_OPCODE(ExperimentalOps, Reserved_0x80000020), // reserved // DebugBreak = 0x80000021, 2147483681U, -2147483615 EXP_OPCODE(ExperimentalOps, DebugBreak), // triggers a breakpoint if a debugger is attached diff --git a/include/dxc/DXIL/DxilOperations.h b/include/dxc/DXIL/DxilOperations.h index fabf07ee14..453315bb06 100644 --- a/include/dxc/DXIL/DxilOperations.h +++ b/include/dxc/DXIL/DxilOperations.h @@ -275,6 +275,7 @@ class OP { unsigned *OptTableIndex = nullptr); static bool IsValidOpCode(unsigned EncodedOpCode); static bool IsValidOpCode(OpCode EncodedOpCode); + static bool IsReservedOpCode(unsigned EncodedOpCode); private: // Static properties. diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index e88a684f21..1026da8d21 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -34,6 +34,10 @@ using OCC = OP::OpCodeClass; // // OP class const-static data and related static methods. // +static const OP::OpCodeProperty ReservedOpCodeProps = { + OC::Invalid, "Reserved", OCC::Reserved, "reserved", Attribute::None, 0, + {}, {}}; + /* import hctdb_instrhelp */ @@ -1994,104 +1998,19 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = { Attribute::None, 1, {{0x63}}, - {{0x0}}}, // Overloads: hfwi - - {OC::Reserved_0x000000E2, - "Reserved_0x000000E2", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000E3, - "Reserved_0x000000E3", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000E4, - "Reserved_0x000000E4", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000E5, - "Reserved_0x000000E5", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000E6, - "Reserved_0x000000E6", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000E7, - "Reserved_0x000000E7", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000E8, - "Reserved_0x000000E8", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000E9, - "Reserved_0x000000E9", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000EA, - "Reserved_0x000000EA", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000EB, - "Reserved_0x000000EB", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000EC, - "Reserved_0x000000EC", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x000000ED, - "Reserved_0x000000ED", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v + {{0x0}}}, // Overloads: hfwi + ReservedOpCodeProps, // Reserved: 0x000000E2 + ReservedOpCodeProps, // Reserved: 0x000000E3 + ReservedOpCodeProps, // Reserved: 0x000000E4 + ReservedOpCodeProps, // Reserved: 0x000000E5 + ReservedOpCodeProps, // Reserved: 0x000000E6 + ReservedOpCodeProps, // Reserved: 0x000000E7 + ReservedOpCodeProps, // Reserved: 0x000000E8 + ReservedOpCodeProps, // Reserved: 0x000000E9 + ReservedOpCodeProps, // Reserved: 0x000000EA + ReservedOpCodeProps, // Reserved: 0x000000EB + ReservedOpCodeProps, // Reserved: 0x000000EC + ReservedOpCodeProps, // Reserved: 0x000000ED // Create/Annotate Node Handles {OC::AllocateNodeOutputRecords, @@ -2277,32 +2196,10 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = { Attribute::None, 0, {}, - {}}, // Overloads: v - - {OC::Reserved_0x00000103, - "Reserved_0x00000103", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000104, - "Reserved_0x00000104", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000105, - "Reserved_0x00000105", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v + {}}, // Overloads: v + ReservedOpCodeProps, // Reserved: 0x00000103 + ReservedOpCodeProps, // Reserved: 0x00000104 + ReservedOpCodeProps, // Reserved: 0x00000105 // Shader Execution Reordering {OC::HitObject_TraceRay, @@ -2528,112 +2425,20 @@ static const OP::OpCodeProperty CoreOps_OpCodeProps[] = { Attribute::ArgMemOnly, 1, {{0x100}}, - {{0x0}}}, // Overloads: u - - {OC::Reserved_0x00000122, - "Reserved_0x00000122", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000123, - "Reserved_0x00000123", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000124, - "Reserved_0x00000124", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000125, - "Reserved_0x00000125", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000126, - "Reserved_0x00000126", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000127, - "Reserved_0x00000127", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000128, - "Reserved_0x00000128", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x00000129, - "Reserved_0x00000129", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x0000012A, - "Reserved_0x0000012A", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x0000012B, - "Reserved_0x0000012B", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x0000012C, - "Reserved_0x0000012C", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x0000012D, - "Reserved_0x0000012D", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v - {OC::Reserved_0x0000012E, - "Reserved_0x0000012E", - OCC::Reserved, - "reserved", - Attribute::None, - 0, - {}, - {}}, // Overloads: v + {{0x0}}}, // Overloads: u + ReservedOpCodeProps, // Reserved: 0x00000122 + ReservedOpCodeProps, // Reserved: 0x00000123 + ReservedOpCodeProps, // Reserved: 0x00000124 + ReservedOpCodeProps, // Reserved: 0x00000125 + ReservedOpCodeProps, // Reserved: 0x00000126 + ReservedOpCodeProps, // Reserved: 0x00000127 + ReservedOpCodeProps, // Reserved: 0x00000128 + ReservedOpCodeProps, // Reserved: 0x00000129 + ReservedOpCodeProps, // Reserved: 0x0000012A + ReservedOpCodeProps, // Reserved: 0x0000012B + ReservedOpCodeProps, // Reserved: 0x0000012C + ReservedOpCodeProps, // Reserved: 0x0000012D + ReservedOpCodeProps, // Reserved: 0x0000012E // Resources {OC::RawBufferVectorLoad, @@ -2975,32 +2780,10 @@ static const OP::OpCodeProperty ExperimentalOps_OpCodeProps[] = { Attribute::None, 2, {{0x400}, {0x400}}, - {{0x63}, {0x63}}}, // Overloads: = DXIL::NumOpCodeTables) return false; + OP::OpCodeTable &Table = OP::g_OpCodeTables[TableIndex]; unsigned Op = (EncodedOpCode & 0xFFFF); - if (Op >= OP::g_OpCodeTables[TableIndex].Count) + if (Op >= Table.Count) return false; TableID = (OP::OpCodeTableID)TID; OpIndex = Op; if (OptTableIndex) *OptTableIndex = TableIndex; - return true; + return Table.Table[Op].opCode != OP::OpCode::Invalid; } bool OP::DecodeOpCode(OpCode EncodedOpCode, OP::OpCodeTableID &TableID, unsigned &OpIndex, unsigned *OptTableIndex) { @@ -3092,6 +2876,19 @@ bool OP::IsValidOpCode(unsigned EncodedOpCode) { bool OP::IsValidOpCode(OP::OpCode EncodedOpCode) { return IsValidOpCode((unsigned)EncodedOpCode); } +bool OP::IsReservedOpCode(unsigned EncodedOpCode) { + if (EncodedOpCode == (unsigned)OP::OpCode::Invalid) + return false; + OP::OpCodeTableID TID = (OP::OpCodeTableID)(EncodedOpCode >> 16); + unsigned TableIndex = GetOpCodeTableIndex(TID); + if (TableIndex >= DXIL::NumOpCodeTables) + return false; + OP::OpCodeTable &Table = OP::g_OpCodeTables[TableIndex]; + unsigned Op = (EncodedOpCode & 0xFFFF); + if (Op >= Table.Count) + return false; + return Table.Table[Op].opCodeClass == OP::OpCodeClass::Reserved; +} const OP::OpCodeProperty &OP::GetOpCodeProps(unsigned OriginalOpCode) { OP::OpCodeTableID TID = OP::OpCodeTableID::CoreOps; unsigned Op = 0; @@ -3282,6 +3079,9 @@ bool OP::CheckOpCodeTable() { const OP::OpCodeTable &Table = OP::g_OpCodeTables[TableIndex]; for (unsigned OpIndex = 0; OpIndex < Table.Count; OpIndex++) { const OP::OpCodeProperty &Prop = Table.Table[OpIndex]; + // Skip reserved opcodes, which must never be used. + if ((unsigned)Prop.opCode == (unsigned)OP::OpCode::Invalid) + continue; OP::OpCodeTableID DecodedTID; unsigned DecodedOpIndex; unsigned DecodedTableIndex; @@ -5936,56 +5736,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) { A(pI32); break; - // - case OpCode::Reserved_0x000000E2: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000E3: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000E4: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000E5: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000E6: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000E7: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000E8: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000E9: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000EA: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000EB: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000EC: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x000000ED: - A(pV); - A(pI32); - break; - // Create/Annotate Node Handles case OpCode::AllocateNodeOutputRecords: A(pNodeRecordHandle); @@ -6145,20 +5895,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) { A(pI32); break; - // - case OpCode::Reserved_0x00000103: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000104: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000105: - A(pV); - A(pI32); - break; - // Shader Execution Reordering case OpCode::HitObject_TraceRay: A(pHit); @@ -6339,60 +6075,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) { A(udt); break; - // - case OpCode::Reserved_0x00000122: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000123: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000124: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000125: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000126: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000127: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000128: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x00000129: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x0000012A: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x0000012B: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x0000012C: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x0000012D: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x0000012E: - A(pV); - A(pI32); - break; - // Resources case OpCode::RawBufferVectorLoad: RRT(pETy); @@ -6690,20 +6372,6 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) { EXT(1); break; - // - case OpCode::Reserved_0x8000001E: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x8000001F: - A(pV); - A(pI32); - break; - case OpCode::Reserved_0x80000020: - A(pV); - A(pI32); - break; - // Debugging case OpCode::DebugBreak: A(pV); @@ -6958,18 +6626,6 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { case OpCode::AnnotateHandle: case OpCode::CreateHandleFromBinding: case OpCode::CreateHandleFromHeap: - case OpCode::Reserved_0x000000E2: - case OpCode::Reserved_0x000000E3: - case OpCode::Reserved_0x000000E4: - case OpCode::Reserved_0x000000E5: - case OpCode::Reserved_0x000000E6: - case OpCode::Reserved_0x000000E7: - case OpCode::Reserved_0x000000E8: - case OpCode::Reserved_0x000000E9: - case OpCode::Reserved_0x000000EA: - case OpCode::Reserved_0x000000EB: - case OpCode::Reserved_0x000000EC: - case OpCode::Reserved_0x000000ED: case OpCode::AllocateNodeOutputRecords: case OpCode::IncrementOutputCount: case OpCode::OutputComplete: @@ -6986,28 +6642,12 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { case OpCode::NodeOutputIsValid: case OpCode::GetRemainingRecursionLevels: case OpCode::AllocateRayQuery2: - case OpCode::Reserved_0x00000103: - case OpCode::Reserved_0x00000104: - case OpCode::Reserved_0x00000105: case OpCode::HitObject_FromRayQuery: case OpCode::HitObject_MakeMiss: case OpCode::HitObject_MakeNop: case OpCode::MaybeReorderThread: case OpCode::HitObject_SetShaderTableIndex: case OpCode::HitObject_LoadLocalRootTableConstant: - case OpCode::Reserved_0x00000122: - case OpCode::Reserved_0x00000123: - case OpCode::Reserved_0x00000124: - case OpCode::Reserved_0x00000125: - case OpCode::Reserved_0x00000126: - case OpCode::Reserved_0x00000127: - case OpCode::Reserved_0x00000128: - case OpCode::Reserved_0x00000129: - case OpCode::Reserved_0x0000012A: - case OpCode::Reserved_0x0000012B: - case OpCode::Reserved_0x0000012C: - case OpCode::Reserved_0x0000012D: - case OpCode::Reserved_0x0000012E: case OpCode::ExperimentalNop: case OpCode::GetGroupWaveIndex: case OpCode::GetGroupWaveCount: @@ -7025,9 +6665,6 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) { case OpCode::MatrixAccumulate: case OpCode::MatrixAccumulateToDescriptor: case OpCode::MatrixAccumulateToMemory: - case OpCode::Reserved_0x8000001E: - case OpCode::Reserved_0x8000001F: - case OpCode::Reserved_0x80000020: case OpCode::DebugBreak: case OpCode::IsDebuggerPresent: return Type::getVoidTy(Ctx); diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp index 624d0b8dc6..7739c105d9 100644 --- a/lib/DxilValidation/DxilValidation.cpp +++ b/lib/DxilValidation/DxilValidation.cpp @@ -3293,10 +3293,13 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) { OP::OpCodeTableID TableID; unsigned OpIndex; if (!OP::DecodeOpCode(Opcode, TableID, OpIndex)) { + std::string OpCodeStr = std::to_string(Opcode); + if (OP::IsReservedOpCode(Opcode)) + OpCodeStr += " (reserved opcode)"; ValCtx.EmitInstrFormatError( &I, ValidationRule::InstrIllegalDXILOpCode, {std::to_string((unsigned)DXIL::OpCode::NumOpCodes), - std::to_string(Opcode)}); + OpCodeStr}); continue; } if (TableID != OP::OpCodeTableID::CoreOps && diff --git a/tools/clang/test/LitDXILValidation/reservedDXILOp.ll b/tools/clang/test/LitDXILValidation/reservedDXILOp.ll new file mode 100644 index 0000000000..2c4b569f59 --- /dev/null +++ b/tools/clang/test/LitDXILValidation/reservedDXILOp.ll @@ -0,0 +1,39 @@ +; REQUIRES: dxil-1-10 +; RUN: not %dxv %s 2>&1 | FileCheck %s + +; Make sure that using a reserved DXIL opcode produces an appropriate error. + +; 302 is currently reserved. If it is ever assigned to a valid DXIL op, +; this test should be updated to use a different reserved opcode. +; See "Reserved values:" comment in main DXIL::OpCode definition in +; DxilConstants.h for reserved opcodes. + +; CHECK: error: DXILOpCode must be [0..{{[0-9]+}}] or a supported experimental opcode. 302 (reserved opcode) specified. +; CHECK: note: at 'call void @dx.op.reserved(i32 302)' in block '#0' of function 'main'. + +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +define void @main() { + call void @dx.op.reserved(i32 302) + ret void +} + +; Function Attrs: nounwind +declare void @dx.op.reserved(i32) #0 + +attributes #0 = { nounwind} + +!llvm.ident = !{!0} +!dx.version = !{!1} +!dx.valver = !{!1} +!dx.shaderModel = !{!2} +!dx.resources = !{!3} +!dx.entryPoints = !{!4} + +!0 = !{!"hand-crafted"} +!1 = !{i32 1, i32 10} +!2 = !{!"vs", i32 6, i32 10} +!3 = !{null, null, null, null} +!4 = !{void ()* @main, !"main", !5, !3, null} +!5 = !{null, null, null} diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index e1fc66e840..533851ce8a 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -70,6 +70,7 @@ def __init__(self, value, name, doc): self.name = name # Name (identifier) self.doc = doc # Documentation string self.category = None + self.reserved = False # whether value reserved and excluded from enum definition class db_dxil_enum(object): @@ -418,6 +419,15 @@ def __getitem__(self, idx): def __iter__(self): return iter(self.ops) + def get_dxil_ops(self, include_reserved=False): + "Get all DXIL operations; optionally include_reserved." + if include_reserved: + return iter(self.ops) + for i in self.ops: + if i.is_reserved: + continue + yield i + def set_op_count_for_version(self, major, minor): op_count = len(self.ops) self.op_enum.dxil_version_info[(major, minor)] = op_count @@ -453,18 +463,14 @@ def add_dxil_op( def add_dxil_op_reserved(self): "Reserve a DXIL opcode for future use; returns the reserved op." - opcode = self._next_id() - # Give the reserved opcode a unique, stable name. This allows ops to be - # replaced with reserved without changing any other reserved op names. - name = f"Reserved_0x{opcode:08X}" # The return value is parameter 0, insert the opcode as 1. op_params = [db_dxil_param(0, "v", "", "reserved"), self.opcode_param] i = db_dxil_inst( - name, + "Reserved", llvm_id=self.call_instr.llvm_id, llvm_name=self.call_instr.llvm_name, - dxil_op=name, - dxil_opid=opcode, + dxil_op="Reserved", + dxil_opid=self._next_id(), dxil_table=self.name, doc="reserved", ops=op_params, @@ -528,18 +534,22 @@ def get_llvm_insts(self): for i in self._llvm_insts: yield i - def get_dxil_ops(self): - "Get all DXIL operations." + def get_dxil_ops(self, include_reserved=False): + "Get all DXIL operations; optionally include_reserved." for table in self.op_tables: for i in table: + if not include_reserved and i.is_reserved: + continue yield i - def get_all_insts(self): - "Get all instructions, including LLVM and DXIL operations." + def get_all_insts(self, include_reserved=False): + "Get all LLVM instructions and DXIL operations; optionally include_reserved." for i in self._llvm_insts: yield i for table in self.op_tables: for i in table: + if not include_reserved and i.is_reserved: + continue yield i def get_insts_by_names(self, *names): @@ -600,8 +610,9 @@ def build_opcode_enum(self): for i in table: v = table.op_enum.add_value(i.dxil_op_index(), i.dxil_op, i.doc) v.category = i.category + v.reserved = i.is_reserved class_dict[i.dxil_class] = i.category - if table != self.core_table: + if table != self.core_table and not i.is_reserved: # // = 0x, U, # Signed id is useful for comparing with IR opcodes, which # are printed as signed i32 values. @@ -9394,6 +9405,8 @@ def add_valrule_msg(self, name, desc, err_msg): ) def add_inst(self, i): + if i.is_reserved: + return i if i.name != "UDiv": # These should not overlap, but UDiv is a known collision. assert i.name not in self.name_idx, f"Duplicate instruction name: {i.name}" diff --git a/utils/hct/hctdb_instrhelp.py b/utils/hct/hctdb_instrhelp.py index 7e2f8b89d7..f238574562 100644 --- a/utils/hct/hctdb_instrhelp.py +++ b/utils/hct/hctdb_instrhelp.py @@ -426,10 +426,10 @@ def print_enum(self, e, **kwargs): print("// %s" % e.doc) print("enum class %s : unsigned {" % e.name) hide_val = kwargs.get("hide_val", False) - sorted_values = e.values + sorted_values = filter(lambda v: not v.reserved, e.values) if kwargs.get("sort_val", True): sorted_values = sorted( - e.values, + sorted_values, key=lambda v: ("" if v.category == None else v.category) + "." + v.name, ) last_category = None @@ -447,6 +447,12 @@ def print_enum(self, e, **kwargs): if v.doc: line_format += " // {doc}" print(line_format.format(name=v.name, value=v.value, doc=v.doc)) + # Print unnamed reserved values separately. + reserved_values = list(filter(lambda v: v.reserved, e.values)) + if len(reserved_values) > 0: + print("") + print(" // Reserved values:") + print(" // " + ", ".join([str(v.value) for v in reserved_values])) if e.last_value_name: lastName = e.last_value_name versioned = [ @@ -462,7 +468,7 @@ def print_enum(self, e, **kwargs): " " + lastName + " = " - + str(len(sorted_values)) + + str(len(e.values)) + ", // exclusive last value of enumeration" ) if e.postfix_lines: @@ -551,11 +557,13 @@ def print_opfunc_props_for_table(self, table): "{" + ",".join(["{0x%x}" % m for m in oloads]) + "}" ) for i in table: + if i.is_reserved: + print(f"ReservedOpCodeProps, // Reserved: 0x{i.dxil_opid:08X}") + continue if last_category != i.category: if last_category != None: print("") - if not i.is_reserved: - print(f" // {i.category}") + print(f" // {i.category}") last_category = i.category scalar_masks = [] vector_masks = [] @@ -1415,7 +1423,7 @@ def get_opcodes_rst(): def get_opcodes_rst_for_table(table): "Create an rst table of opcodes for given opcode table" - instrs = [i for i in table] + instrs = [i for i in table.get_dxil_ops()] rows = [] rows.append(["ID", "Name", "Description"]) for i in instrs: From bf8b6ddac94d286a8a7a680599946a5264b36a76 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Wed, 4 Feb 2026 18:13:35 -0800 Subject: [PATCH 3/3] formatting --- utils/hct/hctdb.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 533851ce8a..1a56396c78 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -70,7 +70,8 @@ def __init__(self, value, name, doc): self.name = name # Name (identifier) self.doc = doc # Documentation string self.category = None - self.reserved = False # whether value reserved and excluded from enum definition + # reserved: whether value reserved and excluded from enum definition + self.reserved = False class db_dxil_enum(object): @@ -482,10 +483,7 @@ def add_dxil_op_reserved(self): def reserve_dxil_ops(self, count=1): "Reserve dxil opcodes for future use; returns list of reserved ops." - return [ - self.add_dxil_op_reserved() - for i in range(0, count) - ] + return [self.add_dxil_op_reserved() for i in range(0, count)] class db_dxil(object):