aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-08-13 23:09:55 -0400
committerAndrew Kelley <andrew@ziglang.org>2023-09-19 09:37:32 -0700
commitb1b155feacaa12a758ef4800cef021da7ae19040 (patch)
tree8c8e20945bb9b523ac04514d94ebe056ddf2191f /src/arch
parentd7daf7c203f583ed440efc68df6ee690ee8f8f32 (diff)
downloadzig-b1b155feacaa12a758ef4800cef021da7ae19040.tar.gz
zig-b1b155feacaa12a758ef4800cef021da7ae19040.zip
llvm: update riscv floating-point c abi for LLVM 17
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/riscv64/abi.zig20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/arch/riscv64/abi.zig b/src/arch/riscv64/abi.zig
index 41a1850635..da74734de4 100644
--- a/src/arch/riscv64/abi.zig
+++ b/src/arch/riscv64/abi.zig
@@ -5,7 +5,7 @@ const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
const Type = @import("../../type.zig").Type;
const Module = @import("../../Module.zig");
-pub const Class = enum { memory, byval, integer, double_integer };
+pub const Class = enum { memory, byval, integer, double_integer, fields };
pub fn classifyType(ty: Type, mod: *Module) Class {
const target = mod.getTarget();
@@ -19,6 +19,24 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
if (bit_size > max_byval_size) return .memory;
return .byval;
}
+
+ if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: {
+ var any_fp = false;
+ var field_count: usize = 0;
+ for (0..ty.structFieldCount(mod)) |field_index| {
+ const field_ty = ty.structFieldType(field_index, mod);
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (field_ty.isRuntimeFloat())
+ any_fp = true
+ else if (!field_ty.isAbiInt(mod))
+ break :fields;
+ field_count += 1;
+ if (field_count > 2) break :fields;
+ }
+ std.debug.assert(field_count > 0 and field_count <= 2);
+ if (any_fp) return .fields;
+ }
+
// TODO this doesn't exactly match what clang produces but its better than nothing
if (bit_size > max_byval_size) return .memory;
if (bit_size > max_byval_size / 2) return .double_integer;