mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
SPIR-V: Split out registry from gen_spirv_spec.zig
This commit is contained in:
parent
42f2ff6ec9
commit
25329ca852
2 changed files with 97 additions and 97 deletions
|
|
@ -1,97 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const g = @import("spirv/grammar.zig");
|
||||||
const Writer = std.ArrayList(u8).Writer;
|
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 {
|
pub fn main() !void {
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
defer arena.deinit();
|
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));
|
const spec = try std.fs.cwd().readFileAlloc(allocator, spec_path, std.math.maxInt(usize));
|
||||||
|
|
||||||
var tokens = std.json.TokenStream.init(spec);
|
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);
|
var buf = std.ArrayList(u8).init(allocator);
|
||||||
defer buf.deinit();
|
defer buf.deinit();
|
||||||
|
|
@ -118,7 +28,7 @@ pub fn main() !void {
|
||||||
try std.io.getStdOut().writeAll(formatted);
|
try std.io.getStdOut().writeAll(formatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(writer: Writer, registry: Registry) !void {
|
fn render(writer: Writer, registry: g.Registry) !void {
|
||||||
try writer.writeAll(
|
try writer.writeAll(
|
||||||
\\//! This file is auto-generated by tools/gen_spirv_spec.zig.
|
\\//! 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");
|
try writer.writeAll("pub const Opcode = extern enum(u16) {\n");
|
||||||
for (instructions) |instr| {
|
for (instructions) |instr| {
|
||||||
try writer.print("{} = {},\n", .{ std.zig.fmtId(instr.opname), instr.opcode });
|
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");
|
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| {
|
for (kinds) |kind| {
|
||||||
switch (kind.category) {
|
switch (kind.category) {
|
||||||
.ValueEnum => try renderValueEnum(writer, kind),
|
.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 });
|
try writer.print("pub const {s} = extern enum(u32) {{\n", .{ enumeration.kind });
|
||||||
|
|
||||||
const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;
|
const enumerants = enumeration.enumerants orelse return error.InvalidRegistry;
|
||||||
|
|
@ -180,7 +90,7 @@ fn renderValueEnum(writer: Writer, enumeration: OperandKind) !void {
|
||||||
try writer.writeAll("_,\n};\n");
|
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 });
|
try writer.print("pub const {s} = packed struct {{\n", .{ enumeration.kind });
|
||||||
|
|
||||||
var flags_by_bitpos = [_]?[]const u8{null} ** 32;
|
var flags_by_bitpos = [_]?[]const u8{null} ** 32;
|
||||||
|
|
|
||||||
90
tools/spirv/grammar.zig
Normal file
90
tools/spirv/grammar.zig
Normal file
|
|
@ -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,
|
||||||
|
};
|
||||||
Loading…
Add table
Reference in a new issue