From fbd7e4506f46b73e351e1f3eb5e7cfc16ebbfc1f Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 7 Jun 2022 19:13:50 +0300 Subject: stage2: implement asm with multiple outputs --- src/codegen/llvm.zig | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index f7a1d732b4..a56dd8cf6f 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5435,10 +5435,6 @@ pub const FuncGen = struct { const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i..][0..extra.data.inputs_len]); extra_i += inputs.len; - if (outputs.len > 1) { - return self.todo("implement llvm codegen for asm with more than 1 output", .{}); - } - var llvm_constraints: std.ArrayListUnmanaged(u8) = .{}; defer llvm_constraints.deinit(self.gpa); @@ -5446,7 +5442,10 @@ pub const FuncGen = struct { defer arena_allocator.deinit(); const arena = arena_allocator.allocator(); - const llvm_params_len = inputs.len; + const return_count: u8 = for (outputs) |output| { + if (output == .none) break 1; + } else 0; + const llvm_params_len = inputs.len + outputs.len - return_count; const llvm_param_types = try arena.alloc(*const llvm.Type, llvm_params_len); const llvm_param_values = try arena.alloc(*const llvm.Value, llvm_params_len); var llvm_param_i: usize = 0; @@ -5456,9 +5455,6 @@ pub const FuncGen = struct { try name_map.ensureUnusedCapacity(arena, outputs.len + inputs.len); for (outputs) |output| { - if (output != .none) { - return self.todo("implement inline asm with non-returned output", .{}); - } const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]); const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0); const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); @@ -5471,6 +5467,15 @@ pub const FuncGen = struct { llvm_constraints.appendAssumeCapacity(','); } llvm_constraints.appendAssumeCapacity('='); + if (output != .none) { + try llvm_constraints.ensureUnusedCapacity(self.gpa, llvm_constraints.capacity + 1); + llvm_constraints.appendAssumeCapacity('*'); + + const output_inst = try self.resolveInst(output); + llvm_param_values[llvm_param_i] = output_inst; + llvm_param_types[llvm_param_i] = output_inst.typeOf(); + llvm_param_i += 1; + } llvm_constraints.appendSliceAssumeCapacity(constraint[1..]); name_map.putAssumeCapacityNoClobber(name, {}); -- cgit v1.2.3 From 6de9eea7bce4023ae150fb5b4d417d66b9bf13fb Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 7 Jun 2022 19:49:40 +0300 Subject: stage2 llvm: fix float/int conversion compiler-rt calls --- src/codegen/llvm.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index a56dd8cf6f..dcdf4888ea 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5012,7 +5012,7 @@ pub const FuncGen = struct { const compiler_rt_operand_abbrev = compilerRtFloatAbbrev(operand_bits); const compiler_rt_dest_abbrev = compilerRtIntAbbrev(rt_int_bits); - const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "un"; + const sign_prefix = if (dest_scalar_ty.isSignedInt()) "" else "uns"; var fn_name_buf: [64]u8 = undefined; const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__fix{s}{s}f{s}i", .{ @@ -9289,7 +9289,7 @@ fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool { } fn compilerRtIntBits(bits: u16) u16 { - inline for (.{ 8, 16, 32, 64, 128 }) |b| { + inline for (.{ 32, 64, 128 }) |b| { if (bits <= b) { return b; } -- cgit v1.2.3