authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-13 23:09:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-19 09:37:32-07:00
logb1b155feacaa12a758ef4800cef021da7ae19040
tree8c8e20945bb9b523ac04514d94ebe056ddf2191f
parentd7daf7c203f583ed440efc68df6ee690ee8f8f32

llvm: update riscv floating-point c abi for LLVM 17


2 files changed, 43 insertions(+), 4 deletions(-)

src/arch/riscv64/abi.zig+19-1
...@@ -5,7 +5,7 @@ const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;...@@ -5,7 +5,7 @@ const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
5const Type = @import("../../type.zig").Type;5const Type = @import("../../type.zig").Type;
6const Module = @import("../../Module.zig");6const Module = @import("../../Module.zig");
77
8pub const Class = enum { memory, byval, integer, double_integer };8pub const Class = enum { memory, byval, integer, double_integer, fields };
99
10pub fn classifyType(ty: Type, mod: *Module) Class {10pub fn classifyType(ty: Type, mod: *Module) Class {
11 const target = mod.getTarget();11 const target = mod.getTarget();
...@@ -19,6 +19,24 @@ pub fn classifyType(ty: Type, mod: *Module) Class {...@@ -19,6 +19,24 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
19 if (bit_size > max_byval_size) return .memory;19 if (bit_size > max_byval_size) return .memory;
20 return .byval;20 return .byval;
21 }21 }
22
23 if (std.Target.riscv.featureSetHas(target.cpu.features, .d)) fields: {
24 var any_fp = false;
25 var field_count: usize = 0;
26 for (0..ty.structFieldCount(mod)) |field_index| {
27 const field_ty = ty.structFieldType(field_index, mod);
28 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
29 if (field_ty.isRuntimeFloat())
30 any_fp = true
31 else if (!field_ty.isAbiInt(mod))
32 break :fields;
33 field_count += 1;
34 if (field_count > 2) break :fields;
35 }
36 std.debug.assert(field_count > 0 and field_count <= 2);
37 if (any_fp) return .fields;
38 }
39
22 // TODO this doesn't exactly match what clang produces but its better than nothing40 // TODO this doesn't exactly match what clang produces but its better than nothing
23 if (bit_size > max_byval_size) return .memory;41 if (bit_size > max_byval_size) return .memory;
24 if (bit_size > max_byval_size / 2) return .double_integer;42 if (bit_size > max_byval_size / 2) return .double_integer;
src/codegen/llvm.zig+24-3
...@@ -10674,6 +10674,17 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu...@@ -10674,6 +10674,17 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu
10674 return o.builder.structType(.normal, &.{ .i64, .i64 });10674 return o.builder.structType(.normal, &.{ .i64, .i64 });
10675 },10675 },
10676 .byval => return o.lowerType(return_type),10676 .byval => return o.lowerType(return_type),
10677 .fields => {
10678 var types_len: usize = 0;
10679 var types: [8]Builder.Type = undefined;
10680 for (0..return_type.structFieldCount(mod)) |field_index| {
10681 const field_ty = return_type.structFieldType(field_index, mod);
10682 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
10683 types[types_len] = try o.lowerType(field_ty);
10684 types_len += 1;
10685 }
10686 return o.builder.structType(.normal, types[0..types_len]);
10687 },
10677 }10688 }
10678 },10689 },
10679 // TODO investigate C ABI for other architectures10690 // TODO investigate C ABI for other architectures
...@@ -10887,14 +10898,24 @@ const ParamTypeIterator = struct {...@@ -10887,14 +10898,24 @@ const ParamTypeIterator = struct {
10887 .riscv32, .riscv64 => {10898 .riscv32, .riscv64 => {
10888 it.zig_index += 1;10899 it.zig_index += 1;
10889 it.llvm_index += 1;10900 it.llvm_index += 1;
10890 if (ty.toIntern() == .f16_type) {10901 if (ty.toIntern() == .f16_type and
10891 return .as_u16;10902 !std.Target.riscv.featureSetHas(target.cpu.features, .d)) return .as_u16;
10892 }
10893 switch (riscv_c_abi.classifyType(ty, mod)) {10903 switch (riscv_c_abi.classifyType(ty, mod)) {
10894 .memory => return .byref_mut,10904 .memory => return .byref_mut,
10895 .byval => return .byval,10905 .byval => return .byval,
10896 .integer => return .abi_sized_int,10906 .integer => return .abi_sized_int,
10897 .double_integer => return Lowering{ .i64_array = 2 },10907 .double_integer => return Lowering{ .i64_array = 2 },
10908 .fields => {
10909 it.types_len = 0;
10910 for (0..ty.structFieldCount(mod)) |field_index| {
10911 const field_ty = ty.structFieldType(field_index, mod);
10912 if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
10913 it.types_buffer[it.types_len] = try it.object.lowerType(field_ty);
10914 it.types_len += 1;
10915 }
10916 it.llvm_index += it.types_len - 1;
10917 return .multiple_llvm_types;
10918 },
10898 }10919 }
10899 },10920 },
10900 // TODO investigate C ABI for other architectures10921 // TODO investigate C ABI for other architectures