Commit 25329ca852
Changed files (2)
tools
tools/spirv/grammar.zig
@@ -0,0 +1,90 @@
+//! See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
+//! and the files in https://github.com/KhronosGroup/SPIRV-Headers/blob/master/include/spirv/unified1/
+//! Note: Non-canonical casing in these structs used to match SPIR-V spec json.
+pub const Registry = union(enum) {
+ core: CoreRegistry,
+ extension: ExtensionRegistry,
+};
+
+pub const CoreRegistry = struct {
+ copyright: [][]const u8,
+ /// Hexadecimal representation of the magic number
+ magic_number: []const u8,
+ major_version: u32,
+ minor_version: u32,
+ revision: u32,
+ instruction_printing_class: []InstructionPrintingClass,
+ instructions: []Instruction,
+ operand_kinds: []OperandKind,
+};
+
+pub const ExtensionRegistry = struct {
+ copyright: [][]const u8,
+ version: u32,
+ revision: u32,
+ instructions: []Instruction,
+ operand_kinds: []OperandKind = &[_]OperandKind{},
+};
+
+pub const InstructionPrintingClass = struct {
+ tag: []const u8,
+ heading: ?[]const u8 = null,
+};
+
+pub const Instruction = struct {
+ opname: []const u8,
+ class: ?[]const u8 = null, // Note: Only available in the core registry.
+ opcode: u32,
+ operands: []Operand = &[_]Operand{},
+ capabilities: [][]const u8 = &[_][]const u8{},
+ extensions: [][]const u8 = &[_][]const u8{},
+ version: ?[]const u8 = null,
+
+ lastVersion: ?[]const u8 = null,
+};
+
+pub const Operand = struct {
+ kind: []const u8,
+ /// If this field is 'null', the operand is only expected once.
+ quantifier: ?Quantifier = null,
+ name: []const u8 = "",
+};
+
+pub const Quantifier = enum {
+ /// zero or once
+ @"?",
+ /// zero or more
+ @"*",
+};
+
+pub const OperandCategory = enum {
+ BitEnum,
+ ValueEnum,
+ Id,
+ Literal,
+ Composite,
+};
+
+pub const OperandKind = struct {
+ category: OperandCategory,
+ /// The name
+ kind: []const u8,
+ doc: ?[]const u8 = null,
+ enumerants: ?[]Enumerant = null,
+ bases: ?[]const []const u8 = null,
+};
+
+pub const Enumerant = struct {
+ enumerant: []const u8,
+ value: union(enum) {
+ bitflag: []const u8, // Hexadecimal representation of the value
+ int: u31,
+ },
+ capabilities: [][]const u8 = &[_][]const u8{},
+ /// Valid for .ValueEnum and .BitEnum
+ extensions: [][]const u8 = &[_][]const u8{},
+ /// `quantifier` will always be `null`.
+ parameters: []Operand = &[_]Operand{},
+ version: ?[]const u8 = null,
+ lastVersion: ?[]const u8 = null,
+};
tools/gen_spirv_spec.zig
@@ -1,97 +1,7 @@
const std = @import("std");
+const g = @import("spirv/grammar.zig");
const Writer = std.ArrayList(u8).Writer;
-//! See https://www.khronos.org/registry/spir-v/specs/unified1/MachineReadableGrammar.html
-//! and the files in https://github.com/KhronosGroup/SPIRV-Headers/blob/master/include/spirv/unified1/
-//! Note: Non-canonical casing in these structs used to match SPIR-V spec json.
-const Registry = union(enum) {
- core: CoreRegistry,
- extension: ExtensionRegistry,
-};
-
-const CoreRegistry = struct {
- copyright: [][]const u8,
- /// Hexadecimal representation of the magic number
- magic_number: []const u8,
- major_version: u32,
- minor_version: u32,
- revision: u32,
- instruction_printing_class: []InstructionPrintingClass,
- instructions: []Instruction,
- operand_kinds: []OperandKind,
-};
-
-const ExtensionRegistry = struct {
- copyright: [][]const u8,
- version: u32,
- revision: u32,
- instructions: []Instruction,
- operand_kinds: []OperandKind = &[_]OperandKind{},
-};
-
-const InstructionPrintingClass = struct {
- tag: []const u8,
- heading: ?[]const u8 = null,
-};
-
-const Instruction = struct {
- opname: []const u8,
- class: ?[]const u8 = null, // Note: Only available in the core registry.
- opcode: u32,
- operands: []Operand = &[_]Operand{},
- capabilities: [][]const u8 = &[_][]const u8{},
- extensions: [][]const u8 = &[_][]const u8{},
- version: ?[]const u8 = null,
-
- lastVersion: ?[]const u8 = null,
-};
-
-const Operand = struct {
- kind: []const u8,
- /// If this field is 'null', the operand is only expected once.
- quantifier: ?Quantifier = null,
- name: []const u8 = "",
-};
-
-const Quantifier = enum {
- /// zero or once
- @"?",
- /// zero or more
- @"*",
-};
-
-const OperandCategory = enum {
- BitEnum,
- ValueEnum,
- Id,
- Literal,
- Composite,
-};
-
-const OperandKind = struct {
- category: OperandCategory,
- /// The name
- kind: []const u8,
- doc: ?[]const u8 = null,
- enumerants: ?[]Enumerant = null,
- bases: ?[]const []const u8 = null,
-};
-
-const Enumerant = struct {
- enumerant: []const u8,
- value: union(enum) {
- bitflag: []const u8, // Hexadecimal representation of the value
- int: u31,
- },
- capabilities: [][]const u8 = &[_][]const u8{},
- /// Valid for .ValueEnum and .BitEnum
- extensions: [][]const u8 = &[_][]const u8{},
- /// `quantifier` will always be `null`.
- parameters: []Operand = &[_]Operand{},
- version: ?[]const u8 = null,
- lastVersion: ?[]const u8 = null,
-};
-
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
@@ -106,7 +16,7 @@ pub fn main() !void {
const spec = try std.fs.cwd().readFileAlloc(allocator, spec_path, std.math.maxInt(usize));
var tokens = std.json.TokenStream.init(spec);
- var registry = try std.json.parse(Registry, &tokens, .{.allocator = allocator});
+ var registry = try std.json.parse(g.Registry, &tokens, .{.allocator = allocator});
var buf = std.ArrayList(u8).init(allocator);
defer buf.deinit();
@@ -118,7 +28,7 @@ pub fn main() !void {
try std.io.getStdOut().writeAll(formatted);
}
-fn render(writer: Writer, registry: Registry) !void {
+fn render(writer: Writer, registry: g.Registry) !void {
try writer.writeAll(
\\//! This file is auto-generated by tools/gen_spirv_spec.zig.
\\
@@ -149,7 +59,7 @@ fn render(writer: Writer, registry: Registry) !void {
}
}
-fn renderOpcodes(writer: Writer, instructions: []const Instruction) !void {
+fn renderOpcodes(writer: Writer, instructions: []const g.Instruction) !void {
try writer.writeAll("pub const Opcode = extern enum(u16) {\n");
for (instructions) |instr| {
try writer.print("{} = {},\n", .{ std.zig.fmtId(instr.opname), instr.opcode });
@@ -157,7 +67,7 @@ fn renderOpcodes(writer: Writer, instructions: []const Instruction) !void {
try writer.writeAll("_,\n};\n");
}
-fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {
+fn renderOperandKinds(writer: Writer, kinds: []const g.OperandKind) !void {
for (kinds) |kind| {
switch (kind.category) {
.ValueEnum => try renderValueEnum(writer, kind),
@@ -167,7 +77,7 @@ fn renderOperandKinds(writer: Writer, kinds: []const OperandKind) !void {
}
}
-fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {
+fn renderValueEnum(writer: Writer, enumeration: g.OperandKind) !void {
try writer.print("pub const {s} = extern enum(u32) {{\n", .{ enumeration.kind });
const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;
@@ -180,7 +90,7 @@ fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {
try writer.writeAll("_,\n};\n");
}
-fn renderBitEnum(writer: Writer, enumeration: OperandKind) !void {
+fn renderBitEnum(writer: Writer, enumeration: g.OperandKind) !void {
try writer.print("pub const {s} = packed struct {{\n", .{ enumeration.kind });
var flags_by_bitpos = [_]?[]const u8{null} ** 32;