mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
spirv: define and use extended instruction set opcodes
This commit is contained in:
+291
-288
@@ -16,7 +16,7 @@ const Assembler = @This();
|
||||
cg: *CodeGen,
|
||||
errors: std.ArrayListUnmanaged(ErrorMsg) = .empty,
|
||||
src: []const u8 = undefined,
|
||||
/// `self.src` tokenized.
|
||||
/// `ass.src` tokenized.
|
||||
tokens: std.ArrayListUnmanaged(Token) = .empty,
|
||||
current_token: u32 = 0,
|
||||
/// The instruction that is currently being parsed or has just been parsed.
|
||||
@@ -25,8 +25,8 @@ inst: struct {
|
||||
operands: std.ArrayListUnmanaged(Operand) = .empty,
|
||||
string_bytes: std.ArrayListUnmanaged(u8) = .empty,
|
||||
|
||||
fn result(self: @This()) ?AsmValue.Ref {
|
||||
for (self.operands.items[0..@min(self.operands.items.len, 2)]) |op| {
|
||||
fn result(ass: @This()) ?AsmValue.Ref {
|
||||
for (ass.operands.items[0..@min(ass.operands.items.len, 2)]) |op| {
|
||||
switch (op) {
|
||||
.result_id => |index| return index,
|
||||
else => {},
|
||||
@@ -55,42 +55,42 @@ const Operand = union(enum) {
|
||||
string: u32,
|
||||
};
|
||||
|
||||
pub fn deinit(self: *Assembler) void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
for (self.errors.items) |err| gpa.free(err.msg);
|
||||
self.tokens.deinit(gpa);
|
||||
self.errors.deinit(gpa);
|
||||
self.inst.operands.deinit(gpa);
|
||||
self.inst.string_bytes.deinit(gpa);
|
||||
self.value_map.deinit(gpa);
|
||||
self.inst_map.deinit(gpa);
|
||||
pub fn deinit(ass: *Assembler) void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
for (ass.errors.items) |err| gpa.free(err.msg);
|
||||
ass.tokens.deinit(gpa);
|
||||
ass.errors.deinit(gpa);
|
||||
ass.inst.operands.deinit(gpa);
|
||||
ass.inst.string_bytes.deinit(gpa);
|
||||
ass.value_map.deinit(gpa);
|
||||
ass.inst_map.deinit(gpa);
|
||||
}
|
||||
|
||||
const Error = error{ AssembleFail, OutOfMemory };
|
||||
|
||||
pub fn assemble(self: *Assembler, src: []const u8) Error!void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
pub fn assemble(ass: *Assembler, src: []const u8) Error!void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
self.src = src;
|
||||
self.errors.clearRetainingCapacity();
|
||||
ass.src = src;
|
||||
ass.errors.clearRetainingCapacity();
|
||||
|
||||
// Populate the opcode map if it isn't already
|
||||
if (self.inst_map.count() == 0) {
|
||||
if (ass.inst_map.count() == 0) {
|
||||
const instructions = spec.InstructionSet.core.instructions();
|
||||
try self.inst_map.ensureUnusedCapacity(gpa, @intCast(instructions.len));
|
||||
try ass.inst_map.ensureUnusedCapacity(gpa, @intCast(instructions.len));
|
||||
for (spec.InstructionSet.core.instructions(), 0..) |inst, i| {
|
||||
const entry = try self.inst_map.getOrPut(gpa, inst.name);
|
||||
const entry = try ass.inst_map.getOrPut(gpa, inst.name);
|
||||
assert(entry.index == i);
|
||||
}
|
||||
}
|
||||
|
||||
try self.tokenize();
|
||||
while (!self.testToken(.eof)) {
|
||||
try self.parseInstruction();
|
||||
try self.processInstruction();
|
||||
try ass.tokenize();
|
||||
while (!ass.testToken(.eof)) {
|
||||
try ass.parseInstruction();
|
||||
try ass.processInstruction();
|
||||
}
|
||||
|
||||
if (self.errors.items.len > 0) return error.AssembleFail;
|
||||
if (ass.errors.items.len > 0) return error.AssembleFail;
|
||||
}
|
||||
|
||||
const ErrorMsg = struct {
|
||||
@@ -99,23 +99,23 @@ const ErrorMsg = struct {
|
||||
msg: []const u8,
|
||||
};
|
||||
|
||||
fn addError(self: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn addError(ass: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
const msg = try std.fmt.allocPrint(gpa, fmt, args);
|
||||
errdefer gpa.free(msg);
|
||||
try self.errors.append(gpa, .{
|
||||
try ass.errors.append(gpa, .{
|
||||
.byte_offset = offset,
|
||||
.msg = msg,
|
||||
});
|
||||
}
|
||||
|
||||
fn fail(self: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) Error {
|
||||
try self.addError(offset, fmt, args);
|
||||
fn fail(ass: *Assembler, offset: u32, comptime fmt: []const u8, args: anytype) Error {
|
||||
try ass.addError(offset, fmt, args);
|
||||
return error.AssembleFail;
|
||||
}
|
||||
|
||||
fn todo(self: *Assembler, comptime fmt: []const u8, args: anytype) Error {
|
||||
return self.fail(0, "todo: " ++ fmt, args);
|
||||
fn todo(ass: *Assembler, comptime fmt: []const u8, args: anytype) Error {
|
||||
return ass.fail(0, "todo: " ++ fmt, args);
|
||||
}
|
||||
|
||||
const AsmValue = union(enum) {
|
||||
@@ -139,8 +139,8 @@ const AsmValue = union(enum) {
|
||||
/// Retrieve the result-id of this AsmValue. Asserts that this AsmValue
|
||||
/// is of a variant that allows the result to be obtained (not an unresolved
|
||||
/// forward declaration, not in the process of being declared, etc).
|
||||
pub fn resultId(self: AsmValue) Id {
|
||||
return switch (self) {
|
||||
pub fn resultId(value: AsmValue) Id {
|
||||
return switch (value) {
|
||||
.just_declared,
|
||||
.unresolved_forward_reference,
|
||||
// TODO: Lower this value as constant?
|
||||
@@ -153,61 +153,62 @@ const AsmValue = union(enum) {
|
||||
}
|
||||
};
|
||||
|
||||
/// Attempt to process the instruction currently in `self.inst`.
|
||||
/// Attempt to process the instruction currently in `ass.inst`.
|
||||
/// This for example emits the instruction in the module or function, or
|
||||
/// records type definitions.
|
||||
/// If this function returns `error.AssembleFail`, an explanatory
|
||||
/// error message has already been emitted into `self.errors`.
|
||||
fn processInstruction(self: *Assembler) !void {
|
||||
const module = self.cg.module;
|
||||
const result: AsmValue = switch (self.inst.opcode) {
|
||||
/// error message has already been emitted into `ass.errors`.
|
||||
fn processInstruction(ass: *Assembler) !void {
|
||||
const module = ass.cg.module;
|
||||
const result: AsmValue = switch (ass.inst.opcode) {
|
||||
.OpEntryPoint => {
|
||||
return self.fail(self.currentToken().start, "cannot export entry points in assembly", .{});
|
||||
return ass.fail(ass.currentToken().start, "cannot export entry points in assembly", .{});
|
||||
},
|
||||
.OpExecutionMode, .OpExecutionModeId => {
|
||||
return self.fail(self.currentToken().start, "cannot set execution mode in assembly", .{});
|
||||
return ass.fail(ass.currentToken().start, "cannot set execution mode in assembly", .{});
|
||||
},
|
||||
.OpCapability => {
|
||||
try module.addCapability(@enumFromInt(self.inst.operands.items[0].value));
|
||||
try module.addCapability(@enumFromInt(ass.inst.operands.items[0].value));
|
||||
return;
|
||||
},
|
||||
.OpExtension => {
|
||||
const ext_name_offset = self.inst.operands.items[0].string;
|
||||
const ext_name = std.mem.sliceTo(self.inst.string_bytes.items[ext_name_offset..], 0);
|
||||
const ext_name_offset = ass.inst.operands.items[0].string;
|
||||
const ext_name = std.mem.sliceTo(ass.inst.string_bytes.items[ext_name_offset..], 0);
|
||||
try module.addExtension(ext_name);
|
||||
return;
|
||||
},
|
||||
.OpExtInstImport => blk: {
|
||||
const set_name_offset = self.inst.operands.items[1].string;
|
||||
const set_name = std.mem.sliceTo(self.inst.string_bytes.items[set_name_offset..], 0);
|
||||
const set_name_offset = ass.inst.operands.items[1].string;
|
||||
const set_name = std.mem.sliceTo(ass.inst.string_bytes.items[set_name_offset..], 0);
|
||||
const set_tag = std.meta.stringToEnum(spec.InstructionSet, set_name) orelse {
|
||||
return self.fail(set_name_offset, "unknown instruction set: {s}", .{set_name});
|
||||
return ass.fail(set_name_offset, "unknown instruction set: {s}", .{set_name});
|
||||
};
|
||||
break :blk .{ .value = try module.importInstructionSet(set_tag) };
|
||||
},
|
||||
else => switch (self.inst.opcode.class()) {
|
||||
.type_declaration => try self.processTypeInstruction(),
|
||||
else => (try self.processGenericInstruction()) orelse return,
|
||||
else => switch (ass.inst.opcode.class()) {
|
||||
.type_declaration => try ass.processTypeInstruction(),
|
||||
else => (try ass.processGenericInstruction()) orelse return,
|
||||
},
|
||||
};
|
||||
|
||||
const result_ref = self.inst.result().?;
|
||||
switch (self.value_map.values()[result_ref]) {
|
||||
.just_declared => self.value_map.values()[result_ref] = result,
|
||||
const result_ref = ass.inst.result().?;
|
||||
switch (ass.value_map.values()[result_ref]) {
|
||||
.just_declared => ass.value_map.values()[result_ref] = result,
|
||||
else => {
|
||||
// TODO: Improve source location.
|
||||
const name = self.value_map.keys()[result_ref];
|
||||
return self.fail(0, "duplicate definition of %{s}", .{name});
|
||||
const name = ass.value_map.keys()[result_ref];
|
||||
return ass.fail(0, "duplicate definition of %{s}", .{name});
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
const gpa = self.cg.module.gpa;
|
||||
const module = self.cg.module;
|
||||
const operands = self.inst.operands.items;
|
||||
fn processTypeInstruction(ass: *Assembler) !AsmValue {
|
||||
const cg = ass.cg;
|
||||
const gpa = cg.module.gpa;
|
||||
const module = cg.module;
|
||||
const operands = ass.inst.operands.items;
|
||||
const section = &module.sections.globals;
|
||||
const id = switch (self.inst.opcode) {
|
||||
const id = switch (ass.inst.opcode) {
|
||||
.OpTypeVoid => try module.voidType(),
|
||||
.OpTypeBool => try module.boolType(),
|
||||
.OpTypeInt => blk: {
|
||||
@@ -216,11 +217,11 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
1 => .signed,
|
||||
else => {
|
||||
// TODO: Improve source location.
|
||||
return self.fail(0, "{} is not a valid signedness (expected 0 or 1)", .{operands[2].literal32});
|
||||
return ass.fail(0, "{} is not a valid signedness (expected 0 or 1)", .{operands[2].literal32});
|
||||
},
|
||||
};
|
||||
const width = std.math.cast(u16, operands[1].literal32) orelse {
|
||||
return self.fail(0, "int type of {} bits is too large", .{operands[1].literal32});
|
||||
return ass.fail(0, "int type of {} bits is too large", .{operands[1].literal32});
|
||||
};
|
||||
break :blk try module.intType(signedness, width);
|
||||
},
|
||||
@@ -229,22 +230,22 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
switch (bits) {
|
||||
16, 32, 64 => {},
|
||||
else => {
|
||||
return self.fail(0, "{} is not a valid bit count for floats (expected 16, 32 or 64)", .{bits});
|
||||
return ass.fail(0, "{} is not a valid bit count for floats (expected 16, 32 or 64)", .{bits});
|
||||
},
|
||||
}
|
||||
break :blk try module.floatType(@intCast(bits));
|
||||
},
|
||||
.OpTypeVector => blk: {
|
||||
const child_type = try self.resolveRefId(operands[1].ref_id);
|
||||
const child_type = try ass.resolveRefId(operands[1].ref_id);
|
||||
break :blk try module.vectorType(operands[2].literal32, child_type);
|
||||
},
|
||||
.OpTypeArray => {
|
||||
// TODO: The length of an OpTypeArray is determined by a constant (which may be a spec constant),
|
||||
// and so some consideration must be taken when entering this in the type system.
|
||||
return self.todo("process OpTypeArray", .{});
|
||||
return ass.todo("process OpTypeArray", .{});
|
||||
},
|
||||
.OpTypeRuntimeArray => blk: {
|
||||
const element_type = try self.resolveRefId(operands[1].ref_id);
|
||||
const element_type = try ass.resolveRefId(operands[1].ref_id);
|
||||
const result_id = module.allocId();
|
||||
try section.emit(module.gpa, .OpTypeRuntimeArray, .{
|
||||
.id_result = result_id,
|
||||
@@ -254,7 +255,7 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
},
|
||||
.OpTypePointer => blk: {
|
||||
const storage_class: StorageClass = @enumFromInt(operands[1].value);
|
||||
const child_type = try self.resolveRefId(operands[2].ref_id);
|
||||
const child_type = try ass.resolveRefId(operands[2].ref_id);
|
||||
const result_id = module.allocId();
|
||||
try section.emit(module.gpa, .OpTypePointer, .{
|
||||
.id_result = result_id,
|
||||
@@ -264,13 +265,14 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
break :blk result_id;
|
||||
},
|
||||
.OpTypeStruct => blk: {
|
||||
const ids = try gpa.alloc(Id, operands[1..].len);
|
||||
defer gpa.free(ids);
|
||||
for (operands[1..], ids) |op, *id| id.* = try self.resolveRefId(op.ref_id);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const ids = try cg.id_scratch.addManyAsSlice(gpa, operands[1..].len);
|
||||
for (operands[1..], ids) |op, *id| id.* = try ass.resolveRefId(op.ref_id);
|
||||
break :blk try module.structType(ids, null, null, .none);
|
||||
},
|
||||
.OpTypeImage => blk: {
|
||||
const sampled_type = try self.resolveRefId(operands[1].ref_id);
|
||||
const sampled_type = try ass.resolveRefId(operands[1].ref_id);
|
||||
const result_id = module.allocId();
|
||||
try section.emit(gpa, .OpTypeImage, .{
|
||||
.id_result = result_id,
|
||||
@@ -290,19 +292,21 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
break :blk result_id;
|
||||
},
|
||||
.OpTypeSampledImage => blk: {
|
||||
const image_type = try self.resolveRefId(operands[1].ref_id);
|
||||
const image_type = try ass.resolveRefId(operands[1].ref_id);
|
||||
const result_id = module.allocId();
|
||||
try section.emit(gpa, .OpTypeSampledImage, .{ .id_result = result_id, .image_type = image_type });
|
||||
break :blk result_id;
|
||||
},
|
||||
.OpTypeFunction => blk: {
|
||||
const param_operands = operands[2..];
|
||||
const return_type = try self.resolveRefId(operands[1].ref_id);
|
||||
const return_type = try ass.resolveRefId(operands[1].ref_id);
|
||||
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const param_types = try cg.id_scratch.addManyAsSlice(gpa, param_operands.len);
|
||||
|
||||
const param_types = try module.gpa.alloc(Id, param_operands.len);
|
||||
defer module.gpa.free(param_types);
|
||||
for (param_types, param_operands) |*param, operand| {
|
||||
param.* = try self.resolveRefId(operand.ref_id);
|
||||
param.* = try ass.resolveRefId(operand.ref_id);
|
||||
}
|
||||
const result_id = module.allocId();
|
||||
try section.emit(module.gpa, .OpTypeFunction, .{
|
||||
@@ -312,7 +316,7 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
});
|
||||
break :blk result_id;
|
||||
},
|
||||
else => return self.todo("process type instruction {s}", .{@tagName(self.inst.opcode)}),
|
||||
else => return ass.todo("process type instruction {s}", .{@tagName(ass.inst.opcode)}),
|
||||
};
|
||||
|
||||
return .{ .ty = id };
|
||||
@@ -320,31 +324,30 @@ fn processTypeInstruction(self: *Assembler) !AsmValue {
|
||||
|
||||
/// - No forward references are allowed in operands.
|
||||
/// - Target section is determined from instruction type.
|
||||
fn processGenericInstruction(self: *Assembler) !?AsmValue {
|
||||
const module = self.cg.module;
|
||||
fn processGenericInstruction(ass: *Assembler) !?AsmValue {
|
||||
const module = ass.cg.module;
|
||||
const target = module.zcu.getTarget();
|
||||
const operands = self.inst.operands.items;
|
||||
const operands = ass.inst.operands.items;
|
||||
var maybe_spv_decl_index: ?Decl.Index = null;
|
||||
const section = switch (self.inst.opcode.class()) {
|
||||
const section = switch (ass.inst.opcode.class()) {
|
||||
.constant_creation => &module.sections.globals,
|
||||
.annotation => &module.sections.annotations,
|
||||
.type_declaration => unreachable, // Handled elsewhere.
|
||||
else => switch (self.inst.opcode) {
|
||||
else => switch (ass.inst.opcode) {
|
||||
.OpEntryPoint => unreachable,
|
||||
.OpExecutionMode, .OpExecutionModeId => &module.sections.execution_modes,
|
||||
.OpVariable => section: {
|
||||
const storage_class: spec.StorageClass = @enumFromInt(operands[2].value);
|
||||
if (storage_class == .function) break :section &self.cg.prologue;
|
||||
if (storage_class == .function) break :section &ass.cg.prologue;
|
||||
maybe_spv_decl_index = try module.allocDecl(.global);
|
||||
if (!target.cpu.has(.spirv, .v1_4) and storage_class != .input and storage_class != .output) {
|
||||
// Before version 1.4, the interface’s storage classes are limited to the Input and Output
|
||||
break :section &module.sections.globals;
|
||||
}
|
||||
try self.cg.decl_deps.put(module.gpa, maybe_spv_decl_index.?, {});
|
||||
try module.declareDeclDeps(maybe_spv_decl_index.?, &.{});
|
||||
try ass.cg.module.decl_deps.append(module.gpa, maybe_spv_decl_index.?);
|
||||
break :section &module.sections.globals;
|
||||
},
|
||||
else => &self.cg.body,
|
||||
else => &ass.cg.body,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -374,12 +377,12 @@ fn processGenericInstruction(self: *Assembler) !?AsmValue {
|
||||
section.writeOperand(Id, maybe_result_id.?);
|
||||
},
|
||||
.ref_id => |index| {
|
||||
const result = try self.resolveRef(index);
|
||||
const result = try ass.resolveRef(index);
|
||||
try section.ensureUnusedCapacity(module.gpa, 1);
|
||||
section.writeOperand(spec.Id, result.resultId());
|
||||
},
|
||||
.string => |offset| {
|
||||
const text = std.mem.sliceTo(self.inst.string_bytes.items[offset..], 0);
|
||||
const text = std.mem.sliceTo(ass.inst.string_bytes.items[offset..], 0);
|
||||
const size = std.math.divCeil(usize, text.len + 1, @sizeOf(Word)) catch unreachable;
|
||||
try section.ensureUnusedCapacity(module.gpa, size);
|
||||
section.writeOperand(spec.LiteralString, text);
|
||||
@@ -388,74 +391,74 @@ fn processGenericInstruction(self: *Assembler) !?AsmValue {
|
||||
}
|
||||
|
||||
const actual_word_count = section.instructions.items.len - first_word;
|
||||
section.instructions.items[first_word] |= @as(u32, @as(u16, @intCast(actual_word_count))) << 16 | @intFromEnum(self.inst.opcode);
|
||||
section.instructions.items[first_word] |= @as(u32, @as(u16, @intCast(actual_word_count))) << 16 | @intFromEnum(ass.inst.opcode);
|
||||
|
||||
if (maybe_result_id) |result| return .{ .value = result };
|
||||
return null;
|
||||
}
|
||||
|
||||
fn resolveMaybeForwardRef(self: *Assembler, ref: AsmValue.Ref) !AsmValue {
|
||||
const value = self.value_map.values()[ref];
|
||||
fn resolveMaybeForwardRef(ass: *Assembler, ref: AsmValue.Ref) !AsmValue {
|
||||
const value = ass.value_map.values()[ref];
|
||||
switch (value) {
|
||||
.just_declared => {
|
||||
const name = self.value_map.keys()[ref];
|
||||
const name = ass.value_map.keys()[ref];
|
||||
// TODO: Improve source location.
|
||||
return self.fail(0, "self-referential parameter %{s}", .{name});
|
||||
return ass.fail(0, "ass-referential parameter %{s}", .{name});
|
||||
},
|
||||
else => return value,
|
||||
}
|
||||
}
|
||||
|
||||
fn resolveRef(self: *Assembler, ref: AsmValue.Ref) !AsmValue {
|
||||
const value = try self.resolveMaybeForwardRef(ref);
|
||||
fn resolveRef(ass: *Assembler, ref: AsmValue.Ref) !AsmValue {
|
||||
const value = try ass.resolveMaybeForwardRef(ref);
|
||||
switch (value) {
|
||||
.just_declared => unreachable,
|
||||
.unresolved_forward_reference => {
|
||||
const name = self.value_map.keys()[ref];
|
||||
const name = ass.value_map.keys()[ref];
|
||||
// TODO: Improve source location.
|
||||
return self.fail(0, "reference to undeclared result-id %{s}", .{name});
|
||||
return ass.fail(0, "reference to undeclared result-id %{s}", .{name});
|
||||
},
|
||||
else => return value,
|
||||
}
|
||||
}
|
||||
|
||||
fn resolveRefId(self: *Assembler, ref: AsmValue.Ref) !Id {
|
||||
const value = try self.resolveRef(ref);
|
||||
fn resolveRefId(ass: *Assembler, ref: AsmValue.Ref) !Id {
|
||||
const value = try ass.resolveRef(ref);
|
||||
return value.resultId();
|
||||
}
|
||||
|
||||
fn parseInstruction(self: *Assembler) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseInstruction(ass: *Assembler) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
self.inst.opcode = undefined;
|
||||
self.inst.operands.clearRetainingCapacity();
|
||||
self.inst.string_bytes.clearRetainingCapacity();
|
||||
ass.inst.opcode = undefined;
|
||||
ass.inst.operands.clearRetainingCapacity();
|
||||
ass.inst.string_bytes.clearRetainingCapacity();
|
||||
|
||||
const lhs_result_tok = self.currentToken();
|
||||
const maybe_lhs_result: ?AsmValue.Ref = if (self.eatToken(.result_id_assign)) blk: {
|
||||
const name = self.tokenText(lhs_result_tok)[1..];
|
||||
const entry = try self.value_map.getOrPut(gpa, name);
|
||||
try self.expectToken(.equals);
|
||||
const lhs_result_tok = ass.currentToken();
|
||||
const maybe_lhs_result: ?AsmValue.Ref = if (ass.eatToken(.result_id_assign)) blk: {
|
||||
const name = ass.tokenText(lhs_result_tok)[1..];
|
||||
const entry = try ass.value_map.getOrPut(gpa, name);
|
||||
try ass.expectToken(.equals);
|
||||
if (!entry.found_existing) {
|
||||
entry.value_ptr.* = .just_declared;
|
||||
}
|
||||
break :blk @intCast(entry.index);
|
||||
} else null;
|
||||
|
||||
const opcode_tok = self.currentToken();
|
||||
const opcode_tok = ass.currentToken();
|
||||
if (maybe_lhs_result != null) {
|
||||
try self.expectToken(.opcode);
|
||||
} else if (!self.eatToken(.opcode)) {
|
||||
return self.fail(opcode_tok.start, "expected start of instruction, found {s}", .{opcode_tok.tag.name()});
|
||||
try ass.expectToken(.opcode);
|
||||
} else if (!ass.eatToken(.opcode)) {
|
||||
return ass.fail(opcode_tok.start, "expected start of instruction, found {s}", .{opcode_tok.tag.name()});
|
||||
}
|
||||
|
||||
const opcode_text = self.tokenText(opcode_tok);
|
||||
const index = self.inst_map.getIndex(opcode_text) orelse {
|
||||
return self.fail(opcode_tok.start, "invalid opcode '{s}'", .{opcode_text});
|
||||
const opcode_text = ass.tokenText(opcode_tok);
|
||||
const index = ass.inst_map.getIndex(opcode_text) orelse {
|
||||
return ass.fail(opcode_tok.start, "invalid opcode '{s}'", .{opcode_text});
|
||||
};
|
||||
|
||||
const inst = spec.InstructionSet.core.instructions()[index];
|
||||
self.inst.opcode = @enumFromInt(inst.opcode);
|
||||
ass.inst.opcode = @enumFromInt(inst.opcode);
|
||||
|
||||
const expected_operands = inst.operands;
|
||||
// This is a loop because the result-id is not always the first operand.
|
||||
@@ -464,67 +467,67 @@ fn parseInstruction(self: *Assembler) !void {
|
||||
} else false;
|
||||
|
||||
if (requires_lhs_result and maybe_lhs_result == null) {
|
||||
return self.fail(opcode_tok.start, "opcode '{s}' expects result on left-hand side", .{@tagName(self.inst.opcode)});
|
||||
return ass.fail(opcode_tok.start, "opcode '{s}' expects result on left-hand side", .{@tagName(ass.inst.opcode)});
|
||||
} else if (!requires_lhs_result and maybe_lhs_result != null) {
|
||||
return self.fail(
|
||||
return ass.fail(
|
||||
lhs_result_tok.start,
|
||||
"opcode '{s}' does not expect a result-id on the left-hand side",
|
||||
.{@tagName(self.inst.opcode)},
|
||||
.{@tagName(ass.inst.opcode)},
|
||||
);
|
||||
}
|
||||
|
||||
for (expected_operands) |operand| {
|
||||
if (operand.kind == .id_result) {
|
||||
try self.inst.operands.append(gpa, .{ .result_id = maybe_lhs_result.? });
|
||||
try ass.inst.operands.append(gpa, .{ .result_id = maybe_lhs_result.? });
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (operand.quantifier) {
|
||||
.required => if (self.isAtInstructionBoundary()) {
|
||||
return self.fail(
|
||||
self.currentToken().start,
|
||||
.required => if (ass.isAtInstructionBoundary()) {
|
||||
return ass.fail(
|
||||
ass.currentToken().start,
|
||||
"missing required operand", // TODO: Operand name?
|
||||
.{},
|
||||
);
|
||||
} else {
|
||||
try self.parseOperand(operand.kind);
|
||||
try ass.parseOperand(operand.kind);
|
||||
},
|
||||
.optional => if (!self.isAtInstructionBoundary()) {
|
||||
try self.parseOperand(operand.kind);
|
||||
.optional => if (!ass.isAtInstructionBoundary()) {
|
||||
try ass.parseOperand(operand.kind);
|
||||
},
|
||||
.variadic => while (!self.isAtInstructionBoundary()) {
|
||||
try self.parseOperand(operand.kind);
|
||||
.variadic => while (!ass.isAtInstructionBoundary()) {
|
||||
try ass.parseOperand(operand.kind);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parseOperand(self: *Assembler, kind: spec.OperandKind) Error!void {
|
||||
fn parseOperand(ass: *Assembler, kind: spec.OperandKind) Error!void {
|
||||
switch (kind.category()) {
|
||||
.bit_enum => try self.parseBitEnum(kind),
|
||||
.value_enum => try self.parseValueEnum(kind),
|
||||
.id => try self.parseRefId(),
|
||||
.bit_enum => try ass.parseBitEnum(kind),
|
||||
.value_enum => try ass.parseValueEnum(kind),
|
||||
.id => try ass.parseRefId(),
|
||||
else => switch (kind) {
|
||||
.literal_integer => try self.parseLiteralInteger(),
|
||||
.literal_string => try self.parseString(),
|
||||
.literal_context_dependent_number => try self.parseContextDependentNumber(),
|
||||
.literal_ext_inst_integer => try self.parseLiteralExtInstInteger(),
|
||||
.pair_id_ref_id_ref => try self.parsePhiSource(),
|
||||
else => return self.todo("parse operand of type {s}", .{@tagName(kind)}),
|
||||
.literal_integer => try ass.parseLiteralInteger(),
|
||||
.literal_string => try ass.parseString(),
|
||||
.literal_context_dependent_number => try ass.parseContextDependentNumber(),
|
||||
.literal_ext_inst_integer => try ass.parseLiteralExtInstInteger(),
|
||||
.pair_id_ref_id_ref => try ass.parsePhiSource(),
|
||||
else => return ass.todo("parse operand of type {s}", .{@tagName(kind)}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Also handles parsing any required extra operands.
|
||||
fn parseBitEnum(self: *Assembler, kind: spec.OperandKind) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseBitEnum(ass: *Assembler, kind: spec.OperandKind) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
var tok = self.currentToken();
|
||||
try self.expectToken(.value);
|
||||
var tok = ass.currentToken();
|
||||
try ass.expectToken(.value);
|
||||
|
||||
var text = self.tokenText(tok);
|
||||
var text = ass.tokenText(tok);
|
||||
if (std.mem.eql(u8, text, "None")) {
|
||||
try self.inst.operands.append(gpa, .{ .value = 0 });
|
||||
try ass.inst.operands.append(gpa, .{ .value = 0 });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -535,18 +538,18 @@ fn parseBitEnum(self: *Assembler, kind: spec.OperandKind) !void {
|
||||
if (std.mem.eql(u8, enumerant.name, text))
|
||||
break enumerant;
|
||||
} else {
|
||||
return self.fail(tok.start, "'{s}' is not a valid flag for bitmask {s}", .{ text, @tagName(kind) });
|
||||
return ass.fail(tok.start, "'{s}' is not a valid flag for bitmask {s}", .{ text, @tagName(kind) });
|
||||
};
|
||||
mask |= enumerant.value;
|
||||
if (!self.eatToken(.pipe))
|
||||
if (!ass.eatToken(.pipe))
|
||||
break;
|
||||
|
||||
tok = self.currentToken();
|
||||
try self.expectToken(.value);
|
||||
text = self.tokenText(tok);
|
||||
tok = ass.currentToken();
|
||||
try ass.expectToken(.value);
|
||||
text = ass.tokenText(tok);
|
||||
}
|
||||
|
||||
try self.inst.operands.append(gpa, .{ .value = mask });
|
||||
try ass.inst.operands.append(gpa, .{ .value = mask });
|
||||
|
||||
// Assume values are sorted.
|
||||
// TODO: ensure in generator.
|
||||
@@ -555,45 +558,45 @@ fn parseBitEnum(self: *Assembler, kind: spec.OperandKind) !void {
|
||||
continue;
|
||||
|
||||
for (enumerant.parameters) |param_kind| {
|
||||
if (self.isAtInstructionBoundary()) {
|
||||
return self.fail(self.currentToken().start, "missing required parameter for bit flag '{s}'", .{enumerant.name});
|
||||
if (ass.isAtInstructionBoundary()) {
|
||||
return ass.fail(ass.currentToken().start, "missing required parameter for bit flag '{s}'", .{enumerant.name});
|
||||
}
|
||||
|
||||
try self.parseOperand(param_kind);
|
||||
try ass.parseOperand(param_kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Also handles parsing any required extra operands.
|
||||
fn parseValueEnum(self: *Assembler, kind: spec.OperandKind) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseValueEnum(ass: *Assembler, kind: spec.OperandKind) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
const tok = self.currentToken();
|
||||
if (self.eatToken(.placeholder)) {
|
||||
const name = self.tokenText(tok)[1..];
|
||||
const value = self.value_map.get(name) orelse {
|
||||
return self.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
const tok = ass.currentToken();
|
||||
if (ass.eatToken(.placeholder)) {
|
||||
const name = ass.tokenText(tok)[1..];
|
||||
const value = ass.value_map.get(name) orelse {
|
||||
return ass.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
};
|
||||
switch (value) {
|
||||
.constant => |literal32| {
|
||||
try self.inst.operands.append(gpa, .{ .value = literal32 });
|
||||
try ass.inst.operands.append(gpa, .{ .value = literal32 });
|
||||
},
|
||||
.string => |str| {
|
||||
const enumerant = for (kind.enumerants()) |enumerant| {
|
||||
if (std.mem.eql(u8, enumerant.name, str)) break enumerant;
|
||||
} else {
|
||||
return self.fail(tok.start, "'{s}' is not a valid value for enumeration {s}", .{ str, @tagName(kind) });
|
||||
return ass.fail(tok.start, "'{s}' is not a valid value for enumeration {s}", .{ str, @tagName(kind) });
|
||||
};
|
||||
try self.inst.operands.append(gpa, .{ .value = enumerant.value });
|
||||
try ass.inst.operands.append(gpa, .{ .value = enumerant.value });
|
||||
},
|
||||
else => return self.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name}),
|
||||
else => return ass.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name}),
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try self.expectToken(.value);
|
||||
try ass.expectToken(.value);
|
||||
|
||||
const text = self.tokenText(tok);
|
||||
const text = ass.tokenText(tok);
|
||||
const int_value = std.fmt.parseInt(u32, text, 0) catch null;
|
||||
const enumerant = for (kind.enumerants()) |enumerant| {
|
||||
if (int_value) |v| {
|
||||
@@ -602,131 +605,131 @@ fn parseValueEnum(self: *Assembler, kind: spec.OperandKind) !void {
|
||||
if (std.mem.eql(u8, enumerant.name, text)) break enumerant;
|
||||
}
|
||||
} else {
|
||||
return self.fail(tok.start, "'{s}' is not a valid value for enumeration {s}", .{ text, @tagName(kind) });
|
||||
return ass.fail(tok.start, "'{s}' is not a valid value for enumeration {s}", .{ text, @tagName(kind) });
|
||||
};
|
||||
|
||||
try self.inst.operands.append(gpa, .{ .value = enumerant.value });
|
||||
try ass.inst.operands.append(gpa, .{ .value = enumerant.value });
|
||||
|
||||
for (enumerant.parameters) |param_kind| {
|
||||
if (self.isAtInstructionBoundary()) {
|
||||
return self.fail(self.currentToken().start, "missing required parameter for enum variant '{s}'", .{enumerant.name});
|
||||
if (ass.isAtInstructionBoundary()) {
|
||||
return ass.fail(ass.currentToken().start, "missing required parameter for enum variant '{s}'", .{enumerant.name});
|
||||
}
|
||||
|
||||
try self.parseOperand(param_kind);
|
||||
try ass.parseOperand(param_kind);
|
||||
}
|
||||
}
|
||||
|
||||
fn parseRefId(self: *Assembler) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseRefId(ass: *Assembler) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
const tok = self.currentToken();
|
||||
try self.expectToken(.result_id);
|
||||
const tok = ass.currentToken();
|
||||
try ass.expectToken(.result_id);
|
||||
|
||||
const name = self.tokenText(tok)[1..];
|
||||
const entry = try self.value_map.getOrPut(gpa, name);
|
||||
const name = ass.tokenText(tok)[1..];
|
||||
const entry = try ass.value_map.getOrPut(gpa, name);
|
||||
if (!entry.found_existing) {
|
||||
entry.value_ptr.* = .unresolved_forward_reference;
|
||||
}
|
||||
|
||||
const index: AsmValue.Ref = @intCast(entry.index);
|
||||
try self.inst.operands.append(gpa, .{ .ref_id = index });
|
||||
try ass.inst.operands.append(gpa, .{ .ref_id = index });
|
||||
}
|
||||
|
||||
fn parseLiteralInteger(self: *Assembler) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseLiteralInteger(ass: *Assembler) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
const tok = self.currentToken();
|
||||
if (self.eatToken(.placeholder)) {
|
||||
const name = self.tokenText(tok)[1..];
|
||||
const value = self.value_map.get(name) orelse {
|
||||
return self.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
const tok = ass.currentToken();
|
||||
if (ass.eatToken(.placeholder)) {
|
||||
const name = ass.tokenText(tok)[1..];
|
||||
const value = ass.value_map.get(name) orelse {
|
||||
return ass.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
};
|
||||
switch (value) {
|
||||
.constant => |literal32| {
|
||||
try self.inst.operands.append(gpa, .{ .literal32 = literal32 });
|
||||
try ass.inst.operands.append(gpa, .{ .literal32 = literal32 });
|
||||
},
|
||||
else => {
|
||||
return self.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name});
|
||||
return ass.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name});
|
||||
},
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try self.expectToken(.value);
|
||||
try ass.expectToken(.value);
|
||||
// According to the SPIR-V machine readable grammar, a LiteralInteger
|
||||
// may consist of one or more words. From the SPIR-V docs it seems like there
|
||||
// only one instruction where multiple words are allowed, the literals that make up the
|
||||
// switch cases of OpSwitch. This case is handled separately, and so we just assume
|
||||
// everything is a 32-bit integer in this function.
|
||||
const text = self.tokenText(tok);
|
||||
const text = ass.tokenText(tok);
|
||||
const value = std.fmt.parseInt(u32, text, 0) catch {
|
||||
return self.fail(tok.start, "'{s}' is not a valid 32-bit integer literal", .{text});
|
||||
return ass.fail(tok.start, "'{s}' is not a valid 32-bit integer literal", .{text});
|
||||
};
|
||||
try self.inst.operands.append(gpa, .{ .literal32 = value });
|
||||
try ass.inst.operands.append(gpa, .{ .literal32 = value });
|
||||
}
|
||||
|
||||
fn parseLiteralExtInstInteger(self: *Assembler) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseLiteralExtInstInteger(ass: *Assembler) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
const tok = self.currentToken();
|
||||
if (self.eatToken(.placeholder)) {
|
||||
const name = self.tokenText(tok)[1..];
|
||||
const value = self.value_map.get(name) orelse {
|
||||
return self.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
const tok = ass.currentToken();
|
||||
if (ass.eatToken(.placeholder)) {
|
||||
const name = ass.tokenText(tok)[1..];
|
||||
const value = ass.value_map.get(name) orelse {
|
||||
return ass.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
};
|
||||
switch (value) {
|
||||
.constant => |literal32| {
|
||||
try self.inst.operands.append(gpa, .{ .literal32 = literal32 });
|
||||
try ass.inst.operands.append(gpa, .{ .literal32 = literal32 });
|
||||
},
|
||||
else => {
|
||||
return self.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name});
|
||||
return ass.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name});
|
||||
},
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try self.expectToken(.value);
|
||||
const text = self.tokenText(tok);
|
||||
try ass.expectToken(.value);
|
||||
const text = ass.tokenText(tok);
|
||||
const value = std.fmt.parseInt(u32, text, 0) catch {
|
||||
return self.fail(tok.start, "'{s}' is not a valid 32-bit integer literal", .{text});
|
||||
return ass.fail(tok.start, "'{s}' is not a valid 32-bit integer literal", .{text});
|
||||
};
|
||||
try self.inst.operands.append(gpa, .{ .literal32 = value });
|
||||
try ass.inst.operands.append(gpa, .{ .literal32 = value });
|
||||
}
|
||||
|
||||
fn parseString(self: *Assembler) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseString(ass: *Assembler) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
const tok = self.currentToken();
|
||||
try self.expectToken(.string);
|
||||
const tok = ass.currentToken();
|
||||
try ass.expectToken(.string);
|
||||
// Note, the string might not have a closing quote. In this case,
|
||||
// an error is already emitted but we are trying to continue processing
|
||||
// anyway, so in this function we have to deal with that situation.
|
||||
const text = self.tokenText(tok);
|
||||
const text = ass.tokenText(tok);
|
||||
assert(text.len > 0 and text[0] == '"');
|
||||
const literal = if (text.len != 1 and text[text.len - 1] == '"')
|
||||
text[1 .. text.len - 1]
|
||||
else
|
||||
text[1..];
|
||||
|
||||
const string_offset: u32 = @intCast(self.inst.string_bytes.items.len);
|
||||
try self.inst.string_bytes.ensureUnusedCapacity(gpa, literal.len + 1);
|
||||
self.inst.string_bytes.appendSliceAssumeCapacity(literal);
|
||||
self.inst.string_bytes.appendAssumeCapacity(0);
|
||||
const string_offset: u32 = @intCast(ass.inst.string_bytes.items.len);
|
||||
try ass.inst.string_bytes.ensureUnusedCapacity(gpa, literal.len + 1);
|
||||
ass.inst.string_bytes.appendSliceAssumeCapacity(literal);
|
||||
ass.inst.string_bytes.appendAssumeCapacity(0);
|
||||
|
||||
try self.inst.operands.append(gpa, .{ .string = string_offset });
|
||||
try ass.inst.operands.append(gpa, .{ .string = string_offset });
|
||||
}
|
||||
|
||||
fn parseContextDependentNumber(self: *Assembler) !void {
|
||||
const module = self.cg.module;
|
||||
fn parseContextDependentNumber(ass: *Assembler) !void {
|
||||
const module = ass.cg.module;
|
||||
|
||||
// For context dependent numbers, the actual type to parse is determined by the instruction.
|
||||
// Currently, this operand appears in OpConstant and OpSpecConstant, where the too-be-parsed type
|
||||
// is determined by the result type. That means that in this instructions we have to resolve the
|
||||
// operand type early and look at the result to see how we need to proceed.
|
||||
assert(self.inst.opcode == .OpConstant or self.inst.opcode == .OpSpecConstant);
|
||||
assert(ass.inst.opcode == .OpConstant or ass.inst.opcode == .OpSpecConstant);
|
||||
|
||||
const tok = self.currentToken();
|
||||
const result = try self.resolveRef(self.inst.operands.items[0].ref_id);
|
||||
const tok = ass.currentToken();
|
||||
const result = try ass.resolveRef(ass.inst.operands.items[0].ref_id);
|
||||
const result_id = result.resultId();
|
||||
// We are going to cheat a little bit: The types we are interested in, int and float,
|
||||
// are added to the module and cached via module.intType and module.floatType. Therefore,
|
||||
@@ -741,7 +744,7 @@ fn parseContextDependentNumber(self: *Assembler) !void {
|
||||
const id = entry.value_ptr.*;
|
||||
if (id != result_id) continue;
|
||||
const info = entry.key_ptr.*;
|
||||
return try self.parseContextDependentInt(info.signedness, info.bits);
|
||||
return try ass.parseContextDependentInt(info.signedness, info.bits);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,44 +755,44 @@ fn parseContextDependentNumber(self: *Assembler) !void {
|
||||
if (id != result_id) continue;
|
||||
const info = entry.key_ptr.*;
|
||||
switch (info.bits) {
|
||||
16 => try self.parseContextDependentFloat(16),
|
||||
32 => try self.parseContextDependentFloat(32),
|
||||
64 => try self.parseContextDependentFloat(64),
|
||||
else => return self.fail(tok.start, "cannot parse {}-bit info literal", .{info.bits}),
|
||||
16 => try ass.parseContextDependentFloat(16),
|
||||
32 => try ass.parseContextDependentFloat(32),
|
||||
64 => try ass.parseContextDependentFloat(64),
|
||||
else => return ass.fail(tok.start, "cannot parse {}-bit info literal", .{info.bits}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self.fail(tok.start, "cannot parse literal constant", .{});
|
||||
return ass.fail(tok.start, "cannot parse literal constant", .{});
|
||||
}
|
||||
|
||||
fn parseContextDependentInt(self: *Assembler, signedness: std.builtin.Signedness, width: u32) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseContextDependentInt(ass: *Assembler, signedness: std.builtin.Signedness, width: u32) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
const tok = self.currentToken();
|
||||
if (self.eatToken(.placeholder)) {
|
||||
const name = self.tokenText(tok)[1..];
|
||||
const value = self.value_map.get(name) orelse {
|
||||
return self.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
const tok = ass.currentToken();
|
||||
if (ass.eatToken(.placeholder)) {
|
||||
const name = ass.tokenText(tok)[1..];
|
||||
const value = ass.value_map.get(name) orelse {
|
||||
return ass.fail(tok.start, "invalid placeholder '${s}'", .{name});
|
||||
};
|
||||
switch (value) {
|
||||
.constant => |literal32| {
|
||||
try self.inst.operands.append(gpa, .{ .literal32 = literal32 });
|
||||
try ass.inst.operands.append(gpa, .{ .literal32 = literal32 });
|
||||
},
|
||||
else => {
|
||||
return self.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name});
|
||||
return ass.fail(tok.start, "value '{s}' cannot be used as placeholder", .{name});
|
||||
},
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try self.expectToken(.value);
|
||||
try ass.expectToken(.value);
|
||||
|
||||
if (width == 0 or width > 2 * @bitSizeOf(spec.Word)) {
|
||||
return self.fail(tok.start, "cannot parse {}-bit integer literal", .{width});
|
||||
return ass.fail(tok.start, "cannot parse {}-bit integer literal", .{width});
|
||||
}
|
||||
|
||||
const text = self.tokenText(tok);
|
||||
const text = ass.tokenText(tok);
|
||||
invalid: {
|
||||
// Just parse the integer as the next larger integer type, and check if it overflows afterwards.
|
||||
const int = std.fmt.parseInt(i128, text, 0) catch break :invalid;
|
||||
@@ -804,104 +807,104 @@ fn parseContextDependentInt(self: *Assembler, signedness: std.builtin.Signedness
|
||||
|
||||
// Note, we store the sign-extended version here.
|
||||
if (width <= @bitSizeOf(spec.Word)) {
|
||||
try self.inst.operands.append(gpa, .{ .literal32 = @truncate(@as(u128, @bitCast(int))) });
|
||||
try ass.inst.operands.append(gpa, .{ .literal32 = @truncate(@as(u128, @bitCast(int))) });
|
||||
} else {
|
||||
try self.inst.operands.append(gpa, .{ .literal64 = @truncate(@as(u128, @bitCast(int))) });
|
||||
try ass.inst.operands.append(gpa, .{ .literal64 = @truncate(@as(u128, @bitCast(int))) });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return self.fail(tok.start, "'{s}' is not a valid {s} {}-bit int literal", .{ text, @tagName(signedness), width });
|
||||
return ass.fail(tok.start, "'{s}' is not a valid {s} {}-bit int literal", .{ text, @tagName(signedness), width });
|
||||
}
|
||||
|
||||
fn parseContextDependentFloat(self: *Assembler, comptime width: u16) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
fn parseContextDependentFloat(ass: *Assembler, comptime width: u16) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
const Float = std.meta.Float(width);
|
||||
const Int = std.meta.Int(.unsigned, width);
|
||||
|
||||
const tok = self.currentToken();
|
||||
try self.expectToken(.value);
|
||||
const tok = ass.currentToken();
|
||||
try ass.expectToken(.value);
|
||||
|
||||
const text = self.tokenText(tok);
|
||||
const text = ass.tokenText(tok);
|
||||
|
||||
const value = std.fmt.parseFloat(Float, text) catch {
|
||||
return self.fail(tok.start, "'{s}' is not a valid {}-bit float literal", .{ text, width });
|
||||
return ass.fail(tok.start, "'{s}' is not a valid {}-bit float literal", .{ text, width });
|
||||
};
|
||||
|
||||
const float_bits: Int = @bitCast(value);
|
||||
if (width <= @bitSizeOf(spec.Word)) {
|
||||
try self.inst.operands.append(gpa, .{ .literal32 = float_bits });
|
||||
try ass.inst.operands.append(gpa, .{ .literal32 = float_bits });
|
||||
} else {
|
||||
assert(width <= 2 * @bitSizeOf(spec.Word));
|
||||
try self.inst.operands.append(gpa, .{ .literal64 = float_bits });
|
||||
try ass.inst.operands.append(gpa, .{ .literal64 = float_bits });
|
||||
}
|
||||
}
|
||||
|
||||
fn parsePhiSource(self: *Assembler) !void {
|
||||
try self.parseRefId();
|
||||
if (self.isAtInstructionBoundary()) {
|
||||
return self.fail(self.currentToken().start, "missing phi block parent", .{});
|
||||
fn parsePhiSource(ass: *Assembler) !void {
|
||||
try ass.parseRefId();
|
||||
if (ass.isAtInstructionBoundary()) {
|
||||
return ass.fail(ass.currentToken().start, "missing phi block parent", .{});
|
||||
}
|
||||
try self.parseRefId();
|
||||
try ass.parseRefId();
|
||||
}
|
||||
|
||||
/// Returns whether the `current_token` cursor
|
||||
/// is currently pointing at the start of a new instruction.
|
||||
fn isAtInstructionBoundary(self: Assembler) bool {
|
||||
return switch (self.currentToken().tag) {
|
||||
fn isAtInstructionBoundary(ass: Assembler) bool {
|
||||
return switch (ass.currentToken().tag) {
|
||||
.opcode, .result_id_assign, .eof => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
fn expectToken(self: *Assembler, tag: Token.Tag) !void {
|
||||
if (self.eatToken(tag))
|
||||
fn expectToken(ass: *Assembler, tag: Token.Tag) !void {
|
||||
if (ass.eatToken(tag))
|
||||
return;
|
||||
|
||||
return self.fail(self.currentToken().start, "unexpected {s}, expected {s}", .{
|
||||
self.currentToken().tag.name(),
|
||||
return ass.fail(ass.currentToken().start, "unexpected {s}, expected {s}", .{
|
||||
ass.currentToken().tag.name(),
|
||||
tag.name(),
|
||||
});
|
||||
}
|
||||
|
||||
fn eatToken(self: *Assembler, tag: Token.Tag) bool {
|
||||
if (self.testToken(tag)) {
|
||||
self.current_token += 1;
|
||||
fn eatToken(ass: *Assembler, tag: Token.Tag) bool {
|
||||
if (ass.testToken(tag)) {
|
||||
ass.current_token += 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fn testToken(self: Assembler, tag: Token.Tag) bool {
|
||||
return self.currentToken().tag == tag;
|
||||
fn testToken(ass: Assembler, tag: Token.Tag) bool {
|
||||
return ass.currentToken().tag == tag;
|
||||
}
|
||||
|
||||
fn currentToken(self: Assembler) Token {
|
||||
return self.tokens.items[self.current_token];
|
||||
fn currentToken(ass: Assembler) Token {
|
||||
return ass.tokens.items[ass.current_token];
|
||||
}
|
||||
|
||||
fn tokenText(self: Assembler, tok: Token) []const u8 {
|
||||
return self.src[tok.start..tok.end];
|
||||
fn tokenText(ass: Assembler, tok: Token) []const u8 {
|
||||
return ass.src[tok.start..tok.end];
|
||||
}
|
||||
|
||||
/// Tokenize `self.src` and put the tokens in `self.tokens`.
|
||||
/// Any errors encountered are appended to `self.errors`.
|
||||
fn tokenize(self: *Assembler) !void {
|
||||
const gpa = self.cg.module.gpa;
|
||||
/// Tokenize `ass.src` and put the tokens in `ass.tokens`.
|
||||
/// Any errors encountered are appended to `ass.errors`.
|
||||
fn tokenize(ass: *Assembler) !void {
|
||||
const gpa = ass.cg.module.gpa;
|
||||
|
||||
self.tokens.clearRetainingCapacity();
|
||||
ass.tokens.clearRetainingCapacity();
|
||||
|
||||
var offset: u32 = 0;
|
||||
while (true) {
|
||||
const tok = try self.nextToken(offset);
|
||||
const tok = try ass.nextToken(offset);
|
||||
// Resolve result-id assignment now.
|
||||
// NOTE: If the previous token wasn't a result-id, just ignore it,
|
||||
// we will catch it while parsing.
|
||||
if (tok.tag == .equals and self.tokens.items[self.tokens.items.len - 1].tag == .result_id) {
|
||||
self.tokens.items[self.tokens.items.len - 1].tag = .result_id_assign;
|
||||
if (tok.tag == .equals and ass.tokens.items[ass.tokens.items.len - 1].tag == .result_id) {
|
||||
ass.tokens.items[ass.tokens.items.len - 1].tag = .result_id_assign;
|
||||
}
|
||||
try self.tokens.append(gpa, tok);
|
||||
try ass.tokens.append(gpa, tok);
|
||||
if (tok.tag == .eof)
|
||||
break;
|
||||
offset = tok.end;
|
||||
@@ -943,8 +946,8 @@ const Token = struct {
|
||||
/// These can be used in place of a normal `value`.
|
||||
placeholder,
|
||||
|
||||
fn name(self: Tag) []const u8 {
|
||||
return switch (self) {
|
||||
fn name(tag: Tag) []const u8 {
|
||||
return switch (tag) {
|
||||
.eof => "<end of input>",
|
||||
.result_id => "<result-id>",
|
||||
.result_id_assign => "<assigned result-id>",
|
||||
@@ -963,7 +966,7 @@ const Token = struct {
|
||||
/// that the token is surrounded by whitespace if required, but will not
|
||||
/// interpret the token yet.
|
||||
/// NOTE: This function doesn't handle .result_id_assign - this is handled in tokenize().
|
||||
fn nextToken(self: *Assembler, start_offset: u32) !Token {
|
||||
fn nextToken(ass: *Assembler, start_offset: u32) !Token {
|
||||
// We generally separate the input into the following types:
|
||||
// - Whitespace. Generally ignored, but also used as delimiter for some
|
||||
// tokens.
|
||||
@@ -989,8 +992,8 @@ fn nextToken(self: *Assembler, start_offset: u32) !Token {
|
||||
var token_start = start_offset;
|
||||
var offset = start_offset;
|
||||
var tag = Token.Tag.eof;
|
||||
while (offset < self.src.len) : (offset += 1) {
|
||||
const c = self.src[offset];
|
||||
while (offset < ass.src.len) : (offset += 1) {
|
||||
const c = ass.src[offset];
|
||||
switch (state) {
|
||||
.start => switch (c) {
|
||||
' ', '\t', '\r', '\n' => token_start = offset + 1,
|
||||
@@ -1023,7 +1026,7 @@ fn nextToken(self: *Assembler, start_offset: u32) !Token {
|
||||
},
|
||||
.value => switch (c) {
|
||||
'"' => {
|
||||
try self.addError(offset, "unexpected string literal", .{});
|
||||
try ass.addError(offset, "unexpected string literal", .{});
|
||||
// The user most likely just forgot a delimiter here - keep
|
||||
// the tag as value.
|
||||
break;
|
||||
@@ -1035,7 +1038,7 @@ fn nextToken(self: *Assembler, start_offset: u32) !Token {
|
||||
'_', 'a'...'z', 'A'...'Z', '0'...'9' => {},
|
||||
' ', '\t', '\r', '\n', '=', '|' => break,
|
||||
else => {
|
||||
try self.addError(offset, "illegal character in result-id or placeholder", .{});
|
||||
try ass.addError(offset, "illegal character in result-id or placeholder", .{});
|
||||
// Again, probably a forgotten delimiter here.
|
||||
break;
|
||||
},
|
||||
@@ -1048,7 +1051,7 @@ fn nextToken(self: *Assembler, start_offset: u32) !Token {
|
||||
.string_end => switch (c) {
|
||||
' ', '\t', '\r', '\n', '=', '|' => break,
|
||||
else => {
|
||||
try self.addError(offset, "unexpected character after string literal", .{});
|
||||
try ass.addError(offset, "unexpected character after string literal", .{});
|
||||
// The token is still unmistakibly a string.
|
||||
break;
|
||||
},
|
||||
@@ -1066,13 +1069,13 @@ fn nextToken(self: *Assembler, start_offset: u32) !Token {
|
||||
|
||||
switch (state) {
|
||||
.string, .escape => {
|
||||
try self.addError(token_start, "unterminated string", .{});
|
||||
try ass.addError(token_start, "unterminated string", .{});
|
||||
},
|
||||
.result_id => if (offset - token_start == 1) {
|
||||
try self.addError(token_start, "result-id must have at least one name character", .{});
|
||||
try ass.addError(token_start, "result-id must have at least one name character", .{});
|
||||
},
|
||||
.value => {
|
||||
const text = self.tokenText(tok);
|
||||
const text = ass.tokenText(tok);
|
||||
const prefix = "Op";
|
||||
const looks_like_opcode = text.len > prefix.len and
|
||||
std.mem.startsWith(u8, text, prefix) and
|
||||
|
||||
+310
-290
@@ -144,36 +144,28 @@ const ControlFlow = union(enum) {
|
||||
|
||||
pt: Zcu.PerThread,
|
||||
air: Air,
|
||||
/// Note: If the declaration is not a function, this value will be undefined!
|
||||
liveness: Air.Liveness,
|
||||
owner_nav: InternPool.Nav.Index,
|
||||
module: *Module,
|
||||
control_flow: ControlFlow,
|
||||
base_line: u32,
|
||||
block_label: Id = .none,
|
||||
/// The base offset of the current decl, which is what `dbg_stmt` is relative to.
|
||||
/// An array of function argument result-ids. Each index corresponds with the
|
||||
/// function argument of the same index.
|
||||
args: std.ArrayListUnmanaged(Id) = .empty,
|
||||
/// A counter to keep track of how many `arg` instructions we've seen yet.
|
||||
next_arg_index: u32 = 0,
|
||||
/// A map keeping track of which instruction generated which result-id.
|
||||
args: std.ArrayListUnmanaged(Id) = .empty,
|
||||
inst_results: std.AutoHashMapUnmanaged(Air.Inst.Index, Id) = .empty,
|
||||
file_path_id: Id = .none,
|
||||
id_scratch: std.ArrayListUnmanaged(Id) = .empty,
|
||||
prologue: Section = .{},
|
||||
body: Section = .{},
|
||||
decl_deps: std.AutoArrayHashMapUnmanaged(Decl.Index, void) = .empty,
|
||||
error_msg: ?*Zcu.ErrorMsg = null,
|
||||
|
||||
/// Free resources owned by the CodeGen.
|
||||
pub fn deinit(cg: *CodeGen) void {
|
||||
const gpa = cg.module.gpa;
|
||||
cg.control_flow.deinit(gpa);
|
||||
cg.args.deinit(gpa);
|
||||
cg.inst_results.deinit(gpa);
|
||||
cg.control_flow.deinit(gpa);
|
||||
cg.id_scratch.deinit(gpa);
|
||||
cg.prologue.deinit(gpa);
|
||||
cg.body.deinit(gpa);
|
||||
cg.decl_deps.deinit(gpa);
|
||||
}
|
||||
|
||||
const Error = error{ CodegenFail, OutOfMemory };
|
||||
@@ -191,9 +183,11 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
if (!do_codegen and !ty.hasRuntimeBits(zcu)) return;
|
||||
|
||||
const spv_decl_index = try cg.module.resolveNav(ip, cg.owner_nav);
|
||||
const result_id = cg.module.declPtr(spv_decl_index).result_id;
|
||||
const decl = cg.module.declPtr(spv_decl_index);
|
||||
const result_id = decl.result_id;
|
||||
decl.begin_dep = cg.module.decl_deps.items.len;
|
||||
|
||||
switch (cg.module.declPtr(spv_decl_index).kind) {
|
||||
switch (decl.kind) {
|
||||
.func => {
|
||||
const fn_info = zcu.typeToFunc(ty).?;
|
||||
const return_ty_id = try cg.resolveFnReturnType(.fromInterned(fn_info.return_type));
|
||||
@@ -201,7 +195,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
|
||||
const func_result_id = if (is_test) cg.module.allocId() else result_id;
|
||||
const prototype_ty_id = try cg.resolveType(ty, .direct);
|
||||
try cg.prologue.emit(cg.module.gpa, .OpFunction, .{
|
||||
try cg.prologue.emit(gpa, .OpFunction, .{
|
||||
.id_result_type = return_ty_id,
|
||||
.id_result = func_result_id,
|
||||
.function_type = prototype_ty_id,
|
||||
@@ -218,7 +212,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
|
||||
const param_type_id = try cg.resolveType(param_ty, .direct);
|
||||
const arg_result_id = cg.module.allocId();
|
||||
try cg.prologue.emit(cg.module.gpa, .OpFunctionParameter, .{
|
||||
try cg.prologue.emit(gpa, .OpFunctionParameter, .{
|
||||
.id_result_type = param_type_id,
|
||||
.id_result = arg_result_id,
|
||||
});
|
||||
@@ -230,7 +224,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
|
||||
// The root block of a function declaration should appear before OpVariable instructions,
|
||||
// so it is generated into the function's prologue.
|
||||
try cg.prologue.emit(cg.module.gpa, .OpLabel, .{
|
||||
try cg.prologue.emit(gpa, .OpLabel, .{
|
||||
.id_result = root_block_id,
|
||||
});
|
||||
cg.block_label = root_block_id;
|
||||
@@ -241,23 +235,22 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
_ = try cg.genStructuredBody(.selection, main_body);
|
||||
// We always expect paths to here to end, but we still need the block
|
||||
// to act as a dummy merge block.
|
||||
try cg.body.emit(cg.module.gpa, .OpUnreachable, {});
|
||||
try cg.body.emit(gpa, .OpUnreachable, {});
|
||||
},
|
||||
.unstructured => {
|
||||
try cg.genBody(main_body);
|
||||
},
|
||||
}
|
||||
try cg.body.emit(cg.module.gpa, .OpFunctionEnd, {});
|
||||
try cg.body.emit(gpa, .OpFunctionEnd, {});
|
||||
// Append the actual code into the functions section.
|
||||
try cg.module.sections.functions.append(cg.module.gpa, cg.prologue);
|
||||
try cg.module.sections.functions.append(cg.module.gpa, cg.body);
|
||||
try cg.module.sections.functions.append(gpa, cg.prologue);
|
||||
try cg.module.sections.functions.append(gpa, cg.body);
|
||||
|
||||
// Temporarily generate a test kernel declaration if this is a test function.
|
||||
if (is_test) {
|
||||
try cg.generateTestEntryPoint(nav.fqn.toSlice(ip), spv_decl_index, func_result_id);
|
||||
}
|
||||
|
||||
try cg.module.declareDeclDeps(spv_decl_index, cg.decl_deps.keys());
|
||||
try cg.module.debugName(func_result_id, nav.fqn.toSlice(ip));
|
||||
},
|
||||
.global => {
|
||||
@@ -275,7 +268,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
const ty_id = try cg.resolveType(ty, .indirect);
|
||||
const ptr_ty_id = try cg.module.ptrType(ty_id, storage_class);
|
||||
|
||||
try cg.module.sections.globals.emit(cg.module.gpa, .OpVariable, .{
|
||||
try cg.module.sections.globals.emit(gpa, .OpVariable, .{
|
||||
.id_result_type = ptr_ty_id,
|
||||
.id_result = result_id,
|
||||
.storage_class = storage_class,
|
||||
@@ -307,7 +300,6 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
}
|
||||
|
||||
try cg.module.debugName(result_id, nav.fqn.toSlice(ip));
|
||||
try cg.module.declareDeclDeps(spv_decl_index, &.{});
|
||||
},
|
||||
.invocation_global => {
|
||||
const maybe_init_val: ?Value = switch (ip.indexToKey(val.toIntern())) {
|
||||
@@ -317,8 +309,6 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
else => val,
|
||||
};
|
||||
|
||||
try cg.module.declareDeclDeps(spv_decl_index, &.{});
|
||||
|
||||
const ty_id = try cg.resolveType(ty, .indirect);
|
||||
const ptr_ty_id = try cg.module.ptrType(ty_id, .function);
|
||||
|
||||
@@ -328,7 +318,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
const initializer_proto_ty_id = try cg.module.functionType(void_ty_id, &.{});
|
||||
|
||||
const initializer_id = cg.module.allocId();
|
||||
try cg.prologue.emit(cg.module.gpa, .OpFunction, .{
|
||||
try cg.prologue.emit(gpa, .OpFunction, .{
|
||||
.id_result_type = try cg.resolveType(.void, .direct),
|
||||
.id_result = initializer_id,
|
||||
.function_control = .{},
|
||||
@@ -336,26 +326,25 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
});
|
||||
|
||||
const root_block_id = cg.module.allocId();
|
||||
try cg.prologue.emit(cg.module.gpa, .OpLabel, .{
|
||||
try cg.prologue.emit(gpa, .OpLabel, .{
|
||||
.id_result = root_block_id,
|
||||
});
|
||||
cg.block_label = root_block_id;
|
||||
|
||||
const val_id = try cg.constant(ty, init_val, .indirect);
|
||||
try cg.body.emit(cg.module.gpa, .OpStore, .{
|
||||
try cg.body.emit(gpa, .OpStore, .{
|
||||
.pointer = result_id,
|
||||
.object = val_id,
|
||||
});
|
||||
|
||||
try cg.body.emit(cg.module.gpa, .OpReturn, {});
|
||||
try cg.body.emit(cg.module.gpa, .OpFunctionEnd, {});
|
||||
try cg.module.sections.functions.append(cg.module.gpa, cg.prologue);
|
||||
try cg.module.sections.functions.append(cg.module.gpa, cg.body);
|
||||
try cg.module.declareDeclDeps(spv_decl_index, cg.decl_deps.keys());
|
||||
try cg.body.emit(gpa, .OpReturn, {});
|
||||
try cg.body.emit(gpa, .OpFunctionEnd, {});
|
||||
try cg.module.sections.functions.append(gpa, cg.prologue);
|
||||
try cg.module.sections.functions.append(gpa, cg.body);
|
||||
|
||||
try cg.module.debugNameFmt(initializer_id, "initializer of {f}", .{nav.fqn.fmt(ip)});
|
||||
|
||||
try cg.module.sections.globals.emit(cg.module.gpa, .OpExtInst, .{
|
||||
try cg.module.sections.globals.emit(gpa, .OpExtInst, .{
|
||||
.id_result_type = ptr_ty_id,
|
||||
.id_result = result_id,
|
||||
.set = try cg.module.importInstructionSet(.zig),
|
||||
@@ -363,7 +352,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
.id_ref_4 = &.{initializer_id},
|
||||
});
|
||||
} else {
|
||||
try cg.module.sections.globals.emit(cg.module.gpa, .OpExtInst, .{
|
||||
try cg.module.sections.globals.emit(gpa, .OpExtInst, .{
|
||||
.id_result_type = ptr_ty_id,
|
||||
.id_result = result_id,
|
||||
.set = try cg.module.importInstructionSet(.zig),
|
||||
@@ -373,6 +362,8 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
cg.module.declPtr(spv_decl_index).end_dep = cg.module.decl_deps.items.len;
|
||||
}
|
||||
|
||||
pub fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) Error {
|
||||
@@ -413,7 +404,7 @@ fn resolve(cg: *CodeGen, inst: Air.Inst.Ref) !Id {
|
||||
else => unreachable,
|
||||
};
|
||||
const spv_decl_index = try cg.module.resolveNav(ip, fn_nav);
|
||||
try cg.decl_deps.put(cg.module.gpa, spv_decl_index, {});
|
||||
try cg.module.decl_deps.append(cg.module.gpa, spv_decl_index);
|
||||
return cg.module.declPtr(spv_decl_index).result_id;
|
||||
}
|
||||
|
||||
@@ -433,7 +424,7 @@ fn resolveUav(cg: *CodeGen, val: InternPool.Index) !Id {
|
||||
const ty_id = try cg.resolveType(ty, .indirect);
|
||||
|
||||
const spv_decl_index = blk: {
|
||||
const entry = try cg.module.uav_link.getOrPut(cg.module.gpa, .{ val, .function });
|
||||
const entry = try cg.module.uav_link.getOrPut(gpa, .{ val, .function });
|
||||
if (entry.found_existing) {
|
||||
try cg.addFunctionDep(entry.value_ptr.*, .function);
|
||||
return cg.module.declPtr(entry.value_ptr.*).result_id;
|
||||
@@ -458,57 +449,52 @@ fn resolveUav(cg: *CodeGen, val: InternPool.Index) !Id {
|
||||
// TODO: This should probably be made a little more robust.
|
||||
const func_prologue = cg.prologue;
|
||||
const func_body = cg.body;
|
||||
const func_deps = cg.decl_deps;
|
||||
const block_label = cg.block_label;
|
||||
defer {
|
||||
cg.prologue = func_prologue;
|
||||
cg.body = func_body;
|
||||
cg.decl_deps = func_deps;
|
||||
cg.block_label = block_label;
|
||||
}
|
||||
|
||||
cg.prologue = .{};
|
||||
cg.body = .{};
|
||||
cg.decl_deps = .{};
|
||||
defer {
|
||||
cg.prologue.deinit(gpa);
|
||||
cg.body.deinit(gpa);
|
||||
cg.decl_deps.deinit(gpa);
|
||||
}
|
||||
|
||||
const void_ty_id = try cg.resolveType(.void, .direct);
|
||||
const initializer_proto_ty_id = try cg.module.functionType(void_ty_id, &.{});
|
||||
|
||||
const initializer_id = cg.module.allocId();
|
||||
try cg.prologue.emit(cg.module.gpa, .OpFunction, .{
|
||||
try cg.prologue.emit(gpa, .OpFunction, .{
|
||||
.id_result_type = try cg.resolveType(.void, .direct),
|
||||
.id_result = initializer_id,
|
||||
.function_control = .{},
|
||||
.function_type = initializer_proto_ty_id,
|
||||
});
|
||||
const root_block_id = cg.module.allocId();
|
||||
try cg.prologue.emit(cg.module.gpa, .OpLabel, .{
|
||||
try cg.prologue.emit(gpa, .OpLabel, .{
|
||||
.id_result = root_block_id,
|
||||
});
|
||||
cg.block_label = root_block_id;
|
||||
|
||||
const val_id = try cg.constant(ty, .fromInterned(val), .indirect);
|
||||
try cg.body.emit(cg.module.gpa, .OpStore, .{
|
||||
try cg.body.emit(gpa, .OpStore, .{
|
||||
.pointer = result_id,
|
||||
.object = val_id,
|
||||
});
|
||||
|
||||
try cg.body.emit(cg.module.gpa, .OpReturn, {});
|
||||
try cg.body.emit(cg.module.gpa, .OpFunctionEnd, {});
|
||||
try cg.body.emit(gpa, .OpReturn, {});
|
||||
try cg.body.emit(gpa, .OpFunctionEnd, {});
|
||||
|
||||
try cg.module.sections.functions.append(cg.module.gpa, cg.prologue);
|
||||
try cg.module.sections.functions.append(cg.module.gpa, cg.body);
|
||||
try cg.module.declareDeclDeps(spv_decl_index, cg.decl_deps.keys());
|
||||
try cg.module.sections.functions.append(gpa, cg.prologue);
|
||||
try cg.module.sections.functions.append(gpa, cg.body);
|
||||
|
||||
try cg.module.debugNameFmt(initializer_id, "initializer of __anon_{d}", .{@intFromEnum(val)});
|
||||
|
||||
const fn_decl_ptr_ty_id = try cg.module.ptrType(ty_id, .function);
|
||||
try cg.module.sections.globals.emit(cg.module.gpa, .OpExtInst, .{
|
||||
try cg.module.sections.globals.emit(gpa, .OpExtInst, .{
|
||||
.id_result_type = fn_decl_ptr_ty_id,
|
||||
.id_result = result_id,
|
||||
.set = try cg.module.importInstructionSet(.zig),
|
||||
@@ -521,13 +507,14 @@ fn resolveUav(cg: *CodeGen, val: InternPool.Index) !Id {
|
||||
}
|
||||
|
||||
fn addFunctionDep(cg: *CodeGen, decl_index: Module.Decl.Index, storage_class: StorageClass) !void {
|
||||
const gpa = cg.module.gpa;
|
||||
const target = cg.module.zcu.getTarget();
|
||||
if (target.cpu.has(.spirv, .v1_4)) {
|
||||
try cg.decl_deps.put(cg.module.gpa, decl_index, {});
|
||||
try cg.module.decl_deps.append(gpa, decl_index);
|
||||
} else {
|
||||
// Before version 1.4, the interface’s storage classes are limited to the Input and Output
|
||||
if (storage_class == .input or storage_class == .output) {
|
||||
try cg.decl_deps.put(cg.module.gpa, decl_index, {});
|
||||
try cg.module.decl_deps.append(gpa, decl_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -752,8 +739,10 @@ fn constructCompositeSplat(cg: *CodeGen, ty: Type, constituent: Id) !Id {
|
||||
const zcu = cg.module.zcu;
|
||||
const n: usize = @intCast(ty.arrayLen(zcu));
|
||||
|
||||
const constituents = try gpa.alloc(Id, n);
|
||||
defer gpa.free(constituents);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
|
||||
const constituents = try cg.id_scratch.addManyAsSlice(gpa, n);
|
||||
@memset(constituents, constituent);
|
||||
|
||||
const result_ty_id = try cg.resolveType(ty, .direct);
|
||||
@@ -928,8 +917,9 @@ fn constant(cg: *CodeGen, ty: Type, val: Value, repr: Repr) Error!Id {
|
||||
inline .array_type, .vector_type => |array_type, tag| {
|
||||
const elem_ty: Type = .fromInterned(array_type.child);
|
||||
|
||||
const constituents = try gpa.alloc(Id, @intCast(ty.arrayLenIncludingSentinel(zcu)));
|
||||
defer gpa.free(constituents);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const constituents = try cg.id_scratch.addManyAsSlice(gpa, @intCast(ty.arrayLenIncludingSentinel(zcu)));
|
||||
|
||||
const child_repr: Repr = switch (tag) {
|
||||
.array_type => .indirect,
|
||||
@@ -1044,6 +1034,7 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id {
|
||||
}
|
||||
|
||||
fn derivePtr(cg: *CodeGen, derivation: Value.PointerDeriveStep) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const pt = cg.pt;
|
||||
const zcu = cg.module.zcu;
|
||||
switch (derivation) {
|
||||
@@ -1055,7 +1046,7 @@ fn derivePtr(cg: *CodeGen, derivation: Value.PointerDeriveStep) !Id {
|
||||
// as a runtime operation.
|
||||
const result_ptr_id = cg.module.allocId();
|
||||
const value_id = try cg.constInt(.usize, int.addr);
|
||||
try cg.body.emit(cg.module.gpa, .OpConvertUToPtr, .{
|
||||
try cg.body.emit(gpa, .OpConvertUToPtr, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_ptr_id,
|
||||
.integer_value = value_id,
|
||||
@@ -1103,7 +1094,7 @@ fn derivePtr(cg: *CodeGen, derivation: Value.PointerDeriveStep) !Id {
|
||||
// Allow changing the pointer type child only to restructure arrays.
|
||||
// e.g. [3][2]T to T is fine, as is [2]T -> [2][1]T.
|
||||
const result_ptr_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpBitcast, .{
|
||||
try cg.body.emit(gpa, .OpBitcast, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_ptr_id,
|
||||
.operand = parent_ptr_id,
|
||||
@@ -1191,6 +1182,7 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id {
|
||||
|
||||
const spv_decl_index = try cg.module.resolveNav(ip, nav_index);
|
||||
const spv_decl = cg.module.declPtr(spv_decl_index);
|
||||
const spv_decl_result_id = spv_decl.result_id;
|
||||
assert(spv_decl.kind != .func);
|
||||
|
||||
const storage_class = cg.module.storageClass(nav.getAddrspace());
|
||||
@@ -1205,12 +1197,12 @@ fn constantNavRef(cg: *CodeGen, ty: Type, nav_index: InternPool.Nav.Index) !Id {
|
||||
try cg.body.emit(cg.module.gpa, .OpBitcast, .{
|
||||
.id_result_type = ty_id,
|
||||
.id_result = casted_ptr_id,
|
||||
.operand = spv_decl.result_id,
|
||||
.operand = spv_decl_result_id,
|
||||
});
|
||||
return casted_ptr_id;
|
||||
}
|
||||
|
||||
return spv_decl.result_id;
|
||||
return spv_decl_result_id;
|
||||
}
|
||||
|
||||
// Turn a Zig type's name into a cache reference.
|
||||
@@ -1430,8 +1422,11 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
||||
}
|
||||
|
||||
const return_ty_id = try cg.resolveFnReturnType(.fromInterned(fn_info.return_type));
|
||||
const param_ty_ids = try gpa.alloc(Id, fn_info.param_types.len);
|
||||
defer gpa.free(param_ty_ids);
|
||||
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const param_ty_ids = try cg.id_scratch.addManyAsSlice(gpa, fn_info.param_types.len);
|
||||
|
||||
var param_index: usize = 0;
|
||||
for (fn_info.param_types.get(ip)) |param_ty_index| {
|
||||
const param_ty: Type = .fromInterned(param_ty_index);
|
||||
@@ -1472,8 +1467,9 @@ fn resolveType(cg: *CodeGen, ty: Type, repr: Repr) Error!Id {
|
||||
.@"struct" => {
|
||||
const struct_type = switch (ip.indexToKey(ty.toIntern())) {
|
||||
.tuple_type => |tuple| {
|
||||
const member_types = try gpa.alloc(Id, tuple.values.len);
|
||||
defer gpa.free(member_types);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const member_types = try cg.id_scratch.addManyAsSlice(gpa, tuple.values.len);
|
||||
|
||||
var member_index: usize = 0;
|
||||
for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
|
||||
@@ -1755,11 +1751,14 @@ const Temporary = struct {
|
||||
.exploded_vector => |range| {
|
||||
assert(temp.ty.isVector(zcu));
|
||||
assert(temp.ty.vectorLen(zcu) == range.len);
|
||||
const constituents = try gpa.alloc(Id, range.len);
|
||||
defer gpa.free(constituents);
|
||||
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const constituents = try cg.id_scratch.addManyAsSlice(gpa, range.len);
|
||||
for (constituents, 0..range.len) |*id, i| {
|
||||
id.* = range.at(i);
|
||||
}
|
||||
|
||||
const result_ty_id = try cg.resolveType(temp.ty, .direct);
|
||||
return cg.constructComposite(result_ty_id, constituents);
|
||||
},
|
||||
@@ -2039,14 +2038,12 @@ fn buildFma(cg: *CodeGen, a: Temporary, b: Temporary, c: Temporary) !Temporary {
|
||||
const op_c = try v.prepare(cg, c);
|
||||
|
||||
const set = try cg.importExtendedSet();
|
||||
|
||||
// TODO: Put these numbers in some definition
|
||||
const instruction: u32 = switch (target.os.tag) {
|
||||
.opencl => 26, // fma
|
||||
const opcode: u32 = switch (target.os.tag) {
|
||||
.opencl => @intFromEnum(spec.OpenClOpcode.fma),
|
||||
// NOTE: Vulkan's FMA instruction does *NOT* produce the right values!
|
||||
// its precision guarantees do NOT match zigs and it does NOT match OpenCLs!
|
||||
// it needs to be emulated!
|
||||
.vulkan, .opengl => return cg.todo("implement fma operation for {s} os", .{@tagName(target.os.tag)}),
|
||||
// its precision guarantees do NOT match zigs and it does NOT match OpenCLs!
|
||||
// it needs to be emulated!
|
||||
.vulkan, .opengl => @intFromEnum(spec.GlslOpcode.Fma),
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
@@ -2055,7 +2052,7 @@ fn buildFma(cg: *CodeGen, a: Temporary, b: Temporary, c: Temporary) !Temporary {
|
||||
.id_result_type = op_result_ty_id,
|
||||
.id_result = results.at(i),
|
||||
.set = set,
|
||||
.instruction = .{ .inst = instruction },
|
||||
.instruction = .{ .inst = opcode },
|
||||
.id_ref_4 = &.{ op_a.at(i), op_b.at(i), op_c.at(i) },
|
||||
});
|
||||
}
|
||||
@@ -2138,6 +2135,44 @@ const UnaryOp = enum {
|
||||
log,
|
||||
log2,
|
||||
log10,
|
||||
|
||||
pub fn extInstOpcode(op: UnaryOp, target: *const std.Target) ?u32 {
|
||||
return switch (target.os.tag) {
|
||||
.opencl => @intFromEnum(@as(spec.OpenClOpcode, switch (op) {
|
||||
.i_abs => .s_abs,
|
||||
.f_abs => .fabs,
|
||||
.clz => .clz,
|
||||
.ctz => .ctz,
|
||||
.floor => .floor,
|
||||
.ceil => .ceil,
|
||||
.trunc => .trunc,
|
||||
.round => .round,
|
||||
.sqrt => .sqrt,
|
||||
.sin => .sin,
|
||||
.cos => .cos,
|
||||
.tan => .tan,
|
||||
.exp => .exp,
|
||||
.exp2 => .exp2,
|
||||
.log => .log,
|
||||
.log2 => .log2,
|
||||
.log10 => .log10,
|
||||
else => return null,
|
||||
})),
|
||||
// Note: We'll need to check these for floating point accuracy
|
||||
// Vulkan does not put tight requirements on these, for correction
|
||||
// we might want to emulate them at some point.
|
||||
.vulkan, .opengl => @intFromEnum(@as(spec.GlslOpcode, switch (op) {
|
||||
.i_abs => .SAbs,
|
||||
.f_abs => .FAbs,
|
||||
.floor => .Floor,
|
||||
.ceil => .Ceil,
|
||||
.trunc => .Trunc,
|
||||
.round => .Round,
|
||||
else => return null,
|
||||
})),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
fn buildUnary(cg: *CodeGen, op: UnaryOp, operand: Temporary) !Temporary {
|
||||
@@ -2149,84 +2184,36 @@ fn buildUnary(cg: *CodeGen, op: UnaryOp, operand: Temporary) !Temporary {
|
||||
const op_result_ty = operand.ty.scalarType(zcu);
|
||||
const op_result_ty_id = try cg.resolveType(op_result_ty, .direct);
|
||||
const result_ty = try v.resultType(cg, operand.ty);
|
||||
|
||||
const op_operand = try v.prepare(cg, operand);
|
||||
|
||||
if (switch (op) {
|
||||
.l_not => .OpLogicalNot,
|
||||
.bit_not => .OpNot,
|
||||
.i_neg => .OpSNegate,
|
||||
.f_neg => .OpFNegate,
|
||||
else => @as(?Opcode, null),
|
||||
}) |opcode| {
|
||||
for (0..ops) |i| {
|
||||
try cg.body.emitRaw(cg.module.gpa, opcode, 3);
|
||||
cg.body.writeOperand(Id, op_result_ty_id);
|
||||
cg.body.writeOperand(Id, results.at(i));
|
||||
cg.body.writeOperand(Id, op_operand.at(i));
|
||||
}
|
||||
} else {
|
||||
if (op.extInstOpcode(target)) |opcode| {
|
||||
const set = try cg.importExtendedSet();
|
||||
const extinst: u32 = switch (target.os.tag) {
|
||||
.opencl => switch (op) {
|
||||
.i_abs => 141, // s_abs
|
||||
.f_abs => 23, // fabs
|
||||
.clz => 151, // clz
|
||||
.ctz => 152, // ctz
|
||||
.floor => 25, // floor
|
||||
.ceil => 12, // ceil
|
||||
.trunc => 66, // trunc
|
||||
.round => 55, // round
|
||||
.sqrt => 61, // sqrt
|
||||
.sin => 57, // sin
|
||||
.cos => 14, // cos
|
||||
.tan => 62, // tan
|
||||
.exp => 19, // exp
|
||||
.exp2 => 20, // exp2
|
||||
.log => 37, // log
|
||||
.log2 => 38, // log2
|
||||
.log10 => 39, // log10
|
||||
else => unreachable,
|
||||
},
|
||||
// Note: We'll need to check these for floating point accuracy
|
||||
// Vulkan does not put tight requirements on these, for correction
|
||||
// we might want to emulate them at some point.
|
||||
.vulkan, .opengl => switch (op) {
|
||||
.i_abs => 5, // SAbs
|
||||
.f_abs => 4, // FAbs
|
||||
.floor => 8, // Floor
|
||||
.ceil => 9, // Ceil
|
||||
.trunc => 3, // Trunc
|
||||
.round => 1, // Round
|
||||
.clz,
|
||||
.ctz,
|
||||
.sqrt,
|
||||
.sin,
|
||||
.cos,
|
||||
.tan,
|
||||
.exp,
|
||||
.exp2,
|
||||
.log,
|
||||
.log2,
|
||||
.log10,
|
||||
=> return cg.todo(
|
||||
"implement unary operation '{s}' for {s} os",
|
||||
.{ @tagName(op), @tagName(target.os.tag) },
|
||||
),
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
for (0..ops) |i| {
|
||||
try cg.body.emit(cg.module.gpa, .OpExtInst, .{
|
||||
.id_result_type = op_result_ty_id,
|
||||
.id_result = results.at(i),
|
||||
.set = set,
|
||||
.instruction = .{ .inst = extinst },
|
||||
.instruction = .{ .inst = opcode },
|
||||
.id_ref_4 = &.{op_operand.at(i)},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const opcode: Opcode = switch (op) {
|
||||
.l_not => .OpLogicalNot,
|
||||
.bit_not => .OpNot,
|
||||
.i_neg => .OpSNegate,
|
||||
.f_neg => .OpFNegate,
|
||||
else => return cg.todo(
|
||||
"implement unary operation '{s}' for {s} os",
|
||||
.{ @tagName(op), @tagName(target.os.tag) },
|
||||
),
|
||||
};
|
||||
for (0..ops) |i| {
|
||||
try cg.body.emitRaw(cg.module.gpa, opcode, 3);
|
||||
cg.body.writeOperand(Id, op_result_ty_id);
|
||||
cg.body.writeOperand(Id, results.at(i));
|
||||
cg.body.writeOperand(Id, op_operand.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
return v.finalize(result_ty, results);
|
||||
@@ -2288,9 +2275,9 @@ fn buildWideMul(
|
||||
// OpUMulExtended. For these we will use the OpenCL s_mul_hi to compute the high-order bits
|
||||
// instead.
|
||||
const set = try cg.importExtendedSet();
|
||||
const overflow_inst: u32 = switch (signedness) {
|
||||
.signed => 160, // s_mul_hi
|
||||
.unsigned => 203, // u_mul_hi
|
||||
const overflow_inst: spec.OpenClOpcode = switch (signedness) {
|
||||
.signed => .s_mul_hi,
|
||||
.unsigned => .u_mul_hi,
|
||||
};
|
||||
|
||||
for (0..ops) |i| {
|
||||
@@ -2305,7 +2292,7 @@ fn buildWideMul(
|
||||
.id_result_type = arith_op_ty_id,
|
||||
.id_result = overflow_results.at(i),
|
||||
.set = set,
|
||||
.instruction = .{ .inst = overflow_inst },
|
||||
.instruction = .{ .inst = @intFromEnum(overflow_inst) },
|
||||
.id_ref_4 = &.{ lhs_op.at(i), rhs_op.at(i) },
|
||||
});
|
||||
}
|
||||
@@ -2428,7 +2415,7 @@ fn generateTestEntryPoint(
|
||||
.vulkan, .opengl => {
|
||||
if (cg.module.error_buffer == null) {
|
||||
const spv_err_decl_index = try cg.module.allocDecl(.global);
|
||||
try cg.module.declareDeclDeps(spv_err_decl_index, &.{});
|
||||
const err_buf_result_id = cg.module.declPtr(spv_err_decl_index).result_id;
|
||||
|
||||
const buffer_struct_ty_id = try cg.module.structType(
|
||||
&.{anyerror_ty_id},
|
||||
@@ -2446,14 +2433,13 @@ fn generateTestEntryPoint(
|
||||
.type = buffer_struct_ty_id,
|
||||
});
|
||||
|
||||
const buffer_struct_id = cg.module.declPtr(spv_err_decl_index).result_id;
|
||||
try cg.module.sections.globals.emit(gpa, .OpVariable, .{
|
||||
.id_result_type = ptr_buffer_struct_ty_id,
|
||||
.id_result = buffer_struct_id,
|
||||
.id_result = err_buf_result_id,
|
||||
.storage_class = cg.module.storageClass(.global),
|
||||
});
|
||||
try cg.module.decorate(buffer_struct_id, .{ .descriptor_set = .{ .descriptor_set = 0 } });
|
||||
try cg.module.decorate(buffer_struct_id, .{ .binding = .{ .binding_point = 0 } });
|
||||
try cg.module.decorate(err_buf_result_id, .{ .descriptor_set = .{ .descriptor_set = 0 } });
|
||||
try cg.module.decorate(err_buf_result_id, .{ .binding = .{ .binding_point = 0 } });
|
||||
|
||||
cg.module.error_buffer = spv_err_decl_index;
|
||||
}
|
||||
@@ -2481,7 +2467,7 @@ fn generateTestEntryPoint(
|
||||
|
||||
const spv_err_decl_index = cg.module.error_buffer.?;
|
||||
const buffer_id = cg.module.declPtr(spv_err_decl_index).result_id;
|
||||
try cg.decl_deps.put(gpa, spv_err_decl_index, {});
|
||||
try cg.module.decl_deps.append(gpa, spv_err_decl_index);
|
||||
|
||||
const zero_id = try cg.constInt(.u32, 0);
|
||||
try section.emit(gpa, .OpInBoundsAccessChain, .{
|
||||
@@ -2867,7 +2853,54 @@ fn airShift(cg: *CodeGen, inst: Air.Inst.Index, unsigned: Opcode, signed: Opcode
|
||||
return try result.materialize(cg);
|
||||
}
|
||||
|
||||
const MinMax = enum { min, max };
|
||||
const MinMax = enum {
|
||||
min,
|
||||
max,
|
||||
|
||||
pub fn extInstOpcode(
|
||||
op: MinMax,
|
||||
target: *const std.Target,
|
||||
info: ArithmeticTypeInfo,
|
||||
) u32 {
|
||||
return switch (target.os.tag) {
|
||||
.opencl => @intFromEnum(@as(spec.OpenClOpcode, switch (info.class) {
|
||||
.float => switch (op) {
|
||||
.min => .fmin,
|
||||
.max => .fmax,
|
||||
},
|
||||
.integer, .strange_integer, .composite_integer => switch (info.signedness) {
|
||||
.signed => switch (op) {
|
||||
.min => .s_min,
|
||||
.max => .s_max,
|
||||
},
|
||||
.unsigned => switch (op) {
|
||||
.min => .u_min,
|
||||
.max => .u_max,
|
||||
},
|
||||
},
|
||||
.bool => unreachable,
|
||||
})),
|
||||
.vulkan, .opengl => @intFromEnum(@as(spec.GlslOpcode, switch (info.class) {
|
||||
.float => switch (op) {
|
||||
.min => .FMin,
|
||||
.max => .FMax,
|
||||
},
|
||||
.integer, .strange_integer, .composite_integer => switch (info.signedness) {
|
||||
.signed => switch (op) {
|
||||
.min => .SMin,
|
||||
.max => .SMax,
|
||||
},
|
||||
.unsigned => switch (op) {
|
||||
.min => .UMin,
|
||||
.max => .UMax,
|
||||
},
|
||||
},
|
||||
.bool => unreachable,
|
||||
})),
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
fn airMinMax(cg: *CodeGen, inst: Air.Inst.Index, op: MinMax) !?Id {
|
||||
const bin_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
|
||||
@@ -2895,57 +2928,14 @@ fn minMax(cg: *CodeGen, lhs: Temporary, rhs: Temporary, op: MinMax) !Temporary {
|
||||
const op_lhs = try v.prepare(cg, lhs);
|
||||
const op_rhs = try v.prepare(cg, rhs);
|
||||
|
||||
const ext_inst: u32 = switch (target.os.tag) {
|
||||
.opencl => switch (info.class) {
|
||||
.float => switch (op) {
|
||||
.min => 28, // fmin
|
||||
.max => 27, // fmax
|
||||
},
|
||||
.integer,
|
||||
.strange_integer,
|
||||
.composite_integer,
|
||||
=> switch (info.signedness) {
|
||||
.signed => switch (op) {
|
||||
.min => 158, // s_min
|
||||
.max => 156, // s_max
|
||||
},
|
||||
.unsigned => switch (op) {
|
||||
.min => 159, // u_min
|
||||
.max => 157, // u_max
|
||||
},
|
||||
},
|
||||
.bool => unreachable,
|
||||
},
|
||||
.vulkan, .opengl => switch (info.class) {
|
||||
.float => switch (op) {
|
||||
.min => 37, // FMin
|
||||
.max => 40, // FMax
|
||||
},
|
||||
.integer,
|
||||
.strange_integer,
|
||||
.composite_integer,
|
||||
=> switch (info.signedness) {
|
||||
.signed => switch (op) {
|
||||
.min => 39, // SMin
|
||||
.max => 42, // SMax
|
||||
},
|
||||
.unsigned => switch (op) {
|
||||
.min => 38, // UMin
|
||||
.max => 41, // UMax
|
||||
},
|
||||
},
|
||||
.bool => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
const set = try cg.importExtendedSet();
|
||||
const opcode = op.extInstOpcode(target, info);
|
||||
for (0..ops) |i| {
|
||||
try cg.body.emit(cg.module.gpa, .OpExtInst, .{
|
||||
.id_result_type = op_result_ty_id,
|
||||
.id_result = results.at(i),
|
||||
.set = set,
|
||||
.instruction = .{ .inst = ext_inst },
|
||||
.instruction = .{ .inst = opcode },
|
||||
.id_ref_4 = &.{ op_lhs.at(i), op_rhs.at(i) },
|
||||
});
|
||||
}
|
||||
@@ -3562,8 +3552,9 @@ fn airShuffleOne(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
const elem_ty = result_ty.childType(zcu);
|
||||
const operand = try cg.resolve(unwrapped.operand);
|
||||
|
||||
const constituents = try gpa.alloc(Id, mask.len);
|
||||
defer gpa.free(constituents);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const constituents = try cg.id_scratch.addManyAsSlice(gpa, mask.len);
|
||||
|
||||
for (constituents, mask) |*id, mask_elem| {
|
||||
id.* = switch (mask_elem.unwrap()) {
|
||||
@@ -3588,8 +3579,9 @@ fn airShuffleTwo(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
const operand_a = try cg.resolve(unwrapped.operand_a);
|
||||
const operand_b = try cg.resolve(unwrapped.operand_b);
|
||||
|
||||
const constituents = try gpa.alloc(Id, mask.len);
|
||||
defer gpa.free(constituents);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const constituents = try cg.id_scratch.addManyAsSlice(gpa, mask.len);
|
||||
|
||||
for (constituents, mask) |*id, mask_elem| {
|
||||
id.* = switch (mask_elem.unwrap()) {
|
||||
@@ -3603,17 +3595,6 @@ fn airShuffleTwo(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
return try cg.constructComposite(result_ty_id, constituents);
|
||||
}
|
||||
|
||||
fn indicesToIds(cg: *CodeGen, indices: []const u32) ![]Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const ids = try gpa.alloc(Id, indices.len);
|
||||
errdefer gpa.free(ids);
|
||||
for (indices, ids) |index, *id| {
|
||||
id.* = try cg.constInt(.u32, index);
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
fn accessChainId(
|
||||
cg: *CodeGen,
|
||||
result_ty_id: Id,
|
||||
@@ -3641,8 +3622,12 @@ fn accessChain(
|
||||
indices: []const u32,
|
||||
) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const ids = try cg.indicesToIds(indices);
|
||||
defer gpa.free(ids);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const ids = try cg.id_scratch.addManyAsSlice(gpa, indices.len);
|
||||
for (indices, ids) |index, *id| {
|
||||
id.* = try cg.constInt(.u32, index);
|
||||
}
|
||||
return try cg.accessChainId(result_ty_id, base, ids);
|
||||
}
|
||||
|
||||
@@ -3655,13 +3640,18 @@ fn ptrAccessChain(
|
||||
) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const target = cg.module.zcu.getTarget();
|
||||
const ids = try cg.indicesToIds(indices);
|
||||
defer gpa.free(ids);
|
||||
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const ids = try cg.id_scratch.addManyAsSlice(gpa, indices.len);
|
||||
for (indices, ids) |index, *id| {
|
||||
id.* = try cg.constInt(.u32, index);
|
||||
}
|
||||
|
||||
const result_id = cg.module.allocId();
|
||||
switch (target.os.tag) {
|
||||
.opencl, .amdhsa => {
|
||||
try cg.body.emit(cg.module.gpa, .OpInBoundsPtrAccessChain, .{
|
||||
try cg.body.emit(gpa, .OpInBoundsPtrAccessChain, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_id,
|
||||
.base = base,
|
||||
@@ -3669,8 +3659,8 @@ fn ptrAccessChain(
|
||||
.indexes = ids,
|
||||
});
|
||||
},
|
||||
else => {
|
||||
try cg.body.emit(cg.module.gpa, .OpPtrAccessChain, .{
|
||||
.vulkan, .opengl => {
|
||||
try cg.body.emit(gpa, .OpPtrAccessChain, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_id,
|
||||
.base = base,
|
||||
@@ -3678,6 +3668,7 @@ fn ptrAccessChain(
|
||||
.indexes = ids,
|
||||
});
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
return result_id;
|
||||
}
|
||||
@@ -3739,6 +3730,7 @@ fn cmp(
|
||||
lhs: Temporary,
|
||||
rhs: Temporary,
|
||||
) !Temporary {
|
||||
const gpa = cg.module.gpa;
|
||||
const pt = cg.pt;
|
||||
const zcu = cg.module.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
@@ -3771,14 +3763,14 @@ fn cmp(
|
||||
const usize_ty_id = try cg.resolveType(.usize, .direct);
|
||||
|
||||
const lhs_int_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpConvertPtrToU, .{
|
||||
try cg.body.emit(gpa, .OpConvertPtrToU, .{
|
||||
.id_result_type = usize_ty_id,
|
||||
.id_result = lhs_int_id,
|
||||
.pointer = try lhs.materialize(cg),
|
||||
});
|
||||
|
||||
const rhs_int_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpConvertPtrToU, .{
|
||||
try cg.body.emit(gpa, .OpConvertPtrToU, .{
|
||||
.id_result_type = usize_ty_id,
|
||||
.id_result = rhs_int_id,
|
||||
.pointer = try rhs.materialize(cg),
|
||||
@@ -3937,6 +3929,7 @@ fn bitCast(
|
||||
src_ty: Type,
|
||||
src_id: Id,
|
||||
) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const zcu = cg.module.zcu;
|
||||
const src_ty_id = try cg.resolveType(src_ty, .direct);
|
||||
const dst_ty_id = try cg.resolveType(dst_ty, .direct);
|
||||
@@ -3949,7 +3942,7 @@ fn bitCast(
|
||||
|
||||
if (src_ty.zigTypeTag(zcu) == .int and dst_ty.isPtrAtRuntime(zcu)) {
|
||||
const result_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpConvertUToPtr, .{
|
||||
try cg.body.emit(gpa, .OpConvertUToPtr, .{
|
||||
.id_result_type = dst_ty_id,
|
||||
.id_result = result_id,
|
||||
.integer_value = src_id,
|
||||
@@ -3963,7 +3956,7 @@ fn bitCast(
|
||||
const can_bitcast = (src_ty.isNumeric(zcu) and dst_ty.isNumeric(zcu)) or (src_ty.isPtrAtRuntime(zcu) and dst_ty.isPtrAtRuntime(zcu));
|
||||
if (can_bitcast) {
|
||||
const result_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpBitcast, .{
|
||||
try cg.body.emit(gpa, .OpBitcast, .{
|
||||
.id_result_type = dst_ty_id,
|
||||
.id_result = result_id,
|
||||
.operand = src_id,
|
||||
@@ -3977,7 +3970,7 @@ fn bitCast(
|
||||
const tmp_id = try cg.alloc(src_ty, .{ .storage_class = .function });
|
||||
try cg.store(src_ty, tmp_id, src_id, .{});
|
||||
const casted_ptr_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpBitcast, .{
|
||||
try cg.body.emit(gpa, .OpBitcast, .{
|
||||
.id_result_type = dst_ptr_ty_id,
|
||||
.id_result = casted_ptr_id,
|
||||
.operand = tmp_id,
|
||||
@@ -4057,16 +4050,17 @@ fn airFloatFromInt(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
}
|
||||
|
||||
fn floatFromInt(cg: *CodeGen, result_ty: Type, operand_ty: Type, operand_id: Id) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const operand_info = cg.arithmeticTypeInfo(operand_ty);
|
||||
const result_id = cg.module.allocId();
|
||||
const result_ty_id = try cg.resolveType(result_ty, .direct);
|
||||
switch (operand_info.signedness) {
|
||||
.signed => try cg.body.emit(cg.module.gpa, .OpConvertSToF, .{
|
||||
.signed => try cg.body.emit(gpa, .OpConvertSToF, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_id,
|
||||
.signed_value = operand_id,
|
||||
}),
|
||||
.unsigned => try cg.body.emit(cg.module.gpa, .OpConvertUToF, .{
|
||||
.unsigned => try cg.body.emit(gpa, .OpConvertUToF, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_id,
|
||||
.unsigned_value = operand_id,
|
||||
@@ -4083,16 +4077,17 @@ fn airIntFromFloat(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
}
|
||||
|
||||
fn intFromFloat(cg: *CodeGen, result_ty: Type, operand_id: Id) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const result_info = cg.arithmeticTypeInfo(result_ty);
|
||||
const result_ty_id = try cg.resolveType(result_ty, .direct);
|
||||
const result_id = cg.module.allocId();
|
||||
switch (result_info.signedness) {
|
||||
.signed => try cg.body.emit(cg.module.gpa, .OpConvertFToS, .{
|
||||
.signed => try cg.body.emit(gpa, .OpConvertFToS, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_id,
|
||||
.float_value = operand_id,
|
||||
}),
|
||||
.unsigned => try cg.body.emit(cg.module.gpa, .OpConvertFToU, .{
|
||||
.unsigned => try cg.body.emit(gpa, .OpConvertFToU, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_id,
|
||||
.float_value = operand_id,
|
||||
@@ -4214,10 +4209,13 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
return running_int_id;
|
||||
}
|
||||
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const constituents = try cg.id_scratch.addManyAsSlice(gpa, elements.len);
|
||||
|
||||
const types = try gpa.alloc(Type, elements.len);
|
||||
defer gpa.free(types);
|
||||
const constituents = try gpa.alloc(Id, elements.len);
|
||||
defer gpa.free(constituents);
|
||||
|
||||
var index: usize = 0;
|
||||
|
||||
switch (ip.indexToKey(result_ty.toIntern())) {
|
||||
@@ -4255,8 +4253,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
},
|
||||
.vector => {
|
||||
const n_elems = result_ty.vectorLen(zcu);
|
||||
const elem_ids = try gpa.alloc(Id, n_elems);
|
||||
defer gpa.free(elem_ids);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const elem_ids = try cg.id_scratch.addManyAsSlice(gpa, n_elems);
|
||||
|
||||
for (elements, 0..) |element, i| {
|
||||
elem_ids[i] = try cg.resolve(element);
|
||||
@@ -4268,8 +4267,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
.array => {
|
||||
const array_info = result_ty.arrayInfo(zcu);
|
||||
const n_elems: usize = @intCast(result_ty.arrayLenIncludingSentinel(zcu));
|
||||
const elem_ids = try gpa.alloc(Id, n_elems);
|
||||
defer gpa.free(elem_ids);
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const elem_ids = try cg.id_scratch.addManyAsSlice(gpa, n_elems);
|
||||
|
||||
for (elements, 0..) |element, i| {
|
||||
const id = try cg.resolve(element);
|
||||
@@ -4407,6 +4407,7 @@ fn airPtrElemPtr(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
}
|
||||
|
||||
fn airArrayElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const zcu = cg.module.zcu;
|
||||
const bin_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
|
||||
const array_ty = cg.typeOf(bin_op.lhs);
|
||||
@@ -4427,13 +4428,13 @@ fn airArrayElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
const ptr_elem_ty_id = try cg.module.ptrType(elem_ty_id, .function);
|
||||
|
||||
const tmp_id = cg.module.allocId();
|
||||
try cg.prologue.emit(cg.module.gpa, .OpVariable, .{
|
||||
try cg.prologue.emit(gpa, .OpVariable, .{
|
||||
.id_result_type = ptr_array_ty_id,
|
||||
.id_result = tmp_id,
|
||||
.storage_class = .function,
|
||||
});
|
||||
|
||||
try cg.body.emit(cg.module.gpa, .OpStore, .{
|
||||
try cg.body.emit(gpa, .OpStore, .{
|
||||
.pointer = tmp_id,
|
||||
.object = array_id,
|
||||
});
|
||||
@@ -4441,7 +4442,7 @@ fn airArrayElemVal(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
const elem_ptr_id = try cg.accessChainId(ptr_elem_ty_id, tmp_id, &.{index_id});
|
||||
|
||||
const result_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpLoad, .{
|
||||
try cg.body.emit(gpa, .OpLoad, .{
|
||||
.id_result_type = try cg.resolveType(elem_ty, elem_repr),
|
||||
.id_result = result_id,
|
||||
.pointer = elem_ptr_id,
|
||||
@@ -4914,7 +4915,7 @@ fn structuredBreak(cg: *CodeGen, target_block: Id) !void {
|
||||
.loop => unreachable,
|
||||
};
|
||||
|
||||
try cg.body.emitBranch(cg.module.gpa, merge_block);
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_block });
|
||||
}
|
||||
|
||||
/// Generate a body in a way that exits the body using only structured constructs.
|
||||
@@ -4997,7 +4998,8 @@ fn genStructuredBody(
|
||||
while (i > 0) {
|
||||
i -= 1;
|
||||
const step = merge_stack[i];
|
||||
try cg.body.emitBranch(cg.module.gpa, step.merge_block);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = step.merge_block });
|
||||
try cg.beginSpvBlock(step.merge_block);
|
||||
const next_block = try cg.structuredNextBlock(&.{ incoming, step.incoming });
|
||||
incoming = .{
|
||||
@@ -5010,7 +5012,8 @@ fn genStructuredBody(
|
||||
},
|
||||
.loop => |merge| {
|
||||
// Close the loop by jumping to the continue label
|
||||
try cg.body.emitBranch(cg.module.gpa, block_merge_type.loop.continue_label);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = block_merge_type.loop.continue_label });
|
||||
// For blocks we must simple merge all the incoming blocks to get the next block.
|
||||
try cg.beginSpvBlock(merge.merge_block);
|
||||
return try cg.structuredNextBlock(merge.merges.items);
|
||||
@@ -5064,7 +5067,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index)
|
||||
const result_type_id = try cg.resolveType(ty, .direct);
|
||||
|
||||
try cg.body.emitRaw(
|
||||
cg.module.gpa,
|
||||
gpa,
|
||||
.OpPhi,
|
||||
// result type + result + variable/parent...
|
||||
2 + @as(u16, @intCast(block.incoming_blocks.items.len * 2)),
|
||||
@@ -5100,7 +5103,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index)
|
||||
const this_block = try cg.constInt(.u32, @intFromEnum(inst));
|
||||
const jump_to_this_block_id = cg.module.allocId();
|
||||
const bool_ty_id = try cg.resolveType(.bool, .direct);
|
||||
try cg.body.emit(cg.module.gpa, .OpIEqual, .{
|
||||
try cg.body.emit(gpa, .OpIEqual, .{
|
||||
.id_result_type = bool_ty_id,
|
||||
.id_result = jump_to_this_block_id,
|
||||
.operand_1 = next_block,
|
||||
@@ -5120,11 +5123,11 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index)
|
||||
// generate a conditional branch to there and to the instructions following this block.
|
||||
const merge_label = cg.module.allocId();
|
||||
const then_label = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpSelectionMerge, .{
|
||||
try cg.body.emit(gpa, .OpSelectionMerge, .{
|
||||
.merge_block = merge_label,
|
||||
.selection_control = .{},
|
||||
});
|
||||
try cg.body.emit(cg.module.gpa, .OpBranchConditional, .{
|
||||
try cg.body.emit(gpa, .OpBranchConditional, .{
|
||||
.condition = jump_to_this_block_id,
|
||||
.true_label = then_label,
|
||||
.false_label = merge_label,
|
||||
@@ -5143,7 +5146,7 @@ fn lowerBlock(cg: *CodeGen, inst: Air.Inst.Index, body: []const Air.Inst.Index)
|
||||
// To jump out of a loop block, generate a conditional that exits the block
|
||||
// to the loop merge if the target ID is not the one of this block.
|
||||
const continue_label = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpBranchConditional, .{
|
||||
try cg.body.emit(gpa, .OpBranchConditional, .{
|
||||
.condition = jump_to_this_block_id,
|
||||
.true_label = continue_label,
|
||||
.false_label = merge.merge_block,
|
||||
@@ -5197,12 +5200,13 @@ fn airBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
block.label = cg.module.allocId();
|
||||
}
|
||||
|
||||
try cg.body.emitBranch(cg.module.gpa, block.label.?);
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = block.label.? });
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
const gpa = cg.module.gpa;
|
||||
const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const cond_br = cg.air.extraData(Air.CondBr, pl_op.payload);
|
||||
const then_body: []const Air.Inst.Index = @ptrCast(cg.air.extra.items[cond_br.end..][0..cond_br.data.then_body_len]);
|
||||
@@ -5216,11 +5220,11 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
.structured => {
|
||||
const merge_label = cg.module.allocId();
|
||||
|
||||
try cg.body.emit(cg.module.gpa, .OpSelectionMerge, .{
|
||||
try cg.body.emit(gpa, .OpSelectionMerge, .{
|
||||
.merge_block = merge_label,
|
||||
.selection_control = .{},
|
||||
});
|
||||
try cg.body.emit(cg.module.gpa, .OpBranchConditional, .{
|
||||
try cg.body.emit(gpa, .OpBranchConditional, .{
|
||||
.condition = condition_id,
|
||||
.true_label = then_label,
|
||||
.false_label = else_label,
|
||||
@@ -5232,7 +5236,8 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
.src_label = cg.block_label,
|
||||
.next_block = then_next,
|
||||
};
|
||||
try cg.body.emitBranch(cg.module.gpa, merge_label);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label });
|
||||
|
||||
try cg.beginSpvBlock(else_label);
|
||||
const else_next = try cg.genStructuredBody(.selection, else_body);
|
||||
@@ -5240,7 +5245,8 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
.src_label = cg.block_label,
|
||||
.next_block = else_next,
|
||||
};
|
||||
try cg.body.emitBranch(cg.module.gpa, merge_label);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label });
|
||||
|
||||
try cg.beginSpvBlock(merge_label);
|
||||
const next_block = try cg.structuredNextBlock(&.{ then_incoming, else_incoming });
|
||||
@@ -5248,7 +5254,7 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
try cg.structuredBreak(next_block);
|
||||
},
|
||||
.unstructured => {
|
||||
try cg.body.emit(cg.module.gpa, .OpBranchConditional, .{
|
||||
try cg.body.emit(gpa, .OpBranchConditional, .{
|
||||
.condition = condition_id,
|
||||
.true_label = then_label,
|
||||
.false_label = else_label,
|
||||
@@ -5263,6 +5269,7 @@ fn airCondBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
}
|
||||
|
||||
fn airLoop(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
const gpa = cg.module.gpa;
|
||||
const ty_pl = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const loop = cg.air.extraData(Air.Block, ty_pl.payload);
|
||||
const body: []const Air.Inst.Index = @ptrCast(cg.air.extra.items[loop.end..][0..loop.data.body_len]);
|
||||
@@ -5278,16 +5285,18 @@ fn airLoop(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
// The back-edge must point to the loop header, so generate a separate block for the
|
||||
// loop header so that we don't accidentally include some instructions from there
|
||||
// in the loop.
|
||||
try cg.body.emitBranch(cg.module.gpa, header_label);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = header_label });
|
||||
try cg.beginSpvBlock(header_label);
|
||||
|
||||
// Emit loop header and jump to loop body
|
||||
try cg.body.emit(cg.module.gpa, .OpLoopMerge, .{
|
||||
try cg.body.emit(gpa, .OpLoopMerge, .{
|
||||
.merge_block = merge_label,
|
||||
.continue_target = continue_label,
|
||||
.loop_control = .{},
|
||||
});
|
||||
try cg.body.emitBranch(cg.module.gpa, body_label);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = body_label });
|
||||
|
||||
try cg.beginSpvBlock(body_label);
|
||||
|
||||
@@ -5298,13 +5307,15 @@ fn airLoop(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
try cg.structuredBreak(next_block);
|
||||
|
||||
try cg.beginSpvBlock(continue_label);
|
||||
try cg.body.emitBranch(cg.module.gpa, header_label);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = header_label });
|
||||
},
|
||||
.unstructured => {
|
||||
try cg.body.emitBranch(cg.module.gpa, body_label);
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = body_label });
|
||||
try cg.beginSpvBlock(body_label);
|
||||
try cg.genBody(body);
|
||||
try cg.body.emitBranch(cg.module.gpa, body_label);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = body_label });
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -5332,6 +5343,7 @@ fn airStore(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
}
|
||||
|
||||
fn airRet(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
const gpa = cg.module.gpa;
|
||||
const zcu = cg.module.zcu;
|
||||
const operand = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
|
||||
const ret_ty = cg.typeOf(operand);
|
||||
@@ -5342,17 +5354,18 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
// return type and return zero so they can be function pointers coerced
|
||||
// to functions that return anyerror.
|
||||
const no_err_id = try cg.constInt(.anyerror, 0);
|
||||
return try cg.body.emit(cg.module.gpa, .OpReturnValue, .{ .value = no_err_id });
|
||||
return try cg.body.emit(gpa, .OpReturnValue, .{ .value = no_err_id });
|
||||
} else {
|
||||
return try cg.body.emit(cg.module.gpa, .OpReturn, {});
|
||||
return try cg.body.emit(gpa, .OpReturn, {});
|
||||
}
|
||||
}
|
||||
|
||||
const operand_id = try cg.resolve(operand);
|
||||
try cg.body.emit(cg.module.gpa, .OpReturnValue, .{ .value = operand_id });
|
||||
try cg.body.emit(gpa, .OpReturnValue, .{ .value = operand_id });
|
||||
}
|
||||
|
||||
fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
const gpa = cg.module.gpa;
|
||||
const zcu = cg.module.zcu;
|
||||
const un_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
|
||||
const ptr_ty = cg.typeOf(un_op);
|
||||
@@ -5365,20 +5378,21 @@ fn airRetLoad(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
// return type and return zero so they can be function pointers coerced
|
||||
// to functions that return anyerror.
|
||||
const no_err_id = try cg.constInt(.anyerror, 0);
|
||||
return try cg.body.emit(cg.module.gpa, .OpReturnValue, .{ .value = no_err_id });
|
||||
return try cg.body.emit(gpa, .OpReturnValue, .{ .value = no_err_id });
|
||||
} else {
|
||||
return try cg.body.emit(cg.module.gpa, .OpReturn, {});
|
||||
return try cg.body.emit(gpa, .OpReturn, {});
|
||||
}
|
||||
}
|
||||
|
||||
const ptr = try cg.resolve(un_op);
|
||||
const value = try cg.load(ret_ty, ptr, .{ .is_volatile = ptr_ty.isVolatilePtr(zcu) });
|
||||
try cg.body.emit(cg.module.gpa, .OpReturnValue, .{
|
||||
try cg.body.emit(gpa, .OpReturnValue, .{
|
||||
.value = value,
|
||||
});
|
||||
}
|
||||
|
||||
fn airTry(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
const gpa = cg.module.gpa;
|
||||
const zcu = cg.module.zcu;
|
||||
const pl_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const err_union_id = try cg.resolve(pl_op.operand);
|
||||
@@ -5400,7 +5414,7 @@ fn airTry(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
|
||||
const zero_id = try cg.constInt(.anyerror, 0);
|
||||
const is_err_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpINotEqual, .{
|
||||
try cg.body.emit(gpa, .OpINotEqual, .{
|
||||
.id_result_type = bool_ty_id,
|
||||
.id_result = is_err_id,
|
||||
.operand_1 = err_id,
|
||||
@@ -5420,7 +5434,7 @@ fn airTry(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
// to not break and end in a return instruction. Thus,
|
||||
// for structured control flow, we can just naively use
|
||||
// the ok block as the merge block here.
|
||||
try cg.body.emit(cg.module.gpa, .OpSelectionMerge, .{
|
||||
try cg.body.emit(gpa, .OpSelectionMerge, .{
|
||||
.merge_block = ok_block,
|
||||
.selection_control = .{},
|
||||
});
|
||||
@@ -5428,7 +5442,7 @@ fn airTry(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
.unstructured => {},
|
||||
}
|
||||
|
||||
try cg.body.emit(cg.module.gpa, .OpBranchConditional, .{
|
||||
try cg.body.emit(gpa, .OpBranchConditional, .{
|
||||
.condition = is_err_id,
|
||||
.true_label = err_block,
|
||||
.false_label = ok_block,
|
||||
@@ -5768,14 +5782,14 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
};
|
||||
|
||||
if (cg.control_flow == .structured) {
|
||||
try cg.body.emit(cg.module.gpa, .OpSelectionMerge, .{
|
||||
try cg.body.emit(gpa, .OpSelectionMerge, .{
|
||||
.merge_block = merge_label.?,
|
||||
.selection_control = .{},
|
||||
});
|
||||
}
|
||||
|
||||
// Emit the instruction before generating the blocks.
|
||||
try cg.body.emitRaw(cg.module.gpa, .OpSwitch, 2 + (cond_words + 1) * num_conditions);
|
||||
try cg.body.emitRaw(gpa, .OpSwitch, 2 + (cond_words + 1) * num_conditions);
|
||||
cg.body.writeOperand(Id, cond_indirect);
|
||||
cg.body.writeOperand(Id, default);
|
||||
|
||||
@@ -5830,7 +5844,8 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
.src_label = cg.block_label,
|
||||
.next_block = next_block,
|
||||
});
|
||||
try cg.body.emitBranch(cg.module.gpa, merge_label.?);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label.? });
|
||||
},
|
||||
.unstructured => {
|
||||
try cg.genBody(case.body);
|
||||
@@ -5848,14 +5863,15 @@ fn airSwitchBr(cg: *CodeGen, inst: Air.Inst.Index) !void {
|
||||
.src_label = cg.block_label,
|
||||
.next_block = next_block,
|
||||
});
|
||||
try cg.body.emitBranch(cg.module.gpa, merge_label.?);
|
||||
|
||||
try cg.body.emit(gpa, .OpBranch, .{ .target_label = merge_label.? });
|
||||
},
|
||||
.unstructured => {
|
||||
try cg.genBody(else_body);
|
||||
},
|
||||
}
|
||||
} else {
|
||||
try cg.body.emit(cg.module.gpa, .OpUnreachable, {});
|
||||
try cg.body.emit(gpa, .OpUnreachable, {});
|
||||
}
|
||||
|
||||
if (cg.control_flow == .structured) {
|
||||
@@ -5921,8 +5937,8 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
return cg.todo("implement inline asm with more than 1 output", .{});
|
||||
}
|
||||
|
||||
var as: Assembler = .{ .cg = cg };
|
||||
defer as.deinit();
|
||||
var ass: Assembler = .{ .cg = cg };
|
||||
defer ass.deinit();
|
||||
|
||||
var output_extra_i = extra_i;
|
||||
for (outputs) |output| {
|
||||
@@ -5974,8 +5990,8 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
|
||||
.undef => return cg.fail("assembly input with 'c' constraint cannot be undefined", .{}),
|
||||
|
||||
.int => try as.value_map.put(gpa, name, .{ .constant = @intCast(val.toUnsignedInt(zcu)) }),
|
||||
.enum_literal => |str| try as.value_map.put(gpa, name, .{ .string = str.toSlice(ip) }),
|
||||
.int => try ass.value_map.put(gpa, name, .{ .constant = @intCast(val.toUnsignedInt(zcu)) }),
|
||||
.enum_literal => |str| try ass.value_map.put(gpa, name, .{ .string = str.toSlice(ip) }),
|
||||
|
||||
else => unreachable, // TODO
|
||||
}
|
||||
@@ -5986,10 +6002,10 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
// That's fine for now, just make sure to resolve it as such.
|
||||
const val = (try cg.air.value(input, cg.pt)).?;
|
||||
const ty_id = try cg.resolveType(val.toType(), .direct);
|
||||
try as.value_map.put(gpa, name, .{ .ty = ty_id });
|
||||
try ass.value_map.put(gpa, name, .{ .ty = ty_id });
|
||||
} else {
|
||||
const ty_id = try cg.resolveType(input_ty, .direct);
|
||||
try as.value_map.put(gpa, name, .{ .ty = ty_id });
|
||||
try ass.value_map.put(gpa, name, .{ .ty = ty_id });
|
||||
}
|
||||
} else {
|
||||
if (input_ty.zigTypeTag(zcu) == .type) {
|
||||
@@ -5997,7 +6013,7 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
}
|
||||
|
||||
const val_id = try cg.resolve(input);
|
||||
try as.value_map.put(gpa, name, .{ .value = val_id });
|
||||
try ass.value_map.put(gpa, name, .{ .value = val_id });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6006,17 +6022,17 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
|
||||
const asm_source = std.mem.sliceAsBytes(cg.air.extra.items[extra_i..])[0..extra.data.source_len];
|
||||
|
||||
as.assemble(asm_source) catch |err| switch (err) {
|
||||
ass.assemble(asm_source) catch |err| switch (err) {
|
||||
error.AssembleFail => {
|
||||
// TODO: For now the compiler only supports a single error message per decl,
|
||||
// so to translate the possible multiple errors from the assembler, emit
|
||||
// them as notes here.
|
||||
// TODO: Translate proper error locations.
|
||||
assert(as.errors.items.len != 0);
|
||||
assert(ass.errors.items.len != 0);
|
||||
assert(cg.error_msg == null);
|
||||
const src_loc = zcu.navSrcLoc(cg.owner_nav);
|
||||
cg.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
|
||||
const notes = try zcu.gpa.alloc(Zcu.ErrorMsg, as.errors.items.len);
|
||||
const notes = try zcu.gpa.alloc(Zcu.ErrorMsg, ass.errors.items.len);
|
||||
|
||||
// Sub-scope to prevent `return error.CodegenFail` from running the errdefers.
|
||||
{
|
||||
@@ -6026,8 +6042,8 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
note.deinit(zcu.gpa);
|
||||
};
|
||||
|
||||
while (i < as.errors.items.len) : (i += 1) {
|
||||
notes[i] = try Zcu.ErrorMsg.init(zcu.gpa, src_loc, "{s}", .{as.errors.items[i].msg});
|
||||
while (i < ass.errors.items.len) : (i += 1) {
|
||||
notes[i] = try Zcu.ErrorMsg.init(zcu.gpa, src_loc, "{s}", .{ass.errors.items[i].msg});
|
||||
}
|
||||
}
|
||||
cg.error_msg.?.notes = notes;
|
||||
@@ -6043,7 +6059,7 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
|
||||
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
||||
output_extra_i += (constraint.len + name.len + (2 + 3)) / 4;
|
||||
|
||||
const result = as.value_map.get(name) orelse return {
|
||||
const result = ass.value_map.get(name) orelse return {
|
||||
return cg.fail("invalid asm output '{s}'", .{name});
|
||||
};
|
||||
|
||||
@@ -6083,8 +6099,11 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
|
||||
const callee_id = try cg.resolve(pl_op.operand);
|
||||
|
||||
comptime assert(zig_call_abi_ver == 3);
|
||||
const params = try gpa.alloc(Id, args.len);
|
||||
defer gpa.free(params);
|
||||
|
||||
const scratch_top = cg.id_scratch.items.len;
|
||||
defer cg.id_scratch.shrinkRetainingCapacity(scratch_top);
|
||||
const params = try cg.id_scratch.addManyAsSlice(gpa, args.len);
|
||||
|
||||
var n_params: usize = 0;
|
||||
for (args) |arg| {
|
||||
// Note: resolve() might emit instructions, so we need to call it
|
||||
@@ -6098,7 +6117,7 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
|
||||
n_params += 1;
|
||||
}
|
||||
|
||||
try cg.body.emit(cg.module.gpa, .OpFunctionCall, .{
|
||||
try cg.body.emit(gpa, .OpFunctionCall, .{
|
||||
.id_result_type = result_type_id,
|
||||
.id_result = result_id,
|
||||
.function = callee_id,
|
||||
@@ -6119,15 +6138,16 @@ fn builtin3D(
|
||||
dimension: u32,
|
||||
out_of_range_value: anytype,
|
||||
) !Id {
|
||||
const gpa = cg.module.gpa;
|
||||
if (dimension >= 3) return try cg.constInt(result_ty, out_of_range_value);
|
||||
const u32_ty_id = try cg.module.intType(.unsigned, 32);
|
||||
const vec_ty_id = try cg.module.vectorType(3, u32_ty_id);
|
||||
const ptr_ty_id = try cg.module.ptrType(vec_ty_id, .input);
|
||||
const spv_decl_index = try cg.module.builtin(ptr_ty_id, builtin, .input);
|
||||
try cg.decl_deps.put(cg.module.gpa, spv_decl_index, {});
|
||||
try cg.module.decl_deps.append(gpa, spv_decl_index);
|
||||
const ptr_id = cg.module.declPtr(spv_decl_index).result_id;
|
||||
const vec_id = cg.module.allocId();
|
||||
try cg.body.emit(cg.module.gpa, .OpLoad, .{
|
||||
try cg.body.emit(gpa, .OpLoad, .{
|
||||
.id_result_type = vec_ty_id,
|
||||
.id_result = vec_id,
|
||||
.pointer = ptr_id,
|
||||
|
||||
@@ -125,9 +125,9 @@ pub const Decl = struct {
|
||||
/// - For `invocation_global`, this is the result-id of the associated InvocationGlobal instruction.
|
||||
result_id: Id,
|
||||
/// The offset of the first dependency of this decl in the `decl_deps` array.
|
||||
begin_dep: u32,
|
||||
begin_dep: usize = 0,
|
||||
/// The past-end offset of the dependencies of this decl in the `decl_deps` array.
|
||||
end_dep: u32,
|
||||
end_dep: usize = 0,
|
||||
};
|
||||
|
||||
/// This models a kernel entry point.
|
||||
@@ -258,7 +258,6 @@ pub fn resolveNav(module: *Module, ip: *InternPool, nav_index: InternPool.Nav.In
|
||||
.generic => .invocation_global,
|
||||
else => .global,
|
||||
};
|
||||
|
||||
entry.value_ptr.* = try module.allocDecl(kind);
|
||||
}
|
||||
|
||||
@@ -782,15 +781,15 @@ pub fn builtin(
|
||||
const gop = try module.cache.builtins.getOrPut(module.gpa, .{ spirv_builtin, storage_class });
|
||||
if (!gop.found_existing) {
|
||||
const decl_index = try module.allocDecl(.global);
|
||||
const result_id = module.declPtr(decl_index).result_id;
|
||||
const decl = module.declPtr(decl_index);
|
||||
|
||||
gop.value_ptr.* = decl_index;
|
||||
try module.sections.globals.emit(module.gpa, .OpVariable, .{
|
||||
.id_result_type = result_ty_id,
|
||||
.id_result = result_id,
|
||||
.id_result = decl.result_id,
|
||||
.storage_class = storage_class,
|
||||
});
|
||||
try module.decorate(result_id, .{ .built_in = .{ .built_in = spirv_builtin } });
|
||||
try module.declareDeclDeps(decl_index, &.{});
|
||||
try module.decorate(decl.result_id, .{ .built_in = .{ .built_in = spirv_builtin } });
|
||||
}
|
||||
return gop.value_ptr.*;
|
||||
}
|
||||
@@ -847,8 +846,6 @@ pub fn allocDecl(module: *Module, kind: Decl.Kind) !Decl.Index {
|
||||
try module.decls.append(module.gpa, .{
|
||||
.kind = kind,
|
||||
.result_id = module.allocId(),
|
||||
.begin_dep = undefined,
|
||||
.end_dep = undefined,
|
||||
});
|
||||
|
||||
return @as(Decl.Index, @enumFromInt(@as(u32, @intCast(module.decls.items.len - 1))));
|
||||
@@ -858,17 +855,6 @@ pub fn declPtr(module: *Module, index: Decl.Index) *Decl {
|
||||
return &module.decls.items[@intFromEnum(index)];
|
||||
}
|
||||
|
||||
/// Declare ALL dependencies for a decl.
|
||||
pub fn declareDeclDeps(module: *Module, decl_index: Decl.Index, deps: []const Decl.Index) !void {
|
||||
const begin_dep: u32 = @intCast(module.decl_deps.items.len);
|
||||
try module.decl_deps.appendSlice(module.gpa, deps);
|
||||
const end_dep: u32 = @intCast(module.decl_deps.items.len);
|
||||
|
||||
const decl = module.declPtr(decl_index);
|
||||
decl.begin_dep = begin_dep;
|
||||
decl.end_dep = end_dep;
|
||||
}
|
||||
|
||||
/// Declare a SPIR-V function as an entry point. This causes an extra wrapper
|
||||
/// function to be generated, which is then exported as the real entry point. The purpose of this
|
||||
/// wrapper is to allocate and initialize the structure holding the instance globals.
|
||||
|
||||
@@ -21,7 +21,7 @@ pub fn deinit(section: *Section, allocator: Allocator) void {
|
||||
}
|
||||
|
||||
pub fn reset(section: *Section) void {
|
||||
section.instructions.items.len = 0;
|
||||
section.instructions.clearRetainingCapacity();
|
||||
}
|
||||
|
||||
pub fn toWords(section: Section) []Word {
|
||||
@@ -86,16 +86,6 @@ pub fn emit(
|
||||
section.writeOperands(opcode.Operands(), operands);
|
||||
}
|
||||
|
||||
pub fn emitBranch(
|
||||
section: *Section,
|
||||
allocator: Allocator,
|
||||
target_label: spec.Id,
|
||||
) !void {
|
||||
try section.emit(allocator, .OpBranch, .{
|
||||
.target_label = target_label,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn writeWord(section: *Section, word: Word) void {
|
||||
section.instructions.appendAssumeCapacity(word);
|
||||
}
|
||||
|
||||
+254
-3000
@@ -191,25 +191,6 @@ pub const OperandKind = enum {
|
||||
pair_id_ref_literal_integer,
|
||||
pair_id_ref_id_ref,
|
||||
tensor_operands,
|
||||
debug_info_debug_info_flags,
|
||||
debug_info_debug_base_type_attribute_encoding,
|
||||
debug_info_debug_composite_type,
|
||||
debug_info_debug_type_qualifier,
|
||||
debug_info_debug_operation,
|
||||
open_cl_debug_info_100_debug_info_flags,
|
||||
open_cl_debug_info_100_debug_base_type_attribute_encoding,
|
||||
open_cl_debug_info_100_debug_composite_type,
|
||||
open_cl_debug_info_100_debug_type_qualifier,
|
||||
open_cl_debug_info_100_debug_operation,
|
||||
open_cl_debug_info_100_debug_imported_entity,
|
||||
non_semantic_clspv_reflection_6_kernel_property_flags,
|
||||
non_semantic_shader_debug_info_100_debug_info_flags,
|
||||
non_semantic_shader_debug_info_100_build_identifier_flags,
|
||||
non_semantic_shader_debug_info_100_debug_base_type_attribute_encoding,
|
||||
non_semantic_shader_debug_info_100_debug_composite_type,
|
||||
non_semantic_shader_debug_info_100_debug_type_qualifier,
|
||||
non_semantic_shader_debug_info_100_debug_operation,
|
||||
non_semantic_shader_debug_info_100_debug_imported_entity,
|
||||
|
||||
pub fn category(self: OperandKind) OperandCategory {
|
||||
return switch (self) {
|
||||
@@ -285,25 +266,6 @@ pub const OperandKind = enum {
|
||||
.pair_id_ref_literal_integer => .composite,
|
||||
.pair_id_ref_id_ref => .composite,
|
||||
.tensor_operands => .bit_enum,
|
||||
.debug_info_debug_info_flags => .bit_enum,
|
||||
.debug_info_debug_base_type_attribute_encoding => .value_enum,
|
||||
.debug_info_debug_composite_type => .value_enum,
|
||||
.debug_info_debug_type_qualifier => .value_enum,
|
||||
.debug_info_debug_operation => .value_enum,
|
||||
.open_cl_debug_info_100_debug_info_flags => .bit_enum,
|
||||
.open_cl_debug_info_100_debug_base_type_attribute_encoding => .value_enum,
|
||||
.open_cl_debug_info_100_debug_composite_type => .value_enum,
|
||||
.open_cl_debug_info_100_debug_type_qualifier => .value_enum,
|
||||
.open_cl_debug_info_100_debug_operation => .value_enum,
|
||||
.open_cl_debug_info_100_debug_imported_entity => .value_enum,
|
||||
.non_semantic_clspv_reflection_6_kernel_property_flags => .bit_enum,
|
||||
.non_semantic_shader_debug_info_100_debug_info_flags => .bit_enum,
|
||||
.non_semantic_shader_debug_info_100_build_identifier_flags => .bit_enum,
|
||||
.non_semantic_shader_debug_info_100_debug_base_type_attribute_encoding => .value_enum,
|
||||
.non_semantic_shader_debug_info_100_debug_composite_type => .value_enum,
|
||||
.non_semantic_shader_debug_info_100_debug_type_qualifier => .value_enum,
|
||||
.non_semantic_shader_debug_info_100_debug_operation => .value_enum,
|
||||
.non_semantic_shader_debug_info_100_debug_imported_entity => .value_enum,
|
||||
};
|
||||
}
|
||||
pub fn enumerants(self: OperandKind) []const Enumerant {
|
||||
@@ -1475,178 +1437,10 @@ pub const OperandKind = enum {
|
||||
.{ .name = "MakeElementVisibleARM", .value = 0x0008, .parameters = &.{.id_ref} },
|
||||
.{ .name = "NonPrivateElementARM", .value = 0x0010, .parameters = &.{} },
|
||||
},
|
||||
.debug_info_debug_info_flags => &.{
|
||||
.{ .name = "FlagIsProtected", .value = 0x01, .parameters = &.{} },
|
||||
.{ .name = "FlagIsPrivate", .value = 0x02, .parameters = &.{} },
|
||||
.{ .name = "FlagIsPublic", .value = 0x03, .parameters = &.{} },
|
||||
.{ .name = "FlagIsLocal", .value = 0x04, .parameters = &.{} },
|
||||
.{ .name = "FlagIsDefinition", .value = 0x08, .parameters = &.{} },
|
||||
.{ .name = "FlagFwdDecl", .value = 0x10, .parameters = &.{} },
|
||||
.{ .name = "FlagArtificial", .value = 0x20, .parameters = &.{} },
|
||||
.{ .name = "FlagExplicit", .value = 0x40, .parameters = &.{} },
|
||||
.{ .name = "FlagPrototyped", .value = 0x80, .parameters = &.{} },
|
||||
.{ .name = "FlagObjectPointer", .value = 0x100, .parameters = &.{} },
|
||||
.{ .name = "FlagStaticMember", .value = 0x200, .parameters = &.{} },
|
||||
.{ .name = "FlagIndirectVariable", .value = 0x400, .parameters = &.{} },
|
||||
.{ .name = "FlagLValueReference", .value = 0x800, .parameters = &.{} },
|
||||
.{ .name = "FlagRValueReference", .value = 0x1000, .parameters = &.{} },
|
||||
.{ .name = "FlagIsOptimized", .value = 0x2000, .parameters = &.{} },
|
||||
},
|
||||
.debug_info_debug_base_type_attribute_encoding => &.{
|
||||
.{ .name = "Unspecified", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Address", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Boolean", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "Float", .value = 4, .parameters = &.{} },
|
||||
.{ .name = "Signed", .value = 5, .parameters = &.{} },
|
||||
.{ .name = "SignedChar", .value = 6, .parameters = &.{} },
|
||||
.{ .name = "Unsigned", .value = 7, .parameters = &.{} },
|
||||
.{ .name = "UnsignedChar", .value = 8, .parameters = &.{} },
|
||||
},
|
||||
.debug_info_debug_composite_type => &.{
|
||||
.{ .name = "Class", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Structure", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Union", .value = 2, .parameters = &.{} },
|
||||
},
|
||||
.debug_info_debug_type_qualifier => &.{
|
||||
.{ .name = "ConstType", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "VolatileType", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "RestrictType", .value = 2, .parameters = &.{} },
|
||||
},
|
||||
.debug_info_debug_operation => &.{
|
||||
.{ .name = "Deref", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Plus", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Minus", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "PlusUconst", .value = 3, .parameters = &.{.literal_integer} },
|
||||
.{ .name = "BitPiece", .value = 4, .parameters = &.{ .literal_integer, .literal_integer } },
|
||||
.{ .name = "Swap", .value = 5, .parameters = &.{} },
|
||||
.{ .name = "Xderef", .value = 6, .parameters = &.{} },
|
||||
.{ .name = "StackValue", .value = 7, .parameters = &.{} },
|
||||
.{ .name = "Constu", .value = 8, .parameters = &.{.literal_integer} },
|
||||
},
|
||||
.open_cl_debug_info_100_debug_info_flags => &.{
|
||||
.{ .name = "FlagIsProtected", .value = 0x01, .parameters = &.{} },
|
||||
.{ .name = "FlagIsPrivate", .value = 0x02, .parameters = &.{} },
|
||||
.{ .name = "FlagIsPublic", .value = 0x03, .parameters = &.{} },
|
||||
.{ .name = "FlagIsLocal", .value = 0x04, .parameters = &.{} },
|
||||
.{ .name = "FlagIsDefinition", .value = 0x08, .parameters = &.{} },
|
||||
.{ .name = "FlagFwdDecl", .value = 0x10, .parameters = &.{} },
|
||||
.{ .name = "FlagArtificial", .value = 0x20, .parameters = &.{} },
|
||||
.{ .name = "FlagExplicit", .value = 0x40, .parameters = &.{} },
|
||||
.{ .name = "FlagPrototyped", .value = 0x80, .parameters = &.{} },
|
||||
.{ .name = "FlagObjectPointer", .value = 0x100, .parameters = &.{} },
|
||||
.{ .name = "FlagStaticMember", .value = 0x200, .parameters = &.{} },
|
||||
.{ .name = "FlagIndirectVariable", .value = 0x400, .parameters = &.{} },
|
||||
.{ .name = "FlagLValueReference", .value = 0x800, .parameters = &.{} },
|
||||
.{ .name = "FlagRValueReference", .value = 0x1000, .parameters = &.{} },
|
||||
.{ .name = "FlagIsOptimized", .value = 0x2000, .parameters = &.{} },
|
||||
.{ .name = "FlagIsEnumClass", .value = 0x4000, .parameters = &.{} },
|
||||
.{ .name = "FlagTypePassByValue", .value = 0x8000, .parameters = &.{} },
|
||||
.{ .name = "FlagTypePassByReference", .value = 0x10000, .parameters = &.{} },
|
||||
},
|
||||
.open_cl_debug_info_100_debug_base_type_attribute_encoding => &.{
|
||||
.{ .name = "Unspecified", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Address", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Boolean", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "Float", .value = 3, .parameters = &.{} },
|
||||
.{ .name = "Signed", .value = 4, .parameters = &.{} },
|
||||
.{ .name = "SignedChar", .value = 5, .parameters = &.{} },
|
||||
.{ .name = "Unsigned", .value = 6, .parameters = &.{} },
|
||||
.{ .name = "UnsignedChar", .value = 7, .parameters = &.{} },
|
||||
},
|
||||
.open_cl_debug_info_100_debug_composite_type => &.{
|
||||
.{ .name = "Class", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Structure", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Union", .value = 2, .parameters = &.{} },
|
||||
},
|
||||
.open_cl_debug_info_100_debug_type_qualifier => &.{
|
||||
.{ .name = "ConstType", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "VolatileType", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "RestrictType", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "AtomicType", .value = 3, .parameters = &.{} },
|
||||
},
|
||||
.open_cl_debug_info_100_debug_operation => &.{
|
||||
.{ .name = "Deref", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Plus", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Minus", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "PlusUconst", .value = 3, .parameters = &.{.literal_integer} },
|
||||
.{ .name = "BitPiece", .value = 4, .parameters = &.{ .literal_integer, .literal_integer } },
|
||||
.{ .name = "Swap", .value = 5, .parameters = &.{} },
|
||||
.{ .name = "Xderef", .value = 6, .parameters = &.{} },
|
||||
.{ .name = "StackValue", .value = 7, .parameters = &.{} },
|
||||
.{ .name = "Constu", .value = 8, .parameters = &.{.literal_integer} },
|
||||
.{ .name = "Fragment", .value = 9, .parameters = &.{ .literal_integer, .literal_integer } },
|
||||
},
|
||||
.open_cl_debug_info_100_debug_imported_entity => &.{
|
||||
.{ .name = "ImportedModule", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "ImportedDeclaration", .value = 1, .parameters = &.{} },
|
||||
},
|
||||
.non_semantic_clspv_reflection_6_kernel_property_flags => &.{
|
||||
.{ .name = "MayUsePrintf", .value = 0x1, .parameters = &.{} },
|
||||
},
|
||||
.non_semantic_shader_debug_info_100_debug_info_flags => &.{
|
||||
.{ .name = "FlagIsProtected", .value = 0x01, .parameters = &.{} },
|
||||
.{ .name = "FlagIsPrivate", .value = 0x02, .parameters = &.{} },
|
||||
.{ .name = "FlagIsPublic", .value = 0x03, .parameters = &.{} },
|
||||
.{ .name = "FlagIsLocal", .value = 0x04, .parameters = &.{} },
|
||||
.{ .name = "FlagIsDefinition", .value = 0x08, .parameters = &.{} },
|
||||
.{ .name = "FlagFwdDecl", .value = 0x10, .parameters = &.{} },
|
||||
.{ .name = "FlagArtificial", .value = 0x20, .parameters = &.{} },
|
||||
.{ .name = "FlagExplicit", .value = 0x40, .parameters = &.{} },
|
||||
.{ .name = "FlagPrototyped", .value = 0x80, .parameters = &.{} },
|
||||
.{ .name = "FlagObjectPointer", .value = 0x100, .parameters = &.{} },
|
||||
.{ .name = "FlagStaticMember", .value = 0x200, .parameters = &.{} },
|
||||
.{ .name = "FlagIndirectVariable", .value = 0x400, .parameters = &.{} },
|
||||
.{ .name = "FlagLValueReference", .value = 0x800, .parameters = &.{} },
|
||||
.{ .name = "FlagRValueReference", .value = 0x1000, .parameters = &.{} },
|
||||
.{ .name = "FlagIsOptimized", .value = 0x2000, .parameters = &.{} },
|
||||
.{ .name = "FlagIsEnumClass", .value = 0x4000, .parameters = &.{} },
|
||||
.{ .name = "FlagTypePassByValue", .value = 0x8000, .parameters = &.{} },
|
||||
.{ .name = "FlagTypePassByReference", .value = 0x10000, .parameters = &.{} },
|
||||
.{ .name = "FlagUnknownPhysicalLayout", .value = 0x20000, .parameters = &.{} },
|
||||
},
|
||||
.non_semantic_shader_debug_info_100_build_identifier_flags => &.{
|
||||
.{ .name = "IdentifierPossibleDuplicates", .value = 0x01, .parameters = &.{} },
|
||||
},
|
||||
.non_semantic_shader_debug_info_100_debug_base_type_attribute_encoding => &.{
|
||||
.{ .name = "Unspecified", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Address", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Boolean", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "Float", .value = 3, .parameters = &.{} },
|
||||
.{ .name = "Signed", .value = 4, .parameters = &.{} },
|
||||
.{ .name = "SignedChar", .value = 5, .parameters = &.{} },
|
||||
.{ .name = "Unsigned", .value = 6, .parameters = &.{} },
|
||||
.{ .name = "UnsignedChar", .value = 7, .parameters = &.{} },
|
||||
},
|
||||
.non_semantic_shader_debug_info_100_debug_composite_type => &.{
|
||||
.{ .name = "Class", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Structure", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Union", .value = 2, .parameters = &.{} },
|
||||
},
|
||||
.non_semantic_shader_debug_info_100_debug_type_qualifier => &.{
|
||||
.{ .name = "ConstType", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "VolatileType", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "RestrictType", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "AtomicType", .value = 3, .parameters = &.{} },
|
||||
},
|
||||
.non_semantic_shader_debug_info_100_debug_operation => &.{
|
||||
.{ .name = "Deref", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "Plus", .value = 1, .parameters = &.{} },
|
||||
.{ .name = "Minus", .value = 2, .parameters = &.{} },
|
||||
.{ .name = "PlusUconst", .value = 3, .parameters = &.{.id_ref} },
|
||||
.{ .name = "BitPiece", .value = 4, .parameters = &.{ .id_ref, .id_ref } },
|
||||
.{ .name = "Swap", .value = 5, .parameters = &.{} },
|
||||
.{ .name = "Xderef", .value = 6, .parameters = &.{} },
|
||||
.{ .name = "StackValue", .value = 7, .parameters = &.{} },
|
||||
.{ .name = "Constu", .value = 8, .parameters = &.{.id_ref} },
|
||||
.{ .name = "Fragment", .value = 9, .parameters = &.{ .id_ref, .id_ref } },
|
||||
},
|
||||
.non_semantic_shader_debug_info_100_debug_imported_entity => &.{
|
||||
.{ .name = "ImportedModule", .value = 0, .parameters = &.{} },
|
||||
.{ .name = "ImportedDeclaration", .value = 1, .parameters = &.{} },
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Opcode = enum(u16) {
|
||||
OpNop = 0,
|
||||
OpUndef = 1,
|
||||
@@ -3533,6 +3327,259 @@ pub const Opcode = enum(u16) {
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const GlslOpcode = enum(u16) {
|
||||
Round = 1,
|
||||
RoundEven = 2,
|
||||
Trunc = 3,
|
||||
FAbs = 4,
|
||||
SAbs = 5,
|
||||
FSign = 6,
|
||||
SSign = 7,
|
||||
Floor = 8,
|
||||
Ceil = 9,
|
||||
Fract = 10,
|
||||
Radians = 11,
|
||||
Degrees = 12,
|
||||
Sin = 13,
|
||||
Cos = 14,
|
||||
Tan = 15,
|
||||
Asin = 16,
|
||||
Acos = 17,
|
||||
Atan = 18,
|
||||
Sinh = 19,
|
||||
Cosh = 20,
|
||||
Tanh = 21,
|
||||
Asinh = 22,
|
||||
Acosh = 23,
|
||||
Atanh = 24,
|
||||
Atan2 = 25,
|
||||
Pow = 26,
|
||||
Exp = 27,
|
||||
Log = 28,
|
||||
Exp2 = 29,
|
||||
Log2 = 30,
|
||||
Sqrt = 31,
|
||||
InverseSqrt = 32,
|
||||
Determinant = 33,
|
||||
MatrixInverse = 34,
|
||||
Modf = 35,
|
||||
ModfStruct = 36,
|
||||
FMin = 37,
|
||||
UMin = 38,
|
||||
SMin = 39,
|
||||
FMax = 40,
|
||||
UMax = 41,
|
||||
SMax = 42,
|
||||
FClamp = 43,
|
||||
UClamp = 44,
|
||||
SClamp = 45,
|
||||
FMix = 46,
|
||||
IMix = 47,
|
||||
Step = 48,
|
||||
SmoothStep = 49,
|
||||
Fma = 50,
|
||||
Frexp = 51,
|
||||
FrexpStruct = 52,
|
||||
Ldexp = 53,
|
||||
PackSnorm4x8 = 54,
|
||||
PackUnorm4x8 = 55,
|
||||
PackSnorm2x16 = 56,
|
||||
PackUnorm2x16 = 57,
|
||||
PackHalf2x16 = 58,
|
||||
PackDouble2x32 = 59,
|
||||
UnpackSnorm2x16 = 60,
|
||||
UnpackUnorm2x16 = 61,
|
||||
UnpackHalf2x16 = 62,
|
||||
UnpackSnorm4x8 = 63,
|
||||
UnpackUnorm4x8 = 64,
|
||||
UnpackDouble2x32 = 65,
|
||||
Length = 66,
|
||||
Distance = 67,
|
||||
Cross = 68,
|
||||
Normalize = 69,
|
||||
FaceForward = 70,
|
||||
Reflect = 71,
|
||||
Refract = 72,
|
||||
FindILsb = 73,
|
||||
FindSMsb = 74,
|
||||
FindUMsb = 75,
|
||||
InterpolateAtCentroid = 76,
|
||||
InterpolateAtSample = 77,
|
||||
InterpolateAtOffset = 78,
|
||||
NMin = 79,
|
||||
NMax = 80,
|
||||
NClamp = 81,
|
||||
};
|
||||
|
||||
pub const OpenClOpcode = enum(u16) {
|
||||
acos = 0,
|
||||
acosh = 1,
|
||||
acospi = 2,
|
||||
asin = 3,
|
||||
asinh = 4,
|
||||
asinpi = 5,
|
||||
atan = 6,
|
||||
atan2 = 7,
|
||||
atanh = 8,
|
||||
atanpi = 9,
|
||||
atan2pi = 10,
|
||||
cbrt = 11,
|
||||
ceil = 12,
|
||||
copysign = 13,
|
||||
cos = 14,
|
||||
cosh = 15,
|
||||
cospi = 16,
|
||||
erfc = 17,
|
||||
erf = 18,
|
||||
exp = 19,
|
||||
exp2 = 20,
|
||||
exp10 = 21,
|
||||
expm1 = 22,
|
||||
fabs = 23,
|
||||
fdim = 24,
|
||||
floor = 25,
|
||||
fma = 26,
|
||||
fmax = 27,
|
||||
fmin = 28,
|
||||
fmod = 29,
|
||||
fract = 30,
|
||||
frexp = 31,
|
||||
hypot = 32,
|
||||
ilogb = 33,
|
||||
ldexp = 34,
|
||||
lgamma = 35,
|
||||
lgamma_r = 36,
|
||||
log = 37,
|
||||
log2 = 38,
|
||||
log10 = 39,
|
||||
log1p = 40,
|
||||
logb = 41,
|
||||
mad = 42,
|
||||
maxmag = 43,
|
||||
minmag = 44,
|
||||
modf = 45,
|
||||
nan = 46,
|
||||
nextafter = 47,
|
||||
pow = 48,
|
||||
pown = 49,
|
||||
powr = 50,
|
||||
remainder = 51,
|
||||
remquo = 52,
|
||||
rint = 53,
|
||||
rootn = 54,
|
||||
round = 55,
|
||||
rsqrt = 56,
|
||||
sin = 57,
|
||||
sincos = 58,
|
||||
sinh = 59,
|
||||
sinpi = 60,
|
||||
sqrt = 61,
|
||||
tan = 62,
|
||||
tanh = 63,
|
||||
tanpi = 64,
|
||||
tgamma = 65,
|
||||
trunc = 66,
|
||||
half_cos = 67,
|
||||
half_divide = 68,
|
||||
half_exp = 69,
|
||||
half_exp2 = 70,
|
||||
half_exp10 = 71,
|
||||
half_log = 72,
|
||||
half_log2 = 73,
|
||||
half_log10 = 74,
|
||||
half_powr = 75,
|
||||
half_recip = 76,
|
||||
half_rsqrt = 77,
|
||||
half_sin = 78,
|
||||
half_sqrt = 79,
|
||||
half_tan = 80,
|
||||
native_cos = 81,
|
||||
native_divide = 82,
|
||||
native_exp = 83,
|
||||
native_exp2 = 84,
|
||||
native_exp10 = 85,
|
||||
native_log = 86,
|
||||
native_log2 = 87,
|
||||
native_log10 = 88,
|
||||
native_powr = 89,
|
||||
native_recip = 90,
|
||||
native_rsqrt = 91,
|
||||
native_sin = 92,
|
||||
native_sqrt = 93,
|
||||
native_tan = 94,
|
||||
fclamp = 95,
|
||||
degrees = 96,
|
||||
fmax_common = 97,
|
||||
fmin_common = 98,
|
||||
mix = 99,
|
||||
radians = 100,
|
||||
step = 101,
|
||||
smoothstep = 102,
|
||||
sign = 103,
|
||||
cross = 104,
|
||||
distance = 105,
|
||||
length = 106,
|
||||
normalize = 107,
|
||||
fast_distance = 108,
|
||||
fast_length = 109,
|
||||
fast_normalize = 110,
|
||||
s_abs = 141,
|
||||
s_abs_diff = 142,
|
||||
s_add_sat = 143,
|
||||
u_add_sat = 144,
|
||||
s_hadd = 145,
|
||||
u_hadd = 146,
|
||||
s_rhadd = 147,
|
||||
u_rhadd = 148,
|
||||
s_clamp = 149,
|
||||
u_clamp = 150,
|
||||
clz = 151,
|
||||
ctz = 152,
|
||||
s_mad_hi = 153,
|
||||
u_mad_sat = 154,
|
||||
s_mad_sat = 155,
|
||||
s_max = 156,
|
||||
u_max = 157,
|
||||
s_min = 158,
|
||||
u_min = 159,
|
||||
s_mul_hi = 160,
|
||||
rotate = 161,
|
||||
s_sub_sat = 162,
|
||||
u_sub_sat = 163,
|
||||
u_upsample = 164,
|
||||
s_upsample = 165,
|
||||
popcount = 166,
|
||||
s_mad24 = 167,
|
||||
u_mad24 = 168,
|
||||
s_mul24 = 169,
|
||||
u_mul24 = 170,
|
||||
vloadn = 171,
|
||||
vstoren = 172,
|
||||
vload_half = 173,
|
||||
vload_halfn = 174,
|
||||
vstore_half = 175,
|
||||
vstore_half_r = 176,
|
||||
vstore_halfn = 177,
|
||||
vstore_halfn_r = 178,
|
||||
vloada_halfn = 179,
|
||||
vstorea_halfn = 180,
|
||||
vstorea_halfn_r = 181,
|
||||
shuffle = 182,
|
||||
shuffle2 = 183,
|
||||
printf = 184,
|
||||
prefetch = 185,
|
||||
bitselect = 186,
|
||||
select = 187,
|
||||
u_abs = 201,
|
||||
u_abs_diff = 202,
|
||||
u_mul_hi = 203,
|
||||
u_mad_hi = 204,
|
||||
};
|
||||
|
||||
pub const Zig = enum(u16) {
|
||||
InvocationGlobal = 0,
|
||||
};
|
||||
pub const ImageOperands = packed struct {
|
||||
bias: bool = false,
|
||||
lod: bool = false,
|
||||
@@ -5494,335 +5541,10 @@ pub const TensorOperands = packed struct {
|
||||
_reserved_bit_31: bool = false,
|
||||
};
|
||||
};
|
||||
pub const @"DebugInfo.DebugInfoFlags" = packed struct {
|
||||
flag_is_protected: bool = false,
|
||||
flag_is_private: bool = false,
|
||||
flag_is_local: bool = false,
|
||||
flag_is_definition: bool = false,
|
||||
flag_fwd_decl: bool = false,
|
||||
flag_artificial: bool = false,
|
||||
flag_explicit: bool = false,
|
||||
flag_prototyped: bool = false,
|
||||
flag_object_pointer: bool = false,
|
||||
flag_static_member: bool = false,
|
||||
flag_indirect_variable: bool = false,
|
||||
flag_l_value_reference: bool = false,
|
||||
flag_r_value_reference: bool = false,
|
||||
flag_is_optimized: bool = false,
|
||||
_reserved_bit_14: bool = false,
|
||||
_reserved_bit_15: bool = false,
|
||||
_reserved_bit_16: bool = false,
|
||||
_reserved_bit_17: bool = false,
|
||||
_reserved_bit_18: bool = false,
|
||||
_reserved_bit_19: bool = false,
|
||||
_reserved_bit_20: bool = false,
|
||||
_reserved_bit_21: bool = false,
|
||||
_reserved_bit_22: bool = false,
|
||||
_reserved_bit_23: bool = false,
|
||||
_reserved_bit_24: bool = false,
|
||||
_reserved_bit_25: bool = false,
|
||||
_reserved_bit_26: bool = false,
|
||||
_reserved_bit_27: bool = false,
|
||||
_reserved_bit_28: bool = false,
|
||||
_reserved_bit_29: bool = false,
|
||||
_reserved_bit_30: bool = false,
|
||||
_reserved_bit_31: bool = false,
|
||||
};
|
||||
pub const @"DebugInfo.DebugBaseTypeAttributeEncoding" = enum(u32) {
|
||||
unspecified = 0,
|
||||
address = 1,
|
||||
boolean = 2,
|
||||
float = 4,
|
||||
signed = 5,
|
||||
signed_char = 6,
|
||||
unsigned = 7,
|
||||
unsigned_char = 8,
|
||||
};
|
||||
pub const @"DebugInfo.DebugCompositeType" = enum(u32) {
|
||||
class = 0,
|
||||
structure = 1,
|
||||
@"union" = 2,
|
||||
};
|
||||
pub const @"DebugInfo.DebugTypeQualifier" = enum(u32) {
|
||||
const_type = 0,
|
||||
volatile_type = 1,
|
||||
restrict_type = 2,
|
||||
};
|
||||
pub const @"DebugInfo.DebugOperation" = enum(u32) {
|
||||
deref = 0,
|
||||
plus = 1,
|
||||
minus = 2,
|
||||
plus_uconst = 3,
|
||||
bit_piece = 4,
|
||||
swap = 5,
|
||||
xderef = 6,
|
||||
stack_value = 7,
|
||||
constu = 8,
|
||||
|
||||
pub const Extended = union(@"DebugInfo.DebugOperation") {
|
||||
deref,
|
||||
plus,
|
||||
minus,
|
||||
plus_uconst: struct { literal_integer: LiteralInteger },
|
||||
bit_piece: struct { literal_integer_0: LiteralInteger, literal_integer_1: LiteralInteger },
|
||||
swap,
|
||||
xderef,
|
||||
stack_value,
|
||||
constu: struct { literal_integer: LiteralInteger },
|
||||
};
|
||||
};
|
||||
pub const @"OpenCL.DebugInfo.100.DebugInfoFlags" = packed struct {
|
||||
flag_is_protected: bool = false,
|
||||
flag_is_private: bool = false,
|
||||
flag_is_local: bool = false,
|
||||
flag_is_definition: bool = false,
|
||||
flag_fwd_decl: bool = false,
|
||||
flag_artificial: bool = false,
|
||||
flag_explicit: bool = false,
|
||||
flag_prototyped: bool = false,
|
||||
flag_object_pointer: bool = false,
|
||||
flag_static_member: bool = false,
|
||||
flag_indirect_variable: bool = false,
|
||||
flag_l_value_reference: bool = false,
|
||||
flag_r_value_reference: bool = false,
|
||||
flag_is_optimized: bool = false,
|
||||
flag_is_enum_class: bool = false,
|
||||
flag_type_pass_by_value: bool = false,
|
||||
flag_type_pass_by_reference: bool = false,
|
||||
_reserved_bit_17: bool = false,
|
||||
_reserved_bit_18: bool = false,
|
||||
_reserved_bit_19: bool = false,
|
||||
_reserved_bit_20: bool = false,
|
||||
_reserved_bit_21: bool = false,
|
||||
_reserved_bit_22: bool = false,
|
||||
_reserved_bit_23: bool = false,
|
||||
_reserved_bit_24: bool = false,
|
||||
_reserved_bit_25: bool = false,
|
||||
_reserved_bit_26: bool = false,
|
||||
_reserved_bit_27: bool = false,
|
||||
_reserved_bit_28: bool = false,
|
||||
_reserved_bit_29: bool = false,
|
||||
_reserved_bit_30: bool = false,
|
||||
_reserved_bit_31: bool = false,
|
||||
};
|
||||
pub const @"OpenCL.DebugInfo.100.DebugBaseTypeAttributeEncoding" = enum(u32) {
|
||||
unspecified = 0,
|
||||
address = 1,
|
||||
boolean = 2,
|
||||
float = 3,
|
||||
signed = 4,
|
||||
signed_char = 5,
|
||||
unsigned = 6,
|
||||
unsigned_char = 7,
|
||||
};
|
||||
pub const @"OpenCL.DebugInfo.100.DebugCompositeType" = enum(u32) {
|
||||
class = 0,
|
||||
structure = 1,
|
||||
@"union" = 2,
|
||||
};
|
||||
pub const @"OpenCL.DebugInfo.100.DebugTypeQualifier" = enum(u32) {
|
||||
const_type = 0,
|
||||
volatile_type = 1,
|
||||
restrict_type = 2,
|
||||
atomic_type = 3,
|
||||
};
|
||||
pub const @"OpenCL.DebugInfo.100.DebugOperation" = enum(u32) {
|
||||
deref = 0,
|
||||
plus = 1,
|
||||
minus = 2,
|
||||
plus_uconst = 3,
|
||||
bit_piece = 4,
|
||||
swap = 5,
|
||||
xderef = 6,
|
||||
stack_value = 7,
|
||||
constu = 8,
|
||||
fragment = 9,
|
||||
|
||||
pub const Extended = union(@"OpenCL.DebugInfo.100.DebugOperation") {
|
||||
deref,
|
||||
plus,
|
||||
minus,
|
||||
plus_uconst: struct { literal_integer: LiteralInteger },
|
||||
bit_piece: struct { literal_integer_0: LiteralInteger, literal_integer_1: LiteralInteger },
|
||||
swap,
|
||||
xderef,
|
||||
stack_value,
|
||||
constu: struct { literal_integer: LiteralInteger },
|
||||
fragment: struct { literal_integer_0: LiteralInteger, literal_integer_1: LiteralInteger },
|
||||
};
|
||||
};
|
||||
pub const @"OpenCL.DebugInfo.100.DebugImportedEntity" = enum(u32) {
|
||||
imported_module = 0,
|
||||
imported_declaration = 1,
|
||||
};
|
||||
pub const @"NonSemantic.ClspvReflection.6.KernelPropertyFlags" = packed struct {
|
||||
may_use_printf: bool = false,
|
||||
_reserved_bit_1: bool = false,
|
||||
_reserved_bit_2: bool = false,
|
||||
_reserved_bit_3: bool = false,
|
||||
_reserved_bit_4: bool = false,
|
||||
_reserved_bit_5: bool = false,
|
||||
_reserved_bit_6: bool = false,
|
||||
_reserved_bit_7: bool = false,
|
||||
_reserved_bit_8: bool = false,
|
||||
_reserved_bit_9: bool = false,
|
||||
_reserved_bit_10: bool = false,
|
||||
_reserved_bit_11: bool = false,
|
||||
_reserved_bit_12: bool = false,
|
||||
_reserved_bit_13: bool = false,
|
||||
_reserved_bit_14: bool = false,
|
||||
_reserved_bit_15: bool = false,
|
||||
_reserved_bit_16: bool = false,
|
||||
_reserved_bit_17: bool = false,
|
||||
_reserved_bit_18: bool = false,
|
||||
_reserved_bit_19: bool = false,
|
||||
_reserved_bit_20: bool = false,
|
||||
_reserved_bit_21: bool = false,
|
||||
_reserved_bit_22: bool = false,
|
||||
_reserved_bit_23: bool = false,
|
||||
_reserved_bit_24: bool = false,
|
||||
_reserved_bit_25: bool = false,
|
||||
_reserved_bit_26: bool = false,
|
||||
_reserved_bit_27: bool = false,
|
||||
_reserved_bit_28: bool = false,
|
||||
_reserved_bit_29: bool = false,
|
||||
_reserved_bit_30: bool = false,
|
||||
_reserved_bit_31: bool = false,
|
||||
};
|
||||
pub const @"NonSemantic.Shader.DebugInfo.100.DebugInfoFlags" = packed struct {
|
||||
flag_is_protected: bool = false,
|
||||
flag_is_private: bool = false,
|
||||
flag_is_local: bool = false,
|
||||
flag_is_definition: bool = false,
|
||||
flag_fwd_decl: bool = false,
|
||||
flag_artificial: bool = false,
|
||||
flag_explicit: bool = false,
|
||||
flag_prototyped: bool = false,
|
||||
flag_object_pointer: bool = false,
|
||||
flag_static_member: bool = false,
|
||||
flag_indirect_variable: bool = false,
|
||||
flag_l_value_reference: bool = false,
|
||||
flag_r_value_reference: bool = false,
|
||||
flag_is_optimized: bool = false,
|
||||
flag_is_enum_class: bool = false,
|
||||
flag_type_pass_by_value: bool = false,
|
||||
flag_type_pass_by_reference: bool = false,
|
||||
flag_unknown_physical_layout: bool = false,
|
||||
_reserved_bit_18: bool = false,
|
||||
_reserved_bit_19: bool = false,
|
||||
_reserved_bit_20: bool = false,
|
||||
_reserved_bit_21: bool = false,
|
||||
_reserved_bit_22: bool = false,
|
||||
_reserved_bit_23: bool = false,
|
||||
_reserved_bit_24: bool = false,
|
||||
_reserved_bit_25: bool = false,
|
||||
_reserved_bit_26: bool = false,
|
||||
_reserved_bit_27: bool = false,
|
||||
_reserved_bit_28: bool = false,
|
||||
_reserved_bit_29: bool = false,
|
||||
_reserved_bit_30: bool = false,
|
||||
_reserved_bit_31: bool = false,
|
||||
};
|
||||
pub const @"NonSemantic.Shader.DebugInfo.100.BuildIdentifierFlags" = packed struct {
|
||||
identifier_possible_duplicates: bool = false,
|
||||
_reserved_bit_1: bool = false,
|
||||
_reserved_bit_2: bool = false,
|
||||
_reserved_bit_3: bool = false,
|
||||
_reserved_bit_4: bool = false,
|
||||
_reserved_bit_5: bool = false,
|
||||
_reserved_bit_6: bool = false,
|
||||
_reserved_bit_7: bool = false,
|
||||
_reserved_bit_8: bool = false,
|
||||
_reserved_bit_9: bool = false,
|
||||
_reserved_bit_10: bool = false,
|
||||
_reserved_bit_11: bool = false,
|
||||
_reserved_bit_12: bool = false,
|
||||
_reserved_bit_13: bool = false,
|
||||
_reserved_bit_14: bool = false,
|
||||
_reserved_bit_15: bool = false,
|
||||
_reserved_bit_16: bool = false,
|
||||
_reserved_bit_17: bool = false,
|
||||
_reserved_bit_18: bool = false,
|
||||
_reserved_bit_19: bool = false,
|
||||
_reserved_bit_20: bool = false,
|
||||
_reserved_bit_21: bool = false,
|
||||
_reserved_bit_22: bool = false,
|
||||
_reserved_bit_23: bool = false,
|
||||
_reserved_bit_24: bool = false,
|
||||
_reserved_bit_25: bool = false,
|
||||
_reserved_bit_26: bool = false,
|
||||
_reserved_bit_27: bool = false,
|
||||
_reserved_bit_28: bool = false,
|
||||
_reserved_bit_29: bool = false,
|
||||
_reserved_bit_30: bool = false,
|
||||
_reserved_bit_31: bool = false,
|
||||
};
|
||||
pub const @"NonSemantic.Shader.DebugInfo.100.DebugBaseTypeAttributeEncoding" = enum(u32) {
|
||||
unspecified = 0,
|
||||
address = 1,
|
||||
boolean = 2,
|
||||
float = 3,
|
||||
signed = 4,
|
||||
signed_char = 5,
|
||||
unsigned = 6,
|
||||
unsigned_char = 7,
|
||||
};
|
||||
pub const @"NonSemantic.Shader.DebugInfo.100.DebugCompositeType" = enum(u32) {
|
||||
class = 0,
|
||||
structure = 1,
|
||||
@"union" = 2,
|
||||
};
|
||||
pub const @"NonSemantic.Shader.DebugInfo.100.DebugTypeQualifier" = enum(u32) {
|
||||
const_type = 0,
|
||||
volatile_type = 1,
|
||||
restrict_type = 2,
|
||||
atomic_type = 3,
|
||||
};
|
||||
pub const @"NonSemantic.Shader.DebugInfo.100.DebugOperation" = enum(u32) {
|
||||
deref = 0,
|
||||
plus = 1,
|
||||
minus = 2,
|
||||
plus_uconst = 3,
|
||||
bit_piece = 4,
|
||||
swap = 5,
|
||||
xderef = 6,
|
||||
stack_value = 7,
|
||||
constu = 8,
|
||||
fragment = 9,
|
||||
|
||||
pub const Extended = union(@"NonSemantic.Shader.DebugInfo.100.DebugOperation") {
|
||||
deref,
|
||||
plus,
|
||||
minus,
|
||||
plus_uconst: struct { id_ref: Id },
|
||||
bit_piece: struct { id_ref_0: Id, id_ref_1: Id },
|
||||
swap,
|
||||
xderef,
|
||||
stack_value,
|
||||
constu: struct { id_ref: Id },
|
||||
fragment: struct { id_ref_0: Id, id_ref_1: Id },
|
||||
};
|
||||
};
|
||||
pub const @"NonSemantic.Shader.DebugInfo.100.DebugImportedEntity" = enum(u32) {
|
||||
imported_module = 0,
|
||||
imported_declaration = 1,
|
||||
};
|
||||
pub const InstructionSet = enum {
|
||||
core,
|
||||
SPV_AMD_shader_trinary_minmax,
|
||||
SPV_EXT_INST_TYPE_TOSA_001000_1,
|
||||
@"NonSemantic.VkspReflection",
|
||||
SPV_AMD_shader_explicit_vertex_parameter,
|
||||
DebugInfo,
|
||||
@"NonSemantic.DebugBreak",
|
||||
@"OpenCL.DebugInfo.100",
|
||||
@"NonSemantic.ClspvReflection.6",
|
||||
@"GLSL.std.450",
|
||||
SPV_AMD_shader_ballot,
|
||||
@"NonSemantic.DebugPrintf",
|
||||
SPV_AMD_gcn_shader,
|
||||
@"OpenCL.std",
|
||||
@"NonSemantic.Shader.DebugInfo.100",
|
||||
zig,
|
||||
|
||||
pub fn instructions(self: InstructionSet) []const Instruction {
|
||||
@@ -14088,1972 +13810,6 @@ pub const InstructionSet = enum {
|
||||
},
|
||||
},
|
||||
},
|
||||
.SPV_AMD_shader_trinary_minmax => &.{
|
||||
.{
|
||||
.name = "FMin3AMD",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "UMin3AMD",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SMin3AMD",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "FMax3AMD",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "UMax3AMD",
|
||||
.opcode = 5,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SMax3AMD",
|
||||
.opcode = 6,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "FMid3AMD",
|
||||
.opcode = 7,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "UMid3AMD",
|
||||
.opcode = 8,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SMid3AMD",
|
||||
.opcode = 9,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.SPV_EXT_INST_TYPE_TOSA_001000_1 => &.{
|
||||
.{
|
||||
.name = "ARGMAX",
|
||||
.opcode = 0,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "AVG_POOL2D",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CONV2D",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CONV3D",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DEPTHWISE_CONV2D",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "FFT2D",
|
||||
.opcode = 5,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "MATMUL",
|
||||
.opcode = 6,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "MAX_POOL2D",
|
||||
.opcode = 7,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "RFFT2D",
|
||||
.opcode = 8,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "TRANSPOSE_CONV2D",
|
||||
.opcode = 9,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CLAMP",
|
||||
.opcode = 10,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ERF",
|
||||
.opcode = 11,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SIGMOID",
|
||||
.opcode = 12,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "TANH",
|
||||
.opcode = 13,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ADD",
|
||||
.opcode = 14,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ARITHMETIC_RIGHT_SHIFT",
|
||||
.opcode = 15,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "BITWISE_AND",
|
||||
.opcode = 16,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "BITWISE_OR",
|
||||
.opcode = 17,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "BITWISE_XOR",
|
||||
.opcode = 18,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "INTDIV",
|
||||
.opcode = 19,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LOGICAL_AND",
|
||||
.opcode = 20,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LOGICAL_LEFT_SHIFT",
|
||||
.opcode = 21,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LOGICAL_RIGHT_SHIFT",
|
||||
.opcode = 22,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LOGICAL_OR",
|
||||
.opcode = 23,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LOGICAL_XOR",
|
||||
.opcode = 24,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "MAXIMUM",
|
||||
.opcode = 25,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "MINIMUM",
|
||||
.opcode = 26,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "MUL",
|
||||
.opcode = 27,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "POW",
|
||||
.opcode = 28,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SUB",
|
||||
.opcode = 29,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "TABLE",
|
||||
.opcode = 30,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ABS",
|
||||
.opcode = 31,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "BITWISE_NOT",
|
||||
.opcode = 32,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CEIL",
|
||||
.opcode = 33,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CLZ",
|
||||
.opcode = 34,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "COS",
|
||||
.opcode = 35,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "EXP",
|
||||
.opcode = 36,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "FLOOR",
|
||||
.opcode = 37,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LOG",
|
||||
.opcode = 38,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LOGICAL_NOT",
|
||||
.opcode = 39,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "NEGATE",
|
||||
.opcode = 40,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "RECIPROCAL",
|
||||
.opcode = 41,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "RSQRT",
|
||||
.opcode = 42,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SIN",
|
||||
.opcode = 43,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SELECT",
|
||||
.opcode = 44,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "EQUAL",
|
||||
.opcode = 45,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "GREATER",
|
||||
.opcode = 46,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "GREATER_EQUAL",
|
||||
.opcode = 47,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "REDUCE_ALL",
|
||||
.opcode = 48,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "REDUCE_ANY",
|
||||
.opcode = 49,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "REDUCE_MAX",
|
||||
.opcode = 50,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "REDUCE_MIN",
|
||||
.opcode = 51,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "REDUCE_PRODUCT",
|
||||
.opcode = 52,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "REDUCE_SUM",
|
||||
.opcode = 53,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CONCAT",
|
||||
.opcode = 54,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PAD",
|
||||
.opcode = 55,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "RESHAPE",
|
||||
.opcode = 56,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "REVERSE",
|
||||
.opcode = 57,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SLICE",
|
||||
.opcode = 58,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "TILE",
|
||||
.opcode = 59,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "TRANSPOSE",
|
||||
.opcode = 60,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "GATHER",
|
||||
.opcode = 61,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SCATTER",
|
||||
.opcode = 62,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "RESIZE",
|
||||
.opcode = 63,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CAST",
|
||||
.opcode = 64,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "RESCALE",
|
||||
.opcode = 65,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.@"NonSemantic.VkspReflection" => &.{
|
||||
.{
|
||||
.name = "Configuration",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "StartCounter",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "StopCounter",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PushConstants",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SpecializationMapEntry",
|
||||
.opcode = 5,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DescriptorSetBuffer",
|
||||
.opcode = 6,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DescriptorSetImage",
|
||||
.opcode = 7,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DescriptorSetSampler",
|
||||
.opcode = 8,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.SPV_AMD_shader_explicit_vertex_parameter => &.{
|
||||
.{
|
||||
.name = "InterpolateAtVertexAMD",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.DebugInfo => &.{
|
||||
.{
|
||||
.name = "DebugInfoNone",
|
||||
.opcode = 0,
|
||||
.operands = &.{},
|
||||
},
|
||||
.{
|
||||
.name = "DebugCompilationUnit",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeBasic",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_base_type_attribute_encoding, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypePointer",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .storage_class, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeQualifier",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_type_qualifier, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeArray",
|
||||
.opcode = 5,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeVector",
|
||||
.opcode = 6,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypedef",
|
||||
.opcode = 7,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeFunction",
|
||||
.opcode = 8,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeEnum",
|
||||
.opcode = 9,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .pair_id_ref_id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeComposite",
|
||||
.opcode = 10,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_composite_type, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeMember",
|
||||
.opcode = 11,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeInheritance",
|
||||
.opcode = 12,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypePtrToMember",
|
||||
.opcode = 13,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplate",
|
||||
.opcode = 14,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateParameter",
|
||||
.opcode = 15,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateTemplateParameter",
|
||||
.opcode = 16,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateParameterPack",
|
||||
.opcode = 17,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugGlobalVariable",
|
||||
.opcode = 18,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugFunctionDeclaration",
|
||||
.opcode = 19,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugFunction",
|
||||
.opcode = 20,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .debug_info_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLexicalBlock",
|
||||
.opcode = 21,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLexicalBlockDiscriminator",
|
||||
.opcode = 22,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugScope",
|
||||
.opcode = 23,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugNoScope",
|
||||
.opcode = 24,
|
||||
.operands = &.{},
|
||||
},
|
||||
.{
|
||||
.name = "DebugInlinedAt",
|
||||
.opcode = 25,
|
||||
.operands = &.{
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLocalVariable",
|
||||
.opcode = 26,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugInlinedVariable",
|
||||
.opcode = 27,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugDeclare",
|
||||
.opcode = 28,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugValue",
|
||||
.opcode = 29,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugOperation",
|
||||
.opcode = 30,
|
||||
.operands = &.{
|
||||
.{ .kind = .debug_info_debug_operation, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugExpression",
|
||||
.opcode = 31,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugMacroDef",
|
||||
.opcode = 32,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugMacroUndef",
|
||||
.opcode = 33,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.@"NonSemantic.DebugBreak" => &.{
|
||||
.{
|
||||
.name = "DebugBreak",
|
||||
.opcode = 1,
|
||||
.operands = &.{},
|
||||
},
|
||||
},
|
||||
.@"OpenCL.DebugInfo.100" => &.{
|
||||
.{
|
||||
.name = "DebugInfoNone",
|
||||
.opcode = 0,
|
||||
.operands = &.{},
|
||||
},
|
||||
.{
|
||||
.name = "DebugCompilationUnit",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .source_language, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeBasic",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_base_type_attribute_encoding, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypePointer",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .storage_class, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeQualifier",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_type_qualifier, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeArray",
|
||||
.opcode = 5,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeVector",
|
||||
.opcode = 6,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypedef",
|
||||
.opcode = 7,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeFunction",
|
||||
.opcode = 8,
|
||||
.operands = &.{
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeEnum",
|
||||
.opcode = 9,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .pair_id_ref_id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeComposite",
|
||||
.opcode = 10,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_composite_type, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeMember",
|
||||
.opcode = 11,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeInheritance",
|
||||
.opcode = 12,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypePtrToMember",
|
||||
.opcode = 13,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplate",
|
||||
.opcode = 14,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateParameter",
|
||||
.opcode = 15,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateTemplateParameter",
|
||||
.opcode = 16,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateParameterPack",
|
||||
.opcode = 17,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugGlobalVariable",
|
||||
.opcode = 18,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugFunctionDeclaration",
|
||||
.opcode = 19,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugFunction",
|
||||
.opcode = 20,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLexicalBlock",
|
||||
.opcode = 21,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLexicalBlockDiscriminator",
|
||||
.opcode = 22,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugScope",
|
||||
.opcode = 23,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugNoScope",
|
||||
.opcode = 24,
|
||||
.operands = &.{},
|
||||
},
|
||||
.{
|
||||
.name = "DebugInlinedAt",
|
||||
.opcode = 25,
|
||||
.operands = &.{
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLocalVariable",
|
||||
.opcode = 26,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_info_flags, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugInlinedVariable",
|
||||
.opcode = 27,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugDeclare",
|
||||
.opcode = 28,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugValue",
|
||||
.opcode = 29,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugOperation",
|
||||
.opcode = 30,
|
||||
.operands = &.{
|
||||
.{ .kind = .open_cl_debug_info_100_debug_operation, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugExpression",
|
||||
.opcode = 31,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugMacroDef",
|
||||
.opcode = 32,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugMacroUndef",
|
||||
.opcode = 33,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugImportedEntity",
|
||||
.opcode = 34,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .open_cl_debug_info_100_debug_imported_entity, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugSource",
|
||||
.opcode = 35,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugModuleINTEL",
|
||||
.opcode = 36,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .literal_integer, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.@"NonSemantic.ClspvReflection.6" => &.{
|
||||
.{
|
||||
.name = "Kernel",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentInfo",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentStorageBuffer",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentUniform",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentPodStorageBuffer",
|
||||
.opcode = 5,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentPodUniform",
|
||||
.opcode = 6,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentPodPushConstant",
|
||||
.opcode = 7,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentSampledImage",
|
||||
.opcode = 8,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentStorageImage",
|
||||
.opcode = 9,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentSampler",
|
||||
.opcode = 10,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentWorkgroup",
|
||||
.opcode = 11,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SpecConstantWorkgroupSize",
|
||||
.opcode = 12,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SpecConstantGlobalOffset",
|
||||
.opcode = 13,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SpecConstantWorkDim",
|
||||
.opcode = 14,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PushConstantGlobalOffset",
|
||||
.opcode = 15,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PushConstantEnqueuedLocalSize",
|
||||
.opcode = 16,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PushConstantGlobalSize",
|
||||
.opcode = 17,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PushConstantRegionOffset",
|
||||
.opcode = 18,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PushConstantNumWorkgroups",
|
||||
.opcode = 19,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PushConstantRegionGroupOffset",
|
||||
.opcode = 20,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ConstantDataStorageBuffer",
|
||||
.opcode = 21,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ConstantDataUniform",
|
||||
.opcode = 22,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "LiteralSampler",
|
||||
.opcode = 23,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PropertyRequiredWorkgroupSize",
|
||||
.opcode = 24,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SpecConstantSubgroupMaxSize",
|
||||
.opcode = 25,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentPointerPushConstant",
|
||||
.opcode = 26,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentPointerUniform",
|
||||
.opcode = 27,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ProgramScopeVariablesStorageBuffer",
|
||||
.opcode = 28,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ProgramScopeVariablePointerRelocation",
|
||||
.opcode = 29,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ImageArgumentInfoChannelOrderPushConstant",
|
||||
.opcode = 30,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ImageArgumentInfoChannelDataTypePushConstant",
|
||||
.opcode = 31,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ImageArgumentInfoChannelOrderUniform",
|
||||
.opcode = 32,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ImageArgumentInfoChannelDataTypeUniform",
|
||||
.opcode = 33,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentStorageTexelBuffer",
|
||||
.opcode = 34,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ArgumentUniformTexelBuffer",
|
||||
.opcode = 35,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ConstantDataPointerPushConstant",
|
||||
.opcode = 36,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "ProgramScopeVariablePointerPushConstant",
|
||||
.opcode = 37,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PrintfInfo",
|
||||
.opcode = 38,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PrintfBufferStorageBuffer",
|
||||
.opcode = 39,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "PrintfBufferPointerPushConstant",
|
||||
.opcode = 40,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "NormalizedSamplerMaskPushConstant",
|
||||
.opcode = 41,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "WorkgroupVariableSize",
|
||||
.opcode = 42,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.@"GLSL.std.450" => &.{
|
||||
.{
|
||||
.name = "Round",
|
||||
@@ -16662,71 +14418,6 @@ pub const InstructionSet = enum {
|
||||
},
|
||||
},
|
||||
},
|
||||
.SPV_AMD_shader_ballot => &.{
|
||||
.{
|
||||
.name = "SwizzleInvocationsAMD",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "SwizzleInvocationsMaskedAMD",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "WriteInvocationAMD",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "MbcntAMD",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.@"NonSemantic.DebugPrintf" => &.{
|
||||
.{
|
||||
.name = "DebugPrintf",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
},
|
||||
.SPV_AMD_gcn_shader => &.{
|
||||
.{
|
||||
.name = "CubeFaceIndexAMD",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "CubeFaceCoordAMD",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "TimeAMD",
|
||||
.opcode = 3,
|
||||
.operands = &.{},
|
||||
},
|
||||
},
|
||||
.@"OpenCL.std" => &.{
|
||||
.{
|
||||
.name = "acos",
|
||||
@@ -17977,443 +15668,6 @@ pub const InstructionSet = enum {
|
||||
},
|
||||
},
|
||||
},
|
||||
.@"NonSemantic.Shader.DebugInfo.100" => &.{
|
||||
.{
|
||||
.name = "DebugInfoNone",
|
||||
.opcode = 0,
|
||||
.operands = &.{},
|
||||
},
|
||||
.{
|
||||
.name = "DebugCompilationUnit",
|
||||
.opcode = 1,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeBasic",
|
||||
.opcode = 2,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypePointer",
|
||||
.opcode = 3,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeQualifier",
|
||||
.opcode = 4,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeArray",
|
||||
.opcode = 5,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeVector",
|
||||
.opcode = 6,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypedef",
|
||||
.opcode = 7,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeFunction",
|
||||
.opcode = 8,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeEnum",
|
||||
.opcode = 9,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .pair_id_ref_id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeComposite",
|
||||
.opcode = 10,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeMember",
|
||||
.opcode = 11,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeInheritance",
|
||||
.opcode = 12,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypePtrToMember",
|
||||
.opcode = 13,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplate",
|
||||
.opcode = 14,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateParameter",
|
||||
.opcode = 15,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateTemplateParameter",
|
||||
.opcode = 16,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeTemplateParameterPack",
|
||||
.opcode = 17,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugGlobalVariable",
|
||||
.opcode = 18,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugFunctionDeclaration",
|
||||
.opcode = 19,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugFunction",
|
||||
.opcode = 20,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLexicalBlock",
|
||||
.opcode = 21,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLexicalBlockDiscriminator",
|
||||
.opcode = 22,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugScope",
|
||||
.opcode = 23,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugNoScope",
|
||||
.opcode = 24,
|
||||
.operands = &.{},
|
||||
},
|
||||
.{
|
||||
.name = "DebugInlinedAt",
|
||||
.opcode = 25,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLocalVariable",
|
||||
.opcode = 26,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugInlinedVariable",
|
||||
.opcode = 27,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugDeclare",
|
||||
.opcode = 28,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugValue",
|
||||
.opcode = 29,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugOperation",
|
||||
.opcode = 30,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugExpression",
|
||||
.opcode = 31,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .variadic },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugMacroDef",
|
||||
.opcode = 32,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugMacroUndef",
|
||||
.opcode = 33,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugImportedEntity",
|
||||
.opcode = 34,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugSource",
|
||||
.opcode = 35,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .optional },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugFunctionDefinition",
|
||||
.opcode = 101,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugSourceContinued",
|
||||
.opcode = 102,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugLine",
|
||||
.opcode = 103,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugNoLine",
|
||||
.opcode = 104,
|
||||
.operands = &.{},
|
||||
},
|
||||
.{
|
||||
.name = "DebugBuildIdentifier",
|
||||
.opcode = 105,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugStoragePath",
|
||||
.opcode = 106,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugEntryPoint",
|
||||
.opcode = 107,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
.{
|
||||
.name = "DebugTypeMatrix",
|
||||
.opcode = 108,
|
||||
.operands = &.{
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
.{ .kind = .id_ref, .quantifier = .required },
|
||||
},
|
||||
},
|
||||
},
|
||||
.zig => &.{
|
||||
.{
|
||||
.name = "InvocationGlobal",
|
||||
|
||||
+32
-8
@@ -23,6 +23,7 @@ const Linker = @This();
|
||||
|
||||
base: link.File,
|
||||
module: Module,
|
||||
cg: CodeGen,
|
||||
|
||||
pub fn createEmpty(
|
||||
arena: Allocator,
|
||||
@@ -63,6 +64,16 @@ pub fn createEmpty(
|
||||
.arena = arena,
|
||||
.zcu = comp.zcu.?,
|
||||
},
|
||||
.cg = .{
|
||||
// These fields are populated in generate()
|
||||
.pt = undefined,
|
||||
.air = undefined,
|
||||
.liveness = undefined,
|
||||
.owner_nav = undefined,
|
||||
.module = undefined,
|
||||
.control_flow = .{ .structured = .{} },
|
||||
.base_line = undefined,
|
||||
},
|
||||
};
|
||||
errdefer linker.deinit();
|
||||
|
||||
@@ -84,6 +95,7 @@ pub fn open(
|
||||
}
|
||||
|
||||
pub fn deinit(linker: *Linker) void {
|
||||
linker.cg.deinit();
|
||||
linker.module.deinit();
|
||||
}
|
||||
|
||||
@@ -99,29 +111,41 @@ fn generate(
|
||||
const gpa = zcu.gpa;
|
||||
const structured_cfg = zcu.navFileScope(nav_index).mod.?.structured_cfg;
|
||||
|
||||
var cg: CodeGen = .{
|
||||
linker.cg.control_flow.deinit(gpa);
|
||||
linker.cg.args.clearRetainingCapacity();
|
||||
linker.cg.inst_results.clearRetainingCapacity();
|
||||
linker.cg.id_scratch.clearRetainingCapacity();
|
||||
linker.cg.prologue.reset();
|
||||
linker.cg.body.reset();
|
||||
|
||||
linker.cg = .{
|
||||
.pt = pt,
|
||||
.module = &linker.module,
|
||||
.owner_nav = nav_index,
|
||||
.air = air,
|
||||
.liveness = liveness,
|
||||
.owner_nav = nav_index,
|
||||
.module = &linker.module,
|
||||
.control_flow = switch (structured_cfg) {
|
||||
true => .{ .structured = .{} },
|
||||
false => .{ .unstructured = .{} },
|
||||
},
|
||||
.base_line = zcu.navSrcLine(nav_index),
|
||||
};
|
||||
defer cg.deinit();
|
||||
|
||||
cg.genNav(do_codegen) catch |err| switch (err) {
|
||||
error.CodegenFail => switch (zcu.codegenFailMsg(nav_index, cg.error_msg.?)) {
|
||||
.args = linker.cg.args,
|
||||
.inst_results = linker.cg.inst_results,
|
||||
.id_scratch = linker.cg.id_scratch,
|
||||
.prologue = linker.cg.prologue,
|
||||
.body = linker.cg.body,
|
||||
};
|
||||
|
||||
linker.cg.genNav(do_codegen) catch |err| switch (err) {
|
||||
error.CodegenFail => switch (zcu.codegenFailMsg(nav_index, linker.cg.error_msg.?)) {
|
||||
error.CodegenFail => {},
|
||||
error.OutOfMemory => |e| return e,
|
||||
},
|
||||
else => |other| {
|
||||
// There might be an error that happened *after* linker.error_msg
|
||||
// was already allocated, so be sure to free it.
|
||||
if (cg.error_msg) |error_msg| {
|
||||
if (linker.cg.error_msg) |error_msg| {
|
||||
error_msg.deinit(gpa);
|
||||
}
|
||||
|
||||
|
||||
+83
-62
@@ -12,6 +12,7 @@ const ExtendedStructSet = std.StringHashMap(void);
|
||||
|
||||
const Extension = struct {
|
||||
name: []const u8,
|
||||
opcode_name: []const u8,
|
||||
spec: ExtensionRegistry,
|
||||
};
|
||||
|
||||
@@ -44,23 +45,11 @@ const OperandKindMap = std.ArrayHashMap(StringPair, OperandKind, StringPairConte
|
||||
|
||||
/// Khronos made it so that these names are not defined explicitly, so
|
||||
/// we need to hardcode it (like they did).
|
||||
/// See https://github.com/KhronosGroup/SPIRV-Registry/
|
||||
const set_names = std.StaticStringMap([]const u8).initComptime(.{
|
||||
.{ "opencl.std.100", "OpenCL.std" },
|
||||
.{ "glsl.std.450", "GLSL.std.450" },
|
||||
.{ "opencl.debuginfo.100", "OpenCL.DebugInfo.100" },
|
||||
.{ "spv-amd-shader-ballot", "SPV_AMD_shader_ballot" },
|
||||
.{ "nonsemantic.shader.debuginfo.100", "NonSemantic.Shader.DebugInfo.100" },
|
||||
.{ "nonsemantic.vkspreflection", "NonSemantic.VkspReflection" },
|
||||
.{ "nonsemantic.clspvreflection", "NonSemantic.ClspvReflection.6" }, // This version needs to be handled manually
|
||||
.{ "spv-amd-gcn-shader", "SPV_AMD_gcn_shader" },
|
||||
.{ "spv-amd-shader-trinary-minmax", "SPV_AMD_shader_trinary_minmax" },
|
||||
.{ "debuginfo", "DebugInfo" },
|
||||
.{ "nonsemantic.debugprintf", "NonSemantic.DebugPrintf" },
|
||||
.{ "spv-amd-shader-explicit-vertex-parameter", "SPV_AMD_shader_explicit_vertex_parameter" },
|
||||
.{ "nonsemantic.debugbreak", "NonSemantic.DebugBreak" },
|
||||
.{ "tosa.001000.1", "SPV_EXT_INST_TYPE_TOSA_001000_1" },
|
||||
.{ "zig", "zig" },
|
||||
/// See https://github.com/KhronosGroup/SPIRV-Registry
|
||||
const set_names = std.StaticStringMap(struct { []const u8, []const u8 }).initComptime(.{
|
||||
.{ "opencl.std.100", .{ "OpenCL.std", "OpenClOpcode" } },
|
||||
.{ "glsl.std.450", .{ "GLSL.std.450", "GlslOpcode" } },
|
||||
.{ "zig", .{ "zig", "Zig" } },
|
||||
});
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.smp_allocator);
|
||||
@@ -78,7 +67,7 @@ pub fn main() !void {
|
||||
const dir = try std.fs.cwd().openDir(json_path, .{ .iterate = true });
|
||||
|
||||
const core_spec = try readRegistry(CoreRegistry, dir, "spirv.core.grammar.json");
|
||||
std.sort.block(Instruction, core_spec.instructions, CmpInst{}, CmpInst.lt);
|
||||
std.mem.sortUnstable(Instruction, core_spec.instructions, CmpInst{}, CmpInst.lt);
|
||||
|
||||
var exts = std.ArrayList(Extension).init(allocator);
|
||||
|
||||
@@ -134,14 +123,24 @@ fn readExtRegistry(exts: *std.ArrayList(Extension), dir: std.fs.Dir, sub_path: [
|
||||
const name = filename["extinst.".len .. filename.len - ".grammar.json".len];
|
||||
const spec = try readRegistry(ExtensionRegistry, dir, sub_path);
|
||||
|
||||
const set_name = set_names.get(name) orelse {
|
||||
std.log.info("ignored instruction set '{s}'", .{name});
|
||||
return;
|
||||
};
|
||||
|
||||
std.sort.block(Instruction, spec.instructions, CmpInst{}, CmpInst.lt);
|
||||
|
||||
try exts.append(.{ .name = set_names.get(name).?, .spec = spec });
|
||||
try exts.append(.{
|
||||
.name = set_name.@"0",
|
||||
.opcode_name = set_name.@"1",
|
||||
.spec = spec,
|
||||
});
|
||||
}
|
||||
|
||||
fn readRegistry(comptime RegistryType: type, dir: std.fs.Dir, path: []const u8) !RegistryType {
|
||||
const spec = try dir.readFileAlloc(allocator, path, std.math.maxInt(usize));
|
||||
// Required for json parsing.
|
||||
// TODO: ALI
|
||||
@setEvalBranchQuota(10000);
|
||||
|
||||
var scanner = std.json.Scanner.initCompleteInput(allocator, spec);
|
||||
@@ -191,7 +190,11 @@ fn tagPriorityScore(tag: []const u8) usize {
|
||||
}
|
||||
}
|
||||
|
||||
fn render(writer: *std.io.Writer, registry: CoreRegistry, extensions: []const Extension) !void {
|
||||
fn render(
|
||||
writer: *std.io.Writer,
|
||||
registry: CoreRegistry,
|
||||
extensions: []const Extension,
|
||||
) !void {
|
||||
try writer.writeAll(
|
||||
\\//! This file is auto-generated by tools/gen_spirv_spec.zig.
|
||||
\\
|
||||
@@ -317,13 +320,18 @@ fn render(writer: *std.io.Writer, registry: CoreRegistry, extensions: []const Ex
|
||||
// Note: extensions don't seem to have class.
|
||||
try renderClass(writer, registry.instructions);
|
||||
try renderOperandKind(writer, all_operand_kinds.values());
|
||||
try renderOpcodes(writer, registry.instructions, extended_structs);
|
||||
|
||||
try renderOpcodes(writer, "Opcode", true, registry.instructions, extended_structs);
|
||||
for (extensions) |ext| {
|
||||
try renderOpcodes(writer, ext.opcode_name, false, ext.spec.instructions, extended_structs);
|
||||
}
|
||||
|
||||
try renderOperandKinds(writer, all_operand_kinds.values(), extended_structs);
|
||||
try renderInstructionSet(writer, registry, extensions, all_operand_kinds);
|
||||
}
|
||||
|
||||
fn renderInstructionSet(
|
||||
writer: anytype,
|
||||
writer: *std.io.Writer,
|
||||
core: CoreRegistry,
|
||||
extensions: []const Extension,
|
||||
all_operand_kinds: OperandKindMap,
|
||||
@@ -358,7 +366,7 @@ fn renderInstructionSet(
|
||||
}
|
||||
|
||||
fn renderInstructionsCase(
|
||||
writer: anytype,
|
||||
writer: *std.io.Writer,
|
||||
set_name: []const u8,
|
||||
instructions: []const Instruction,
|
||||
all_operand_kinds: OperandKindMap,
|
||||
@@ -405,7 +413,7 @@ fn renderInstructionsCase(
|
||||
);
|
||||
}
|
||||
|
||||
fn renderClass(writer: anytype, instructions: []const Instruction) !void {
|
||||
fn renderClass(writer: *std.io.Writer, instructions: []const Instruction) !void {
|
||||
var class_map = std.StringArrayHashMap(void).init(allocator);
|
||||
|
||||
for (instructions) |inst| {
|
||||
@@ -454,7 +462,7 @@ fn formatId(identifier: []const u8) std.fmt.Alt(Formatter, Formatter.format) {
|
||||
return .{ .data = .{ .data = identifier } };
|
||||
}
|
||||
|
||||
fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void {
|
||||
fn renderOperandKind(writer: *std.io.Writer, operands: []const OperandKind) !void {
|
||||
try writer.writeAll(
|
||||
\\pub const OperandKind = enum {
|
||||
\\ opcode,
|
||||
@@ -510,7 +518,7 @@ fn renderOperandKind(writer: anytype, operands: []const OperandKind) !void {
|
||||
try writer.writeAll("};\n}\n};\n");
|
||||
}
|
||||
|
||||
fn renderEnumerant(writer: anytype, enumerant: Enumerant) !void {
|
||||
fn renderEnumerant(writer: *std.io.Writer, enumerant: Enumerant) !void {
|
||||
try writer.print(".{{.name = \"{s}\", .value = ", .{enumerant.enumerant});
|
||||
switch (enumerant.value) {
|
||||
.bitflag => |flag| try writer.writeAll(flag),
|
||||
@@ -527,7 +535,9 @@ fn renderEnumerant(writer: anytype, enumerant: Enumerant) !void {
|
||||
}
|
||||
|
||||
fn renderOpcodes(
|
||||
writer: anytype,
|
||||
writer: *std.io.Writer,
|
||||
opcode_type_name: []const u8,
|
||||
want_operands: bool,
|
||||
instructions: []const Instruction,
|
||||
extended_structs: ExtendedStructSet,
|
||||
) !void {
|
||||
@@ -538,7 +548,9 @@ fn renderOpcodes(
|
||||
try aliases.ensureTotalCapacity(instructions.len);
|
||||
|
||||
for (instructions, 0..) |inst, i| {
|
||||
if (std.mem.eql(u8, inst.class.?, "@exclude")) continue;
|
||||
if (inst.class) |class| {
|
||||
if (std.mem.eql(u8, class, "@exclude")) continue;
|
||||
}
|
||||
|
||||
const result = inst_map.getOrPutAssumeCapacity(inst.opcode);
|
||||
if (!result.found_existing) {
|
||||
@@ -562,58 +574,67 @@ fn renderOpcodes(
|
||||
|
||||
const instructions_indices = inst_map.values();
|
||||
|
||||
try writer.writeAll("pub const Opcode = enum(u16) {\n");
|
||||
try writer.print("\npub const {f} = enum(u16) {{\n", .{std.zig.fmtId(opcode_type_name)});
|
||||
for (instructions_indices) |i| {
|
||||
const inst = instructions[i];
|
||||
try writer.print("{f} = {},\n", .{ std.zig.fmtId(inst.opname), inst.opcode });
|
||||
}
|
||||
|
||||
try writer.writeAll(
|
||||
\\
|
||||
);
|
||||
try writer.writeAll("\n");
|
||||
|
||||
for (aliases.items) |alias| {
|
||||
try writer.print("pub const {f} = Opcode.{f};\n", .{
|
||||
try writer.print("pub const {f} = {f}.{f};\n", .{
|
||||
formatId(instructions[alias.inst].opname),
|
||||
std.zig.fmtId(opcode_type_name),
|
||||
formatId(instructions[alias.alias].opname),
|
||||
});
|
||||
}
|
||||
|
||||
try writer.writeAll(
|
||||
\\
|
||||
\\pub fn Operands(comptime self: Opcode) type {
|
||||
\\ return switch (self) {
|
||||
\\
|
||||
);
|
||||
if (want_operands) {
|
||||
try writer.print(
|
||||
\\
|
||||
\\pub fn Operands(comptime self: {f}) type {{
|
||||
\\ return switch (self) {{
|
||||
\\
|
||||
, .{std.zig.fmtId(opcode_type_name)});
|
||||
|
||||
for (instructions_indices) |i| {
|
||||
const inst = instructions[i];
|
||||
try renderOperand(writer, .instruction, inst.opname, inst.operands, extended_structs, false);
|
||||
for (instructions_indices) |i| {
|
||||
const inst = instructions[i];
|
||||
try renderOperand(writer, .instruction, inst.opname, inst.operands, extended_structs, false);
|
||||
}
|
||||
|
||||
try writer.writeAll(
|
||||
\\ };
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
|
||||
try writer.print(
|
||||
\\pub fn class(self: {f}) Class {{
|
||||
\\ return switch (self) {{
|
||||
\\
|
||||
, .{std.zig.fmtId(opcode_type_name)});
|
||||
|
||||
for (instructions_indices) |i| {
|
||||
const inst = instructions[i];
|
||||
try writer.print(".{f} => .{f},\n", .{ std.zig.fmtId(inst.opname), formatId(inst.class.?) });
|
||||
}
|
||||
|
||||
try writer.writeAll(
|
||||
\\ };
|
||||
\\}
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
try writer.writeAll(
|
||||
\\ };
|
||||
\\}
|
||||
\\pub fn class(self: Opcode) Class {
|
||||
\\ return switch (self) {
|
||||
\\
|
||||
);
|
||||
|
||||
for (instructions_indices) |i| {
|
||||
const inst = instructions[i];
|
||||
try writer.print(".{f} => .{f},\n", .{ std.zig.fmtId(inst.opname), formatId(inst.class.?) });
|
||||
}
|
||||
|
||||
try writer.writeAll(
|
||||
\\ };
|
||||
\\}
|
||||
\\};
|
||||
\\
|
||||
);
|
||||
}
|
||||
|
||||
fn renderOperandKinds(
|
||||
writer: anytype,
|
||||
writer: *std.io.Writer,
|
||||
kinds: []const OperandKind,
|
||||
extended_structs: ExtendedStructSet,
|
||||
) !void {
|
||||
@@ -627,7 +648,7 @@ fn renderOperandKinds(
|
||||
}
|
||||
|
||||
fn renderValueEnum(
|
||||
writer: anytype,
|
||||
writer: *std.io.Writer,
|
||||
enumeration: OperandKind,
|
||||
extended_structs: ExtendedStructSet,
|
||||
) !void {
|
||||
@@ -705,7 +726,7 @@ fn renderValueEnum(
|
||||
}
|
||||
|
||||
fn renderBitEnum(
|
||||
writer: anytype,
|
||||
writer: *std.io.Writer,
|
||||
enumeration: OperandKind,
|
||||
extended_structs: ExtendedStructSet,
|
||||
) !void {
|
||||
@@ -788,7 +809,7 @@ fn renderBitEnum(
|
||||
}
|
||||
|
||||
fn renderOperand(
|
||||
writer: anytype,
|
||||
writer: *std.io.Writer,
|
||||
kind: enum {
|
||||
@"union",
|
||||
instruction,
|
||||
@@ -872,7 +893,7 @@ fn renderOperand(
|
||||
try writer.writeAll(",\n");
|
||||
}
|
||||
|
||||
fn renderFieldName(writer: anytype, operands: []const Operand, field_index: usize) !void {
|
||||
fn renderFieldName(writer: *std.io.Writer, operands: []const Operand, field_index: usize) !void {
|
||||
const operand = operands[field_index];
|
||||
|
||||
derive_from_kind: {
|
||||
|
||||
Reference in New Issue
Block a user