Commit 074ba69ba6

Robin Voetter <robin@voetter.nl>
2022-01-30 20:48:16
spirv: assembler
spirv: introduce SpvModule.Fn to generate function code into spirv: assembler error message setup spirv: runtime spec info spirv: inline assembly tokenizer spirv: inline assembly lhs result/opcode parsing spirv: forgot to fmt spirv: tokenize opcodes and assigned result-ids spirv: operand parsing setup spirv: assembler string literals spirv: assembler integer literals spirv: assembler value enums spirv: assembler bit masks spirv: update assembler to new asm air format spirv: target 1.5 for now Current vulkan sdk version (1.3.204) ships spirv tools targetting 1.5, and so these do not work with binaries targetting 1.6 yet. In the future, this version number should be decided by the target. spirv: store operands in flat arraylist. Instead of having dedicated Operand variants for variadic operands, just flatten them and store them in the normal inst.operands list. This is a little simpler, but is not easily decodable in the operand data representation. spirv: parse variadic assembly operands spirv: improve assembler result-id tokenization spirv: begin instruction processing spirv: only remove decl if it was actually allocated spirv: work around weird miscompilation Seems like there are problems with switch in anonymous struct literals. spirv: begin resolving some types in assembler spirv: improve instruction processing spirv: rename some types + process OpTypeInt spirv: process OpTypeVector spirv: process OpTypeMatrix and OpTypeSampler spirv: add opcode class to spec, remove @exclude'd instructions spirv: process more type instructions spirv: OpTypeFunction spirv: OpTypeOpaque spirv: parse LiteralContextDependentNumber operands spirv: emit assembly instruction into right section spirv: parse OpPhi parameters spirv: inline assembly inputs spirv: also copy air types spirv: inline assembly outputs spirv: spir-v address spaces spirv: basic vector constants/types and shuffle spirv: assembler OpTypeImage spirv: some stuff spirv: remove spirv address spaces for now
1 parent 32ce2f9
lib/std/builtin.zig
@@ -168,7 +168,7 @@ pub const AddressSpace = enum {
     gs,
     fs,
     ss,
-    // GPU address spaces
+    // GPU address spaces.
     global,
     constant,
     param,
lib/std/target.zig
@@ -1179,10 +1179,12 @@ pub const Target = struct {
             /// Returns whether this architecture supports the address space
             pub fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
                 const is_nvptx = arch == .nvptx or arch == .nvptx64;
+                const is_spirv = arch == .spirv32 or arch == .spirv64;
+                const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
                 return switch (address_space) {
                     .generic => true,
                     .fs, .gs, .ss => arch == .x86_64 or arch == .x86,
-                    .global, .constant, .local, .shared => arch == .amdgcn or is_nvptx,
+                    .global, .constant, .local, .shared => is_gpu,
                     .param => is_nvptx,
                 };
             }
src/codegen/spirv/Assembler.zig
@@ -0,0 +1,1017 @@
+const Assembler = @This();
+
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
+
+const spec = @import("spec.zig");
+const Opcode = spec.Opcode;
+const Word = spec.Word;
+const IdRef = spec.IdRef;
+const IdResult = spec.IdResult;
+
+const SpvModule = @import("Module.zig");
+const SpvType = @import("type.zig").Type;
+
+/// Represents a token in the assembly template.
+const Token = struct {
+    tag: Tag,
+    start: u32,
+    end: u32,
+
+    const Tag = enum {
+        /// Returned when there was no more input to match.
+        eof,
+        /// %identifier
+        result_id,
+        /// %identifier when appearing on the LHS of an equals sign.
+        /// While not technically a token, its relatively easy to resolve
+        /// this during lexical analysis and relieves a bunch of headaches
+        /// during parsing.
+        result_id_assign,
+        /// Mask, int, or float. These are grouped together as some
+        /// SPIR-V enumerants look a bit like integers as well (for example
+        /// "3D"), and so it is easier to just interpret them as the expected
+        /// type when resolving an instruction's operands.
+        value,
+        /// An enumerant that looks like an opcode, that is, OpXxxx.
+        /// Not necessarily a *valid* opcode.
+        opcode,
+        /// String literals.
+        /// Note, this token is also returned for unterminated
+        /// strings. In this case the closing " is not present.
+        string,
+        /// |.
+        pipe,
+        /// =.
+        equals,
+
+        fn name(self: Tag) []const u8 {
+            return switch (self) {
+                .eof => "<end of input>",
+                .result_id => "<result-id>",
+                .result_id_assign => "<assigned result-id>",
+                .value => "<value>",
+                .opcode => "<opcode>",
+                .string => "<string literal>",
+                .pipe => "'|'",
+                .equals => "'='",
+            };
+        }
+    };
+};
+
+/// This union represents utility information for a decoded operand.
+/// Note that this union only needs to maintain a minimal amount of
+/// bookkeeping: these values are enough to either decode the operands
+/// into a spec type, or emit it directly into its binary form.
+const Operand = union(enum) {
+    /// Any 'simple' 32-bit value. This could be a mask or
+    /// enumerant, etc, depending on the operands.
+    value: u32,
+
+    /// An int- or float literal encoded as 1 word. This may be
+    /// a 32-bit literal or smaller, already in the proper format:
+    /// the opper bits are 0 for floats and unsigned ints, and sign-extended
+    /// for signed ints.
+    literal32: u32,
+
+    /// An int- or float literal encoded as 2 words. This may be a 33-bit
+    /// to 64 bit literal, already in the proper format:
+    /// the opper bits are 0 for floats and unsigned ints, and sign-extended
+    /// for signed ints.
+    literal64: u64,
+
+    /// A result-id which is assigned to in this instruction. If present,
+    /// this is the first operand of the instruction.
+    result_id: AsmValue.Ref,
+
+    /// A result-id which referred to (not assigned to) in this instruction.
+    ref_id: AsmValue.Ref,
+
+    /// Offset into `inst.string_bytes`. The string ends at the next zero-terminator.
+    string: u32,
+};
+
+/// A structure representing an error message that the assembler may return, when
+/// the assembly source is not syntactically or semantically correct.
+const ErrorMsg = struct {
+    /// The offset in bytes from the start of `src` that this error occured.
+    byte_offset: u32,
+    /// An explanatory error message.
+    /// Memory is owned by `self.gpa`. TODO: Maybe allocate this with an arena
+    /// allocator if it is needed elsewhere?
+    msg: []const u8,
+};
+
+/// Possible errors the `assemble` function may return.
+const Error = error{ AssembleFail, OutOfMemory };
+
+/// This union is used to keep track of results of spir-v instructions. This can either be just a plain
+/// result-id, in the case of most instructions, or for example a type that is constructed from
+/// an OpTypeXxx instruction.
+const AsmValue = union(enum) {
+    /// The results are stored in an array hash map, and can be referred to either by name (without the %),
+    /// or by values of this index type.
+    pub const Ref = u32;
+
+    /// This result-value is the RHS of the current instruction.
+    just_declared,
+
+    /// This is used as placeholder for ref-ids of which the result-id is not yet known.
+    /// It will be further resolved at a later stage to a more concrete forward reference.
+    unresolved_forward_reference,
+
+    /// This result-value is a normal result produced by a different instruction.
+    value: IdRef,
+
+    /// This result-value represents a type registered into the module's type system.
+    ty: SpvType.Ref,
+
+    /// Retrieve the result-id of this AsmValue. Asserts that this AsmValue
+    /// is of a variant that allows the result to be obtained (not an unresolved
+    /// forward declaration, not in the process of being declared, etc).
+    pub fn resultId(self: AsmValue, spv: *const SpvModule) IdRef {
+        return switch (self) {
+            .just_declared, .unresolved_forward_reference => unreachable,
+            .value => |result| result,
+            .ty => |ref| spv.typeResultId(ref).toRef(),
+        };
+    }
+};
+
+/// This map type maps results to values. Results can be addressed either by name (without the %), or by
+/// AsmValue.Ref in AsmValueMap.keys/.values.
+const AsmValueMap = std.StringArrayHashMapUnmanaged(AsmValue);
+
+/// An allocator used for common allocations.
+gpa: Allocator,
+
+/// A list of errors that occured during processing the assembly.
+errors: std.ArrayListUnmanaged(ErrorMsg) = .{},
+
+/// The source code that is being assembled.
+src: []const u8,
+
+/// The module that this assembly is associated to.
+/// Instructions like OpType*, OpDecorate, etc are emitted into this module.
+spv: *SpvModule,
+
+/// The function that the function-specific instructions should be emitted to.
+func: *SpvModule.Fn,
+
+/// `self.src` tokenized.
+tokens: std.ArrayListUnmanaged(Token) = .{},
+
+/// The token that is next during parsing.
+current_token: u32 = 0,
+
+/// This field groups the properties of the instruction that is currently
+/// being parsed or has just been parsed.
+inst: struct {
+    /// The opcode of the current instruction.
+    opcode: Opcode = undefined,
+    /// Operands of the current instruction.
+    operands: std.ArrayListUnmanaged(Operand) = .{},
+    /// This is where string data resides. Strings are zero-terminated.
+    string_bytes: std.ArrayListUnmanaged(u8) = .{},
+
+    /// Return a reference to the result of this instruction, if any.
+    fn result(self: @This()) ?AsmValue.Ref {
+        // The result, if present, is either the first or second
+        // operand of an instruction.
+        for (self.operands.items[0..@min(self.operands.items.len, 2)]) |op| {
+            switch (op) {
+                .result_id => |index| return index,
+                else => {},
+            }
+        }
+        return null;
+    }
+} = .{},
+
+/// This map maps results to their tracked values.
+value_map: AsmValueMap = .{},
+
+/// Free the resources owned by this assembler.
+pub fn deinit(self: *Assembler) void {
+    for (self.errors.items) |err| {
+        self.gpa.free(err.msg);
+    }
+    self.tokens.deinit(self.gpa);
+    self.errors.deinit(self.gpa);
+    self.inst.operands.deinit(self.gpa);
+    self.inst.string_bytes.deinit(self.gpa);
+    self.value_map.deinit(self.gpa);
+}
+
+pub fn assemble(self: *Assembler) Error!void {
+    try self.tokenize();
+    while (!self.testToken(.eof)) {
+        try self.parseInstruction();
+        try self.processInstruction();
+    }
+    if (self.errors.items.len > 0)
+        return error.AssembleFail;
+}
+
+fn addError(self: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) !void {
+    const msg = try std.fmt.allocPrint(self.gpa, fmt, args);
+    errdefer self.gpa.free(msg);
+    try self.errors.append(self.gpa, .{
+        .byte_offset = offset,
+        .msg = msg,
+    });
+}
+
+fn fail(self: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) Error {
+    try self.addError(offset, fmt, args);
+    return error.AssembleFail;
+}
+
+fn todo(self: *Assembler, comptime fmt: []const u8, args: anytype) Error {
+    return self.fail(0, "todo: " ++ fmt, args);
+}
+
+/// Attempt to process the instruction currently in `self.inst`.
+/// This for example emits the instruction in the module or function, or
+/// records type definitions.
+/// If this function returns `error.AssembleFail`, an explanatory
+/// error message has already been emitted into `self.errors`.
+fn processInstruction(self: *Assembler) !void {
+    const result = switch (self.inst.opcode.class()) {
+        .TypeDeclaration => try self.processTypeInstruction(),
+        else => if (try self.processGenericInstruction()) |result|
+            result
+        else
+            return,
+    };
+
+    const result_ref = self.inst.result().?;
+    switch (self.value_map.values()[result_ref]) {
+        .just_declared => self.value_map.values()[result_ref] = result,
+        else => {
+            // TODO: Improve source location.
+            const name = self.value_map.keys()[result_ref];
+            return self.fail(0, "duplicate definition of %{s}", .{name});
+        },
+    }
+}
+
+/// Record `self.inst` into the module's type system, and return the AsmValue that
+/// refers to the result.
+fn processTypeInstruction(self: *Assembler) !AsmValue {
+    const operands = self.inst.operands.items;
+    const ty = switch (self.inst.opcode) {
+        .OpTypeVoid => SpvType.initTag(.void),
+        .OpTypeBool => SpvType.initTag(.bool),
+        .OpTypeInt => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Int);
+            const signedness: std.builtin.Signedness = switch (operands[2].literal32) {
+                0 => .unsigned,
+                1 => .signed,
+                else => {
+                    // TODO: Improve source location.
+                    return self.fail(0, "'{}' is not a valid signedness (expected 0 or 1)", .{operands[2].literal32});
+                },
+            };
+            payload.* = .{
+                .width = operands[1].literal32,
+                .signedness = signedness,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeFloat => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Float);
+            payload.* = .{
+                .width = operands[1].literal32,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeVector => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Vector);
+            payload.* = .{
+                .component_type = try self.resolveTypeRef(operands[1].ref_id),
+                .component_count = operands[2].literal32,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeMatrix => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Matrix);
+            payload.* = .{
+                .column_type = try self.resolveTypeRef(operands[1].ref_id),
+                .column_count = operands[2].literal32,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeImage => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Image);
+            payload.* = .{
+                .sampled_type = try self.resolveTypeRef(operands[1].ref_id),
+                .dim = @intToEnum(spec.Dim, operands[2].value),
+                .depth = switch (operands[3].literal32) {
+                    0 => .no,
+                    1 => .yes,
+                    2 => .maybe,
+                    else => {
+                        return self.fail(0, "'{}' is not a valid image depth (expected 0, 1 or 2)", .{operands[3].literal32});
+                    },
+                },
+                .arrayed = switch (operands[4].literal32) {
+                    0 => false,
+                    1 => true,
+                    else => {
+                        return self.fail(0, "'{}' is not a valid image arrayed-ness (expected 0 or 1)", .{operands[4].literal32});
+                    },
+                },
+                .multisampled = switch (operands[5].literal32) {
+                    0 => false,
+                    1 => true,
+                    else => {
+                        return self.fail(0, "'{}' is not a valid image multisampled-ness (expected 0 or 1)", .{operands[5].literal32});
+                    },
+                },
+                .sampled = switch (operands[6].literal32) {
+                    0 => .known_at_runtime,
+                    1 => .with_sampler,
+                    2 => .without_sampler,
+                    else => {
+                        return self.fail(0, "'{}' is not a valid image sampled-ness (expected 0, 1 or 2)", .{operands[6].literal32});
+                    },
+                },
+                .format = @intToEnum(spec.ImageFormat, operands[7].value),
+                .access_qualifier = if (operands.len > 8)
+                    @intToEnum(spec.AccessQualifier, operands[8].value)
+                else
+                    null,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeSampler => SpvType.initTag(.sampler),
+        .OpTypeSampledImage => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.SampledImage);
+            payload.* = .{
+                .image_type = try self.resolveTypeRef(operands[1].ref_id),
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeArray => {
+            // TODO: The length of an OpTypeArray is determined by a constant (which may be a spec constant),
+            // and so some consideration must be taken when entering this in the type system.
+            return self.todo("process OpTypeArray", .{});
+        },
+        .OpTypeRuntimeArray => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.RuntimeArray);
+            payload.* = .{
+                .element_type = try self.resolveTypeRef(operands[1].ref_id),
+                // TODO: Fetch array stride from decorations.
+                .array_stride = 0,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeOpaque => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Opaque);
+            const name_offset = operands[1].string;
+            payload.* = .{
+                .name = std.mem.sliceTo(self.inst.string_bytes.items[name_offset..], 0),
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypePointer => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Pointer);
+            payload.* = .{
+                .storage_class = @intToEnum(spec.StorageClass, operands[1].value),
+                .child_type = try self.resolveTypeRef(operands[2].ref_id),
+                // TODO: Fetch these values from decorations.
+                .array_stride = 0,
+                .alignment = null,
+                .max_byte_offset = null,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeFunction => blk: {
+            const param_operands = operands[2..];
+            const param_types = try self.spv.arena.alloc(SpvType.Ref, param_operands.len);
+            for (param_types) |*param, i| {
+                param.* = try self.resolveTypeRef(param_operands[i].ref_id);
+            }
+            const payload = try self.spv.arena.create(SpvType.Payload.Function);
+            payload.* = .{
+                .return_type = try self.resolveTypeRef(operands[1].ref_id),
+                .parameters = param_types,
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypeEvent => SpvType.initTag(.event),
+        .OpTypeDeviceEvent => SpvType.initTag(.device_event),
+        .OpTypeReserveId => SpvType.initTag(.reserve_id),
+        .OpTypeQueue => SpvType.initTag(.queue),
+        .OpTypePipe => blk: {
+            const payload = try self.spv.arena.create(SpvType.Payload.Pipe);
+            payload.* = .{
+                .qualifier = @intToEnum(spec.AccessQualifier, operands[1].value),
+            };
+            break :blk SpvType.initPayload(&payload.base);
+        },
+        .OpTypePipeStorage => SpvType.initTag(.pipe_storage),
+        .OpTypeNamedBarrier => SpvType.initTag(.named_barrier),
+        else => return self.todo("process type instruction {s}", .{@tagName(self.inst.opcode)}),
+    };
+
+    const ref = try self.spv.resolveType(ty);
+    return AsmValue{ .ty = ref };
+}
+
+/// Emit `self.inst` into `self.spv` and `self.func`, and return the AsmValue
+/// that this produces (if any). This function processes common instructions:
+/// - No forward references are allowed in operands.
+/// - Target section is determined from instruction type.
+/// - Function-local instructions are emitted in `self.func`.
+fn processGenericInstruction(self: *Assembler) !?AsmValue {
+    const operands = self.inst.operands.items;
+    const section = switch (self.inst.opcode.class()) {
+        .ConstantCreation => &self.spv.sections.types_globals_constants,
+        .Annotation => &self.spv.sections.annotations,
+        .TypeDeclaration => unreachable, // Handled elsewhere.
+        else => switch (self.inst.opcode) {
+            .OpEntryPoint => &self.spv.sections.entry_points,
+            .OpExecutionMode, .OpExecutionModeId => &self.spv.sections.execution_modes,
+            .OpVariable => switch (@intToEnum(spec.StorageClass, operands[2].value)) {
+                .Function => &self.func.prologue,
+                else => &self.spv.sections.types_globals_constants,
+            },
+            // Default case - to be worked out further.
+            else => &self.func.body,
+        },
+    };
+
+    var maybe_result_id: ?IdResult = null;
+    const first_word = section.instructions.items.len;
+    // At this point we're not quite sure how many operands this instruction is going to have,
+    // so insert 0 and patch up the actual opcode word later.
+    try section.ensureUnusedCapacity(self.spv.gpa, 1);
+    section.writeWord(0);
+
+    for (operands) |operand| {
+        switch (operand) {
+            .value, .literal32 => |word| {
+                try section.ensureUnusedCapacity(self.spv.gpa, 1);
+                section.writeWord(word);
+            },
+            .literal64 => |dword| {
+                try section.ensureUnusedCapacity(self.spv.gpa, 2);
+                section.writeDoubleWord(dword);
+            },
+            .result_id => {
+                maybe_result_id = self.spv.allocId();
+                try section.ensureUnusedCapacity(self.spv.gpa, 1);
+                section.writeOperand(IdResult, maybe_result_id.?);
+            },
+            .ref_id => |index| {
+                const result = try self.resolveRef(index);
+                try section.ensureUnusedCapacity(self.spv.gpa, 1);
+                section.writeOperand(spec.IdRef, result.resultId(self.spv));
+            },
+            .string => |offset| {
+                const text = std.mem.sliceTo(self.inst.string_bytes.items[offset..], 0);
+                const size = std.math.divCeil(usize, text.len + 1, @sizeOf(Word)) catch unreachable;
+                try section.ensureUnusedCapacity(self.spv.gpa, size);
+                section.writeOperand(spec.LiteralString, text);
+            },
+        }
+    }
+
+    const actual_word_count = section.instructions.items.len - first_word;
+    section.instructions.items[first_word] |= @as(u32, @intCast(u16, actual_word_count)) << 16 | @enumToInt(self.inst.opcode);
+
+    if (maybe_result_id) |result| {
+        return AsmValue{ .value = result.toRef() };
+    }
+    return null;
+}
+
+/// Resolve a value reference. This function makes sure that the reference is
+/// not self-referential, but it does allow the result to be forward declared.
+fn resolveMaybeForwardRef(self: *Assembler, ref: AsmValue.Ref) !AsmValue {
+    const value = self.value_map.values()[ref];
+    switch (value) {
+        .just_declared => {
+            const name = self.value_map.keys()[ref];
+            // TODO: Improve source location.
+            return self.fail(0, "self-referential parameter %{s}", .{name});
+        },
+        else => return value,
+    }
+}
+
+/// Resolve a value reference. This function
+/// makes sure that the result is not self-referential, nor that it is forward declared.
+fn resolveRef(self: *Assembler, ref: AsmValue.Ref) !AsmValue {
+    const value = try self.resolveMaybeForwardRef(ref);
+    switch (value) {
+        .just_declared => unreachable,
+        .unresolved_forward_reference => {
+            const name = self.value_map.keys()[ref];
+            // TODO: Improve source location.
+            return self.fail(0, "reference to undeclared result-id %{s}", .{name});
+        },
+        else => return value,
+    }
+}
+
+/// Resolve a value reference as type.
+fn resolveTypeRef(self: *Assembler, ref: AsmValue.Ref) !SpvType.Ref {
+    const value = try self.resolveRef(ref);
+    switch (value) {
+        .just_declared, .unresolved_forward_reference => unreachable,
+        .ty => |ty_ref| return ty_ref,
+        else => {
+            const name = self.value_map.keys()[ref];
+            // TODO: Improve source location.
+            return self.fail(0, "expected operand %{s} to refer to a type", .{name});
+        },
+    }
+}
+
+/// Attempt to parse an instruction into `self.inst`.
+/// If this function returns `error.AssembleFail`, an explanatory
+/// error message has been emitted into `self.errors`.
+fn parseInstruction(self: *Assembler) !void {
+    self.inst.opcode = undefined;
+    self.inst.operands.shrinkRetainingCapacity(0);
+    self.inst.string_bytes.shrinkRetainingCapacity(0);
+
+    const lhs_result_tok = self.currentToken();
+    const maybe_lhs_result = if (self.eatToken(.result_id_assign)) blk: {
+        const name = self.tokenText(lhs_result_tok)[1..];
+        const entry = try self.value_map.getOrPut(self.gpa, name);
+        try self.expectToken(.equals);
+        if (!entry.found_existing) {
+            entry.value_ptr.* = .just_declared;
+        }
+        break :blk @intCast(AsmValue.Ref, entry.index);
+    } else null;
+
+    const opcode_tok = self.currentToken();
+    if (maybe_lhs_result != null) {
+        try self.expectToken(.opcode);
+    } else if (!self.eatToken(.opcode)) {
+        return self.fail(opcode_tok.start, "expected start of instruction, found {s}", .{opcode_tok.tag.name()});
+    }
+
+    const opcode_text = self.tokenText(opcode_tok);
+    @setEvalBranchQuota(10000);
+    self.inst.opcode = std.meta.stringToEnum(Opcode, opcode_text) orelse {
+        return self.fail(opcode_tok.start, "invalid opcode '{s}'", .{opcode_text});
+    };
+
+    const expected_operands = self.inst.opcode.operands();
+    // This is a loop because the result-id is not always the first operand.
+    const requires_lhs_result = for (expected_operands) |op| {
+        if (op.kind == .IdResult) break true;
+    } else false;
+
+    if (requires_lhs_result and maybe_lhs_result == null) {
+        return self.fail(opcode_tok.start, "opcode '{s}' expects result on left-hand side", .{@tagName(self.inst.opcode)});
+    } else if (!requires_lhs_result and maybe_lhs_result != null) {
+        return self.fail(
+            lhs_result_tok.start,
+            "opcode '{s}' does not expect a result-id on the left-hand side",
+            .{@tagName(self.inst.opcode)},
+        );
+    }
+
+    for (expected_operands) |operand| {
+        if (operand.kind == .IdResult) {
+            try self.inst.operands.append(self.gpa, .{ .result_id = maybe_lhs_result.? });
+            continue;
+        }
+
+        switch (operand.quantifier) {
+            .required => if (self.isAtInstructionBoundary()) {
+                return self.fail(
+                    self.currentToken().start,
+                    "missing required operand", // TODO: Operand name?
+                    .{},
+                );
+            } else {
+                try self.parseOperand(operand.kind);
+            },
+            .optional => if (!self.isAtInstructionBoundary()) {
+                try self.parseOperand(operand.kind);
+            },
+            .variadic => while (!self.isAtInstructionBoundary()) {
+                try self.parseOperand(operand.kind);
+            },
+        }
+    }
+}
+
+/// Parse a single operand of a particular type.
+fn parseOperand(self: *Assembler, kind: spec.OperandKind) Error!void {
+    switch (kind.category()) {
+        .bit_enum => try self.parseBitEnum(kind),
+        .value_enum => try self.parseValueEnum(kind),
+        .id => try self.parseRefId(),
+        else => switch (kind) {
+            .LiteralInteger => try self.parseLiteralInteger(),
+            .LiteralString => try self.parseString(),
+            .LiteralContextDependentNumber => try self.parseContextDependentNumber(),
+            .PairIdRefIdRef => try self.parsePhiSource(),
+            else => return self.todo("parse operand of type {s}", .{@tagName(kind)}),
+        },
+    }
+}
+
+/// Also handles parsing any required extra operands.
+fn parseBitEnum(self: *Assembler, kind: spec.OperandKind) !void {
+    var tok = self.currentToken();
+    try self.expectToken(.value);
+
+    var text = self.tokenText(tok);
+    if (std.mem.eql(u8, text, "None")) {
+        try self.inst.operands.append(self.gpa, .{ .value = 0 });
+        return;
+    }
+
+    const enumerants = kind.enumerants();
+    var mask: u32 = 0;
+    while (true) {
+        const enumerant = for (enumerants) |enumerant| {
+            if (std.mem.eql(u8, enumerant.name, text))
+                break enumerant;
+        } else {
+            return self.fail(tok.start, "'{s}' is not a valid flag for bitmask {s}", .{ text, @tagName(kind) });
+        };
+        mask |= enumerant.value;
+        if (!self.eatToken(.pipe))
+            break;
+
+        tok = self.currentToken();
+        try self.expectToken(.value);
+        text = self.tokenText(tok);
+    }
+
+    try self.inst.operands.append(self.gpa, .{ .value = mask });
+
+    // Assume values are sorted.
+    // TODO: ensure in generator.
+    for (enumerants) |enumerant| {
+        if ((mask & enumerant.value) == 0)
+            continue;
+
+        for (enumerant.parameters) |param_kind| {
+            if (self.isAtInstructionBoundary()) {
+                return self.fail(self.currentToken().start, "missing required parameter for bit flag '{s}'", .{enumerant.name});
+            }
+
+            try self.parseOperand(param_kind);
+        }
+    }
+}
+
+/// Also handles parsing any required extra operands.
+fn parseValueEnum(self: *Assembler, kind: spec.OperandKind) !void {
+    const tok = self.currentToken();
+    try self.expectToken(.value);
+
+    const text = self.tokenText(tok);
+    const enumerant = for (kind.enumerants()) |enumerant| {
+        if (std.mem.eql(u8, enumerant.name, text))
+            break enumerant;
+    } else {
+        return self.fail(tok.start, "'{s}' is not a valid value for enumeration {s}", .{ text, @tagName(kind) });
+    };
+
+    try self.inst.operands.append(self.gpa, .{ .value = enumerant.value });
+
+    for (enumerant.parameters) |param_kind| {
+        if (self.isAtInstructionBoundary()) {
+            return self.fail(self.currentToken().start, "missing required parameter for enum variant '{s}'", .{enumerant.name});
+        }
+
+        try self.parseOperand(param_kind);
+    }
+}
+
+fn parseRefId(self: *Assembler) !void {
+    const tok = self.currentToken();
+    try self.expectToken(.result_id);
+
+    const name = self.tokenText(tok)[1..];
+    const entry = try self.value_map.getOrPut(self.gpa, name);
+    if (!entry.found_existing) {
+        entry.value_ptr.* = .unresolved_forward_reference;
+    }
+
+    const index = @intCast(AsmValue.Ref, entry.index);
+    try self.inst.operands.append(self.gpa, .{ .ref_id = index });
+}
+
+fn parseLiteralInteger(self: *Assembler) !void {
+    const tok = self.currentToken();
+    try self.expectToken(.value);
+    // According to the SPIR-V machine readable grammar, a LiteralInteger
+    // may consist of one or more words. From the SPIR-V docs it seems like there
+    // only one instruction where multiple words are allowed, the literals that make up the
+    // switch cases of OpSwitch. This case is handled separately, and so we just assume
+    // everything is a 32-bit integer in this function.
+    const text = self.tokenText(tok);
+    const value = std.fmt.parseInt(u32, text, 0) catch {
+        return self.fail(tok.start, "'{s}' is not a valid 32-bit integer literal", .{text});
+    };
+    try self.inst.operands.append(self.gpa, .{ .literal32 = value });
+}
+
+fn parseString(self: *Assembler) !void {
+    const tok = self.currentToken();
+    try self.expectToken(.string);
+    // Note, the string might not have a closing quote. In this case,
+    // an error is already emitted but we are trying to continue processing
+    // anyway, so in this function we have to deal with that situation.
+    const text = self.tokenText(tok);
+    assert(text.len > 0 and text[0] == '"');
+    const literal = if (text.len != 1 and text[text.len - 1] == '"')
+        text[1 .. text.len - 1]
+    else
+        text[1..];
+
+    const string_offset = @intCast(u32, self.inst.string_bytes.items.len);
+    try self.inst.string_bytes.ensureUnusedCapacity(self.gpa, literal.len + 1);
+    self.inst.string_bytes.appendSliceAssumeCapacity(literal);
+    self.inst.string_bytes.appendAssumeCapacity(0);
+
+    try self.inst.operands.append(self.gpa, .{ .string = string_offset });
+}
+
+fn parseContextDependentNumber(self: *Assembler) !void {
+    // For context dependent numbers, the actual type to parse is determined by the instruction.
+    // Currently, this operand appears in OpConstant and OpSpecConstant, where the too-be-parsed type
+    // is determined by the result type. That means that in this instructions we have to resolve the
+    // operand type early and look at the result to see how we need to proceed.
+    assert(self.inst.opcode == .OpConstant or self.inst.opcode == .OpSpecConstant);
+
+    const tok = self.currentToken();
+    const result_type_ref = try self.resolveTypeRef(self.inst.operands.items[0].ref_id);
+    const result_type = self.spv.type_cache.keys()[result_type_ref];
+    switch (result_type.tag()) {
+        .int => {
+            const int = result_type.castTag(.int).?;
+            try self.parseContextDependentInt(int.signedness, int.width);
+        },
+        .float => {
+            const width = result_type.castTag(.float).?.width;
+            switch (width) {
+                16 => try self.parseContextDependentFloat(16),
+                32 => try self.parseContextDependentFloat(32),
+                64 => try self.parseContextDependentFloat(64),
+                else => return self.fail(tok.start, "cannot parse {}-bit float literal", .{width}),
+            }
+        },
+        else => return self.fail(tok.start, "cannot parse literal constant {s}", .{@tagName(result_type.tag())}),
+    }
+}
+
+fn parseContextDependentInt(self: *Assembler, signedness: std.builtin.Signedness, width: u32) !void {
+    const tok = self.currentToken();
+    try self.expectToken(.value);
+
+    if (width == 0 or width > 2 * @bitSizeOf(spec.Word)) {
+        return self.fail(tok.start, "cannot parse {}-bit integer literal", .{width});
+    }
+
+    const text = self.tokenText(tok);
+    invalid: {
+        // Just parse the integer as the next larger integer type, and check if it overflows afterwards.
+        const int = std.fmt.parseInt(i128, text, 0) catch break :invalid;
+        const min = switch (signedness) {
+            .unsigned => 0,
+            .signed => -(@as(i128, 1) << (@intCast(u7, width) - 1)),
+        };
+        const max = (@as(i128, 1) << (@intCast(u7, width) - @boolToInt(signedness == .signed))) - 1;
+        if (int < min or int > max) {
+            break :invalid;
+        }
+
+        // Note, we store the sign-extended version here.
+        if (width <= @bitSizeOf(spec.Word)) {
+            try self.inst.operands.append(self.gpa, .{ .literal32 = @truncate(u32, @bitCast(u128, int)) });
+        } else {
+            try self.inst.operands.append(self.gpa, .{ .literal64 = @truncate(u64, @bitCast(u128, int)) });
+        }
+        return;
+    }
+
+    return self.fail(tok.start, "'{s}' is not a valid {s} {}-bit int literal", .{ text, @tagName(signedness), width });
+}
+
+fn parseContextDependentFloat(self: *Assembler, comptime width: u16) !void {
+    const Float = std.meta.Float(width);
+    const Int = std.meta.Int(.unsigned, width);
+
+    const tok = self.currentToken();
+    try self.expectToken(.value);
+
+    const text = self.tokenText(tok);
+
+    const value = std.fmt.parseFloat(Float, text) catch {
+        return self.fail(tok.start, "'{s}' is not a valid {}-bit float literal", .{ text, width });
+    };
+
+    const float_bits = @bitCast(Int, value);
+    if (width <= @bitSizeOf(spec.Word)) {
+        try self.inst.operands.append(self.gpa, .{ .literal32 = float_bits });
+    } else {
+        assert(width <= 2 * @bitSizeOf(spec.Word));
+        try self.inst.operands.append(self.gpa, .{ .literal64 = float_bits });
+    }
+}
+
+fn parsePhiSource(self: *Assembler) !void {
+    try self.parseRefId();
+    if (self.isAtInstructionBoundary()) {
+        return self.fail(self.currentToken().start, "missing phi block parent", .{});
+    }
+    try self.parseRefId();
+}
+
+/// Returns whether the `current_token` cursor is currently pointing
+/// at the start of a new instruction.
+fn isAtInstructionBoundary(self: Assembler) bool {
+    return switch (self.currentToken().tag) {
+        .opcode, .result_id_assign, .eof => true,
+        else => false,
+    };
+}
+
+fn expectToken(self: *Assembler, tag: Token.Tag) !void {
+    if (self.eatToken(tag))
+        return;
+
+    return self.fail(self.currentToken().start, "unexpected {s}, expected {s}", .{
+        self.currentToken().tag.name(),
+        tag.name(),
+    });
+}
+
+fn eatToken(self: *Assembler, tag: Token.Tag) bool {
+    if (self.testToken(tag)) {
+        self.current_token += 1;
+        return true;
+    }
+    return false;
+}
+
+fn testToken(self: Assembler, tag: Token.Tag) bool {
+    return self.currentToken().tag == tag;
+}
+
+fn currentToken(self: Assembler) Token {
+    return self.tokens.items[self.current_token];
+}
+
+fn tokenText(self: Assembler, tok: Token) []const u8 {
+    return self.src[tok.start..tok.end];
+}
+
+/// Tokenize `self.src` and put the tokens in `self.tokens`.
+/// Any errors encountered are appended to `self.errors`.
+fn tokenize(self: *Assembler) !void {
+    var offset: u32 = 0;
+    while (true) {
+        const tok = try self.nextToken(offset);
+        // Resolve result-id assignment now.
+        // Note: If the previous token wasn't a result-id, just ignore it,
+        // we will catch it while parsing.
+        if (tok.tag == .equals and self.tokens.items[self.tokens.items.len - 1].tag == .result_id) {
+            self.tokens.items[self.tokens.items.len - 1].tag = .result_id_assign;
+        }
+        try self.tokens.append(self.gpa, tok);
+        if (tok.tag == .eof)
+            break;
+        offset = tok.end;
+    }
+}
+
+/// Retrieve the next token from the input. This function will assert
+/// that the token is surrounded by whitespace if required, but will not
+/// interpret the token yet.
+/// Note: This function doesn't handle .result_id_assign - this is handled in
+/// tokenize().
+fn nextToken(self: *Assembler, start_offset: u32) !Token {
+    // We generally separate the input into the following types:
+    // - Whitespace. Generally ignored, but also used as delimiter for some
+    //   tokens.
+    // - Values. This entails integers, floats, enums - anything that
+    //   consists of alphanumeric characters, delimited by whitespace.
+    // - Result-IDs. This entails anything that consists of alphanumeric characters and _, and
+    //   starts with a %. In contrast to values, this entity can be checked for complete correctness
+    //   relatively easily here.
+    // - Strings. This entails quote-delimited text such as "abc".
+    //   SPIR-V strings have only two escapes, \" and \\.
+    // - Sigils, = and |. In this assembler, these are not required to have whitespace
+    //   around them (they act as delimiters) as they do in SPIRV-Tools.
+
+    var state: enum {
+        start,
+        value,
+        result_id,
+        string,
+        string_end,
+        escape,
+    } = .start;
+    var token_start = start_offset;
+    var offset = start_offset;
+    var tag = Token.Tag.eof;
+    while (offset < self.src.len) : (offset += 1) {
+        const c = self.src[offset];
+        switch (state) {
+            .start => switch (c) {
+                ' ', '\t', '\r', '\n' => token_start = offset + 1,
+                '"' => {
+                    state = .string;
+                    tag = .string;
+                },
+                '%' => {
+                    state = .result_id;
+                    tag = .result_id;
+                },
+                '|' => {
+                    tag = .pipe;
+                    offset += 1;
+                    break;
+                },
+                '=' => {
+                    tag = .equals;
+                    offset += 1;
+                    break;
+                },
+                else => {
+                    state = .value;
+                    tag = .value;
+                },
+            },
+            .value => switch (c) {
+                '"' => {
+                    try self.addError(offset, "unexpected string literal", .{});
+                    // The user most likely just forgot a delimiter here - keep
+                    // the tag as value.
+                    break;
+                },
+                ' ', '\t', '\r', '\n', '=', '|' => break,
+                else => {},
+            },
+            .result_id => switch (c) {
+                '_', 'a'...'z', 'A'...'Z', '0'...'9' => {},
+                ' ', '\t', '\r', '\n', '=', '|' => break,
+                else => {
+                    try self.addError(offset, "illegal character in result-id", .{});
+                    // Again, probably a forgotten delimiter here.
+                    break;
+                },
+            },
+            .string => switch (c) {
+                '\\' => state = .escape,
+                '"' => state = .string_end,
+                else => {}, // Note, strings may include newlines
+            },
+            .string_end => switch (c) {
+                ' ', '\t', '\r', '\n', '=', '|' => break,
+                else => {
+                    try self.addError(offset, "unexpected character after string literal", .{});
+                    // The token is still unmistakibly a string.
+                    break;
+                },
+            },
+            // Escapes simply skip the next char.
+            .escape => state = .string,
+        }
+    }
+
+    var tok = Token{
+        .tag = tag,
+        .start = token_start,
+        .end = offset,
+    };
+
+    switch (state) {
+        .string, .escape => {
+            try self.addError(token_start, "unterminated string", .{});
+        },
+        .result_id => if (offset - token_start == 1) {
+            try self.addError(token_start, "result-id must have at least one name character", .{});
+        },
+        .value => {
+            const text = self.tokenText(tok);
+            const prefix = "Op";
+            const looks_like_opcode = text.len > prefix.len and
+                std.mem.startsWith(u8, text, prefix) and
+                std.ascii.isUpper(text[prefix.len]);
+            if (looks_like_opcode)
+                tok.tag = .opcode;
+        },
+        else => {},
+    }
+
+    return tok;
+}
src/codegen/spirv/Module.zig
@@ -24,6 +24,37 @@ const Type = @import("type.zig").Type;
 
 const TypeCache = std.ArrayHashMapUnmanaged(Type, IdResultType, Type.ShallowHashContext32, true);
 
+/// This structure represents a function that is in-progress of being emitted.
+/// Commonly, the contents of this structure will be merged with the appropriate
+/// sections of the module and re-used. Note that the SPIR-V module system makes
+/// no attempt of compacting result-id's, so any Fn instance should ultimately
+/// be merged into the module it's result-id's are allocated from.
+pub const Fn = struct {
+    /// The prologue of this function; this section contains the function's
+    /// OpFunction, OpFunctionParameter, OpLabel and OpVariable instructions, and
+    /// is separated from the actual function contents as OpVariable instructions
+    /// must appear in the first block of a function definition.
+    prologue: Section = .{},
+    /// The code of the body of this function.
+    /// This section should also contain the OpFunctionEnd instruction marking
+    /// the end of this function definition.
+    body: Section = .{},
+
+    /// Reset this function without deallocating resources, so that
+    /// it may be used to emit code for another function.
+    pub fn reset(self: *Fn) void {
+        self.prologue.reset();
+        self.body.reset();
+    }
+
+    /// Free the resources owned by this function.
+    pub fn deinit(self: *Fn, a: Allocator) void {
+        self.prologue.deinit(a);
+        self.body.deinit(a);
+        self.* = undefined;
+    }
+};
+
 /// A general-purpose allocator which may be used to allocate resources for this module
 gpa: Allocator,
 
@@ -40,7 +71,8 @@ sections: struct {
     // memory model defined by target, not required here.
     /// OpEntryPoint instructions.
     entry_points: Section = .{},
-    // OpExecutionMode and OpExecutionModeId instructions - skip for now.
+    /// OpExecutionMode and OpExecutionModeId instructions.
+    execution_modes: Section = .{},
     /// OpString, OpSourcExtension, OpSource, OpSourceContinued.
     debug_strings: Section = .{},
     // OpName, OpMemberName - skip for now.
@@ -81,6 +113,7 @@ pub fn deinit(self: *Module) void {
     self.sections.capabilities.deinit(self.gpa);
     self.sections.extensions.deinit(self.gpa);
     self.sections.entry_points.deinit(self.gpa);
+    self.sections.execution_modes.deinit(self.gpa);
     self.sections.debug_strings.deinit(self.gpa);
     self.sections.annotations.deinit(self.gpa);
     self.sections.types_globals_constants.deinit(self.gpa);
@@ -107,7 +140,7 @@ pub fn flush(self: Module, file: std.fs.File) !void {
 
     const header = [_]Word{
         spec.magic_number,
-        (spec.version.major << 16) | (spec.version.minor << 8),
+        (1 << 16) | (5 << 8),
         0, // TODO: Register Zig compiler magic number.
         self.idBound(),
         0, // Schema (currently reserved for future use)
@@ -119,6 +152,7 @@ pub fn flush(self: Module, file: std.fs.File) !void {
         self.sections.capabilities.toWords(),
         self.sections.extensions.toWords(),
         self.sections.entry_points.toWords(),
+        self.sections.execution_modes.toWords(),
         self.sections.debug_strings.toWords(),
         self.sections.annotations.toWords(),
         self.sections.types_globals_constants.toWords(),
@@ -140,6 +174,12 @@ pub fn flush(self: Module, file: std.fs.File) !void {
     try file.pwritevAll(&iovc_buffers, 0);
 }
 
+/// Merge the sections making up a function declaration into this module.
+pub fn addFunction(self: *Module, func: Fn) !void {
+    try self.sections.functions.append(self.gpa, func.prologue);
+    try self.sections.functions.append(self.gpa, func.body);
+}
+
 /// Fetch the result-id of an OpString instruction that encodes the path of the source
 /// file of the decl. This function may also emit an OpSource with source-level information regarding
 /// the decl.
@@ -175,11 +215,13 @@ pub fn resolveType(self: *Module, ty: Type) !Type.Ref {
     if (!result.found_existing) {
         result.value_ptr.* = try self.emitType(ty);
     }
+
     return result.index;
 }
 
 pub fn resolveTypeId(self: *Module, ty: Type) !IdRef {
-    return self.typeResultId(try self.resolveType(ty));
+    const type_ref = try self.resolveType(ty);
+    return self.typeResultId(type_ref);
 }
 
 /// Get the result-id of a particular type, by reference. Asserts type_ref is valid.
@@ -208,14 +250,18 @@ pub fn emitType(self: *Module, ty: Type) !IdResultType {
     switch (ty.tag()) {
         .void => try types.emit(self.gpa, .OpTypeVoid, result_id_operand),
         .bool => try types.emit(self.gpa, .OpTypeBool, result_id_operand),
-        .int => try types.emit(self.gpa, .OpTypeInt, .{
-            .id_result = result_id,
-            .width = ty.payload(.int).width,
-            .signedness = switch (ty.payload(.int).signedness) {
-                .unsigned => @as(spec.LiteralInteger, 0),
+        .int => {
+            const signedness: spec.LiteralInteger = switch (ty.payload(.int).signedness) {
+                .unsigned => 0,
                 .signed => 1,
-            },
-        }),
+            };
+
+            try types.emit(self.gpa, .OpTypeInt, .{
+                .id_result = result_id,
+                .width = ty.payload(.int).width,
+                .signedness = signedness,
+            });
+        },
         .float => try types.emit(self.gpa, .OpTypeFloat, .{
             .id_result = result_id,
             .width = ty.payload(.float).width,
src/codegen/spirv/Section.zig
@@ -36,14 +36,19 @@ pub fn append(section: *Section, allocator: Allocator, other_section: Section) !
     try section.instructions.appendSlice(allocator, other_section.instructions.items);
 }
 
+/// Ensure capacity of at least `capacity` more words in this section.
+pub fn ensureUnusedCapacity(section: *Section, allocator: Allocator, capacity: usize) !void {
+    try section.instructions.ensureUnusedCapacity(allocator, capacity);
+}
+
 /// Write an instruction and size, operands are to be inserted manually.
 pub fn emitRaw(
     section: *Section,
     allocator: Allocator,
     opcode: Opcode,
-    operands: usize, // opcode itself not included
+    operand_words: usize, // opcode itself not included
 ) !void {
-    const word_count = 1 + operands;
+    const word_count = 1 + operand_words;
     try section.instructions.ensureUnusedCapacity(allocator, word_count);
     section.writeWord((@intCast(Word, word_count << 16)) | @enumToInt(opcode));
 }
@@ -96,7 +101,7 @@ pub fn writeWords(section: *Section, words: []const Word) void {
     section.instructions.appendSliceAssumeCapacity(words);
 }
 
-fn writeDoubleWord(section: *Section, dword: DoubleWord) void {
+pub fn writeDoubleWord(section: *Section, dword: DoubleWord) void {
     section.writeWords(&.{
         @truncate(Word, dword),
         @truncate(Word, dword >> @bitSizeOf(Word)),
src/codegen/spirv/spec.zig
@@ -39,8 +39,1103 @@ pub const PairLiteralIntegerIdRef = struct { value: LiteralInteger, label: IdRef
 pub const PairIdRefLiteralInteger = struct { target: IdRef, member: LiteralInteger };
 pub const PairIdRefIdRef = [2]IdRef;
 
-pub const version = Version{ .major = 1, .minor = 5, .patch = 4 };
+pub const Quantifier = enum {
+    required,
+    optional,
+    variadic,
+};
+
+pub const Operand = struct {
+    kind: OperandKind,
+    quantifier: Quantifier,
+};
+
+pub const OperandCategory = enum {
+    bit_enum,
+    value_enum,
+    id,
+    literal,
+    composite,
+};
+
+pub const Enumerant = struct {
+    name: []const u8,
+    value: Word,
+    parameters: []const OperandKind,
+};
+
+pub const version = Version{ .major = 1, .minor = 6, .patch = 1 };
 pub const magic_number: Word = 0x07230203;
+
+pub const Class = enum {
+    Miscellaneous,
+    Debug,
+    Extension,
+    ModeSetting,
+    TypeDeclaration,
+    ConstantCreation,
+    Function,
+    Memory,
+    Annotation,
+    Composite,
+    Image,
+    Conversion,
+    Arithmetic,
+    RelationalAndLogical,
+    Bit,
+    Derivative,
+    Primitive,
+    Barrier,
+    Atomic,
+    ControlFlow,
+    Group,
+    Pipe,
+    DeviceSideEnqueue,
+    NonUniform,
+    Reserved,
+};
+pub const OperandKind = enum {
+    ImageOperands,
+    FPFastMathMode,
+    SelectionControl,
+    LoopControl,
+    FunctionControl,
+    MemorySemantics,
+    MemoryAccess,
+    KernelProfilingInfo,
+    RayFlags,
+    FragmentShadingRate,
+    SourceLanguage,
+    ExecutionModel,
+    AddressingModel,
+    MemoryModel,
+    ExecutionMode,
+    StorageClass,
+    Dim,
+    SamplerAddressingMode,
+    SamplerFilterMode,
+    ImageFormat,
+    ImageChannelOrder,
+    ImageChannelDataType,
+    FPRoundingMode,
+    FPDenormMode,
+    QuantizationModes,
+    FPOperationMode,
+    OverflowModes,
+    LinkageType,
+    AccessQualifier,
+    FunctionParameterAttribute,
+    Decoration,
+    BuiltIn,
+    Scope,
+    GroupOperation,
+    KernelEnqueueFlags,
+    Capability,
+    RayQueryIntersection,
+    RayQueryCommittedIntersectionType,
+    RayQueryCandidateIntersectionType,
+    PackedVectorFormat,
+    IdResultType,
+    IdResult,
+    IdMemorySemantics,
+    IdScope,
+    IdRef,
+    LiteralInteger,
+    LiteralString,
+    LiteralContextDependentNumber,
+    LiteralExtInstInteger,
+    LiteralSpecConstantOpInteger,
+    PairLiteralIntegerIdRef,
+    PairIdRefLiteralInteger,
+    PairIdRefIdRef,
+
+    pub fn category(self: OperandKind) OperandCategory {
+        return switch (self) {
+            .ImageOperands => .bit_enum,
+            .FPFastMathMode => .bit_enum,
+            .SelectionControl => .bit_enum,
+            .LoopControl => .bit_enum,
+            .FunctionControl => .bit_enum,
+            .MemorySemantics => .bit_enum,
+            .MemoryAccess => .bit_enum,
+            .KernelProfilingInfo => .bit_enum,
+            .RayFlags => .bit_enum,
+            .FragmentShadingRate => .bit_enum,
+            .SourceLanguage => .value_enum,
+            .ExecutionModel => .value_enum,
+            .AddressingModel => .value_enum,
+            .MemoryModel => .value_enum,
+            .ExecutionMode => .value_enum,
+            .StorageClass => .value_enum,
+            .Dim => .value_enum,
+            .SamplerAddressingMode => .value_enum,
+            .SamplerFilterMode => .value_enum,
+            .ImageFormat => .value_enum,
+            .ImageChannelOrder => .value_enum,
+            .ImageChannelDataType => .value_enum,
+            .FPRoundingMode => .value_enum,
+            .FPDenormMode => .value_enum,
+            .QuantizationModes => .value_enum,
+            .FPOperationMode => .value_enum,
+            .OverflowModes => .value_enum,
+            .LinkageType => .value_enum,
+            .AccessQualifier => .value_enum,
+            .FunctionParameterAttribute => .value_enum,
+            .Decoration => .value_enum,
+            .BuiltIn => .value_enum,
+            .Scope => .value_enum,
+            .GroupOperation => .value_enum,
+            .KernelEnqueueFlags => .value_enum,
+            .Capability => .value_enum,
+            .RayQueryIntersection => .value_enum,
+            .RayQueryCommittedIntersectionType => .value_enum,
+            .RayQueryCandidateIntersectionType => .value_enum,
+            .PackedVectorFormat => .value_enum,
+            .IdResultType => .id,
+            .IdResult => .id,
+            .IdMemorySemantics => .id,
+            .IdScope => .id,
+            .IdRef => .id,
+            .LiteralInteger => .literal,
+            .LiteralString => .literal,
+            .LiteralContextDependentNumber => .literal,
+            .LiteralExtInstInteger => .literal,
+            .LiteralSpecConstantOpInteger => .literal,
+            .PairLiteralIntegerIdRef => .composite,
+            .PairIdRefLiteralInteger => .composite,
+            .PairIdRefIdRef => .composite,
+        };
+    }
+    pub fn enumerants(self: OperandKind) []const Enumerant {
+        return switch (self) {
+            .ImageOperands => &[_]Enumerant{
+                .{ .name = "Bias", .value = 0x0001, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "Lod", .value = 0x0002, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "Grad", .value = 0x0004, .parameters = &[_]OperandKind{ .IdRef, .IdRef } },
+                .{ .name = "ConstOffset", .value = 0x0008, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "Offset", .value = 0x0010, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "ConstOffsets", .value = 0x0020, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "Sample", .value = 0x0040, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "MinLod", .value = 0x0080, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "MakeTexelAvailable", .value = 0x0100, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "MakeTexelAvailableKHR", .value = 0x0100, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "MakeTexelVisible", .value = 0x0200, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "MakeTexelVisibleKHR", .value = 0x0200, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "NonPrivateTexel", .value = 0x0400, .parameters = &[_]OperandKind{} },
+                .{ .name = "NonPrivateTexelKHR", .value = 0x0400, .parameters = &[_]OperandKind{} },
+                .{ .name = "VolatileTexel", .value = 0x0800, .parameters = &[_]OperandKind{} },
+                .{ .name = "VolatileTexelKHR", .value = 0x0800, .parameters = &[_]OperandKind{} },
+                .{ .name = "SignExtend", .value = 0x1000, .parameters = &[_]OperandKind{} },
+                .{ .name = "ZeroExtend", .value = 0x2000, .parameters = &[_]OperandKind{} },
+                .{ .name = "Nontemporal", .value = 0x4000, .parameters = &[_]OperandKind{} },
+                .{ .name = "Offsets", .value = 0x10000, .parameters = &[_]OperandKind{.IdRef} },
+            },
+            .FPFastMathMode => &[_]Enumerant{
+                .{ .name = "NotNaN", .value = 0x0001, .parameters = &[_]OperandKind{} },
+                .{ .name = "NotInf", .value = 0x0002, .parameters = &[_]OperandKind{} },
+                .{ .name = "NSZ", .value = 0x0004, .parameters = &[_]OperandKind{} },
+                .{ .name = "AllowRecip", .value = 0x0008, .parameters = &[_]OperandKind{} },
+                .{ .name = "Fast", .value = 0x0010, .parameters = &[_]OperandKind{} },
+                .{ .name = "AllowContractFastINTEL", .value = 0x10000, .parameters = &[_]OperandKind{} },
+                .{ .name = "AllowReassocINTEL", .value = 0x20000, .parameters = &[_]OperandKind{} },
+            },
+            .SelectionControl => &[_]Enumerant{
+                .{ .name = "Flatten", .value = 0x0001, .parameters = &[_]OperandKind{} },
+                .{ .name = "DontFlatten", .value = 0x0002, .parameters = &[_]OperandKind{} },
+            },
+            .LoopControl => &[_]Enumerant{
+                .{ .name = "Unroll", .value = 0x0001, .parameters = &[_]OperandKind{} },
+                .{ .name = "DontUnroll", .value = 0x0002, .parameters = &[_]OperandKind{} },
+                .{ .name = "DependencyInfinite", .value = 0x0004, .parameters = &[_]OperandKind{} },
+                .{ .name = "DependencyLength", .value = 0x0008, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MinIterations", .value = 0x0010, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MaxIterations", .value = 0x0020, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "IterationMultiple", .value = 0x0040, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "PeelCount", .value = 0x0080, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "PartialCount", .value = 0x0100, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "InitiationIntervalINTEL", .value = 0x10000, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MaxConcurrencyINTEL", .value = 0x20000, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "DependencyArrayINTEL", .value = 0x40000, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "PipelineEnableINTEL", .value = 0x80000, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "LoopCoalesceINTEL", .value = 0x100000, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MaxInterleavingINTEL", .value = 0x200000, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SpeculatedIterationsINTEL", .value = 0x400000, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "NoFusionINTEL", .value = 0x800000, .parameters = &[_]OperandKind{.LiteralInteger} },
+            },
+            .FunctionControl => &[_]Enumerant{
+                .{ .name = "Inline", .value = 0x0001, .parameters = &[_]OperandKind{} },
+                .{ .name = "DontInline", .value = 0x0002, .parameters = &[_]OperandKind{} },
+                .{ .name = "Pure", .value = 0x0004, .parameters = &[_]OperandKind{} },
+                .{ .name = "Const", .value = 0x0008, .parameters = &[_]OperandKind{} },
+                .{ .name = "OptNoneINTEL", .value = 0x10000, .parameters = &[_]OperandKind{} },
+            },
+            .MemorySemantics => &[_]Enumerant{
+                .{ .name = "Relaxed", .value = 0x0000, .parameters = &[_]OperandKind{} },
+                .{ .name = "Acquire", .value = 0x0002, .parameters = &[_]OperandKind{} },
+                .{ .name = "Release", .value = 0x0004, .parameters = &[_]OperandKind{} },
+                .{ .name = "AcquireRelease", .value = 0x0008, .parameters = &[_]OperandKind{} },
+                .{ .name = "SequentiallyConsistent", .value = 0x0010, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformMemory", .value = 0x0040, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupMemory", .value = 0x0080, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorkgroupMemory", .value = 0x0100, .parameters = &[_]OperandKind{} },
+                .{ .name = "CrossWorkgroupMemory", .value = 0x0200, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicCounterMemory", .value = 0x0400, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageMemory", .value = 0x0800, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputMemory", .value = 0x1000, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputMemoryKHR", .value = 0x1000, .parameters = &[_]OperandKind{} },
+                .{ .name = "MakeAvailable", .value = 0x2000, .parameters = &[_]OperandKind{} },
+                .{ .name = "MakeAvailableKHR", .value = 0x2000, .parameters = &[_]OperandKind{} },
+                .{ .name = "MakeVisible", .value = 0x4000, .parameters = &[_]OperandKind{} },
+                .{ .name = "MakeVisibleKHR", .value = 0x4000, .parameters = &[_]OperandKind{} },
+                .{ .name = "Volatile", .value = 0x8000, .parameters = &[_]OperandKind{} },
+            },
+            .MemoryAccess => &[_]Enumerant{
+                .{ .name = "Volatile", .value = 0x0001, .parameters = &[_]OperandKind{} },
+                .{ .name = "Aligned", .value = 0x0002, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Nontemporal", .value = 0x0004, .parameters = &[_]OperandKind{} },
+                .{ .name = "MakePointerAvailable", .value = 0x0008, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "MakePointerAvailableKHR", .value = 0x0008, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "MakePointerVisible", .value = 0x0010, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "MakePointerVisibleKHR", .value = 0x0010, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "NonPrivatePointer", .value = 0x0020, .parameters = &[_]OperandKind{} },
+                .{ .name = "NonPrivatePointerKHR", .value = 0x0020, .parameters = &[_]OperandKind{} },
+            },
+            .KernelProfilingInfo => &[_]Enumerant{
+                .{ .name = "CmdExecTime", .value = 0x0001, .parameters = &[_]OperandKind{} },
+            },
+            .RayFlags => &[_]Enumerant{
+                .{ .name = "NoneKHR", .value = 0x0000, .parameters = &[_]OperandKind{} },
+                .{ .name = "OpaqueKHR", .value = 0x0001, .parameters = &[_]OperandKind{} },
+                .{ .name = "NoOpaqueKHR", .value = 0x0002, .parameters = &[_]OperandKind{} },
+                .{ .name = "TerminateOnFirstHitKHR", .value = 0x0004, .parameters = &[_]OperandKind{} },
+                .{ .name = "SkipClosestHitShaderKHR", .value = 0x0008, .parameters = &[_]OperandKind{} },
+                .{ .name = "CullBackFacingTrianglesKHR", .value = 0x0010, .parameters = &[_]OperandKind{} },
+                .{ .name = "CullFrontFacingTrianglesKHR", .value = 0x0020, .parameters = &[_]OperandKind{} },
+                .{ .name = "CullOpaqueKHR", .value = 0x0040, .parameters = &[_]OperandKind{} },
+                .{ .name = "CullNoOpaqueKHR", .value = 0x0080, .parameters = &[_]OperandKind{} },
+                .{ .name = "SkipTrianglesKHR", .value = 0x0100, .parameters = &[_]OperandKind{} },
+                .{ .name = "SkipAABBsKHR", .value = 0x0200, .parameters = &[_]OperandKind{} },
+            },
+            .FragmentShadingRate => &[_]Enumerant{
+                .{ .name = "Vertical2Pixels", .value = 0x0001, .parameters = &[_]OperandKind{} },
+                .{ .name = "Vertical4Pixels", .value = 0x0002, .parameters = &[_]OperandKind{} },
+                .{ .name = "Horizontal2Pixels", .value = 0x0004, .parameters = &[_]OperandKind{} },
+                .{ .name = "Horizontal4Pixels", .value = 0x0008, .parameters = &[_]OperandKind{} },
+            },
+            .SourceLanguage => &[_]Enumerant{
+                .{ .name = "Unknown", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "ESSL", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "GLSL", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "OpenCL_C", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "OpenCL_CPP", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "HLSL", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "CPP_for_OpenCL", .value = 6, .parameters = &[_]OperandKind{} },
+            },
+            .ExecutionModel => &[_]Enumerant{
+                .{ .name = "Vertex", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "TessellationControl", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "TessellationEvaluation", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Geometry", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "Fragment", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "GLCompute", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "Kernel", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "TaskNV", .value = 5267, .parameters = &[_]OperandKind{} },
+                .{ .name = "MeshNV", .value = 5268, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayGenerationNV", .value = 5313, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayGenerationKHR", .value = 5313, .parameters = &[_]OperandKind{} },
+                .{ .name = "IntersectionNV", .value = 5314, .parameters = &[_]OperandKind{} },
+                .{ .name = "IntersectionKHR", .value = 5314, .parameters = &[_]OperandKind{} },
+                .{ .name = "AnyHitNV", .value = 5315, .parameters = &[_]OperandKind{} },
+                .{ .name = "AnyHitKHR", .value = 5315, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClosestHitNV", .value = 5316, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClosestHitKHR", .value = 5316, .parameters = &[_]OperandKind{} },
+                .{ .name = "MissNV", .value = 5317, .parameters = &[_]OperandKind{} },
+                .{ .name = "MissKHR", .value = 5317, .parameters = &[_]OperandKind{} },
+                .{ .name = "CallableNV", .value = 5318, .parameters = &[_]OperandKind{} },
+                .{ .name = "CallableKHR", .value = 5318, .parameters = &[_]OperandKind{} },
+            },
+            .AddressingModel => &[_]Enumerant{
+                .{ .name = "Logical", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Physical32", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "Physical64", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "PhysicalStorageBuffer64", .value = 5348, .parameters = &[_]OperandKind{} },
+                .{ .name = "PhysicalStorageBuffer64EXT", .value = 5348, .parameters = &[_]OperandKind{} },
+            },
+            .MemoryModel => &[_]Enumerant{
+                .{ .name = "Simple", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "GLSL450", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "OpenCL", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Vulkan", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "VulkanKHR", .value = 3, .parameters = &[_]OperandKind{} },
+            },
+            .ExecutionMode => &[_]Enumerant{
+                .{ .name = "Invocations", .value = 0, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SpacingEqual", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "SpacingFractionalEven", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "SpacingFractionalOdd", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "VertexOrderCw", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "VertexOrderCcw", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "PixelCenterInteger", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "OriginUpperLeft", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "OriginLowerLeft", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "EarlyFragmentTests", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "PointMode", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "Xfb", .value = 11, .parameters = &[_]OperandKind{} },
+                .{ .name = "DepthReplacing", .value = 12, .parameters = &[_]OperandKind{} },
+                .{ .name = "DepthGreater", .value = 14, .parameters = &[_]OperandKind{} },
+                .{ .name = "DepthLess", .value = 15, .parameters = &[_]OperandKind{} },
+                .{ .name = "DepthUnchanged", .value = 16, .parameters = &[_]OperandKind{} },
+                .{ .name = "LocalSize", .value = 17, .parameters = &[_]OperandKind{ .LiteralInteger, .LiteralInteger, .LiteralInteger } },
+                .{ .name = "LocalSizeHint", .value = 18, .parameters = &[_]OperandKind{ .LiteralInteger, .LiteralInteger, .LiteralInteger } },
+                .{ .name = "InputPoints", .value = 19, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputLines", .value = 20, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputLinesAdjacency", .value = 21, .parameters = &[_]OperandKind{} },
+                .{ .name = "Triangles", .value = 22, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputTrianglesAdjacency", .value = 23, .parameters = &[_]OperandKind{} },
+                .{ .name = "Quads", .value = 24, .parameters = &[_]OperandKind{} },
+                .{ .name = "Isolines", .value = 25, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputVertices", .value = 26, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "OutputPoints", .value = 27, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputLineStrip", .value = 28, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputTriangleStrip", .value = 29, .parameters = &[_]OperandKind{} },
+                .{ .name = "VecTypeHint", .value = 30, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "ContractionOff", .value = 31, .parameters = &[_]OperandKind{} },
+                .{ .name = "Initializer", .value = 33, .parameters = &[_]OperandKind{} },
+                .{ .name = "Finalizer", .value = 34, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupSize", .value = 35, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SubgroupsPerWorkgroup", .value = 36, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SubgroupsPerWorkgroupId", .value = 37, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "LocalSizeId", .value = 38, .parameters = &[_]OperandKind{ .IdRef, .IdRef, .IdRef } },
+                .{ .name = "LocalSizeHintId", .value = 39, .parameters = &[_]OperandKind{ .IdRef, .IdRef, .IdRef } },
+                .{ .name = "SubgroupUniformControlFlowKHR", .value = 4421, .parameters = &[_]OperandKind{} },
+                .{ .name = "PostDepthCoverage", .value = 4446, .parameters = &[_]OperandKind{} },
+                .{ .name = "DenormPreserve", .value = 4459, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "DenormFlushToZero", .value = 4460, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SignedZeroInfNanPreserve", .value = 4461, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "RoundingModeRTE", .value = 4462, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "RoundingModeRTZ", .value = 4463, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "StencilRefReplacingEXT", .value = 5027, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputLinesNV", .value = 5269, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputPrimitivesNV", .value = 5270, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "DerivativeGroupQuadsNV", .value = 5289, .parameters = &[_]OperandKind{} },
+                .{ .name = "DerivativeGroupLinearNV", .value = 5290, .parameters = &[_]OperandKind{} },
+                .{ .name = "OutputTrianglesNV", .value = 5298, .parameters = &[_]OperandKind{} },
+                .{ .name = "PixelInterlockOrderedEXT", .value = 5366, .parameters = &[_]OperandKind{} },
+                .{ .name = "PixelInterlockUnorderedEXT", .value = 5367, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampleInterlockOrderedEXT", .value = 5368, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampleInterlockUnorderedEXT", .value = 5369, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShadingRateInterlockOrderedEXT", .value = 5370, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShadingRateInterlockUnorderedEXT", .value = 5371, .parameters = &[_]OperandKind{} },
+                .{ .name = "SharedLocalMemorySizeINTEL", .value = 5618, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "RoundingModeRTPINTEL", .value = 5620, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "RoundingModeRTNINTEL", .value = 5621, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "FloatingPointModeALTINTEL", .value = 5622, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "FloatingPointModeIEEEINTEL", .value = 5623, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MaxWorkgroupSizeINTEL", .value = 5893, .parameters = &[_]OperandKind{ .LiteralInteger, .LiteralInteger, .LiteralInteger } },
+                .{ .name = "MaxWorkDimINTEL", .value = 5894, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "NoGlobalOffsetINTEL", .value = 5895, .parameters = &[_]OperandKind{} },
+                .{ .name = "NumSIMDWorkitemsINTEL", .value = 5896, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SchedulerTargetFmaxMhzINTEL", .value = 5903, .parameters = &[_]OperandKind{.LiteralInteger} },
+            },
+            .StorageClass => &[_]Enumerant{
+                .{ .name = "UniformConstant", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Input", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "Uniform", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Output", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "Workgroup", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "CrossWorkgroup", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "Private", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "Function", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "Generic", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "PushConstant", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicCounter", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "Image", .value = 11, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageBuffer", .value = 12, .parameters = &[_]OperandKind{} },
+                .{ .name = "CallableDataNV", .value = 5328, .parameters = &[_]OperandKind{} },
+                .{ .name = "CallableDataKHR", .value = 5328, .parameters = &[_]OperandKind{} },
+                .{ .name = "IncomingCallableDataNV", .value = 5329, .parameters = &[_]OperandKind{} },
+                .{ .name = "IncomingCallableDataKHR", .value = 5329, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayPayloadNV", .value = 5338, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayPayloadKHR", .value = 5338, .parameters = &[_]OperandKind{} },
+                .{ .name = "HitAttributeNV", .value = 5339, .parameters = &[_]OperandKind{} },
+                .{ .name = "HitAttributeKHR", .value = 5339, .parameters = &[_]OperandKind{} },
+                .{ .name = "IncomingRayPayloadNV", .value = 5342, .parameters = &[_]OperandKind{} },
+                .{ .name = "IncomingRayPayloadKHR", .value = 5342, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderRecordBufferNV", .value = 5343, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderRecordBufferKHR", .value = 5343, .parameters = &[_]OperandKind{} },
+                .{ .name = "PhysicalStorageBuffer", .value = 5349, .parameters = &[_]OperandKind{} },
+                .{ .name = "PhysicalStorageBufferEXT", .value = 5349, .parameters = &[_]OperandKind{} },
+                .{ .name = "CodeSectionINTEL", .value = 5605, .parameters = &[_]OperandKind{} },
+                .{ .name = "DeviceOnlyINTEL", .value = 5936, .parameters = &[_]OperandKind{} },
+                .{ .name = "HostOnlyINTEL", .value = 5937, .parameters = &[_]OperandKind{} },
+            },
+            .Dim => &[_]Enumerant{
+                .{ .name = "1D", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "2D", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "3D", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Cube", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rect", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "Buffer", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubpassData", .value = 6, .parameters = &[_]OperandKind{} },
+            },
+            .SamplerAddressingMode => &[_]Enumerant{
+                .{ .name = "None", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClampToEdge", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "Clamp", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Repeat", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "RepeatMirrored", .value = 4, .parameters = &[_]OperandKind{} },
+            },
+            .SamplerFilterMode => &[_]Enumerant{
+                .{ .name = "Nearest", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Linear", .value = 1, .parameters = &[_]OperandKind{} },
+            },
+            .ImageFormat => &[_]Enumerant{
+                .{ .name = "Unknown", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba32f", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba16f", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "R32f", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba8", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba8Snorm", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg32f", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg16f", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "R11fG11fB10f", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "R16f", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba16", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgb10A2", .value = 11, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg16", .value = 12, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg8", .value = 13, .parameters = &[_]OperandKind{} },
+                .{ .name = "R16", .value = 14, .parameters = &[_]OperandKind{} },
+                .{ .name = "R8", .value = 15, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba16Snorm", .value = 16, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg16Snorm", .value = 17, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg8Snorm", .value = 18, .parameters = &[_]OperandKind{} },
+                .{ .name = "R16Snorm", .value = 19, .parameters = &[_]OperandKind{} },
+                .{ .name = "R8Snorm", .value = 20, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba32i", .value = 21, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba16i", .value = 22, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba8i", .value = 23, .parameters = &[_]OperandKind{} },
+                .{ .name = "R32i", .value = 24, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg32i", .value = 25, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg16i", .value = 26, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg8i", .value = 27, .parameters = &[_]OperandKind{} },
+                .{ .name = "R16i", .value = 28, .parameters = &[_]OperandKind{} },
+                .{ .name = "R8i", .value = 29, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba32ui", .value = 30, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba16ui", .value = 31, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgba8ui", .value = 32, .parameters = &[_]OperandKind{} },
+                .{ .name = "R32ui", .value = 33, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rgb10a2ui", .value = 34, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg32ui", .value = 35, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg16ui", .value = 36, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rg8ui", .value = 37, .parameters = &[_]OperandKind{} },
+                .{ .name = "R16ui", .value = 38, .parameters = &[_]OperandKind{} },
+                .{ .name = "R8ui", .value = 39, .parameters = &[_]OperandKind{} },
+                .{ .name = "R64ui", .value = 40, .parameters = &[_]OperandKind{} },
+                .{ .name = "R64i", .value = 41, .parameters = &[_]OperandKind{} },
+            },
+            .ImageChannelOrder => &[_]Enumerant{
+                .{ .name = "R", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "A", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "RG", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "RA", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "RGB", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "RGBA", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "BGRA", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "ARGB", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "Intensity", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "Luminance", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "Rx", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "RGx", .value = 11, .parameters = &[_]OperandKind{} },
+                .{ .name = "RGBx", .value = 12, .parameters = &[_]OperandKind{} },
+                .{ .name = "Depth", .value = 13, .parameters = &[_]OperandKind{} },
+                .{ .name = "DepthStencil", .value = 14, .parameters = &[_]OperandKind{} },
+                .{ .name = "sRGB", .value = 15, .parameters = &[_]OperandKind{} },
+                .{ .name = "sRGBx", .value = 16, .parameters = &[_]OperandKind{} },
+                .{ .name = "sRGBA", .value = 17, .parameters = &[_]OperandKind{} },
+                .{ .name = "sBGRA", .value = 18, .parameters = &[_]OperandKind{} },
+                .{ .name = "ABGR", .value = 19, .parameters = &[_]OperandKind{} },
+            },
+            .ImageChannelDataType => &[_]Enumerant{
+                .{ .name = "SnormInt8", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "SnormInt16", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnormInt8", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnormInt16", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnormShort565", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnormShort555", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnormInt101010", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "SignedInt8", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "SignedInt16", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "SignedInt32", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnsignedInt8", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnsignedInt16", .value = 11, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnsignedInt32", .value = 12, .parameters = &[_]OperandKind{} },
+                .{ .name = "HalfFloat", .value = 13, .parameters = &[_]OperandKind{} },
+                .{ .name = "Float", .value = 14, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnormInt24", .value = 15, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnormInt101010_2", .value = 16, .parameters = &[_]OperandKind{} },
+            },
+            .FPRoundingMode => &[_]Enumerant{
+                .{ .name = "RTE", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "RTZ", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "RTP", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "RTN", .value = 3, .parameters = &[_]OperandKind{} },
+            },
+            .FPDenormMode => &[_]Enumerant{
+                .{ .name = "Preserve", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "FlushToZero", .value = 1, .parameters = &[_]OperandKind{} },
+            },
+            .QuantizationModes => &[_]Enumerant{
+                .{ .name = "TRN", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "TRN_ZERO", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "RND", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "RND_ZERO", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "RND_INF", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "RND_MIN_INF", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "RND_CONV", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "RND_CONV_ODD", .value = 7, .parameters = &[_]OperandKind{} },
+            },
+            .FPOperationMode => &[_]Enumerant{
+                .{ .name = "IEEE", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "ALT", .value = 1, .parameters = &[_]OperandKind{} },
+            },
+            .OverflowModes => &[_]Enumerant{
+                .{ .name = "WRAP", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "SAT", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "SAT_ZERO", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "SAT_SYM", .value = 3, .parameters = &[_]OperandKind{} },
+            },
+            .LinkageType => &[_]Enumerant{
+                .{ .name = "Export", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Import", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "LinkOnceODR", .value = 2, .parameters = &[_]OperandKind{} },
+            },
+            .AccessQualifier => &[_]Enumerant{
+                .{ .name = "ReadOnly", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "WriteOnly", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "ReadWrite", .value = 2, .parameters = &[_]OperandKind{} },
+            },
+            .FunctionParameterAttribute => &[_]Enumerant{
+                .{ .name = "Zext", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Sext", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "ByVal", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Sret", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "NoAlias", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "NoCapture", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "NoWrite", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "NoReadWrite", .value = 7, .parameters = &[_]OperandKind{} },
+            },
+            .Decoration => &[_]Enumerant{
+                .{ .name = "RelaxedPrecision", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "SpecId", .value = 1, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Block", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "BufferBlock", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "RowMajor", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "ColMajor", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "ArrayStride", .value = 6, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MatrixStride", .value = 7, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "GLSLShared", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "GLSLPacked", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "CPacked", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "BuiltIn", .value = 11, .parameters = &[_]OperandKind{.BuiltIn} },
+                .{ .name = "NoPerspective", .value = 13, .parameters = &[_]OperandKind{} },
+                .{ .name = "Flat", .value = 14, .parameters = &[_]OperandKind{} },
+                .{ .name = "Patch", .value = 15, .parameters = &[_]OperandKind{} },
+                .{ .name = "Centroid", .value = 16, .parameters = &[_]OperandKind{} },
+                .{ .name = "Sample", .value = 17, .parameters = &[_]OperandKind{} },
+                .{ .name = "Invariant", .value = 18, .parameters = &[_]OperandKind{} },
+                .{ .name = "Restrict", .value = 19, .parameters = &[_]OperandKind{} },
+                .{ .name = "Aliased", .value = 20, .parameters = &[_]OperandKind{} },
+                .{ .name = "Volatile", .value = 21, .parameters = &[_]OperandKind{} },
+                .{ .name = "Constant", .value = 22, .parameters = &[_]OperandKind{} },
+                .{ .name = "Coherent", .value = 23, .parameters = &[_]OperandKind{} },
+                .{ .name = "NonWritable", .value = 24, .parameters = &[_]OperandKind{} },
+                .{ .name = "NonReadable", .value = 25, .parameters = &[_]OperandKind{} },
+                .{ .name = "Uniform", .value = 26, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformId", .value = 27, .parameters = &[_]OperandKind{.IdScope} },
+                .{ .name = "SaturatedConversion", .value = 28, .parameters = &[_]OperandKind{} },
+                .{ .name = "Stream", .value = 29, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Location", .value = 30, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Component", .value = 31, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Index", .value = 32, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Binding", .value = 33, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "DescriptorSet", .value = 34, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Offset", .value = 35, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "XfbBuffer", .value = 36, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "XfbStride", .value = 37, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "FuncParamAttr", .value = 38, .parameters = &[_]OperandKind{.FunctionParameterAttribute} },
+                .{ .name = "FPRoundingMode", .value = 39, .parameters = &[_]OperandKind{.FPRoundingMode} },
+                .{ .name = "FPFastMathMode", .value = 40, .parameters = &[_]OperandKind{.FPFastMathMode} },
+                .{ .name = "LinkageAttributes", .value = 41, .parameters = &[_]OperandKind{ .LiteralString, .LinkageType } },
+                .{ .name = "NoContraction", .value = 42, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputAttachmentIndex", .value = 43, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "Alignment", .value = 44, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MaxByteOffset", .value = 45, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "AlignmentId", .value = 46, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "MaxByteOffsetId", .value = 47, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "NoSignedWrap", .value = 4469, .parameters = &[_]OperandKind{} },
+                .{ .name = "NoUnsignedWrap", .value = 4470, .parameters = &[_]OperandKind{} },
+                .{ .name = "ExplicitInterpAMD", .value = 4999, .parameters = &[_]OperandKind{} },
+                .{ .name = "OverrideCoverageNV", .value = 5248, .parameters = &[_]OperandKind{} },
+                .{ .name = "PassthroughNV", .value = 5250, .parameters = &[_]OperandKind{} },
+                .{ .name = "ViewportRelativeNV", .value = 5252, .parameters = &[_]OperandKind{} },
+                .{ .name = "SecondaryViewportRelativeNV", .value = 5256, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "PerPrimitiveNV", .value = 5271, .parameters = &[_]OperandKind{} },
+                .{ .name = "PerViewNV", .value = 5272, .parameters = &[_]OperandKind{} },
+                .{ .name = "PerTaskNV", .value = 5273, .parameters = &[_]OperandKind{} },
+                .{ .name = "PerVertexKHR", .value = 5285, .parameters = &[_]OperandKind{} },
+                .{ .name = "PerVertexNV", .value = 5285, .parameters = &[_]OperandKind{} },
+                .{ .name = "NonUniform", .value = 5300, .parameters = &[_]OperandKind{} },
+                .{ .name = "NonUniformEXT", .value = 5300, .parameters = &[_]OperandKind{} },
+                .{ .name = "RestrictPointer", .value = 5355, .parameters = &[_]OperandKind{} },
+                .{ .name = "RestrictPointerEXT", .value = 5355, .parameters = &[_]OperandKind{} },
+                .{ .name = "AliasedPointer", .value = 5356, .parameters = &[_]OperandKind{} },
+                .{ .name = "AliasedPointerEXT", .value = 5356, .parameters = &[_]OperandKind{} },
+                .{ .name = "BindlessSamplerNV", .value = 5398, .parameters = &[_]OperandKind{} },
+                .{ .name = "BindlessImageNV", .value = 5399, .parameters = &[_]OperandKind{} },
+                .{ .name = "BoundSamplerNV", .value = 5400, .parameters = &[_]OperandKind{} },
+                .{ .name = "BoundImageNV", .value = 5401, .parameters = &[_]OperandKind{} },
+                .{ .name = "SIMTCallINTEL", .value = 5599, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "ReferencedIndirectlyINTEL", .value = 5602, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClobberINTEL", .value = 5607, .parameters = &[_]OperandKind{.LiteralString} },
+                .{ .name = "SideEffectsINTEL", .value = 5608, .parameters = &[_]OperandKind{} },
+                .{ .name = "VectorComputeVariableINTEL", .value = 5624, .parameters = &[_]OperandKind{} },
+                .{ .name = "FuncParamIOKindINTEL", .value = 5625, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "VectorComputeFunctionINTEL", .value = 5626, .parameters = &[_]OperandKind{} },
+                .{ .name = "StackCallINTEL", .value = 5627, .parameters = &[_]OperandKind{} },
+                .{ .name = "GlobalVariableOffsetINTEL", .value = 5628, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "CounterBuffer", .value = 5634, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "HlslCounterBufferGOOGLE", .value = 5634, .parameters = &[_]OperandKind{.IdRef} },
+                .{ .name = "UserSemantic", .value = 5635, .parameters = &[_]OperandKind{.LiteralString} },
+                .{ .name = "HlslSemanticGOOGLE", .value = 5635, .parameters = &[_]OperandKind{.LiteralString} },
+                .{ .name = "UserTypeGOOGLE", .value = 5636, .parameters = &[_]OperandKind{.LiteralString} },
+                .{ .name = "FunctionRoundingModeINTEL", .value = 5822, .parameters = &[_]OperandKind{ .LiteralInteger, .FPRoundingMode } },
+                .{ .name = "FunctionDenormModeINTEL", .value = 5823, .parameters = &[_]OperandKind{ .LiteralInteger, .FPDenormMode } },
+                .{ .name = "RegisterINTEL", .value = 5825, .parameters = &[_]OperandKind{} },
+                .{ .name = "MemoryINTEL", .value = 5826, .parameters = &[_]OperandKind{.LiteralString} },
+                .{ .name = "NumbanksINTEL", .value = 5827, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "BankwidthINTEL", .value = 5828, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "MaxPrivateCopiesINTEL", .value = 5829, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SinglepumpINTEL", .value = 5830, .parameters = &[_]OperandKind{} },
+                .{ .name = "DoublepumpINTEL", .value = 5831, .parameters = &[_]OperandKind{} },
+                .{ .name = "MaxReplicatesINTEL", .value = 5832, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "SimpleDualPortINTEL", .value = 5833, .parameters = &[_]OperandKind{} },
+                .{ .name = "MergeINTEL", .value = 5834, .parameters = &[_]OperandKind{ .LiteralString, .LiteralString } },
+                .{ .name = "BankBitsINTEL", .value = 5835, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "ForcePow2DepthINTEL", .value = 5836, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "BurstCoalesceINTEL", .value = 5899, .parameters = &[_]OperandKind{} },
+                .{ .name = "CacheSizeINTEL", .value = 5900, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "DontStaticallyCoalesceINTEL", .value = 5901, .parameters = &[_]OperandKind{} },
+                .{ .name = "PrefetchINTEL", .value = 5902, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "StallEnableINTEL", .value = 5905, .parameters = &[_]OperandKind{} },
+                .{ .name = "FuseLoopsInFunctionINTEL", .value = 5907, .parameters = &[_]OperandKind{} },
+                .{ .name = "BufferLocationINTEL", .value = 5921, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "IOPipeStorageINTEL", .value = 5944, .parameters = &[_]OperandKind{.LiteralInteger} },
+                .{ .name = "FunctionFloatingPointModeINTEL", .value = 6080, .parameters = &[_]OperandKind{ .LiteralInteger, .FPOperationMode } },
+                .{ .name = "SingleElementVectorINTEL", .value = 6085, .parameters = &[_]OperandKind{} },
+                .{ .name = "VectorComputeCallableFunctionINTEL", .value = 6087, .parameters = &[_]OperandKind{} },
+                .{ .name = "MediaBlockIOINTEL", .value = 6140, .parameters = &[_]OperandKind{} },
+            },
+            .BuiltIn => &[_]Enumerant{
+                .{ .name = "Position", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "PointSize", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClipDistance", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "CullDistance", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "VertexId", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "InstanceId", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "PrimitiveId", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "InvocationId", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "Layer", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "ViewportIndex", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "TessLevelOuter", .value = 11, .parameters = &[_]OperandKind{} },
+                .{ .name = "TessLevelInner", .value = 12, .parameters = &[_]OperandKind{} },
+                .{ .name = "TessCoord", .value = 13, .parameters = &[_]OperandKind{} },
+                .{ .name = "PatchVertices", .value = 14, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragCoord", .value = 15, .parameters = &[_]OperandKind{} },
+                .{ .name = "PointCoord", .value = 16, .parameters = &[_]OperandKind{} },
+                .{ .name = "FrontFacing", .value = 17, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampleId", .value = 18, .parameters = &[_]OperandKind{} },
+                .{ .name = "SamplePosition", .value = 19, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampleMask", .value = 20, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragDepth", .value = 22, .parameters = &[_]OperandKind{} },
+                .{ .name = "HelperInvocation", .value = 23, .parameters = &[_]OperandKind{} },
+                .{ .name = "NumWorkgroups", .value = 24, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorkgroupSize", .value = 25, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorkgroupId", .value = 26, .parameters = &[_]OperandKind{} },
+                .{ .name = "LocalInvocationId", .value = 27, .parameters = &[_]OperandKind{} },
+                .{ .name = "GlobalInvocationId", .value = 28, .parameters = &[_]OperandKind{} },
+                .{ .name = "LocalInvocationIndex", .value = 29, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorkDim", .value = 30, .parameters = &[_]OperandKind{} },
+                .{ .name = "GlobalSize", .value = 31, .parameters = &[_]OperandKind{} },
+                .{ .name = "EnqueuedWorkgroupSize", .value = 32, .parameters = &[_]OperandKind{} },
+                .{ .name = "GlobalOffset", .value = 33, .parameters = &[_]OperandKind{} },
+                .{ .name = "GlobalLinearId", .value = 34, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupSize", .value = 36, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupMaxSize", .value = 37, .parameters = &[_]OperandKind{} },
+                .{ .name = "NumSubgroups", .value = 38, .parameters = &[_]OperandKind{} },
+                .{ .name = "NumEnqueuedSubgroups", .value = 39, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupId", .value = 40, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupLocalInvocationId", .value = 41, .parameters = &[_]OperandKind{} },
+                .{ .name = "VertexIndex", .value = 42, .parameters = &[_]OperandKind{} },
+                .{ .name = "InstanceIndex", .value = 43, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupEqMask", .value = 4416, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupEqMaskKHR", .value = 4416, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupGeMask", .value = 4417, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupGeMaskKHR", .value = 4417, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupGtMask", .value = 4418, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupGtMaskKHR", .value = 4418, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupLeMask", .value = 4419, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupLeMaskKHR", .value = 4419, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupLtMask", .value = 4420, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupLtMaskKHR", .value = 4420, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaseVertex", .value = 4424, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaseInstance", .value = 4425, .parameters = &[_]OperandKind{} },
+                .{ .name = "DrawIndex", .value = 4426, .parameters = &[_]OperandKind{} },
+                .{ .name = "PrimitiveShadingRateKHR", .value = 4432, .parameters = &[_]OperandKind{} },
+                .{ .name = "DeviceIndex", .value = 4438, .parameters = &[_]OperandKind{} },
+                .{ .name = "ViewIndex", .value = 4440, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShadingRateKHR", .value = 4444, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordNoPerspAMD", .value = 4992, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordNoPerspCentroidAMD", .value = 4993, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordNoPerspSampleAMD", .value = 4994, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordSmoothAMD", .value = 4995, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordSmoothCentroidAMD", .value = 4996, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordSmoothSampleAMD", .value = 4997, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordPullModelAMD", .value = 4998, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragStencilRefEXT", .value = 5014, .parameters = &[_]OperandKind{} },
+                .{ .name = "ViewportMaskNV", .value = 5253, .parameters = &[_]OperandKind{} },
+                .{ .name = "SecondaryPositionNV", .value = 5257, .parameters = &[_]OperandKind{} },
+                .{ .name = "SecondaryViewportMaskNV", .value = 5258, .parameters = &[_]OperandKind{} },
+                .{ .name = "PositionPerViewNV", .value = 5261, .parameters = &[_]OperandKind{} },
+                .{ .name = "ViewportMaskPerViewNV", .value = 5262, .parameters = &[_]OperandKind{} },
+                .{ .name = "FullyCoveredEXT", .value = 5264, .parameters = &[_]OperandKind{} },
+                .{ .name = "TaskCountNV", .value = 5274, .parameters = &[_]OperandKind{} },
+                .{ .name = "PrimitiveCountNV", .value = 5275, .parameters = &[_]OperandKind{} },
+                .{ .name = "PrimitiveIndicesNV", .value = 5276, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClipDistancePerViewNV", .value = 5277, .parameters = &[_]OperandKind{} },
+                .{ .name = "CullDistancePerViewNV", .value = 5278, .parameters = &[_]OperandKind{} },
+                .{ .name = "LayerPerViewNV", .value = 5279, .parameters = &[_]OperandKind{} },
+                .{ .name = "MeshViewCountNV", .value = 5280, .parameters = &[_]OperandKind{} },
+                .{ .name = "MeshViewIndicesNV", .value = 5281, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordKHR", .value = 5286, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordNV", .value = 5286, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordNoPerspKHR", .value = 5287, .parameters = &[_]OperandKind{} },
+                .{ .name = "BaryCoordNoPerspNV", .value = 5287, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragSizeEXT", .value = 5292, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentSizeNV", .value = 5292, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragInvocationCountEXT", .value = 5293, .parameters = &[_]OperandKind{} },
+                .{ .name = "InvocationsPerPixelNV", .value = 5293, .parameters = &[_]OperandKind{} },
+                .{ .name = "LaunchIdNV", .value = 5319, .parameters = &[_]OperandKind{} },
+                .{ .name = "LaunchIdKHR", .value = 5319, .parameters = &[_]OperandKind{} },
+                .{ .name = "LaunchSizeNV", .value = 5320, .parameters = &[_]OperandKind{} },
+                .{ .name = "LaunchSizeKHR", .value = 5320, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorldRayOriginNV", .value = 5321, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorldRayOriginKHR", .value = 5321, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorldRayDirectionNV", .value = 5322, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorldRayDirectionKHR", .value = 5322, .parameters = &[_]OperandKind{} },
+                .{ .name = "ObjectRayOriginNV", .value = 5323, .parameters = &[_]OperandKind{} },
+                .{ .name = "ObjectRayOriginKHR", .value = 5323, .parameters = &[_]OperandKind{} },
+                .{ .name = "ObjectRayDirectionNV", .value = 5324, .parameters = &[_]OperandKind{} },
+                .{ .name = "ObjectRayDirectionKHR", .value = 5324, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTminNV", .value = 5325, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTminKHR", .value = 5325, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTmaxNV", .value = 5326, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTmaxKHR", .value = 5326, .parameters = &[_]OperandKind{} },
+                .{ .name = "InstanceCustomIndexNV", .value = 5327, .parameters = &[_]OperandKind{} },
+                .{ .name = "InstanceCustomIndexKHR", .value = 5327, .parameters = &[_]OperandKind{} },
+                .{ .name = "ObjectToWorldNV", .value = 5330, .parameters = &[_]OperandKind{} },
+                .{ .name = "ObjectToWorldKHR", .value = 5330, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorldToObjectNV", .value = 5331, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorldToObjectKHR", .value = 5331, .parameters = &[_]OperandKind{} },
+                .{ .name = "HitTNV", .value = 5332, .parameters = &[_]OperandKind{} },
+                .{ .name = "HitKindNV", .value = 5333, .parameters = &[_]OperandKind{} },
+                .{ .name = "HitKindKHR", .value = 5333, .parameters = &[_]OperandKind{} },
+                .{ .name = "CurrentRayTimeNV", .value = 5334, .parameters = &[_]OperandKind{} },
+                .{ .name = "IncomingRayFlagsNV", .value = 5351, .parameters = &[_]OperandKind{} },
+                .{ .name = "IncomingRayFlagsKHR", .value = 5351, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayGeometryIndexKHR", .value = 5352, .parameters = &[_]OperandKind{} },
+                .{ .name = "WarpsPerSMNV", .value = 5374, .parameters = &[_]OperandKind{} },
+                .{ .name = "SMCountNV", .value = 5375, .parameters = &[_]OperandKind{} },
+                .{ .name = "WarpIDNV", .value = 5376, .parameters = &[_]OperandKind{} },
+                .{ .name = "SMIDNV", .value = 5377, .parameters = &[_]OperandKind{} },
+            },
+            .Scope => &[_]Enumerant{
+                .{ .name = "CrossDevice", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Device", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "Workgroup", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Subgroup", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "Invocation", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "QueueFamily", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "QueueFamilyKHR", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderCallKHR", .value = 6, .parameters = &[_]OperandKind{} },
+            },
+            .GroupOperation => &[_]Enumerant{
+                .{ .name = "Reduce", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "InclusiveScan", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "ExclusiveScan", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClusteredReduce", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "PartitionedReduceNV", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "PartitionedInclusiveScanNV", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "PartitionedExclusiveScanNV", .value = 8, .parameters = &[_]OperandKind{} },
+            },
+            .KernelEnqueueFlags => &[_]Enumerant{
+                .{ .name = "NoWait", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "WaitKernel", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "WaitWorkGroup", .value = 2, .parameters = &[_]OperandKind{} },
+            },
+            .Capability => &[_]Enumerant{
+                .{ .name = "Matrix", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "Shader", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "Geometry", .value = 2, .parameters = &[_]OperandKind{} },
+                .{ .name = "Tessellation", .value = 3, .parameters = &[_]OperandKind{} },
+                .{ .name = "Addresses", .value = 4, .parameters = &[_]OperandKind{} },
+                .{ .name = "Linkage", .value = 5, .parameters = &[_]OperandKind{} },
+                .{ .name = "Kernel", .value = 6, .parameters = &[_]OperandKind{} },
+                .{ .name = "Vector16", .value = 7, .parameters = &[_]OperandKind{} },
+                .{ .name = "Float16Buffer", .value = 8, .parameters = &[_]OperandKind{} },
+                .{ .name = "Float16", .value = 9, .parameters = &[_]OperandKind{} },
+                .{ .name = "Float64", .value = 10, .parameters = &[_]OperandKind{} },
+                .{ .name = "Int64", .value = 11, .parameters = &[_]OperandKind{} },
+                .{ .name = "Int64Atomics", .value = 12, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageBasic", .value = 13, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageReadWrite", .value = 14, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageMipmap", .value = 15, .parameters = &[_]OperandKind{} },
+                .{ .name = "Pipes", .value = 17, .parameters = &[_]OperandKind{} },
+                .{ .name = "Groups", .value = 18, .parameters = &[_]OperandKind{} },
+                .{ .name = "DeviceEnqueue", .value = 19, .parameters = &[_]OperandKind{} },
+                .{ .name = "LiteralSampler", .value = 20, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicStorage", .value = 21, .parameters = &[_]OperandKind{} },
+                .{ .name = "Int16", .value = 22, .parameters = &[_]OperandKind{} },
+                .{ .name = "TessellationPointSize", .value = 23, .parameters = &[_]OperandKind{} },
+                .{ .name = "GeometryPointSize", .value = 24, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageGatherExtended", .value = 25, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageImageMultisample", .value = 27, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformBufferArrayDynamicIndexing", .value = 28, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampledImageArrayDynamicIndexing", .value = 29, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageBufferArrayDynamicIndexing", .value = 30, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageImageArrayDynamicIndexing", .value = 31, .parameters = &[_]OperandKind{} },
+                .{ .name = "ClipDistance", .value = 32, .parameters = &[_]OperandKind{} },
+                .{ .name = "CullDistance", .value = 33, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageCubeArray", .value = 34, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampleRateShading", .value = 35, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageRect", .value = 36, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampledRect", .value = 37, .parameters = &[_]OperandKind{} },
+                .{ .name = "GenericPointer", .value = 38, .parameters = &[_]OperandKind{} },
+                .{ .name = "Int8", .value = 39, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputAttachment", .value = 40, .parameters = &[_]OperandKind{} },
+                .{ .name = "SparseResidency", .value = 41, .parameters = &[_]OperandKind{} },
+                .{ .name = "MinLod", .value = 42, .parameters = &[_]OperandKind{} },
+                .{ .name = "Sampled1D", .value = 43, .parameters = &[_]OperandKind{} },
+                .{ .name = "Image1D", .value = 44, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampledCubeArray", .value = 45, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampledBuffer", .value = 46, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageBuffer", .value = 47, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageMSArray", .value = 48, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageImageExtendedFormats", .value = 49, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageQuery", .value = 50, .parameters = &[_]OperandKind{} },
+                .{ .name = "DerivativeControl", .value = 51, .parameters = &[_]OperandKind{} },
+                .{ .name = "InterpolationFunction", .value = 52, .parameters = &[_]OperandKind{} },
+                .{ .name = "TransformFeedback", .value = 53, .parameters = &[_]OperandKind{} },
+                .{ .name = "GeometryStreams", .value = 54, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageImageReadWithoutFormat", .value = 55, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageImageWriteWithoutFormat", .value = 56, .parameters = &[_]OperandKind{} },
+                .{ .name = "MultiViewport", .value = 57, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupDispatch", .value = 58, .parameters = &[_]OperandKind{} },
+                .{ .name = "NamedBarrier", .value = 59, .parameters = &[_]OperandKind{} },
+                .{ .name = "PipeStorage", .value = 60, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniform", .value = 61, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformVote", .value = 62, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformArithmetic", .value = 63, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformBallot", .value = 64, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformShuffle", .value = 65, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformShuffleRelative", .value = 66, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformClustered", .value = 67, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformQuad", .value = 68, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderLayer", .value = 69, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderViewportIndex", .value = 70, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformDecoration", .value = 71, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentShadingRateKHR", .value = 4422, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupBallotKHR", .value = 4423, .parameters = &[_]OperandKind{} },
+                .{ .name = "DrawParameters", .value = 4427, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorkgroupMemoryExplicitLayoutKHR", .value = 4428, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorkgroupMemoryExplicitLayout8BitAccessKHR", .value = 4429, .parameters = &[_]OperandKind{} },
+                .{ .name = "WorkgroupMemoryExplicitLayout16BitAccessKHR", .value = 4430, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupVoteKHR", .value = 4431, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageBuffer16BitAccess", .value = 4433, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageUniformBufferBlock16", .value = 4433, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformAndStorageBuffer16BitAccess", .value = 4434, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageUniform16", .value = 4434, .parameters = &[_]OperandKind{} },
+                .{ .name = "StoragePushConstant16", .value = 4435, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageInputOutput16", .value = 4436, .parameters = &[_]OperandKind{} },
+                .{ .name = "DeviceGroup", .value = 4437, .parameters = &[_]OperandKind{} },
+                .{ .name = "MultiView", .value = 4439, .parameters = &[_]OperandKind{} },
+                .{ .name = "VariablePointersStorageBuffer", .value = 4441, .parameters = &[_]OperandKind{} },
+                .{ .name = "VariablePointers", .value = 4442, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicStorageOps", .value = 4445, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampleMaskPostDepthCoverage", .value = 4447, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageBuffer8BitAccess", .value = 4448, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformAndStorageBuffer8BitAccess", .value = 4449, .parameters = &[_]OperandKind{} },
+                .{ .name = "StoragePushConstant8", .value = 4450, .parameters = &[_]OperandKind{} },
+                .{ .name = "DenormPreserve", .value = 4464, .parameters = &[_]OperandKind{} },
+                .{ .name = "DenormFlushToZero", .value = 4465, .parameters = &[_]OperandKind{} },
+                .{ .name = "SignedZeroInfNanPreserve", .value = 4466, .parameters = &[_]OperandKind{} },
+                .{ .name = "RoundingModeRTE", .value = 4467, .parameters = &[_]OperandKind{} },
+                .{ .name = "RoundingModeRTZ", .value = 4468, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayQueryProvisionalKHR", .value = 4471, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayQueryKHR", .value = 4472, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTraversalPrimitiveCullingKHR", .value = 4478, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTracingKHR", .value = 4479, .parameters = &[_]OperandKind{} },
+                .{ .name = "Float16ImageAMD", .value = 5008, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageGatherBiasLodAMD", .value = 5009, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentMaskAMD", .value = 5010, .parameters = &[_]OperandKind{} },
+                .{ .name = "StencilExportEXT", .value = 5013, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageReadWriteLodAMD", .value = 5015, .parameters = &[_]OperandKind{} },
+                .{ .name = "Int64ImageEXT", .value = 5016, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderClockKHR", .value = 5055, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampleMaskOverrideCoverageNV", .value = 5249, .parameters = &[_]OperandKind{} },
+                .{ .name = "GeometryShaderPassthroughNV", .value = 5251, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderViewportIndexLayerEXT", .value = 5254, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderViewportIndexLayerNV", .value = 5254, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderViewportMaskNV", .value = 5255, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderStereoViewNV", .value = 5259, .parameters = &[_]OperandKind{} },
+                .{ .name = "PerViewAttributesNV", .value = 5260, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentFullyCoveredEXT", .value = 5265, .parameters = &[_]OperandKind{} },
+                .{ .name = "MeshShadingNV", .value = 5266, .parameters = &[_]OperandKind{} },
+                .{ .name = "ImageFootprintNV", .value = 5282, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentBarycentricKHR", .value = 5284, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentBarycentricNV", .value = 5284, .parameters = &[_]OperandKind{} },
+                .{ .name = "ComputeDerivativeGroupQuadsNV", .value = 5288, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentDensityEXT", .value = 5291, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShadingRateNV", .value = 5291, .parameters = &[_]OperandKind{} },
+                .{ .name = "GroupNonUniformPartitionedNV", .value = 5297, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderNonUniform", .value = 5301, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderNonUniformEXT", .value = 5301, .parameters = &[_]OperandKind{} },
+                .{ .name = "RuntimeDescriptorArray", .value = 5302, .parameters = &[_]OperandKind{} },
+                .{ .name = "RuntimeDescriptorArrayEXT", .value = 5302, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputAttachmentArrayDynamicIndexing", .value = 5303, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputAttachmentArrayDynamicIndexingEXT", .value = 5303, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformTexelBufferArrayDynamicIndexing", .value = 5304, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformTexelBufferArrayDynamicIndexingEXT", .value = 5304, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageTexelBufferArrayDynamicIndexing", .value = 5305, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageTexelBufferArrayDynamicIndexingEXT", .value = 5305, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformBufferArrayNonUniformIndexing", .value = 5306, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformBufferArrayNonUniformIndexingEXT", .value = 5306, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampledImageArrayNonUniformIndexing", .value = 5307, .parameters = &[_]OperandKind{} },
+                .{ .name = "SampledImageArrayNonUniformIndexingEXT", .value = 5307, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageBufferArrayNonUniformIndexing", .value = 5308, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageBufferArrayNonUniformIndexingEXT", .value = 5308, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageImageArrayNonUniformIndexing", .value = 5309, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageImageArrayNonUniformIndexingEXT", .value = 5309, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputAttachmentArrayNonUniformIndexing", .value = 5310, .parameters = &[_]OperandKind{} },
+                .{ .name = "InputAttachmentArrayNonUniformIndexingEXT", .value = 5310, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformTexelBufferArrayNonUniformIndexing", .value = 5311, .parameters = &[_]OperandKind{} },
+                .{ .name = "UniformTexelBufferArrayNonUniformIndexingEXT", .value = 5311, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageTexelBufferArrayNonUniformIndexing", .value = 5312, .parameters = &[_]OperandKind{} },
+                .{ .name = "StorageTexelBufferArrayNonUniformIndexingEXT", .value = 5312, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTracingNV", .value = 5340, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTracingMotionBlurNV", .value = 5341, .parameters = &[_]OperandKind{} },
+                .{ .name = "VulkanMemoryModel", .value = 5345, .parameters = &[_]OperandKind{} },
+                .{ .name = "VulkanMemoryModelKHR", .value = 5345, .parameters = &[_]OperandKind{} },
+                .{ .name = "VulkanMemoryModelDeviceScope", .value = 5346, .parameters = &[_]OperandKind{} },
+                .{ .name = "VulkanMemoryModelDeviceScopeKHR", .value = 5346, .parameters = &[_]OperandKind{} },
+                .{ .name = "PhysicalStorageBufferAddresses", .value = 5347, .parameters = &[_]OperandKind{} },
+                .{ .name = "PhysicalStorageBufferAddressesEXT", .value = 5347, .parameters = &[_]OperandKind{} },
+                .{ .name = "ComputeDerivativeGroupLinearNV", .value = 5350, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayTracingProvisionalKHR", .value = 5353, .parameters = &[_]OperandKind{} },
+                .{ .name = "CooperativeMatrixNV", .value = 5357, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentShaderSampleInterlockEXT", .value = 5363, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentShaderShadingRateInterlockEXT", .value = 5372, .parameters = &[_]OperandKind{} },
+                .{ .name = "ShaderSMBuiltinsNV", .value = 5373, .parameters = &[_]OperandKind{} },
+                .{ .name = "FragmentShaderPixelInterlockEXT", .value = 5378, .parameters = &[_]OperandKind{} },
+                .{ .name = "DemoteToHelperInvocation", .value = 5379, .parameters = &[_]OperandKind{} },
+                .{ .name = "DemoteToHelperInvocationEXT", .value = 5379, .parameters = &[_]OperandKind{} },
+                .{ .name = "BindlessTextureNV", .value = 5390, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupShuffleINTEL", .value = 5568, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupBufferBlockIOINTEL", .value = 5569, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupImageBlockIOINTEL", .value = 5570, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupImageMediaBlockIOINTEL", .value = 5579, .parameters = &[_]OperandKind{} },
+                .{ .name = "RoundToInfinityINTEL", .value = 5582, .parameters = &[_]OperandKind{} },
+                .{ .name = "FloatingPointModeINTEL", .value = 5583, .parameters = &[_]OperandKind{} },
+                .{ .name = "IntegerFunctions2INTEL", .value = 5584, .parameters = &[_]OperandKind{} },
+                .{ .name = "FunctionPointersINTEL", .value = 5603, .parameters = &[_]OperandKind{} },
+                .{ .name = "IndirectReferencesINTEL", .value = 5604, .parameters = &[_]OperandKind{} },
+                .{ .name = "AsmINTEL", .value = 5606, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicFloat32MinMaxEXT", .value = 5612, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicFloat64MinMaxEXT", .value = 5613, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicFloat16MinMaxEXT", .value = 5616, .parameters = &[_]OperandKind{} },
+                .{ .name = "VectorComputeINTEL", .value = 5617, .parameters = &[_]OperandKind{} },
+                .{ .name = "VectorAnyINTEL", .value = 5619, .parameters = &[_]OperandKind{} },
+                .{ .name = "ExpectAssumeKHR", .value = 5629, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupAvcMotionEstimationINTEL", .value = 5696, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupAvcMotionEstimationIntraINTEL", .value = 5697, .parameters = &[_]OperandKind{} },
+                .{ .name = "SubgroupAvcMotionEstimationChromaINTEL", .value = 5698, .parameters = &[_]OperandKind{} },
+                .{ .name = "VariableLengthArrayINTEL", .value = 5817, .parameters = &[_]OperandKind{} },
+                .{ .name = "FunctionFloatControlINTEL", .value = 5821, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPGAMemoryAttributesINTEL", .value = 5824, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPFastMathModeINTEL", .value = 5837, .parameters = &[_]OperandKind{} },
+                .{ .name = "ArbitraryPrecisionIntegersINTEL", .value = 5844, .parameters = &[_]OperandKind{} },
+                .{ .name = "ArbitraryPrecisionFloatingPointINTEL", .value = 5845, .parameters = &[_]OperandKind{} },
+                .{ .name = "UnstructuredLoopControlsINTEL", .value = 5886, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPGALoopControlsINTEL", .value = 5888, .parameters = &[_]OperandKind{} },
+                .{ .name = "KernelAttributesINTEL", .value = 5892, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPGAKernelAttributesINTEL", .value = 5897, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPGAMemoryAccessesINTEL", .value = 5898, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPGAClusterAttributesINTEL", .value = 5904, .parameters = &[_]OperandKind{} },
+                .{ .name = "LoopFuseINTEL", .value = 5906, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPGABufferLocationINTEL", .value = 5920, .parameters = &[_]OperandKind{} },
+                .{ .name = "ArbitraryPrecisionFixedPointINTEL", .value = 5922, .parameters = &[_]OperandKind{} },
+                .{ .name = "USMStorageClassesINTEL", .value = 5935, .parameters = &[_]OperandKind{} },
+                .{ .name = "IOPipesINTEL", .value = 5943, .parameters = &[_]OperandKind{} },
+                .{ .name = "BlockingPipesINTEL", .value = 5945, .parameters = &[_]OperandKind{} },
+                .{ .name = "FPGARegINTEL", .value = 5948, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProductInputAll", .value = 6016, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProductInputAllKHR", .value = 6016, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProductInput4x8Bit", .value = 6017, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProductInput4x8BitKHR", .value = 6017, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProductInput4x8BitPacked", .value = 6018, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProductInput4x8BitPackedKHR", .value = 6018, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProduct", .value = 6019, .parameters = &[_]OperandKind{} },
+                .{ .name = "DotProductKHR", .value = 6019, .parameters = &[_]OperandKind{} },
+                .{ .name = "BitInstructions", .value = 6025, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicFloat32AddEXT", .value = 6033, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicFloat64AddEXT", .value = 6034, .parameters = &[_]OperandKind{} },
+                .{ .name = "LongConstantCompositeINTEL", .value = 6089, .parameters = &[_]OperandKind{} },
+                .{ .name = "OptNoneINTEL", .value = 6094, .parameters = &[_]OperandKind{} },
+                .{ .name = "AtomicFloat16AddEXT", .value = 6095, .parameters = &[_]OperandKind{} },
+                .{ .name = "DebugInfoModuleINTEL", .value = 6114, .parameters = &[_]OperandKind{} },
+            },
+            .RayQueryIntersection => &[_]Enumerant{
+                .{ .name = "RayQueryCandidateIntersectionKHR", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayQueryCommittedIntersectionKHR", .value = 1, .parameters = &[_]OperandKind{} },
+            },
+            .RayQueryCommittedIntersectionType => &[_]Enumerant{
+                .{ .name = "RayQueryCommittedIntersectionNoneKHR", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayQueryCommittedIntersectionTriangleKHR", .value = 1, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayQueryCommittedIntersectionGeneratedKHR", .value = 2, .parameters = &[_]OperandKind{} },
+            },
+            .RayQueryCandidateIntersectionType => &[_]Enumerant{
+                .{ .name = "RayQueryCandidateIntersectionTriangleKHR", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "RayQueryCandidateIntersectionAABBKHR", .value = 1, .parameters = &[_]OperandKind{} },
+            },
+            .PackedVectorFormat => &[_]Enumerant{
+                .{ .name = "PackedVectorFormat4x8Bit", .value = 0, .parameters = &[_]OperandKind{} },
+                .{ .name = "PackedVectorFormat4x8BitKHR", .value = 0, .parameters = &[_]OperandKind{} },
+            },
+            .IdResultType => unreachable,
+            .IdResult => unreachable,
+            .IdMemorySemantics => unreachable,
+            .IdScope => unreachable,
+            .IdRef => unreachable,
+            .LiteralInteger => unreachable,
+            .LiteralString => unreachable,
+            .LiteralContextDependentNumber => unreachable,
+            .LiteralExtInstInteger => unreachable,
+            .LiteralSpecConstantOpInteger => unreachable,
+            .PairLiteralIntegerIdRef => unreachable,
+            .PairIdRefLiteralInteger => unreachable,
+            .PairIdRefIdRef => unreachable,
+        };
+    }
+};
 pub const Opcode = enum(u16) {
     OpNop = 0,
     OpUndef = 1,
@@ -398,6 +1493,12 @@ pub const Opcode = enum(u16) {
     OpConvertUToAccelerationStructureKHR = 4447,
     OpIgnoreIntersectionKHR = 4448,
     OpTerminateRayKHR = 4449,
+    OpSDot = 4450,
+    OpUDot = 4451,
+    OpSUDot = 4452,
+    OpSDotAccSat = 4453,
+    OpUDotAccSat = 4454,
+    OpSUDotAccSat = 4455,
     OpTypeRayQueryKHR = 4472,
     OpRayQueryInitializeKHR = 4473,
     OpRayQueryTerminateKHR = 4474,
@@ -423,6 +1524,8 @@ pub const Opcode = enum(u16) {
     OpIgnoreIntersectionNV = 5335,
     OpTerminateRayNV = 5336,
     OpTraceNV = 5337,
+    OpTraceMotionNV = 5338,
+    OpTraceRayMotionNV = 5339,
     OpTypeAccelerationStructureKHR = 5341,
     OpExecuteCallableNV = 5344,
     OpTypeCooperativeMatrixNV = 5358,
@@ -432,8 +1535,15 @@ pub const Opcode = enum(u16) {
     OpCooperativeMatrixLengthNV = 5362,
     OpBeginInvocationInterlockEXT = 5364,
     OpEndInvocationInterlockEXT = 5365,
-    OpDemoteToHelperInvocationEXT = 5380,
+    OpDemoteToHelperInvocation = 5380,
     OpIsHelperInvocationEXT = 5381,
+    OpConvertUToImageNV = 5391,
+    OpConvertUToSamplerNV = 5392,
+    OpConvertImageToUNV = 5393,
+    OpConvertSamplerToUNV = 5394,
+    OpConvertUToSampledImageNV = 5395,
+    OpConvertSampledImageToUNV = 5396,
+    OpSamplerImageAddressingModeNV = 5397,
     OpSubgroupShuffleINTEL = 5571,
     OpSubgroupShuffleDownINTEL = 5572,
     OpSubgroupShuffleUpINTEL = 5573,
@@ -458,141 +1568,13 @@ pub const Opcode = enum(u16) {
     OpUSubSatINTEL = 5596,
     OpIMul32x16INTEL = 5597,
     OpUMul32x16INTEL = 5598,
-    OpConstFunctionPointerINTEL = 5600,
-    OpFunctionPointerCallINTEL = 5601,
-    OpAsmTargetINTEL = 5609,
-    OpAsmINTEL = 5610,
-    OpAsmCallINTEL = 5611,
     OpAtomicFMinEXT = 5614,
     OpAtomicFMaxEXT = 5615,
     OpAssumeTrueKHR = 5630,
     OpExpectKHR = 5631,
     OpDecorateString = 5632,
     OpMemberDecorateString = 5633,
-    OpVmeImageINTEL = 5699,
-    OpTypeVmeImageINTEL = 5700,
-    OpTypeAvcImePayloadINTEL = 5701,
-    OpTypeAvcRefPayloadINTEL = 5702,
-    OpTypeAvcSicPayloadINTEL = 5703,
-    OpTypeAvcMcePayloadINTEL = 5704,
-    OpTypeAvcMceResultINTEL = 5705,
-    OpTypeAvcImeResultINTEL = 5706,
-    OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707,
-    OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708,
-    OpTypeAvcImeSingleReferenceStreaminINTEL = 5709,
-    OpTypeAvcImeDualReferenceStreaminINTEL = 5710,
-    OpTypeAvcRefResultINTEL = 5711,
-    OpTypeAvcSicResultINTEL = 5712,
-    OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713,
-    OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714,
-    OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715,
-    OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716,
-    OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717,
-    OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718,
-    OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719,
-    OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720,
-    OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721,
-    OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722,
-    OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723,
-    OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724,
-    OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725,
-    OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726,
-    OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727,
-    OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728,
-    OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729,
-    OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730,
-    OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731,
-    OpSubgroupAvcMceConvertToImePayloadINTEL = 5732,
-    OpSubgroupAvcMceConvertToImeResultINTEL = 5733,
-    OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734,
-    OpSubgroupAvcMceConvertToRefResultINTEL = 5735,
-    OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736,
-    OpSubgroupAvcMceConvertToSicResultINTEL = 5737,
-    OpSubgroupAvcMceGetMotionVectorsINTEL = 5738,
-    OpSubgroupAvcMceGetInterDistortionsINTEL = 5739,
-    OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740,
-    OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741,
-    OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742,
-    OpSubgroupAvcMceGetInterDirectionsINTEL = 5743,
-    OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744,
-    OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745,
-    OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746,
-    OpSubgroupAvcImeInitializeINTEL = 5747,
-    OpSubgroupAvcImeSetSingleReferenceINTEL = 5748,
-    OpSubgroupAvcImeSetDualReferenceINTEL = 5749,
-    OpSubgroupAvcImeRefWindowSizeINTEL = 5750,
-    OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751,
-    OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752,
-    OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753,
-    OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754,
-    OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755,
-    OpSubgroupAvcImeSetWeightedSadINTEL = 5756,
-    OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757,
-    OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758,
-    OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759,
-    OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760,
-    OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761,
-    OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762,
-    OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763,
-    OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764,
-    OpSubgroupAvcImeConvertToMceResultINTEL = 5765,
-    OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766,
-    OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767,
-    OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768,
-    OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769,
-    OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770,
-    OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771,
-    OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772,
-    OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773,
-    OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774,
-    OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775,
-    OpSubgroupAvcImeGetBorderReachedINTEL = 5776,
-    OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777,
-    OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778,
-    OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779,
-    OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780,
-    OpSubgroupAvcFmeInitializeINTEL = 5781,
-    OpSubgroupAvcBmeInitializeINTEL = 5782,
-    OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783,
-    OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784,
-    OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785,
-    OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786,
-    OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787,
-    OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788,
-    OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789,
-    OpSubgroupAvcRefConvertToMceResultINTEL = 5790,
-    OpSubgroupAvcSicInitializeINTEL = 5791,
-    OpSubgroupAvcSicConfigureSkcINTEL = 5792,
-    OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793,
-    OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794,
-    OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795,
-    OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796,
-    OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797,
-    OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798,
-    OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799,
-    OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800,
-    OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801,
-    OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802,
-    OpSubgroupAvcSicEvaluateIpeINTEL = 5803,
-    OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804,
-    OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805,
-    OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806,
-    OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807,
-    OpSubgroupAvcSicConvertToMceResultINTEL = 5808,
-    OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809,
-    OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810,
-    OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811,
-    OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812,
-    OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813,
-    OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814,
-    OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815,
-    OpSubgroupAvcSicGetInterRawSadsINTEL = 5816,
-    OpVariableLengthArrayINTEL = 5818,
-    OpSaveMemoryINTEL = 5819,
-    OpRestoreMemoryINTEL = 5820,
     OpLoopControlINTEL = 5887,
-    OpPtrCastToCrossWorkgroupINTEL = 5934,
-    OpCrossWorkgroupCastToPtrINTEL = 5938,
     OpReadPipeBlockingINTEL = 5946,
     OpWritePipeBlockingINTEL = 5947,
     OpFPGARegINTEL = 5949,
@@ -619,8 +1601,15 @@ pub const Opcode = enum(u16) {
     OpConstantCompositeContinuedINTEL = 6091,
     OpSpecConstantCompositeContinuedINTEL = 6092,
 
+    pub const OpSDotKHR = Opcode.OpSDot;
+    pub const OpUDotKHR = Opcode.OpUDot;
+    pub const OpSUDotKHR = Opcode.OpSUDot;
+    pub const OpSDotAccSatKHR = Opcode.OpSDotAccSat;
+    pub const OpUDotAccSatKHR = Opcode.OpUDotAccSat;
+    pub const OpSUDotAccSatKHR = Opcode.OpSUDotAccSat;
     pub const OpReportIntersectionNV = Opcode.OpReportIntersectionKHR;
     pub const OpTypeAccelerationStructureNV = Opcode.OpTypeAccelerationStructureKHR;
+    pub const OpDemoteToHelperInvocationEXT = Opcode.OpDemoteToHelperInvocation;
     pub const OpDecorateStringGOOGLE = Opcode.OpDecorateString;
     pub const OpMemberDecorateStringGOOGLE = Opcode.OpMemberDecorateString;
 
@@ -982,6 +1971,12 @@ pub const Opcode = enum(u16) {
             .OpConvertUToAccelerationStructureKHR => struct { id_result_type: IdResultType, id_result: IdResult, accel: IdRef },
             .OpIgnoreIntersectionKHR => void,
             .OpTerminateRayKHR => void,
+            .OpSDot => struct { id_result_type: IdResultType, id_result: IdResult, vector_1: IdRef, vector_2: IdRef, packed_vector_format: ?PackedVectorFormat = null },
+            .OpUDot => struct { id_result_type: IdResultType, id_result: IdResult, vector_1: IdRef, vector_2: IdRef, packed_vector_format: ?PackedVectorFormat = null },
+            .OpSUDot => struct { id_result_type: IdResultType, id_result: IdResult, vector_1: IdRef, vector_2: IdRef, packed_vector_format: ?PackedVectorFormat = null },
+            .OpSDotAccSat => struct { id_result_type: IdResultType, id_result: IdResult, vector_1: IdRef, vector_2: IdRef, accumulator: IdRef, packed_vector_format: ?PackedVectorFormat = null },
+            .OpUDotAccSat => struct { id_result_type: IdResultType, id_result: IdResult, vector_1: IdRef, vector_2: IdRef, accumulator: IdRef, packed_vector_format: ?PackedVectorFormat = null },
+            .OpSUDotAccSat => struct { id_result_type: IdResultType, id_result: IdResult, vector_1: IdRef, vector_2: IdRef, accumulator: IdRef, packed_vector_format: ?PackedVectorFormat = null },
             .OpTypeRayQueryKHR => struct { id_result: IdResult },
             .OpRayQueryInitializeKHR => struct { rayquery: IdRef, accel: IdRef, rayflags: IdRef, cullmask: IdRef, rayorigin: IdRef, raytmin: IdRef, raydirection: IdRef, raytmax: IdRef },
             .OpRayQueryTerminateKHR => struct { rayquery: IdRef },
@@ -1007,6 +2002,8 @@ pub const Opcode = enum(u16) {
             .OpIgnoreIntersectionNV => void,
             .OpTerminateRayNV => void,
             .OpTraceNV => struct { accel: IdRef, ray_flags: IdRef, cull_mask: IdRef, sbt_offset: IdRef, sbt_stride: IdRef, miss_index: IdRef, ray_origin: IdRef, ray_tmin: IdRef, ray_direction: IdRef, ray_tmax: IdRef, payloadid: IdRef },
+            .OpTraceMotionNV => struct { accel: IdRef, ray_flags: IdRef, cull_mask: IdRef, sbt_offset: IdRef, sbt_stride: IdRef, miss_index: IdRef, ray_origin: IdRef, ray_tmin: IdRef, ray_direction: IdRef, ray_tmax: IdRef, time: IdRef, payloadid: IdRef },
+            .OpTraceRayMotionNV => struct { accel: IdRef, ray_flags: IdRef, cull_mask: IdRef, sbt_offset: IdRef, sbt_stride: IdRef, miss_index: IdRef, ray_origin: IdRef, ray_tmin: IdRef, ray_direction: IdRef, ray_tmax: IdRef, time: IdRef, payload: IdRef },
             .OpTypeAccelerationStructureKHR => struct { id_result: IdResult },
             .OpExecuteCallableNV => struct { sbt_index: IdRef, callable_dataid: IdRef },
             .OpTypeCooperativeMatrixNV => struct { id_result: IdResult, component_type: IdRef, execution: IdScope, rows: IdRef, columns: IdRef },
@@ -1016,8 +2013,15 @@ pub const Opcode = enum(u16) {
             .OpCooperativeMatrixLengthNV => struct { id_result_type: IdResultType, id_result: IdResult, type: IdRef },
             .OpBeginInvocationInterlockEXT => void,
             .OpEndInvocationInterlockEXT => void,
-            .OpDemoteToHelperInvocationEXT => void,
+            .OpDemoteToHelperInvocation => void,
             .OpIsHelperInvocationEXT => struct { id_result_type: IdResultType, id_result: IdResult },
+            .OpConvertUToImageNV => struct { id_result_type: IdResultType, id_result: IdResult, operand: IdRef },
+            .OpConvertUToSamplerNV => struct { id_result_type: IdResultType, id_result: IdResult, operand: IdRef },
+            .OpConvertImageToUNV => struct { id_result_type: IdResultType, id_result: IdResult, operand: IdRef },
+            .OpConvertSamplerToUNV => struct { id_result_type: IdResultType, id_result: IdResult, operand: IdRef },
+            .OpConvertUToSampledImageNV => struct { id_result_type: IdResultType, id_result: IdResult, operand: IdRef },
+            .OpConvertSampledImageToUNV => struct { id_result_type: IdResultType, id_result: IdResult, operand: IdRef },
+            .OpSamplerImageAddressingModeNV => struct { bit_width: LiteralInteger },
             .OpSubgroupShuffleINTEL => struct { id_result_type: IdResultType, id_result: IdResult, data: IdRef, invocationid: IdRef },
             .OpSubgroupShuffleDownINTEL => struct { id_result_type: IdResultType, id_result: IdResult, current: IdRef, next: IdRef, delta: IdRef },
             .OpSubgroupShuffleUpINTEL => struct { id_result_type: IdResultType, id_result: IdResult, previous: IdRef, current: IdRef, delta: IdRef },
@@ -1042,141 +2046,13 @@ pub const Opcode = enum(u16) {
             .OpUSubSatINTEL => struct { id_result_type: IdResultType, id_result: IdResult, operand_1: IdRef, operand_2: IdRef },
             .OpIMul32x16INTEL => struct { id_result_type: IdResultType, id_result: IdResult, operand_1: IdRef, operand_2: IdRef },
             .OpUMul32x16INTEL => struct { id_result_type: IdResultType, id_result: IdResult, operand_1: IdRef, operand_2: IdRef },
-            .OpConstFunctionPointerINTEL => struct { id_result_type: IdResultType, id_result: IdResult, function: IdRef },
-            .OpFunctionPointerCallINTEL => struct { id_result_type: IdResultType, id_result: IdResult, operand_1: []const IdRef = &.{} },
-            .OpAsmTargetINTEL => struct { id_result_type: IdResultType, id_result: IdResult, asm_target: LiteralString },
-            .OpAsmINTEL => struct { id_result_type: IdResultType, id_result: IdResult, asm_type: IdRef, target: IdRef, asm_instructions: LiteralString, constraints: LiteralString },
-            .OpAsmCallINTEL => struct { id_result_type: IdResultType, id_result: IdResult, @"asm": IdRef, argument_0: []const IdRef = &.{} },
             .OpAtomicFMinEXT => struct { id_result_type: IdResultType, id_result: IdResult, pointer: IdRef, memory: IdScope, semantics: IdMemorySemantics, value: IdRef },
             .OpAtomicFMaxEXT => struct { id_result_type: IdResultType, id_result: IdResult, pointer: IdRef, memory: IdScope, semantics: IdMemorySemantics, value: IdRef },
             .OpAssumeTrueKHR => struct { condition: IdRef },
             .OpExpectKHR => struct { id_result_type: IdResultType, id_result: IdResult, value: IdRef, expectedvalue: IdRef },
             .OpDecorateString => struct { target: IdRef, decoration: Decoration.Extended },
             .OpMemberDecorateString => struct { struct_type: IdRef, member: LiteralInteger, decoration: Decoration.Extended },
-            .OpVmeImageINTEL => struct { id_result_type: IdResultType, id_result: IdResult, image_type: IdRef, sampler: IdRef },
-            .OpTypeVmeImageINTEL => struct { id_result: IdResult, image_type: IdRef },
-            .OpTypeAvcImePayloadINTEL => struct { id_result: IdResult },
-            .OpTypeAvcRefPayloadINTEL => struct { id_result: IdResult },
-            .OpTypeAvcSicPayloadINTEL => struct { id_result: IdResult },
-            .OpTypeAvcMcePayloadINTEL => struct { id_result: IdResult },
-            .OpTypeAvcMceResultINTEL => struct { id_result: IdResult },
-            .OpTypeAvcImeResultINTEL => struct { id_result: IdResult },
-            .OpTypeAvcImeResultSingleReferenceStreamoutINTEL => struct { id_result: IdResult },
-            .OpTypeAvcImeResultDualReferenceStreamoutINTEL => struct { id_result: IdResult },
-            .OpTypeAvcImeSingleReferenceStreaminINTEL => struct { id_result: IdResult },
-            .OpTypeAvcImeDualReferenceStreaminINTEL => struct { id_result: IdResult },
-            .OpTypeAvcRefResultINTEL => struct { id_result: IdResult },
-            .OpTypeAvcSicResultINTEL => struct { id_result: IdResult },
-            .OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, slice_type: IdRef, qp: IdRef },
-            .OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, reference_base_penalty: IdRef, payload: IdRef },
-            .OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, slice_type: IdRef, qp: IdRef },
-            .OpSubgroupAvcMceSetInterShapePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packed_shape_penalty: IdRef, payload: IdRef },
-            .OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, slice_type: IdRef, qp: IdRef },
-            .OpSubgroupAvcMceSetInterDirectionPenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, direction_cost: IdRef, payload: IdRef },
-            .OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, slice_type: IdRef, qp: IdRef },
-            .OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL => struct { id_result_type: IdResultType, id_result: IdResult, slice_type: IdRef, qp: IdRef },
-            .OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL => struct { id_result_type: IdResultType, id_result: IdResult },
-            .OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL => struct { id_result_type: IdResultType, id_result: IdResult },
-            .OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL => struct { id_result_type: IdResultType, id_result: IdResult },
-            .OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packed_cost_center_delta: IdRef, packed_cost_table: IdRef, cost_precision: IdRef, payload: IdRef },
-            .OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, slice_type: IdRef, qp: IdRef },
-            .OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult },
-            .OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult },
-            .OpSubgroupAvcMceSetAcOnlyHaarINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL => struct { id_result_type: IdResultType, id_result: IdResult, source_field_polarity: IdRef, payload: IdRef },
-            .OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL => struct { id_result_type: IdResultType, id_result: IdResult, reference_field_polarity: IdRef, payload: IdRef },
-            .OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL => struct { id_result_type: IdResultType, id_result: IdResult, forward_reference_field_polarity: IdRef, backward_reference_field_polarity: IdRef, payload: IdRef },
-            .OpSubgroupAvcMceConvertToImePayloadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceConvertToImeResultINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceConvertToRefPayloadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceConvertToRefResultINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceConvertToSicPayloadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceConvertToSicResultINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetMotionVectorsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetInterDistortionsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetBestInterDistortionsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetInterMajorShapeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetInterMinorShapeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetInterDirectionsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetInterMotionVectorCountINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetInterReferenceIdsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packed_reference_ids: IdRef, packed_reference_parameter_field_polarities: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeInitializeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_coord: IdRef, partition_mask: IdRef, sad_adjustment: IdRef },
-            .OpSubgroupAvcImeSetSingleReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, ref_offset: IdRef, search_window_config: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeSetDualReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, fwd_ref_offset: IdRef, bwd_ref_offset: IdRef, id_ref_4: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeRefWindowSizeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, search_window_config: IdRef, dual_ref: IdRef },
-            .OpSubgroupAvcImeAdjustRefOffsetINTEL => struct { id_result_type: IdResultType, id_result: IdResult, ref_offset: IdRef, src_coord: IdRef, ref_window_size: IdRef, image_size: IdRef },
-            .OpSubgroupAvcImeConvertToMcePayloadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeSetMaxMotionVectorCountINTEL => struct { id_result_type: IdResultType, id_result: IdResult, max_motion_vector_count: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL => struct { id_result_type: IdResultType, id_result: IdResult, threshold: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeSetWeightedSadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packed_sad_weights: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeEvaluateWithDualReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, fwd_ref_image: IdRef, bwd_ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, ref_image: IdRef, payload: IdRef, streamin_components: IdRef },
-            .OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, fwd_ref_image: IdRef, bwd_ref_image: IdRef, payload: IdRef, streamin_components: IdRef },
-            .OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, fwd_ref_image: IdRef, bwd_ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, ref_image: IdRef, payload: IdRef, streamin_components: IdRef },
-            .OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, fwd_ref_image: IdRef, bwd_ref_image: IdRef, payload: IdRef, streamin_components: IdRef },
-            .OpSubgroupAvcImeConvertToMceResultINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeGetSingleReferenceStreaminINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeGetDualReferenceStreaminINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeStripDualReferenceStreamoutINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef, major_shape: IdRef },
-            .OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef, major_shape: IdRef },
-            .OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef, major_shape: IdRef },
-            .OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef, major_shape: IdRef, direction: IdRef },
-            .OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef, major_shape: IdRef, direction: IdRef },
-            .OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef, major_shape: IdRef, direction: IdRef },
-            .OpSubgroupAvcImeGetBorderReachedINTEL => struct { id_result_type: IdResultType, id_result: IdResult, image_select: IdRef, payload: IdRef },
-            .OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcFmeInitializeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_coord: IdRef, motion_vectors: IdRef, major_shapes: IdRef, minor_shapes: IdRef, direction: IdRef, pixel_resolution: IdRef, sad_adjustment: IdRef },
-            .OpSubgroupAvcBmeInitializeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_coord: IdRef, motion_vectors: IdRef, major_shapes: IdRef, minor_shapes: IdRef, direction: IdRef, pixel_resolution: IdRef, bidirectional_weight: IdRef, sad_adjustment: IdRef },
-            .OpSubgroupAvcRefConvertToMcePayloadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcRefSetBidirectionalMixDisableINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcRefSetBilinearFilterEnableINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcRefEvaluateWithDualReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, fwd_ref_image: IdRef, bwd_ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, packed_reference_ids: IdRef, payload: IdRef },
-            .OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, packed_reference_ids: IdRef, packed_reference_field_polarities: IdRef, payload: IdRef },
-            .OpSubgroupAvcRefConvertToMceResultINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicInitializeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_coord: IdRef },
-            .OpSubgroupAvcSicConfigureSkcINTEL => struct { id_result_type: IdResultType, id_result: IdResult, skip_block_partition_type: IdRef, skip_motion_vector_mask: IdRef, motion_vectors: IdRef, bidirectional_weight: IdRef, sad_adjustment: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicConfigureIpeLumaINTEL => struct { id_result_type: IdResultType, id_result: IdResult, luma_intra_partition_mask: IdRef, intra_neighbour_availabilty: IdRef, left_edge_luma_pixels: IdRef, upper_left_corner_luma_pixel: IdRef, upper_edge_luma_pixels: IdRef, upper_right_edge_luma_pixels: IdRef, sad_adjustment: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicConfigureIpeLumaChromaINTEL => struct { id_result_type: IdResultType, id_result: IdResult, luma_intra_partition_mask: IdRef, intra_neighbour_availabilty: IdRef, left_edge_luma_pixels: IdRef, upper_left_corner_luma_pixel: IdRef, upper_edge_luma_pixels: IdRef, upper_right_edge_luma_pixels: IdRef, left_edge_chroma_pixels: IdRef, upper_left_corner_chroma_pixel: IdRef, upper_edge_chroma_pixels: IdRef, sad_adjustment: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicGetMotionVectorMaskINTEL => struct { id_result_type: IdResultType, id_result: IdResult, skip_block_partition_type: IdRef, direction: IdRef },
-            .OpSubgroupAvcSicConvertToMcePayloadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packed_shape_penalty: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL => struct { id_result_type: IdResultType, id_result: IdResult, luma_mode_penalty: IdRef, luma_packed_neighbor_modes: IdRef, luma_packed_non_dc_penalty: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL => struct { id_result_type: IdResultType, id_result: IdResult, chroma_mode_base_penalty: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicSetBilinearFilterEnableINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packed_sad_coefficients: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL => struct { id_result_type: IdResultType, id_result: IdResult, block_based_skip_type: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicEvaluateIpeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicEvaluateWithDualReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, fwd_ref_image: IdRef, bwd_ref_image: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, packed_reference_ids: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL => struct { id_result_type: IdResultType, id_result: IdResult, src_image: IdRef, packed_reference_ids: IdRef, packed_reference_field_polarities: IdRef, payload: IdRef },
-            .OpSubgroupAvcSicConvertToMceResultINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetIpeLumaShapeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetPackedIpeLumaModesINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetIpeChromaModeINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpSubgroupAvcSicGetInterRawSadsINTEL => struct { id_result_type: IdResultType, id_result: IdResult, payload: IdRef },
-            .OpVariableLengthArrayINTEL => struct { id_result_type: IdResultType, id_result: IdResult, lenght: IdRef },
-            .OpSaveMemoryINTEL => struct { id_result_type: IdResultType, id_result: IdResult },
-            .OpRestoreMemoryINTEL => struct { ptr: IdRef },
             .OpLoopControlINTEL => struct { loop_control_parameters: []const LiteralInteger = &.{} },
-            .OpPtrCastToCrossWorkgroupINTEL => struct { id_result_type: IdResultType, id_result: IdResult, pointer: IdRef },
-            .OpCrossWorkgroupCastToPtrINTEL => struct { id_result_type: IdResultType, id_result: IdResult, pointer: IdRef },
             .OpReadPipeBlockingINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packet_size: IdRef, packet_alignment: IdRef },
             .OpWritePipeBlockingINTEL => struct { id_result_type: IdResultType, id_result: IdResult, packet_size: IdRef, packet_alignment: IdRef },
             .OpFPGARegINTEL => struct { id_result_type: IdResultType, id_result: IdResult, result: IdRef, input: IdRef },
@@ -1198,12 +2074,3169 @@ pub const Opcode = enum(u16) {
             .OpRayQueryGetIntersectionObjectToWorldKHR => struct { id_result_type: IdResultType, id_result: IdResult, rayquery: IdRef, intersection: IdRef },
             .OpRayQueryGetIntersectionWorldToObjectKHR => struct { id_result_type: IdResultType, id_result: IdResult, rayquery: IdRef, intersection: IdRef },
             .OpAtomicFAddEXT => struct { id_result_type: IdResultType, id_result: IdResult, pointer: IdRef, memory: IdScope, semantics: IdMemorySemantics, value: IdRef },
-            .OpTypeBufferSurfaceINTEL => struct { id_result: IdResult },
+            .OpTypeBufferSurfaceINTEL => struct { id_result: IdResult, accessqualifier: AccessQualifier },
             .OpTypeStructContinuedINTEL => struct { id_ref: []const IdRef = &.{} },
             .OpConstantCompositeContinuedINTEL => struct { constituents: []const IdRef = &.{} },
             .OpSpecConstantCompositeContinuedINTEL => struct { constituents: []const IdRef = &.{} },
         };
     }
+    pub fn operands(self: Opcode) []const Operand {
+        return switch (self) {
+            .OpNop => &[_]Operand{},
+            .OpUndef => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpSourceContinued => &[_]Operand{
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpSource => &[_]Operand{
+                .{ .kind = .SourceLanguage, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+                .{ .kind = .LiteralString, .quantifier = .optional },
+            },
+            .OpSourceExtension => &[_]Operand{
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpName => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpMemberName => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpString => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpLine => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpExtension => &[_]Operand{
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpExtInstImport => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpExtInst => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralExtInstInteger, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpMemoryModel => &[_]Operand{
+                .{ .kind = .AddressingModel, .quantifier = .required },
+                .{ .kind = .MemoryModel, .quantifier = .required },
+            },
+            .OpEntryPoint => &[_]Operand{
+                .{ .kind = .ExecutionModel, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralString, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpExecutionMode => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ExecutionMode, .quantifier = .required },
+            },
+            .OpCapability => &[_]Operand{
+                .{ .kind = .Capability, .quantifier = .required },
+            },
+            .OpTypeVoid => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpTypeBool => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpTypeInt => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpTypeFloat => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpTypeVector => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpTypeMatrix => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpTypeImage => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .Dim, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .ImageFormat, .quantifier = .required },
+                .{ .kind = .AccessQualifier, .quantifier = .optional },
+            },
+            .OpTypeSampler => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpTypeSampledImage => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeArray => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeRuntimeArray => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeStruct => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpTypeOpaque => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpTypePointer => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .StorageClass, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeFunction => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpTypeEvent => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpTypeDeviceEvent => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpTypeReserveId => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpTypeQueue => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpTypePipe => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .AccessQualifier, .quantifier = .required },
+            },
+            .OpTypeForwardPointer => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .StorageClass, .quantifier = .required },
+            },
+            .OpConstantTrue => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpConstantFalse => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpConstant => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralContextDependentNumber, .quantifier = .required },
+            },
+            .OpConstantComposite => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpConstantSampler => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .SamplerAddressingMode, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .SamplerFilterMode, .quantifier = .required },
+            },
+            .OpConstantNull => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpSpecConstantTrue => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpSpecConstantFalse => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpSpecConstant => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralContextDependentNumber, .quantifier = .required },
+            },
+            .OpSpecConstantComposite => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpSpecConstantOp => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralSpecConstantOpInteger, .quantifier = .required },
+            },
+            .OpFunction => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .FunctionControl, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFunctionParameter => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpFunctionEnd => &[_]Operand{},
+            .OpFunctionCall => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpVariable => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .StorageClass, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpImageTexelPointer => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpLoad => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+            },
+            .OpStore => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+            },
+            .OpCopyMemory => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+            },
+            .OpCopyMemorySized => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+            },
+            .OpAccessChain => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpInBoundsAccessChain => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpPtrAccessChain => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpArrayLength => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpGenericPtrMemSemantics => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpInBoundsPtrAccessChain => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpDecorate => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .Decoration, .quantifier = .required },
+            },
+            .OpMemberDecorate => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .Decoration, .quantifier = .required },
+            },
+            .OpDecorationGroup => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpGroupDecorate => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpGroupMemberDecorate => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PairIdRefLiteralInteger, .quantifier = .variadic },
+            },
+            .OpVectorExtractDynamic => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpVectorInsertDynamic => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpVectorShuffle => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .variadic },
+            },
+            .OpCompositeConstruct => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpCompositeExtract => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .variadic },
+            },
+            .OpCompositeInsert => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .variadic },
+            },
+            .OpCopyObject => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTranspose => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSampledImage => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageSampleImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSampleExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageSampleDrefImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSampleDrefExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageSampleProjImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSampleProjExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageSampleProjDrefImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSampleProjDrefExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageFetch => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageGather => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageDrefGather => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageRead => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageWrite => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImage => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageQueryFormat => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageQueryOrder => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageQuerySizeLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageQuerySize => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageQueryLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageQueryLevels => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageQuerySamples => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertFToU => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertFToS => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertSToF => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertUToF => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUConvert => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSConvert => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFConvert => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpQuantizeToF16 => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertPtrToU => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSatConvertSToU => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSatConvertUToS => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertUToPtr => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpPtrCastToGeneric => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGenericCastToPtr => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGenericCastToPtrExplicit => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .StorageClass, .quantifier = .required },
+            },
+            .OpBitcast => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSNegate => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFNegate => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIAdd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFAdd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpISub => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFSub => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIMul => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFMul => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUDiv => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSDiv => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFDiv => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUMod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSRem => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSMod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFRem => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFMod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpVectorTimesScalar => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpMatrixTimesScalar => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpVectorTimesMatrix => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpMatrixTimesVector => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpMatrixTimesMatrix => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpOuterProduct => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIAddCarry => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpISubBorrow => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUMulExtended => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSMulExtended => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAny => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAll => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIsNan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIsInf => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIsFinite => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIsNormal => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSignBitSet => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpLessOrGreater => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpOrdered => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUnordered => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpLogicalEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpLogicalNotEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpLogicalOr => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpLogicalAnd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpLogicalNot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSelect => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpINotEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUGreaterThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSGreaterThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUGreaterThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSGreaterThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpULessThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSLessThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpULessThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSLessThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFOrdEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFUnordEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFOrdNotEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFUnordNotEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFOrdLessThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFUnordLessThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFOrdGreaterThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFUnordGreaterThan => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFOrdLessThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFUnordLessThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFOrdGreaterThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFUnordGreaterThanEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpShiftRightLogical => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpShiftRightArithmetic => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpShiftLeftLogical => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitwiseOr => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitwiseXor => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitwiseAnd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpNot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitFieldInsert => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitFieldSExtract => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitFieldUExtract => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitReverse => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBitCount => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDPdx => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDPdy => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFwidth => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDPdxFine => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDPdyFine => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFwidthFine => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDPdxCoarse => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDPdyCoarse => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFwidthCoarse => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpEmitVertex => &[_]Operand{},
+            .OpEndPrimitive => &[_]Operand{},
+            .OpEmitStreamVertex => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpEndStreamPrimitive => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpControlBarrier => &[_]Operand{
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpMemoryBarrier => &[_]Operand{
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpAtomicLoad => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpAtomicStore => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicExchange => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicCompareExchange => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicCompareExchangeWeak => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicIIncrement => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpAtomicIDecrement => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpAtomicIAdd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicISub => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicSMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicUMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicSMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicUMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicAnd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicOr => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicXor => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpPhi => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .PairIdRefIdRef, .quantifier = .variadic },
+            },
+            .OpLoopMerge => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LoopControl, .quantifier = .required },
+            },
+            .OpSelectionMerge => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .SelectionControl, .quantifier = .required },
+            },
+            .OpLabel => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpBranch => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBranchConditional => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .variadic },
+            },
+            .OpSwitch => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PairLiteralIntegerIdRef, .quantifier = .variadic },
+            },
+            .OpKill => &[_]Operand{},
+            .OpReturn => &[_]Operand{},
+            .OpReturnValue => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUnreachable => &[_]Operand{},
+            .OpLifetimeStart => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpLifetimeStop => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpGroupAsyncCopy => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupWaitEvents => &[_]Operand{
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupAll => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupAny => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupBroadcast => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupIAdd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupFAdd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupFMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupUMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupSMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupFMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupUMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupSMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReadPipe => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpWritePipe => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReservedReadPipe => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReservedWritePipe => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReserveReadPipePackets => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReserveWritePipePackets => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpCommitReadPipe => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpCommitWritePipe => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIsValidReserveId => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetNumPipePackets => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetMaxPipePackets => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupReserveReadPipePackets => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupReserveWritePipePackets => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupCommitReadPipe => &[_]Operand{
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupCommitWritePipe => &[_]Operand{
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpEnqueueMarker => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpEnqueueKernel => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpGetKernelNDrangeSubGroupCount => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetKernelNDrangeMaxSubGroupSize => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetKernelWorkGroupSize => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetKernelPreferredWorkGroupSizeMultiple => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRetainEvent => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReleaseEvent => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpCreateUserEvent => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpIsValidEvent => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSetUserEventStatus => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpCaptureEventProfilingInfo => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetDefaultQueue => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpBuildNDRange => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpImageSparseSampleImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSparseSampleExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageSparseSampleDrefImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSparseSampleDrefExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageSparseSampleProjImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSparseSampleProjExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageSparseSampleProjDrefImplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSparseSampleProjDrefExplicitLod => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .required },
+            },
+            .OpImageSparseFetch => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSparseGather => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSparseDrefGather => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpImageSparseTexelsResident => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpNoLine => &[_]Operand{},
+            .OpAtomicFlagTestAndSet => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpAtomicFlagClear => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpImageSparseRead => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpSizeOf => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypePipeStorage => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpConstantPipeStorage => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpCreatePipeFromPipeStorage => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetKernelLocalSizeForSubgroupCount => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGetKernelMaxNumSubgroups => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeNamedBarrier => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpNamedBarrierInitialize => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpMemoryNamedBarrier => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+            },
+            .OpModuleProcessed => &[_]Operand{
+                .{ .kind = .LiteralString, .quantifier = .required },
+            },
+            .OpExecutionModeId => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ExecutionMode, .quantifier = .required },
+            },
+            .OpDecorateId => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .Decoration, .quantifier = .required },
+            },
+            .OpGroupNonUniformElect => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+            },
+            .OpGroupNonUniformAll => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformAny => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformAllEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformBroadcast => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformBroadcastFirst => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformBallot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformInverseBallot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformBallotBitExtract => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformBallotBitCount => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformBallotFindLSB => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformBallotFindMSB => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformShuffle => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformShuffleXor => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformShuffleUp => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformShuffleDown => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformIAdd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformFAdd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformIMul => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformFMul => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformSMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformUMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformFMin => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformSMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformUMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformFMax => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformBitwiseAnd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformBitwiseOr => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformBitwiseXor => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformLogicalAnd => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformLogicalOr => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformLogicalXor => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .optional },
+            },
+            .OpGroupNonUniformQuadBroadcast => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupNonUniformQuadSwap => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpCopyLogical => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpPtrEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpPtrNotEqual => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpPtrDiff => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTerminateInvocation => &[_]Operand{},
+            .OpSubgroupBallotKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupFirstInvocationKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupAllKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupAnyKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupAllEqualKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupReadInvocationKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTraceRayKHR => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpExecuteCallableKHR => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertUToAccelerationStructureKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIgnoreIntersectionKHR => &[_]Operand{},
+            .OpTerminateRayKHR => &[_]Operand{},
+            .OpSDot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PackedVectorFormat, .quantifier = .optional },
+            },
+            .OpUDot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PackedVectorFormat, .quantifier = .optional },
+            },
+            .OpSUDot => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PackedVectorFormat, .quantifier = .optional },
+            },
+            .OpSDotAccSat => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PackedVectorFormat, .quantifier = .optional },
+            },
+            .OpUDotAccSat => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PackedVectorFormat, .quantifier = .optional },
+            },
+            .OpSUDotAccSat => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .PackedVectorFormat, .quantifier = .optional },
+            },
+            .OpTypeRayQueryKHR => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpRayQueryInitializeKHR => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryTerminateKHR => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGenerateIntersectionKHR => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryConfirmIntersectionKHR => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryProceedKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionTypeKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupIAddNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupFAddNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupFMinNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupUMinNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupSMinNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupFMaxNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupUMaxNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpGroupSMaxNonUniformAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .GroupOperation, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFragmentMaskFetchAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFragmentFetchAMD => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReadClockKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+            },
+            .OpImageSampleFootprintNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .ImageOperands, .quantifier = .optional },
+            },
+            .OpGroupNonUniformPartitionNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpWritePackedPrimitiveIndices4x8NV => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpReportIntersectionKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIgnoreIntersectionNV => &[_]Operand{},
+            .OpTerminateRayNV => &[_]Operand{},
+            .OpTraceNV => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTraceMotionNV => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTraceRayMotionNV => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeAccelerationStructureKHR => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpExecuteCallableNV => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeCooperativeMatrixNV => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpCooperativeMatrixLoadNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+            },
+            .OpCooperativeMatrixStoreNV => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .MemoryAccess, .quantifier = .optional },
+            },
+            .OpCooperativeMatrixMulAddNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpCooperativeMatrixLengthNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpBeginInvocationInterlockEXT => &[_]Operand{},
+            .OpEndInvocationInterlockEXT => &[_]Operand{},
+            .OpDemoteToHelperInvocation => &[_]Operand{},
+            .OpIsHelperInvocationEXT => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+            },
+            .OpConvertUToImageNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertUToSamplerNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertImageToUNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertSamplerToUNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertUToSampledImageNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpConvertSampledImageToUNV => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSamplerImageAddressingModeNV => &[_]Operand{
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+            },
+            .OpSubgroupShuffleINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupShuffleDownINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupShuffleUpINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupShuffleXorINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupBlockReadINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupBlockWriteINTEL => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupImageBlockReadINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupImageBlockWriteINTEL => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupImageMediaBlockReadINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpSubgroupImageMediaBlockWriteINTEL => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUCountLeadingZerosINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUCountTrailingZerosINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAbsISubINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAbsUSubINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIAddSatINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUAddSatINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIAverageINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUAverageINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIAverageRoundedINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUAverageRoundedINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpISubSatINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUSubSatINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpIMul32x16INTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpUMul32x16INTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicFMinEXT => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicFMaxEXT => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAssumeTrueKHR => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpExpectKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpDecorateString => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .Decoration, .quantifier = .required },
+            },
+            .OpMemberDecorateString => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .LiteralInteger, .quantifier = .required },
+                .{ .kind = .Decoration, .quantifier = .required },
+            },
+            .OpLoopControlINTEL => &[_]Operand{
+                .{ .kind = .LiteralInteger, .quantifier = .variadic },
+            },
+            .OpReadPipeBlockingINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpWritePipeBlockingINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpFPGARegINTEL => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetRayTMinKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetRayFlagsKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionTKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionInstanceCustomIndexKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionInstanceIdKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionGeometryIndexKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionPrimitiveIndexKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionBarycentricsKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionFrontFaceKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionCandidateAABBOpaqueKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionObjectRayDirectionKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionObjectRayOriginKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetWorldRayDirectionKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetWorldRayOriginKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionObjectToWorldKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpRayQueryGetIntersectionWorldToObjectKHR => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpAtomicFAddEXT => &[_]Operand{
+                .{ .kind = .IdResultType, .quantifier = .required },
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+                .{ .kind = .IdScope, .quantifier = .required },
+                .{ .kind = .IdMemorySemantics, .quantifier = .required },
+                .{ .kind = .IdRef, .quantifier = .required },
+            },
+            .OpTypeBufferSurfaceINTEL => &[_]Operand{
+                .{ .kind = .IdResult, .quantifier = .required },
+                .{ .kind = .AccessQualifier, .quantifier = .required },
+            },
+            .OpTypeStructContinuedINTEL => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpConstantCompositeContinuedINTEL => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+            .OpSpecConstantCompositeContinuedINTEL => &[_]Operand{
+                .{ .kind = .IdRef, .quantifier = .variadic },
+            },
+        };
+    }
+    pub fn class(self: Opcode) Class {
+        return switch (self) {
+            .OpNop => .Miscellaneous,
+            .OpUndef => .Miscellaneous,
+            .OpSourceContinued => .Debug,
+            .OpSource => .Debug,
+            .OpSourceExtension => .Debug,
+            .OpName => .Debug,
+            .OpMemberName => .Debug,
+            .OpString => .Debug,
+            .OpLine => .Debug,
+            .OpExtension => .Extension,
+            .OpExtInstImport => .Extension,
+            .OpExtInst => .Extension,
+            .OpMemoryModel => .ModeSetting,
+            .OpEntryPoint => .ModeSetting,
+            .OpExecutionMode => .ModeSetting,
+            .OpCapability => .ModeSetting,
+            .OpTypeVoid => .TypeDeclaration,
+            .OpTypeBool => .TypeDeclaration,
+            .OpTypeInt => .TypeDeclaration,
+            .OpTypeFloat => .TypeDeclaration,
+            .OpTypeVector => .TypeDeclaration,
+            .OpTypeMatrix => .TypeDeclaration,
+            .OpTypeImage => .TypeDeclaration,
+            .OpTypeSampler => .TypeDeclaration,
+            .OpTypeSampledImage => .TypeDeclaration,
+            .OpTypeArray => .TypeDeclaration,
+            .OpTypeRuntimeArray => .TypeDeclaration,
+            .OpTypeStruct => .TypeDeclaration,
+            .OpTypeOpaque => .TypeDeclaration,
+            .OpTypePointer => .TypeDeclaration,
+            .OpTypeFunction => .TypeDeclaration,
+            .OpTypeEvent => .TypeDeclaration,
+            .OpTypeDeviceEvent => .TypeDeclaration,
+            .OpTypeReserveId => .TypeDeclaration,
+            .OpTypeQueue => .TypeDeclaration,
+            .OpTypePipe => .TypeDeclaration,
+            .OpTypeForwardPointer => .TypeDeclaration,
+            .OpConstantTrue => .ConstantCreation,
+            .OpConstantFalse => .ConstantCreation,
+            .OpConstant => .ConstantCreation,
+            .OpConstantComposite => .ConstantCreation,
+            .OpConstantSampler => .ConstantCreation,
+            .OpConstantNull => .ConstantCreation,
+            .OpSpecConstantTrue => .ConstantCreation,
+            .OpSpecConstantFalse => .ConstantCreation,
+            .OpSpecConstant => .ConstantCreation,
+            .OpSpecConstantComposite => .ConstantCreation,
+            .OpSpecConstantOp => .ConstantCreation,
+            .OpFunction => .Function,
+            .OpFunctionParameter => .Function,
+            .OpFunctionEnd => .Function,
+            .OpFunctionCall => .Function,
+            .OpVariable => .Memory,
+            .OpImageTexelPointer => .Memory,
+            .OpLoad => .Memory,
+            .OpStore => .Memory,
+            .OpCopyMemory => .Memory,
+            .OpCopyMemorySized => .Memory,
+            .OpAccessChain => .Memory,
+            .OpInBoundsAccessChain => .Memory,
+            .OpPtrAccessChain => .Memory,
+            .OpArrayLength => .Memory,
+            .OpGenericPtrMemSemantics => .Memory,
+            .OpInBoundsPtrAccessChain => .Memory,
+            .OpDecorate => .Annotation,
+            .OpMemberDecorate => .Annotation,
+            .OpDecorationGroup => .Annotation,
+            .OpGroupDecorate => .Annotation,
+            .OpGroupMemberDecorate => .Annotation,
+            .OpVectorExtractDynamic => .Composite,
+            .OpVectorInsertDynamic => .Composite,
+            .OpVectorShuffle => .Composite,
+            .OpCompositeConstruct => .Composite,
+            .OpCompositeExtract => .Composite,
+            .OpCompositeInsert => .Composite,
+            .OpCopyObject => .Composite,
+            .OpTranspose => .Composite,
+            .OpSampledImage => .Image,
+            .OpImageSampleImplicitLod => .Image,
+            .OpImageSampleExplicitLod => .Image,
+            .OpImageSampleDrefImplicitLod => .Image,
+            .OpImageSampleDrefExplicitLod => .Image,
+            .OpImageSampleProjImplicitLod => .Image,
+            .OpImageSampleProjExplicitLod => .Image,
+            .OpImageSampleProjDrefImplicitLod => .Image,
+            .OpImageSampleProjDrefExplicitLod => .Image,
+            .OpImageFetch => .Image,
+            .OpImageGather => .Image,
+            .OpImageDrefGather => .Image,
+            .OpImageRead => .Image,
+            .OpImageWrite => .Image,
+            .OpImage => .Image,
+            .OpImageQueryFormat => .Image,
+            .OpImageQueryOrder => .Image,
+            .OpImageQuerySizeLod => .Image,
+            .OpImageQuerySize => .Image,
+            .OpImageQueryLod => .Image,
+            .OpImageQueryLevels => .Image,
+            .OpImageQuerySamples => .Image,
+            .OpConvertFToU => .Conversion,
+            .OpConvertFToS => .Conversion,
+            .OpConvertSToF => .Conversion,
+            .OpConvertUToF => .Conversion,
+            .OpUConvert => .Conversion,
+            .OpSConvert => .Conversion,
+            .OpFConvert => .Conversion,
+            .OpQuantizeToF16 => .Conversion,
+            .OpConvertPtrToU => .Conversion,
+            .OpSatConvertSToU => .Conversion,
+            .OpSatConvertUToS => .Conversion,
+            .OpConvertUToPtr => .Conversion,
+            .OpPtrCastToGeneric => .Conversion,
+            .OpGenericCastToPtr => .Conversion,
+            .OpGenericCastToPtrExplicit => .Conversion,
+            .OpBitcast => .Conversion,
+            .OpSNegate => .Arithmetic,
+            .OpFNegate => .Arithmetic,
+            .OpIAdd => .Arithmetic,
+            .OpFAdd => .Arithmetic,
+            .OpISub => .Arithmetic,
+            .OpFSub => .Arithmetic,
+            .OpIMul => .Arithmetic,
+            .OpFMul => .Arithmetic,
+            .OpUDiv => .Arithmetic,
+            .OpSDiv => .Arithmetic,
+            .OpFDiv => .Arithmetic,
+            .OpUMod => .Arithmetic,
+            .OpSRem => .Arithmetic,
+            .OpSMod => .Arithmetic,
+            .OpFRem => .Arithmetic,
+            .OpFMod => .Arithmetic,
+            .OpVectorTimesScalar => .Arithmetic,
+            .OpMatrixTimesScalar => .Arithmetic,
+            .OpVectorTimesMatrix => .Arithmetic,
+            .OpMatrixTimesVector => .Arithmetic,
+            .OpMatrixTimesMatrix => .Arithmetic,
+            .OpOuterProduct => .Arithmetic,
+            .OpDot => .Arithmetic,
+            .OpIAddCarry => .Arithmetic,
+            .OpISubBorrow => .Arithmetic,
+            .OpUMulExtended => .Arithmetic,
+            .OpSMulExtended => .Arithmetic,
+            .OpAny => .RelationalAndLogical,
+            .OpAll => .RelationalAndLogical,
+            .OpIsNan => .RelationalAndLogical,
+            .OpIsInf => .RelationalAndLogical,
+            .OpIsFinite => .RelationalAndLogical,
+            .OpIsNormal => .RelationalAndLogical,
+            .OpSignBitSet => .RelationalAndLogical,
+            .OpLessOrGreater => .RelationalAndLogical,
+            .OpOrdered => .RelationalAndLogical,
+            .OpUnordered => .RelationalAndLogical,
+            .OpLogicalEqual => .RelationalAndLogical,
+            .OpLogicalNotEqual => .RelationalAndLogical,
+            .OpLogicalOr => .RelationalAndLogical,
+            .OpLogicalAnd => .RelationalAndLogical,
+            .OpLogicalNot => .RelationalAndLogical,
+            .OpSelect => .RelationalAndLogical,
+            .OpIEqual => .RelationalAndLogical,
+            .OpINotEqual => .RelationalAndLogical,
+            .OpUGreaterThan => .RelationalAndLogical,
+            .OpSGreaterThan => .RelationalAndLogical,
+            .OpUGreaterThanEqual => .RelationalAndLogical,
+            .OpSGreaterThanEqual => .RelationalAndLogical,
+            .OpULessThan => .RelationalAndLogical,
+            .OpSLessThan => .RelationalAndLogical,
+            .OpULessThanEqual => .RelationalAndLogical,
+            .OpSLessThanEqual => .RelationalAndLogical,
+            .OpFOrdEqual => .RelationalAndLogical,
+            .OpFUnordEqual => .RelationalAndLogical,
+            .OpFOrdNotEqual => .RelationalAndLogical,
+            .OpFUnordNotEqual => .RelationalAndLogical,
+            .OpFOrdLessThan => .RelationalAndLogical,
+            .OpFUnordLessThan => .RelationalAndLogical,
+            .OpFOrdGreaterThan => .RelationalAndLogical,
+            .OpFUnordGreaterThan => .RelationalAndLogical,
+            .OpFOrdLessThanEqual => .RelationalAndLogical,
+            .OpFUnordLessThanEqual => .RelationalAndLogical,
+            .OpFOrdGreaterThanEqual => .RelationalAndLogical,
+            .OpFUnordGreaterThanEqual => .RelationalAndLogical,
+            .OpShiftRightLogical => .Bit,
+            .OpShiftRightArithmetic => .Bit,
+            .OpShiftLeftLogical => .Bit,
+            .OpBitwiseOr => .Bit,
+            .OpBitwiseXor => .Bit,
+            .OpBitwiseAnd => .Bit,
+            .OpNot => .Bit,
+            .OpBitFieldInsert => .Bit,
+            .OpBitFieldSExtract => .Bit,
+            .OpBitFieldUExtract => .Bit,
+            .OpBitReverse => .Bit,
+            .OpBitCount => .Bit,
+            .OpDPdx => .Derivative,
+            .OpDPdy => .Derivative,
+            .OpFwidth => .Derivative,
+            .OpDPdxFine => .Derivative,
+            .OpDPdyFine => .Derivative,
+            .OpFwidthFine => .Derivative,
+            .OpDPdxCoarse => .Derivative,
+            .OpDPdyCoarse => .Derivative,
+            .OpFwidthCoarse => .Derivative,
+            .OpEmitVertex => .Primitive,
+            .OpEndPrimitive => .Primitive,
+            .OpEmitStreamVertex => .Primitive,
+            .OpEndStreamPrimitive => .Primitive,
+            .OpControlBarrier => .Barrier,
+            .OpMemoryBarrier => .Barrier,
+            .OpAtomicLoad => .Atomic,
+            .OpAtomicStore => .Atomic,
+            .OpAtomicExchange => .Atomic,
+            .OpAtomicCompareExchange => .Atomic,
+            .OpAtomicCompareExchangeWeak => .Atomic,
+            .OpAtomicIIncrement => .Atomic,
+            .OpAtomicIDecrement => .Atomic,
+            .OpAtomicIAdd => .Atomic,
+            .OpAtomicISub => .Atomic,
+            .OpAtomicSMin => .Atomic,
+            .OpAtomicUMin => .Atomic,
+            .OpAtomicSMax => .Atomic,
+            .OpAtomicUMax => .Atomic,
+            .OpAtomicAnd => .Atomic,
+            .OpAtomicOr => .Atomic,
+            .OpAtomicXor => .Atomic,
+            .OpPhi => .ControlFlow,
+            .OpLoopMerge => .ControlFlow,
+            .OpSelectionMerge => .ControlFlow,
+            .OpLabel => .ControlFlow,
+            .OpBranch => .ControlFlow,
+            .OpBranchConditional => .ControlFlow,
+            .OpSwitch => .ControlFlow,
+            .OpKill => .ControlFlow,
+            .OpReturn => .ControlFlow,
+            .OpReturnValue => .ControlFlow,
+            .OpUnreachable => .ControlFlow,
+            .OpLifetimeStart => .ControlFlow,
+            .OpLifetimeStop => .ControlFlow,
+            .OpGroupAsyncCopy => .Group,
+            .OpGroupWaitEvents => .Group,
+            .OpGroupAll => .Group,
+            .OpGroupAny => .Group,
+            .OpGroupBroadcast => .Group,
+            .OpGroupIAdd => .Group,
+            .OpGroupFAdd => .Group,
+            .OpGroupFMin => .Group,
+            .OpGroupUMin => .Group,
+            .OpGroupSMin => .Group,
+            .OpGroupFMax => .Group,
+            .OpGroupUMax => .Group,
+            .OpGroupSMax => .Group,
+            .OpReadPipe => .Pipe,
+            .OpWritePipe => .Pipe,
+            .OpReservedReadPipe => .Pipe,
+            .OpReservedWritePipe => .Pipe,
+            .OpReserveReadPipePackets => .Pipe,
+            .OpReserveWritePipePackets => .Pipe,
+            .OpCommitReadPipe => .Pipe,
+            .OpCommitWritePipe => .Pipe,
+            .OpIsValidReserveId => .Pipe,
+            .OpGetNumPipePackets => .Pipe,
+            .OpGetMaxPipePackets => .Pipe,
+            .OpGroupReserveReadPipePackets => .Pipe,
+            .OpGroupReserveWritePipePackets => .Pipe,
+            .OpGroupCommitReadPipe => .Pipe,
+            .OpGroupCommitWritePipe => .Pipe,
+            .OpEnqueueMarker => .DeviceSideEnqueue,
+            .OpEnqueueKernel => .DeviceSideEnqueue,
+            .OpGetKernelNDrangeSubGroupCount => .DeviceSideEnqueue,
+            .OpGetKernelNDrangeMaxSubGroupSize => .DeviceSideEnqueue,
+            .OpGetKernelWorkGroupSize => .DeviceSideEnqueue,
+            .OpGetKernelPreferredWorkGroupSizeMultiple => .DeviceSideEnqueue,
+            .OpRetainEvent => .DeviceSideEnqueue,
+            .OpReleaseEvent => .DeviceSideEnqueue,
+            .OpCreateUserEvent => .DeviceSideEnqueue,
+            .OpIsValidEvent => .DeviceSideEnqueue,
+            .OpSetUserEventStatus => .DeviceSideEnqueue,
+            .OpCaptureEventProfilingInfo => .DeviceSideEnqueue,
+            .OpGetDefaultQueue => .DeviceSideEnqueue,
+            .OpBuildNDRange => .DeviceSideEnqueue,
+            .OpImageSparseSampleImplicitLod => .Image,
+            .OpImageSparseSampleExplicitLod => .Image,
+            .OpImageSparseSampleDrefImplicitLod => .Image,
+            .OpImageSparseSampleDrefExplicitLod => .Image,
+            .OpImageSparseSampleProjImplicitLod => .Image,
+            .OpImageSparseSampleProjExplicitLod => .Image,
+            .OpImageSparseSampleProjDrefImplicitLod => .Image,
+            .OpImageSparseSampleProjDrefExplicitLod => .Image,
+            .OpImageSparseFetch => .Image,
+            .OpImageSparseGather => .Image,
+            .OpImageSparseDrefGather => .Image,
+            .OpImageSparseTexelsResident => .Image,
+            .OpNoLine => .Debug,
+            .OpAtomicFlagTestAndSet => .Atomic,
+            .OpAtomicFlagClear => .Atomic,
+            .OpImageSparseRead => .Image,
+            .OpSizeOf => .Miscellaneous,
+            .OpTypePipeStorage => .TypeDeclaration,
+            .OpConstantPipeStorage => .Pipe,
+            .OpCreatePipeFromPipeStorage => .Pipe,
+            .OpGetKernelLocalSizeForSubgroupCount => .DeviceSideEnqueue,
+            .OpGetKernelMaxNumSubgroups => .DeviceSideEnqueue,
+            .OpTypeNamedBarrier => .TypeDeclaration,
+            .OpNamedBarrierInitialize => .Barrier,
+            .OpMemoryNamedBarrier => .Barrier,
+            .OpModuleProcessed => .Debug,
+            .OpExecutionModeId => .ModeSetting,
+            .OpDecorateId => .Annotation,
+            .OpGroupNonUniformElect => .NonUniform,
+            .OpGroupNonUniformAll => .NonUniform,
+            .OpGroupNonUniformAny => .NonUniform,
+            .OpGroupNonUniformAllEqual => .NonUniform,
+            .OpGroupNonUniformBroadcast => .NonUniform,
+            .OpGroupNonUniformBroadcastFirst => .NonUniform,
+            .OpGroupNonUniformBallot => .NonUniform,
+            .OpGroupNonUniformInverseBallot => .NonUniform,
+            .OpGroupNonUniformBallotBitExtract => .NonUniform,
+            .OpGroupNonUniformBallotBitCount => .NonUniform,
+            .OpGroupNonUniformBallotFindLSB => .NonUniform,
+            .OpGroupNonUniformBallotFindMSB => .NonUniform,
+            .OpGroupNonUniformShuffle => .NonUniform,
+            .OpGroupNonUniformShuffleXor => .NonUniform,
+            .OpGroupNonUniformShuffleUp => .NonUniform,
+            .OpGroupNonUniformShuffleDown => .NonUniform,
+            .OpGroupNonUniformIAdd => .NonUniform,
+            .OpGroupNonUniformFAdd => .NonUniform,
+            .OpGroupNonUniformIMul => .NonUniform,
+            .OpGroupNonUniformFMul => .NonUniform,
+            .OpGroupNonUniformSMin => .NonUniform,
+            .OpGroupNonUniformUMin => .NonUniform,
+            .OpGroupNonUniformFMin => .NonUniform,
+            .OpGroupNonUniformSMax => .NonUniform,
+            .OpGroupNonUniformUMax => .NonUniform,
+            .OpGroupNonUniformFMax => .NonUniform,
+            .OpGroupNonUniformBitwiseAnd => .NonUniform,
+            .OpGroupNonUniformBitwiseOr => .NonUniform,
+            .OpGroupNonUniformBitwiseXor => .NonUniform,
+            .OpGroupNonUniformLogicalAnd => .NonUniform,
+            .OpGroupNonUniformLogicalOr => .NonUniform,
+            .OpGroupNonUniformLogicalXor => .NonUniform,
+            .OpGroupNonUniformQuadBroadcast => .NonUniform,
+            .OpGroupNonUniformQuadSwap => .NonUniform,
+            .OpCopyLogical => .Composite,
+            .OpPtrEqual => .Memory,
+            .OpPtrNotEqual => .Memory,
+            .OpPtrDiff => .Memory,
+            .OpTerminateInvocation => .ControlFlow,
+            .OpSubgroupBallotKHR => .Group,
+            .OpSubgroupFirstInvocationKHR => .Group,
+            .OpSubgroupAllKHR => .Group,
+            .OpSubgroupAnyKHR => .Group,
+            .OpSubgroupAllEqualKHR => .Group,
+            .OpSubgroupReadInvocationKHR => .Group,
+            .OpTraceRayKHR => .Reserved,
+            .OpExecuteCallableKHR => .Reserved,
+            .OpConvertUToAccelerationStructureKHR => .Reserved,
+            .OpIgnoreIntersectionKHR => .Reserved,
+            .OpTerminateRayKHR => .Reserved,
+            .OpSDot => .Arithmetic,
+            .OpUDot => .Arithmetic,
+            .OpSUDot => .Arithmetic,
+            .OpSDotAccSat => .Arithmetic,
+            .OpUDotAccSat => .Arithmetic,
+            .OpSUDotAccSat => .Arithmetic,
+            .OpTypeRayQueryKHR => .Reserved,
+            .OpRayQueryInitializeKHR => .Reserved,
+            .OpRayQueryTerminateKHR => .Reserved,
+            .OpRayQueryGenerateIntersectionKHR => .Reserved,
+            .OpRayQueryConfirmIntersectionKHR => .Reserved,
+            .OpRayQueryProceedKHR => .Reserved,
+            .OpRayQueryGetIntersectionTypeKHR => .Reserved,
+            .OpGroupIAddNonUniformAMD => .Group,
+            .OpGroupFAddNonUniformAMD => .Group,
+            .OpGroupFMinNonUniformAMD => .Group,
+            .OpGroupUMinNonUniformAMD => .Group,
+            .OpGroupSMinNonUniformAMD => .Group,
+            .OpGroupFMaxNonUniformAMD => .Group,
+            .OpGroupUMaxNonUniformAMD => .Group,
+            .OpGroupSMaxNonUniformAMD => .Group,
+            .OpFragmentMaskFetchAMD => .Reserved,
+            .OpFragmentFetchAMD => .Reserved,
+            .OpReadClockKHR => .Reserved,
+            .OpImageSampleFootprintNV => .Image,
+            .OpGroupNonUniformPartitionNV => .NonUniform,
+            .OpWritePackedPrimitiveIndices4x8NV => .Reserved,
+            .OpReportIntersectionKHR => .Reserved,
+            .OpIgnoreIntersectionNV => .Reserved,
+            .OpTerminateRayNV => .Reserved,
+            .OpTraceNV => .Reserved,
+            .OpTraceMotionNV => .Reserved,
+            .OpTraceRayMotionNV => .Reserved,
+            .OpTypeAccelerationStructureKHR => .Reserved,
+            .OpExecuteCallableNV => .Reserved,
+            .OpTypeCooperativeMatrixNV => .Reserved,
+            .OpCooperativeMatrixLoadNV => .Reserved,
+            .OpCooperativeMatrixStoreNV => .Reserved,
+            .OpCooperativeMatrixMulAddNV => .Reserved,
+            .OpCooperativeMatrixLengthNV => .Reserved,
+            .OpBeginInvocationInterlockEXT => .Reserved,
+            .OpEndInvocationInterlockEXT => .Reserved,
+            .OpDemoteToHelperInvocation => .ControlFlow,
+            .OpIsHelperInvocationEXT => .Reserved,
+            .OpConvertUToImageNV => .Reserved,
+            .OpConvertUToSamplerNV => .Reserved,
+            .OpConvertImageToUNV => .Reserved,
+            .OpConvertSamplerToUNV => .Reserved,
+            .OpConvertUToSampledImageNV => .Reserved,
+            .OpConvertSampledImageToUNV => .Reserved,
+            .OpSamplerImageAddressingModeNV => .Reserved,
+            .OpSubgroupShuffleINTEL => .Group,
+            .OpSubgroupShuffleDownINTEL => .Group,
+            .OpSubgroupShuffleUpINTEL => .Group,
+            .OpSubgroupShuffleXorINTEL => .Group,
+            .OpSubgroupBlockReadINTEL => .Group,
+            .OpSubgroupBlockWriteINTEL => .Group,
+            .OpSubgroupImageBlockReadINTEL => .Group,
+            .OpSubgroupImageBlockWriteINTEL => .Group,
+            .OpSubgroupImageMediaBlockReadINTEL => .Group,
+            .OpSubgroupImageMediaBlockWriteINTEL => .Group,
+            .OpUCountLeadingZerosINTEL => .Reserved,
+            .OpUCountTrailingZerosINTEL => .Reserved,
+            .OpAbsISubINTEL => .Reserved,
+            .OpAbsUSubINTEL => .Reserved,
+            .OpIAddSatINTEL => .Reserved,
+            .OpUAddSatINTEL => .Reserved,
+            .OpIAverageINTEL => .Reserved,
+            .OpUAverageINTEL => .Reserved,
+            .OpIAverageRoundedINTEL => .Reserved,
+            .OpUAverageRoundedINTEL => .Reserved,
+            .OpISubSatINTEL => .Reserved,
+            .OpUSubSatINTEL => .Reserved,
+            .OpIMul32x16INTEL => .Reserved,
+            .OpUMul32x16INTEL => .Reserved,
+            .OpAtomicFMinEXT => .Atomic,
+            .OpAtomicFMaxEXT => .Atomic,
+            .OpAssumeTrueKHR => .Miscellaneous,
+            .OpExpectKHR => .Miscellaneous,
+            .OpDecorateString => .Annotation,
+            .OpMemberDecorateString => .Annotation,
+            .OpLoopControlINTEL => .Reserved,
+            .OpReadPipeBlockingINTEL => .Pipe,
+            .OpWritePipeBlockingINTEL => .Pipe,
+            .OpFPGARegINTEL => .Reserved,
+            .OpRayQueryGetRayTMinKHR => .Reserved,
+            .OpRayQueryGetRayFlagsKHR => .Reserved,
+            .OpRayQueryGetIntersectionTKHR => .Reserved,
+            .OpRayQueryGetIntersectionInstanceCustomIndexKHR => .Reserved,
+            .OpRayQueryGetIntersectionInstanceIdKHR => .Reserved,
+            .OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR => .Reserved,
+            .OpRayQueryGetIntersectionGeometryIndexKHR => .Reserved,
+            .OpRayQueryGetIntersectionPrimitiveIndexKHR => .Reserved,
+            .OpRayQueryGetIntersectionBarycentricsKHR => .Reserved,
+            .OpRayQueryGetIntersectionFrontFaceKHR => .Reserved,
+            .OpRayQueryGetIntersectionCandidateAABBOpaqueKHR => .Reserved,
+            .OpRayQueryGetIntersectionObjectRayDirectionKHR => .Reserved,
+            .OpRayQueryGetIntersectionObjectRayOriginKHR => .Reserved,
+            .OpRayQueryGetWorldRayDirectionKHR => .Reserved,
+            .OpRayQueryGetWorldRayOriginKHR => .Reserved,
+            .OpRayQueryGetIntersectionObjectToWorldKHR => .Reserved,
+            .OpRayQueryGetIntersectionWorldToObjectKHR => .Reserved,
+            .OpAtomicFAddEXT => .Atomic,
+            .OpTypeBufferSurfaceINTEL => .TypeDeclaration,
+            .OpTypeStructContinuedINTEL => .TypeDeclaration,
+            .OpConstantCompositeContinuedINTEL => .ConstantCreation,
+            .OpSpecConstantCompositeContinuedINTEL => .ConstantCreation,
+        };
+    }
 };
 pub const ImageOperands = packed struct {
     Bias: bool = false,
@@ -1220,9 +5253,9 @@ pub const ImageOperands = packed struct {
     VolatileTexel: bool = false,
     SignExtend: bool = false,
     ZeroExtend: bool = false,
-    _reserved_bit_14: bool = false,
+    Nontemporal: bool = false,
     _reserved_bit_15: bool = false,
-    _reserved_bit_16: bool = false,
+    Offsets: bool = false,
     _reserved_bit_17: bool = false,
     _reserved_bit_18: bool = false,
     _reserved_bit_19: bool = false,
@@ -1259,9 +5292,9 @@ pub const ImageOperands = packed struct {
         VolatileTexel: bool = false,
         SignExtend: bool = false,
         ZeroExtend: bool = false,
-        _reserved_bit_14: bool = false,
+        Nontemporal: bool = false,
         _reserved_bit_15: bool = false,
-        _reserved_bit_16: bool = false,
+        Offsets: ?struct { id_ref: IdRef } = null,
         _reserved_bit_17: bool = false,
         _reserved_bit_18: bool = false,
         _reserved_bit_19: bool = false,
@@ -1433,7 +5466,7 @@ pub const FunctionControl = packed struct {
     _reserved_bit_13: bool = false,
     _reserved_bit_14: bool = false,
     _reserved_bit_15: bool = false,
-    _reserved_bit_16: bool = false,
+    OptNoneINTEL: bool = false,
     _reserved_bit_17: bool = false,
     _reserved_bit_18: bool = false,
     _reserved_bit_19: bool = false,
@@ -1670,6 +5703,7 @@ pub const SourceLanguage = enum(u32) {
     OpenCL_C = 3,
     OpenCL_CPP = 4,
     HLSL = 5,
+    CPP_for_OpenCL = 6,
 };
 pub const ExecutionModel = enum(u32) {
     Vertex = 0,
@@ -1750,6 +5784,7 @@ pub const ExecutionMode = enum(u32) {
     SubgroupsPerWorkgroupId = 37,
     LocalSizeId = 38,
     LocalSizeHintId = 39,
+    SubgroupUniformControlFlowKHR = 4421,
     PostDepthCoverage = 4446,
     DenormPreserve = 4459,
     DenormFlushToZero = 4460,
@@ -1817,7 +5852,8 @@ pub const ExecutionMode = enum(u32) {
         SubgroupsPerWorkgroup: struct { subgroups_per_workgroup: LiteralInteger },
         SubgroupsPerWorkgroupId: struct { subgroups_per_workgroup: IdRef },
         LocalSizeId: struct { x_size: IdRef, y_size: IdRef, z_size: IdRef },
-        LocalSizeHintId: struct { local_size_hint: IdRef },
+        LocalSizeHintId: struct { x_size_hint: IdRef, y_size_hint: IdRef, z_size_hint: IdRef },
+        SubgroupUniformControlFlowKHR,
         PostDepthCoverage,
         DenormPreserve: struct { target_width: LiteralInteger },
         DenormFlushToZero: struct { target_width: LiteralInteger },
@@ -1996,10 +6032,26 @@ pub const FPDenormMode = enum(u32) {
     Preserve = 0,
     FlushToZero = 1,
 };
+pub const QuantizationModes = enum(u32) {
+    TRN = 0,
+    TRN_ZERO = 1,
+    RND = 2,
+    RND_ZERO = 3,
+    RND_INF = 4,
+    RND_MIN_INF = 5,
+    RND_CONV = 6,
+    RND_CONV_ODD = 7,
+};
 pub const FPOperationMode = enum(u32) {
     IEEE = 0,
     ALT = 1,
 };
+pub const OverflowModes = enum(u32) {
+    WRAP = 0,
+    SAT = 1,
+    SAT_ZERO = 2,
+    SAT_SYM = 3,
+};
 pub const LinkageType = enum(u32) {
     Export = 0,
     Import = 1,
@@ -2078,10 +6130,14 @@ pub const Decoration = enum(u32) {
     PerPrimitiveNV = 5271,
     PerViewNV = 5272,
     PerTaskNV = 5273,
-    PerVertexNV = 5285,
+    PerVertexKHR = 5285,
     NonUniform = 5300,
     RestrictPointer = 5355,
     AliasedPointer = 5356,
+    BindlessSamplerNV = 5398,
+    BindlessImageNV = 5399,
+    BoundSamplerNV = 5400,
+    BoundImageNV = 5401,
     SIMTCallINTEL = 5599,
     ReferencedIndirectlyINTEL = 5602,
     ClobberINTEL = 5607,
@@ -2119,7 +6175,9 @@ pub const Decoration = enum(u32) {
     FunctionFloatingPointModeINTEL = 6080,
     SingleElementVectorINTEL = 6085,
     VectorComputeCallableFunctionINTEL = 6087,
+    MediaBlockIOINTEL = 6140,
 
+    pub const PerVertexNV = Decoration.PerVertexKHR;
     pub const NonUniformEXT = Decoration.NonUniform;
     pub const RestrictPointerEXT = Decoration.RestrictPointer;
     pub const AliasedPointerEXT = Decoration.AliasedPointer;
@@ -2184,10 +6242,14 @@ pub const Decoration = enum(u32) {
         PerPrimitiveNV,
         PerViewNV,
         PerTaskNV,
-        PerVertexNV,
+        PerVertexKHR,
         NonUniform,
         RestrictPointer,
         AliasedPointer,
+        BindlessSamplerNV,
+        BindlessImageNV,
+        BoundSamplerNV,
+        BoundImageNV,
         SIMTCallINTEL: struct { n: LiteralInteger },
         ReferencedIndirectlyINTEL,
         ClobberINTEL: struct { register: LiteralString },
@@ -2225,6 +6287,7 @@ pub const Decoration = enum(u32) {
         FunctionFloatingPointModeINTEL: struct { target_width: LiteralInteger, fp_operation_mode: FPOperationMode },
         SingleElementVectorINTEL,
         VectorComputeCallableFunctionINTEL,
+        MediaBlockIOINTEL,
     };
 };
 pub const BuiltIn = enum(u32) {
@@ -2303,8 +6366,8 @@ pub const BuiltIn = enum(u32) {
     LayerPerViewNV = 5279,
     MeshViewCountNV = 5280,
     MeshViewIndicesNV = 5281,
-    BaryCoordNV = 5286,
-    BaryCoordNoPerspNV = 5287,
+    BaryCoordKHR = 5286,
+    BaryCoordNoPerspKHR = 5287,
     FragSizeEXT = 5292,
     FragInvocationCountEXT = 5293,
     LaunchIdKHR = 5319,
@@ -2320,6 +6383,7 @@ pub const BuiltIn = enum(u32) {
     WorldToObjectKHR = 5331,
     HitTNV = 5332,
     HitKindKHR = 5333,
+    CurrentRayTimeNV = 5334,
     IncomingRayFlagsKHR = 5351,
     RayGeometryIndexKHR = 5352,
     WarpsPerSMNV = 5374,
@@ -2332,6 +6396,8 @@ pub const BuiltIn = enum(u32) {
     pub const SubgroupGtMaskKHR = BuiltIn.SubgroupGtMask;
     pub const SubgroupLeMaskKHR = BuiltIn.SubgroupLeMask;
     pub const SubgroupLtMaskKHR = BuiltIn.SubgroupLtMask;
+    pub const BaryCoordNV = BuiltIn.BaryCoordKHR;
+    pub const BaryCoordNoPerspNV = BuiltIn.BaryCoordNoPerspKHR;
     pub const FragmentSizeNV = BuiltIn.FragSizeEXT;
     pub const InvocationsPerPixelNV = BuiltIn.FragInvocationCountEXT;
     pub const LaunchIdNV = BuiltIn.LaunchIdKHR;
@@ -2443,6 +6509,7 @@ pub const Capability = enum(u32) {
     GroupNonUniformQuad = 68,
     ShaderLayer = 69,
     ShaderViewportIndex = 70,
+    UniformDecoration = 71,
     FragmentShadingRateKHR = 4422,
     SubgroupBallotKHR = 4423,
     DrawParameters = 4427,
@@ -2488,7 +6555,7 @@ pub const Capability = enum(u32) {
     FragmentFullyCoveredEXT = 5265,
     MeshShadingNV = 5266,
     ImageFootprintNV = 5282,
-    FragmentBarycentricNV = 5284,
+    FragmentBarycentricKHR = 5284,
     ComputeDerivativeGroupQuadsNV = 5288,
     FragmentDensityEXT = 5291,
     GroupNonUniformPartitionedNV = 5297,
@@ -2505,6 +6572,7 @@ pub const Capability = enum(u32) {
     UniformTexelBufferArrayNonUniformIndexing = 5311,
     StorageTexelBufferArrayNonUniformIndexing = 5312,
     RayTracingNV = 5340,
+    RayTracingMotionBlurNV = 5341,
     VulkanMemoryModel = 5345,
     VulkanMemoryModelDeviceScope = 5346,
     PhysicalStorageBufferAddresses = 5347,
@@ -2515,7 +6583,8 @@ pub const Capability = enum(u32) {
     FragmentShaderShadingRateInterlockEXT = 5372,
     ShaderSMBuiltinsNV = 5373,
     FragmentShaderPixelInterlockEXT = 5378,
-    DemoteToHelperInvocationEXT = 5379,
+    DemoteToHelperInvocation = 5379,
+    BindlessTextureNV = 5390,
     SubgroupShuffleINTEL = 5568,
     SubgroupBufferBlockIOINTEL = 5569,
     SubgroupImageBlockIOINTEL = 5570,
@@ -2540,6 +6609,7 @@ pub const Capability = enum(u32) {
     FPGAMemoryAttributesINTEL = 5824,
     FPFastMathModeINTEL = 5837,
     ArbitraryPrecisionIntegersINTEL = 5844,
+    ArbitraryPrecisionFloatingPointINTEL = 5845,
     UnstructuredLoopControlsINTEL = 5886,
     FPGALoopControlsINTEL = 5888,
     KernelAttributesINTEL = 5892,
@@ -2548,17 +6618,27 @@ pub const Capability = enum(u32) {
     FPGAClusterAttributesINTEL = 5904,
     LoopFuseINTEL = 5906,
     FPGABufferLocationINTEL = 5920,
+    ArbitraryPrecisionFixedPointINTEL = 5922,
     USMStorageClassesINTEL = 5935,
     IOPipesINTEL = 5943,
     BlockingPipesINTEL = 5945,
     FPGARegINTEL = 5948,
+    DotProductInputAll = 6016,
+    DotProductInput4x8Bit = 6017,
+    DotProductInput4x8BitPacked = 6018,
+    DotProduct = 6019,
+    BitInstructions = 6025,
     AtomicFloat32AddEXT = 6033,
     AtomicFloat64AddEXT = 6034,
     LongConstantCompositeINTEL = 6089,
+    OptNoneINTEL = 6094,
+    AtomicFloat16AddEXT = 6095,
+    DebugInfoModuleINTEL = 6114,
 
     pub const StorageUniformBufferBlock16 = Capability.StorageBuffer16BitAccess;
     pub const StorageUniform16 = Capability.UniformAndStorageBuffer16BitAccess;
     pub const ShaderViewportIndexLayerNV = Capability.ShaderViewportIndexLayerEXT;
+    pub const FragmentBarycentricNV = Capability.FragmentBarycentricKHR;
     pub const ShadingRateNV = Capability.FragmentDensityEXT;
     pub const ShaderNonUniformEXT = Capability.ShaderNonUniform;
     pub const RuntimeDescriptorArrayEXT = Capability.RuntimeDescriptorArray;
@@ -2575,6 +6655,11 @@ pub const Capability = enum(u32) {
     pub const VulkanMemoryModelKHR = Capability.VulkanMemoryModel;
     pub const VulkanMemoryModelDeviceScopeKHR = Capability.VulkanMemoryModelDeviceScope;
     pub const PhysicalStorageBufferAddressesEXT = Capability.PhysicalStorageBufferAddresses;
+    pub const DemoteToHelperInvocationEXT = Capability.DemoteToHelperInvocation;
+    pub const DotProductInputAllKHR = Capability.DotProductInputAll;
+    pub const DotProductInput4x8BitKHR = Capability.DotProductInput4x8Bit;
+    pub const DotProductInput4x8BitPackedKHR = Capability.DotProductInput4x8BitPacked;
+    pub const DotProductKHR = Capability.DotProduct;
 };
 pub const RayQueryIntersection = enum(u32) {
     RayQueryCandidateIntersectionKHR = 0,
@@ -2589,3 +6674,8 @@ pub const RayQueryCandidateIntersectionType = enum(u32) {
     RayQueryCandidateIntersectionTriangleKHR = 0,
     RayQueryCandidateIntersectionAABBKHR = 1,
 };
+pub const PackedVectorFormat = enum(u32) {
+    PackedVectorFormat4x8Bit = 0,
+
+    pub const PackedVectorFormat4x8BitKHR = PackedVectorFormat.PackedVectorFormat4x8Bit;
+};
src/codegen/spirv.zig
@@ -10,6 +10,7 @@ const Type = @import("../type.zig").Type;
 const Value = @import("../value.zig").Value;
 const LazySrcLoc = Module.LazySrcLoc;
 const Air = @import("../Air.zig");
+const Zir = @import("../Zir.zig");
 const Liveness = @import("../Liveness.zig");
 
 const spec = @import("spirv/spec.zig");
@@ -22,6 +23,7 @@ const IdResultType = spec.IdResultType;
 const SpvModule = @import("spirv/Module.zig");
 const SpvSection = @import("spirv/Section.zig");
 const SpvType = @import("spirv/type.zig").Type;
+const SpvAssembler = @import("spirv/Assembler.zig");
 
 const InstMap = std.AutoHashMapUnmanaged(Air.Inst.Index, IdRef);
 
@@ -37,10 +39,13 @@ pub const BlockMap = std.AutoHashMapUnmanaged(Air.Inst.Index, struct {
 
 /// This structure is used to compile a declaration, and contains all relevant meta-information to deal with that.
 pub const DeclGen = struct {
+    /// A general-purpose allocator that can be used for any allocations for this DeclGen.
+    gpa: Allocator,
+
     /// The Zig module that we are generating decls for.
     module: *Module,
 
-    /// The SPIR-V module code should be put in.
+    /// The SPIR-V module that instructions should be emitted into.
     spv: *SpvModule,
 
     /// The decl we are currently generating code for.
@@ -71,18 +76,14 @@ pub const DeclGen = struct {
     /// The label of the SPIR-V block we are currently generating.
     current_block_label_id: IdRef,
 
-    /// The actual instructions for this function. We need to declare all locals in
-    /// the first block, and because we don't know which locals there are going to be,
-    /// we're just going to generate everything after the locals-section in this array.
-    /// Note: It will not contain OpFunction, OpFunctionParameter, OpVariable and the
-    /// initial OpLabel. These will be generated into spv.sections.functions directly.
-    code: SpvSection = .{},
+    /// The code (prologue and body) for the function we are currently generating code for.
+    func: SpvModule.Fn = .{},
 
     /// If `gen` returned `Error.CodegenFail`, this contains an explanatory message.
     /// Memory is owned by `module.gpa`.
     error_msg: ?*Module.ErrorMsg,
 
-    /// Possible errors the `gen` function may return.
+    /// Possible errors the `genDecl` function may return.
     const Error = error{ CodegenFail, OutOfMemory };
 
     /// This structure is used to return information about a type typically used for
@@ -132,8 +133,9 @@ pub const DeclGen = struct {
 
     /// Initialize the common resources of a DeclGen. Some fields are left uninitialized,
     /// only set when `gen` is called.
-    pub fn init(module: *Module, spv: *SpvModule) DeclGen {
+    pub fn init(allocator: Allocator, module: *Module, spv: *SpvModule) DeclGen {
         return .{
+            .gpa = allocator,
             .module = module,
             .spv = spv,
             .decl = undefined,
@@ -158,12 +160,19 @@ pub const DeclGen = struct {
         self.inst_results.clearRetainingCapacity();
         self.blocks.clearRetainingCapacity();
         self.current_block_label_id = undefined;
-        self.code.reset();
+        self.func.reset();
         self.error_msg = null;
 
         self.genDecl() catch |err| switch (err) {
             error.CodegenFail => return self.error_msg,
-            else => |others| return others,
+            else => |others| {
+                // There might be an error that happened *after* self.error_msg
+                // was already allocated, so be sure to free it.
+                if (self.error_msg) |error_msg| {
+                    error_msg.deinit(self.module.gpa);
+                }
+                return others;
+            },
         };
 
         return null;
@@ -171,18 +180,18 @@ pub const DeclGen = struct {
 
     /// Free resources owned by the DeclGen.
     pub fn deinit(self: *DeclGen) void {
-        self.args.deinit(self.spv.gpa);
-        self.inst_results.deinit(self.spv.gpa);
-        self.blocks.deinit(self.spv.gpa);
-        self.code.deinit(self.spv.gpa);
+        self.args.deinit(self.gpa);
+        self.inst_results.deinit(self.gpa);
+        self.blocks.deinit(self.gpa);
+        self.func.deinit(self.gpa);
     }
 
     /// Return the target which we are currently compiling for.
-    fn getTarget(self: *DeclGen) std.Target {
+    pub fn getTarget(self: *DeclGen) std.Target {
         return self.module.getTarget();
     }
 
-    fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
+    pub fn fail(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
         @setCold(true);
         const src = LazySrcLoc.nodeOffset(0);
         const src_loc = src.toSrcLoc(self.decl);
@@ -191,13 +200,8 @@ pub const DeclGen = struct {
         return error.CodegenFail;
     }
 
-    fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
-        @setCold(true);
-        const src = LazySrcLoc.nodeOffset(0);
-        const src_loc = src.toSrcLoc(self.decl);
-        assert(self.error_msg == null);
-        self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "TODO (SPIR-V): " ++ format, args);
-        return error.CodegenFail;
+    pub fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) Error {
+        return self.fail("TODO (SPIR-V): " ++ format, args);
     }
 
     /// Fetch the result-id for a previously generated instruction or constant.
@@ -214,7 +218,7 @@ pub const DeclGen = struct {
     /// Note that there is no such thing as nested blocks like in ZIR or AIR, so we don't need to
     /// keep track of the previous block.
     fn beginSpvBlock(self: *DeclGen, label_id: IdResult) !void {
-        try self.code.emit(self.spv.gpa, .OpLabel, .{ .id_result = label_id });
+        try self.func.body.emit(self.spv.gpa, .OpLabel, .{ .id_result = label_id });
         self.current_block_label_id = label_id.toRef();
     }
 
@@ -320,6 +324,17 @@ pub const DeclGen = struct {
     /// Generate a constant representing `val`.
     /// TODO: Deduplication?
     fn genConstant(self: *DeclGen, ty: Type, val: Value) Error!IdRef {
+        if (ty.zigTypeTag() == .Fn) {
+             const fn_decl_index = switch (val.tag()) {
+                 .extern_fn => val.castTag(.extern_fn).?.data.owner_decl,
+                 .function => val.castTag(.function).?.data.owner_decl,
+                 else => unreachable,
+             };
+             const decl = self.module.declPtr(fn_decl_index);
+             self.module.markDeclAlive(decl);
+             return decl.fn_link.spirv.id.toRef();
+        }
+
         const target = self.getTarget();
         const section = &self.spv.sections.types_globals_constants;
         const result_id = self.spv.allocId();
@@ -387,7 +402,27 @@ pub const DeclGen = struct {
                     .value = value,
                 });
             },
+            .Vector => switch (val.tag()) {
+                .aggregate => {
+                    const elem_vals = val.castTag(.aggregate).?.data;
+                    const vector_len = @intCast(usize, ty.vectorLen());
+                    const elem_ty = ty.elemType();
+
+                    const elem_refs = try self.gpa.alloc(IdRef, vector_len);
+                    defer self.gpa.free(elem_refs);
+                    for (elem_refs) |*elem, i| {
+                        elem.* = try self.genConstant(elem_ty, elem_vals[i]);
+                    }
+                    try section.emit(self.spv.gpa, .OpConstantComposite, .{
+                        .id_result_type = result_type_id,
+                        .id_result = result_id,
+                        .constituents = elem_refs,
+                    });
+                },
+                else => unreachable, // TODO
+            },
             .Void => unreachable,
+            .Fn => unreachable,
             else => return self.todo("constant generation of type {}", .{ty.fmtDebug()}),
         }
 
@@ -396,7 +431,8 @@ pub const DeclGen = struct {
 
     /// Turn a Zig type into a SPIR-V Type, and return its type result-id.
     fn resolveTypeId(self: *DeclGen, ty: Type) !IdResultType {
-        return self.spv.typeResultId(try self.resolveType(ty));
+        const type_ref = try self.resolveType(ty);
+        return self.spv.typeResultId(type_ref);
     }
 
     /// Turn a Zig type into a SPIR-V Type, and return a reference to it.
@@ -447,8 +483,8 @@ pub const DeclGen = struct {
                 break :blk try self.spv.resolveType(SpvType.initPayload(&payload.base));
             },
             .Fn => blk: {
-                // We only support zig-calling-convention functions, no varargs.
-                if (ty.fnCallingConvention() != .Unspecified)
+                // We only support C-calling-convention functions for now, no varargs.
+                if (ty.fnCallingConvention() != .C)
                     return self.fail("Unsupported calling convention for SPIR-V", .{});
                 if (ty.fnIsVarArgs())
                     return self.fail("VarArgs functions are unsupported for SPIR-V", .{});
@@ -464,11 +500,19 @@ pub const DeclGen = struct {
                 payload.* = .{ .return_type = return_type, .parameters = param_types };
                 break :blk try self.spv.resolveType(SpvType.initPayload(&payload.base));
             },
-            .Pointer => {
-                // This type can now be properly implemented, but we still need to implement the storage classes as proper address spaces.
-                return self.todo("Implement type Pointer properly", .{});
+            .Pointer => blk: {
+                const payload = try self.spv.arena.create(SpvType.Payload.Pointer);
+                payload.* = .{
+                    .storage_class = spirvStorageClass(ty.ptrAddressSpace()),
+                    .child_type = try self.resolveType(ty.elemType()),
+                    .array_stride = 0,
+                    // Note: only available in Kernels!
+                    .alignment = null,
+                    .max_byte_offset = null,
+                };
+                break :blk try self.spv.resolveType(SpvType.initPayload(&payload.base));
             },
-            .Vector => {
+            .Vector => blk: {
                 // Although not 100% the same, Zig vectors map quite neatly to SPIR-V vectors (including many integer and float operations
                 // which work on them), so simply use those.
                 // Note: SPIR-V vectors only support bools, ints and floats, so pointer vectors need to be supported another way.
@@ -476,8 +520,14 @@ pub const DeclGen = struct {
                 // TODO: The SPIR-V spec mentions that vector sizes may be quite restricted! look into which we can use, and whether OpTypeVector
                 // is adequate at all for this.
 
-                // TODO: Vectors are not yet supported by the self-hosted compiler itself it seems.
-                return self.todo("Implement type Vector", .{});
+                // TODO: Properly verify sizes and child type.
+
+                const payload = try self.spv.arena.create(SpvType.Payload.Vector);
+                payload.* = .{
+                    .component_type = try self.resolveType(ty.elemType()),
+                    .component_count = @intCast(u32, ty.vectorLen()),
+                };
+                break :blk try self.spv.resolveType(SpvType.initPayload(&payload.base));
             },
 
             .Null,
@@ -494,25 +544,14 @@ pub const DeclGen = struct {
         };
     }
 
-    /// SPIR-V requires pointers to have a storage class (address space), and so we have a special function for that.
-    /// TODO: The result of this needs to be cached.
-    fn genPointerType(self: *DeclGen, ty: Type, storage_class: spec.StorageClass) !IdResultType {
-        assert(ty.zigTypeTag() == .Pointer);
-
-        const result_id = self.spv.allocId();
-
-        // TODO: There are many constraints which are ignored for now: We may only create pointers to certain types, and to other types
-        // if more capabilities are enabled. For example, we may only create pointers to f16 if Float16Buffer is enabled.
-        // These also relates to the pointer's address space.
-        const child_id = try self.resolveTypeId(ty.elemType());
-
-        try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpTypePointer, .{
-            .id_result = result_id,
-            .storage_class = storage_class,
-            .type = child_id.toRef(),
-        });
-
-        return result_id.toResultType();
+    fn spirvStorageClass(as: std.builtin.AddressSpace) spec.StorageClass {
+        return switch (as) {
+            .generic => .Generic, // TODO: Disallow?
+            .gs, .fs, .ss => unreachable,
+            .shared => .Workgroup,
+            .local => .Private,
+            .global, .param, .constant => unreachable,
+        };
     }
 
     fn genDecl(self: *DeclGen) !void {
@@ -522,7 +561,7 @@ pub const DeclGen = struct {
         if (decl.val.castTag(.function)) |_| {
             assert(decl.ty.zigTypeTag() == .Fn);
             const prototype_id = try self.resolveTypeId(decl.ty);
-            try self.spv.sections.functions.emit(self.spv.gpa, .OpFunction, .{
+            try self.func.prologue.emit(self.spv.gpa, .OpFunction, .{
                 .id_result_type = try self.resolveTypeId(decl.ty.fnReturnType()),
                 .id_result = result_id,
                 .function_control = .{}, // TODO: We can set inline here if the type requires it.
@@ -532,11 +571,11 @@ pub const DeclGen = struct {
             const params = decl.ty.fnParamLen();
             var i: usize = 0;
 
-            try self.args.ensureUnusedCapacity(self.spv.gpa, params);
+            try self.args.ensureUnusedCapacity(self.gpa, params);
             while (i < params) : (i += 1) {
                 const param_type_id = try self.resolveTypeId(decl.ty.fnParamType(i));
                 const arg_result_id = self.spv.allocId();
-                try self.spv.sections.functions.emit(self.spv.gpa, .OpFunctionParameter, .{
+                try self.func.prologue.emit(self.spv.gpa, .OpFunctionParameter, .{
                     .id_result_type = param_type_id,
                     .id_result = arg_result_id,
                 });
@@ -546,9 +585,9 @@ pub const DeclGen = struct {
             // TODO: This could probably be done in a better way...
             const root_block_id = self.spv.allocId();
 
-            // We need to generate the label directly in the functions section here because we're going to write the local variables after
-            // here. Since we're not generating in self.code, we're just going to bypass self.beginSpvBlock here.
-            try self.spv.sections.functions.emit(self.spv.gpa, .OpLabel, .{
+            // The root block of a function declaration should appear before OpVariable instructions,
+            // so it is generated into the function's prologue.
+            try self.func.prologue.emit(self.spv.gpa, .OpLabel, .{
                 .id_result = root_block_id,
             });
             self.current_block_label_id = root_block_id.toRef();
@@ -557,8 +596,8 @@ pub const DeclGen = struct {
             try self.genBody(main_body);
 
             // Append the actual code into the functions section.
-            try self.spv.sections.functions.append(self.spv.gpa, self.code);
-            try self.spv.sections.functions.emit(self.spv.gpa, .OpFunctionEnd, {});
+            try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
+            try self.spv.addFunction(self.func);
         } else {
             // TODO
             // return self.todo("generate decl type {}", .{decl.ty.zigTypeTag()});
@@ -579,6 +618,8 @@ pub const DeclGen = struct {
             .sub, .subwrap => try self.airArithOp(inst, .OpFSub, .OpISub, .OpISub),
             .mul, .mulwrap => try self.airArithOp(inst, .OpFMul, .OpIMul, .OpIMul),
 
+            .shuffle => try self.airShuffle(inst),
+
             .bit_and  => try self.airBinOpSimple(inst, .OpBitwiseAnd),
             .bit_or   => try self.airBinOpSimple(inst, .OpBitwiseOr),
             .xor      => try self.airBinOpSimple(inst, .OpBitwiseXor),
@@ -608,14 +649,18 @@ pub const DeclGen = struct {
             .ret        => return self.airRet(inst),
             .store      => return self.airStore(inst),
             .unreach    => return self.airUnreach(),
+            .assembly   => (try self.airAssembly(inst)) orelse return,
+
+            .dbg_var_ptr => return,
+            .dbg_var_val => return,
+            .dbg_block_begin => return,
+            .dbg_block_end => return,
             // zig fmt: on
 
-            else => |tag| return self.todo("implement AIR tag {s}", .{
-                @tagName(tag),
-            }),
+            else => |tag| return self.todo("implement AIR tag {s}", .{@tagName(tag)}),
         };
 
-        try self.inst_results.putNoClobber(self.spv.gpa, inst, result_id);
+        try self.inst_results.putNoClobber(self.gpa, inst, result_id);
     }
 
     fn airBinOpSimple(self: *DeclGen, inst: Air.Inst.Index, comptime opcode: Opcode) !IdRef {
@@ -624,7 +669,7 @@ pub const DeclGen = struct {
         const rhs_id = try self.resolve(bin_op.rhs);
         const result_id = self.spv.allocId();
         const result_type_id = try self.resolveTypeId(self.air.typeOfIndex(inst));
-        try self.code.emit(self.spv.gpa, opcode, .{
+        try self.func.body.emit(self.spv.gpa, opcode, .{
             .id_result_type = result_type_id,
             .id_result = result_id,
             .operand_1 = lhs_id,
@@ -680,9 +725,9 @@ pub const DeclGen = struct {
         };
 
         switch (opcode_index) {
-            0 => try self.code.emit(self.spv.gpa, fop, operands),
-            1 => try self.code.emit(self.spv.gpa, sop, operands),
-            2 => try self.code.emit(self.spv.gpa, uop, operands),
+            0 => try self.func.body.emit(self.spv.gpa, fop, operands),
+            1 => try self.func.body.emit(self.spv.gpa, sop, operands),
+            2 => try self.func.body.emit(self.spv.gpa, uop, operands),
             else => unreachable,
         }
         // TODO: Trap on overflow? Probably going to be annoying.
@@ -691,6 +736,41 @@ pub const DeclGen = struct {
         return result_id.toRef();
     }
 
+    fn airShuffle(self: *DeclGen, inst: Air.Inst.Index) !IdRef {
+        const ty = self.air.typeOfIndex(inst);
+        const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+        const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
+        const a = try self.resolve(extra.a);
+        const b = try self.resolve(extra.b);
+        const mask = self.air.values[extra.mask];
+        const mask_len = extra.mask_len;
+        const a_len = self.air.typeOf(extra.a).vectorLen();
+
+        const result_id = self.spv.allocId();
+        const result_type_id = try self.resolveTypeId(ty);
+        // Similar to LLVM, SPIR-V uses indices larger than the length of the first vector
+        // to index into the second vector.
+        try self.func.body.emitRaw(self.spv.gpa, .OpVectorShuffle, 4 + mask_len);
+        self.func.body.writeOperand(spec.IdResultType, result_type_id);
+        self.func.body.writeOperand(spec.IdResult, result_id);
+        self.func.body.writeOperand(spec.IdRef, a);
+        self.func.body.writeOperand(spec.IdRef, b);
+
+        var i: usize = 0;
+        while (i < mask_len) : (i += 1) {
+            var buf: Value.ElemValueBuffer = undefined;
+            const elem = mask.elemValueBuffer(self.module, i, &buf);
+            if (elem.isUndef()) {
+                self.func.body.writeOperand(spec.LiteralInteger, 0xFFFF_FFFF);
+            } else {
+                const int = elem.toSignedInt();
+                const unsigned = if (int >= 0) @intCast(u32, int) else @intCast(u32, ~int + a_len);
+                self.func.body.writeOperand(spec.LiteralInteger, unsigned);
+            }
+        }
+        return result_id.toRef();
+    }
+
     fn airCmp(self: *DeclGen, inst: Air.Inst.Index, comptime fop: Opcode, comptime sop: Opcode, comptime uop: Opcode) !IdRef {
         const bin_op = self.air.instructions.items(.data)[inst].bin_op;
         const lhs_id = try self.resolve(bin_op.lhs);
@@ -727,9 +807,9 @@ pub const DeclGen = struct {
         };
 
         switch (opcode_index) {
-            0 => try self.code.emit(self.spv.gpa, fop, operands),
-            1 => try self.code.emit(self.spv.gpa, sop, operands),
-            2 => try self.code.emit(self.spv.gpa, uop, operands),
+            0 => try self.func.body.emit(self.spv.gpa, fop, operands),
+            1 => try self.func.body.emit(self.spv.gpa, sop, operands),
+            2 => try self.func.body.emit(self.spv.gpa, uop, operands),
             else => unreachable,
         }
 
@@ -741,7 +821,7 @@ pub const DeclGen = struct {
         const operand_id = try self.resolve(ty_op.operand);
         const result_id = self.spv.allocId();
         const result_type_id = try self.resolveTypeId(Type.initTag(.bool));
-        try self.code.emit(self.spv.gpa, .OpLogicalNot, .{
+        try self.func.body.emit(self.spv.gpa, .OpLogicalNot, .{
             .id_result_type = result_type_id,
             .id_result = result_id,
             .operand = operand_id,
@@ -751,13 +831,18 @@ pub const DeclGen = struct {
 
     fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !IdRef {
         const ty = self.air.typeOfIndex(inst);
-        const storage_class = spec.StorageClass.Function;
-        const result_type_id = try self.genPointerType(ty, storage_class);
+        const result_type_id = try self.resolveTypeId(ty);
         const result_id = self.spv.allocId();
 
         // Rather than generating into code here, we're just going to generate directly into the functions section so that
         // variable declarations appear in the first block of the function.
-        try self.spv.sections.functions.emit(self.spv.gpa, .OpVariable, .{
+        const storage_class = spirvStorageClass(ty.ptrAddressSpace());
+        const section = if (storage_class == .Function)
+            &self.func.prologue
+        else
+            &self.spv.sections.types_globals_constants;
+
+        try section.emit(self.spv.gpa, .OpVariable, .{
             .id_result_type = result_type_id,
             .id_result = result_id,
             .storage_class = storage_class,
@@ -779,15 +864,15 @@ pub const DeclGen = struct {
         const label_id = self.spv.allocId();
 
         // 4 chosen as arbitrary initial capacity.
-        var incoming_blocks = try std.ArrayListUnmanaged(IncomingBlock).initCapacity(self.spv.gpa, 4);
+        var incoming_blocks = try std.ArrayListUnmanaged(IncomingBlock).initCapacity(self.gpa, 4);
 
-        try self.blocks.putNoClobber(self.spv.gpa, inst, .{
+        try self.blocks.putNoClobber(self.gpa, inst, .{
             .label_id = label_id.toRef(),
             .incoming_blocks = &incoming_blocks,
         });
         defer {
             assert(self.blocks.remove(inst));
-            incoming_blocks.deinit(self.spv.gpa);
+            incoming_blocks.deinit(self.gpa);
         }
 
         const ty = self.air.typeOfIndex(inst);
@@ -807,15 +892,14 @@ pub const DeclGen = struct {
         const result_id = self.spv.allocId();
 
         // TODO: OpPhi is limited in the types that it may produce, such as pointers. Figure out which other types
-        // are not allowed to be created from a phi node, and throw an error for those. For now, resolveTypeId already throws
-        // an error for pointers.
+        // are not allowed to be created from a phi node, and throw an error for those.
         const result_type_id = try self.resolveTypeId(ty);
         _ = result_type_id;
 
-        try self.code.emitRaw(self.spv.gpa, .OpPhi, 2 + @intCast(u16, incoming_blocks.items.len * 2)); // result type + result + variable/parent...
+        try self.func.body.emitRaw(self.spv.gpa, .OpPhi, 2 + @intCast(u16, incoming_blocks.items.len * 2)); // result type + result + variable/parent...
 
         for (incoming_blocks.items) |incoming| {
-            self.code.writeOperand(spec.PairIdRefIdRef, .{ incoming.break_value_id, incoming.src_label_id });
+            self.func.body.writeOperand(spec.PairIdRefIdRef, .{ incoming.break_value_id, incoming.src_label_id });
         }
 
         return result_id.toRef();
@@ -829,10 +913,10 @@ pub const DeclGen = struct {
         if (operand_ty.hasRuntimeBits()) {
             const operand_id = try self.resolve(br.operand);
             // current_block_label_id should not be undefined here, lest there is a br or br_void in the function's body.
-            try block.incoming_blocks.append(self.spv.gpa, .{ .src_label_id = self.current_block_label_id, .break_value_id = operand_id });
+            try block.incoming_blocks.append(self.gpa, .{ .src_label_id = self.current_block_label_id, .break_value_id = operand_id });
         }
 
-        try self.code.emit(self.spv.gpa, .OpBranch, .{ .target_label = block.label_id });
+        try self.func.body.emit(self.spv.gpa, .OpBranch, .{ .target_label = block.label_id });
     }
 
     fn airCondBr(self: *DeclGen, inst: Air.Inst.Index) !void {
@@ -849,7 +933,7 @@ pub const DeclGen = struct {
         // TODO: We can generate OpSelectionMerge here if we know the target block that both of these will resolve to,
         // but i don't know if those will always resolve to the same block.
 
-        try self.code.emit(self.spv.gpa, .OpBranchConditional, .{
+        try self.func.body.emit(self.spv.gpa, .OpBranchConditional, .{
             .condition = condition_id,
             .true_label = then_label_id.toRef(),
             .false_label = else_label_id.toRef(),
@@ -864,7 +948,7 @@ pub const DeclGen = struct {
     fn airDbgStmt(self: *DeclGen, inst: Air.Inst.Index) !void {
         const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt;
         const src_fname_id = try self.spv.resolveSourceFileName(self.decl);
-        try self.code.emit(self.spv.gpa, .OpLine, .{
+        try self.func.body.emit(self.spv.gpa, .OpLine, .{
             .file = src_fname_id,
             .line = dbg_stmt.line,
             .column = dbg_stmt.column,
@@ -883,7 +967,7 @@ pub const DeclGen = struct {
             .Volatile = ty.isVolatilePtr(),
         };
 
-        try self.code.emit(self.spv.gpa, .OpLoad, .{
+        try self.func.body.emit(self.spv.gpa, .OpLoad, .{
             .id_result_type = result_type_id,
             .id_result = result_id,
             .pointer = operand_id,
@@ -900,13 +984,13 @@ pub const DeclGen = struct {
         const loop_label_id = self.spv.allocId();
 
         // Jump to the loop entry point
-        try self.code.emit(self.spv.gpa, .OpBranch, .{ .target_label = loop_label_id.toRef() });
+        try self.func.body.emit(self.spv.gpa, .OpBranch, .{ .target_label = loop_label_id.toRef() });
 
         // TODO: Look into OpLoopMerge.
         try self.beginSpvBlock(loop_label_id);
         try self.genBody(body);
 
-        try self.code.emit(self.spv.gpa, .OpBranch, .{ .target_label = loop_label_id.toRef() });
+        try self.func.body.emit(self.spv.gpa, .OpBranch, .{ .target_label = loop_label_id.toRef() });
     }
 
     fn airRet(self: *DeclGen, inst: Air.Inst.Index) !void {
@@ -914,9 +998,9 @@ pub const DeclGen = struct {
         const operand_ty = self.air.typeOf(operand);
         if (operand_ty.hasRuntimeBits()) {
             const operand_id = try self.resolve(operand);
-            try self.code.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });
+            try self.func.body.emit(self.spv.gpa, .OpReturnValue, .{ .value = operand_id });
         } else {
-            try self.code.emit(self.spv.gpa, .OpReturn, {});
+            try self.func.body.emit(self.spv.gpa, .OpReturn, {});
         }
     }
 
@@ -930,7 +1014,7 @@ pub const DeclGen = struct {
             .Volatile = lhs_ty.isVolatilePtr(),
         };
 
-        try self.code.emit(self.spv.gpa, .OpStore, .{
+        try self.func.body.emit(self.spv.gpa, .OpStore, .{
             .pointer = dst_ptr_id,
             .object = src_val_id,
             .memory_access = access,
@@ -938,6 +1022,134 @@ pub const DeclGen = struct {
     }
 
     fn airUnreach(self: *DeclGen) !void {
-        try self.code.emit(self.spv.gpa, .OpUnreachable, {});
+        try self.func.body.emit(self.spv.gpa, .OpUnreachable, {});
+    }
+
+    fn airAssembly(self: *DeclGen, inst: Air.Inst.Index) !?IdRef {
+        const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+        const extra = self.air.extraData(Air.Asm, ty_pl.payload);
+
+        const is_volatile = @truncate(u1, extra.data.flags >> 31) != 0;
+        const clobbers_len = @truncate(u31, extra.data.flags);
+
+        if (!is_volatile and self.liveness.isUnused(inst)) return null;
+
+        var extra_i: usize = extra.end;
+        const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.outputs_len]);
+        extra_i += outputs.len;
+        const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]);
+        extra_i += inputs.len;
+
+        if (outputs.len > 1) {
+            return self.todo("implement inline asm with more than 1 output", .{});
+        }
+
+        var output_extra_i = extra_i;
+        for (outputs) |output| {
+            if (output != .none) {
+                return self.todo("implement inline asm with non-returned output", .{});
+            }
+            const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
+            const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
+            const name = std.mem.sliceTo(extra_bytes[constraint.len + 1..], 0);
+            extra_i += (constraint.len + name.len + (2 + 3)) / 4;
+            // TODO: Record output and use it somewhere.
+        }
+
+        var input_extra_i = extra_i;
+        for (inputs) |input| {
+            const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
+            const constraint = std.mem.sliceTo(extra_bytes, 0);
+            const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
+            // This equation accounts for the fact that even if we have exactly 4 bytes
+            // for the string, we still use the next u32 for the null terminator.
+            extra_i += (constraint.len + name.len + (2 + 3)) / 4;
+            // TODO: Record input and use it somewhere.
+            _ = input;
+        }
+
+        {
+            var clobber_i: u32 = 0;
+            while (clobber_i < clobbers_len) : (clobber_i += 1) {
+                const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
+                extra_i += clobber.len / 4 + 1;
+                // TODO: Record clobber and use it somewhere.
+            }
+        }
+
+        const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len];
+
+        var as = SpvAssembler{
+            .gpa = self.gpa,
+            .src = asm_source,
+            .spv = self.spv,
+            .func = &self.func,
+        };
+        defer as.deinit();
+
+        for (inputs) |input| {
+            const extra_bytes = std.mem.sliceAsBytes(self.air.extra[input_extra_i..]);
+            const constraint = std.mem.sliceTo(extra_bytes, 0);
+            const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
+            // This equation accounts for the fact that even if we have exactly 4 bytes
+            // for the string, we still use the next u32 for the null terminator.
+            input_extra_i += (constraint.len + name.len + (2 + 3)) / 4;
+
+            const value = try self.resolve(input);
+            try as.value_map.put(as.gpa, name, .{.value = value});
+        }
+
+        as.assemble() catch |err| switch (err) {
+            error.AssembleFail => {
+                // TODO: For now the compiler only supports a single error message per decl,
+                // so to translate the possible multiple errors from the assembler, emit
+                // them as notes here.
+                // TODO: Translate proper error locations.
+                assert(as.errors.items.len != 0);
+                assert(self.error_msg == null);
+                const loc = LazySrcLoc.nodeOffset(0);
+                const src_loc = loc.toSrcLoc(self.decl);
+                self.error_msg = try Module.ErrorMsg.create(self.module.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
+                const notes = try self.module.gpa.alloc(Module.ErrorMsg, as.errors.items.len);
+
+                // Sub-scope to prevent `return error.CodegenFail` from running the errdefers.
+                {
+                    errdefer self.module.gpa.free(notes);
+                    var i: usize = 0;
+                    errdefer for (notes[0..i]) |*note| {
+                        note.deinit(self.module.gpa);
+                    };
+
+                    while (i < as.errors.items.len) : (i += 1) {
+                        notes[i] = try Module.ErrorMsg.init(self.module.gpa, src_loc, "{s}", .{as.errors.items[i].msg});
+                    }
+                }
+                self.error_msg.?.notes = notes;
+                return error.CodegenFail;
+            },
+            else => |others| return others,
+        };
+
+        for (outputs) |output| {
+            _ = output;
+            const extra_bytes = std.mem.sliceAsBytes(self.air.extra[output_extra_i..]);
+            const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[output_extra_i..]), 0);
+            const name = std.mem.sliceTo(extra_bytes[constraint.len + 1..], 0);
+            output_extra_i += (constraint.len + name.len + (2 + 3)) / 4;
+
+            const result = as.value_map.get(name) orelse return {
+                return self.fail("invalid asm output '{s}'", .{name});
+            };
+
+            switch (result) {
+                .just_declared, .unresolved_forward_reference => unreachable,
+                .ty => return self.fail("cannot return spir-v type as value from assembly", .{}),
+                .value => |ref| return ref,
+            }
+
+            // TODO: Multiple results
+        }
+
+        return null;
     }
 };
src/link/SpirV.zig
@@ -58,13 +58,13 @@ decl_table: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclGenContext) = .
 
 const DeclGenContext = struct {
     air: Air,
-    air_value_arena: ArenaAllocator.State,
+    air_arena: ArenaAllocator.State,
     liveness: Liveness,
 
     fn deinit(self: *DeclGenContext, gpa: Allocator) void {
         self.air.deinit(gpa);
         self.liveness.deinit(gpa);
-        self.air_value_arena.promote(gpa).deinit();
+        self.air_arena.promote(gpa).deinit();
         self.* = undefined;
     }
 };
@@ -140,7 +140,7 @@ pub fn updateFunc(self: *SpirV, module: *Module, func: *Module.Fn, air: Air, liv
 
     result.value_ptr.* = .{
         .air = new_air,
-        .air_value_arena = arena.state,
+        .air_arena = arena.state,
         .liveness = new_liveness,
     };
 }
@@ -167,13 +167,13 @@ pub fn updateDeclExports(
 }
 
 pub fn freeDecl(self: *SpirV, decl_index: Module.Decl.Index) void {
-    const index = self.decl_table.getIndex(decl_index).?;
-    const module = self.base.options.module.?;
-    const decl = module.declPtr(decl_index);
-    if (decl.val.tag() == .function) {
-        self.decl_table.values()[index].deinit(self.base.allocator);
+    if (self.decl_table.getIndex(decl_index)) |index| {
+        const module = self.base.options.module.?;
+        const decl = module.declPtr(decl_index);
+        if (decl.val.tag() == .function) {
+            self.decl_table.values()[index].deinit(self.base.allocator);
+        }
     }
-    self.decl_table.swapRemoveAt(index);
 }
 
 pub fn flush(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
@@ -218,7 +218,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
     }
 
     // Now, actually generate the code for all declarations.
-    var decl_gen = codegen.DeclGen.init(module, &spv);
+    var decl_gen = codegen.DeclGen.init(self.base.allocator, module, &spv);
     defer decl_gen.deinit();
 
     var it = self.decl_table.iterator();
@@ -245,16 +245,18 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
 
 fn writeCapabilities(spv: *SpvModule, target: std.Target) !void {
     // TODO: Integrate with a hypothetical feature system
-    const cap: spec.Capability = switch (target.os.tag) {
-        .opencl => .Kernel,
-        .glsl450 => .Shader,
-        .vulkan => .VulkanMemoryModel,
+    const caps: []const spec.Capability = switch (target.os.tag) {
+        .opencl => &.{.Kernel},
+        .glsl450 => &.{.Shader},
+        .vulkan => &.{.Shader},
         else => unreachable, // TODO
     };
 
-    try spv.sections.capabilities.emit(spv.gpa, .OpCapability, .{
-        .capability = cap,
-    });
+    for (caps) |cap| {
+        try spv.sections.capabilities.emit(spv.gpa, .OpCapability, .{
+            .capability = cap,
+        });
+    }
 }
 
 fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void {
@@ -271,7 +273,7 @@ fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void {
     const memory_model: spec.MemoryModel = switch (target.os.tag) {
         .opencl => .OpenCL,
         .glsl450 => .GLSL450,
-        .vulkan => .Vulkan,
+        .vulkan => .GLSL450,
         else => unreachable,
     };
 
@@ -296,17 +298,27 @@ fn cloneLiveness(l: Liveness, gpa: Allocator) !Liveness {
     };
 }
 
-fn cloneAir(air: Air, gpa: Allocator, value_arena: Allocator) !Air {
+fn cloneAir(air: Air, gpa: Allocator, air_arena: Allocator) !Air {
     const values = try gpa.alloc(Value, air.values.len);
     errdefer gpa.free(values);
 
     for (values) |*value, i| {
-        value.* = try air.values[i].copy(value_arena);
+        value.* = try air.values[i].copy(air_arena);
     }
 
     var instructions = try air.instructions.toMultiArrayList().clone(gpa);
     errdefer instructions.deinit(gpa);
 
+    const air_tags = instructions.items(.tag);
+    const air_datas = instructions.items(.data);
+
+    for (air_tags) |tag, i| {
+        switch (tag) {
+            .arg, .alloc, .ret_ptr, .const_ty => air_datas[i].ty = try air_datas[i].ty.copy(air_arena),
+            else => {},
+        }
+    }
+
     return Air{
         .instructions = instructions.slice(),
         .extra = try gpa.dupe(u32, air.extra),
src/stage1/all_types.hpp
@@ -99,7 +99,7 @@ enum AddressSpace {
     AddressSpaceConstant,
     AddressSpaceParam,
     AddressSpaceShared,
-    AddressSpaceLocal
+    AddressSpaceLocal,
 };
 
 // This one corresponds to the builtin.zig enum.
src/Sema.zig
@@ -30952,10 +30952,14 @@ pub fn analyzeAddressSpace(
     const address_space = addrspace_tv.val.toEnum(std.builtin.AddressSpace);
     const target = sema.mod.getTarget();
     const arch = target.cpu.arch;
+
     const is_nv = arch == .nvptx or arch == .nvptx64;
-    const is_gpu = is_nv or arch == .amdgcn;
+    const is_amd = arch == .amdgcn;
+    const is_spirv = arch == .spirv32 or arch == .spirv64;
+    const is_gpu = is_nv or is_amd or is_spirv;
 
     const supported = switch (address_space) {
+        // TODO: on spir-v only when os is opencl.
         .generic => true,
         .gs, .fs, .ss => (arch == .x86 or arch == .x86_64) and ctx == .pointer,
         // TODO: check that .shared and .local are left uninitialized
tools/gen_spirv_spec.zig
@@ -116,6 +116,31 @@ fn render(writer: anytype, allocator: Allocator, registry: g.CoreRegistry) !void
         \\pub const PairIdRefLiteralInteger = struct { target: IdRef, member: LiteralInteger };
         \\pub const PairIdRefIdRef = [2]IdRef;
         \\
+        \\pub const Quantifier = enum {
+        \\    required,
+        \\    optional,
+        \\    variadic,
+        \\};
+        \\
+        \\pub const Operand = struct {
+        \\    kind: OperandKind,
+        \\    quantifier: Quantifier,
+        \\};
+        \\
+        \\pub const OperandCategory = enum {
+        \\    bit_enum,
+        \\    value_enum,
+        \\    id,
+        \\    literal,
+        \\    composite,
+        \\};
+        \\
+        \\pub const Enumerant = struct {
+        \\    name: []const u8,
+        \\    value: Word,
+        \\    parameters: []const OperandKind,
+        \\};
+        \\
         \\
     );
 
@@ -123,14 +148,118 @@ fn render(writer: anytype, allocator: Allocator, registry: g.CoreRegistry) !void
         \\pub const version = Version{{ .major = {}, .minor = {}, .patch = {} }};
         \\pub const magic_number: Word = {s};
         \\
+        \\
     ,
         .{ registry.major_version, registry.minor_version, registry.revision, registry.magic_number },
     );
+
     const extended_structs = try extendedStructs(allocator, registry.operand_kinds);
+    try renderClass(writer, allocator, registry.instructions);
+    try renderOperandKind(writer, registry.operand_kinds);
     try renderOpcodes(writer, allocator, registry.instructions, extended_structs);
     try renderOperandKinds(writer, allocator, registry.operand_kinds, extended_structs);
 }
 
+fn renderClass(writer: anytype, allocator: Allocator, instructions: []const g.Instruction) !void {
+    var class_map = std.StringArrayHashMap(void).init(allocator);
+
+    for (instructions) |inst| {
+        if (std.mem.eql(u8, inst.class.?, "@exclude")) {
+            continue;
+        }
+        try class_map.put(inst.class.?, {});
+    }
+
+    try writer.writeAll("pub const Class = enum {\n");
+    for (class_map.keys()) |class| {
+        try renderInstructionClass(writer, class);
+        try writer.writeAll(",\n");
+    }
+    try writer.writeAll("};\n");
+}
+
+fn renderInstructionClass(writer: anytype, class: []const u8) !void {
+    // Just assume that these wont clobber zig builtin types.
+    var prev_was_sep = true;
+    for (class) |c| {
+        switch (c) {
+            '-', '_' => prev_was_sep = true,
+            else => if (prev_was_sep) {
+                try writer.writeByte(std.ascii.toUpper(c));
+                prev_was_sep = false;
+            } else {
+                try writer.writeByte(std.ascii.toLower(c));
+            },
+        }
+    }
+}
+
+fn renderOperandKind(writer: anytype, operands: []const g.OperandKind) !void {
+    try writer.writeAll("pub const OperandKind = enum {\n");
+    for (operands) |operand| {
+        try writer.print("{},\n", .{std.zig.fmtId(operand.kind)});
+    }
+    try writer.writeAll(
+        \\
+        \\pub fn category(self: OperandKind) OperandCategory {
+        \\return switch (self) {
+        \\
+    );
+    for (operands) |operand| {
+        const cat = switch (operand.category) {
+            .BitEnum => "bit_enum",
+            .ValueEnum => "value_enum",
+            .Id => "id",
+            .Literal => "literal",
+            .Composite => "composite",
+        };
+        try writer.print(".{} => .{s},\n", .{ std.zig.fmtId(operand.kind), cat });
+    }
+    try writer.writeAll(
+        \\};
+        \\}
+        \\pub fn enumerants(self: OperandKind) []const Enumerant {
+        \\return switch (self) {
+        \\
+    );
+    for (operands) |operand| {
+        switch (operand.category) {
+            .BitEnum, .ValueEnum => {},
+            else => {
+                try writer.print(".{} => unreachable,\n", .{std.zig.fmtId(operand.kind)});
+                continue;
+            },
+        }
+
+        try writer.print(".{} => &[_]Enumerant{{", .{std.zig.fmtId(operand.kind)});
+        for (operand.enumerants.?) |enumerant| {
+            if (enumerant.value == .bitflag and std.mem.eql(u8, enumerant.enumerant, "None")) {
+                continue;
+            }
+            try renderEnumerant(writer, enumerant);
+            try writer.writeAll(",");
+        }
+        try writer.writeAll("},\n");
+    }
+    try writer.writeAll("};\n}\n};\n");
+}
+
+fn renderEnumerant(writer: anytype, enumerant: g.Enumerant) !void {
+    try writer.print(".{{.name = \"{s}\", .value = ", .{enumerant.enumerant});
+    switch (enumerant.value) {
+        .bitflag => |flag| try writer.writeAll(flag),
+        .int => |int| try writer.print("{}", .{int}),
+    }
+    try writer.writeAll(", .parameters = &[_]OperandKind{");
+    for (enumerant.parameters) |param, i| {
+        if (i != 0)
+            try writer.writeAll(", ");
+        // Note, param.quantifier will always be one.
+        try writer.print(".{}", .{std.zig.fmtId(param.kind)});
+    }
+    try writer.writeAll("}}");
+}
+
 fn renderOpcodes(
     writer: anytype,
     allocator: Allocator,
@@ -144,6 +273,9 @@ fn renderOpcodes(
     try aliases.ensureTotalCapacity(instructions.len);
 
     for (instructions) |inst, i| {
+        if (std.mem.eql(u8, inst.class.?, "@exclude")) {
+            continue;
+        }
         const result = inst_map.getOrPutAssumeCapacity(inst.opcode);
         if (!result.found_existing) {
             result.value_ptr.* = i;
@@ -192,6 +324,47 @@ fn renderOpcodes(
         const inst = instructions[i];
         try renderOperand(writer, .instruction, inst.opname, inst.operands, extended_structs);
     }
+
+    try writer.writeAll(
+        \\};
+        \\}
+        \\pub fn operands(self: Opcode) []const Operand {
+        \\return switch (self) {
+        \\
+    );
+
+    for (instructions_indices) |i| {
+        const inst = instructions[i];
+        try writer.print(".{} => &[_]Operand{{", .{std.zig.fmtId(inst.opname)});
+        for (inst.operands) |operand| {
+            const quantifier = if (operand.quantifier) |q|
+                switch (q) {
+                    .@"?" => "optional",
+                    .@"*" => "variadic",
+                }
+            else
+                "required";
+
+            try writer.print(".{{.kind = .{s}, .quantifier = .{s}}},", .{ operand.kind, quantifier });
+        }
+        try writer.writeAll("},\n");
+    }
+
+    try writer.writeAll(
+        \\};
+        \\}
+        \\pub fn class(self: Opcode) Class {
+        \\return switch (self) {
+        \\
+    );
+
+    for (instructions_indices) |i| {
+        const inst = instructions[i];
+        try writer.print(".{} => .", .{std.zig.fmtId(inst.opname)});
+        try renderInstructionClass(writer, inst.class.?);
+        try writer.writeAll(",\n");
+    }
+
     try writer.writeAll("};\n}\n};\n");
 }
 
@@ -298,7 +471,7 @@ fn renderBitEnum(
     for (enumerants) |enumerant, i| {
         if (enumerant.value != .bitflag) return error.InvalidRegistry;
         const value = try parseHexInt(enumerant.value.bitflag);
-        if (@popCount(value) == 0) {
+        if (value == 0) {
             continue; // Skip 'none' items
         }