authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-12 00:08:14+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-05-14 19:49:32+02:00
log25329ca8521fc34a5cedc837a1142e1111d4e844
tree348be2989f742d0e6e0e06d25ef3189723dae492
parent42f2ff6ec9ad370cc58d8b2d85f62af346e9b5b8

SPIR-V: Split out registry from gen_spirv_spec.zig


2 files changed, 97 insertions(+), 97 deletions(-)

tools/gen_spirv_spec.zig+7-97
...@@ -1,97 +1,7 @@...@@ -1,97 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const g = @import("spirv/grammar.zig");
2const Writer = std.ArrayList(u8).Writer;3const Writer = std.ArrayList(u8).Writer;
34
4//! See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
5//! and the files in https://github.com/KhronosGroup/SPIRV-Headers/blob/master/include/spirv/unified1/
6//! Note: Non-canonical casing in these structs used to match SPIR-V spec json.
7const Registry = union(enum) {
8 core: CoreRegistry,
9 extension: ExtensionRegistry,
10};
11
12const 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
24const ExtensionRegistry = struct {
25 copyright: [][]const u8,
26 version: u32,
27 revision: u32,
28 instructions: []Instruction,
29 operand_kinds: []OperandKind = &[_]OperandKind{},
30};
31
32const InstructionPrintingClass = struct {
33 tag: []const u8,
34 heading: ?[]const u8 = null,
35};
36
37const Instruction = struct {
38 opname: []const u8,
39 class: ?[]const u8 = null, // Note: Only available in the core registry.
40 opcode: u32,
41 operands: []Operand = &[_]Operand{},
42 capabilities: [][]const u8 = &[_][]const u8{},
43 extensions: [][]const u8 = &[_][]const u8{},
44 version: ?[]const u8 = null,
45
46 lastVersion: ?[]const u8 = null,
47};
48
49const Operand = struct {
50 kind: []const u8,
51 /// If this field is 'null', the operand is only expected once.
52 quantifier: ?Quantifier = null,
53 name: []const u8 = "",
54};
55
56const Quantifier = enum {
57 /// zero or once
58 @"?",
59 /// zero or more
60 @"*",
61};
62
63const OperandCategory = enum {
64 BitEnum,
65 ValueEnum,
66 Id,
67 Literal,
68 Composite,
69};
70
71const OperandKind = struct {
72 category: OperandCategory,
73 /// The name
74 kind: []const u8,
75 doc: ?[]const u8 = null,
76 enumerants: ?[]Enumerant = null,
77 bases: ?[]const []const u8 = null,
78};
79
80const Enumerant = struct {
81 enumerant: []const u8,
82 value: union(enum) {
83 bitflag: []const u8, // Hexadecimal representation of the value
84 int: u31,
85 },
86 capabilities: [][]const u8 = &[_][]const u8{},
87 /// Valid for .ValueEnum and .BitEnum
88 extensions: [][]const u8 = &[_][]const u8{},
89 /// `quantifier` will always be `null`.
90 parameters: []Operand = &[_]Operand{},
91 version: ?[]const u8 = null,
92 lastVersion: ?[]const u8 = null,
93};
94
95pub fn main() !void {5pub fn main() !void {
96 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);6 var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
97 defer arena.deinit();7 defer arena.deinit();
...@@ -106,7 +16,7 @@ pub fn main() !void {...@@ -106,7 +16,7 @@ pub fn main() !void {
106 const spec = try std.fs.cwd().readFileAlloc(allocator, spec_path, std.math.maxInt(usize));16 const spec = try std.fs.cwd().readFileAlloc(allocator, spec_path, std.math.maxInt(usize));
10717
108 var tokens = std.json.TokenStream.init(spec);18 var tokens = std.json.TokenStream.init(spec);
109 var registry = try std.json.parse(Registry, &tokens, .{.allocator = allocator});19 var registry = try std.json.parse(g.Registry, &tokens, .{.allocator = allocator});
11020
111 var buf = std.ArrayList(u8).init(allocator);21 var buf = std.ArrayList(u8).init(allocator);
112 defer buf.deinit();22 defer buf.deinit();
...@@ -118,7 +28,7 @@ pub fn main() !void {...@@ -118,7 +28,7 @@ pub fn main() !void {
118 try std.io.getStdOut().writeAll(formatted);28 try std.io.getStdOut().writeAll(formatted);
119}29}
12030
121fn render(writer: Writer, registry: Registry) !void {31fn render(writer: Writer, registry: g.Registry) !void {
122 try writer.writeAll(32 try writer.writeAll(
123 \\//! This file is auto-generated by tools/gen_spirv_spec.zig.33 \\//! This file is auto-generated by tools/gen_spirv_spec.zig.
124 \\34 \\
...@@ -149,7 +59,7 @@ fn render(writer: Writer, registry: Registry) !void {...@@ -149,7 +59,7 @@ fn render(writer: Writer, registry: Registry) !void {
149 }59 }
150}60}
15161
152fn renderOpcodes(writer: Writer, instructions: []const Instruction) !void {62fn renderOpcodes(writer: Writer, instructions: []const g.Instruction) !void {
153 try writer.writeAll("pub const Opcode = extern enum(u16) {\n");63 try writer.writeAll("pub const Opcode = extern enum(u16) {\n");
154 for (instructions) |instr| {64 for (instructions) |instr| {
155 try writer.print("{} = {},\n", .{ std.zig.fmtId(instr.opname), instr.opcode });65 try writer.print("{} = {},\n", .{ std.zig.fmtId(instr.opname), instr.opcode });
...@@ -157,7 +67,7 @@ fn renderOpcodes(writer: Writer, instructions: []const Instruction) !void {...@@ -157,7 +67,7 @@ fn renderOpcodes(writer: Writer, instructions: []const Instruction) !void {
157 try writer.writeAll("_,\n};\n");67 try writer.writeAll("_,\n};\n");
158}68}
15969
160fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {70fn renderOperandKinds(writer: Writer, kinds: []const g.OperandKind) !void {
161 for (kinds) |kind| {71 for (kinds) |kind| {
162 switch (kind.category) {72 switch (kind.category) {
163 .ValueEnum => try renderValueEnum(writer, kind),73 .ValueEnum => try renderValueEnum(writer, kind),
...@@ -167,7 +77,7 @@ fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {...@@ -167,7 +77,7 @@ fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {
167 }77 }
168}78}
16979
170fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {80fn renderValueEnum(writer: Writer, enumeration: g.OperandKind) !void {
171 try writer.print("pub const {s} = extern enum(u32) {{\n", .{ enumeration.kind });81 try writer.print("pub const {s} = extern enum(u32) {{\n", .{ enumeration.kind });
17282
173 const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;83 const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;
...@@ -180,7 +90,7 @@ fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {...@@ -180,7 +90,7 @@ fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {
180 try writer.writeAll("_,\n};\n");90 try writer.writeAll("_,\n};\n");
181}91}
18292
183fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {93fn renderBitEnum(writer: Writer, enumeration: g.OperandKind) !void {
184 try writer.print("pub const {s} = packed struct {{\n", .{ enumeration.kind });94 try writer.print("pub const {s} = packed struct {{\n", .{ enumeration.kind });
18595
186 var flags_by_bitpos = [_]?[]const u8{null} ** 32;96 var flags_by_bitpos = [_]?[]const u8{null} ** 32;
tools/spirv/grammar.zig created+90
...@@ -0,0 +1,90 @@
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.
4pub const Registry = union(enum) {
5 core: CoreRegistry,
6 extension: ExtensionRegistry,
7};
8
9pub const CoreRegistry = struct {
10 copyright: [][]const u8,
11 /// Hexadecimal representation of the magic number
12 magic_number: []const u8,
13 major_version: u32,
14 minor_version: u32,
15 revision: u32,
16 instruction_printing_class: []InstructionPrintingClass,
17 instructions: []Instruction,
18 operand_kinds: []OperandKind,
19};
20
21pub const ExtensionRegistry = struct {
22 copyright: [][]const u8,
23 version: u32,
24 revision: u32,
25 instructions: []Instruction,
26 operand_kinds: []OperandKind = &[_]OperandKind{},
27};
28
29pub const InstructionPrintingClass = struct {
30 tag: []const u8,
31 heading: ?[]const u8 = null,
32};
33
34pub const Instruction = struct {
35 opname: []const u8,
36 class: ?[]const u8 = null, // Note: Only available in the core registry.
37 opcode: u32,
38 operands: []Operand = &[_]Operand{},
39 capabilities: [][]const u8 = &[_][]const u8{},
40 extensions: [][]const u8 = &[_][]const u8{},
41 version: ?[]const u8 = null,
42
43 lastVersion: ?[]const u8 = null,
44};
45
46pub const Operand = struct {
47 kind: []const u8,
48 /// If this field is 'null', the operand is only expected once.
49 quantifier: ?Quantifier = null,
50 name: []const u8 = "",
51};
52
53pub const Quantifier = enum {
54 /// zero or once
55 @"?",
56 /// zero or more
57 @"*",
58};
59
60pub const OperandCategory = enum {
61 BitEnum,
62 ValueEnum,
63 Id,
64 Literal,
65 Composite,
66};
67
68pub const OperandKind = struct {
69 category: OperandCategory,
70 /// The name
71 kind: []const u8,
72 doc: ?[]const u8 = null,
73 enumerants: ?[]Enumerant = null,
74 bases: ?[]const []const u8 = null,
75};
76
77pub const Enumerant = struct {
78 enumerant: []const u8,
79 value: union(enum) {
80 bitflag: []const u8, // Hexadecimal representation of the value
81 int: u31,
82 },
83 capabilities: [][]const u8 = &[_][]const u8{},
84 /// Valid for .ValueEnum and .BitEnum
85 extensions: [][]const u8 = &[_][]const u8{},
86 /// `quantifier` will always be `null`.
87 parameters: []Operand = &[_]Operand{},
88 version: ?[]const u8 = null,
89 lastVersion: ?[]const u8 = null,
90};