diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Air.zig | 2 | ||||
| -rw-r--r-- | src/Sema.zig | 20 | ||||
| -rw-r--r-- | src/arch/aarch64/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/arch/arm/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/arch/riscv64/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 6 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 39 |
7 files changed, 63 insertions, 22 deletions
diff --git a/src/Air.zig b/src/Air.zig index 39215495c3..d02491ff89 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -815,6 +815,8 @@ pub const VectorCmp = struct { /// terminated string. pad to the next u32 after the null byte. /// 3. for every inputs_len /// - constraint: memory at this position is reinterpreted as a null +/// terminated string. +/// - name: memory at this position is reinterpreted as a null /// terminated string. pad to the next u32 after the null byte. /// 4. for every clobbers_len /// - clobber_name: memory at this position is reinterpreted as a null diff --git a/src/Sema.zig b/src/Sema.zig index 112939c995..9f5d6d5f9e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -10295,15 +10295,12 @@ fn zirAsm( }; const args = try sema.arena.alloc(Air.Inst.Ref, inputs_len); - const inputs = try sema.arena.alloc([]const u8, inputs_len); + const inputs = try sema.arena.alloc(struct { c: []const u8, n: []const u8 }, inputs_len); for (args) |*arg, arg_i| { const input = sema.code.extraData(Zir.Inst.Asm.Input, extra_i); extra_i = input.end; - const name = sema.code.nullTerminatedString(input.data.name); - _ = name; // TODO: use the name - const uncasted_arg = sema.resolveInst(input.data.operand); const uncasted_arg_ty = sema.typeOf(uncasted_arg); switch (uncasted_arg_ty.zigTypeTag()) { @@ -10313,8 +10310,9 @@ fn zirAsm( } const constraint = sema.code.nullTerminatedString(input.data.constraint); - needed_capacity += constraint.len / 4 + 1; - inputs[arg_i] = constraint; + const name = sema.code.nullTerminatedString(input.data.name); + needed_capacity += (constraint.len + name.len + 1) / 4 + 1; + inputs[arg_i] = .{ .c = constraint, .n = name }; } const clobbers = try sema.arena.alloc([]const u8, clobbers_len); @@ -10353,11 +10351,13 @@ fn zirAsm( buffer[o.constraint.len] = 0; sema.air_extra.items.len += o.constraint.len / 4 + 1; } - for (inputs) |constraint| { + for (inputs) |input| { const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); - mem.copy(u8, buffer, constraint); - buffer[constraint.len] = 0; - sema.air_extra.items.len += constraint.len / 4 + 1; + mem.copy(u8, buffer, input.c); + buffer[input.c.len] = 0; + mem.copy(u8, buffer[input.c.len + 1 ..], input.n); + buffer[input.c.len + 1 + input.n.len] = 0; + sema.air_extra.items.len += (input.c.len + input.n.len + 1) / 4 + 1; } for (clobbers) |clobber| { const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice()); diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 142611d083..ea946d6ba6 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -3200,10 +3200,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { } else null; for (inputs) |input| { - const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); + const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); + const constraint = std.mem.sliceTo(input_bytes, 0); + const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes // for the string, we still use the next u32 for the null terminator. - extra_i += constraint.len / 4 + 1; + extra_i += (constraint.len + input_name.len + 1) / 4 + 1; if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 6e03dbf4fa..85545e33a5 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -3609,10 +3609,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { } else null; for (inputs) |input| { - const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); + const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); + const constraint = std.mem.sliceTo(input_bytes, 0); + const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes // for the string, we still use the next u32 for the null terminator. - extra_i += constraint.len / 4 + 1; + extra_i += (constraint.len + input_name.len + 1) / 4 + 1; if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index bbc880f0bd..ac12bbceaf 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -2113,10 +2113,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { } else null; for (inputs) |input| { - const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); + const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); + const constraint = std.mem.sliceTo(input_bytes, 0); + const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes // for the string, we still use the next u32 for the null terminator. - extra_i += constraint.len / 4 + 1; + extra_i += (constraint.len + input_name.len + 1) / 4 + 1; if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 9ecd2d4551..b093209a2e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -4618,10 +4618,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { } else null; for (inputs) |input| { - const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); + const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); + const constraint = std.mem.sliceTo(input_bytes, 0); + const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes // for the string, we still use the next u32 for the null terminator. - extra_i += constraint.len / 4 + 1; + extra_i += (constraint.len + input_name.len + 1) / 4 + 1; if (constraint.len < 3 or constraint[0] != '{' or constraint[constraint.len - 1] != '}') { return self.fail("unrecognized asm input constraint: '{s}'", .{constraint}); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index af68255fe8..1391d8fe66 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4545,11 +4545,14 @@ pub const FuncGen = struct { total_i += 1; } + const input_start_extra_i = extra_i; for (inputs) |input| { - const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); + const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); + const constraint = std.mem.sliceTo(input_bytes, 0); + const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); // This equation accounts for the fact that even if we have exactly 4 bytes // for the string, we still use the next u32 for the null terminator. - extra_i += constraint.len / 4 + 1; + extra_i += (constraint.len + input_name.len + 1) / 4 + 1; const arg_llvm_value = try self.resolveInst(input); @@ -4591,11 +4594,12 @@ pub const FuncGen = struct { var rendered_template = std.ArrayList(u8).init(self.gpa); defer rendered_template.deinit(); - const State = enum { start, percent }; + const State = enum { start, percent, input }; var state: State = .start; - for (asm_source) |byte| { + var name_start: usize = undefined; + for (asm_source) |byte, i| { switch (state) { .start => switch (byte) { '%' => state = .percent, @@ -4606,12 +4610,39 @@ pub const FuncGen = struct { try rendered_template.append('%'); state = .start; }, + '[' => { + try rendered_template.append('$'); + name_start = i + 1; + state = .input; + }, else => { try rendered_template.append('%'); try rendered_template.append(byte); state = .start; }, }, + .input => switch (byte) { + ']' => { + const name = asm_source[name_start..i]; + state = .start; + + extra_i = input_start_extra_i; + for (inputs) |_, input_i| { + const input_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); + const constraint = std.mem.sliceTo(input_bytes, 0); + const input_name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); + extra_i += (constraint.len + input_name.len + 1) / 4 + 1; + + if (std.mem.eql(u8, name, input_name)) { + try rendered_template.writer().print("{d}", .{input_i}); + break; + } + } else { + return self.todo("TODO validate asm in Sema", .{}); + } + }, + else => {}, + }, } } |
