Commit cb48376bec

mlugg <mlugg@mlugg.co.uk>
2024-10-15 16:11:02
cbe,translate-c: support more callconvs
There are several more that we could support here, but I didn't feel like going down the rabbit-hole of figuring them out. In particular, some of the Clang enum fields aren't specific enough for us, so we'll have to switch on the target to figure out how to translate-c them. That can be a future enhancement.
1 parent 67580ed
Changed files (4)
lib
compiler
aro_translate_c
src
lib/compiler/aro_translate_c/ast.zig
@@ -560,6 +560,7 @@ pub const Payload = struct {
         pub const CallingConvention = enum {
             c,
             x86_64_sysv,
+            x86_64_win,
             x86_stdcall,
             x86_fastcall,
             x86_thiscall,
@@ -567,6 +568,7 @@ pub const Payload = struct {
             aarch64_vfabi,
             arm_aapcs,
             arm_aapcs_vfp,
+            m68k_rtd,
         };
     };
 
@@ -2834,6 +2836,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
                 });
             },
             .x86_64_sysv,
+            .x86_64_win,
             .x86_stdcall,
             .x86_fastcall,
             .x86_thiscall,
@@ -2841,6 +2844,7 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex {
             .aarch64_vfabi,
             .arm_aapcs,
             .arm_aapcs_vfp,
+            .m68k_rtd,
             => cc_node: {
                 // .{ .foo = .{} }
                 _ = try c.addToken(.period, ".");
src/codegen/c.zig
@@ -7605,16 +7605,38 @@ fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void {
 }
 
 fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8 {
+    if (zcu.getTarget().cCallingConvention()) |ccc| {
+        if (cc.eql(ccc)) {
+            return null;
+        }
+    }
     return switch (cc) {
         .auto, .naked => null,
+
+        .x86_64_sysv, .x86_sysv => "sysv_abi",
+        .x86_64_win, .x86_win => "ms_abi",
         .x86_stdcall => "stdcall",
         .x86_fastcall => "fastcall",
-        .x86_vectorcall, .x86_64_vectorcall => "vectorcall",
-        else => {
-            // `Zcu.callconvSupported` means this must be the C callconv.
-            assert(cc.eql(zcu.getTarget().cCallingConvention().?));
-            return null;
-        },
+        .x86_thiscall => "thiscall",
+
+        .x86_vectorcall,
+        .x86_64_vectorcall,
+        => "vectorcall",
+
+        .x86_64_regcall_v3_sysv,
+        .x86_64_regcall_v4_win,
+        .x86_regcall_v3,
+        .x86_regcall_v4_win,
+        => "regcall",
+
+        .aarch64_vfabi => "aarch64_vector_pcs",
+        .aarch64_vfabi_sve => "aarch64_sve_pcs",
+        .arm_aapcs => "pcs(\"aapcs\")",
+        .arm_aapcs_vfp => "pcs(\"aapcs-vfp\")",
+        .riscv64_lp64_v, .riscv32_ilp32_v => "riscv_vector_cc",
+        .m68k_rtd => "m68k_rtd",
+
+        else => unreachable, // `Zcu.callconvSupported`
     };
 }
 
src/translate_c.zig
@@ -5005,6 +5005,7 @@ fn transCC(
     return switch (clang_cc) {
         .C => .c,
         .X86_64SysV => .x86_64_sysv,
+        .Win64 => .x86_64_win,
         .X86StdCall => .x86_stdcall,
         .X86FastCall => .x86_fastcall,
         .X86ThisCall => .x86_thiscall,
@@ -5012,6 +5013,7 @@ fn transCC(
         .AArch64VectorCall => .aarch64_vfabi,
         .AAPCS => .arm_aapcs,
         .AAPCS_VFP => .arm_aapcs_vfp,
+        .M68kRTD => .m68k_rtd,
         else => return fail(
             c,
             error.UnsupportedType,
src/Zcu.zig
@@ -3568,12 +3568,27 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
                 }
             }
             break :ok switch (cc) {
+                .x86_64_sysv,
+                .x86_64_win,
                 .x86_64_vectorcall,
+                .x86_64_regcall_v3_sysv,
+                .x86_64_regcall_v4_win,
                 .x86_fastcall,
                 .x86_thiscall,
                 .x86_vectorcall,
+                .x86_regcall_v3,
+                .x86_regcall_v4_win,
+                .aarch64_vfabi,
+                .aarch64_vfabi_sve,
+                .arm_aapcs,
+                .arm_aapcs_vfp,
+                .riscv64_lp64_v,
+                .riscv32_ilp32_v,
+                .m68k_rtd,
                 => |opts| opts.incoming_stack_alignment == null,
 
+                .x86_sysv,
+                .x86_win,
                 .x86_stdcall,
                 => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0,