Commit cd95444e47

Andrew Kelley <andrew@ziglang.org>
2021-01-05 21:59:33
stage2: C backend: remove format() hackery
All C backend tests passing now, except for emit-h tests. Next task in the branch is to restore emit-h.
1 parent 58cfaa5
Changed files (4)
src
codegen
link
test
stage2
src/codegen/c.zig
@@ -27,42 +27,6 @@ pub const CValue = union(enum) {
     arg: usize,
     /// By-value
     decl: *Decl,
-
-    pub fn printed(value: CValue, object: *Object) Printed {
-        return .{
-            .value = value,
-            .object = object,
-        };
-    }
-
-    pub const Printed = struct {
-        value: CValue,
-        object: *Object,
-
-        /// TODO this got unwieldly, I want to remove the ability to print this way
-        pub fn format(
-            self: Printed,
-            comptime fmt: []const u8,
-            options: std.fmt.FormatOptions,
-            writer: anytype,
-        ) error{OutOfMemory}!void {
-            if (fmt.len != 0) @compileError("Unknown format string: '" ++ fmt ++ "'");
-            switch (self.value) {
-                .none => unreachable,
-                .local => |i| return std.fmt.format(writer, "t{d}", .{i}),
-                .local_ref => |i| return std.fmt.format(writer, "&t{d}", .{i}),
-                .constant => |inst| {
-                    const o = self.object;
-                    o.dg.renderValue(writer, inst.ty, inst.value().?) catch |err| switch (err) {
-                        error.OutOfMemory => return error.OutOfMemory,
-                        error.AnalysisFail => return,
-                    };
-                },
-                .arg => |i| return std.fmt.format(writer, "a{d}", .{i}),
-                .decl => |decl| return writer.writeAll(mem.span(decl.name)),
-            }
-        }
-    };
 };
 
 pub const CValueMap = std.AutoHashMap(*Inst, CValue);
@@ -103,6 +67,17 @@ pub const Object = struct {
         try o.code.writer().writeByteNTimes(' ', indent_amt);
     }
 
+    fn writeCValue(o: *Object, writer: Writer, c_value: CValue) !void {
+        switch (c_value) {
+            .none => unreachable,
+            .local => |i| return writer.print("t{d}", .{i}),
+            .local_ref => |i| return writer.print("&t{d}", .{i}),
+            .constant => |inst| return o.dg.renderValue(writer, inst.ty, inst.value().?),
+            .arg => |i| return writer.print("a{d}", .{i}),
+            .decl => |decl| return writer.writeAll(mem.span(decl.name)),
+        }
+    }
+
     fn renderTypeAndName(
         o: *Object,
         writer: Writer,
@@ -127,7 +102,9 @@ pub const Object = struct {
             .Const => "const ",
             .Mut => "",
         };
-        try writer.print(" {s}{}{s}", .{ const_prefix, name.printed(o), suffix.items });
+        try writer.print(" {s}", .{const_prefix});
+        try o.writeCValue(writer, name);
+        try writer.writeAll(suffix.items);
     }
 };
 
@@ -353,7 +330,7 @@ pub fn genDecl(o: *Object) !void {
         try writer.writeAll("\n");
         for (instructions) |inst| {
             const result_value = switch (inst.tag) {
-                .add => try genBinOp(o, inst.castTag(.add).?, "+"),
+                .add => try genBinOp(o, inst.castTag(.add).?, " + "),
                 .alloc => try genAlloc(o, inst.castTag(.alloc).?),
                 .arg => genArg(o),
                 .assembly => try genAsm(o, inst.castTag(.assembly).?),
@@ -361,19 +338,19 @@ pub fn genDecl(o: *Object) !void {
                 .bitcast => try genBitcast(o, inst.castTag(.bitcast).?),
                 .breakpoint => try genBreakpoint(o, inst.castTag(.breakpoint).?),
                 .call => try genCall(o, inst.castTag(.call).?),
-                .cmp_eq => try genBinOp(o, inst.castTag(.cmp_eq).?, "=="),
-                .cmp_gt => try genBinOp(o, inst.castTag(.cmp_gt).?, ">"),
-                .cmp_gte => try genBinOp(o, inst.castTag(.cmp_gte).?, ">="),
-                .cmp_lt => try genBinOp(o, inst.castTag(.cmp_lt).?, "<"),
-                .cmp_lte => try genBinOp(o, inst.castTag(.cmp_lte).?, "<="),
-                .cmp_neq => try genBinOp(o, inst.castTag(.cmp_neq).?, "!="),
+                .cmp_eq => try genBinOp(o, inst.castTag(.cmp_eq).?, " == "),
+                .cmp_gt => try genBinOp(o, inst.castTag(.cmp_gt).?, " > "),
+                .cmp_gte => try genBinOp(o, inst.castTag(.cmp_gte).?, " >= "),
+                .cmp_lt => try genBinOp(o, inst.castTag(.cmp_lt).?, " < "),
+                .cmp_lte => try genBinOp(o, inst.castTag(.cmp_lte).?, " <= "),
+                .cmp_neq => try genBinOp(o, inst.castTag(.cmp_neq).?, " != "),
                 .dbg_stmt => try genDbgStmt(o, inst.castTag(.dbg_stmt).?),
                 .intcast => try genIntCast(o, inst.castTag(.intcast).?),
                 .load => try genLoad(o, inst.castTag(.load).?),
                 .ret => try genRet(o, inst.castTag(.ret).?),
                 .retvoid => try genRetVoid(o),
                 .store => try genStore(o, inst.castTag(.store).?),
-                .sub => try genBinOp(o, inst.castTag(.sub).?, "-"),
+                .sub => try genBinOp(o, inst.castTag(.sub).?, " - "),
                 .unreach => try genUnreach(o, inst.castTag(.unreach).?),
                 else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),
             };
@@ -457,10 +434,14 @@ fn genLoad(o: *Object, inst: *Inst.UnOp) !CValue {
     switch (operand) {
         .local_ref => |i| {
             const wrapped: CValue = .{ .local = i };
-            try writer.print(" = {};\n", .{wrapped.printed(o)});
+            try writer.writeAll(" = ");
+            try o.writeCValue(writer, wrapped);
+            try writer.writeAll(";\n");
         },
         else => {
-            try writer.print(" = *{};\n", .{operand.printed(o)});
+            try writer.writeAll(" = *");
+            try o.writeCValue(writer, operand);
+            try writer.writeAll(";\n");
         },
     }
     return local;
@@ -469,7 +450,10 @@ fn genLoad(o: *Object, inst: *Inst.UnOp) !CValue {
 fn genRet(o: *Object, inst: *Inst.UnOp) !CValue {
     const operand = try o.resolveInst(inst.operand);
     try o.indent();
-    try o.code.writer().print("return {};\n", .{operand.printed(o)});
+    const writer = o.code.writer();
+    try writer.writeAll("return ");
+    try o.writeCValue(writer, operand);
+    try writer.writeAll(";\n");
     return CValue.none;
 }
 
@@ -484,7 +468,9 @@ fn genIntCast(o: *Object, inst: *Inst.UnOp) !CValue {
     const local = try o.allocLocal(inst.base.ty, .Const);
     try writer.writeAll(" = (");
     try o.dg.renderType(writer, inst.base.ty);
-    try writer.print("){};\n", .{from.printed(o)});
+    try writer.writeAll(")");
+    try o.writeCValue(writer, from);
+    try writer.writeAll(";\n");
     return local;
 }
 
@@ -498,10 +484,17 @@ fn genStore(o: *Object, inst: *Inst.BinOp) !CValue {
     switch (dest_ptr) {
         .local_ref => |i| {
             const dest: CValue = .{ .local = i };
-            try writer.print("{} = {};\n", .{ dest.printed(o), src_val.printed(o) });
+            try o.writeCValue(writer, dest);
+            try writer.writeAll(" = ");
+            try o.writeCValue(writer, src_val);
+            try writer.writeAll(";\n");
         },
         else => {
-            try writer.print("*{} = {};\n", .{ dest_ptr.printed(o), src_val.printed(o) });
+            try writer.writeAll("*");
+            try o.writeCValue(writer, dest_ptr);
+            try writer.writeAll(" = ");
+            try o.writeCValue(writer, src_val);
+            try writer.writeAll(";\n");
         },
     }
     return CValue.none;
@@ -517,7 +510,13 @@ fn genBinOp(o: *Object, inst: *Inst.BinOp, operator: []const u8) !CValue {
     try o.indent();
     const writer = o.code.writer();
     const local = try o.allocLocal(inst.base.ty, .Const);
-    try writer.print(" = {} {s} {};\n", .{ lhs.printed(o), operator, rhs.printed(o) });
+
+    try writer.writeAll(" = ");
+    try o.writeCValue(writer, lhs);
+    try writer.writeAll(operator);
+    try o.writeCValue(writer, rhs);
+    try writer.writeAll(";\n");
+
     return local;
 }
 
@@ -556,7 +555,7 @@ fn genCall(o: *Object, inst: *Inst.Call) !CValue {
                     try o.dg.renderValue(writer, arg.ty, val);
                 } else {
                     const val = try o.resolveInst(arg);
-                    try writer.print("{}", .{val.printed(o)});
+                    try o.writeCValue(writer, val);
                 }
             }
         }
@@ -585,16 +584,25 @@ fn genBitcast(o: *Object, inst: *Inst.UnOp) !CValue {
         const local = try o.allocLocal(inst.base.ty, .Const);
         try writer.writeAll(" = (");
         try o.dg.renderType(writer, inst.base.ty);
-        try writer.print("){};\n", .{operand.printed(o)});
+
+        try writer.writeAll(")");
+        try o.writeCValue(writer, operand);
+        try writer.writeAll(";\n");
         return local;
     }
 
     const local = try o.allocLocal(inst.base.ty, .Mut);
     try writer.writeAll(";\n");
     try o.indent();
-    try writer.print("memcpy(&{}, &{}, sizeof {});\n", .{
-        local.printed(o), operand.printed(o), local.printed(o),
-    });
+
+    try writer.writeAll("memcpy(&");
+    try o.writeCValue(writer, local);
+    try writer.writeAll(", &");
+    try o.writeCValue(writer, operand);
+    try writer.writeAll(", sizeof ");
+    try o.writeCValue(writer, local);
+    try writer.writeAll(");\n");
+
     return local;
 }
 
@@ -623,9 +631,10 @@ fn genAsm(o: *Object, as: *Inst.Assembly) !CValue {
             try o.indent();
             try writer.writeAll("register ");
             try o.dg.renderType(writer, arg.ty);
-            try writer.print(" {s}_constant __asm__(\"{s}\") = {};\n", .{
-                reg, reg, arg_c_value.printed(o),
-            });
+
+            try writer.print(" {s}_constant __asm__(\"{s}\") = ", .{ reg, reg });
+            try o.writeCValue(writer, arg_c_value);
+            try writer.writeAll(";\n");
         } else {
             return o.dg.fail(o.dg.decl.src(), "TODO non-explicit inline asm regs", .{});
         }
@@ -648,7 +657,7 @@ fn genAsm(o: *Object, as: *Inst.Assembly) !CValue {
                 if (index > 0) {
                     try writer.writeAll(", ");
                 }
-                try writer.print("\"\"({s}_constant)", .{reg});
+                try writer.print("\"r\"({s}_constant)", .{reg});
             } else {
                 // This is blocked by the earlier test
                 unreachable;
src/link/C/zig.h
@@ -22,24 +22,31 @@
 #define zig_unreachable()
 #endif
 
-#if defined(_MSC_VER)
-#define zig_breakpoint __debugbreak()
+#if __STDC_VERSION__ >= 199901L
+#define zig_restrict restrict
+#elif defined(__GNUC__)
+#define zig_restrict __restrict
 #else
-#if defined(__MINGW32__) || defined(__MINGW64__)
-#define zig_breakpoint __debugbreak()
+#define zig_restrict
+#endif
+
+#if defined(_MSC_VER)
+#define zig_breakpoint() __debugbreak()
+#elif defined(__MINGW32__) || defined(__MINGW64__)
+#define zig_breakpoint() __debugbreak()
 #elif defined(__clang__)
-#define zig_breakpoint __builtin_debugtrap()
+#define zig_breakpoint() __builtin_debugtrap()
 #elif defined(__GNUC__)
-#define zig_breakpoint __builtin_trap()
+#define zig_breakpoint() __builtin_trap()
 #elif defined(__i386__) || defined(__x86_64__)
-#define zig_breakpoint __asm__ volatile("int $0x03");
+#define zig_breakpoint() __asm__ volatile("int $0x03");
 #else
-#define zig_breakpoint raise(SIGTRAP)
-#endif
+#define zig_breakpoint() raise(SIGTRAP)
 #endif
 
 #include <stdint.h>
+#include <stddef.h>
 #define int128_t __int128
 #define uint128_t unsigned __int128
-#include <string.h>
+void *memcpy (void *zig_restrict, const void *zig_restrict, size_t);
 
src/link/C.zig
@@ -101,14 +101,12 @@ pub fn updateDecl(self: *C, module: *Module, decl: *Module.Decl) !void {
     defer object.dg.fwd_decl.deinit();
 
     codegen.genDecl(&object) catch |err| switch (err) {
-        error.AnalysisFail => {},
+        error.AnalysisFail => {
+            try module.failed_decls.put(module.gpa, decl, object.dg.error_msg.?);
+            return;
+        },
         else => |e| return e,
     };
-    // The code may populate this error without returning error.AnalysisFail.
-    if (object.dg.error_msg) |msg| {
-        try module.failed_decls.put(module.gpa, decl, msg);
-        return;
-    }
 
     fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged();
     code.* = object.code.moveToUnmanaged();
test/stage2/cbe.zig
@@ -31,6 +31,100 @@ pub fn addCases(ctx: *TestContext) !void {
         , "yo" ++ std.cstr.line_sep);
     }
 
+    {
+        var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64);
+
+        // Exit with 0
+        case.addCompareOutput(
+            \\fn exitGood() noreturn {
+            \\    asm volatile ("syscall"
+            \\        :
+            \\        : [number] "{rax}" (231),
+            \\          [arg1] "{rdi}" (0)
+            \\    );
+            \\    unreachable;
+            \\}
+            \\
+            \\export fn main() c_int {
+            \\    exitGood();
+            \\}
+        , "");
+
+        // Pass a usize parameter to exit
+        case.addCompareOutput(
+            \\export fn main() c_int {
+            \\    exit(0);
+            \\}
+            \\
+            \\fn exit(code: usize) noreturn {
+            \\    asm volatile ("syscall"
+            \\        :
+            \\        : [number] "{rax}" (231),
+            \\          [arg1] "{rdi}" (code)
+            \\    );
+            \\    unreachable;
+            \\}
+        , "");
+
+        // Change the parameter to u8
+        case.addCompareOutput(
+            \\export fn main() c_int {
+            \\    exit(0);
+            \\}
+            \\
+            \\fn exit(code: u8) noreturn {
+            \\    asm volatile ("syscall"
+            \\        :
+            \\        : [number] "{rax}" (231),
+            \\          [arg1] "{rdi}" (code)
+            \\    );
+            \\    unreachable;
+            \\}
+        , "");
+
+        // Do some arithmetic at the exit callsite
+        case.addCompareOutput(
+            \\export fn main() c_int {
+            \\    exitMath(1);
+            \\}
+            \\
+            \\fn exitMath(a: u8) noreturn {
+            \\    exit(0 + a - a);
+            \\}
+            \\
+            \\fn exit(code: u8) noreturn {
+            \\    asm volatile ("syscall"
+            \\        :
+            \\        : [number] "{rax}" (231),
+            \\          [arg1] "{rdi}" (code)
+            \\    );
+            \\    unreachable;
+            \\}
+            \\
+        , "");
+
+        // Invert the arithmetic
+        case.addCompareOutput(
+            \\export fn main() c_int {
+            \\    exitMath(1);
+            \\}
+            \\
+            \\fn exitMath(a: u8) noreturn {
+            \\    exit(a + 0 - a);
+            \\}
+            \\
+            \\fn exit(code: u8) noreturn {
+            \\    asm volatile ("syscall"
+            \\        :
+            \\        : [number] "{rax}" (231),
+            \\          [arg1] "{rdi}" (code)
+            \\    );
+            \\    unreachable;
+            \\}
+            \\
+        , "");
+    }
+
     {
         var case = ctx.exeFromCompiledC("alloc and retptr", .{});
 
@@ -86,6 +180,8 @@ pub fn addCases(ctx: *TestContext) !void {
         \\    unreachable;
         \\}
     ,
+        \\zig_noreturn void _start(void);
+        \\
         \\zig_noreturn void _start(void) {
         \\    zig_breakpoint();
         \\    zig_unreachable();
@@ -98,223 +194,6 @@ pub fn addCases(ctx: *TestContext) !void {
         \\void start(void);
         \\
     );
-    ctx.c("less empty start function", linux_x64,
-        \\fn main() noreturn {
-        \\    unreachable;
-        \\}
-        \\
-        \\export fn _start() noreturn {
-        \\    main();
-        \\}
-    ,
-        \\static zig_noreturn void main(void);
-        \\
-        \\static zig_noreturn void main(void) {
-        \\    zig_breakpoint();
-        \\    zig_unreachable();
-        \\}
-        \\
-        \\zig_noreturn void _start(void) {
-        \\    main();
-        \\}
-        \\
-    );
-    // TODO: implement return values
-    // TODO: figure out a way to prevent asm constants from being generated
-    ctx.c("inline asm", linux_x64,
-        \\fn exitGood() noreturn {
-        \\    asm volatile ("syscall"
-        \\        :
-        \\        : [number] "{rax}" (231),
-        \\          [arg1] "{rdi}" (0)
-        \\    );
-        \\    unreachable;
-        \\}
-        \\
-        \\export fn _start() noreturn {
-        \\    exitGood();
-        \\}
-    ,
-        \\static zig_noreturn void exitGood(void);
-        \\
-        \\static uint8_t exitGood__anon_0[6] = "{rax}";
-        \\static uint8_t exitGood__anon_1[6] = "{rdi}";
-        \\static uint8_t exitGood__anon_2[8] = "syscall";
-        \\
-        \\static zig_noreturn void exitGood(void) {
-        \\    register uintptr_t rax_constant __asm__("rax") = 231;
-        \\    register uintptr_t rdi_constant __asm__("rdi") = 0;
-        \\    __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
-        \\    zig_breakpoint();
-        \\    zig_unreachable();
-        \\}
-        \\
-        \\zig_noreturn void _start(void) {
-        \\    exitGood();
-        \\}
-        \\
-    );
-    ctx.c("exit with parameter", linux_x64,
-        \\export fn _start() noreturn {
-        \\    exit(0);
-        \\}
-        \\
-        \\fn exit(code: usize) noreturn {
-        \\    asm volatile ("syscall"
-        \\        :
-        \\        : [number] "{rax}" (231),
-        \\          [arg1] "{rdi}" (code)
-        \\    );
-        \\    unreachable;
-        \\}
-        \\
-    ,
-        \\static zig_noreturn void exit(uintptr_t arg0);
-        \\
-        \\static uint8_t exit__anon_0[6] = "{rax}";
-        \\static uint8_t exit__anon_1[6] = "{rdi}";
-        \\static uint8_t exit__anon_2[8] = "syscall";
-        \\
-        \\zig_noreturn void _start(void) {
-        \\    exit(0);
-        \\}
-        \\
-        \\static zig_noreturn void exit(uintptr_t arg0) {
-        \\    register uintptr_t rax_constant __asm__("rax") = 231;
-        \\    register uintptr_t rdi_constant __asm__("rdi") = arg0;
-        \\    __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
-        \\    zig_breakpoint();
-        \\    zig_unreachable();
-        \\}
-        \\
-    );
-    ctx.c("exit with u8 parameter", linux_x64,
-        \\export fn _start() noreturn {
-        \\    exit(0);
-        \\}
-        \\
-        \\fn exit(code: u8) noreturn {
-        \\    asm volatile ("syscall"
-        \\        :
-        \\        : [number] "{rax}" (231),
-        \\          [arg1] "{rdi}" (code)
-        \\    );
-        \\    unreachable;
-        \\}
-        \\
-    ,
-        \\static zig_noreturn void exit(uint8_t arg0);
-        \\
-        \\static uint8_t exit__anon_0[6] = "{rax}";
-        \\static uint8_t exit__anon_1[6] = "{rdi}";
-        \\static uint8_t exit__anon_2[8] = "syscall";
-        \\
-        \\zig_noreturn void _start(void) {
-        \\    exit(0);
-        \\}
-        \\
-        \\static zig_noreturn void exit(uint8_t arg0) {
-        \\    uintptr_t const __temp_0 = (uintptr_t)arg0;
-        \\    register uintptr_t rax_constant __asm__("rax") = 231;
-        \\    register uintptr_t rdi_constant __asm__("rdi") = __temp_0;
-        \\    __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
-        \\    zig_breakpoint();
-        \\    zig_unreachable();
-        \\}
-        \\
-    );
-    ctx.c("exit with u8 arithmetic", linux_x64,
-        \\export fn _start() noreturn {
-        \\    exitMath(1);
-        \\}
-        \\
-        \\fn exitMath(a: u8) noreturn {
-        \\    exit(0 + a - a);
-        \\}
-        \\
-        \\fn exit(code: u8) noreturn {
-        \\    asm volatile ("syscall"
-        \\        :
-        \\        : [number] "{rax}" (231),
-        \\          [arg1] "{rdi}" (code)
-        \\    );
-        \\    unreachable;
-        \\}
-        \\
-    ,
-        \\static zig_noreturn void exitMath(uint8_t arg0);
-        \\static zig_noreturn void exit(uint8_t arg0);
-        \\
-        \\static uint8_t exit__anon_0[6] = "{rax}";
-        \\static uint8_t exit__anon_1[6] = "{rdi}";
-        \\static uint8_t exit__anon_2[8] = "syscall";
-        \\
-        \\zig_noreturn void _start(void) {
-        \\    exitMath(1);
-        \\}
-        \\
-        \\static zig_noreturn void exitMath(uint8_t arg0) {
-        \\    uint8_t const __temp_0 = 0 + arg0;
-        \\    uint8_t const __temp_1 = __temp_0 - arg0;
-        \\    exit(__temp_1);
-        \\}
-        \\
-        \\static zig_noreturn void exit(uint8_t arg0) {
-        \\    uintptr_t const __temp_0 = (uintptr_t)arg0;
-        \\    register uintptr_t rax_constant __asm__("rax") = 231;
-        \\    register uintptr_t rdi_constant __asm__("rdi") = __temp_0;
-        \\    __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
-        \\    zig_breakpoint();
-        \\    zig_unreachable();
-        \\}
-        \\
-    );
-    ctx.c("exit with u8 arithmetic inverted", linux_x64,
-        \\export fn _start() noreturn {
-        \\    exitMath(1);
-        \\}
-        \\
-        \\fn exitMath(a: u8) noreturn {
-        \\    exit(a + 0 - a);
-        \\}
-        \\
-        \\fn exit(code: u8) noreturn {
-        \\    asm volatile ("syscall"
-        \\        :
-        \\        : [number] "{rax}" (231),
-        \\          [arg1] "{rdi}" (code)
-        \\    );
-        \\    unreachable;
-        \\}
-        \\
-    ,
-        \\static zig_noreturn void exitMath(uint8_t arg0);
-        \\static zig_noreturn void exit(uint8_t arg0);
-        \\
-        \\static uint8_t exit__anon_0[6] = "{rax}";
-        \\static uint8_t exit__anon_1[6] = "{rdi}";
-        \\static uint8_t exit__anon_2[8] = "syscall";
-        \\
-        \\zig_noreturn void _start(void) {
-        \\    exitMath(1);
-        \\}
-        \\
-        \\static zig_noreturn void exitMath(uint8_t arg0) {
-        \\    uint8_t const __temp_0 = arg0 + 0;
-        \\    uint8_t const __temp_1 = __temp_0 - arg0;
-        \\    exit(__temp_1);
-        \\}
-        \\
-        \\static zig_noreturn void exit(uint8_t arg0) {
-        \\    uintptr_t const __temp_0 = (uintptr_t)arg0;
-        \\    register uintptr_t rax_constant __asm__("rax") = 231;
-        \\    register uintptr_t rdi_constant __asm__("rdi") = __temp_0;
-        \\    __asm volatile ("syscall" :: ""(rax_constant), ""(rdi_constant));
-        \\    zig_breakpoint();
-        \\    zig_unreachable();
-        \\}
-        \\
-    );
     ctx.h("header with single param function", linux_x64,
         \\export fn start(a: u8) void{}
     ,