From 9f8b2ff9e223315682fbe9237239714b7d8883f6 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Thu, 5 Oct 2023 17:45:02 -0400 Subject: [PATCH] x86_64: fix C abi typos --- src/arch/x86_64/CodeGen.zig | 50 ++++++++++++++++++++++++------------- src/arch/x86_64/abi.zig | 10 ++++---- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 868bf4d337..60e8181fae 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2568,7 +2568,7 @@ fn airFptrunc(self: *Self, inst: Air.Inst.Index) !void { 80, 128 => true, else => unreachable, }, - 80 => switch (dst_bits) { + 80 => switch (src_bits) { 128 => true, else => unreachable, }, @@ -10278,6 +10278,8 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { } fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void { + const mod = self.bin_file.options.module.?; + const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null; defer if (src_lock) |lock| self.register_manager.unlockReg(lock); @@ -10315,18 +10317,31 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError .off = -dst_reg_off.off, } }, }), - .register_pair => |dst_regs| for (dst_regs, 0..) |dst_reg, dst_reg_i| switch (src_mcv) { - .register_pair => |src_regs| try self.genSetReg( - dst_reg, - Type.usize, - .{ .register = src_regs[dst_reg_i] }, - ), - else => try self.genSetReg( - dst_reg, - Type.usize, - src_mcv.address().offset(@intCast(dst_reg_i * 8)).deref(), - ), - .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref)), + .register_pair => |dst_regs| { + switch (src_mcv) { + .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref)), + else => {}, + } + const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none); + for (dst_regs, classes, 0..) |dst_reg, class, dst_reg_i| { + const class_ty = switch (class) { + .integer => Type.usize, + .sse => Type.f64, + else => unreachable, + }; + switch (src_mcv) { + .register_pair => |src_regs| try self.genSetReg( + dst_reg, + class_ty, + .{ .register = src_regs[dst_reg_i] }, + ), + else => try self.genSetReg( + dst_reg, + class_ty, + src_mcv.address().offset(@intCast(dst_reg_i * 8)).deref(), + ), + } + } }, .indirect => |reg_off| try self.genSetMem(.{ .reg = reg_off.reg }, reg_off.off, ty, src_mcv), .memory, .load_direct, .load_got, .load_tlv => { @@ -12566,7 +12581,7 @@ fn resolveCallingConventionValues( const classes = switch (resolved_cc) { .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, mod, .ret), .none), - .Win64 => &[1]abi.Class{abi.classifyWindows(ret_ty, mod)}, + .Win64 => &.{abi.classifyWindows(ret_ty, mod)}, else => unreachable, }; for (classes) |class| switch (class) { @@ -12639,9 +12654,10 @@ fn resolveCallingConventionValues( var arg_mcv: [2]MCValue = undefined; var arg_mcv_i: usize = 0; - const classes = switch (self.target.os.tag) { - .windows => &[1]abi.Class{abi.classifyWindows(ty, mod)}, - else => mem.sliceTo(&abi.classifySystemV(ty, mod, .arg), .none), + const classes = switch (resolved_cc) { + .SysV => mem.sliceTo(&abi.classifySystemV(ty, mod, .arg), .none), + .Win64 => &.{abi.classifyWindows(ty, mod)}, + else => unreachable, }; for (classes) |class| switch (class) { .integer => { diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig index 682c2644e1..73559a03d1 100644 --- a/src/arch/x86_64/abi.zig +++ b/src/arch/x86_64/abi.zig @@ -64,7 +64,7 @@ pub fn classifyWindows(ty: Type, mod: *Module) Class { } } -pub const Context = enum { ret, arg, other }; +pub const Context = enum { ret, arg, field, other }; /// There are a maximum of 8 possible return slots. Returned values are in /// the beginning of the array; unused slots are filled with .none. @@ -120,7 +120,7 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class { }, .Float => switch (ty.floatBits(target)) { 16 => { - if (ctx == .other) { + if (ctx == .field) { result[0] = .memory; } else { // TODO clang doesn't allow __fp16 as .ret or .arg @@ -140,7 +140,7 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class { // "Arguments of types __float128, _Decimal128 and __m128 are // split into two halves. The least significant ones belong // to class SSE, the most significant one to class SSEUP." - if (ctx == .other) { + if (ctx == .field) { result[0] = .memory; return result; } @@ -229,7 +229,7 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class { if (field_align != .none and field_align.compare(.lt, field_ty.abiAlignment(mod))) return memory_class; const field_size = field_ty.abiSize(mod); - const field_class_array = classifySystemV(field_ty, mod, .other); + const field_class_array = classifySystemV(field_ty, mod, .field); const field_class = std.mem.sliceTo(&field_class_array, .none); if (byte_i + field_size <= 8) { // Combine this field with the previous one. @@ -347,7 +347,7 @@ pub fn classifySystemV(ty: Type, mod: *Module, ctx: Context) [8]Class { return memory_class; } // Combine this field with the previous one. - const field_class = classifySystemV(field_ty.toType(), mod, .other); + const field_class = classifySystemV(field_ty.toType(), mod, .field); for (&result, 0..) |*result_item, i| { const field_item = field_class[i]; // "If both classes are equal, this is the resulting class."