master
  1//! See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
  2//! and the files in https://github.com/KhronosGroup/SPIRV-Headers/blob/master/include/spirv/unified1/
  3//! Note: Non-canonical casing in these structs used to match SPIR-V spec json.
  4
  5const std = @import("std");
  6
  7pub const Registry = union(enum) {
  8    core: CoreRegistry,
  9    extension: ExtensionRegistry,
 10};
 11
 12pub const CoreRegistry = struct {
 13    copyright: [][]const u8,
 14    /// Hexadecimal representation of the magic number
 15    magic_number: []const u8,
 16    major_version: u32,
 17    minor_version: u32,
 18    revision: u32,
 19    instruction_printing_class: []InstructionPrintingClass,
 20    instructions: []Instruction,
 21    operand_kinds: []OperandKind,
 22};
 23
 24pub const ExtensionRegistry = struct {
 25    copyright: ?[][]const u8 = null,
 26    version: ?u32 = null,
 27    revision: u32,
 28    instructions: []Instruction,
 29    operand_kinds: []OperandKind = &[_]OperandKind{},
 30};
 31
 32pub const InstructionPrintingClass = struct {
 33    tag: []const u8,
 34    heading: ?[]const u8 = null,
 35};
 36
 37pub const Instruction = struct {
 38    opname: []const u8,
 39    class: ?[]const u8 = null, // Note: Only available in the core registry.
 40    aliases: [][]const u8 = &[_][]const u8{},
 41    opcode: u32,
 42    operands: []Operand = &[_]Operand{},
 43    capabilities: [][]const u8 = &[_][]const u8{},
 44    provisional: bool = false,
 45    // DebugModuleINTEL has this...
 46    capability: ?[]const u8 = null,
 47    extensions: [][]const u8 = &[_][]const u8{},
 48    version: ?[]const u8 = null,
 49
 50    lastVersion: ?[]const u8 = null,
 51};
 52
 53pub const Operand = struct {
 54    kind: []const u8,
 55    /// If this field is 'null', the operand is only expected once.
 56    quantifier: ?Quantifier = null,
 57    name: []const u8 = "",
 58};
 59
 60pub const Quantifier = enum {
 61    /// zero or once
 62    @"?",
 63    /// zero or more
 64    @"*",
 65};
 66
 67pub const OperandCategory = enum {
 68    BitEnum,
 69    ValueEnum,
 70    Id,
 71    Literal,
 72    Composite,
 73};
 74
 75pub const OperandKind = struct {
 76    category: OperandCategory,
 77    /// The name
 78    kind: []const u8,
 79    doc: ?[]const u8 = null,
 80    enumerants: ?[]Enumerant = null,
 81    bases: ?[]const []const u8 = null,
 82};
 83
 84pub const Enumerant = struct {
 85    enumerant: []const u8,
 86    aliases: [][]const u8 = &[_][]const u8{},
 87    value: union(enum) {
 88        bitflag: []const u8, // Hexadecimal representation of the value
 89        int: u31,
 90
 91        pub fn jsonParse(
 92            allocator: std.mem.Allocator,
 93            source: anytype,
 94            options: std.json.ParseOptions,
 95        ) std.json.ParseError(@TypeOf(source.*))!@This() {
 96            _ = options;
 97            switch (try source.nextAlloc(allocator, .alloc_if_needed)) {
 98                inline .string, .allocated_string => |s| return @This(){ .bitflag = s },
 99                inline .number, .allocated_number => |s| return @This(){ .int = try std.fmt.parseInt(u31, s, 10) },
100                else => return error.UnexpectedToken,
101            }
102        }
103        pub const jsonStringify = @compileError("not supported");
104    },
105    capabilities: [][]const u8 = &[_][]const u8{},
106    provisional: bool = false,
107    /// Valid for .ValueEnum and .BitEnum
108    extensions: [][]const u8 = &[_][]const u8{},
109    /// `quantifier` will always be `null`.
110    parameters: []Operand = &[_]Operand{},
111    version: ?[]const u8 = null,
112    lastVersion: ?[]const u8 = null,
113};