authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-03-09 12:31:39+01:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2024-03-18 19:13:48+01:00
log9b058117f0f4595d43fbe08a3e659ac865e8b459
treebfb32104ccd2306f00d805b2ab37f15a7f47fcf5
parent028f532dc0ef1d544d6fcb9074cef92a11d6d25b
signaturebadge-check Signed by SSH key SHA256:ZS52FNyUv2WUXvO4njmVaFVO46RHojFuOrxRc4LuKzg

spirv: update assembler with new spec


1 files changed, 21 insertions(+), 3 deletions(-)

src/codegen/spirv/Assembler.zig+21-3
......@@ -194,6 +194,11 @@ inst: struct {
194194/// This map maps results to their tracked values.
195195value_map: AsmValueMap = .{},
196196
197/// This set is used to quickly transform from an opcode name to the
198/// index in its instruction set. The index of the key is the
199/// index in `spec.InstructionSet.core.instructions()`.
200instruction_map: std.StringArrayHashMapUnmanaged(void) = .{},
201
197202/// Free the resources owned by this assembler.
198203pub fn deinit(self: *Assembler) void {
199204 for (self.errors.items) |err| {
......@@ -204,9 +209,20 @@ pub fn deinit(self: *Assembler) void {
204209 self.inst.operands.deinit(self.gpa);
205210 self.inst.string_bytes.deinit(self.gpa);
206211 self.value_map.deinit(self.gpa);
212 self.instruction_map.deinit(self.gpa);
207213}
208214
209215pub fn assemble(self: *Assembler) Error!void {
216 // Populate the opcode map if it isn't already
217 if (self.instruction_map.count() == 0) {
218 const instructions = spec.InstructionSet.core.instructions();
219 try self.instruction_map.ensureUnusedCapacity(self.gpa, @intCast(instructions.len));
220 for (spec.InstructionSet.core.instructions(), 0..) |inst, i| {
221 const entry = try self.instruction_map.getOrPut(self.gpa, inst.name);
222 assert(entry.index == i);
223 }
224 }
225
210226 try self.tokenize();
211227 while (!self.testToken(.eof)) {
212228 try self.parseInstruction();
......@@ -475,12 +491,14 @@ fn parseInstruction(self: *Assembler) !void {
475491 }
476492
477493 const opcode_text = self.tokenText(opcode_tok);
478 @setEvalBranchQuota(10000);
479 self.inst.opcode = std.meta.stringToEnum(Opcode, opcode_text) orelse {
494 const index = self.instruction_map.getIndex(opcode_text) orelse {
480495 return self.fail(opcode_tok.start, "invalid opcode '{s}'", .{opcode_text});
481496 };
482497
483 const expected_operands = self.inst.opcode.operands();
498 const inst = spec.InstructionSet.core.instructions()[index];
499 self.inst.opcode = @enumFromInt(inst.opcode);
500
501 const expected_operands = inst.operands;
484502 // This is a loop because the result-id is not always the first operand.
485503 const requires_lhs_result = for (expected_operands) |op| {
486504 if (op.kind == .IdResult) break true;