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};