From cca7c50b54bbf5d763da839582edff69bd9d051d Mon Sep 17 00:00:00 2001 From: xtex Date: Sun, 30 Aug 2026 21:15:42 +0800 Subject: [PATCH] loongarch: ABI resolve for f16/f32/f64/f128 --- src/codegen/loongarch/Select.zig | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/codegen/loongarch/Select.zig b/src/codegen/loongarch/Select.zig index 04197dc7c4f41d43a2f5ed408823eeda83b2ee33..1b1dd5a4b858d781c19461ffae00da265c6e77a0 100644 --- a/src/codegen/loongarch/Select.zig +++ b/src/codegen/loongarch/Select.zig @@ -3758,7 +3758,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, } else if (dst_tag == .float and src_tag == .float) { assert(dst_ty.floatBits(isel.target) == src_ty.floatBits(isel.target)); try dst_vi.value.defMove(isel, ty_op.operand); - } else if (dst_ty.isAbiInt(zcu) and src_tag == .float and isel.canUseFprForFloat(src_ty)) { + } else if (dst_ty.isAbiInt(zcu) and src_tag == .float and isel.canUseFprForFloat(src_ty.floatBits(isel.target))) { const dst_int_info = dst_ty.intInfo(zcu); assert(dst_int_info.bits == src_ty.floatBits(isel.target)); @@ -3773,7 +3773,7 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, 64 => .@"movfr2gr.d"(dst_reg, src_reg), }); try src_mat.finish(isel); - } else if (dst_tag == .float and src_ty.isAbiInt(zcu) and isel.canUseFprForFloat(dst_ty)) { + } else if (dst_tag == .float and src_ty.isAbiInt(zcu) and isel.canUseFprForFloat(dst_ty.floatBits(isel.target))) { const src_int_info = src_ty.intInfo(zcu); assert(dst_ty.floatBits(isel.target) == src_int_info.bits); @@ -6942,6 +6942,7 @@ pub const CallAbiIterator = struct { }, .simple_type => |simple_type| switch (simple_type) { .f80 => continue :type_key .{ .int_type = .{ .signedness = .unsigned, .bits = 80 } }, + .f128 => continue :type_key .{ .int_type = .{ .signedness = .unsigned, .bits = 128 } }, .usize, .isize, .c_char, @@ -6959,7 +6960,22 @@ pub const CallAbiIterator = struct { .signedness = .unsigned, .bits = zcu.errorSetBits(), } }, - .f16, .f32, .f64, .f128, .c_longdouble => return isel.fail("CallAbiIterator.resolve({t})", .{simple_type}), + .f16, .f32, .f64 => { + const bits = ty.floatBits(isel.target); + if (isel.canUseFprForFloat(bits)) { + if (it.allocReg(.fpr)) |reg| { + wip_vi.setHintRegister(isel, reg); + if (bits != 16) { + wip_vi.setHintModifier(isel, .fromFloatBits(bits)); + } else { + wip_vi.setHintModifier(isel, .floating32); + } + } else it.assignStack(wip_vi); + } else { + continue :type_key .{ .int_type = .{ .signedness = .unsigned, .bits = bits } }; + } + }, + .c_longdouble => return isel.fail("CallAbiIterator.resolve({t})", .{simple_type}), else => return isel.fail("CallAbiIterator.resolve({t})", .{simple_type}), }, .struct_type => { @@ -7280,8 +7296,8 @@ fn vectorBits(isel: *Select) u7 { } } -fn canUseFprForFloat(isel: *Select, ty: ZigType) bool { - return ty.floatBits(isel.target) <= isel.fprBits(); +fn canUseFprForFloat(isel: *Select, bits: u16) bool { + return bits <= isel.fprBits(); } fn typeOfField(isel: *Select, ty: ZigType, offset: u64) ?ZigType { -- 2.54.0