| author | |
| committer | |
| log | 6bf52b0505ad7317b5f0d6fa77b7c41318b9c73b |
| tree | 22b5acedc288f3f2085fa4a170ee3d7629e8a9fe |
| parent | 2d888a8e639856e8cb6e4c6f9e6a27647b464952 |
| parent | f7d679ceae2403d4137d75d4afe32a3e8eb0cf16 |
| signature |
Replace `std.builtin.CallingConvention` with a tagged union, eliminating `@setAlignStack`79 files changed, 2020 insertions(+), 942 deletions(-)
doc/langref/enum_export_error.zig+2-1| ... | @@ -3,4 +3,5 @@ export fn entry(foo: Foo) void { | ... | @@ -3,4 +3,5 @@ export fn entry(foo: Foo) void { |
| 3 | _ = foo; | 3 | _ = foo; |
| 4 | } | 4 | } |
| 5 | 5 | ||
| 6 | // obj=parameter of type 'enum_export_error.Foo' not allowed in function with calling convention 'C' | 6 | // obj=parameter of type 'enum_export_error.Foo' not allowed in function with calling convention 'x86_64_sysv' |
| 7 | // target=x86_64-linux |
lib/compiler/aro_translate_c/ast.zig+60-8| ... | @@ -550,12 +550,26 @@ pub const Payload = struct { | ... | @@ -550,12 +550,26 @@ pub const Payload = struct { |
| 550 | is_var_args: bool, | 550 | is_var_args: bool, |
| 551 | name: ?[]const u8, | 551 | name: ?[]const u8, |
| 552 | linksection_string: ?[]const u8, | 552 | linksection_string: ?[]const u8, |
| 553 | explicit_callconv: ?std.builtin.CallingConvention, | 553 | explicit_callconv: ?CallingConvention, |
| 554 | params: []Param, | 554 | params: []Param, |
| 555 | return_type: Node, | 555 | return_type: Node, |
| 556 | body: ?Node, | 556 | body: ?Node, |
| 557 | alignment: ?c_uint, | 557 | alignment: ?c_uint, |
| 558 | }, | 558 | }, |
| 559 | |||
| 560 | pub const CallingConvention = enum { | ||
| 561 | c, | ||
| 562 | x86_64_sysv, | ||
| 563 | x86_64_win, | ||
| 564 | x86_stdcall, | ||
| 565 | x86_fastcall, | ||
| 566 | x86_thiscall, | ||
| 567 | x86_vectorcall, | ||
| 568 | aarch64_vfabi, | ||
| 569 | arm_aapcs, | ||
| 570 | arm_aapcs_vfp, | ||
| 571 | m68k_rtd, | ||
| 572 | }; | ||
| 559 | }; | 573 | }; |
| 560 | 574 | ||
| 561 | pub const Param = struct { | 575 | pub const Param = struct { |
| ... | @@ -2812,14 +2826,52 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { | ... | @@ -2812,14 +2826,52 @@ fn renderFunc(c: *Context, node: Node) !NodeIndex { |
| 2812 | const callconv_expr = if (payload.explicit_callconv) |some| blk: { | 2826 | const callconv_expr = if (payload.explicit_callconv) |some| blk: { |
| 2813 | _ = try c.addToken(.keyword_callconv, "callconv"); | 2827 | _ = try c.addToken(.keyword_callconv, "callconv"); |
| 2814 | _ = try c.addToken(.l_paren, "("); | 2828 | _ = try c.addToken(.l_paren, "("); |
| 2815 | _ = try c.addToken(.period, "."); | 2829 | const cc_node = switch (some) { |
| 2816 | const res = try c.addNode(.{ | 2830 | .c => cc_node: { |
| 2817 | .tag = .enum_literal, | 2831 | _ = try c.addToken(.period, "."); |
| 2818 | .main_token = try c.addTokenFmt(.identifier, "{s}", .{@tagName(some)}), | 2832 | break :cc_node try c.addNode(.{ |
| 2819 | .data = undefined, | 2833 | .tag = .enum_literal, |
| 2820 | }); | 2834 | .main_token = try c.addToken(.identifier, "c"), |
| 2835 | .data = undefined, | ||
| 2836 | }); | ||
| 2837 | }, | ||
| 2838 | .x86_64_sysv, | ||
| 2839 | .x86_64_win, | ||
| 2840 | .x86_stdcall, | ||
| 2841 | .x86_fastcall, | ||
| 2842 | .x86_thiscall, | ||
| 2843 | .x86_vectorcall, | ||
| 2844 | .aarch64_vfabi, | ||
| 2845 | .arm_aapcs, | ||
| 2846 | .arm_aapcs_vfp, | ||
| 2847 | .m68k_rtd, | ||
| 2848 | => cc_node: { | ||
| 2849 | // .{ .foo = .{} } | ||
| 2850 | _ = try c.addToken(.period, "."); | ||
| 2851 | const outer_lbrace = try c.addToken(.l_brace, "{"); | ||
| 2852 | _ = try c.addToken(.period, "."); | ||
| 2853 | _ = try c.addToken(.identifier, @tagName(some)); | ||
| 2854 | _ = try c.addToken(.equal, "="); | ||
| 2855 | _ = try c.addToken(.period, "."); | ||
| 2856 | const inner_lbrace = try c.addToken(.l_brace, "{"); | ||
| 2857 | _ = try c.addToken(.r_brace, "}"); | ||
| 2858 | _ = try c.addToken(.r_brace, "}"); | ||
| 2859 | break :cc_node try c.addNode(.{ | ||
| 2860 | .tag = .struct_init_dot_two, | ||
| 2861 | .main_token = outer_lbrace, | ||
| 2862 | .data = .{ | ||
| 2863 | .lhs = try c.addNode(.{ | ||
| 2864 | .tag = .struct_init_dot_two, | ||
| 2865 | .main_token = inner_lbrace, | ||
| 2866 | .data = .{ .lhs = 0, .rhs = 0 }, | ||
| 2867 | }), | ||
| 2868 | .rhs = 0, | ||
| 2869 | }, | ||
| 2870 | }); | ||
| 2871 | }, | ||
| 2872 | }; | ||
| 2821 | _ = try c.addToken(.r_paren, ")"); | 2873 | _ = try c.addToken(.r_paren, ")"); |
| 2822 | break :blk res; | 2874 | break :blk cc_node; |
| 2823 | } else 0; | 2875 | } else 0; |
| 2824 | 2876 | ||
| 2825 | const return_type_expr = try renderNode(c, payload.return_type); | 2877 | const return_type_expr = try renderNode(c, payload.return_type); |
lib/compiler_rt/int.zig-39| ... | @@ -10,7 +10,6 @@ const is_test = builtin.is_test; | ... | @@ -10,7 +10,6 @@ const is_test = builtin.is_test; |
| 10 | const common = @import("common.zig"); | 10 | const common = @import("common.zig"); |
| 11 | const udivmod = @import("udivmod.zig").udivmod; | 11 | const udivmod = @import("udivmod.zig").udivmod; |
| 12 | const __divti3 = @import("divti3.zig").__divti3; | 12 | const __divti3 = @import("divti3.zig").__divti3; |
| 13 | const arm = @import("arm.zig"); | ||
| 14 | 13 | ||
| 15 | pub const panic = common.panic; | 14 | pub const panic = common.panic; |
| 16 | 15 | ||
| ... | @@ -102,25 +101,6 @@ test "test_divmoddi4" { | ... | @@ -102,25 +101,6 @@ test "test_divmoddi4" { |
| 102 | } | 101 | } |
| 103 | } | 102 | } |
| 104 | 103 | ||
| 105 | fn test_one_aeabi_ldivmod(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { | ||
| 106 | const LdivmodRes = extern struct { | ||
| 107 | q: i64, // r1:r0 | ||
| 108 | r: i64, // r3:r2 | ||
| 109 | }; | ||
| 110 | const actualIdivmod = @as(*const fn (a: i64, b: i64) callconv(.AAPCS) LdivmodRes, @ptrCast(&arm.__aeabi_ldivmod)); | ||
| 111 | const arm_res = actualIdivmod(a, b); | ||
| 112 | try testing.expectEqual(expected_q, arm_res.q); | ||
| 113 | try testing.expectEqual(expected_r, arm_res.r); | ||
| 114 | } | ||
| 115 | |||
| 116 | test "arm.__aeabi_ldivmod" { | ||
| 117 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; | ||
| 118 | |||
| 119 | for (cases__divmodsi4) |case| { | ||
| 120 | try test_one_aeabi_ldivmod(case[0], case[1], case[2], case[3]); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.C) u64 { | 104 | pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.C) u64 { |
| 125 | return udivmod(u64, a, b, maybe_rem); | 105 | return udivmod(u64, a, b, maybe_rem); |
| 126 | } | 106 | } |
| ... | @@ -261,25 +241,6 @@ test "test_divmodsi4" { | ... | @@ -261,25 +241,6 @@ test "test_divmodsi4" { |
| 261 | } | 241 | } |
| 262 | } | 242 | } |
| 263 | 243 | ||
| 264 | fn test_one_aeabi_idivmod(a: i32, b: i32, expected_q: i32, expected_r: i32) !void { | ||
| 265 | const IdivmodRes = extern struct { | ||
| 266 | q: i32, // r0 | ||
| 267 | r: i32, // r1 | ||
| 268 | }; | ||
| 269 | const actualIdivmod = @as(*const fn (a: i32, b: i32) callconv(.AAPCS) IdivmodRes, @ptrCast(&arm.__aeabi_idivmod)); | ||
| 270 | const arm_res = actualIdivmod(a, b); | ||
| 271 | try testing.expectEqual(expected_q, arm_res.q); | ||
| 272 | try testing.expectEqual(expected_r, arm_res.r); | ||
| 273 | } | ||
| 274 | |||
| 275 | test "arm.__aeabi_idivmod" { | ||
| 276 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; | ||
| 277 | |||
| 278 | for (cases__divmodsi4) |case| { | ||
| 279 | try test_one_aeabi_idivmod(case[0], case[1], case[2], case[3]); | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 { | 244 | pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 { |
| 284 | const d = __udivsi3(a, b); | 245 | const d = __udivsi3(a, b); |
| 285 | rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))); | 246 | rem.* = @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))); |
lib/compiler_rt/udivmoddi4_test.zig-21| ... | @@ -3,7 +3,6 @@ | ... | @@ -3,7 +3,6 @@ |
| 3 | const testing = @import("std").testing; | 3 | const testing = @import("std").testing; |
| 4 | const builtin = @import("builtin"); | 4 | const builtin = @import("builtin"); |
| 5 | const __udivmoddi4 = @import("int.zig").__udivmoddi4; | 5 | const __udivmoddi4 = @import("int.zig").__udivmoddi4; |
| 6 | const __aeabi_uldivmod = @import("arm.zig").__aeabi_uldivmod; | ||
| 7 | 6 | ||
| 8 | fn test__udivmoddi4(a: u64, b: u64, expected_q: u64, expected_r: u64) !void { | 7 | fn test__udivmoddi4(a: u64, b: u64, expected_q: u64, expected_r: u64) !void { |
| 9 | var r: u64 = undefined; | 8 | var r: u64 = undefined; |
| ... | @@ -18,26 +17,6 @@ test "udivmoddi4" { | ... | @@ -18,26 +17,6 @@ test "udivmoddi4" { |
| 18 | } | 17 | } |
| 19 | } | 18 | } |
| 20 | 19 | ||
| 21 | const ARMRes = extern struct { | ||
| 22 | q: u64, // r1:r0 | ||
| 23 | r: u64, // r3:r2 | ||
| 24 | }; | ||
| 25 | |||
| 26 | fn test__aeabi_uldivmod(a: u64, b: u64, expected_q: u64, expected_r: u64) !void { | ||
| 27 | const actualUldivmod = @as(*const fn (a: u64, b: u64) callconv(.AAPCS) ARMRes, @ptrCast(&__aeabi_uldivmod)); | ||
| 28 | const arm_res = actualUldivmod(a, b); | ||
| 29 | try testing.expectEqual(expected_q, arm_res.q); | ||
| 30 | try testing.expectEqual(expected_r, arm_res.r); | ||
| 31 | } | ||
| 32 | |||
| 33 | test "arm.__aeabi_uldivmod" { | ||
| 34 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; | ||
| 35 | |||
| 36 | for (cases) |case| { | ||
| 37 | try test__aeabi_uldivmod(case[0], case[1], case[2], case[3]); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | const cases = [_][4]u64{ | 20 | const cases = [_][4]u64{ |
| 42 | [_]u64{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000}, | 21 | [_]u64{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000}, |
| 43 | [_]u64{0x0000000000000000, 0x0000000000000002, 0x0000000000000000, 0x0000000000000000}, | 22 | [_]u64{0x0000000000000000, 0x0000000000000002, 0x0000000000000000, 0x0000000000000000}, |
lib/compiler_rt/udivmodsi4_test.zig+8-17| ... | @@ -2,27 +2,18 @@ | ... | @@ -2,27 +2,18 @@ |
| 2 | // zig fmt: off | 2 | // zig fmt: off |
| 3 | const testing = @import("std").testing; | 3 | const testing = @import("std").testing; |
| 4 | const builtin = @import("builtin"); | 4 | const builtin = @import("builtin"); |
| 5 | const __aeabi_uidivmod = @import("arm.zig").__aeabi_uidivmod; | 5 | const __udivmodsi4 = @import("int.zig").__udivmodsi4; |
| 6 | 6 | ||
| 7 | const ARMRes = extern struct { | 7 | fn test__udivmodsi4(a: u32, b: u32, expected_q: u32, expected_r: u32) !void { |
| 8 | q: u32, // r0 | 8 | var r: u32 = undefined; |
| 9 | r: u32, // r1 | 9 | const q = __udivmodsi4(a, b, &r); |
| 10 | }; | 10 | try testing.expectEqual(expected_q, q); |
| 11 | 11 | try testing.expectEqual(expected_r, r); | |
| 12 | fn test__aeabi_uidivmod(a: u32, b: u32, expected_q: u32, expected_r: u32) !void { | ||
| 13 | const actualUidivmod = @as(*const fn (a: u32, b: u32) callconv(.AAPCS) ARMRes, @ptrCast(&__aeabi_uidivmod)); | ||
| 14 | const arm_res = actualUidivmod(a, b); | ||
| 15 | try testing.expectEqual(expected_q, arm_res.q); | ||
| 16 | try testing.expectEqual(expected_r, arm_res.r); | ||
| 17 | } | 12 | } |
| 18 | 13 | ||
| 19 | test "arm.__aeabi_uidivmod" { | 14 | test "udivmodsi4" { |
| 20 | if (!builtin.cpu.arch.isARM()) return error.SkipZigTest; | ||
| 21 | |||
| 22 | var i: i32 = 0; | ||
| 23 | for (cases) |case| { | 15 | for (cases) |case| { |
| 24 | try test__aeabi_uidivmod(case[0], case[1], case[2], case[3]); | 16 | try test__udivmodsi4(case[0], case[1], case[2], case[3]); |
| 25 | i+=1; | ||
| 26 | } | 17 | } |
| 27 | } | 18 | } |
| 28 | 19 |
lib/std/Target.zig+229| ... | @@ -1609,6 +1609,165 @@ pub const Cpu = struct { | ... | @@ -1609,6 +1609,165 @@ pub const Cpu = struct { |
| 1609 | else => ".X", | 1609 | else => ".X", |
| 1610 | }; | 1610 | }; |
| 1611 | } | 1611 | } |
| 1612 | |||
| 1613 | /// Returns the array of `Arch` to which a specific `std.builtin.CallingConvention` applies. | ||
| 1614 | /// Asserts that `cc` is not `.auto`, `.@"async"`, `.naked`, or `.@"inline"`. | ||
| 1615 | pub fn fromCallingConvention(cc: std.builtin.CallingConvention.Tag) []const Arch { | ||
| 1616 | return switch (cc) { | ||
| 1617 | .auto, | ||
| 1618 | .@"async", | ||
| 1619 | .naked, | ||
| 1620 | .@"inline", | ||
| 1621 | => unreachable, | ||
| 1622 | |||
| 1623 | .x86_64_sysv, | ||
| 1624 | .x86_64_win, | ||
| 1625 | .x86_64_regcall_v3_sysv, | ||
| 1626 | .x86_64_regcall_v4_win, | ||
| 1627 | .x86_64_vectorcall, | ||
| 1628 | .x86_64_interrupt, | ||
| 1629 | => &.{.x86_64}, | ||
| 1630 | |||
| 1631 | .x86_sysv, | ||
| 1632 | .x86_win, | ||
| 1633 | .x86_stdcall, | ||
| 1634 | .x86_fastcall, | ||
| 1635 | .x86_thiscall, | ||
| 1636 | .x86_thiscall_mingw, | ||
| 1637 | .x86_regcall_v3, | ||
| 1638 | .x86_regcall_v4_win, | ||
| 1639 | .x86_vectorcall, | ||
| 1640 | .x86_interrupt, | ||
| 1641 | => &.{.x86}, | ||
| 1642 | |||
| 1643 | .aarch64_aapcs, | ||
| 1644 | .aarch64_aapcs_darwin, | ||
| 1645 | .aarch64_aapcs_win, | ||
| 1646 | .aarch64_vfabi, | ||
| 1647 | .aarch64_vfabi_sve, | ||
| 1648 | => &.{ .aarch64, .aarch64_be }, | ||
| 1649 | |||
| 1650 | .arm_apcs, | ||
| 1651 | .arm_aapcs, | ||
| 1652 | .arm_aapcs_vfp, | ||
| 1653 | .arm_aapcs16_vfp, | ||
| 1654 | .arm_interrupt, | ||
| 1655 | => &.{ .arm, .armeb, .thumb, .thumbeb }, | ||
| 1656 | |||
| 1657 | .mips64_n64, | ||
| 1658 | .mips64_n32, | ||
| 1659 | .mips64_interrupt, | ||
| 1660 | => &.{ .mips64, .mips64el }, | ||
| 1661 | |||
| 1662 | .mips_o32, | ||
| 1663 | .mips_interrupt, | ||
| 1664 | => &.{ .mips, .mipsel }, | ||
| 1665 | |||
| 1666 | .riscv64_lp64, | ||
| 1667 | .riscv64_lp64_v, | ||
| 1668 | .riscv64_interrupt, | ||
| 1669 | => &.{.riscv64}, | ||
| 1670 | |||
| 1671 | .riscv32_ilp32, | ||
| 1672 | .riscv32_ilp32_v, | ||
| 1673 | .riscv32_interrupt, | ||
| 1674 | => &.{.riscv32}, | ||
| 1675 | |||
| 1676 | .sparc64_sysv, | ||
| 1677 | => &.{.sparc64}, | ||
| 1678 | |||
| 1679 | .sparc_sysv, | ||
| 1680 | => &.{.sparc}, | ||
| 1681 | |||
| 1682 | .powerpc64_elf, | ||
| 1683 | .powerpc64_elf_altivec, | ||
| 1684 | .powerpc64_elf_v2, | ||
| 1685 | => &.{ .powerpc64, .powerpc64le }, | ||
| 1686 | |||
| 1687 | .powerpc_sysv, | ||
| 1688 | .powerpc_sysv_altivec, | ||
| 1689 | .powerpc_aix, | ||
| 1690 | .powerpc_aix_altivec, | ||
| 1691 | => &.{ .powerpc, .powerpcle }, | ||
| 1692 | |||
| 1693 | .wasm_watc, | ||
| 1694 | => &.{ .wasm64, .wasm32 }, | ||
| 1695 | |||
| 1696 | .arc_sysv, | ||
| 1697 | => &.{.arc}, | ||
| 1698 | |||
| 1699 | .avr_gnu, | ||
| 1700 | .avr_builtin, | ||
| 1701 | .avr_signal, | ||
| 1702 | .avr_interrupt, | ||
| 1703 | => &.{.avr}, | ||
| 1704 | |||
| 1705 | .bpf_std, | ||
| 1706 | => &.{ .bpfel, .bpfeb }, | ||
| 1707 | |||
| 1708 | .csky_sysv, | ||
| 1709 | .csky_interrupt, | ||
| 1710 | => &.{.csky}, | ||
| 1711 | |||
| 1712 | .hexagon_sysv, | ||
| 1713 | .hexagon_sysv_hvx, | ||
| 1714 | => &.{.hexagon}, | ||
| 1715 | |||
| 1716 | .lanai_sysv, | ||
| 1717 | => &.{.lanai}, | ||
| 1718 | |||
| 1719 | .loongarch64_lp64, | ||
| 1720 | => &.{.loongarch64}, | ||
| 1721 | |||
| 1722 | .loongarch32_ilp32, | ||
| 1723 | => &.{.loongarch32}, | ||
| 1724 | |||
| 1725 | .m68k_sysv, | ||
| 1726 | .m68k_gnu, | ||
| 1727 | .m68k_rtd, | ||
| 1728 | .m68k_interrupt, | ||
| 1729 | => &.{.m68k}, | ||
| 1730 | |||
| 1731 | .msp430_eabi, | ||
| 1732 | => &.{.msp430}, | ||
| 1733 | |||
| 1734 | .propeller1_sysv, | ||
| 1735 | => &.{.propeller1}, | ||
| 1736 | |||
| 1737 | .propeller2_sysv, | ||
| 1738 | => &.{.propeller2}, | ||
| 1739 | |||
| 1740 | .s390x_sysv, | ||
| 1741 | .s390x_sysv_vx, | ||
| 1742 | => &.{.s390x}, | ||
| 1743 | |||
| 1744 | .ve_sysv, | ||
| 1745 | => &.{.ve}, | ||
| 1746 | |||
| 1747 | .xcore_xs1, | ||
| 1748 | .xcore_xs2, | ||
| 1749 | => &.{.xcore}, | ||
| 1750 | |||
| 1751 | .xtensa_call0, | ||
| 1752 | .xtensa_windowed, | ||
| 1753 | => &.{.xtensa}, | ||
| 1754 | |||
| 1755 | .amdgcn_device, | ||
| 1756 | .amdgcn_kernel, | ||
| 1757 | .amdgcn_cs, | ||
| 1758 | => &.{.amdgcn}, | ||
| 1759 | |||
| 1760 | .nvptx_device, | ||
| 1761 | .nvptx_kernel, | ||
| 1762 | => &.{ .nvptx, .nvptx64 }, | ||
| 1763 | |||
| 1764 | .spirv_device, | ||
| 1765 | .spirv_kernel, | ||
| 1766 | .spirv_fragment, | ||
| 1767 | .spirv_vertex, | ||
| 1768 | => &.{ .spirv, .spirv32, .spirv64 }, | ||
| 1769 | }; | ||
| 1770 | } | ||
| 1612 | }; | 1771 | }; |
| 1613 | 1772 | ||
| 1614 | pub const Model = struct { | 1773 | pub const Model = struct { |
| ... | @@ -2873,6 +3032,76 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 { | ... | @@ -2873,6 +3032,76 @@ pub fn cTypePreferredAlignment(target: Target, c_type: CType) u16 { |
| 2873 | ); | 3032 | ); |
| 2874 | } | 3033 | } |
| 2875 | 3034 | ||
| 3035 | pub fn cCallingConvention(target: Target) ?std.builtin.CallingConvention { | ||
| 3036 | return switch (target.cpu.arch) { | ||
| 3037 | .x86_64 => switch (target.os.tag) { | ||
| 3038 | .windows, .uefi => .{ .x86_64_win = .{} }, | ||
| 3039 | else => .{ .x86_64_sysv = .{} }, | ||
| 3040 | }, | ||
| 3041 | .x86 => switch (target.os.tag) { | ||
| 3042 | .windows, .uefi => .{ .x86_win = .{} }, | ||
| 3043 | else => .{ .x86_sysv = .{} }, | ||
| 3044 | }, | ||
| 3045 | .aarch64, .aarch64_be => if (target.os.tag.isDarwin()) cc: { | ||
| 3046 | break :cc .{ .aarch64_aapcs_darwin = .{} }; | ||
| 3047 | } else switch (target.os.tag) { | ||
| 3048 | .windows => .{ .aarch64_aapcs_win = .{} }, | ||
| 3049 | else => .{ .aarch64_aapcs = .{} }, | ||
| 3050 | }, | ||
| 3051 | .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) { | ||
| 3052 | .netbsd => .{ .arm_apcs = .{} }, | ||
| 3053 | else => switch (target.abi.floatAbi()) { | ||
| 3054 | .soft => .{ .arm_aapcs = .{} }, | ||
| 3055 | .hard => .{ .arm_aapcs_vfp = .{} }, | ||
| 3056 | }, | ||
| 3057 | }, | ||
| 3058 | .mips64, .mips64el => switch (target.abi) { | ||
| 3059 | .gnuabin32 => .{ .mips64_n32 = .{} }, | ||
| 3060 | else => .{ .mips64_n64 = .{} }, | ||
| 3061 | }, | ||
| 3062 | .mips, .mipsel => .{ .mips_o32 = .{} }, | ||
| 3063 | .riscv64 => .{ .riscv64_lp64 = .{} }, | ||
| 3064 | .riscv32 => .{ .riscv32_ilp32 = .{} }, | ||
| 3065 | .sparc64 => .{ .sparc64_sysv = .{} }, | ||
| 3066 | .sparc => .{ .sparc_sysv = .{} }, | ||
| 3067 | .powerpc64 => if (target.isMusl()) | ||
| 3068 | .{ .powerpc64_elf_v2 = .{} } | ||
| 3069 | else | ||
| 3070 | .{ .powerpc64_elf = .{} }, | ||
| 3071 | .powerpc64le => .{ .powerpc64_elf_v2 = .{} }, | ||
| 3072 | .powerpc, .powerpcle => switch (target.os.tag) { | ||
| 3073 | .aix => .{ .powerpc_aix = .{} }, | ||
| 3074 | else => .{ .powerpc_sysv = .{} }, | ||
| 3075 | }, | ||
| 3076 | .wasm32 => .{ .wasm_watc = .{} }, | ||
| 3077 | .wasm64 => .{ .wasm_watc = .{} }, | ||
| 3078 | .arc => .{ .arc_sysv = .{} }, | ||
| 3079 | .avr => .avr_gnu, | ||
| 3080 | .bpfel, .bpfeb => .{ .bpf_std = .{} }, | ||
| 3081 | .csky => .{ .csky_sysv = .{} }, | ||
| 3082 | .hexagon => .{ .hexagon_sysv = .{} }, | ||
| 3083 | .kalimba => null, | ||
| 3084 | .lanai => .{ .lanai_sysv = .{} }, | ||
| 3085 | .loongarch64 => .{ .loongarch64_lp64 = .{} }, | ||
| 3086 | .loongarch32 => .{ .loongarch32_ilp32 = .{} }, | ||
| 3087 | .m68k => if (target.abi.isGnu() or target.abi.isMusl()) | ||
| 3088 | .{ .m68k_gnu = .{} } | ||
| 3089 | else | ||
| 3090 | .{ .m68k_sysv = .{} }, | ||
| 3091 | .msp430 => .{ .msp430_eabi = .{} }, | ||
| 3092 | .propeller1 => .{ .propeller1_sysv = .{} }, | ||
| 3093 | .propeller2 => .{ .propeller2_sysv = .{} }, | ||
| 3094 | .s390x => .{ .s390x_sysv = .{} }, | ||
| 3095 | .spu_2 => null, | ||
| 3096 | .ve => .{ .ve_sysv = .{} }, | ||
| 3097 | .xcore => .{ .xcore_xs1 = .{} }, | ||
| 3098 | .xtensa => .{ .xtensa_call0 = .{} }, | ||
| 3099 | .amdgcn => .{ .amdgcn_device = .{} }, | ||
| 3100 | .nvptx, .nvptx64 => .nvptx_device, | ||
| 3101 | .spirv, .spirv32, .spirv64 => .spirv_device, | ||
| 3102 | }; | ||
| 3103 | } | ||
| 3104 | |||
| 2876 | pub fn osArchName(target: std.Target) [:0]const u8 { | 3105 | pub fn osArchName(target: std.Target) [:0]const u8 { |
| 2877 | return target.os.tag.archName(target.cpu.arch); | 3106 | return target.os.tag.archName(target.cpu.arch); |
| 2878 | } | 3107 | } |
lib/std/builtin.zig+330-44| ... | @@ -160,54 +160,340 @@ pub const OptimizeMode = enum { | ... | @@ -160,54 +160,340 @@ pub const OptimizeMode = enum { |
| 160 | /// Deprecated; use OptimizeMode. | 160 | /// Deprecated; use OptimizeMode. |
| 161 | pub const Mode = OptimizeMode; | 161 | pub const Mode = OptimizeMode; |
| 162 | 162 | ||
| 163 | /// The calling convention of a function defines how arguments and return values are passed, as well | ||
| 164 | /// as any other requirements which callers and callees must respect, such as register preservation | ||
| 165 | /// and stack alignment. | ||
| 166 | /// | ||
| 163 | /// This data structure is used by the Zig language code generation and | 167 | /// This data structure is used by the Zig language code generation and |
| 164 | /// therefore must be kept in sync with the compiler implementation. | 168 | /// therefore must be kept in sync with the compiler implementation. |
| 165 | pub const CallingConvention = enum(u8) { | 169 | pub const CallingConvention = union(enum(u8)) { |
| 166 | /// This is the default Zig calling convention used when not using `export` on `fn` | 170 | pub const Tag = @typeInfo(CallingConvention).@"union".tag_type.?; |
| 167 | /// and no other calling convention is specified. | 171 | |
| 168 | Unspecified, | 172 | /// This is an alias for the default C calling convention for this target. |
| 169 | /// Matches the C ABI for the target. | 173 | /// Functions marked as `extern` or `export` are given this calling convention by default. |
| 170 | /// This is the default calling convention when using `export` on `fn` | 174 | pub const c = builtin.target.cCallingConvention().?; |
| 171 | /// and no other calling convention is specified. | 175 | |
| 172 | C, | 176 | pub const winapi: CallingConvention = switch (builtin.target.cpu.arch) { |
| 173 | /// This makes a function not have any function prologue or epilogue, | 177 | .x86_64 => .{ .x86_64_win = .{} }, |
| 174 | /// making the function itself uncallable in regular Zig code. | 178 | .x86 => .{ .x86_stdcall = .{} }, |
| 175 | /// This can be useful when integrating with assembly. | 179 | .aarch64 => .{ .aarch64_aapcs_win = .{} }, |
| 176 | Naked, | 180 | .thumb => .{ .arm_aapcs_vfp = .{} }, |
| 177 | /// Functions with this calling convention are called asynchronously, | 181 | else => unreachable, |
| 178 | /// as if called as `async function()`. | 182 | }; |
| 179 | Async, | 183 | |
| 180 | /// Functions with this calling convention are inlined at all call sites. | 184 | pub const kernel: CallingConvention = switch (builtin.target.cpu.arch) { |
| 181 | Inline, | 185 | .amdgcn => .amdgcn_kernel, |
| 182 | /// x86-only. | 186 | .nvptx, .nvptx64 => .nvptx_kernel, |
| 183 | Interrupt, | 187 | .spirv, .spirv32, .spirv64 => .spirv_kernel, |
| 184 | Signal, | 188 | else => unreachable, |
| 185 | /// x86-only. | 189 | }; |
| 186 | Stdcall, | 190 | |
| 187 | /// x86-only. | 191 | /// Deprecated; use `.auto`. |
| 188 | Fastcall, | 192 | pub const Unspecified: CallingConvention = .auto; |
| 189 | /// x86-only. | 193 | /// Deprecated; use `.c`. |
| 190 | Vectorcall, | 194 | pub const C: CallingConvention = .c; |
| 191 | /// x86-only. | 195 | /// Deprecated; use `.naked`. |
| 192 | Thiscall, | 196 | pub const Naked: CallingConvention = .naked; |
| 197 | /// Deprecated; use `.@"async"`. | ||
| 198 | pub const Async: CallingConvention = .@"async"; | ||
| 199 | /// Deprecated; use `.@"inline"`. | ||
| 200 | pub const Inline: CallingConvention = .@"inline"; | ||
| 201 | /// Deprecated; use `.x86_64_interrupt`, `.x86_interrupt`, or `.avr_interrupt`. | ||
| 202 | pub const Interrupt: CallingConvention = switch (builtin.target.cpu.arch) { | ||
| 203 | .x86_64 => .{ .x86_64_interrupt = .{} }, | ||
| 204 | .x86 => .{ .x86_interrupt = .{} }, | ||
| 205 | .avr => .avr_interrupt, | ||
| 206 | else => unreachable, | ||
| 207 | }; | ||
| 208 | /// Deprecated; use `.avr_signal`. | ||
| 209 | pub const Signal: CallingConvention = .avr_signal; | ||
| 210 | /// Deprecated; use `.x86_stdcall`. | ||
| 211 | pub const Stdcall: CallingConvention = .{ .x86_stdcall = .{} }; | ||
| 212 | /// Deprecated; use `.x86_fastcall`. | ||
| 213 | pub const Fastcall: CallingConvention = .{ .x86_fastcall = .{} }; | ||
| 214 | /// Deprecated; use `.x86_64_vectorcall`, `.x86_vectorcall`, or `aarch64_vfabi`. | ||
| 215 | pub const Vectorcall: CallingConvention = switch (builtin.target.cpu.arch) { | ||
| 216 | .x86_64 => .{ .x86_64_vectorcall = .{} }, | ||
| 217 | .x86 => .{ .x86_vectorcall = .{} }, | ||
| 218 | .aarch64, .aarch64_be => .{ .aarch64_vfabi = .{} }, | ||
| 219 | else => unreachable, | ||
| 220 | }; | ||
| 221 | /// Deprecated; use `.x86_thiscall`. | ||
| 222 | pub const Thiscall: CallingConvention = .{ .x86_thiscall = .{} }; | ||
| 223 | /// Deprecated; use `.arm_apcs`. | ||
| 224 | pub const APCS: CallingConvention = .{ .arm_apcs = .{} }; | ||
| 225 | /// Deprecated; use `.arm_aapcs`. | ||
| 226 | pub const AAPCS: CallingConvention = .{ .arm_aapcs = .{} }; | ||
| 227 | /// Deprecated; use `.arm_aapcs_vfp`. | ||
| 228 | pub const AAPCSVFP: CallingConvention = .{ .arm_aapcs_vfp = .{} }; | ||
| 229 | /// Deprecated; use `.x86_64_sysv`. | ||
| 230 | pub const SysV: CallingConvention = .{ .x86_64_sysv = .{} }; | ||
| 231 | /// Deprecated; use `.x86_64_win`. | ||
| 232 | pub const Win64: CallingConvention = .{ .x86_64_win = .{} }; | ||
| 233 | /// Deprecated; use `.kernel`. | ||
| 234 | pub const Kernel: CallingConvention = .kernel; | ||
| 235 | /// Deprecated; use `.spirv_fragment`. | ||
| 236 | pub const Fragment: CallingConvention = .spirv_fragment; | ||
| 237 | /// Deprecated; use `.spirv_vertex`. | ||
| 238 | pub const Vertex: CallingConvention = .spirv_vertex; | ||
| 239 | |||
| 240 | /// The default Zig calling convention when neither `export` nor `inline` is specified. | ||
| 241 | /// This calling convention makes no guarantees about stack alignment, registers, etc. | ||
| 242 | /// It can only be used within this Zig compilation unit. | ||
| 243 | auto, | ||
| 244 | |||
| 245 | /// The calling convention of a function that can be called with `async` syntax. An `async` call | ||
| 246 | /// of a runtime-known function must target a function with this calling convention. | ||
| 247 | /// Comptime-known functions with other calling conventions may be coerced to this one. | ||
| 248 | @"async", | ||
| 249 | |||
| 250 | /// Functions with this calling convention have no prologue or epilogue, making the function | ||
| 251 | /// uncallable in regular Zig code. This can be useful when integrating with assembly. | ||
| 252 | naked, | ||
| 253 | |||
| 254 | /// This calling convention is exactly equivalent to using the `inline` keyword on a function | ||
| 255 | /// definition. This function will be semantically inlined by the Zig compiler at call sites. | ||
| 256 | /// Pointers to inline functions are comptime-only. | ||
| 257 | @"inline", | ||
| 258 | |||
| 259 | // Calling conventions for the `x86_64` architecture. | ||
| 260 | x86_64_sysv: CommonOptions, | ||
| 261 | x86_64_win: CommonOptions, | ||
| 262 | x86_64_regcall_v3_sysv: CommonOptions, | ||
| 263 | x86_64_regcall_v4_win: CommonOptions, | ||
| 264 | x86_64_vectorcall: CommonOptions, | ||
| 265 | x86_64_interrupt: CommonOptions, | ||
| 266 | |||
| 267 | // Calling conventions for the `x86` architecture. | ||
| 268 | x86_sysv: X86RegparmOptions, | ||
| 269 | x86_win: X86RegparmOptions, | ||
| 270 | x86_stdcall: X86RegparmOptions, | ||
| 271 | x86_fastcall: CommonOptions, | ||
| 272 | x86_thiscall: CommonOptions, | ||
| 273 | x86_thiscall_mingw: CommonOptions, | ||
| 274 | x86_regcall_v3: CommonOptions, | ||
| 275 | x86_regcall_v4_win: CommonOptions, | ||
| 276 | x86_vectorcall: CommonOptions, | ||
| 277 | x86_interrupt: CommonOptions, | ||
| 278 | |||
| 279 | // Calling conventions for the `aarch64` and `aarch64_be` architectures. | ||
| 280 | aarch64_aapcs: CommonOptions, | ||
| 281 | aarch64_aapcs_darwin: CommonOptions, | ||
| 282 | aarch64_aapcs_win: CommonOptions, | ||
| 283 | aarch64_vfabi: CommonOptions, | ||
| 284 | aarch64_vfabi_sve: CommonOptions, | ||
| 285 | |||
| 286 | // Calling convetions for the `arm`, `armeb`, `thumb`, and `thumbeb` architectures. | ||
| 193 | /// ARM Procedure Call Standard (obsolete) | 287 | /// ARM Procedure Call Standard (obsolete) |
| 194 | /// ARM-only. | 288 | arm_apcs: CommonOptions, |
| 195 | APCS, | 289 | /// ARM Architecture Procedure Call Standard |
| 196 | /// ARM Architecture Procedure Call Standard (current standard) | 290 | arm_aapcs: CommonOptions, |
| 197 | /// ARM-only. | ||
| 198 | AAPCS, | ||
| 199 | /// ARM Architecture Procedure Call Standard Vector Floating-Point | 291 | /// ARM Architecture Procedure Call Standard Vector Floating-Point |
| 200 | /// ARM-only. | 292 | arm_aapcs_vfp: CommonOptions, |
| 201 | AAPCSVFP, | 293 | arm_aapcs16_vfp: CommonOptions, |
| 202 | /// x86-64-only. | 294 | arm_interrupt: ArmInterruptOptions, |
| 203 | SysV, | 295 | |
| 204 | /// x86-64-only. | 296 | // Calling conventions for the `mips64` architecture. |
| 205 | Win64, | 297 | mips64_n64: CommonOptions, |
| 206 | /// AMD GPU, NVPTX, or SPIR-V kernel | 298 | mips64_n32: CommonOptions, |
| 207 | Kernel, | 299 | mips64_interrupt: MipsInterruptOptions, |
| 208 | // Vulkan-only | 300 | |
| 209 | Fragment, | 301 | // Calling conventions for the `mips` architecture. |
| 210 | Vertex, | 302 | mips_o32: CommonOptions, |
| 303 | mips_interrupt: MipsInterruptOptions, | ||
| 304 | |||
| 305 | // Calling conventions for the `riscv64` architecture. | ||
| 306 | riscv64_lp64: CommonOptions, | ||
| 307 | riscv64_lp64_v: CommonOptions, | ||
| 308 | riscv64_interrupt: RiscvInterruptOptions, | ||
| 309 | |||
| 310 | // Calling conventions for the `riscv32` architecture. | ||
| 311 | riscv32_ilp32: CommonOptions, | ||
| 312 | riscv32_ilp32_v: CommonOptions, | ||
| 313 | riscv32_interrupt: RiscvInterruptOptions, | ||
| 314 | |||
| 315 | // Calling conventions for the `sparc64` architecture. | ||
| 316 | sparc64_sysv: CommonOptions, | ||
| 317 | |||
| 318 | // Calling conventions for the `sparc` architecture. | ||
| 319 | sparc_sysv: CommonOptions, | ||
| 320 | |||
| 321 | // Calling conventions for the `powerpc64` and `powerpc64le` architectures. | ||
| 322 | powerpc64_elf: CommonOptions, | ||
| 323 | powerpc64_elf_altivec: CommonOptions, | ||
| 324 | powerpc64_elf_v2: CommonOptions, | ||
| 325 | |||
| 326 | // Calling conventions for the `powerpc` and `powerpcle` architectures. | ||
| 327 | powerpc_sysv: CommonOptions, | ||
| 328 | powerpc_sysv_altivec: CommonOptions, | ||
| 329 | powerpc_aix: CommonOptions, | ||
| 330 | powerpc_aix_altivec: CommonOptions, | ||
| 331 | |||
| 332 | /// The standard `wasm32`/`wasm64` calling convention, as specified in the WebAssembly Tool Conventions. | ||
| 333 | wasm_watc: CommonOptions, | ||
| 334 | |||
| 335 | /// The standard `arc` calling convention. | ||
| 336 | arc_sysv: CommonOptions, | ||
| 337 | |||
| 338 | // Calling conventions for the `avr` architecture. | ||
| 339 | avr_gnu, | ||
| 340 | avr_builtin, | ||
| 341 | avr_signal, | ||
| 342 | avr_interrupt, | ||
| 343 | |||
| 344 | /// The standard `bpfel`/`bpfeb` calling convention. | ||
| 345 | bpf_std: CommonOptions, | ||
| 346 | |||
| 347 | // Calling conventions for the `csky` architecture. | ||
| 348 | csky_sysv: CommonOptions, | ||
| 349 | csky_interrupt: CommonOptions, | ||
| 350 | |||
| 351 | // Calling conventions for the `hexagon` architecture. | ||
| 352 | hexagon_sysv: CommonOptions, | ||
| 353 | hexagon_sysv_hvx: CommonOptions, | ||
| 354 | |||
| 355 | /// The standard `lanai` calling convention. | ||
| 356 | lanai_sysv: CommonOptions, | ||
| 357 | |||
| 358 | /// The standard `loongarch64` calling convention. | ||
| 359 | loongarch64_lp64: CommonOptions, | ||
| 360 | |||
| 361 | /// The standard `loongarch32` calling convention. | ||
| 362 | loongarch32_ilp32: CommonOptions, | ||
| 363 | |||
| 364 | // Calling conventions for the `m68k` architecture. | ||
| 365 | m68k_sysv: CommonOptions, | ||
| 366 | m68k_gnu: CommonOptions, | ||
| 367 | m68k_rtd: CommonOptions, | ||
| 368 | m68k_interrupt: CommonOptions, | ||
| 369 | |||
| 370 | /// The standard `msp430` calling convention. | ||
| 371 | msp430_eabi: CommonOptions, | ||
| 372 | |||
| 373 | /// The standard `propeller1` calling convention. | ||
| 374 | propeller1_sysv: CommonOptions, | ||
| 375 | |||
| 376 | /// The standard `propeller2` calling convention. | ||
| 377 | propeller2_sysv: CommonOptions, | ||
| 378 | |||
| 379 | // Calling conventions for the `s390x` architecture. | ||
| 380 | s390x_sysv: CommonOptions, | ||
| 381 | s390x_sysv_vx: CommonOptions, | ||
| 382 | |||
| 383 | /// The standard `ve` calling convention. | ||
| 384 | ve_sysv: CommonOptions, | ||
| 385 | |||
| 386 | // Calling conventions for the `xcore` architecture. | ||
| 387 | xcore_xs1: CommonOptions, | ||
| 388 | xcore_xs2: CommonOptions, | ||
| 389 | |||
| 390 | // Calling conventions for the `xtensa` architecture. | ||
| 391 | xtensa_call0: CommonOptions, | ||
| 392 | xtensa_windowed: CommonOptions, | ||
| 393 | |||
| 394 | // Calling conventions for the `amdgcn` architecture. | ||
| 395 | amdgcn_device: CommonOptions, | ||
| 396 | amdgcn_kernel, | ||
| 397 | amdgcn_cs: CommonOptions, | ||
| 398 | |||
| 399 | // Calling conventions for the `nvptx` architecture. | ||
| 400 | nvptx_device, | ||
| 401 | nvptx_kernel, | ||
| 402 | |||
| 403 | // Calling conventions for kernels and shaders on the `spirv`, `spirv32`, and `spirv64` architectures. | ||
| 404 | spirv_device, | ||
| 405 | spirv_kernel, | ||
| 406 | spirv_fragment, | ||
| 407 | spirv_vertex, | ||
| 408 | |||
| 409 | /// Options shared across most calling conventions. | ||
| 410 | pub const CommonOptions = struct { | ||
| 411 | /// The boundary the stack is aligned to when the function is called. | ||
| 412 | /// `null` means the default for this calling convention. | ||
| 413 | incoming_stack_alignment: ?u64 = null, | ||
| 414 | }; | ||
| 415 | |||
| 416 | /// Options for x86 calling conventions which support the regparm attribute to pass some | ||
| 417 | /// arguments in registers. | ||
| 418 | pub const X86RegparmOptions = struct { | ||
| 419 | /// The boundary the stack is aligned to when the function is called. | ||
| 420 | /// `null` means the default for this calling convention. | ||
| 421 | incoming_stack_alignment: ?u64 = null, | ||
| 422 | /// The number of arguments to pass in registers before passing the remaining arguments | ||
| 423 | /// according to the calling convention. | ||
| 424 | /// Equivalent to `__attribute__((regparm(x)))` in Clang and GCC. | ||
| 425 | register_params: u2 = 0, | ||
| 426 | }; | ||
| 427 | |||
| 428 | /// Options for the `arm_interrupt` calling convention. | ||
| 429 | pub const ArmInterruptOptions = struct { | ||
| 430 | /// The boundary the stack is aligned to when the function is called. | ||
| 431 | /// `null` means the default for this calling convention. | ||
| 432 | incoming_stack_alignment: ?u64 = null, | ||
| 433 | /// The kind of interrupt being received. | ||
| 434 | type: InterruptType = .generic, | ||
| 435 | |||
| 436 | pub const InterruptType = enum(u3) { | ||
| 437 | generic, | ||
| 438 | irq, | ||
| 439 | fiq, | ||
| 440 | swi, | ||
| 441 | abort, | ||
| 442 | undef, | ||
| 443 | }; | ||
| 444 | }; | ||
| 445 | |||
| 446 | /// Options for the `mips_interrupt` and `mips64_interrupt` calling conventions. | ||
| 447 | pub const MipsInterruptOptions = struct { | ||
| 448 | /// The boundary the stack is aligned to when the function is called. | ||
| 449 | /// `null` means the default for this calling convention. | ||
| 450 | incoming_stack_alignment: ?u64 = null, | ||
| 451 | /// The interrupt mode. | ||
| 452 | mode: InterruptMode = .eic, | ||
| 453 | |||
| 454 | pub const InterruptMode = enum(u4) { | ||
| 455 | eic, | ||
| 456 | sw0, | ||
| 457 | sw1, | ||
| 458 | hw0, | ||
| 459 | hw1, | ||
| 460 | hw2, | ||
| 461 | hw3, | ||
| 462 | hw4, | ||
| 463 | hw5, | ||
| 464 | }; | ||
| 465 | }; | ||
| 466 | |||
| 467 | /// Options for the `riscv32_interrupt` and `riscv64_interrupt` calling conventions. | ||
| 468 | pub const RiscvInterruptOptions = struct { | ||
| 469 | /// The boundary the stack is aligned to when the function is called. | ||
| 470 | /// `null` means the default for this calling convention. | ||
| 471 | incoming_stack_alignment: ?u64 = null, | ||
| 472 | /// The privilege mode. | ||
| 473 | mode: PrivilegeMode = .machine, | ||
| 474 | |||
| 475 | pub const PrivilegeMode = enum(u2) { | ||
| 476 | supervisor, | ||
| 477 | machine, | ||
| 478 | }; | ||
| 479 | }; | ||
| 480 | |||
| 481 | /// Returns the array of `std.Target.Cpu.Arch` to which this `CallingConvention` applies. | ||
| 482 | /// Asserts that `cc` is not `.auto`, `.@"async"`, `.naked`, or `.@"inline"`. | ||
| 483 | pub fn archs(cc: CallingConvention) []const std.Target.Cpu.Arch { | ||
| 484 | return std.Target.Cpu.Arch.fromCallingConvention(cc); | ||
| 485 | } | ||
| 486 | |||
| 487 | pub fn eql(a: CallingConvention, b: CallingConvention) bool { | ||
| 488 | return std.meta.eql(a, b); | ||
| 489 | } | ||
| 490 | |||
| 491 | pub fn withStackAlign(cc: CallingConvention, incoming_stack_alignment: u64) CallingConvention { | ||
| 492 | const tag: CallingConvention.Tag = cc; | ||
| 493 | var result = cc; | ||
| 494 | @field(result, @tagName(tag)).incoming_stack_alignment = incoming_stack_alignment; | ||
| 495 | return result; | ||
| 496 | } | ||
| 211 | }; | 497 | }; |
| 212 | 498 | ||
| 213 | /// This data structure is used by the Zig language code generation and | 499 | /// This data structure is used by the Zig language code generation and |
lib/std/crypto/25519/field.zig+3-3| ... | @@ -6,9 +6,9 @@ const NonCanonicalError = crypto.errors.NonCanonicalError; | ... | @@ -6,9 +6,9 @@ const NonCanonicalError = crypto.errors.NonCanonicalError; |
| 6 | const NotSquareError = crypto.errors.NotSquareError; | 6 | const NotSquareError = crypto.errors.NotSquareError; |
| 7 | 7 | ||
| 8 | // Inline conditionally, when it can result in large code generation. | 8 | // Inline conditionally, when it can result in large code generation. |
| 9 | const bloaty_inline = switch (builtin.mode) { | 9 | const bloaty_inline: std.builtin.CallingConvention = switch (builtin.mode) { |
| 10 | .ReleaseSafe, .ReleaseFast => .Inline, | 10 | .ReleaseSafe, .ReleaseFast => .@"inline", |
| 11 | .Debug, .ReleaseSmall => .Unspecified, | 11 | .Debug, .ReleaseSmall => .auto, |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | pub const Fe = struct { | 14 | pub const Fe = struct { |
lib/std/os/windows.zig+1-4| ... | @@ -2824,10 +2824,7 @@ pub const STD_OUTPUT_HANDLE = maxInt(DWORD) - 11 + 1; | ... | @@ -2824,10 +2824,7 @@ pub const STD_OUTPUT_HANDLE = maxInt(DWORD) - 11 + 1; |
| 2824 | /// The standard error device. Initially, this is the active console screen buffer, CONOUT$. | 2824 | /// The standard error device. Initially, this is the active console screen buffer, CONOUT$. |
| 2825 | pub const STD_ERROR_HANDLE = maxInt(DWORD) - 12 + 1; | 2825 | pub const STD_ERROR_HANDLE = maxInt(DWORD) - 12 + 1; |
| 2826 | 2826 | ||
| 2827 | pub const WINAPI: std.builtin.CallingConvention = if (native_arch == .x86) | 2827 | pub const WINAPI: std.builtin.CallingConvention = .winapi; |
| 2828 | .Stdcall | ||
| 2829 | else | ||
| 2830 | .C; | ||
| 2831 | 2828 | ||
| 2832 | pub const BOOL = c_int; | 2829 | pub const BOOL = c_int; |
| 2833 | pub const BOOLEAN = BYTE; | 2830 | pub const BOOLEAN = BYTE; |
lib/std/start.zig+4-7| ... | @@ -55,7 +55,7 @@ comptime { | ... | @@ -55,7 +55,7 @@ comptime { |
| 55 | if (builtin.link_libc and @hasDecl(root, "main")) { | 55 | if (builtin.link_libc and @hasDecl(root, "main")) { |
| 56 | if (native_arch.isWasm()) { | 56 | if (native_arch.isWasm()) { |
| 57 | @export(&mainWithoutEnv, .{ .name = "main" }); | 57 | @export(&mainWithoutEnv, .{ .name = "main" }); |
| 58 | } else if (@typeInfo(@TypeOf(root.main)).@"fn".calling_convention != .C) { | 58 | } else if (!@typeInfo(@TypeOf(root.main)).@"fn".calling_convention.eql(.c)) { |
| 59 | @export(&main, .{ .name = "main" }); | 59 | @export(&main, .{ .name = "main" }); |
| 60 | } | 60 | } |
| 61 | } else if (native_os == .windows) { | 61 | } else if (native_os == .windows) { |
| ... | @@ -102,12 +102,11 @@ fn main2() callconv(.C) c_int { | ... | @@ -102,12 +102,11 @@ fn main2() callconv(.C) c_int { |
| 102 | return 0; | 102 | return 0; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | fn _start2() callconv(.C) noreturn { | 105 | fn _start2() callconv(.withStackAlign(.c, 1)) noreturn { |
| 106 | callMain2(); | 106 | callMain2(); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | fn callMain2() noreturn { | 109 | fn callMain2() noreturn { |
| 110 | @setAlignStack(16); | ||
| 111 | root.main(); | 110 | root.main(); |
| 112 | exit2(0); | 111 | exit2(0); |
| 113 | } | 112 | } |
| ... | @@ -428,8 +427,7 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -428,8 +427,7 @@ fn _start() callconv(.Naked) noreturn { |
| 428 | ); | 427 | ); |
| 429 | } | 428 | } |
| 430 | 429 | ||
| 431 | fn WinStartup() callconv(std.os.windows.WINAPI) noreturn { | 430 | fn WinStartup() callconv(.withStackAlign(.winapi, 1)) noreturn { |
| 432 | @setAlignStack(16); | ||
| 433 | if (!builtin.single_threaded and !builtin.link_libc) { | 431 | if (!builtin.single_threaded and !builtin.link_libc) { |
| 434 | _ = @import("os/windows/tls.zig"); | 432 | _ = @import("os/windows/tls.zig"); |
| 435 | } | 433 | } |
| ... | @@ -439,8 +437,7 @@ fn WinStartup() callconv(std.os.windows.WINAPI) noreturn { | ... | @@ -439,8 +437,7 @@ fn WinStartup() callconv(std.os.windows.WINAPI) noreturn { |
| 439 | std.os.windows.ntdll.RtlExitUserProcess(callMain()); | 437 | std.os.windows.ntdll.RtlExitUserProcess(callMain()); |
| 440 | } | 438 | } |
| 441 | 439 | ||
| 442 | fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { | 440 | fn wWinMainCRTStartup() callconv(.withStackAlign(.winapi, 1)) noreturn { |
| 443 | @setAlignStack(16); | ||
| 444 | if (!builtin.single_threaded and !builtin.link_libc) { | 441 | if (!builtin.single_threaded and !builtin.link_libc) { |
| 445 | _ = @import("os/windows/tls.zig"); | 442 | _ = @import("os/windows/tls.zig"); |
| 446 | } | 443 | } |
lib/std/zig/AstGen.zig-9| ... | @@ -2902,7 +2902,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2902,7 +2902,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2902 | .breakpoint, | 2902 | .breakpoint, |
| 2903 | .disable_instrumentation, | 2903 | .disable_instrumentation, |
| 2904 | .set_float_mode, | 2904 | .set_float_mode, |
| 2905 | .set_align_stack, | ||
| 2906 | .branch_hint, | 2905 | .branch_hint, |
| 2907 | => break :b true, | 2906 | => break :b true, |
| 2908 | else => break :b false, | 2907 | else => break :b false, |
| ... | @@ -9324,14 +9323,6 @@ fn builtinCall( | ... | @@ -9324,14 +9323,6 @@ fn builtinCall( |
| 9324 | }); | 9323 | }); |
| 9325 | return rvalue(gz, ri, .void_value, node); | 9324 | return rvalue(gz, ri, .void_value, node); |
| 9326 | }, | 9325 | }, |
| 9327 | .set_align_stack => { | ||
| 9328 | const order = try expr(gz, scope, coerced_align_ri, params[0]); | ||
| 9329 | _ = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{ | ||
| 9330 | .node = gz.nodeIndexToRelative(node), | ||
| 9331 | .operand = order, | ||
| 9332 | }); | ||
| 9333 | return rvalue(gz, ri, .void_value, node); | ||
| 9334 | }, | ||
| 9335 | 9326 | ||
| 9336 | .src => { | 9327 | .src => { |
| 9337 | // Incorporate the source location into the source hash, so that | 9328 | // Incorporate the source location into the source hash, so that |
lib/std/zig/AstRlAnnotate.zig-1| ... | @@ -909,7 +909,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. | ... | @@ -909,7 +909,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 909 | .wasm_memory_size, | 909 | .wasm_memory_size, |
| 910 | .splat, | 910 | .splat, |
| 911 | .set_float_mode, | 911 | .set_float_mode, |
| 912 | .set_align_stack, | ||
| 913 | .type_info, | 912 | .type_info, |
| 914 | .work_item_id, | 913 | .work_item_id, |
| 915 | .work_group_size, | 914 | .work_group_size, |
lib/std/zig/BuiltinFn.zig-9| ... | @@ -82,7 +82,6 @@ pub const Tag = enum { | ... | @@ -82,7 +82,6 @@ pub const Tag = enum { |
| 82 | rem, | 82 | rem, |
| 83 | return_address, | 83 | return_address, |
| 84 | select, | 84 | select, |
| 85 | set_align_stack, | ||
| 86 | set_eval_branch_quota, | 85 | set_eval_branch_quota, |
| 87 | set_float_mode, | 86 | set_float_mode, |
| 88 | set_runtime_safety, | 87 | set_runtime_safety, |
| ... | @@ -744,14 +743,6 @@ pub const list = list: { | ... | @@ -744,14 +743,6 @@ pub const list = list: { |
| 744 | .param_count = 4, | 743 | .param_count = 4, |
| 745 | }, | 744 | }, |
| 746 | }, | 745 | }, |
| 747 | .{ | ||
| 748 | "@setAlignStack", | ||
| 749 | .{ | ||
| 750 | .tag = .set_align_stack, | ||
| 751 | .param_count = 1, | ||
| 752 | .illegal_outside_function = true, | ||
| 753 | }, | ||
| 754 | }, | ||
| 755 | .{ | 746 | .{ |
| 756 | "@setEvalBranchQuota", | 747 | "@setEvalBranchQuota", |
| 757 | .{ | 748 | .{ |
lib/std/zig/Zir.zig-4| ... | @@ -1982,9 +1982,6 @@ pub const Inst = struct { | ... | @@ -1982,9 +1982,6 @@ pub const Inst = struct { |
| 1982 | /// Implement builtin `@setFloatMode`. | 1982 | /// Implement builtin `@setFloatMode`. |
| 1983 | /// `operand` is payload index to `UnNode`. | 1983 | /// `operand` is payload index to `UnNode`. |
| 1984 | set_float_mode, | 1984 | set_float_mode, |
| 1985 | /// Implement builtin `@setAlignStack`. | ||
| 1986 | /// `operand` is payload index to `UnNode`. | ||
| 1987 | set_align_stack, | ||
| 1988 | /// Implements the `@errorCast` builtin. | 1985 | /// Implements the `@errorCast` builtin. |
| 1989 | /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand. | 1986 | /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand. |
| 1990 | error_cast, | 1987 | error_cast, |
| ... | @@ -4012,7 +4009,6 @@ fn findDeclsInner( | ... | @@ -4012,7 +4009,6 @@ fn findDeclsInner( |
| 4012 | .wasm_memory_grow, | 4009 | .wasm_memory_grow, |
| 4013 | .prefetch, | 4010 | .prefetch, |
| 4014 | .set_float_mode, | 4011 | .set_float_mode, |
| 4015 | .set_align_stack, | ||
| 4016 | .error_cast, | 4012 | .error_cast, |
| 4017 | .await_nosuspend, | 4013 | .await_nosuspend, |
| 4018 | .breakpoint, | 4014 | .breakpoint, |
lib/std/zig/c_builtins.zig+1-1| ... | @@ -265,4 +265,4 @@ pub fn __builtin_mul_overflow(a: anytype, b: anytype, result: *@TypeOf(a, b)) c_ | ... | @@ -265,4 +265,4 @@ pub fn __builtin_mul_overflow(a: anytype, b: anytype, result: *@TypeOf(a, b)) c_ |
| 265 | // It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented | 265 | // It is used in a run-translated-c test and a test-translate-c test to ensure that non-implemented |
| 266 | // builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the | 266 | // builtins are correctly demoted. If you implement __builtin_alloca_with_align, please update the |
| 267 | // run-translated-c test and the test-translate-c test to use a different non-implemented builtin. | 267 | // run-translated-c test and the test-translate-c test to use a different non-implemented builtin. |
| 268 | // pub fn __builtin_alloca_with_align(size: usize, alignment: usize) callconv(.Inline) *anyopaque {} | 268 | // pub inline fn __builtin_alloca_with_align(size: usize, alignment: usize) *anyopaque {} |
lib/std/zig/parser_test.zig+5-5| ... | @@ -107,15 +107,15 @@ test "zig fmt: respect line breaks before functions" { | ... | @@ -107,15 +107,15 @@ test "zig fmt: respect line breaks before functions" { |
| 107 | ); | 107 | ); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | test "zig fmt: rewrite callconv(.Inline) to the inline keyword" { | 110 | test "zig fmt: rewrite callconv(.@\"inline\") to the inline keyword" { |
| 111 | try testTransform( | 111 | try testTransform( |
| 112 | \\fn foo() callconv(.Inline) void {} | 112 | \\fn foo() callconv(.@"inline") void {} |
| 113 | \\const bar = .Inline; | 113 | \\const bar: @import("std").builtin.CallingConvention = .@"inline"; |
| 114 | \\fn foo() callconv(bar) void {} | 114 | \\fn foo() callconv(bar) void {} |
| 115 | \\ | 115 | \\ |
| 116 | , | 116 | , |
| 117 | \\inline fn foo() void {} | 117 | \\inline fn foo() void {} |
| 118 | \\const bar = .Inline; | 118 | \\const bar: @import("std").builtin.CallingConvention = .@"inline"; |
| 119 | \\fn foo() callconv(bar) void {} | 119 | \\fn foo() callconv(bar) void {} |
| 120 | \\ | 120 | \\ |
| 121 | ); | 121 | ); |
| ... | @@ -3062,7 +3062,7 @@ test "zig fmt: functions" { | ... | @@ -3062,7 +3062,7 @@ test "zig fmt: functions" { |
| 3062 | \\pub export fn puts(s: *const u8) align(2 + 2) c_int; | 3062 | \\pub export fn puts(s: *const u8) align(2 + 2) c_int; |
| 3063 | \\pub inline fn puts(s: *const u8) align(2 + 2) c_int; | 3063 | \\pub inline fn puts(s: *const u8) align(2 + 2) c_int; |
| 3064 | \\pub noinline fn puts(s: *const u8) align(2 + 2) c_int; | 3064 | \\pub noinline fn puts(s: *const u8) align(2 + 2) c_int; |
| 3065 | \\pub fn callInlineFn(func: fn () callconv(.Inline) void) void { | 3065 | \\pub fn callInlineFn(func: fn () callconv(.@"inline") void) void { |
| 3066 | \\ func(); | 3066 | \\ func(); |
| 3067 | \\} | 3067 | \\} |
| 3068 | \\ | 3068 | \\ |
lib/std/zig/render.zig+4-2| ... | @@ -184,8 +184,9 @@ fn renderMember( | ... | @@ -184,8 +184,9 @@ fn renderMember( |
| 184 | tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProtoOne).callconv_expr | 184 | tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProtoOne).callconv_expr |
| 185 | else | 185 | else |
| 186 | tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProto).callconv_expr; | 186 | tree.extraData(datas[fn_proto].lhs, Ast.Node.FnProto).callconv_expr; |
| 187 | // Keep in sync with logic in `renderFnProto`. Search this file for the marker PROMOTE_CALLCONV_INLINE | ||
| 187 | if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) { | 188 | if (callconv_expr != 0 and tree.nodes.items(.tag)[callconv_expr] == .enum_literal) { |
| 188 | if (mem.eql(u8, "Inline", tree.tokenSlice(main_tokens[callconv_expr]))) { | 189 | if (mem.eql(u8, "@\"inline\"", tree.tokenSlice(main_tokens[callconv_expr]))) { |
| 189 | try ais.writer().writeAll("inline "); | 190 | try ais.writer().writeAll("inline "); |
| 190 | } | 191 | } |
| 191 | } | 192 | } |
| ... | @@ -1839,7 +1840,8 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi | ... | @@ -1839,7 +1840,8 @@ fn renderFnProto(r: *Render, fn_proto: Ast.full.FnProto, space: Space) Error!voi |
| 1839 | try renderToken(r, section_rparen, .space); // ) | 1840 | try renderToken(r, section_rparen, .space); // ) |
| 1840 | } | 1841 | } |
| 1841 | 1842 | ||
| 1842 | const is_callconv_inline = mem.eql(u8, "Inline", tree.tokenSlice(tree.nodes.items(.main_token)[fn_proto.ast.callconv_expr])); | 1843 | // Keep in sync with logic in `renderMember`. Search this file for the marker PROMOTE_CALLCONV_INLINE |
| 1844 | const is_callconv_inline = mem.eql(u8, "@\"inline\"", tree.tokenSlice(tree.nodes.items(.main_token)[fn_proto.ast.callconv_expr])); | ||
| 1843 | const is_declaration = fn_proto.name_token != null; | 1845 | const is_declaration = fn_proto.name_token != null; |
| 1844 | if (fn_proto.ast.callconv_expr != 0 and !(is_declaration and is_callconv_inline)) { | 1846 | if (fn_proto.ast.callconv_expr != 0 and !(is_declaration and is_callconv_inline)) { |
| 1845 | const callconv_lparen = tree.firstToken(fn_proto.ast.callconv_expr) - 1; | 1847 | const callconv_lparen = tree.firstToken(fn_proto.ast.callconv_expr) - 1; |
src/InternPool.zig+88-30| ... | @@ -2011,10 +2011,10 @@ pub const Key = union(enum) { | ... | @@ -2011,10 +2011,10 @@ pub const Key = union(enum) { |
| 2011 | a.return_type == b.return_type and | 2011 | a.return_type == b.return_type and |
| 2012 | a.comptime_bits == b.comptime_bits and | 2012 | a.comptime_bits == b.comptime_bits and |
| 2013 | a.noalias_bits == b.noalias_bits and | 2013 | a.noalias_bits == b.noalias_bits and |
| 2014 | a.cc == b.cc and | ||
| 2015 | a.is_var_args == b.is_var_args and | 2014 | a.is_var_args == b.is_var_args and |
| 2016 | a.is_generic == b.is_generic and | 2015 | a.is_generic == b.is_generic and |
| 2017 | a.is_noinline == b.is_noinline; | 2016 | a.is_noinline == b.is_noinline and |
| 2017 | std.meta.eql(a.cc, b.cc); | ||
| 2018 | } | 2018 | } |
| 2019 | 2019 | ||
| 2020 | pub fn hash(self: FuncType, hasher: *Hash, ip: *const InternPool) void { | 2020 | pub fn hash(self: FuncType, hasher: *Hash, ip: *const InternPool) void { |
| ... | @@ -5444,7 +5444,7 @@ pub const Tag = enum(u8) { | ... | @@ -5444,7 +5444,7 @@ pub const Tag = enum(u8) { |
| 5444 | flags: Flags, | 5444 | flags: Flags, |
| 5445 | 5445 | ||
| 5446 | pub const Flags = packed struct(u32) { | 5446 | pub const Flags = packed struct(u32) { |
| 5447 | cc: std.builtin.CallingConvention, | 5447 | cc: PackedCallingConvention, |
| 5448 | is_var_args: bool, | 5448 | is_var_args: bool, |
| 5449 | is_generic: bool, | 5449 | is_generic: bool, |
| 5450 | has_comptime_bits: bool, | 5450 | has_comptime_bits: bool, |
| ... | @@ -5453,7 +5453,7 @@ pub const Tag = enum(u8) { | ... | @@ -5453,7 +5453,7 @@ pub const Tag = enum(u8) { |
| 5453 | cc_is_generic: bool, | 5453 | cc_is_generic: bool, |
| 5454 | section_is_generic: bool, | 5454 | section_is_generic: bool, |
| 5455 | addrspace_is_generic: bool, | 5455 | addrspace_is_generic: bool, |
| 5456 | _: u16 = 0, | 5456 | _: u6 = 0, |
| 5457 | }; | 5457 | }; |
| 5458 | }; | 5458 | }; |
| 5459 | 5459 | ||
| ... | @@ -5618,12 +5618,11 @@ pub const FuncAnalysis = packed struct(u32) { | ... | @@ -5618,12 +5618,11 @@ pub const FuncAnalysis = packed struct(u32) { |
| 5618 | branch_hint: std.builtin.BranchHint, | 5618 | branch_hint: std.builtin.BranchHint, |
| 5619 | is_noinline: bool, | 5619 | is_noinline: bool, |
| 5620 | calls_or_awaits_errorable_fn: bool, | 5620 | calls_or_awaits_errorable_fn: bool, |
| 5621 | stack_alignment: Alignment, | ||
| 5622 | /// True if this function has an inferred error set. | 5621 | /// True if this function has an inferred error set. |
| 5623 | inferred_error_set: bool, | 5622 | inferred_error_set: bool, |
| 5624 | disable_instrumentation: bool, | 5623 | disable_instrumentation: bool, |
| 5625 | 5624 | ||
| 5626 | _: u17 = 0, | 5625 | _: u23 = 0, |
| 5627 | 5626 | ||
| 5628 | pub const State = enum(u2) { | 5627 | pub const State = enum(u2) { |
| 5629 | /// The runtime function has never been referenced. | 5628 | /// The runtime function has never been referenced. |
| ... | @@ -6912,7 +6911,7 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke | ... | @@ -6912,7 +6911,7 @@ fn extraFuncType(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke |
| 6912 | .return_type = type_function.data.return_type, | 6911 | .return_type = type_function.data.return_type, |
| 6913 | .comptime_bits = comptime_bits, | 6912 | .comptime_bits = comptime_bits, |
| 6914 | .noalias_bits = noalias_bits, | 6913 | .noalias_bits = noalias_bits, |
| 6915 | .cc = type_function.data.flags.cc, | 6914 | .cc = type_function.data.flags.cc.unpack(), |
| 6916 | .is_var_args = type_function.data.flags.is_var_args, | 6915 | .is_var_args = type_function.data.flags.is_var_args, |
| 6917 | .is_noinline = type_function.data.flags.is_noinline, | 6916 | .is_noinline = type_function.data.flags.is_noinline, |
| 6918 | .cc_is_generic = type_function.data.flags.cc_is_generic, | 6917 | .cc_is_generic = type_function.data.flags.cc_is_generic, |
| ... | @@ -8526,7 +8525,7 @@ pub const GetFuncTypeKey = struct { | ... | @@ -8526,7 +8525,7 @@ pub const GetFuncTypeKey = struct { |
| 8526 | comptime_bits: u32 = 0, | 8525 | comptime_bits: u32 = 0, |
| 8527 | noalias_bits: u32 = 0, | 8526 | noalias_bits: u32 = 0, |
| 8528 | /// `null` means generic. | 8527 | /// `null` means generic. |
| 8529 | cc: ?std.builtin.CallingConvention = .Unspecified, | 8528 | cc: ?std.builtin.CallingConvention = .auto, |
| 8530 | is_var_args: bool = false, | 8529 | is_var_args: bool = false, |
| 8531 | is_generic: bool = false, | 8530 | is_generic: bool = false, |
| 8532 | is_noinline: bool = false, | 8531 | is_noinline: bool = false, |
| ... | @@ -8564,7 +8563,7 @@ pub fn getFuncType( | ... | @@ -8564,7 +8563,7 @@ pub fn getFuncType( |
| 8564 | .params_len = params_len, | 8563 | .params_len = params_len, |
| 8565 | .return_type = key.return_type, | 8564 | .return_type = key.return_type, |
| 8566 | .flags = .{ | 8565 | .flags = .{ |
| 8567 | .cc = key.cc orelse .Unspecified, | 8566 | .cc = .pack(key.cc orelse .auto), |
| 8568 | .is_var_args = key.is_var_args, | 8567 | .is_var_args = key.is_var_args, |
| 8569 | .has_comptime_bits = key.comptime_bits != 0, | 8568 | .has_comptime_bits = key.comptime_bits != 0, |
| 8570 | .has_noalias_bits = key.noalias_bits != 0, | 8569 | .has_noalias_bits = key.noalias_bits != 0, |
| ... | @@ -8696,7 +8695,6 @@ pub fn getFuncDecl( | ... | @@ -8696,7 +8695,6 @@ pub fn getFuncDecl( |
| 8696 | .branch_hint = .none, | 8695 | .branch_hint = .none, |
| 8697 | .is_noinline = key.is_noinline, | 8696 | .is_noinline = key.is_noinline, |
| 8698 | .calls_or_awaits_errorable_fn = false, | 8697 | .calls_or_awaits_errorable_fn = false, |
| 8699 | .stack_alignment = .none, | ||
| 8700 | .inferred_error_set = false, | 8698 | .inferred_error_set = false, |
| 8701 | .disable_instrumentation = false, | 8699 | .disable_instrumentation = false, |
| 8702 | }, | 8700 | }, |
| ... | @@ -8800,7 +8798,6 @@ pub fn getFuncDeclIes( | ... | @@ -8800,7 +8798,6 @@ pub fn getFuncDeclIes( |
| 8800 | .branch_hint = .none, | 8798 | .branch_hint = .none, |
| 8801 | .is_noinline = key.is_noinline, | 8799 | .is_noinline = key.is_noinline, |
| 8802 | .calls_or_awaits_errorable_fn = false, | 8800 | .calls_or_awaits_errorable_fn = false, |
| 8803 | .stack_alignment = .none, | ||
| 8804 | .inferred_error_set = true, | 8801 | .inferred_error_set = true, |
| 8805 | .disable_instrumentation = false, | 8802 | .disable_instrumentation = false, |
| 8806 | }, | 8803 | }, |
| ... | @@ -8818,7 +8815,7 @@ pub fn getFuncDeclIes( | ... | @@ -8818,7 +8815,7 @@ pub fn getFuncDeclIes( |
| 8818 | .params_len = params_len, | 8815 | .params_len = params_len, |
| 8819 | .return_type = error_union_type, | 8816 | .return_type = error_union_type, |
| 8820 | .flags = .{ | 8817 | .flags = .{ |
| 8821 | .cc = key.cc orelse .Unspecified, | 8818 | .cc = .pack(key.cc orelse .auto), |
| 8822 | .is_var_args = key.is_var_args, | 8819 | .is_var_args = key.is_var_args, |
| 8823 | .has_comptime_bits = key.comptime_bits != 0, | 8820 | .has_comptime_bits = key.comptime_bits != 0, |
| 8824 | .has_noalias_bits = key.noalias_bits != 0, | 8821 | .has_noalias_bits = key.noalias_bits != 0, |
| ... | @@ -8992,7 +8989,6 @@ pub fn getFuncInstance( | ... | @@ -8992,7 +8989,6 @@ pub fn getFuncInstance( |
| 8992 | .branch_hint = .none, | 8989 | .branch_hint = .none, |
| 8993 | .is_noinline = arg.is_noinline, | 8990 | .is_noinline = arg.is_noinline, |
| 8994 | .calls_or_awaits_errorable_fn = false, | 8991 | .calls_or_awaits_errorable_fn = false, |
| 8995 | .stack_alignment = .none, | ||
| 8996 | .inferred_error_set = false, | 8992 | .inferred_error_set = false, |
| 8997 | .disable_instrumentation = false, | 8993 | .disable_instrumentation = false, |
| 8998 | }, | 8994 | }, |
| ... | @@ -9092,7 +9088,6 @@ pub fn getFuncInstanceIes( | ... | @@ -9092,7 +9088,6 @@ pub fn getFuncInstanceIes( |
| 9092 | .branch_hint = .none, | 9088 | .branch_hint = .none, |
| 9093 | .is_noinline = arg.is_noinline, | 9089 | .is_noinline = arg.is_noinline, |
| 9094 | .calls_or_awaits_errorable_fn = false, | 9090 | .calls_or_awaits_errorable_fn = false, |
| 9095 | .stack_alignment = .none, | ||
| 9096 | .inferred_error_set = true, | 9091 | .inferred_error_set = true, |
| 9097 | .disable_instrumentation = false, | 9092 | .disable_instrumentation = false, |
| 9098 | }, | 9093 | }, |
| ... | @@ -9110,7 +9105,7 @@ pub fn getFuncInstanceIes( | ... | @@ -9110,7 +9105,7 @@ pub fn getFuncInstanceIes( |
| 9110 | .params_len = params_len, | 9105 | .params_len = params_len, |
| 9111 | .return_type = error_union_type, | 9106 | .return_type = error_union_type, |
| 9112 | .flags = .{ | 9107 | .flags = .{ |
| 9113 | .cc = arg.cc, | 9108 | .cc = .pack(arg.cc), |
| 9114 | .is_var_args = false, | 9109 | .is_var_args = false, |
| 9115 | .has_comptime_bits = false, | 9110 | .has_comptime_bits = false, |
| 9116 | .has_noalias_bits = arg.noalias_bits != 0, | 9111 | .has_noalias_bits = arg.noalias_bits != 0, |
| ... | @@ -11871,21 +11866,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis { | ... | @@ -11871,21 +11866,6 @@ pub fn funcAnalysisUnordered(ip: *const InternPool, func: Index) FuncAnalysis { |
| 11871 | return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered); | 11866 | return @atomicLoad(FuncAnalysis, @constCast(ip).funcAnalysisPtr(func), .unordered); |
| 11872 | } | 11867 | } |
| 11873 | 11868 | ||
| 11874 | pub fn funcMaxStackAlignment(ip: *InternPool, func: Index, new_stack_alignment: Alignment) void { | ||
| 11875 | const unwrapped_func = func.unwrap(ip); | ||
| 11876 | const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex; | ||
| 11877 | extra_mutex.lock(); | ||
| 11878 | defer extra_mutex.unlock(); | ||
| 11879 | |||
| 11880 | const analysis_ptr = ip.funcAnalysisPtr(func); | ||
| 11881 | var analysis = analysis_ptr.*; | ||
| 11882 | analysis.stack_alignment = switch (analysis.stack_alignment) { | ||
| 11883 | .none => new_stack_alignment, | ||
| 11884 | else => |old_stack_alignment| old_stack_alignment.maxStrict(new_stack_alignment), | ||
| 11885 | }; | ||
| 11886 | @atomicStore(FuncAnalysis, analysis_ptr, analysis, .release); | ||
| 11887 | } | ||
| 11888 | |||
| 11889 | pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void { | 11869 | pub fn funcSetCallsOrAwaitsErrorableFn(ip: *InternPool, func: Index) void { |
| 11890 | const unwrapped_func = func.unwrap(ip); | 11870 | const unwrapped_func = func.unwrap(ip); |
| 11891 | const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex; | 11871 | const extra_mutex = &ip.getLocal(unwrapped_func.tid).mutate.extra.mutex; |
| ... | @@ -12224,3 +12204,81 @@ pub fn getErrorValue( | ... | @@ -12224,3 +12204,81 @@ pub fn getErrorValue( |
| 12224 | pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt { | 12204 | pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt { |
| 12225 | return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null); | 12205 | return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null); |
| 12226 | } | 12206 | } |
| 12207 | |||
| 12208 | const PackedCallingConvention = packed struct(u18) { | ||
| 12209 | tag: std.builtin.CallingConvention.Tag, | ||
| 12210 | /// May be ignored depending on `tag`. | ||
| 12211 | incoming_stack_alignment: Alignment, | ||
| 12212 | /// Interpretation depends on `tag`. | ||
| 12213 | extra: u4, | ||
| 12214 | |||
| 12215 | fn pack(cc: std.builtin.CallingConvention) PackedCallingConvention { | ||
| 12216 | return switch (cc) { | ||
| 12217 | inline else => |pl, tag| switch (@TypeOf(pl)) { | ||
| 12218 | void => .{ | ||
| 12219 | .tag = tag, | ||
| 12220 | .incoming_stack_alignment = .none, // unused | ||
| 12221 | .extra = 0, // unused | ||
| 12222 | }, | ||
| 12223 | std.builtin.CallingConvention.CommonOptions => .{ | ||
| 12224 | .tag = tag, | ||
| 12225 | .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), | ||
| 12226 | .extra = 0, // unused | ||
| 12227 | }, | ||
| 12228 | std.builtin.CallingConvention.X86RegparmOptions => .{ | ||
| 12229 | .tag = tag, | ||
| 12230 | .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), | ||
| 12231 | .extra = pl.register_params, | ||
| 12232 | }, | ||
| 12233 | std.builtin.CallingConvention.ArmInterruptOptions => .{ | ||
| 12234 | .tag = tag, | ||
| 12235 | .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), | ||
| 12236 | .extra = @intFromEnum(pl.type), | ||
| 12237 | }, | ||
| 12238 | std.builtin.CallingConvention.MipsInterruptOptions => .{ | ||
| 12239 | .tag = tag, | ||
| 12240 | .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), | ||
| 12241 | .extra = @intFromEnum(pl.mode), | ||
| 12242 | }, | ||
| 12243 | std.builtin.CallingConvention.RiscvInterruptOptions => .{ | ||
| 12244 | .tag = tag, | ||
| 12245 | .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), | ||
| 12246 | .extra = @intFromEnum(pl.mode), | ||
| 12247 | }, | ||
| 12248 | else => comptime unreachable, | ||
| 12249 | }, | ||
| 12250 | }; | ||
| 12251 | } | ||
| 12252 | |||
| 12253 | fn unpack(cc: PackedCallingConvention) std.builtin.CallingConvention { | ||
| 12254 | return switch (cc.tag) { | ||
| 12255 | inline else => |tag| @unionInit( | ||
| 12256 | std.builtin.CallingConvention, | ||
| 12257 | @tagName(tag), | ||
| 12258 | switch (@FieldType(std.builtin.CallingConvention, @tagName(tag))) { | ||
| 12259 | void => {}, | ||
| 12260 | std.builtin.CallingConvention.CommonOptions => .{ | ||
| 12261 | .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), | ||
| 12262 | }, | ||
| 12263 | std.builtin.CallingConvention.X86RegparmOptions => .{ | ||
| 12264 | .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), | ||
| 12265 | .register_params = @intCast(cc.extra), | ||
| 12266 | }, | ||
| 12267 | std.builtin.CallingConvention.ArmInterruptOptions => .{ | ||
| 12268 | .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), | ||
| 12269 | .type = @enumFromInt(cc.extra), | ||
| 12270 | }, | ||
| 12271 | std.builtin.CallingConvention.MipsInterruptOptions => .{ | ||
| 12272 | .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), | ||
| 12273 | .mode = @enumFromInt(cc.extra), | ||
| 12274 | }, | ||
| 12275 | std.builtin.CallingConvention.RiscvInterruptOptions => .{ | ||
| 12276 | .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), | ||
| 12277 | .mode = @enumFromInt(cc.extra), | ||
| 12278 | }, | ||
| 12279 | else => comptime unreachable, | ||
| 12280 | }, | ||
| 12281 | ), | ||
| 12282 | }; | ||
| 12283 | } | ||
| 12284 | }; |
src/Sema.zig+260-141| ... | @@ -26,7 +26,7 @@ owner: AnalUnit, | ... | @@ -26,7 +26,7 @@ owner: AnalUnit, |
| 26 | /// in the case of an inline or comptime function call. | 26 | /// in the case of an inline or comptime function call. |
| 27 | /// This could be `none`, a `func_decl`, or a `func_instance`. | 27 | /// This could be `none`, a `func_decl`, or a `func_instance`. |
| 28 | func_index: InternPool.Index, | 28 | func_index: InternPool.Index, |
| 29 | /// Whether the type of func_index has a calling convention of `.Naked`. | 29 | /// Whether the type of func_index has a calling convention of `.naked`. |
| 30 | func_is_naked: bool, | 30 | func_is_naked: bool, |
| 31 | /// Used to restore the error return trace when returning a non-error from a function. | 31 | /// Used to restore the error return trace when returning a non-error from a function. |
| 32 | error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none, | 32 | error_return_trace_index_on_fn_entry: Air.Inst.Ref = .none, |
| ... | @@ -1326,11 +1326,6 @@ fn analyzeBodyInner( | ... | @@ -1326,11 +1326,6 @@ fn analyzeBodyInner( |
| 1326 | i += 1; | 1326 | i += 1; |
| 1327 | continue; | 1327 | continue; |
| 1328 | }, | 1328 | }, |
| 1329 | .set_align_stack => { | ||
| 1330 | try sema.zirSetAlignStack(block, extended); | ||
| 1331 | i += 1; | ||
| 1332 | continue; | ||
| 1333 | }, | ||
| 1334 | .breakpoint => { | 1329 | .breakpoint => { |
| 1335 | if (!block.is_comptime) { | 1330 | if (!block.is_comptime) { |
| 1336 | _ = try block.addNoOp(.breakpoint); | 1331 | _ = try block.addNoOp(.breakpoint); |
| ... | @@ -1355,7 +1350,7 @@ fn analyzeBodyInner( | ... | @@ -1355,7 +1350,7 @@ fn analyzeBodyInner( |
| 1355 | }, | 1350 | }, |
| 1356 | .value_placeholder => unreachable, // never appears in a body | 1351 | .value_placeholder => unreachable, // never appears in a body |
| 1357 | .field_parent_ptr => try sema.zirFieldParentPtr(block, extended), | 1352 | .field_parent_ptr => try sema.zirFieldParentPtr(block, extended), |
| 1358 | .builtin_value => try sema.zirBuiltinValue(extended), | 1353 | .builtin_value => try sema.zirBuiltinValue(block, extended), |
| 1359 | .inplace_arith_result_ty => try sema.zirInplaceArithResultTy(extended), | 1354 | .inplace_arith_result_ty => try sema.zirInplaceArithResultTy(extended), |
| 1360 | }; | 1355 | }; |
| 1361 | }, | 1356 | }, |
| ... | @@ -2698,6 +2693,20 @@ fn analyzeAsInt( | ... | @@ -2698,6 +2693,20 @@ fn analyzeAsInt( |
| 2698 | return try val.toUnsignedIntSema(sema.pt); | 2693 | return try val.toUnsignedIntSema(sema.pt); |
| 2699 | } | 2694 | } |
| 2700 | 2695 | ||
| 2696 | fn analyzeValueAsCallconv( | ||
| 2697 | sema: *Sema, | ||
| 2698 | block: *Block, | ||
| 2699 | src: LazySrcLoc, | ||
| 2700 | unresolved_val: Value, | ||
| 2701 | ) !std.builtin.CallingConvention { | ||
| 2702 | const resolved_val = try sema.resolveLazyValue(unresolved_val); | ||
| 2703 | return resolved_val.interpret(std.builtin.CallingConvention, sema.pt) catch |err| switch (err) { | ||
| 2704 | error.OutOfMemory => |e| return e, | ||
| 2705 | error.UndefinedValue => return sema.failWithUseOfUndef(block, src), | ||
| 2706 | error.TypeMismatch => @panic("std.builtin is corrupt"), | ||
| 2707 | }; | ||
| 2708 | } | ||
| 2709 | |||
| 2701 | /// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`, | 2710 | /// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`, |
| 2702 | /// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`. | 2711 | /// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`. |
| 2703 | fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue { | 2712 | fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue { |
| ... | @@ -6496,35 +6505,6 @@ pub fn analyzeExport( | ... | @@ -6496,35 +6505,6 @@ pub fn analyzeExport( |
| 6496 | }); | 6505 | }); |
| 6497 | } | 6506 | } |
| 6498 | 6507 | ||
| 6499 | fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void { | ||
| 6500 | const pt = sema.pt; | ||
| 6501 | const zcu = pt.zcu; | ||
| 6502 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | ||
| 6503 | const operand_src = block.builtinCallArgSrc(extra.node, 0); | ||
| 6504 | const src = block.nodeOffset(extra.node); | ||
| 6505 | const alignment = try sema.resolveAlign(block, operand_src, extra.operand); | ||
| 6506 | |||
| 6507 | const func = switch (sema.owner.unwrap()) { | ||
| 6508 | .func => |func| func, | ||
| 6509 | .cau => return sema.fail(block, src, "@setAlignStack outside of function scope", .{}), | ||
| 6510 | }; | ||
| 6511 | |||
| 6512 | if (alignment.order(Alignment.fromNonzeroByteUnits(256)).compare(.gt)) { | ||
| 6513 | return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{ | ||
| 6514 | alignment.toByteUnits().?, | ||
| 6515 | }); | ||
| 6516 | } | ||
| 6517 | |||
| 6518 | switch (Value.fromInterned(func).typeOf(zcu).fnCallingConvention(zcu)) { | ||
| 6519 | .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}), | ||
| 6520 | .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}), | ||
| 6521 | else => {}, | ||
| 6522 | } | ||
| 6523 | |||
| 6524 | zcu.intern_pool.funcMaxStackAlignment(sema.func_index, alignment); | ||
| 6525 | sema.allow_memoize = false; | ||
| 6526 | } | ||
| 6527 | |||
| 6528 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { | 6508 | fn zirDisableInstrumentation(sema: *Sema) CompileError!void { |
| 6529 | const pt = sema.pt; | 6509 | const pt = sema.pt; |
| 6530 | const zcu = pt.zcu; | 6510 | const zcu = pt.zcu; |
| ... | @@ -7554,7 +7534,7 @@ fn analyzeCall( | ... | @@ -7554,7 +7534,7 @@ fn analyzeCall( |
| 7554 | if (try sema.resolveValue(func)) |func_val| | 7534 | if (try sema.resolveValue(func)) |func_val| |
| 7555 | if (func_val.isUndef(zcu)) | 7535 | if (func_val.isUndef(zcu)) |
| 7556 | return sema.failWithUseOfUndef(block, call_src); | 7536 | return sema.failWithUseOfUndef(block, call_src); |
| 7557 | if (cc == .Naked) { | 7537 | if (cc == .naked) { |
| 7558 | const maybe_func_inst = try sema.funcDeclSrcInst(func); | 7538 | const maybe_func_inst = try sema.funcDeclSrcInst(func); |
| 7559 | const msg = msg: { | 7539 | const msg = msg: { |
| 7560 | const msg = try sema.errMsg( | 7540 | const msg = try sema.errMsg( |
| ... | @@ -7587,7 +7567,7 @@ fn analyzeCall( | ... | @@ -7587,7 +7567,7 @@ fn analyzeCall( |
| 7587 | .async_kw => return sema.failWithUseOfAsync(block, call_src), | 7567 | .async_kw => return sema.failWithUseOfAsync(block, call_src), |
| 7588 | }; | 7568 | }; |
| 7589 | 7569 | ||
| 7590 | if (modifier == .never_inline and func_ty_info.cc == .Inline) { | 7570 | if (modifier == .never_inline and func_ty_info.cc == .@"inline") { |
| 7591 | return sema.fail(block, call_src, "'never_inline' call of inline function", .{}); | 7571 | return sema.fail(block, call_src, "'never_inline' call of inline function", .{}); |
| 7592 | } | 7572 | } |
| 7593 | if (modifier == .always_inline and func_ty_info.is_noinline) { | 7573 | if (modifier == .always_inline and func_ty_info.is_noinline) { |
| ... | @@ -7598,7 +7578,7 @@ fn analyzeCall( | ... | @@ -7598,7 +7578,7 @@ fn analyzeCall( |
| 7598 | 7578 | ||
| 7599 | const is_generic_call = func_ty_info.is_generic; | 7579 | const is_generic_call = func_ty_info.is_generic; |
| 7600 | var is_comptime_call = block.is_comptime or modifier == .compile_time; | 7580 | var is_comptime_call = block.is_comptime or modifier == .compile_time; |
| 7601 | var is_inline_call = is_comptime_call or modifier == .always_inline or func_ty_info.cc == .Inline; | 7581 | var is_inline_call = is_comptime_call or modifier == .always_inline or func_ty_info.cc == .@"inline"; |
| 7602 | var comptime_reason: ?*const Block.ComptimeReason = null; | 7582 | var comptime_reason: ?*const Block.ComptimeReason = null; |
| 7603 | if (!is_inline_call and !is_comptime_call) { | 7583 | if (!is_inline_call and !is_comptime_call) { |
| 7604 | if (try Type.fromInterned(func_ty_info.return_type).comptimeOnlySema(pt)) { | 7584 | if (try Type.fromInterned(func_ty_info.return_type).comptimeOnlySema(pt)) { |
| ... | @@ -8455,7 +8435,7 @@ fn instantiateGenericCall( | ... | @@ -8455,7 +8435,7 @@ fn instantiateGenericCall( |
| 8455 | } | 8435 | } |
| 8456 | // Similarly, if the call evaluated to a generic type we need to instead | 8436 | // Similarly, if the call evaluated to a generic type we need to instead |
| 8457 | // call it inline. | 8437 | // call it inline. |
| 8458 | if (func_ty_info.is_generic or func_ty_info.cc == .Inline) { | 8438 | if (func_ty_info.is_generic or func_ty_info.cc == .@"inline") { |
| 8459 | return error.GenericPoison; | 8439 | return error.GenericPoison; |
| 8460 | } | 8440 | } |
| 8461 | 8441 | ||
| ... | @@ -9505,7 +9485,7 @@ fn zirFunc( | ... | @@ -9505,7 +9485,7 @@ fn zirFunc( |
| 9505 | 9485 | ||
| 9506 | // If this instruction has a body, then it's a function declaration, and we decide | 9486 | // If this instruction has a body, then it's a function declaration, and we decide |
| 9507 | // the callconv based on whether it is exported. Otherwise, the callconv defaults | 9487 | // the callconv based on whether it is exported. Otherwise, the callconv defaults |
| 9508 | // to `.Unspecified`. | 9488 | // to `.auto`. |
| 9509 | const cc: std.builtin.CallingConvention = if (has_body) cc: { | 9489 | const cc: std.builtin.CallingConvention = if (has_body) cc: { |
| 9510 | const func_decl_cau = if (sema.generic_owner != .none) cau: { | 9490 | const func_decl_cau = if (sema.generic_owner != .none) cau: { |
| 9511 | const generic_owner_fn = zcu.funcInfo(sema.generic_owner); | 9491 | const generic_owner_fn = zcu.funcInfo(sema.generic_owner); |
| ... | @@ -9518,8 +9498,26 @@ fn zirFunc( | ... | @@ -9518,8 +9498,26 @@ fn zirFunc( |
| 9518 | const zir_decl = sema.code.getDeclaration(decl_inst)[0]; | 9498 | const zir_decl = sema.code.getDeclaration(decl_inst)[0]; |
| 9519 | break :exported zir_decl.flags.is_export; | 9499 | break :exported zir_decl.flags.is_export; |
| 9520 | }; | 9500 | }; |
| 9521 | break :cc if (fn_is_exported) .C else .Unspecified; | 9501 | if (fn_is_exported) { |
| 9522 | } else .Unspecified; | 9502 | break :cc target.cCallingConvention() orelse { |
| 9503 | // This target has no default C calling convention. We sometimes trigger a similar | ||
| 9504 | // error by trying to evaluate `std.builtin.CallingConvention.c`, so for consistency, | ||
| 9505 | // let's eval that now and just get the transitive error. (It's guaranteed to error | ||
| 9506 | // because it does the exact `cCallingConvention` call we just did.) | ||
| 9507 | const cc_type = try sema.getBuiltinType("CallingConvention"); | ||
| 9508 | _ = try sema.namespaceLookupVal( | ||
| 9509 | block, | ||
| 9510 | LazySrcLoc.unneeded, | ||
| 9511 | cc_type.getNamespaceIndex(zcu), | ||
| 9512 | try ip.getOrPutString(sema.gpa, pt.tid, "c", .no_embedded_nulls), | ||
| 9513 | ); | ||
| 9514 | // The above should have errored. | ||
| 9515 | @panic("std.builtin is corrupt"); | ||
| 9516 | }; | ||
| 9517 | } else { | ||
| 9518 | break :cc .auto; | ||
| 9519 | } | ||
| 9520 | } else .auto; | ||
| 9523 | 9521 | ||
| 9524 | return sema.funcCommon( | 9522 | return sema.funcCommon( |
| 9525 | block, | 9523 | block, |
| ... | @@ -9654,35 +9652,91 @@ fn handleExternLibName( | ... | @@ -9654,35 +9652,91 @@ fn handleExternLibName( |
| 9654 | /// These are calling conventions that are confirmed to work with variadic functions. | 9652 | /// These are calling conventions that are confirmed to work with variadic functions. |
| 9655 | /// Any calling conventions not included here are either not yet verified to work with variadic | 9653 | /// Any calling conventions not included here are either not yet verified to work with variadic |
| 9656 | /// functions or there are no more other calling conventions that support variadic functions. | 9654 | /// functions or there are no more other calling conventions that support variadic functions. |
| 9657 | const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention{ | 9655 | const calling_conventions_supporting_var_args = [_]std.builtin.CallingConvention.Tag{ |
| 9658 | .C, | 9656 | .x86_64_sysv, |
| 9657 | .x86_64_win, | ||
| 9658 | .x86_sysv, | ||
| 9659 | .x86_win, | ||
| 9660 | .aarch64_aapcs, | ||
| 9661 | .aarch64_aapcs_darwin, | ||
| 9662 | .aarch64_aapcs_win, | ||
| 9663 | .aarch64_vfabi, | ||
| 9664 | .aarch64_vfabi_sve, | ||
| 9665 | .arm_apcs, | ||
| 9666 | .arm_aapcs, | ||
| 9667 | .arm_aapcs_vfp, | ||
| 9668 | .arm_aapcs16_vfp, | ||
| 9669 | .mips64_n64, | ||
| 9670 | .mips64_n32, | ||
| 9671 | .mips_o32, | ||
| 9672 | .riscv64_lp64, | ||
| 9673 | .riscv64_lp64_v, | ||
| 9674 | .riscv32_ilp32, | ||
| 9675 | .riscv32_ilp32_v, | ||
| 9676 | .sparc64_sysv, | ||
| 9677 | .sparc_sysv, | ||
| 9678 | .powerpc64_elf, | ||
| 9679 | .powerpc64_elf_altivec, | ||
| 9680 | .powerpc64_elf_v2, | ||
| 9681 | .powerpc_sysv, | ||
| 9682 | .powerpc_sysv_altivec, | ||
| 9683 | .powerpc_aix, | ||
| 9684 | .powerpc_aix_altivec, | ||
| 9685 | .wasm_watc, | ||
| 9686 | .arc_sysv, | ||
| 9687 | .avr_gnu, | ||
| 9688 | .bpf_std, | ||
| 9689 | .csky_sysv, | ||
| 9690 | .hexagon_sysv, | ||
| 9691 | .hexagon_sysv_hvx, | ||
| 9692 | .lanai_sysv, | ||
| 9693 | .loongarch64_lp64, | ||
| 9694 | .loongarch32_ilp32, | ||
| 9695 | .m68k_sysv, | ||
| 9696 | .m68k_gnu, | ||
| 9697 | .m68k_rtd, | ||
| 9698 | .msp430_eabi, | ||
| 9699 | .s390x_sysv, | ||
| 9700 | .s390x_sysv_vx, | ||
| 9701 | .ve_sysv, | ||
| 9702 | .xcore_xs1, | ||
| 9703 | .xcore_xs2, | ||
| 9704 | .xtensa_call0, | ||
| 9705 | .xtensa_windowed, | ||
| 9659 | }; | 9706 | }; |
| 9660 | fn callConvSupportsVarArgs(cc: std.builtin.CallingConvention) bool { | 9707 | fn callConvSupportsVarArgs(cc: std.builtin.CallingConvention.Tag) bool { |
| 9661 | return for (calling_conventions_supporting_var_args) |supported_cc| { | 9708 | return for (calling_conventions_supporting_var_args) |supported_cc| { |
| 9662 | if (cc == supported_cc) return true; | 9709 | if (cc == supported_cc) return true; |
| 9663 | } else false; | 9710 | } else false; |
| 9664 | } | 9711 | } |
| 9665 | fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention) CompileError!void { | 9712 | fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc: std.builtin.CallingConvention.Tag) CompileError!void { |
| 9666 | const CallingConventionsSupportingVarArgsList = struct { | 9713 | const CallingConventionsSupportingVarArgsList = struct { |
| 9667 | pub fn format(_: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | 9714 | arch: std.Target.Cpu.Arch, |
| 9715 | pub fn format(ctx: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { | ||
| 9668 | _ = fmt; | 9716 | _ = fmt; |
| 9669 | _ = options; | 9717 | _ = options; |
| 9670 | for (calling_conventions_supporting_var_args, 0..) |cc_inner, i| { | 9718 | var first = true; |
| 9671 | if (i != 0) | 9719 | for (calling_conventions_supporting_var_args) |cc_inner| { |
| 9720 | for (std.Target.Cpu.Arch.fromCallingConvention(cc_inner)) |supported_arch| { | ||
| 9721 | if (supported_arch == ctx.arch) break; | ||
| 9722 | } else continue; // callconv not supported by this arch | ||
| 9723 | if (!first) { | ||
| 9672 | try writer.writeAll(", "); | 9724 | try writer.writeAll(", "); |
| 9673 | try writer.print("'.{s}'", .{@tagName(cc_inner)}); | 9725 | } |
| 9726 | first = false; | ||
| 9727 | try writer.print("'{s}'", .{@tagName(cc_inner)}); | ||
| 9674 | } | 9728 | } |
| 9675 | } | 9729 | } |
| 9676 | }; | 9730 | }; |
| 9677 | 9731 | ||
| 9678 | if (!callConvSupportsVarArgs(cc)) { | 9732 | if (!callConvSupportsVarArgs(cc)) { |
| 9679 | const msg = msg: { | 9733 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 9680 | const msg = try sema.errMsg(src, "variadic function does not support '.{s}' calling convention", .{@tagName(cc)}); | 9734 | const msg = try sema.errMsg(src, "variadic function does not support '{s}' calling convention", .{@tagName(cc)}); |
| 9681 | errdefer msg.destroy(sema.gpa); | 9735 | errdefer msg.destroy(sema.gpa); |
| 9682 | try sema.errNote(src, msg, "supported calling conventions: {}", .{CallingConventionsSupportingVarArgsList{}}); | 9736 | const target = sema.pt.zcu.getTarget(); |
| 9737 | try sema.errNote(src, msg, "supported calling conventions: {}", .{CallingConventionsSupportingVarArgsList{ .arch = target.cpu.arch }}); | ||
| 9683 | break :msg msg; | 9738 | break :msg msg; |
| 9684 | }; | 9739 | }); |
| 9685 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 9686 | } | 9740 | } |
| 9687 | } | 9741 | } |
| 9688 | 9742 | ||
| ... | @@ -9743,7 +9797,7 @@ fn funcCommon( | ... | @@ -9743,7 +9797,7 @@ fn funcCommon( |
| 9743 | // default values which are only meaningful for the generic function, *not* | 9797 | // default values which are only meaningful for the generic function, *not* |
| 9744 | // the instantiation, which can depend on comptime parameters. | 9798 | // the instantiation, which can depend on comptime parameters. |
| 9745 | // Related proposal: https://github.com/ziglang/zig/issues/11834 | 9799 | // Related proposal: https://github.com/ziglang/zig/issues/11834 |
| 9746 | const cc_resolved = cc orelse .Unspecified; | 9800 | const cc_resolved = cc orelse .auto; |
| 9747 | var comptime_bits: u32 = 0; | 9801 | var comptime_bits: u32 = 0; |
| 9748 | for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| { | 9802 | for (block.params.items(.ty), block.params.items(.is_comptime), 0..) |param_ty_ip, param_is_comptime, i| { |
| 9749 | const param_ty = Type.fromInterned(param_ty_ip); | 9803 | const param_ty = Type.fromInterned(param_ty_ip); |
| ... | @@ -9761,10 +9815,10 @@ fn funcCommon( | ... | @@ -9761,10 +9815,10 @@ fn funcCommon( |
| 9761 | } | 9815 | } |
| 9762 | const this_generic = param_ty.isGenericPoison(); | 9816 | const this_generic = param_ty.isGenericPoison(); |
| 9763 | is_generic = is_generic or this_generic; | 9817 | is_generic = is_generic or this_generic; |
| 9764 | if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) { | 9818 | if (param_is_comptime and !target_util.fnCallConvAllowsZigTypes(cc_resolved)) { |
| 9765 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); | 9819 | return sema.fail(block, param_src, "comptime parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); |
| 9766 | } | 9820 | } |
| 9767 | if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved)) { | 9821 | if (this_generic and !sema.no_partial_func_ty and !target_util.fnCallConvAllowsZigTypes(cc_resolved)) { |
| 9768 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); | 9822 | return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc_resolved)}); |
| 9769 | } | 9823 | } |
| 9770 | if (!param_ty.isValidParamType(zcu)) { | 9824 | if (!param_ty.isValidParamType(zcu)) { |
| ... | @@ -9773,7 +9827,7 @@ fn funcCommon( | ... | @@ -9773,7 +9827,7 @@ fn funcCommon( |
| 9773 | opaque_str, param_ty.fmt(pt), | 9827 | opaque_str, param_ty.fmt(pt), |
| 9774 | }); | 9828 | }); |
| 9775 | } | 9829 | } |
| 9776 | if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) { | 9830 | if (!this_generic and !target_util.fnCallConvAllowsZigTypes(cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) { |
| 9777 | const msg = msg: { | 9831 | const msg = msg: { |
| 9778 | const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ | 9832 | const msg = try sema.errMsg(param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ |
| 9779 | param_ty.fmt(pt), @tagName(cc_resolved), | 9833 | param_ty.fmt(pt), @tagName(cc_resolved), |
| ... | @@ -9807,15 +9861,24 @@ fn funcCommon( | ... | @@ -9807,15 +9861,24 @@ fn funcCommon( |
| 9807 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); | 9861 | return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{}); |
| 9808 | } | 9862 | } |
| 9809 | switch (cc_resolved) { | 9863 | switch (cc_resolved) { |
| 9810 | .Interrupt => if (target.cpu.arch.isX86()) { | 9864 | .x86_64_interrupt, .x86_interrupt => { |
| 9811 | const err_code_size = target.ptrBitWidth(); | 9865 | const err_code_size = target.ptrBitWidth(); |
| 9812 | switch (i) { | 9866 | switch (i) { |
| 9813 | 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with 'Interrupt' calling convention must be a pointer type", .{}), | 9867 | 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{s}' calling convention must be a pointer type", .{@tagName(cc_resolved)}), |
| 9814 | 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with 'Interrupt' calling convention must be a {d}-bit integer", .{err_code_size}), | 9868 | 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{s}' calling convention must be a {d}-bit integer", .{ @tagName(cc_resolved), err_code_size }), |
| 9815 | else => return sema.fail(block, param_src, "'Interrupt' calling convention supports up to 2 parameters, found {d}", .{i + 1}), | 9869 | else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc_resolved), i + 1 }), |
| 9816 | } | 9870 | } |
| 9817 | } else return sema.fail(block, param_src, "parameters are not allowed with 'Interrupt' calling convention", .{}), | 9871 | }, |
| 9818 | .Signal => return sema.fail(block, param_src, "parameters are not allowed with 'Signal' calling convention", .{}), | 9872 | .arm_interrupt, |
| 9873 | .mips64_interrupt, | ||
| 9874 | .mips_interrupt, | ||
| 9875 | .riscv64_interrupt, | ||
| 9876 | .riscv32_interrupt, | ||
| 9877 | .avr_interrupt, | ||
| 9878 | .csky_interrupt, | ||
| 9879 | .m68k_interrupt, | ||
| 9880 | .avr_signal, | ||
| 9881 | => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc_resolved)}), | ||
| 9819 | else => {}, | 9882 | else => {}, |
| 9820 | } | 9883 | } |
| 9821 | } | 9884 | } |
| ... | @@ -10064,7 +10127,6 @@ fn finishFunc( | ... | @@ -10064,7 +10127,6 @@ fn finishFunc( |
| 10064 | const zcu = pt.zcu; | 10127 | const zcu = pt.zcu; |
| 10065 | const ip = &zcu.intern_pool; | 10128 | const ip = &zcu.intern_pool; |
| 10066 | const gpa = sema.gpa; | 10129 | const gpa = sema.gpa; |
| 10067 | const target = zcu.getTarget(); | ||
| 10068 | 10130 | ||
| 10069 | const return_type: Type = if (opt_func_index == .none or ret_poison) | 10131 | const return_type: Type = if (opt_func_index == .none or ret_poison) |
| 10070 | bare_return_type | 10132 | bare_return_type |
| ... | @@ -10077,7 +10139,7 @@ fn finishFunc( | ... | @@ -10077,7 +10139,7 @@ fn finishFunc( |
| 10077 | opaque_str, return_type.fmt(pt), | 10139 | opaque_str, return_type.fmt(pt), |
| 10078 | }); | 10140 | }); |
| 10079 | } | 10141 | } |
| 10080 | if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and | 10142 | if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(cc_resolved) and |
| 10081 | !try sema.validateExternType(return_type, .ret_ty)) | 10143 | !try sema.validateExternType(return_type, .ret_ty)) |
| 10082 | { | 10144 | { |
| 10083 | const msg = msg: { | 10145 | const msg = msg: { |
| ... | @@ -10133,57 +10195,63 @@ fn finishFunc( | ... | @@ -10133,57 +10195,63 @@ fn finishFunc( |
| 10133 | return sema.failWithOwnedErrorMsg(block, msg); | 10195 | return sema.failWithOwnedErrorMsg(block, msg); |
| 10134 | } | 10196 | } |
| 10135 | 10197 | ||
| 10198 | validate_incoming_stack_align: { | ||
| 10199 | const a: u64 = switch (cc_resolved) { | ||
| 10200 | inline else => |payload| if (@TypeOf(payload) != void and @hasField(@TypeOf(payload), "incoming_stack_alignment")) | ||
| 10201 | payload.incoming_stack_alignment orelse break :validate_incoming_stack_align | ||
| 10202 | else | ||
| 10203 | break :validate_incoming_stack_align, | ||
| 10204 | }; | ||
| 10205 | if (!std.math.isPowerOfTwo(a)) { | ||
| 10206 | return sema.fail(block, cc_src, "calling convention incoming stack alignment '{d}' is not a power of two", .{a}); | ||
| 10207 | } | ||
| 10208 | } | ||
| 10209 | |||
| 10136 | switch (cc_resolved) { | 10210 | switch (cc_resolved) { |
| 10137 | .Interrupt, .Signal => if (return_type.zigTypeTag(zcu) != .void and return_type.zigTypeTag(zcu) != .noreturn) { | 10211 | .x86_64_interrupt, |
| 10212 | .x86_interrupt, | ||
| 10213 | .arm_interrupt, | ||
| 10214 | .mips64_interrupt, | ||
| 10215 | .mips_interrupt, | ||
| 10216 | .riscv64_interrupt, | ||
| 10217 | .riscv32_interrupt, | ||
| 10218 | .avr_interrupt, | ||
| 10219 | .csky_interrupt, | ||
| 10220 | .m68k_interrupt, | ||
| 10221 | .avr_signal, | ||
| 10222 | => if (return_type.zigTypeTag(zcu) != .void and return_type.zigTypeTag(zcu) != .noreturn) { | ||
| 10138 | return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(cc_resolved)}); | 10223 | return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(cc_resolved)}); |
| 10139 | }, | 10224 | }, |
| 10140 | .Inline => if (is_noinline) { | 10225 | .@"inline" => if (is_noinline) { |
| 10141 | return sema.fail(block, cc_src, "'noinline' function cannot have callconv 'Inline'", .{}); | 10226 | return sema.fail(block, cc_src, "'noinline' function cannot have calling convention 'inline'", .{}); |
| 10142 | }, | 10227 | }, |
| 10143 | else => {}, | 10228 | else => {}, |
| 10144 | } | 10229 | } |
| 10145 | 10230 | ||
| 10146 | const arch = target.cpu.arch; | 10231 | switch (zcu.callconvSupported(cc_resolved)) { |
| 10147 | if (@as(?[]const u8, switch (cc_resolved) { | 10232 | .ok => {}, |
| 10148 | .Unspecified, .C, .Naked, .Async, .Inline => null, | 10233 | .bad_arch => |allowed_archs| { |
| 10149 | .Interrupt => switch (arch) { | 10234 | const ArchListFormatter = struct { |
| 10150 | .x86, .x86_64, .avr, .msp430 => null, | 10235 | archs: []const std.Target.Cpu.Arch, |
| 10151 | else => "x86, x86_64, AVR, and MSP430", | 10236 | pub fn format(formatter: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { |
| 10152 | }, | 10237 | _ = fmt; |
| 10153 | .Signal => switch (arch) { | 10238 | _ = options; |
| 10154 | .avr => null, | 10239 | for (formatter.archs, 0..) |arch, i| { |
| 10155 | else => "AVR", | 10240 | if (i != 0) |
| 10156 | }, | 10241 | try writer.writeAll(", "); |
| 10157 | .Stdcall, .Fastcall, .Thiscall => switch (arch) { | 10242 | try writer.print("'{s}'", .{@tagName(arch)}); |
| 10158 | .x86 => null, | 10243 | } |
| 10159 | else => "x86", | 10244 | } |
| 10160 | }, | 10245 | }; |
| 10161 | .Vectorcall => switch (arch) { | 10246 | return sema.fail(block, cc_src, "calling convention '{s}' only available on architectures {}", .{ |
| 10162 | .x86, .aarch64, .aarch64_be => null, | 10247 | @tagName(cc_resolved), |
| 10163 | else => "x86 and AArch64", | 10248 | ArchListFormatter{ .archs = allowed_archs }, |
| 10164 | }, | 10249 | }); |
| 10165 | .APCS, .AAPCS, .AAPCSVFP => switch (arch) { | 10250 | }, |
| 10166 | .arm, .armeb, .aarch64, .aarch64_be, .thumb, .thumbeb => null, | 10251 | .bad_backend => |bad_backend| return sema.fail(block, cc_src, "calling convention '{s}' not supported by compiler backend '{s}'", .{ |
| 10167 | else => "ARM", | ||
| 10168 | }, | ||
| 10169 | .SysV, .Win64 => switch (arch) { | ||
| 10170 | .x86_64 => null, | ||
| 10171 | else => "x86_64", | ||
| 10172 | }, | ||
| 10173 | .Kernel => switch (arch) { | ||
| 10174 | .nvptx, .nvptx64, .amdgcn, .spirv, .spirv32, .spirv64 => null, | ||
| 10175 | else => "nvptx, amdgcn and SPIR-V", | ||
| 10176 | }, | ||
| 10177 | .Fragment, .Vertex => switch (arch) { | ||
| 10178 | .spirv, .spirv32, .spirv64 => null, | ||
| 10179 | else => "SPIR-V", | ||
| 10180 | }, | ||
| 10181 | })) |allowed_platform| { | ||
| 10182 | return sema.fail(block, cc_src, "callconv '{s}' is only available on {s}, not {s}", .{ | ||
| 10183 | @tagName(cc_resolved), | 10252 | @tagName(cc_resolved), |
| 10184 | allowed_platform, | 10253 | @tagName(bad_backend), |
| 10185 | @tagName(arch), | 10254 | }), |
| 10186 | }); | ||
| 10187 | } | 10255 | } |
| 10188 | 10256 | ||
| 10189 | if (is_generic and sema.no_partial_func_ty) return error.GenericPoison; | 10257 | if (is_generic and sema.no_partial_func_ty) return error.GenericPoison; |
| ... | @@ -18342,10 +18410,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -18342,10 +18410,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 18342 | } }); | 18410 | } }); |
| 18343 | 18411 | ||
| 18344 | const callconv_ty = try sema.getBuiltinType("CallingConvention"); | 18412 | const callconv_ty = try sema.getBuiltinType("CallingConvention"); |
| 18413 | const callconv_val = Value.uninterpret(func_ty_info.cc, callconv_ty, pt) catch |err| switch (err) { | ||
| 18414 | error.TypeMismatch => @panic("std.builtin is corrupt"), | ||
| 18415 | error.OutOfMemory => |e| return e, | ||
| 18416 | }; | ||
| 18345 | 18417 | ||
| 18346 | const field_values = .{ | 18418 | const field_values: [5]InternPool.Index = .{ |
| 18347 | // calling_convention: CallingConvention, | 18419 | // calling_convention: CallingConvention, |
| 18348 | (try pt.enumValueFieldIndex(callconv_ty, @intFromEnum(func_ty_info.cc))).toIntern(), | 18420 | callconv_val.toIntern(), |
| 18349 | // is_generic: bool, | 18421 | // is_generic: bool, |
| 18350 | Value.makeBool(func_ty_info.is_generic).toIntern(), | 18422 | Value.makeBool(func_ty_info.is_generic).toIntern(), |
| 18351 | // is_var_args: bool, | 18423 | // is_var_args: bool, |
| ... | @@ -22171,7 +22243,7 @@ fn zirReify( | ... | @@ -22171,7 +22243,7 @@ fn zirReify( |
| 22171 | } | 22243 | } |
| 22172 | 22244 | ||
| 22173 | const is_var_args = is_var_args_val.toBool(); | 22245 | const is_var_args = is_var_args_val.toBool(); |
| 22174 | const cc = zcu.toEnum(std.builtin.CallingConvention, calling_convention_val); | 22246 | const cc = try sema.analyzeValueAsCallconv(block, src, calling_convention_val); |
| 22175 | if (is_var_args) { | 22247 | if (is_var_args) { |
| 22176 | try sema.checkCallConvSupportsVarArgs(block, src, cc); | 22248 | try sema.checkCallConvSupportsVarArgs(block, src, cc); |
| 22177 | } | 22249 | } |
| ... | @@ -26670,7 +26742,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -26670,7 +26742,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26670 | if (val.isGenericPoison()) { | 26742 | if (val.isGenericPoison()) { |
| 26671 | break :blk null; | 26743 | break :blk null; |
| 26672 | } | 26744 | } |
| 26673 | break :blk zcu.toEnum(std.builtin.CallingConvention, val); | 26745 | break :blk try sema.analyzeValueAsCallconv(block, cc_src, val); |
| 26674 | } else if (extra.data.bits.has_cc_ref) blk: { | 26746 | } else if (extra.data.bits.has_cc_ref) blk: { |
| 26675 | const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); | 26747 | const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]); |
| 26676 | extra_index += 1; | 26748 | extra_index += 1; |
| ... | @@ -26689,7 +26761,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -26689,7 +26761,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26689 | error.GenericPoison => break :blk null, | 26761 | error.GenericPoison => break :blk null, |
| 26690 | else => |e| return e, | 26762 | else => |e| return e, |
| 26691 | }; | 26763 | }; |
| 26692 | break :blk zcu.toEnum(std.builtin.CallingConvention, cc_val); | 26764 | break :blk try sema.analyzeValueAsCallconv(block, cc_src, cc_val); |
| 26693 | } else cc: { | 26765 | } else cc: { |
| 26694 | if (has_body) { | 26766 | if (has_body) { |
| 26695 | const decl_inst = if (sema.generic_owner != .none) decl_inst: { | 26767 | const decl_inst = if (sema.generic_owner != .none) decl_inst: { |
| ... | @@ -26705,7 +26777,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -26705,7 +26777,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 26705 | break :cc .C; | 26777 | break :cc .C; |
| 26706 | } | 26778 | } |
| 26707 | } | 26779 | } |
| 26708 | break :cc .Unspecified; | 26780 | break :cc .auto; |
| 26709 | }; | 26781 | }; |
| 26710 | 26782 | ||
| 26711 | const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: { | 26783 | const ret_ty: Type = if (extra.data.bits.has_ret_ty_body) blk: { |
| ... | @@ -27132,9 +27204,15 @@ fn zirInComptime( | ... | @@ -27132,9 +27204,15 @@ fn zirInComptime( |
| 27132 | return if (block.is_comptime) .bool_true else .bool_false; | 27204 | return if (block.is_comptime) .bool_true else .bool_false; |
| 27133 | } | 27205 | } |
| 27134 | 27206 | ||
| 27135 | fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 27207 | fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 27136 | const pt = sema.pt; | 27208 | const pt = sema.pt; |
| 27209 | const zcu = pt.zcu; | ||
| 27210 | const gpa = zcu.gpa; | ||
| 27211 | const ip = &zcu.intern_pool; | ||
| 27212 | |||
| 27213 | const src = block.nodeOffset(@bitCast(extended.operand)); | ||
| 27137 | const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); | 27214 | const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small); |
| 27215 | |||
| 27138 | const type_name = switch (value) { | 27216 | const type_name = switch (value) { |
| 27139 | .atomic_order => "AtomicOrder", | 27217 | .atomic_order => "AtomicOrder", |
| 27140 | .atomic_rmw_op => "AtomicRmwOp", | 27218 | .atomic_rmw_op => "AtomicRmwOp", |
| ... | @@ -27152,21 +27230,25 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr | ... | @@ -27152,21 +27230,25 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr |
| 27152 | // Values are handled here. | 27230 | // Values are handled here. |
| 27153 | .calling_convention_c => { | 27231 | .calling_convention_c => { |
| 27154 | const callconv_ty = try sema.getBuiltinType("CallingConvention"); | 27232 | const callconv_ty = try sema.getBuiltinType("CallingConvention"); |
| 27155 | comptime assert(@intFromEnum(std.builtin.CallingConvention.C) == 1); | 27233 | return try sema.namespaceLookupVal( |
| 27156 | const val = try pt.intern(.{ .enum_tag = .{ | 27234 | block, |
| 27157 | .ty = callconv_ty.toIntern(), | 27235 | src, |
| 27158 | .int = .one_u8, | 27236 | callconv_ty.getNamespaceIndex(zcu), |
| 27159 | } }); | 27237 | try ip.getOrPutString(gpa, pt.tid, "c", .no_embedded_nulls), |
| 27160 | return Air.internedToRef(val); | 27238 | ) orelse @panic("std.builtin is corrupt"); |
| 27161 | }, | 27239 | }, |
| 27162 | .calling_convention_inline => { | 27240 | .calling_convention_inline => { |
| 27241 | comptime assert(@typeInfo(std.builtin.CallingConvention.Tag).@"enum".tag_type == u8); | ||
| 27163 | const callconv_ty = try sema.getBuiltinType("CallingConvention"); | 27242 | const callconv_ty = try sema.getBuiltinType("CallingConvention"); |
| 27164 | comptime assert(@intFromEnum(std.builtin.CallingConvention.Inline) == 4); | 27243 | const callconv_tag_ty = callconv_ty.unionTagType(zcu) orelse @panic("std.builtin is corrupt"); |
| 27165 | const val = try pt.intern(.{ .enum_tag = .{ | 27244 | const inline_tag_val = try pt.enumValue( |
| 27166 | .ty = callconv_ty.toIntern(), | 27245 | callconv_tag_ty, |
| 27167 | .int = .four_u8, | 27246 | (try pt.intValue( |
| 27168 | } }); | 27247 | Type.u8, |
| 27169 | return Air.internedToRef(val); | 27248 | @intFromEnum(std.builtin.CallingConvention.@"inline"), |
| 27249 | )).toIntern(), | ||
| 27250 | ); | ||
| 27251 | return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src); | ||
| 27170 | }, | 27252 | }, |
| 27171 | }; | 27253 | }; |
| 27172 | const ty = try sema.getBuiltinType(type_name); | 27254 | const ty = try sema.getBuiltinType(type_name); |
| ... | @@ -27353,7 +27435,7 @@ fn explainWhyTypeIsComptimeInner( | ... | @@ -27353,7 +27435,7 @@ fn explainWhyTypeIsComptimeInner( |
| 27353 | try sema.errNote(src_loc, msg, "function is generic", .{}); | 27435 | try sema.errNote(src_loc, msg, "function is generic", .{}); |
| 27354 | } | 27436 | } |
| 27355 | switch (fn_info.cc) { | 27437 | switch (fn_info.cc) { |
| 27356 | .Inline => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}), | 27438 | .@"inline" => try sema.errNote(src_loc, msg, "function has inline calling convention", .{}), |
| 27357 | else => {}, | 27439 | else => {}, |
| 27358 | } | 27440 | } |
| 27359 | if (Type.fromInterned(fn_info.return_type).comptimeOnly(zcu)) { | 27441 | if (Type.fromInterned(fn_info.return_type).comptimeOnly(zcu)) { |
| ... | @@ -27461,13 +27543,12 @@ fn validateExternType( | ... | @@ -27461,13 +27543,12 @@ fn validateExternType( |
| 27461 | }, | 27543 | }, |
| 27462 | .@"fn" => { | 27544 | .@"fn" => { |
| 27463 | if (position != .other) return false; | 27545 | if (position != .other) return false; |
| 27464 | const target = zcu.getTarget(); | ||
| 27465 | // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI. | 27546 | // For now we want to authorize PTX kernel to use zig objects, even if we end up exposing the ABI. |
| 27466 | // The goal is to experiment with more integrated CPU/GPU code. | 27547 | // The goal is to experiment with more integrated CPU/GPU code. |
| 27467 | if (ty.fnCallingConvention(zcu) == .Kernel and (target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64)) { | 27548 | if (ty.fnCallingConvention(zcu) == .nvptx_kernel) { |
| 27468 | return true; | 27549 | return true; |
| 27469 | } | 27550 | } |
| 27470 | return !target_util.fnCallConvAllowsZigTypes(target, ty.fnCallingConvention(zcu)); | 27551 | return !target_util.fnCallConvAllowsZigTypes(ty.fnCallingConvention(zcu)); |
| 27471 | }, | 27552 | }, |
| 27472 | .@"enum" => { | 27553 | .@"enum" => { |
| 27473 | return sema.validateExternType(ty.intTagType(zcu), position); | 27554 | return sema.validateExternType(ty.intTagType(zcu), position); |
| ... | @@ -27547,9 +27628,9 @@ fn explainWhyTypeIsNotExtern( | ... | @@ -27547,9 +27628,9 @@ fn explainWhyTypeIsNotExtern( |
| 27547 | return; | 27628 | return; |
| 27548 | } | 27629 | } |
| 27549 | switch (ty.fnCallingConvention(zcu)) { | 27630 | switch (ty.fnCallingConvention(zcu)) { |
| 27550 | .Unspecified => try sema.errNote(src_loc, msg, "extern function must specify calling convention", .{}), | 27631 | .auto => try sema.errNote(src_loc, msg, "extern function must specify calling convention", .{}), |
| 27551 | .Async => try sema.errNote(src_loc, msg, "async function cannot be extern", .{}), | 27632 | .@"async" => try sema.errNote(src_loc, msg, "async function cannot be extern", .{}), |
| 27552 | .Inline => try sema.errNote(src_loc, msg, "inline function cannot be extern", .{}), | 27633 | .@"inline" => try sema.errNote(src_loc, msg, "inline function cannot be extern", .{}), |
| 27553 | else => return, | 27634 | else => return, |
| 27554 | } | 27635 | } |
| 27555 | }, | 27636 | }, |
| ... | @@ -31176,8 +31257,8 @@ fn coerceInMemoryAllowedFns( | ... | @@ -31176,8 +31257,8 @@ fn coerceInMemoryAllowedFns( |
| 31176 | return InMemoryCoercionResult{ .fn_generic = dest_info.is_generic }; | 31257 | return InMemoryCoercionResult{ .fn_generic = dest_info.is_generic }; |
| 31177 | } | 31258 | } |
| 31178 | 31259 | ||
| 31179 | if (dest_info.cc != src_info.cc) { | 31260 | if (!callconvCoerceAllowed(target, src_info.cc, dest_info.cc)) { |
| 31180 | return InMemoryCoercionResult{ .fn_cc = .{ | 31261 | return .{ .fn_cc = .{ |
| 31181 | .actual = src_info.cc, | 31262 | .actual = src_info.cc, |
| 31182 | .wanted = dest_info.cc, | 31263 | .wanted = dest_info.cc, |
| 31183 | } }; | 31264 | } }; |
| ... | @@ -31250,6 +31331,44 @@ fn coerceInMemoryAllowedFns( | ... | @@ -31250,6 +31331,44 @@ fn coerceInMemoryAllowedFns( |
| 31250 | return .ok; | 31331 | return .ok; |
| 31251 | } | 31332 | } |
| 31252 | 31333 | ||
| 31334 | fn callconvCoerceAllowed( | ||
| 31335 | target: std.Target, | ||
| 31336 | src_cc: std.builtin.CallingConvention, | ||
| 31337 | dest_cc: std.builtin.CallingConvention, | ||
| 31338 | ) bool { | ||
| 31339 | const Tag = std.builtin.CallingConvention.Tag; | ||
| 31340 | if (@as(Tag, src_cc) != @as(Tag, dest_cc)) return false; | ||
| 31341 | |||
| 31342 | switch (src_cc) { | ||
| 31343 | inline else => |src_data, tag| { | ||
| 31344 | const dest_data = @field(dest_cc, @tagName(tag)); | ||
| 31345 | if (@TypeOf(src_data) != void) { | ||
| 31346 | const default_stack_align = target.stackAlignment(); | ||
| 31347 | const src_stack_align = src_data.incoming_stack_alignment orelse default_stack_align; | ||
| 31348 | const dest_stack_align = src_data.incoming_stack_alignment orelse default_stack_align; | ||
| 31349 | if (dest_stack_align < src_stack_align) return false; | ||
| 31350 | } | ||
| 31351 | switch (@TypeOf(src_data)) { | ||
| 31352 | void, std.builtin.CallingConvention.CommonOptions => {}, | ||
| 31353 | std.builtin.CallingConvention.X86RegparmOptions => { | ||
| 31354 | if (src_data.register_params != dest_data.register_params) return false; | ||
| 31355 | }, | ||
| 31356 | std.builtin.CallingConvention.ArmInterruptOptions => { | ||
| 31357 | if (src_data.type != dest_data.type) return false; | ||
| 31358 | }, | ||
| 31359 | std.builtin.CallingConvention.MipsInterruptOptions => { | ||
| 31360 | if (src_data.mode != dest_data.mode) return false; | ||
| 31361 | }, | ||
| 31362 | std.builtin.CallingConvention.RiscvInterruptOptions => { | ||
| 31363 | if (src_data.mode != dest_data.mode) return false; | ||
| 31364 | }, | ||
| 31365 | else => comptime unreachable, | ||
| 31366 | } | ||
| 31367 | }, | ||
| 31368 | } | ||
| 31369 | return true; | ||
| 31370 | } | ||
| 31371 | |||
| 31253 | fn coerceInMemoryAllowedPtrs( | 31372 | fn coerceInMemoryAllowedPtrs( |
| 31254 | sema: *Sema, | 31373 | sema: *Sema, |
| 31255 | block: *Block, | 31374 | block: *Block, |
| ... | @@ -36306,7 +36425,7 @@ fn resolveInferredErrorSet( | ... | @@ -36306,7 +36425,7 @@ fn resolveInferredErrorSet( |
| 36306 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, | 36425 | // because inline function does not create a new declaration, and the ies has been filled with analyzeCall, |
| 36307 | // so here we can simply skip this case. | 36426 | // so here we can simply skip this case. |
| 36308 | if (ies_func_info.return_type == .generic_poison_type) { | 36427 | if (ies_func_info.return_type == .generic_poison_type) { |
| 36309 | assert(ies_func_info.cc == .Inline); | 36428 | assert(ies_func_info.cc == .@"inline"); |
| 36310 | } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) { | 36429 | } else if (ip.errorUnionSet(ies_func_info.return_type) == ies_index) { |
| 36311 | if (ies_func_info.is_generic) { | 36430 | if (ies_func_info.is_generic) { |
| 36312 | return sema.failWithOwnedErrorMsg(block, msg: { | 36431 | return sema.failWithOwnedErrorMsg(block, msg: { |
src/Type.zig+12-5| ... | @@ -390,10 +390,17 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error | ... | @@ -390,10 +390,17 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error |
| 390 | try writer.writeAll("..."); | 390 | try writer.writeAll("..."); |
| 391 | } | 391 | } |
| 392 | try writer.writeAll(") "); | 392 | try writer.writeAll(") "); |
| 393 | if (fn_info.cc != .Unspecified) { | 393 | if (fn_info.cc != .auto) print_cc: { |
| 394 | try writer.writeAll("callconv(."); | 394 | if (zcu.getTarget().cCallingConvention()) |ccc| { |
| 395 | try writer.writeAll(@tagName(fn_info.cc)); | 395 | if (fn_info.cc.eql(ccc)) { |
| 396 | try writer.writeAll(") "); | 396 | try writer.writeAll("callconv(.c) "); |
| 397 | break :print_cc; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | switch (fn_info.cc) { | ||
| 401 | .auto, .@"async", .naked, .@"inline" => try writer.print("callconv(.{}) ", .{std.zig.fmtId(@tagName(fn_info.cc))}), | ||
| 402 | else => try writer.print("callconv({any}) ", .{fn_info.cc}), | ||
| 403 | } | ||
| 397 | } | 404 | } |
| 398 | if (fn_info.return_type == .generic_poison_type) { | 405 | if (fn_info.return_type == .generic_poison_type) { |
| 399 | try writer.writeAll("anytype"); | 406 | try writer.writeAll("anytype"); |
| ... | @@ -791,7 +798,7 @@ pub fn fnHasRuntimeBitsInner( | ... | @@ -791,7 +798,7 @@ pub fn fnHasRuntimeBitsInner( |
| 791 | const fn_info = zcu.typeToFunc(ty).?; | 798 | const fn_info = zcu.typeToFunc(ty).?; |
| 792 | if (fn_info.is_generic) return false; | 799 | if (fn_info.is_generic) return false; |
| 793 | if (fn_info.is_var_args) return true; | 800 | if (fn_info.is_var_args) return true; |
| 794 | if (fn_info.cc == .Inline) return false; | 801 | if (fn_info.cc == .@"inline") return false; |
| 795 | return !try Type.fromInterned(fn_info.return_type).comptimeOnlyInner(strat, zcu, tid); | 802 | return !try Type.fromInterned(fn_info.return_type).comptimeOnlyInner(strat, zcu, tid); |
| 796 | } | 803 | } |
| 797 | 804 |
src/Value.zig+156| ... | @@ -4490,3 +4490,159 @@ pub fn resolveLazy( | ... | @@ -4490,3 +4490,159 @@ pub fn resolveLazy( |
| 4490 | else => return val, | 4490 | else => return val, |
| 4491 | } | 4491 | } |
| 4492 | } | 4492 | } |
| 4493 | |||
| 4494 | /// Given a `Value` representing a comptime-known value of type `T`, unwrap it into an actual `T` known to the compiler. | ||
| 4495 | /// This is useful for accessing `std.builtin` structures received from comptime logic. | ||
| 4496 | /// `val` must be fully resolved. | ||
| 4497 | pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMemory, UndefinedValue, TypeMismatch }!T { | ||
| 4498 | const zcu = pt.zcu; | ||
| 4499 | const ip = &zcu.intern_pool; | ||
| 4500 | const ty = val.typeOf(zcu); | ||
| 4501 | if (ty.zigTypeTag(zcu) != @typeInfo(T)) return error.TypeMismatch; | ||
| 4502 | if (val.isUndef(zcu)) return error.UndefinedValue; | ||
| 4503 | |||
| 4504 | return switch (@typeInfo(T)) { | ||
| 4505 | .type, | ||
| 4506 | .noreturn, | ||
| 4507 | .comptime_float, | ||
| 4508 | .comptime_int, | ||
| 4509 | .undefined, | ||
| 4510 | .null, | ||
| 4511 | .@"fn", | ||
| 4512 | .@"opaque", | ||
| 4513 | .enum_literal, | ||
| 4514 | => comptime unreachable, // comptime-only or otherwise impossible | ||
| 4515 | |||
| 4516 | .pointer, | ||
| 4517 | .array, | ||
| 4518 | .error_union, | ||
| 4519 | .error_set, | ||
| 4520 | .frame, | ||
| 4521 | .@"anyframe", | ||
| 4522 | .vector, | ||
| 4523 | => comptime unreachable, // unsupported | ||
| 4524 | |||
| 4525 | .void => {}, | ||
| 4526 | |||
| 4527 | .bool => switch (val.toIntern()) { | ||
| 4528 | .bool_false => false, | ||
| 4529 | .bool_true => true, | ||
| 4530 | else => unreachable, | ||
| 4531 | }, | ||
| 4532 | |||
| 4533 | .int => switch (ip.indexToKey(val.toIntern()).int.storage) { | ||
| 4534 | .lazy_align, .lazy_size => unreachable, // `val` is fully resolved | ||
| 4535 | inline .u64, .i64 => |x| std.math.cast(T, x) orelse return error.TypeMismatch, | ||
| 4536 | .big_int => |big| big.to(T) catch return error.TypeMismatch, | ||
| 4537 | }, | ||
| 4538 | |||
| 4539 | .float => val.toFloat(T, zcu), | ||
| 4540 | |||
| 4541 | .optional => |opt| if (val.optionalValue(zcu)) |unwrapped| | ||
| 4542 | try unwrapped.interpret(opt.child, pt) | ||
| 4543 | else | ||
| 4544 | null, | ||
| 4545 | |||
| 4546 | .@"enum" => zcu.toEnum(T, val), | ||
| 4547 | |||
| 4548 | .@"union" => |@"union"| { | ||
| 4549 | const union_obj = zcu.typeToUnion(ty) orelse return error.TypeMismatch; | ||
| 4550 | if (union_obj.field_types.len != @"union".fields.len) return error.TypeMismatch; | ||
| 4551 | const tag_val = val.unionTag(zcu) orelse return error.TypeMismatch; | ||
| 4552 | const tag = try tag_val.interpret(@"union".tag_type.?, pt); | ||
| 4553 | return switch (tag) { | ||
| 4554 | inline else => |tag_comptime| @unionInit( | ||
| 4555 | T, | ||
| 4556 | @tagName(tag_comptime), | ||
| 4557 | try val.unionValue(zcu).interpret(@FieldType(T, @tagName(tag_comptime)), pt), | ||
| 4558 | ), | ||
| 4559 | }; | ||
| 4560 | }, | ||
| 4561 | |||
| 4562 | .@"struct" => |@"struct"| { | ||
| 4563 | if (ty.structFieldCount(zcu) != @"struct".fields.len) return error.TypeMismatch; | ||
| 4564 | var result: T = undefined; | ||
| 4565 | inline for (@"struct".fields, 0..) |field, field_idx| { | ||
| 4566 | const field_val = try val.fieldValue(pt, field_idx); | ||
| 4567 | @field(result, field.name) = try field_val.interpret(field.type, pt); | ||
| 4568 | } | ||
| 4569 | return result; | ||
| 4570 | }, | ||
| 4571 | }; | ||
| 4572 | } | ||
| 4573 | |||
| 4574 | /// Given any `val` and a `Type` corresponding `@TypeOf(val)`, construct a `Value` representing it which can be used | ||
| 4575 | /// within the compilation. This is useful for passing `std.builtin` structures in the compiler back to the compilation. | ||
| 4576 | /// This is the inverse of `interpret`. | ||
| 4577 | pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory, TypeMismatch }!Value { | ||
| 4578 | const T = @TypeOf(val); | ||
| 4579 | |||
| 4580 | const zcu = pt.zcu; | ||
| 4581 | if (ty.zigTypeTag(zcu) != @typeInfo(T)) return error.TypeMismatch; | ||
| 4582 | |||
| 4583 | return switch (@typeInfo(T)) { | ||
| 4584 | .type, | ||
| 4585 | .noreturn, | ||
| 4586 | .comptime_float, | ||
| 4587 | .comptime_int, | ||
| 4588 | .undefined, | ||
| 4589 | .null, | ||
| 4590 | .@"fn", | ||
| 4591 | .@"opaque", | ||
| 4592 | .enum_literal, | ||
| 4593 | => comptime unreachable, // comptime-only or otherwise impossible | ||
| 4594 | |||
| 4595 | .pointer, | ||
| 4596 | .array, | ||
| 4597 | .error_union, | ||
| 4598 | .error_set, | ||
| 4599 | .frame, | ||
| 4600 | .@"anyframe", | ||
| 4601 | .vector, | ||
| 4602 | => comptime unreachable, // unsupported | ||
| 4603 | |||
| 4604 | .void => .void, | ||
| 4605 | |||
| 4606 | .bool => if (val) .true else .false, | ||
| 4607 | |||
| 4608 | .int => try pt.intValue(ty, val), | ||
| 4609 | |||
| 4610 | .float => try pt.floatValue(ty, val), | ||
| 4611 | |||
| 4612 | .optional => if (val) |some| | ||
| 4613 | .fromInterned(try pt.intern(.{ .opt = .{ | ||
| 4614 | .ty = ty.toIntern(), | ||
| 4615 | .val = (try uninterpret(some, ty.optionalChild(zcu), pt)).toIntern(), | ||
| 4616 | } })) | ||
| 4617 | else | ||
| 4618 | try pt.nullValue(ty), | ||
| 4619 | |||
| 4620 | .@"enum" => try pt.enumValue(ty, (try uninterpret(@intFromEnum(val), ty.intTagType(zcu), pt)).toIntern()), | ||
| 4621 | |||
| 4622 | .@"union" => |@"union"| { | ||
| 4623 | const tag: @"union".tag_type.? = val; | ||
| 4624 | const tag_val = try uninterpret(tag, ty.unionTagType(zcu).?, pt); | ||
| 4625 | const field_ty = ty.unionFieldType(tag_val, zcu) orelse return error.TypeMismatch; | ||
| 4626 | return switch (val) { | ||
| 4627 | inline else => |payload| try pt.unionValue( | ||
| 4628 | ty, | ||
| 4629 | tag_val, | ||
| 4630 | try uninterpret(payload, field_ty, pt), | ||
| 4631 | ), | ||
| 4632 | }; | ||
| 4633 | }, | ||
| 4634 | |||
| 4635 | .@"struct" => |@"struct"| { | ||
| 4636 | if (ty.structFieldCount(zcu) != @"struct".fields.len) return error.TypeMismatch; | ||
| 4637 | var field_vals: [@"struct".fields.len]InternPool.Index = undefined; | ||
| 4638 | inline for (&field_vals, @"struct".fields, 0..) |*field_val, field, field_idx| { | ||
| 4639 | const field_ty = ty.fieldType(field_idx, zcu); | ||
| 4640 | field_val.* = (try uninterpret(@field(val, field.name), field_ty, pt)).toIntern(); | ||
| 4641 | } | ||
| 4642 | return .fromInterned(try pt.intern(.{ .aggregate = .{ | ||
| 4643 | .ty = ty.toIntern(), | ||
| 4644 | .storage = .{ .elems = &field_vals }, | ||
| 4645 | } })); | ||
| 4646 | }, | ||
| 4647 | }; | ||
| 4648 | } |
src/Zcu.zig+108| ... | @@ -3539,3 +3539,111 @@ pub fn maybeUnresolveIes(zcu: *Zcu, func_index: InternPool.Index) !void { | ... | @@ -3539,3 +3539,111 @@ pub fn maybeUnresolveIes(zcu: *Zcu, func_index: InternPool.Index) !void { |
| 3539 | zcu.intern_pool.funcSetIesResolved(func_index, .none); | 3539 | zcu.intern_pool.funcSetIesResolved(func_index, .none); |
| 3540 | } | 3540 | } |
| 3541 | } | 3541 | } |
| 3542 | |||
| 3543 | pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enum) { | ||
| 3544 | ok, | ||
| 3545 | bad_arch: []const std.Target.Cpu.Arch, // value is allowed archs for cc | ||
| 3546 | bad_backend: std.builtin.CompilerBackend, // value is current backend | ||
| 3547 | } { | ||
| 3548 | const target = zcu.getTarget(); | ||
| 3549 | const backend = target_util.zigBackend(target, zcu.comp.config.use_llvm); | ||
| 3550 | switch (cc) { | ||
| 3551 | .auto, .@"inline" => return .ok, | ||
| 3552 | .@"async" => return .{ .bad_backend = backend }, // nothing supports async currently | ||
| 3553 | .naked => {}, // depends only on backend | ||
| 3554 | else => for (cc.archs()) |allowed_arch| { | ||
| 3555 | if (allowed_arch == target.cpu.arch) break; | ||
| 3556 | } else return .{ .bad_arch = cc.archs() }, | ||
| 3557 | } | ||
| 3558 | const backend_ok = switch (backend) { | ||
| 3559 | .stage1 => unreachable, | ||
| 3560 | .other => unreachable, | ||
| 3561 | _ => unreachable, | ||
| 3562 | |||
| 3563 | .stage2_llvm => @import("codegen/llvm.zig").toLlvmCallConv(cc, target) != null, | ||
| 3564 | .stage2_c => ok: { | ||
| 3565 | if (target.cCallingConvention()) |default_c| { | ||
| 3566 | if (cc.eql(default_c)) { | ||
| 3567 | break :ok true; | ||
| 3568 | } | ||
| 3569 | } | ||
| 3570 | break :ok switch (cc) { | ||
| 3571 | .x86_64_sysv, | ||
| 3572 | .x86_64_win, | ||
| 3573 | .x86_64_vectorcall, | ||
| 3574 | .x86_64_regcall_v3_sysv, | ||
| 3575 | .x86_64_regcall_v4_win, | ||
| 3576 | .x86_fastcall, | ||
| 3577 | .x86_thiscall, | ||
| 3578 | .x86_vectorcall, | ||
| 3579 | .x86_regcall_v3, | ||
| 3580 | .x86_regcall_v4_win, | ||
| 3581 | .aarch64_vfabi, | ||
| 3582 | .aarch64_vfabi_sve, | ||
| 3583 | .arm_aapcs, | ||
| 3584 | .arm_aapcs_vfp, | ||
| 3585 | .riscv64_lp64_v, | ||
| 3586 | .riscv32_ilp32_v, | ||
| 3587 | .m68k_rtd, | ||
| 3588 | => |opts| opts.incoming_stack_alignment == null, | ||
| 3589 | |||
| 3590 | .x86_sysv, | ||
| 3591 | .x86_win, | ||
| 3592 | .x86_stdcall, | ||
| 3593 | => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0, | ||
| 3594 | |||
| 3595 | .naked => true, | ||
| 3596 | |||
| 3597 | else => false, | ||
| 3598 | }; | ||
| 3599 | }, | ||
| 3600 | .stage2_wasm => switch (cc) { | ||
| 3601 | .wasm_watc => |opts| opts.incoming_stack_alignment == null, | ||
| 3602 | else => false, | ||
| 3603 | }, | ||
| 3604 | .stage2_arm => switch (cc) { | ||
| 3605 | .arm_aapcs => |opts| opts.incoming_stack_alignment == null, | ||
| 3606 | .naked => true, | ||
| 3607 | else => false, | ||
| 3608 | }, | ||
| 3609 | .stage2_x86_64 => switch (cc) { | ||
| 3610 | .x86_64_sysv, .x86_64_win, .naked => true, // incoming stack alignment supported | ||
| 3611 | else => false, | ||
| 3612 | }, | ||
| 3613 | .stage2_aarch64 => switch (cc) { | ||
| 3614 | .aarch64_aapcs, | ||
| 3615 | .aarch64_aapcs_darwin, | ||
| 3616 | .aarch64_aapcs_win, | ||
| 3617 | => |opts| opts.incoming_stack_alignment == null, | ||
| 3618 | .naked => true, | ||
| 3619 | else => false, | ||
| 3620 | }, | ||
| 3621 | .stage2_x86 => switch (cc) { | ||
| 3622 | .x86_sysv, | ||
| 3623 | .x86_win, | ||
| 3624 | => |opts| opts.incoming_stack_alignment == null and opts.register_params == 0, | ||
| 3625 | .naked => true, | ||
| 3626 | else => false, | ||
| 3627 | }, | ||
| 3628 | .stage2_riscv64 => switch (cc) { | ||
| 3629 | .riscv64_lp64 => |opts| opts.incoming_stack_alignment == null, | ||
| 3630 | .naked => true, | ||
| 3631 | else => false, | ||
| 3632 | }, | ||
| 3633 | .stage2_sparc64 => switch (cc) { | ||
| 3634 | .sparc64_sysv => |opts| opts.incoming_stack_alignment == null, | ||
| 3635 | .naked => true, | ||
| 3636 | else => false, | ||
| 3637 | }, | ||
| 3638 | .stage2_spirv64 => switch (cc) { | ||
| 3639 | .spirv_device, | ||
| 3640 | .spirv_kernel, | ||
| 3641 | .spirv_fragment, | ||
| 3642 | .spirv_vertex, | ||
| 3643 | => true, | ||
| 3644 | else => false, | ||
| 3645 | }, | ||
| 3646 | }; | ||
| 3647 | if (!backend_ok) return .{ .bad_backend = backend }; | ||
| 3648 | return .ok; | ||
| 3649 | } |
src/Zcu/PerThread.zig+1-1| ... | @@ -2090,7 +2090,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError! | ... | @@ -2090,7 +2090,7 @@ fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index) Zcu.SemaError! |
| 2090 | .code = zir, | 2090 | .code = zir, |
| 2091 | .owner = anal_unit, | 2091 | .owner = anal_unit, |
| 2092 | .func_index = func_index, | 2092 | .func_index = func_index, |
| 2093 | .func_is_naked = fn_ty_info.cc == .Naked, | 2093 | .func_is_naked = fn_ty_info.cc == .naked, |
| 2094 | .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type), | 2094 | .fn_ret_ty = Type.fromInterned(fn_ty_info.return_type), |
| 2095 | .fn_ret_ty_ies = null, | 2095 | .fn_ret_ty_ies = null, |
| 2096 | .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota), | 2096 | .branch_quota = @max(func.branchQuotaUnordered(ip), Sema.default_branch_quota), |
src/arch/aarch64/CodeGen.zig+5-5| ... | @@ -468,7 +468,7 @@ fn gen(self: *Self) !void { | ... | @@ -468,7 +468,7 @@ fn gen(self: *Self) !void { |
| 468 | const pt = self.pt; | 468 | const pt = self.pt; |
| 469 | const zcu = pt.zcu; | 469 | const zcu = pt.zcu; |
| 470 | const cc = self.fn_type.fnCallingConvention(zcu); | 470 | const cc = self.fn_type.fnCallingConvention(zcu); |
| 471 | if (cc != .Naked) { | 471 | if (cc != .naked) { |
| 472 | // stp fp, lr, [sp, #-16]! | 472 | // stp fp, lr, [sp, #-16]! |
| 473 | _ = try self.addInst(.{ | 473 | _ = try self.addInst(.{ |
| 474 | .tag = .stp, | 474 | .tag = .stp, |
| ... | @@ -6229,14 +6229,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6229,14 +6229,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6229 | const ret_ty = fn_ty.fnReturnType(zcu); | 6229 | const ret_ty = fn_ty.fnReturnType(zcu); |
| 6230 | 6230 | ||
| 6231 | switch (cc) { | 6231 | switch (cc) { |
| 6232 | .Naked => { | 6232 | .naked => { |
| 6233 | assert(result.args.len == 0); | 6233 | assert(result.args.len == 0); |
| 6234 | result.return_value = .{ .unreach = {} }; | 6234 | result.return_value = .{ .unreach = {} }; |
| 6235 | result.stack_byte_count = 0; | 6235 | result.stack_byte_count = 0; |
| 6236 | result.stack_align = 1; | 6236 | result.stack_align = 1; |
| 6237 | return result; | 6237 | return result; |
| 6238 | }, | 6238 | }, |
| 6239 | .C => { | 6239 | .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => { |
| 6240 | // ARM64 Procedure Call Standard | 6240 | // ARM64 Procedure Call Standard |
| 6241 | var ncrn: usize = 0; // Next Core Register Number | 6241 | var ncrn: usize = 0; // Next Core Register Number |
| 6242 | var nsaa: u32 = 0; // Next stacked argument address | 6242 | var nsaa: u32 = 0; // Next stacked argument address |
| ... | @@ -6266,7 +6266,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6266,7 +6266,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6266 | 6266 | ||
| 6267 | // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned | 6267 | // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned |
| 6268 | // values to spread across odd-numbered registers. | 6268 | // values to spread across odd-numbered registers. |
| 6269 | if (Type.fromInterned(ty).abiAlignment(zcu) == .@"16" and !self.target.isDarwin()) { | 6269 | if (Type.fromInterned(ty).abiAlignment(zcu) == .@"16" and cc != .aarch64_aapcs_darwin) { |
| 6270 | // Round up NCRN to the next even number | 6270 | // Round up NCRN to the next even number |
| 6271 | ncrn += ncrn % 2; | 6271 | ncrn += ncrn % 2; |
| 6272 | } | 6272 | } |
| ... | @@ -6298,7 +6298,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6298,7 +6298,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6298 | result.stack_byte_count = nsaa; | 6298 | result.stack_byte_count = nsaa; |
| 6299 | result.stack_align = 16; | 6299 | result.stack_align = 16; |
| 6300 | }, | 6300 | }, |
| 6301 | .Unspecified => { | 6301 | .auto => { |
| 6302 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { | 6302 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { |
| 6303 | result.return_value = .{ .unreach = {} }; | 6303 | result.return_value = .{ .unreach = {} }; |
| 6304 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { | 6304 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { |
src/arch/arm/CodeGen.zig+4-4| ... | @@ -475,7 +475,7 @@ fn gen(self: *Self) !void { | ... | @@ -475,7 +475,7 @@ fn gen(self: *Self) !void { |
| 475 | const pt = self.pt; | 475 | const pt = self.pt; |
| 476 | const zcu = pt.zcu; | 476 | const zcu = pt.zcu; |
| 477 | const cc = self.fn_type.fnCallingConvention(zcu); | 477 | const cc = self.fn_type.fnCallingConvention(zcu); |
| 478 | if (cc != .Naked) { | 478 | if (cc != .naked) { |
| 479 | // push {fp, lr} | 479 | // push {fp, lr} |
| 480 | const push_reloc = try self.addNop(); | 480 | const push_reloc = try self.addNop(); |
| 481 | 481 | ||
| ... | @@ -6196,14 +6196,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6196,14 +6196,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6196 | const ret_ty = fn_ty.fnReturnType(zcu); | 6196 | const ret_ty = fn_ty.fnReturnType(zcu); |
| 6197 | 6197 | ||
| 6198 | switch (cc) { | 6198 | switch (cc) { |
| 6199 | .Naked => { | 6199 | .naked => { |
| 6200 | assert(result.args.len == 0); | 6200 | assert(result.args.len == 0); |
| 6201 | result.return_value = .{ .unreach = {} }; | 6201 | result.return_value = .{ .unreach = {} }; |
| 6202 | result.stack_byte_count = 0; | 6202 | result.stack_byte_count = 0; |
| 6203 | result.stack_align = 1; | 6203 | result.stack_align = 1; |
| 6204 | return result; | 6204 | return result; |
| 6205 | }, | 6205 | }, |
| 6206 | .C => { | 6206 | .arm_aapcs => { |
| 6207 | // ARM Procedure Call Standard, Chapter 6.5 | 6207 | // ARM Procedure Call Standard, Chapter 6.5 |
| 6208 | var ncrn: usize = 0; // Next Core Register Number | 6208 | var ncrn: usize = 0; // Next Core Register Number |
| 6209 | var nsaa: u32 = 0; // Next stacked argument address | 6209 | var nsaa: u32 = 0; // Next stacked argument address |
| ... | @@ -6254,7 +6254,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6254,7 +6254,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6254 | result.stack_byte_count = nsaa; | 6254 | result.stack_byte_count = nsaa; |
| 6255 | result.stack_align = 8; | 6255 | result.stack_align = 8; |
| 6256 | }, | 6256 | }, |
| 6257 | .Unspecified => { | 6257 | .auto => { |
| 6258 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { | 6258 | if (ret_ty.zigTypeTag(zcu) == .noreturn) { |
| 6259 | result.return_value = .{ .unreach = {} }; | 6259 | result.return_value = .{ .unreach = {} }; |
| 6260 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { | 6260 | } else if (!ret_ty.hasRuntimeBitsIgnoreComptime(zcu) and !ret_ty.isError(zcu)) { |
src/arch/riscv64/CodeGen.zig+9-11| ... | @@ -18,6 +18,7 @@ const Zcu = @import("../../Zcu.zig"); | ... | @@ -18,6 +18,7 @@ const Zcu = @import("../../Zcu.zig"); |
| 18 | const Package = @import("../../Package.zig"); | 18 | const Package = @import("../../Package.zig"); |
| 19 | const InternPool = @import("../../InternPool.zig"); | 19 | const InternPool = @import("../../InternPool.zig"); |
| 20 | const Compilation = @import("../../Compilation.zig"); | 20 | const Compilation = @import("../../Compilation.zig"); |
| 21 | const target_util = @import("../../target.zig"); | ||
| 21 | const trace = @import("../../tracy.zig").trace; | 22 | const trace = @import("../../tracy.zig").trace; |
| 22 | const codegen = @import("../../codegen.zig"); | 23 | const codegen = @import("../../codegen.zig"); |
| 23 | 24 | ||
| ... | @@ -819,10 +820,7 @@ pub fn generate( | ... | @@ -819,10 +820,7 @@ pub fn generate( |
| 819 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); | 820 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 820 | function.frame_allocs.set( | 821 | function.frame_allocs.set( |
| 821 | @intFromEnum(FrameIndex.stack_frame), | 822 | @intFromEnum(FrameIndex.stack_frame), |
| 822 | FrameAlloc.init(.{ | 823 | FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }), |
| 823 | .size = 0, | ||
| 824 | .alignment = func.analysisUnordered(ip).stack_alignment.max(.@"1"), | ||
| 825 | }), | ||
| 826 | ); | 824 | ); |
| 827 | function.frame_allocs.set( | 825 | function.frame_allocs.set( |
| 828 | @intFromEnum(FrameIndex.call_frame), | 826 | @intFromEnum(FrameIndex.call_frame), |
| ... | @@ -977,7 +975,7 @@ pub fn generateLazy( | ... | @@ -977,7 +975,7 @@ pub fn generateLazy( |
| 977 | .pt = pt, | 975 | .pt = pt, |
| 978 | .allocator = gpa, | 976 | .allocator = gpa, |
| 979 | .mir = mir, | 977 | .mir = mir, |
| 980 | .cc = .Unspecified, | 978 | .cc = .auto, |
| 981 | .src_loc = src_loc, | 979 | .src_loc = src_loc, |
| 982 | .output_mode = comp.config.output_mode, | 980 | .output_mode = comp.config.output_mode, |
| 983 | .link_mode = comp.config.link_mode, | 981 | .link_mode = comp.config.link_mode, |
| ... | @@ -1036,7 +1034,7 @@ fn formatWipMir( | ... | @@ -1036,7 +1034,7 @@ fn formatWipMir( |
| 1036 | .instructions = data.func.mir_instructions.slice(), | 1034 | .instructions = data.func.mir_instructions.slice(), |
| 1037 | .frame_locs = data.func.frame_locs.slice(), | 1035 | .frame_locs = data.func.frame_locs.slice(), |
| 1038 | }, | 1036 | }, |
| 1039 | .cc = .Unspecified, | 1037 | .cc = .auto, |
| 1040 | .src_loc = data.func.src_loc, | 1038 | .src_loc = data.func.src_loc, |
| 1041 | .output_mode = comp.config.output_mode, | 1039 | .output_mode = comp.config.output_mode, |
| 1042 | .link_mode = comp.config.link_mode, | 1040 | .link_mode = comp.config.link_mode, |
| ... | @@ -1238,7 +1236,7 @@ fn gen(func: *Func) !void { | ... | @@ -1238,7 +1236,7 @@ fn gen(func: *Func) !void { |
| 1238 | } | 1236 | } |
| 1239 | } | 1237 | } |
| 1240 | 1238 | ||
| 1241 | if (fn_info.cc != .Naked) { | 1239 | if (fn_info.cc != .naked) { |
| 1242 | _ = try func.addPseudo(.pseudo_dbg_prologue_end); | 1240 | _ = try func.addPseudo(.pseudo_dbg_prologue_end); |
| 1243 | 1241 | ||
| 1244 | const backpatch_stack_alloc = try func.addPseudo(.pseudo_dead); | 1242 | const backpatch_stack_alloc = try func.addPseudo(.pseudo_dead); |
| ... | @@ -4894,7 +4892,7 @@ fn genCall( | ... | @@ -4894,7 +4892,7 @@ fn genCall( |
| 4894 | .lib => |lib| try pt.funcType(.{ | 4892 | .lib => |lib| try pt.funcType(.{ |
| 4895 | .param_types = lib.param_types, | 4893 | .param_types = lib.param_types, |
| 4896 | .return_type = lib.return_type, | 4894 | .return_type = lib.return_type, |
| 4897 | .cc = .C, | 4895 | .cc = func.target.cCallingConvention().?, |
| 4898 | }), | 4896 | }), |
| 4899 | }; | 4897 | }; |
| 4900 | 4898 | ||
| ... | @@ -8289,12 +8287,12 @@ fn resolveCallingConventionValues( | ... | @@ -8289,12 +8287,12 @@ fn resolveCallingConventionValues( |
| 8289 | const ret_ty = Type.fromInterned(fn_info.return_type); | 8287 | const ret_ty = Type.fromInterned(fn_info.return_type); |
| 8290 | 8288 | ||
| 8291 | switch (cc) { | 8289 | switch (cc) { |
| 8292 | .Naked => { | 8290 | .naked => { |
| 8293 | assert(result.args.len == 0); | 8291 | assert(result.args.len == 0); |
| 8294 | result.return_value = InstTracking.init(.unreach); | 8292 | result.return_value = InstTracking.init(.unreach); |
| 8295 | result.stack_align = .@"8"; | 8293 | result.stack_align = .@"8"; |
| 8296 | }, | 8294 | }, |
| 8297 | .C, .Unspecified => { | 8295 | .riscv64_lp64, .auto => { |
| 8298 | if (result.args.len > 8) { | 8296 | if (result.args.len > 8) { |
| 8299 | return func.fail("RISC-V calling convention does not support more than 8 arguments", .{}); | 8297 | return func.fail("RISC-V calling convention does not support more than 8 arguments", .{}); |
| 8300 | } | 8298 | } |
| ... | @@ -8359,7 +8357,7 @@ fn resolveCallingConventionValues( | ... | @@ -8359,7 +8357,7 @@ fn resolveCallingConventionValues( |
| 8359 | 8357 | ||
| 8360 | for (param_types, result.args) |ty, *arg| { | 8358 | for (param_types, result.args) |ty, *arg| { |
| 8361 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 8359 | if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 8362 | assert(cc == .Unspecified); | 8360 | assert(cc == .auto); |
| 8363 | arg.* = .none; | 8361 | arg.* = .none; |
| 8364 | continue; | 8362 | continue; |
| 8365 | } | 8363 | } |
src/arch/sparc64/CodeGen.zig+3-3| ... | @@ -366,7 +366,7 @@ fn gen(self: *Self) !void { | ... | @@ -366,7 +366,7 @@ fn gen(self: *Self) !void { |
| 366 | const pt = self.pt; | 366 | const pt = self.pt; |
| 367 | const zcu = pt.zcu; | 367 | const zcu = pt.zcu; |
| 368 | const cc = self.fn_type.fnCallingConvention(zcu); | 368 | const cc = self.fn_type.fnCallingConvention(zcu); |
| 369 | if (cc != .Naked) { | 369 | if (cc != .naked) { |
| 370 | // TODO Finish function prologue and epilogue for sparc64. | 370 | // TODO Finish function prologue and epilogue for sparc64. |
| 371 | 371 | ||
| 372 | // save %sp, stack_reserved_area, %sp | 372 | // save %sp, stack_reserved_area, %sp |
| ... | @@ -4441,14 +4441,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) | ... | @@ -4441,14 +4441,14 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) |
| 4441 | const ret_ty = fn_ty.fnReturnType(zcu); | 4441 | const ret_ty = fn_ty.fnReturnType(zcu); |
| 4442 | 4442 | ||
| 4443 | switch (cc) { | 4443 | switch (cc) { |
| 4444 | .Naked => { | 4444 | .naked => { |
| 4445 | assert(result.args.len == 0); | 4445 | assert(result.args.len == 0); |
| 4446 | result.return_value = .{ .unreach = {} }; | 4446 | result.return_value = .{ .unreach = {} }; |
| 4447 | result.stack_byte_count = 0; | 4447 | result.stack_byte_count = 0; |
| 4448 | result.stack_align = .@"1"; | 4448 | result.stack_align = .@"1"; |
| 4449 | return result; | 4449 | return result; |
| 4450 | }, | 4450 | }, |
| 4451 | .Unspecified, .C => { | 4451 | .auto, .sparc64_sysv => { |
| 4452 | // SPARC Compliance Definition 2.4.1, Chapter 3 | 4452 | // SPARC Compliance Definition 2.4.1, Chapter 3 |
| 4453 | // Low-Level System Information (64-bit psABI) - Function Calling Sequence | 4453 | // Low-Level System Information (64-bit psABI) - Function Calling Sequence |
| 4454 | 4454 |
src/arch/wasm/CodeGen.zig+16-15| ... | @@ -710,7 +710,7 @@ stack_size: u32 = 0, | ... | @@ -710,7 +710,7 @@ stack_size: u32 = 0, |
| 710 | /// The stack alignment, which is 16 bytes by default. This is specified by the | 710 | /// The stack alignment, which is 16 bytes by default. This is specified by the |
| 711 | /// tool-conventions: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md | 711 | /// tool-conventions: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md |
| 712 | /// and also what the llvm backend will emit. | 712 | /// and also what the llvm backend will emit. |
| 713 | /// However, local variables or the usage of `@setAlignStack` can overwrite this default. | 713 | /// However, local variables or the usage of `incoming_stack_alignment` in a `CallingConvention` can overwrite this default. |
| 714 | stack_alignment: Alignment = .@"16", | 714 | stack_alignment: Alignment = .@"16", |
| 715 | 715 | ||
| 716 | // For each individual Wasm valtype we store a seperate free list which | 716 | // For each individual Wasm valtype we store a seperate free list which |
| ... | @@ -1160,7 +1160,7 @@ fn genFunctype( | ... | @@ -1160,7 +1160,7 @@ fn genFunctype( |
| 1160 | if (firstParamSRet(cc, return_type, pt, target)) { | 1160 | if (firstParamSRet(cc, return_type, pt, target)) { |
| 1161 | try temp_params.append(.i32); // memory address is always a 32-bit handle | 1161 | try temp_params.append(.i32); // memory address is always a 32-bit handle |
| 1162 | } else if (return_type.hasRuntimeBitsIgnoreComptime(zcu)) { | 1162 | } else if (return_type.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 1163 | if (cc == .C) { | 1163 | if (cc == .wasm_watc) { |
| 1164 | const res_classes = abi.classifyType(return_type, zcu); | 1164 | const res_classes = abi.classifyType(return_type, zcu); |
| 1165 | assert(res_classes[0] == .direct and res_classes[1] == .none); | 1165 | assert(res_classes[0] == .direct and res_classes[1] == .none); |
| 1166 | const scalar_type = abi.scalarType(return_type, zcu); | 1166 | const scalar_type = abi.scalarType(return_type, zcu); |
| ... | @@ -1178,7 +1178,7 @@ fn genFunctype( | ... | @@ -1178,7 +1178,7 @@ fn genFunctype( |
| 1178 | if (!param_type.hasRuntimeBitsIgnoreComptime(zcu)) continue; | 1178 | if (!param_type.hasRuntimeBitsIgnoreComptime(zcu)) continue; |
| 1179 | 1179 | ||
| 1180 | switch (cc) { | 1180 | switch (cc) { |
| 1181 | .C => { | 1181 | .wasm_watc => { |
| 1182 | const param_classes = abi.classifyType(param_type, zcu); | 1182 | const param_classes = abi.classifyType(param_type, zcu); |
| 1183 | if (param_classes[1] == .none) { | 1183 | if (param_classes[1] == .none) { |
| 1184 | if (param_classes[0] == .direct) { | 1184 | if (param_classes[0] == .direct) { |
| ... | @@ -1367,7 +1367,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1367,7 +1367,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1367 | .args = &.{}, | 1367 | .args = &.{}, |
| 1368 | .return_value = .none, | 1368 | .return_value = .none, |
| 1369 | }; | 1369 | }; |
| 1370 | if (cc == .Naked) return result; | 1370 | if (cc == .naked) return result; |
| 1371 | 1371 | ||
| 1372 | var args = std.ArrayList(WValue).init(func.gpa); | 1372 | var args = std.ArrayList(WValue).init(func.gpa); |
| 1373 | defer args.deinit(); | 1373 | defer args.deinit(); |
| ... | @@ -1382,7 +1382,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1382,7 +1382,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1382 | } | 1382 | } |
| 1383 | 1383 | ||
| 1384 | switch (cc) { | 1384 | switch (cc) { |
| 1385 | .Unspecified => { | 1385 | .auto => { |
| 1386 | for (fn_info.param_types.get(ip)) |ty| { | 1386 | for (fn_info.param_types.get(ip)) |ty| { |
| 1387 | if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) { | 1387 | if (!Type.fromInterned(ty).hasRuntimeBitsIgnoreComptime(zcu)) { |
| 1388 | continue; | 1388 | continue; |
| ... | @@ -1392,7 +1392,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1392,7 +1392,7 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1392 | func.local_index += 1; | 1392 | func.local_index += 1; |
| 1393 | } | 1393 | } |
| 1394 | }, | 1394 | }, |
| 1395 | .C => { | 1395 | .wasm_watc => { |
| 1396 | for (fn_info.param_types.get(ip)) |ty| { | 1396 | for (fn_info.param_types.get(ip)) |ty| { |
| 1397 | const ty_classes = abi.classifyType(Type.fromInterned(ty), zcu); | 1397 | const ty_classes = abi.classifyType(Type.fromInterned(ty), zcu); |
| 1398 | for (ty_classes) |class| { | 1398 | for (ty_classes) |class| { |
| ... | @@ -1410,8 +1410,9 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV | ... | @@ -1410,8 +1410,9 @@ fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWV |
| 1410 | 1410 | ||
| 1411 | fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu.PerThread, target: std.Target) bool { | 1411 | fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu.PerThread, target: std.Target) bool { |
| 1412 | switch (cc) { | 1412 | switch (cc) { |
| 1413 | .Unspecified, .Inline => return isByRef(return_type, pt, target), | 1413 | .@"inline" => unreachable, |
| 1414 | .C => { | 1414 | .auto => return isByRef(return_type, pt, target), |
| 1415 | .wasm_watc => { | ||
| 1415 | const ty_classes = abi.classifyType(return_type, pt.zcu); | 1416 | const ty_classes = abi.classifyType(return_type, pt.zcu); |
| 1416 | if (ty_classes[0] == .indirect) return true; | 1417 | if (ty_classes[0] == .indirect) return true; |
| 1417 | if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true; | 1418 | if (ty_classes[0] == .direct and ty_classes[1] == .direct) return true; |
| ... | @@ -1424,7 +1425,7 @@ fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu. | ... | @@ -1424,7 +1425,7 @@ fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, pt: Zcu. |
| 1424 | /// Lowers a Zig type and its value based on a given calling convention to ensure | 1425 | /// Lowers a Zig type and its value based on a given calling convention to ensure |
| 1425 | /// it matches the ABI. | 1426 | /// it matches the ABI. |
| 1426 | fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: WValue) !void { | 1427 | fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: WValue) !void { |
| 1427 | if (cc != .C) { | 1428 | if (cc != .wasm_watc) { |
| 1428 | return func.lowerToStack(value); | 1429 | return func.lowerToStack(value); |
| 1429 | } | 1430 | } |
| 1430 | 1431 | ||
| ... | @@ -2108,7 +2109,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2108,7 +2109,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2108 | // to the stack instead | 2109 | // to the stack instead |
| 2109 | if (func.return_value != .none) { | 2110 | if (func.return_value != .none) { |
| 2110 | try func.store(func.return_value, operand, ret_ty, 0); | 2111 | try func.store(func.return_value, operand, ret_ty, 0); |
| 2111 | } else if (fn_info.cc == .C and ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 2112 | } else if (fn_info.cc == .wasm_watc and ret_ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 2112 | switch (ret_ty.zigTypeTag(zcu)) { | 2113 | switch (ret_ty.zigTypeTag(zcu)) { |
| 2113 | // Aggregate types can be lowered as a singular value | 2114 | // Aggregate types can be lowered as a singular value |
| 2114 | .@"struct", .@"union" => { | 2115 | .@"struct", .@"union" => { |
| ... | @@ -2286,7 +2287,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2286,7 +2287,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2286 | } else if (first_param_sret) { | 2287 | } else if (first_param_sret) { |
| 2287 | break :result_value sret; | 2288 | break :result_value sret; |
| 2288 | // TODO: Make this less fragile and optimize | 2289 | // TODO: Make this less fragile and optimize |
| 2289 | } else if (zcu.typeToFunc(fn_ty).?.cc == .C and ret_ty.zigTypeTag(zcu) == .@"struct" or ret_ty.zigTypeTag(zcu) == .@"union") { | 2290 | } else if (zcu.typeToFunc(fn_ty).?.cc == .wasm_watc and ret_ty.zigTypeTag(zcu) == .@"struct" or ret_ty.zigTypeTag(zcu) == .@"union") { |
| 2290 | const result_local = try func.allocLocal(ret_ty); | 2291 | const result_local = try func.allocLocal(ret_ty); |
| 2291 | try func.addLabel(.local_set, result_local.local.value); | 2292 | try func.addLabel(.local_set, result_local.local.value); |
| 2292 | const scalar_type = abi.scalarType(ret_ty, zcu); | 2293 | const scalar_type = abi.scalarType(ret_ty, zcu); |
| ... | @@ -2565,7 +2566,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2565,7 +2566,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2565 | const arg = func.args[arg_index]; | 2566 | const arg = func.args[arg_index]; |
| 2566 | const cc = zcu.typeToFunc(zcu.navValue(func.owner_nav).typeOf(zcu)).?.cc; | 2567 | const cc = zcu.typeToFunc(zcu.navValue(func.owner_nav).typeOf(zcu)).?.cc; |
| 2567 | const arg_ty = func.typeOfIndex(inst); | 2568 | const arg_ty = func.typeOfIndex(inst); |
| 2568 | if (cc == .C) { | 2569 | if (cc == .wasm_watc) { |
| 2569 | const arg_classes = abi.classifyType(arg_ty, zcu); | 2570 | const arg_classes = abi.classifyType(arg_ty, zcu); |
| 2570 | for (arg_classes) |class| { | 2571 | for (arg_classes) |class| { |
| 2571 | if (class != .none) { | 2572 | if (class != .none) { |
| ... | @@ -7175,12 +7176,12 @@ fn callIntrinsic( | ... | @@ -7175,12 +7176,12 @@ fn callIntrinsic( |
| 7175 | // Always pass over C-ABI | 7176 | // Always pass over C-ABI |
| 7176 | const pt = func.pt; | 7177 | const pt = func.pt; |
| 7177 | const zcu = pt.zcu; | 7178 | const zcu = pt.zcu; |
| 7178 | var func_type = try genFunctype(func.gpa, .C, param_types, return_type, pt, func.target.*); | 7179 | var func_type = try genFunctype(func.gpa, .{ .wasm_watc = .{} }, param_types, return_type, pt, func.target.*); |
| 7179 | defer func_type.deinit(func.gpa); | 7180 | defer func_type.deinit(func.gpa); |
| 7180 | const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type); | 7181 | const func_type_index = try func.bin_file.zigObjectPtr().?.putOrGetFuncType(func.gpa, func_type); |
| 7181 | try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index); | 7182 | try func.bin_file.addOrUpdateImport(name, symbol_index, null, func_type_index); |
| 7182 | 7183 | ||
| 7183 | const want_sret_param = firstParamSRet(.C, return_type, pt, func.target.*); | 7184 | const want_sret_param = firstParamSRet(.{ .wasm_watc = .{} }, return_type, pt, func.target.*); |
| 7184 | // if we want return as first param, we allocate a pointer to stack, | 7185 | // if we want return as first param, we allocate a pointer to stack, |
| 7185 | // and emit it as our first argument | 7186 | // and emit it as our first argument |
| 7186 | const sret = if (want_sret_param) blk: { | 7187 | const sret = if (want_sret_param) blk: { |
| ... | @@ -7193,7 +7194,7 @@ fn callIntrinsic( | ... | @@ -7193,7 +7194,7 @@ fn callIntrinsic( |
| 7193 | for (args, 0..) |arg, arg_i| { | 7194 | for (args, 0..) |arg, arg_i| { |
| 7194 | assert(!(want_sret_param and arg == .stack)); | 7195 | assert(!(want_sret_param and arg == .stack)); |
| 7195 | assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(zcu)); | 7196 | assert(Type.fromInterned(param_types[arg_i]).hasRuntimeBitsIgnoreComptime(zcu)); |
| 7196 | try func.lowerArg(.C, Type.fromInterned(param_types[arg_i]), arg); | 7197 | try func.lowerArg(.{ .wasm_watc = .{} }, Type.fromInterned(param_types[arg_i]), arg); |
| 7197 | } | 7198 | } |
| 7198 | 7199 | ||
| 7199 | // Actually call our intrinsic | 7200 | // Actually call our intrinsic |
src/arch/x86_64/CodeGen.zig+47-43| ... | @@ -11,6 +11,7 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking); | ... | @@ -11,6 +11,7 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking); |
| 11 | const wip_mir_log = std.log.scoped(.wip_mir); | 11 | const wip_mir_log = std.log.scoped(.wip_mir); |
| 12 | const math = std.math; | 12 | const math = std.math; |
| 13 | const mem = std.mem; | 13 | const mem = std.mem; |
| 14 | const target_util = @import("../../target.zig"); | ||
| 14 | const trace = @import("../../tracy.zig").trace; | 15 | const trace = @import("../../tracy.zig").trace; |
| 15 | 16 | ||
| 16 | const Air = @import("../../Air.zig"); | 17 | const Air = @import("../../Air.zig"); |
| ... | @@ -870,10 +871,7 @@ pub fn generate( | ... | @@ -870,10 +871,7 @@ pub fn generate( |
| 870 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); | 871 | try function.frame_allocs.resize(gpa, FrameIndex.named_count); |
| 871 | function.frame_allocs.set( | 872 | function.frame_allocs.set( |
| 872 | @intFromEnum(FrameIndex.stack_frame), | 873 | @intFromEnum(FrameIndex.stack_frame), |
| 873 | FrameAlloc.init(.{ | 874 | FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }), |
| 874 | .size = 0, | ||
| 875 | .alignment = func.analysisUnordered(ip).stack_alignment.max(.@"1"), | ||
| 876 | }), | ||
| 877 | ); | 875 | ); |
| 878 | function.frame_allocs.set( | 876 | function.frame_allocs.set( |
| 879 | @intFromEnum(FrameIndex.call_frame), | 877 | @intFromEnum(FrameIndex.call_frame), |
| ... | @@ -918,13 +916,13 @@ pub fn generate( | ... | @@ -918,13 +916,13 @@ pub fn generate( |
| 918 | ); | 916 | ); |
| 919 | function.va_info = switch (cc) { | 917 | function.va_info = switch (cc) { |
| 920 | else => undefined, | 918 | else => undefined, |
| 921 | .SysV => .{ .sysv = .{ | 919 | .x86_64_sysv => .{ .sysv = .{ |
| 922 | .gp_count = call_info.gp_count, | 920 | .gp_count = call_info.gp_count, |
| 923 | .fp_count = call_info.fp_count, | 921 | .fp_count = call_info.fp_count, |
| 924 | .overflow_arg_area = .{ .index = .args_frame, .off = call_info.stack_byte_count }, | 922 | .overflow_arg_area = .{ .index = .args_frame, .off = call_info.stack_byte_count }, |
| 925 | .reg_save_area = undefined, | 923 | .reg_save_area = undefined, |
| 926 | } }, | 924 | } }, |
| 927 | .Win64 => .{ .win64 = .{} }, | 925 | .x86_64_win => .{ .win64 = .{} }, |
| 928 | }; | 926 | }; |
| 929 | 927 | ||
| 930 | function.gen() catch |err| switch (err) { | 928 | function.gen() catch |err| switch (err) { |
| ... | @@ -1053,7 +1051,7 @@ pub fn generateLazy( | ... | @@ -1053,7 +1051,7 @@ pub fn generateLazy( |
| 1053 | .bin_file = bin_file, | 1051 | .bin_file = bin_file, |
| 1054 | .allocator = gpa, | 1052 | .allocator = gpa, |
| 1055 | .mir = mir, | 1053 | .mir = mir, |
| 1056 | .cc = abi.resolveCallingConvention(.Unspecified, function.target.*), | 1054 | .cc = abi.resolveCallingConvention(.auto, function.target.*), |
| 1057 | .src_loc = src_loc, | 1055 | .src_loc = src_loc, |
| 1058 | .output_mode = comp.config.output_mode, | 1056 | .output_mode = comp.config.output_mode, |
| 1059 | .link_mode = comp.config.link_mode, | 1057 | .link_mode = comp.config.link_mode, |
| ... | @@ -1159,7 +1157,7 @@ fn formatWipMir( | ... | @@ -1159,7 +1157,7 @@ fn formatWipMir( |
| 1159 | .extra = data.self.mir_extra.items, | 1157 | .extra = data.self.mir_extra.items, |
| 1160 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), | 1158 | .frame_locs = (std.MultiArrayList(Mir.FrameLoc){}).slice(), |
| 1161 | }, | 1159 | }, |
| 1162 | .cc = .Unspecified, | 1160 | .cc = .auto, |
| 1163 | .src_loc = data.self.src_loc, | 1161 | .src_loc = data.self.src_loc, |
| 1164 | .output_mode = comp.config.output_mode, | 1162 | .output_mode = comp.config.output_mode, |
| 1165 | .link_mode = comp.config.link_mode, | 1163 | .link_mode = comp.config.link_mode, |
| ... | @@ -2023,7 +2021,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -2023,7 +2021,7 @@ fn gen(self: *Self) InnerError!void { |
| 2023 | const zcu = pt.zcu; | 2021 | const zcu = pt.zcu; |
| 2024 | const fn_info = zcu.typeToFunc(self.fn_type).?; | 2022 | const fn_info = zcu.typeToFunc(self.fn_type).?; |
| 2025 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); | 2023 | const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*); |
| 2026 | if (cc != .Naked) { | 2024 | if (cc != .naked) { |
| 2027 | try self.asmRegister(.{ ._, .push }, .rbp); | 2025 | try self.asmRegister(.{ ._, .push }, .rbp); |
| 2028 | try self.asmPseudoImmediate(.pseudo_cfi_adjust_cfa_offset_i_s, Immediate.s(8)); | 2026 | try self.asmPseudoImmediate(.pseudo_cfi_adjust_cfa_offset_i_s, Immediate.s(8)); |
| 2029 | try self.asmPseudoRegisterImmediate(.pseudo_cfi_rel_offset_ri_s, .rbp, Immediate.s(0)); | 2027 | try self.asmPseudoRegisterImmediate(.pseudo_cfi_rel_offset_ri_s, .rbp, Immediate.s(0)); |
| ... | @@ -2056,7 +2054,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -2056,7 +2054,7 @@ fn gen(self: *Self) InnerError!void { |
| 2056 | } | 2054 | } |
| 2057 | 2055 | ||
| 2058 | if (fn_info.is_var_args) switch (cc) { | 2056 | if (fn_info.is_var_args) switch (cc) { |
| 2059 | .SysV => { | 2057 | .x86_64_sysv => { |
| 2060 | const info = &self.va_info.sysv; | 2058 | const info = &self.va_info.sysv; |
| 2061 | const reg_save_area_fi = try self.allocFrameIndex(FrameAlloc.init(.{ | 2059 | const reg_save_area_fi = try self.allocFrameIndex(FrameAlloc.init(.{ |
| 2062 | .size = abi.SysV.c_abi_int_param_regs.len * 8 + | 2060 | .size = abi.SysV.c_abi_int_param_regs.len * 8 + |
| ... | @@ -2089,7 +2087,7 @@ fn gen(self: *Self) InnerError!void { | ... | @@ -2089,7 +2087,7 @@ fn gen(self: *Self) InnerError!void { |
| 2089 | 2087 | ||
| 2090 | self.performReloc(skip_sse_reloc); | 2088 | self.performReloc(skip_sse_reloc); |
| 2091 | }, | 2089 | }, |
| 2092 | .Win64 => return self.fail("TODO implement gen var arg function for Win64", .{}), | 2090 | .x86_64_win => return self.fail("TODO implement gen var arg function for Win64", .{}), |
| 2093 | else => unreachable, | 2091 | else => unreachable, |
| 2094 | }; | 2092 | }; |
| 2095 | 2093 | ||
| ... | @@ -2541,7 +2539,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { | ... | @@ -2541,7 +2539,7 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void { |
| 2541 | const enum_ty = Type.fromInterned(lazy_sym.ty); | 2539 | const enum_ty = Type.fromInterned(lazy_sym.ty); |
| 2542 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)}); | 2540 | wip_mir_log.debug("{}.@tagName:", .{enum_ty.fmt(pt)}); |
| 2543 | 2541 | ||
| 2544 | const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*); | 2542 | const resolved_cc = abi.resolveCallingConvention(.auto, self.target.*); |
| 2545 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); | 2543 | const param_regs = abi.getCAbiIntParamRegs(resolved_cc); |
| 2546 | const param_locks = self.register_manager.lockRegsAssumeUnused(2, param_regs[0..2].*); | 2544 | const param_locks = self.register_manager.lockRegsAssumeUnused(2, param_regs[0..2].*); |
| 2547 | defer for (param_locks) |lock| self.register_manager.unlockReg(lock); | 2545 | defer for (param_locks) |lock| self.register_manager.unlockReg(lock); |
| ... | @@ -3008,9 +3006,8 @@ pub fn spillEflagsIfOccupied(self: *Self) !void { | ... | @@ -3008,9 +3006,8 @@ pub fn spillEflagsIfOccupied(self: *Self) !void { |
| 3008 | 3006 | ||
| 3009 | pub fn spillCallerPreservedRegs(self: *Self, cc: std.builtin.CallingConvention) !void { | 3007 | pub fn spillCallerPreservedRegs(self: *Self, cc: std.builtin.CallingConvention) !void { |
| 3010 | switch (cc) { | 3008 | switch (cc) { |
| 3011 | inline .SysV, .Win64 => |known_cc| try self.spillRegisters( | 3009 | .x86_64_sysv => try self.spillRegisters(abi.getCallerPreservedRegs(.{ .x86_64_sysv = .{} })), |
| 3012 | comptime abi.getCallerPreservedRegs(known_cc), | 3010 | .x86_64_win => try self.spillRegisters(abi.getCallerPreservedRegs(.{ .x86_64_win = .{} })), |
| 3013 | ), | ||
| 3014 | else => unreachable, | 3011 | else => unreachable, |
| 3015 | } | 3012 | } |
| 3016 | } | 3013 | } |
| ... | @@ -12384,7 +12381,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12384,7 +12381,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12384 | .lib => |lib| try pt.funcType(.{ | 12381 | .lib => |lib| try pt.funcType(.{ |
| 12385 | .param_types = lib.param_types, | 12382 | .param_types = lib.param_types, |
| 12386 | .return_type = lib.return_type, | 12383 | .return_type = lib.return_type, |
| 12387 | .cc = .C, | 12384 | .cc = self.target.cCallingConvention().?, |
| 12388 | }), | 12385 | }), |
| 12389 | }; | 12386 | }; |
| 12390 | const fn_info = zcu.typeToFunc(fn_ty).?; | 12387 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| ... | @@ -12543,7 +12540,7 @@ fn genCall(self: *Self, info: union(enum) { | ... | @@ -12543,7 +12540,7 @@ fn genCall(self: *Self, info: union(enum) { |
| 12543 | src_arg, | 12540 | src_arg, |
| 12544 | .{}, | 12541 | .{}, |
| 12545 | ), | 12542 | ), |
| 12546 | .C, .SysV, .Win64 => { | 12543 | .x86_64_sysv, .x86_64_win => { |
| 12547 | const promoted_ty = self.promoteInt(arg_ty); | 12544 | const promoted_ty = self.promoteInt(arg_ty); |
| 12548 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(zcu)); | 12545 | const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(zcu)); |
| 12549 | const dst_alias = registerAlias(dst_reg, promoted_abi_size); | 12546 | const dst_alias = registerAlias(dst_reg, promoted_abi_size); |
| ... | @@ -16822,7 +16819,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -16822,7 +16819,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void { |
| 16822 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; | 16819 | const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op; |
| 16823 | const inst_ty = self.typeOfIndex(inst); | 16820 | const inst_ty = self.typeOfIndex(inst); |
| 16824 | const enum_ty = self.typeOf(un_op); | 16821 | const enum_ty = self.typeOf(un_op); |
| 16825 | const resolved_cc = abi.resolveCallingConvention(.Unspecified, self.target.*); | 16822 | const resolved_cc = abi.resolveCallingConvention(.auto, self.target.*); |
| 16826 | 16823 | ||
| 16827 | // We need a properly aligned and sized call frame to be able to call this function. | 16824 | // We need a properly aligned and sized call frame to be able to call this function. |
| 16828 | { | 16825 | { |
| ... | @@ -18915,7 +18912,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18915,7 +18912,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18915 | self.fn_type.fnCallingConvention(zcu), | 18912 | self.fn_type.fnCallingConvention(zcu), |
| 18916 | self.target.*, | 18913 | self.target.*, |
| 18917 | )) { | 18914 | )) { |
| 18918 | .SysV => result: { | 18915 | .x86_64_sysv => result: { |
| 18919 | const info = self.va_info.sysv; | 18916 | const info = self.va_info.sysv; |
| 18920 | const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, zcu)); | 18917 | const dst_fi = try self.allocFrameIndex(FrameAlloc.initSpill(va_list_ty, zcu)); |
| 18921 | var field_off: u31 = 0; | 18918 | var field_off: u31 = 0; |
| ... | @@ -18957,7 +18954,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18957,7 +18954,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void { |
| 18957 | field_off += @intCast(ptr_anyopaque_ty.abiSize(zcu)); | 18954 | field_off += @intCast(ptr_anyopaque_ty.abiSize(zcu)); |
| 18958 | break :result .{ .load_frame = .{ .index = dst_fi } }; | 18955 | break :result .{ .load_frame = .{ .index = dst_fi } }; |
| 18959 | }, | 18956 | }, |
| 18960 | .Win64 => return self.fail("TODO implement c_va_start for Win64", .{}), | 18957 | .x86_64_win => return self.fail("TODO implement c_va_start for Win64", .{}), |
| 18961 | else => unreachable, | 18958 | else => unreachable, |
| 18962 | }; | 18959 | }; |
| 18963 | return self.finishAir(inst, result, .{ .none, .none, .none }); | 18960 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| ... | @@ -18976,7 +18973,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -18976,7 +18973,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 18976 | self.fn_type.fnCallingConvention(zcu), | 18973 | self.fn_type.fnCallingConvention(zcu), |
| 18977 | self.target.*, | 18974 | self.target.*, |
| 18978 | )) { | 18975 | )) { |
| 18979 | .SysV => result: { | 18976 | .x86_64_sysv => result: { |
| 18980 | try self.spillEflagsIfOccupied(); | 18977 | try self.spillEflagsIfOccupied(); |
| 18981 | 18978 | ||
| 18982 | const tmp_regs = | 18979 | const tmp_regs = |
| ... | @@ -19155,7 +19152,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -19155,7 +19152,7 @@ fn airVaArg(self: *Self, inst: Air.Inst.Index) !void { |
| 19155 | ); | 19152 | ); |
| 19156 | break :result promote_mcv; | 19153 | break :result promote_mcv; |
| 19157 | }, | 19154 | }, |
| 19158 | .Win64 => return self.fail("TODO implement c_va_arg for Win64", .{}), | 19155 | .x86_64_win => return self.fail("TODO implement c_va_arg for Win64", .{}), |
| 19159 | else => unreachable, | 19156 | else => unreachable, |
| 19160 | }; | 19157 | }; |
| 19161 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); | 19158 | return self.finishAir(inst, result, .{ ty_op.operand, .none, .none }); |
| ... | @@ -19324,21 +19321,21 @@ fn resolveCallingConventionValues( | ... | @@ -19324,21 +19321,21 @@ fn resolveCallingConventionValues( |
| 19324 | 19321 | ||
| 19325 | const resolved_cc = abi.resolveCallingConvention(cc, self.target.*); | 19322 | const resolved_cc = abi.resolveCallingConvention(cc, self.target.*); |
| 19326 | switch (cc) { | 19323 | switch (cc) { |
| 19327 | .Naked => { | 19324 | .naked => { |
| 19328 | assert(result.args.len == 0); | 19325 | assert(result.args.len == 0); |
| 19329 | result.return_value = InstTracking.init(.unreach); | 19326 | result.return_value = InstTracking.init(.unreach); |
| 19330 | result.stack_align = .@"8"; | 19327 | result.stack_align = .@"8"; |
| 19331 | }, | 19328 | }, |
| 19332 | .C, .SysV, .Win64 => { | 19329 | .x86_64_sysv, .x86_64_win => |cc_opts| { |
| 19333 | var ret_int_reg_i: u32 = 0; | 19330 | var ret_int_reg_i: u32 = 0; |
| 19334 | var ret_sse_reg_i: u32 = 0; | 19331 | var ret_sse_reg_i: u32 = 0; |
| 19335 | var param_int_reg_i: u32 = 0; | 19332 | var param_int_reg_i: u32 = 0; |
| 19336 | var param_sse_reg_i: u32 = 0; | 19333 | var param_sse_reg_i: u32 = 0; |
| 19337 | result.stack_align = .@"16"; | 19334 | result.stack_align = .fromByteUnits(cc_opts.incoming_stack_alignment orelse 16); |
| 19338 | 19335 | ||
| 19339 | switch (resolved_cc) { | 19336 | switch (resolved_cc) { |
| 19340 | .SysV => {}, | 19337 | .x86_64_sysv => {}, |
| 19341 | .Win64 => { | 19338 | .x86_64_win => { |
| 19342 | // Align the stack to 16bytes before allocating shadow stack space (if any). | 19339 | // Align the stack to 16bytes before allocating shadow stack space (if any). |
| 19343 | result.stack_byte_count += @intCast(4 * Type.usize.abiSize(zcu)); | 19340 | result.stack_byte_count += @intCast(4 * Type.usize.abiSize(zcu)); |
| 19344 | }, | 19341 | }, |
| ... | @@ -19356,8 +19353,8 @@ fn resolveCallingConventionValues( | ... | @@ -19356,8 +19353,8 @@ fn resolveCallingConventionValues( |
| 19356 | var ret_tracking_i: usize = 0; | 19353 | var ret_tracking_i: usize = 0; |
| 19357 | 19354 | ||
| 19358 | const classes = switch (resolved_cc) { | 19355 | const classes = switch (resolved_cc) { |
| 19359 | .SysV => mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, self.target.*, .ret), .none), | 19356 | .x86_64_sysv => mem.sliceTo(&abi.classifySystemV(ret_ty, zcu, self.target.*, .ret), .none), |
| 19360 | .Win64 => &.{abi.classifyWindows(ret_ty, zcu)}, | 19357 | .x86_64_win => &.{abi.classifyWindows(ret_ty, zcu)}, |
| 19361 | else => unreachable, | 19358 | else => unreachable, |
| 19362 | }; | 19359 | }; |
| 19363 | for (classes) |class| switch (class) { | 19360 | for (classes) |class| switch (class) { |
| ... | @@ -19419,8 +19416,8 @@ fn resolveCallingConventionValues( | ... | @@ -19419,8 +19416,8 @@ fn resolveCallingConventionValues( |
| 19419 | for (param_types, result.args) |ty, *arg| { | 19416 | for (param_types, result.args) |ty, *arg| { |
| 19420 | assert(ty.hasRuntimeBitsIgnoreComptime(zcu)); | 19417 | assert(ty.hasRuntimeBitsIgnoreComptime(zcu)); |
| 19421 | switch (resolved_cc) { | 19418 | switch (resolved_cc) { |
| 19422 | .SysV => {}, | 19419 | .x86_64_sysv => {}, |
| 19423 | .Win64 => { | 19420 | .x86_64_win => { |
| 19424 | param_int_reg_i = @max(param_int_reg_i, param_sse_reg_i); | 19421 | param_int_reg_i = @max(param_int_reg_i, param_sse_reg_i); |
| 19425 | param_sse_reg_i = param_int_reg_i; | 19422 | param_sse_reg_i = param_int_reg_i; |
| 19426 | }, | 19423 | }, |
| ... | @@ -19431,8 +19428,8 @@ fn resolveCallingConventionValues( | ... | @@ -19431,8 +19428,8 @@ fn resolveCallingConventionValues( |
| 19431 | var arg_mcv_i: usize = 0; | 19428 | var arg_mcv_i: usize = 0; |
| 19432 | 19429 | ||
| 19433 | const classes = switch (resolved_cc) { | 19430 | const classes = switch (resolved_cc) { |
| 19434 | .SysV => mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target.*, .arg), .none), | 19431 | .x86_64_sysv => mem.sliceTo(&abi.classifySystemV(ty, zcu, self.target.*, .arg), .none), |
| 19435 | .Win64 => &.{abi.classifyWindows(ty, zcu)}, | 19432 | .x86_64_win => &.{abi.classifyWindows(ty, zcu)}, |
| 19436 | else => unreachable, | 19433 | else => unreachable, |
| 19437 | }; | 19434 | }; |
| 19438 | for (classes) |class| switch (class) { | 19435 | for (classes) |class| switch (class) { |
| ... | @@ -19464,11 +19461,11 @@ fn resolveCallingConventionValues( | ... | @@ -19464,11 +19461,11 @@ fn resolveCallingConventionValues( |
| 19464 | }, | 19461 | }, |
| 19465 | .sseup => assert(arg_mcv[arg_mcv_i - 1].register.class() == .sse), | 19462 | .sseup => assert(arg_mcv[arg_mcv_i - 1].register.class() == .sse), |
| 19466 | .x87, .x87up, .complex_x87, .memory, .win_i128 => switch (resolved_cc) { | 19463 | .x87, .x87up, .complex_x87, .memory, .win_i128 => switch (resolved_cc) { |
| 19467 | .SysV => switch (class) { | 19464 | .x86_64_sysv => switch (class) { |
| 19468 | .x87, .x87up, .complex_x87, .memory => break, | 19465 | .x87, .x87up, .complex_x87, .memory => break, |
| 19469 | else => unreachable, | 19466 | else => unreachable, |
| 19470 | }, | 19467 | }, |
| 19471 | .Win64 => if (ty.abiSize(zcu) > 8) { | 19468 | .x86_64_win => if (ty.abiSize(zcu) > 8) { |
| 19472 | const param_int_reg = | 19469 | const param_int_reg = |
| 19473 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64(); | 19470 | abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64(); |
| 19474 | param_int_reg_i += 1; | 19471 | param_int_reg_i += 1; |
| ... | @@ -19515,10 +19512,13 @@ fn resolveCallingConventionValues( | ... | @@ -19515,10 +19512,13 @@ fn resolveCallingConventionValues( |
| 19515 | } | 19512 | } |
| 19516 | 19513 | ||
| 19517 | const param_size: u31 = @intCast(ty.abiSize(zcu)); | 19514 | const param_size: u31 = @intCast(ty.abiSize(zcu)); |
| 19518 | const param_align: u31 = | 19515 | const param_align = ty.abiAlignment(zcu).max(.@"8"); |
| 19519 | @intCast(@max(ty.abiAlignment(zcu).toByteUnits().?, 8)); | 19516 | result.stack_byte_count = mem.alignForward( |
| 19520 | result.stack_byte_count = | 19517 | u31, |
| 19521 | mem.alignForward(u31, result.stack_byte_count, param_align); | 19518 | result.stack_byte_count, |
| 19519 | @intCast(param_align.toByteUnits().?), | ||
| 19520 | ); | ||
| 19521 | result.stack_align = result.stack_align.max(param_align); | ||
| 19522 | arg.* = .{ .load_frame = .{ | 19522 | arg.* = .{ .load_frame = .{ |
| 19523 | .index = stack_frame_base, | 19523 | .index = stack_frame_base, |
| 19524 | .off = result.stack_byte_count, | 19524 | .off = result.stack_byte_count, |
| ... | @@ -19530,7 +19530,7 @@ fn resolveCallingConventionValues( | ... | @@ -19530,7 +19530,7 @@ fn resolveCallingConventionValues( |
| 19530 | assert(param_sse_reg_i <= 16); | 19530 | assert(param_sse_reg_i <= 16); |
| 19531 | result.fp_count = param_sse_reg_i; | 19531 | result.fp_count = param_sse_reg_i; |
| 19532 | }, | 19532 | }, |
| 19533 | .Unspecified => { | 19533 | .auto => { |
| 19534 | result.stack_align = .@"16"; | 19534 | result.stack_align = .@"16"; |
| 19535 | 19535 | ||
| 19536 | // Return values | 19536 | // Return values |
| ... | @@ -19560,9 +19560,13 @@ fn resolveCallingConventionValues( | ... | @@ -19560,9 +19560,13 @@ fn resolveCallingConventionValues( |
| 19560 | continue; | 19560 | continue; |
| 19561 | } | 19561 | } |
| 19562 | const param_size: u31 = @intCast(ty.abiSize(zcu)); | 19562 | const param_size: u31 = @intCast(ty.abiSize(zcu)); |
| 19563 | const param_align: u31 = @intCast(ty.abiAlignment(zcu).toByteUnits().?); | 19563 | const param_align = ty.abiAlignment(zcu); |
| 19564 | result.stack_byte_count = | 19564 | result.stack_byte_count = mem.alignForward( |
| 19565 | mem.alignForward(u31, result.stack_byte_count, param_align); | 19565 | u31, |
| 19566 | result.stack_byte_count, | ||
| 19567 | @intCast(param_align.toByteUnits().?), | ||
| 19568 | ); | ||
| 19569 | result.stack_align = result.stack_align.max(param_align); | ||
| 19566 | arg.* = .{ .load_frame = .{ | 19570 | arg.* = .{ .load_frame = .{ |
| 19567 | .index = stack_frame_base, | 19571 | .index = stack_frame_base, |
| 19568 | .off = result.stack_byte_count, | 19572 | .off = result.stack_byte_count, |
src/arch/x86_64/abi.zig+15-15| ... | @@ -440,9 +440,9 @@ pub fn resolveCallingConvention( | ... | @@ -440,9 +440,9 @@ pub fn resolveCallingConvention( |
| 440 | target: std.Target, | 440 | target: std.Target, |
| 441 | ) std.builtin.CallingConvention { | 441 | ) std.builtin.CallingConvention { |
| 442 | return switch (cc) { | 442 | return switch (cc) { |
| 443 | .Unspecified, .C => switch (target.os.tag) { | 443 | .auto => switch (target.os.tag) { |
| 444 | else => .SysV, | 444 | else => .{ .x86_64_sysv = .{} }, |
| 445 | .windows => .Win64, | 445 | .windows => .{ .x86_64_win = .{} }, |
| 446 | }, | 446 | }, |
| 447 | else => cc, | 447 | else => cc, |
| 448 | }; | 448 | }; |
| ... | @@ -450,48 +450,48 @@ pub fn resolveCallingConvention( | ... | @@ -450,48 +450,48 @@ pub fn resolveCallingConvention( |
| 450 | 450 | ||
| 451 | pub fn getCalleePreservedRegs(cc: std.builtin.CallingConvention) []const Register { | 451 | pub fn getCalleePreservedRegs(cc: std.builtin.CallingConvention) []const Register { |
| 452 | return switch (cc) { | 452 | return switch (cc) { |
| 453 | .SysV => &SysV.callee_preserved_regs, | 453 | .x86_64_sysv => &SysV.callee_preserved_regs, |
| 454 | .Win64 => &Win64.callee_preserved_regs, | 454 | .x86_64_win => &Win64.callee_preserved_regs, |
| 455 | else => unreachable, | 455 | else => unreachable, |
| 456 | }; | 456 | }; |
| 457 | } | 457 | } |
| 458 | 458 | ||
| 459 | pub fn getCallerPreservedRegs(cc: std.builtin.CallingConvention) []const Register { | 459 | pub fn getCallerPreservedRegs(cc: std.builtin.CallingConvention) []const Register { |
| 460 | return switch (cc) { | 460 | return switch (cc) { |
| 461 | .SysV => &SysV.caller_preserved_regs, | 461 | .x86_64_sysv => &SysV.caller_preserved_regs, |
| 462 | .Win64 => &Win64.caller_preserved_regs, | 462 | .x86_64_win => &Win64.caller_preserved_regs, |
| 463 | else => unreachable, | 463 | else => unreachable, |
| 464 | }; | 464 | }; |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | pub fn getCAbiIntParamRegs(cc: std.builtin.CallingConvention) []const Register { | 467 | pub fn getCAbiIntParamRegs(cc: std.builtin.CallingConvention) []const Register { |
| 468 | return switch (cc) { | 468 | return switch (cc) { |
| 469 | .SysV => &SysV.c_abi_int_param_regs, | 469 | .x86_64_sysv => &SysV.c_abi_int_param_regs, |
| 470 | .Win64 => &Win64.c_abi_int_param_regs, | 470 | .x86_64_win => &Win64.c_abi_int_param_regs, |
| 471 | else => unreachable, | 471 | else => unreachable, |
| 472 | }; | 472 | }; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | pub fn getCAbiSseParamRegs(cc: std.builtin.CallingConvention) []const Register { | 475 | pub fn getCAbiSseParamRegs(cc: std.builtin.CallingConvention) []const Register { |
| 476 | return switch (cc) { | 476 | return switch (cc) { |
| 477 | .SysV => &SysV.c_abi_sse_param_regs, | 477 | .x86_64_sysv => &SysV.c_abi_sse_param_regs, |
| 478 | .Win64 => &Win64.c_abi_sse_param_regs, | 478 | .x86_64_win => &Win64.c_abi_sse_param_regs, |
| 479 | else => unreachable, | 479 | else => unreachable, |
| 480 | }; | 480 | }; |
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | pub fn getCAbiIntReturnRegs(cc: std.builtin.CallingConvention) []const Register { | 483 | pub fn getCAbiIntReturnRegs(cc: std.builtin.CallingConvention) []const Register { |
| 484 | return switch (cc) { | 484 | return switch (cc) { |
| 485 | .SysV => &SysV.c_abi_int_return_regs, | 485 | .x86_64_sysv => &SysV.c_abi_int_return_regs, |
| 486 | .Win64 => &Win64.c_abi_int_return_regs, | 486 | .x86_64_win => &Win64.c_abi_int_return_regs, |
| 487 | else => unreachable, | 487 | else => unreachable, |
| 488 | }; | 488 | }; |
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | pub fn getCAbiSseReturnRegs(cc: std.builtin.CallingConvention) []const Register { | 491 | pub fn getCAbiSseReturnRegs(cc: std.builtin.CallingConvention) []const Register { |
| 492 | return switch (cc) { | 492 | return switch (cc) { |
| 493 | .SysV => &SysV.c_abi_sse_return_regs, | 493 | .x86_64_sysv => &SysV.c_abi_sse_return_regs, |
| 494 | .Win64 => &Win64.c_abi_sse_return_regs, | 494 | .x86_64_win => &Win64.c_abi_sse_return_regs, |
| 495 | else => unreachable, | 495 | else => unreachable, |
| 496 | }; | 496 | }; |
| 497 | } | 497 | } |
src/codegen/c.zig+35-8| ... | @@ -1783,7 +1783,7 @@ pub const DeclGen = struct { | ... | @@ -1783,7 +1783,7 @@ pub const DeclGen = struct { |
| 1783 | const fn_ctype = try dg.ctypeFromType(fn_ty, kind); | 1783 | const fn_ctype = try dg.ctypeFromType(fn_ty, kind); |
| 1784 | 1784 | ||
| 1785 | const fn_info = zcu.typeToFunc(fn_ty).?; | 1785 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| 1786 | if (fn_info.cc == .Naked) { | 1786 | if (fn_info.cc == .naked) { |
| 1787 | switch (kind) { | 1787 | switch (kind) { |
| 1788 | .forward => try w.writeAll("zig_naked_decl "), | 1788 | .forward => try w.writeAll("zig_naked_decl "), |
| 1789 | .complete => try w.writeAll("zig_naked "), | 1789 | .complete => try w.writeAll("zig_naked "), |
| ... | @@ -1796,7 +1796,7 @@ pub const DeclGen = struct { | ... | @@ -1796,7 +1796,7 @@ pub const DeclGen = struct { |
| 1796 | 1796 | ||
| 1797 | var trailing = try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, fn_ctype, .suffix, .{}); | 1797 | var trailing = try renderTypePrefix(dg.pass, &dg.ctype_pool, zcu, w, fn_ctype, .suffix, .{}); |
| 1798 | 1798 | ||
| 1799 | if (toCallingConvention(fn_info.cc)) |call_conv| { | 1799 | if (toCallingConvention(fn_info.cc, zcu)) |call_conv| { |
| 1800 | try w.print("{}zig_callconv({s})", .{ trailing, call_conv }); | 1800 | try w.print("{}zig_callconv({s})", .{ trailing, call_conv }); |
| 1801 | trailing = .maybe_space; | 1801 | trailing = .maybe_space; |
| 1802 | } | 1802 | } |
| ... | @@ -7604,12 +7604,39 @@ fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void { | ... | @@ -7604,12 +7604,39 @@ fn writeMemoryOrder(w: anytype, order: std.builtin.AtomicOrder) !void { |
| 7604 | return w.writeAll(toMemoryOrder(order)); | 7604 | return w.writeAll(toMemoryOrder(order)); |
| 7605 | } | 7605 | } |
| 7606 | 7606 | ||
| 7607 | fn toCallingConvention(call_conv: std.builtin.CallingConvention) ?[]const u8 { | 7607 | fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8 { |
| 7608 | return switch (call_conv) { | 7608 | if (zcu.getTarget().cCallingConvention()) |ccc| { |
| 7609 | .Stdcall => "stdcall", | 7609 | if (cc.eql(ccc)) { |
| 7610 | .Fastcall => "fastcall", | 7610 | return null; |
| 7611 | .Vectorcall => "vectorcall", | 7611 | } |
| 7612 | else => null, | 7612 | } |
| 7613 | return switch (cc) { | ||
| 7614 | .auto, .naked => null, | ||
| 7615 | |||
| 7616 | .x86_64_sysv, .x86_sysv => "sysv_abi", | ||
| 7617 | .x86_64_win, .x86_win => "ms_abi", | ||
| 7618 | .x86_stdcall => "stdcall", | ||
| 7619 | .x86_fastcall => "fastcall", | ||
| 7620 | .x86_thiscall => "thiscall", | ||
| 7621 | |||
| 7622 | .x86_vectorcall, | ||
| 7623 | .x86_64_vectorcall, | ||
| 7624 | => "vectorcall", | ||
| 7625 | |||
| 7626 | .x86_64_regcall_v3_sysv, | ||
| 7627 | .x86_64_regcall_v4_win, | ||
| 7628 | .x86_regcall_v3, | ||
| 7629 | .x86_regcall_v4_win, | ||
| 7630 | => "regcall", | ||
| 7631 | |||
| 7632 | .aarch64_vfabi => "aarch64_vector_pcs", | ||
| 7633 | .aarch64_vfabi_sve => "aarch64_sve_pcs", | ||
| 7634 | .arm_aapcs => "pcs(\"aapcs\")", | ||
| 7635 | .arm_aapcs_vfp => "pcs(\"aapcs-vfp\")", | ||
| 7636 | .riscv64_lp64_v, .riscv32_ilp32_v => "riscv_vector_cc", | ||
| 7637 | .m68k_rtd => "m68k_rtd", | ||
| 7638 | |||
| 7639 | else => unreachable, // `Zcu.callconvSupported` | ||
| 7613 | }; | 7640 | }; |
| 7614 | } | 7641 | } |
| 7615 | 7642 |
src/codegen/llvm.zig+348-242| ... | @@ -1159,7 +1159,7 @@ pub const Object = struct { | ... | @@ -1159,7 +1159,7 @@ pub const Object = struct { |
| 1159 | } | 1159 | } |
| 1160 | 1160 | ||
| 1161 | { | 1161 | { |
| 1162 | var module_flags = try std.ArrayList(Builder.Metadata).initCapacity(o.gpa, 6); | 1162 | var module_flags = try std.ArrayList(Builder.Metadata).initCapacity(o.gpa, 7); |
| 1163 | defer module_flags.deinit(); | 1163 | defer module_flags.deinit(); |
| 1164 | 1164 | ||
| 1165 | const behavior_error = try o.builder.metadataConstant(try o.builder.intConst(.i32, 1)); | 1165 | const behavior_error = try o.builder.metadataConstant(try o.builder.intConst(.i32, 1)); |
| ... | @@ -1233,6 +1233,18 @@ pub const Object = struct { | ... | @@ -1233,6 +1233,18 @@ pub const Object = struct { |
| 1233 | } | 1233 | } |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | const target = comp.root_mod.resolved_target.result; | ||
| 1237 | if (target.os.tag == .windows and (target.cpu.arch == .x86_64 or target.cpu.arch == .x86)) { | ||
| 1238 | // Add the "RegCallv4" flag so that any functions using `x86_regcallcc` use regcall | ||
| 1239 | // v4, which is essentially a requirement on Windows. See corresponding logic in | ||
| 1240 | // `toLlvmCallConvTag`. | ||
| 1241 | module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag( | ||
| 1242 | behavior_max, | ||
| 1243 | try o.builder.metadataString("RegCallv4"), | ||
| 1244 | try o.builder.metadataConstant(.@"1"), | ||
| 1245 | )); | ||
| 1246 | } | ||
| 1247 | |||
| 1236 | try o.builder.metadataNamed(try o.builder.metadataString("llvm.module.flags"), module_flags.items); | 1248 | try o.builder.metadataNamed(try o.builder.metadataString("llvm.module.flags"), module_flags.items); |
| 1237 | } | 1249 | } |
| 1238 | 1250 | ||
| ... | @@ -1467,14 +1479,6 @@ pub const Object = struct { | ... | @@ -1467,14 +1479,6 @@ pub const Object = struct { |
| 1467 | _ = try attributes.removeFnAttr(.@"noinline"); | 1479 | _ = try attributes.removeFnAttr(.@"noinline"); |
| 1468 | } | 1480 | } |
| 1469 | 1481 | ||
| 1470 | const stack_alignment = func.analysisUnordered(ip).stack_alignment; | ||
| 1471 | if (stack_alignment != .none) { | ||
| 1472 | try attributes.addFnAttr(.{ .alignstack = stack_alignment.toLlvm() }, &o.builder); | ||
| 1473 | try attributes.addFnAttr(.@"noinline", &o.builder); | ||
| 1474 | } else { | ||
| 1475 | _ = try attributes.removeFnAttr(.alignstack); | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | if (func_analysis.branch_hint == .cold) { | 1482 | if (func_analysis.branch_hint == .cold) { |
| 1479 | try attributes.addFnAttr(.cold, &o.builder); | 1483 | try attributes.addFnAttr(.cold, &o.builder); |
| 1480 | } else { | 1484 | } else { |
| ... | @@ -1486,7 +1490,7 @@ pub const Object = struct { | ... | @@ -1486,7 +1490,7 @@ pub const Object = struct { |
| 1486 | } else { | 1490 | } else { |
| 1487 | _ = try attributes.removeFnAttr(.sanitize_thread); | 1491 | _ = try attributes.removeFnAttr(.sanitize_thread); |
| 1488 | } | 1492 | } |
| 1489 | const is_naked = fn_info.cc == .Naked; | 1493 | const is_naked = fn_info.cc == .naked; |
| 1490 | if (owner_mod.fuzz and !func_analysis.disable_instrumentation and !is_naked) { | 1494 | if (owner_mod.fuzz and !func_analysis.disable_instrumentation and !is_naked) { |
| 1491 | try attributes.addFnAttr(.optforfuzzing, &o.builder); | 1495 | try attributes.addFnAttr(.optforfuzzing, &o.builder); |
| 1492 | _ = try attributes.removeFnAttr(.skipprofile); | 1496 | _ = try attributes.removeFnAttr(.skipprofile); |
| ... | @@ -1784,7 +1788,7 @@ pub const Object = struct { | ... | @@ -1784,7 +1788,7 @@ pub const Object = struct { |
| 1784 | .liveness = liveness, | 1788 | .liveness = liveness, |
| 1785 | .ng = &ng, | 1789 | .ng = &ng, |
| 1786 | .wip = wip, | 1790 | .wip = wip, |
| 1787 | .is_naked = fn_info.cc == .Naked, | 1791 | .is_naked = fn_info.cc == .naked, |
| 1788 | .fuzz = fuzz, | 1792 | .fuzz = fuzz, |
| 1789 | .ret_ptr = ret_ptr, | 1793 | .ret_ptr = ret_ptr, |
| 1790 | .args = args.items, | 1794 | .args = args.items, |
| ... | @@ -3038,14 +3042,33 @@ pub const Object = struct { | ... | @@ -3038,14 +3042,33 @@ pub const Object = struct { |
| 3038 | llvm_arg_i += 1; | 3042 | llvm_arg_i += 1; |
| 3039 | } | 3043 | } |
| 3040 | 3044 | ||
| 3041 | switch (fn_info.cc) { | 3045 | if (fn_info.cc == .@"async") { |
| 3042 | .Unspecified, .Inline => function_index.setCallConv(.fastcc, &o.builder), | 3046 | @panic("TODO: LLVM backend lower async function"); |
| 3043 | .Naked => try attributes.addFnAttr(.naked, &o.builder), | 3047 | } |
| 3044 | .Async => { | 3048 | |
| 3045 | function_index.setCallConv(.fastcc, &o.builder); | 3049 | { |
| 3046 | @panic("TODO: LLVM backend lower async function"); | 3050 | const cc_info = toLlvmCallConv(fn_info.cc, target).?; |
| 3047 | }, | 3051 | |
| 3048 | else => function_index.setCallConv(toLlvmCallConv(fn_info.cc, target), &o.builder), | 3052 | function_index.setCallConv(cc_info.llvm_cc, &o.builder); |
| 3053 | |||
| 3054 | if (cc_info.align_stack) { | ||
| 3055 | try attributes.addFnAttr(.{ .alignstack = .fromByteUnits(target.stackAlignment()) }, &o.builder); | ||
| 3056 | } else { | ||
| 3057 | _ = try attributes.removeFnAttr(.alignstack); | ||
| 3058 | } | ||
| 3059 | |||
| 3060 | if (cc_info.naked) { | ||
| 3061 | try attributes.addFnAttr(.naked, &o.builder); | ||
| 3062 | } else { | ||
| 3063 | _ = try attributes.removeFnAttr(.naked); | ||
| 3064 | } | ||
| 3065 | |||
| 3066 | for (0..cc_info.inreg_param_count) |param_idx| { | ||
| 3067 | try attributes.addParamAttr(param_idx, .inreg, &o.builder); | ||
| 3068 | } | ||
| 3069 | for (cc_info.inreg_param_count..std.math.maxInt(u2)) |param_idx| { | ||
| 3070 | _ = try attributes.removeParamAttr(param_idx, .inreg); | ||
| 3071 | } | ||
| 3049 | } | 3072 | } |
| 3050 | 3073 | ||
| 3051 | if (resolved.alignment != .none) | 3074 | if (resolved.alignment != .none) |
| ... | @@ -3061,7 +3084,7 @@ pub const Object = struct { | ... | @@ -3061,7 +3084,7 @@ pub const Object = struct { |
| 3061 | // suppress generation of the prologue and epilogue, and the prologue is where the | 3084 | // suppress generation of the prologue and epilogue, and the prologue is where the |
| 3062 | // frame pointer normally gets set up. At time of writing, this is the case for at | 3085 | // frame pointer normally gets set up. At time of writing, this is the case for at |
| 3063 | // least x86 and RISC-V. | 3086 | // least x86 and RISC-V. |
| 3064 | owner_mod.omit_frame_pointer or fn_info.cc == .Naked, | 3087 | owner_mod.omit_frame_pointer or fn_info.cc == .naked, |
| 3065 | ); | 3088 | ); |
| 3066 | 3089 | ||
| 3067 | if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder); | 3090 | if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder); |
| ... | @@ -4618,9 +4641,14 @@ pub const Object = struct { | ... | @@ -4618,9 +4641,14 @@ pub const Object = struct { |
| 4618 | if (!param_ty.isPtrLikeOptional(zcu) and !ptr_info.flags.is_allowzero) { | 4641 | if (!param_ty.isPtrLikeOptional(zcu) and !ptr_info.flags.is_allowzero) { |
| 4619 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); | 4642 | try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder); |
| 4620 | } | 4643 | } |
| 4621 | if (fn_info.cc == .Interrupt) { | 4644 | switch (fn_info.cc) { |
| 4622 | const child_type = try lowerType(o, Type.fromInterned(ptr_info.child)); | 4645 | else => {}, |
| 4623 | try attributes.addParamAttr(llvm_arg_i, .{ .byval = child_type }, &o.builder); | 4646 | .x86_64_interrupt, |
| 4647 | .x86_interrupt, | ||
| 4648 | => { | ||
| 4649 | const child_type = try lowerType(o, Type.fromInterned(ptr_info.child)); | ||
| 4650 | try attributes.addParamAttr(llvm_arg_i, .{ .byval = child_type }, &o.builder); | ||
| 4651 | }, | ||
| 4624 | } | 4652 | } |
| 4625 | if (ptr_info.flags.is_const) { | 4653 | if (ptr_info.flags.is_const) { |
| 4626 | try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder); | 4654 | try attributes.addParamAttr(llvm_arg_i, .readonly, &o.builder); |
| ... | @@ -5677,7 +5705,7 @@ pub const FuncGen = struct { | ... | @@ -5677,7 +5705,7 @@ pub const FuncGen = struct { |
| 5677 | .always_tail => .musttail, | 5705 | .always_tail => .musttail, |
| 5678 | .async_kw, .no_async, .always_inline, .compile_time => unreachable, | 5706 | .async_kw, .no_async, .always_inline, .compile_time => unreachable, |
| 5679 | }, | 5707 | }, |
| 5680 | toLlvmCallConv(fn_info.cc, target), | 5708 | toLlvmCallConvTag(fn_info.cc, target).?, |
| 5681 | try attributes.finish(&o.builder), | 5709 | try attributes.finish(&o.builder), |
| 5682 | try o.lowerType(zig_fn_ty), | 5710 | try o.lowerType(zig_fn_ty), |
| 5683 | llvm_fn, | 5711 | llvm_fn, |
| ... | @@ -5756,7 +5784,7 @@ pub const FuncGen = struct { | ... | @@ -5756,7 +5784,7 @@ pub const FuncGen = struct { |
| 5756 | _ = try fg.wip.callIntrinsicAssumeCold(); | 5784 | _ = try fg.wip.callIntrinsicAssumeCold(); |
| 5757 | _ = try fg.wip.call( | 5785 | _ = try fg.wip.call( |
| 5758 | .normal, | 5786 | .normal, |
| 5759 | toLlvmCallConv(fn_info.cc, target), | 5787 | toLlvmCallConvTag(fn_info.cc, target).?, |
| 5760 | .none, | 5788 | .none, |
| 5761 | panic_global.typeOf(&o.builder), | 5789 | panic_global.typeOf(&o.builder), |
| 5762 | panic_global.toValue(&o.builder), | 5790 | panic_global.toValue(&o.builder), |
| ... | @@ -11554,36 +11582,146 @@ fn toLlvmAtomicRmwBinOp( | ... | @@ -11554,36 +11582,146 @@ fn toLlvmAtomicRmwBinOp( |
| 11554 | }; | 11582 | }; |
| 11555 | } | 11583 | } |
| 11556 | 11584 | ||
| 11557 | fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) Builder.CallConv { | 11585 | const CallingConventionInfo = struct { |
| 11558 | return switch (cc) { | 11586 | /// The LLVM calling convention to use. |
| 11559 | .Unspecified, .Inline, .Async => .fastcc, | 11587 | llvm_cc: Builder.CallConv, |
| 11560 | .C, .Naked => .ccc, | 11588 | /// Whether to use an `alignstack` attribute to forcibly re-align the stack pointer in the function's prologue. |
| 11561 | .Stdcall => .x86_stdcallcc, | 11589 | align_stack: bool, |
| 11562 | .Fastcall => .x86_fastcallcc, | 11590 | /// Whether the function needs a `naked` attribute. |
| 11563 | .Vectorcall => return switch (target.cpu.arch) { | 11591 | naked: bool, |
| 11564 | .x86, .x86_64 => .x86_vectorcallcc, | 11592 | /// How many leading parameters to apply the `inreg` attribute to. |
| 11565 | .aarch64, .aarch64_be => .aarch64_vector_pcs, | 11593 | inreg_param_count: u2 = 0, |
| 11566 | else => unreachable, | 11594 | }; |
| 11567 | }, | 11595 | |
| 11568 | .Thiscall => .x86_thiscallcc, | 11596 | pub fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) ?CallingConventionInfo { |
| 11569 | .APCS => .arm_apcscc, | 11597 | const llvm_cc = toLlvmCallConvTag(cc, target) orelse return null; |
| 11570 | .AAPCS => .arm_aapcscc, | 11598 | const incoming_stack_alignment: ?u64, const register_params: u2 = switch (cc) { |
| 11571 | .AAPCSVFP => .arm_aapcs_vfpcc, | 11599 | inline else => |pl| switch (@TypeOf(pl)) { |
| 11572 | .Interrupt => return switch (target.cpu.arch) { | 11600 | void => .{ null, 0 }, |
| 11573 | .x86, .x86_64 => .x86_intrcc, | 11601 | std.builtin.CallingConvention.CommonOptions => .{ pl.incoming_stack_alignment, 0 }, |
| 11574 | .avr => .avr_intrcc, | 11602 | std.builtin.CallingConvention.X86RegparmOptions => .{ pl.incoming_stack_alignment, pl.register_params }, |
| 11575 | .msp430 => .msp430_intrcc, | ||
| 11576 | else => unreachable, | ||
| 11577 | }, | ||
| 11578 | .Signal => .avr_signalcc, | ||
| 11579 | .SysV => .x86_64_sysvcc, | ||
| 11580 | .Win64 => .win64cc, | ||
| 11581 | .Kernel => return switch (target.cpu.arch) { | ||
| 11582 | .nvptx, .nvptx64 => .ptx_kernel, | ||
| 11583 | .amdgcn => .amdgpu_kernel, | ||
| 11584 | else => unreachable, | 11603 | else => unreachable, |
| 11585 | }, | 11604 | }, |
| 11586 | .Vertex, .Fragment => unreachable, | 11605 | }; |
| 11606 | return .{ | ||
| 11607 | .llvm_cc = llvm_cc, | ||
| 11608 | .align_stack = if (incoming_stack_alignment) |a| need_align: { | ||
| 11609 | const normal_stack_align = target.stackAlignment(); | ||
| 11610 | break :need_align a < normal_stack_align; | ||
| 11611 | } else false, | ||
| 11612 | .naked = cc == .naked, | ||
| 11613 | .inreg_param_count = register_params, | ||
| 11614 | }; | ||
| 11615 | } | ||
| 11616 | fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Target) ?Builder.CallConv { | ||
| 11617 | if (target.cCallingConvention()) |default_c| { | ||
| 11618 | if (cc_tag == default_c) { | ||
| 11619 | return .ccc; | ||
| 11620 | } | ||
| 11621 | } | ||
| 11622 | return switch (cc_tag) { | ||
| 11623 | .@"inline" => unreachable, | ||
| 11624 | .auto, .@"async" => .fastcc, | ||
| 11625 | .naked => .ccc, | ||
| 11626 | .x86_64_sysv => .x86_64_sysvcc, | ||
| 11627 | .x86_64_win => .win64cc, | ||
| 11628 | .x86_64_regcall_v3_sysv => if (target.cpu.arch == .x86_64 and target.os.tag != .windows) | ||
| 11629 | .x86_regcallcc | ||
| 11630 | else | ||
| 11631 | null, | ||
| 11632 | .x86_64_regcall_v4_win => if (target.cpu.arch == .x86_64 and target.os.tag == .windows) | ||
| 11633 | .x86_regcallcc // we use the "RegCallv4" module flag to make this correct | ||
| 11634 | else | ||
| 11635 | null, | ||
| 11636 | .x86_64_vectorcall => .x86_vectorcallcc, | ||
| 11637 | .x86_64_interrupt => .x86_intrcc, | ||
| 11638 | .x86_stdcall => .x86_stdcallcc, | ||
| 11639 | .x86_fastcall => .x86_fastcallcc, | ||
| 11640 | .x86_thiscall => .x86_thiscallcc, | ||
| 11641 | .x86_regcall_v3 => if (target.cpu.arch == .x86 and target.os.tag != .windows) | ||
| 11642 | .x86_regcallcc | ||
| 11643 | else | ||
| 11644 | null, | ||
| 11645 | .x86_regcall_v4_win => if (target.cpu.arch == .x86 and target.os.tag == .windows) | ||
| 11646 | .x86_regcallcc // we use the "RegCallv4" module flag to make this correct | ||
| 11647 | else | ||
| 11648 | null, | ||
| 11649 | .x86_vectorcall => .x86_vectorcallcc, | ||
| 11650 | .x86_interrupt => .x86_intrcc, | ||
| 11651 | .aarch64_vfabi => .aarch64_vector_pcs, | ||
| 11652 | .aarch64_vfabi_sve => .aarch64_sve_vector_pcs, | ||
| 11653 | .arm_apcs => .arm_apcscc, | ||
| 11654 | .arm_aapcs => .arm_aapcscc, | ||
| 11655 | .arm_aapcs_vfp => .arm_aapcs_vfpcc, | ||
| 11656 | .riscv64_lp64_v => .riscv_vectorcallcc, | ||
| 11657 | .riscv32_ilp32_v => .riscv_vectorcallcc, | ||
| 11658 | .avr_builtin => .avr_builtincc, | ||
| 11659 | .avr_signal => .avr_signalcc, | ||
| 11660 | .avr_interrupt => .avr_intrcc, | ||
| 11661 | .m68k_rtd => .m68k_rtdcc, | ||
| 11662 | .m68k_interrupt => .m68k_intrcc, | ||
| 11663 | .amdgcn_kernel => .amdgpu_kernel, | ||
| 11664 | .amdgcn_cs => .amdgpu_cs, | ||
| 11665 | .nvptx_device => .ptx_device, | ||
| 11666 | .nvptx_kernel => .ptx_kernel, | ||
| 11667 | |||
| 11668 | // All the calling conventions which LLVM does not have a general representation for. | ||
| 11669 | // Note that these are often still supported through the `cCallingConvention` path above via `ccc`. | ||
| 11670 | .x86_sysv, | ||
| 11671 | .x86_win, | ||
| 11672 | .x86_thiscall_mingw, | ||
| 11673 | .aarch64_aapcs, | ||
| 11674 | .aarch64_aapcs_darwin, | ||
| 11675 | .aarch64_aapcs_win, | ||
| 11676 | .arm_aapcs16_vfp, | ||
| 11677 | .arm_interrupt, | ||
| 11678 | .mips64_n64, | ||
| 11679 | .mips64_n32, | ||
| 11680 | .mips64_interrupt, | ||
| 11681 | .mips_o32, | ||
| 11682 | .mips_interrupt, | ||
| 11683 | .riscv64_lp64, | ||
| 11684 | .riscv64_interrupt, | ||
| 11685 | .riscv32_ilp32, | ||
| 11686 | .riscv32_interrupt, | ||
| 11687 | .sparc64_sysv, | ||
| 11688 | .sparc_sysv, | ||
| 11689 | .powerpc64_elf, | ||
| 11690 | .powerpc64_elf_altivec, | ||
| 11691 | .powerpc64_elf_v2, | ||
| 11692 | .powerpc_sysv, | ||
| 11693 | .powerpc_sysv_altivec, | ||
| 11694 | .powerpc_aix, | ||
| 11695 | .powerpc_aix_altivec, | ||
| 11696 | .wasm_watc, | ||
| 11697 | .arc_sysv, | ||
| 11698 | .avr_gnu, | ||
| 11699 | .bpf_std, | ||
| 11700 | .csky_sysv, | ||
| 11701 | .csky_interrupt, | ||
| 11702 | .hexagon_sysv, | ||
| 11703 | .hexagon_sysv_hvx, | ||
| 11704 | .lanai_sysv, | ||
| 11705 | .loongarch64_lp64, | ||
| 11706 | .loongarch32_ilp32, | ||
| 11707 | .m68k_sysv, | ||
| 11708 | .m68k_gnu, | ||
| 11709 | .msp430_eabi, | ||
| 11710 | .propeller1_sysv, | ||
| 11711 | .propeller2_sysv, | ||
| 11712 | .s390x_sysv, | ||
| 11713 | .s390x_sysv_vx, | ||
| 11714 | .ve_sysv, | ||
| 11715 | .xcore_xs1, | ||
| 11716 | .xcore_xs2, | ||
| 11717 | .xtensa_call0, | ||
| 11718 | .xtensa_windowed, | ||
| 11719 | .amdgcn_device, | ||
| 11720 | .spirv_device, | ||
| 11721 | .spirv_kernel, | ||
| 11722 | .spirv_fragment, | ||
| 11723 | .spirv_vertex, | ||
| 11724 | => null, | ||
| 11587 | }; | 11725 | }; |
| 11588 | } | 11726 | } |
| 11589 | 11727 | ||
| ... | @@ -11711,31 +11849,27 @@ fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Targe | ... | @@ -11711,31 +11849,27 @@ fn firstParamSRet(fn_info: InternPool.Key.FuncType, zcu: *Zcu, target: std.Targe |
| 11711 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false; | 11849 | if (!return_type.hasRuntimeBitsIgnoreComptime(zcu)) return false; |
| 11712 | 11850 | ||
| 11713 | return switch (fn_info.cc) { | 11851 | return switch (fn_info.cc) { |
| 11714 | .Unspecified, .Inline => returnTypeByRef(zcu, target, return_type), | 11852 | .auto => returnTypeByRef(zcu, target, return_type), |
| 11715 | .C => switch (target.cpu.arch) { | 11853 | .x86_64_sysv => firstParamSRetSystemV(return_type, zcu, target), |
| 11716 | .mips, .mipsel => switch (mips_c_abi.classifyType(return_type, zcu, .ret)) { | 11854 | .x86_64_win => x86_64_abi.classifyWindows(return_type, zcu) == .memory, |
| 11717 | .memory, .i32_array => true, | 11855 | .x86_sysv, .x86_win => isByRef(return_type, zcu), |
| 11718 | .byval => false, | 11856 | .x86_stdcall => !isScalar(zcu, return_type), |
| 11719 | }, | 11857 | .wasm_watc => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect, |
| 11720 | .x86 => isByRef(return_type, zcu), | 11858 | .aarch64_aapcs, |
| 11721 | .x86_64 => switch (target.os.tag) { | 11859 | .aarch64_aapcs_darwin, |
| 11722 | .windows => x86_64_abi.classifyWindows(return_type, zcu) == .memory, | 11860 | .aarch64_aapcs_win, |
| 11723 | else => firstParamSRetSystemV(return_type, zcu, target), | 11861 | => aarch64_c_abi.classifyType(return_type, zcu) == .memory, |
| 11724 | }, | 11862 | .arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) { |
| 11725 | .wasm32 => wasm_c_abi.classifyType(return_type, zcu)[0] == .indirect, | 11863 | .memory, .i64_array => true, |
| 11726 | .aarch64, .aarch64_be => aarch64_c_abi.classifyType(return_type, zcu) == .memory, | 11864 | .i32_array => |size| size != 1, |
| 11727 | .arm, .armeb => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) { | 11865 | .byval => false, |
| 11728 | .memory, .i64_array => true, | ||
| 11729 | .i32_array => |size| size != 1, | ||
| 11730 | .byval => false, | ||
| 11731 | }, | ||
| 11732 | .riscv32, .riscv64 => riscv_c_abi.classifyType(return_type, zcu) == .memory, | ||
| 11733 | else => false, // TODO investigate C ABI for other architectures | ||
| 11734 | }, | 11866 | }, |
| 11735 | .SysV => firstParamSRetSystemV(return_type, zcu, target), | 11867 | .riscv64_lp64, .riscv32_ilp32 => riscv_c_abi.classifyType(return_type, zcu) == .memory, |
| 11736 | .Win64 => x86_64_abi.classifyWindows(return_type, zcu) == .memory, | 11868 | .mips_o32 => switch (mips_c_abi.classifyType(return_type, zcu, .ret)) { |
| 11737 | .Stdcall => !isScalar(zcu, return_type), | 11869 | .memory, .i32_array => true, |
| 11738 | else => false, | 11870 | .byval => false, |
| 11871 | }, | ||
| 11872 | else => false, // TODO: investigate other targets/callconvs | ||
| 11739 | }; | 11873 | }; |
| 11740 | } | 11874 | } |
| 11741 | 11875 | ||
| ... | @@ -11761,82 +11895,64 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu | ... | @@ -11761,82 +11895,64 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.Error!Bu |
| 11761 | } | 11895 | } |
| 11762 | const target = zcu.getTarget(); | 11896 | const target = zcu.getTarget(); |
| 11763 | switch (fn_info.cc) { | 11897 | switch (fn_info.cc) { |
| 11764 | .Unspecified, | 11898 | .@"inline" => unreachable, |
| 11765 | .Inline, | 11899 | .auto => return if (returnTypeByRef(zcu, target, return_type)) .void else o.lowerType(return_type), |
| 11766 | => return if (returnTypeByRef(zcu, target, return_type)) .void else o.lowerType(return_type), | 11900 | |
| 11767 | 11901 | .x86_64_sysv => return lowerSystemVFnRetTy(o, fn_info), | |
| 11768 | .C => { | 11902 | .x86_64_win => return lowerWin64FnRetTy(o, fn_info), |
| 11769 | switch (target.cpu.arch) { | 11903 | .x86_stdcall => return if (isScalar(zcu, return_type)) o.lowerType(return_type) else .void, |
| 11770 | .mips, .mipsel => { | 11904 | .x86_sysv, .x86_win => return if (isByRef(return_type, zcu)) .void else o.lowerType(return_type), |
| 11771 | switch (mips_c_abi.classifyType(return_type, zcu, .ret)) { | 11905 | .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => switch (aarch64_c_abi.classifyType(return_type, zcu)) { |
| 11772 | .memory, .i32_array => return .void, | 11906 | .memory => return .void, |
| 11773 | .byval => return o.lowerType(return_type), | 11907 | .float_array => return o.lowerType(return_type), |
| 11774 | } | 11908 | .byval => return o.lowerType(return_type), |
| 11775 | }, | 11909 | .integer => return o.builder.intType(@intCast(return_type.bitSize(zcu))), |
| 11776 | .x86 => return if (isByRef(return_type, zcu)) .void else o.lowerType(return_type), | 11910 | .double_integer => return o.builder.arrayType(2, .i64), |
| 11777 | .x86_64 => switch (target.os.tag) { | 11911 | }, |
| 11778 | .windows => return lowerWin64FnRetTy(o, fn_info), | 11912 | .arm_aapcs, .arm_aapcs_vfp => switch (arm_c_abi.classifyType(return_type, zcu, .ret)) { |
| 11779 | else => return lowerSystemVFnRetTy(o, fn_info), | 11913 | .memory, .i64_array => return .void, |
| 11780 | }, | 11914 | .i32_array => |len| return if (len == 1) .i32 else .void, |
| 11781 | .wasm32 => { | 11915 | .byval => return o.lowerType(return_type), |
| 11782 | if (isScalar(zcu, return_type)) { | 11916 | }, |
| 11783 | return o.lowerType(return_type); | 11917 | .mips_o32 => switch (mips_c_abi.classifyType(return_type, zcu, .ret)) { |
| 11784 | } | 11918 | .memory, .i32_array => return .void, |
| 11785 | const classes = wasm_c_abi.classifyType(return_type, zcu); | 11919 | .byval => return o.lowerType(return_type), |
| 11786 | if (classes[0] == .indirect or classes[0] == .none) { | 11920 | }, |
| 11787 | return .void; | 11921 | .riscv64_lp64, .riscv32_ilp32 => switch (riscv_c_abi.classifyType(return_type, zcu)) { |
| 11788 | } | 11922 | .memory => return .void, |
| 11789 | 11923 | .integer => { | |
| 11790 | assert(classes[0] == .direct and classes[1] == .none); | 11924 | return o.builder.intType(@intCast(return_type.bitSize(zcu))); |
| 11791 | const scalar_type = wasm_c_abi.scalarType(return_type, zcu); | 11925 | }, |
| 11792 | return o.builder.intType(@intCast(scalar_type.abiSize(zcu) * 8)); | 11926 | .double_integer => { |
| 11793 | }, | 11927 | return o.builder.structType(.normal, &.{ .i64, .i64 }); |
| 11794 | .aarch64, .aarch64_be => { | 11928 | }, |
| 11795 | switch (aarch64_c_abi.classifyType(return_type, zcu)) { | 11929 | .byval => return o.lowerType(return_type), |
| 11796 | .memory => return .void, | 11930 | .fields => { |
| 11797 | .float_array => return o.lowerType(return_type), | 11931 | var types_len: usize = 0; |
| 11798 | .byval => return o.lowerType(return_type), | 11932 | var types: [8]Builder.Type = undefined; |
| 11799 | .integer => return o.builder.intType(@intCast(return_type.bitSize(zcu))), | 11933 | for (0..return_type.structFieldCount(zcu)) |field_index| { |
| 11800 | .double_integer => return o.builder.arrayType(2, .i64), | 11934 | const field_ty = return_type.fieldType(field_index, zcu); |
| 11801 | } | 11935 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; |
| 11802 | }, | 11936 | types[types_len] = try o.lowerType(field_ty); |
| 11803 | .arm, .armeb => { | 11937 | types_len += 1; |
| 11804 | switch (arm_c_abi.classifyType(return_type, zcu, .ret)) { | 11938 | } |
| 11805 | .memory, .i64_array => return .void, | 11939 | return o.builder.structType(.normal, types[0..types_len]); |
| 11806 | .i32_array => |len| return if (len == 1) .i32 else .void, | 11940 | }, |
| 11807 | .byval => return o.lowerType(return_type), | 11941 | }, |
| 11808 | } | 11942 | .wasm_watc => { |
| 11809 | }, | 11943 | if (isScalar(zcu, return_type)) { |
| 11810 | .riscv32, .riscv64 => { | 11944 | return o.lowerType(return_type); |
| 11811 | switch (riscv_c_abi.classifyType(return_type, zcu)) { | 11945 | } |
| 11812 | .memory => return .void, | 11946 | const classes = wasm_c_abi.classifyType(return_type, zcu); |
| 11813 | .integer => { | 11947 | if (classes[0] == .indirect or classes[0] == .none) { |
| 11814 | return o.builder.intType(@intCast(return_type.bitSize(zcu))); | 11948 | return .void; |
| 11815 | }, | ||
| 11816 | .double_integer => { | ||
| 11817 | return o.builder.structType(.normal, &.{ .i64, .i64 }); | ||
| 11818 | }, | ||
| 11819 | .byval => return o.lowerType(return_type), | ||
| 11820 | .fields => { | ||
| 11821 | var types_len: usize = 0; | ||
| 11822 | var types: [8]Builder.Type = undefined; | ||
| 11823 | for (0..return_type.structFieldCount(zcu)) |field_index| { | ||
| 11824 | const field_ty = return_type.fieldType(field_index, zcu); | ||
| 11825 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | ||
| 11826 | types[types_len] = try o.lowerType(field_ty); | ||
| 11827 | types_len += 1; | ||
| 11828 | } | ||
| 11829 | return o.builder.structType(.normal, types[0..types_len]); | ||
| 11830 | }, | ||
| 11831 | } | ||
| 11832 | }, | ||
| 11833 | // TODO investigate C ABI for other architectures | ||
| 11834 | else => return o.lowerType(return_type), | ||
| 11835 | } | 11949 | } |
| 11950 | |||
| 11951 | assert(classes[0] == .direct and classes[1] == .none); | ||
| 11952 | const scalar_type = wasm_c_abi.scalarType(return_type, zcu); | ||
| 11953 | return o.builder.intType(@intCast(scalar_type.abiSize(zcu) * 8)); | ||
| 11836 | }, | 11954 | }, |
| 11837 | .Win64 => return lowerWin64FnRetTy(o, fn_info), | 11955 | // TODO investigate other callconvs |
| 11838 | .SysV => return lowerSystemVFnRetTy(o, fn_info), | ||
| 11839 | .Stdcall => return if (isScalar(zcu, return_type)) o.lowerType(return_type) else .void, | ||
| 11840 | else => return o.lowerType(return_type), | 11956 | else => return o.lowerType(return_type), |
| 11841 | } | 11957 | } |
| 11842 | } | 11958 | } |
| ... | @@ -11989,7 +12105,8 @@ const ParamTypeIterator = struct { | ... | @@ -11989,7 +12105,8 @@ const ParamTypeIterator = struct { |
| 11989 | return .no_bits; | 12105 | return .no_bits; |
| 11990 | } | 12106 | } |
| 11991 | switch (it.fn_info.cc) { | 12107 | switch (it.fn_info.cc) { |
| 11992 | .Unspecified, .Inline => { | 12108 | .@"inline" => unreachable, |
| 12109 | .auto => { | ||
| 11993 | it.zig_index += 1; | 12110 | it.zig_index += 1; |
| 11994 | it.llvm_index += 1; | 12111 | it.llvm_index += 1; |
| 11995 | if (ty.isSlice(zcu) or | 12112 | if (ty.isSlice(zcu) or |
| ... | @@ -12010,97 +12127,12 @@ const ParamTypeIterator = struct { | ... | @@ -12010,97 +12127,12 @@ const ParamTypeIterator = struct { |
| 12010 | return .byval; | 12127 | return .byval; |
| 12011 | } | 12128 | } |
| 12012 | }, | 12129 | }, |
| 12013 | .Async => { | 12130 | .@"async" => { |
| 12014 | @panic("TODO implement async function lowering in the LLVM backend"); | 12131 | @panic("TODO implement async function lowering in the LLVM backend"); |
| 12015 | }, | 12132 | }, |
| 12016 | .C => switch (target.cpu.arch) { | 12133 | .x86_64_sysv => return it.nextSystemV(ty), |
| 12017 | .mips, .mipsel => { | 12134 | .x86_64_win => return it.nextWin64(ty), |
| 12018 | it.zig_index += 1; | 12135 | .x86_stdcall => { |
| 12019 | it.llvm_index += 1; | ||
| 12020 | switch (mips_c_abi.classifyType(ty, zcu, .arg)) { | ||
| 12021 | .memory => { | ||
| 12022 | it.byval_attr = true; | ||
| 12023 | return .byref; | ||
| 12024 | }, | ||
| 12025 | .byval => return .byval, | ||
| 12026 | .i32_array => |size| return Lowering{ .i32_array = size }, | ||
| 12027 | } | ||
| 12028 | }, | ||
| 12029 | .x86_64 => switch (target.os.tag) { | ||
| 12030 | .windows => return it.nextWin64(ty), | ||
| 12031 | else => return it.nextSystemV(ty), | ||
| 12032 | }, | ||
| 12033 | .wasm32 => { | ||
| 12034 | it.zig_index += 1; | ||
| 12035 | it.llvm_index += 1; | ||
| 12036 | if (isScalar(zcu, ty)) { | ||
| 12037 | return .byval; | ||
| 12038 | } | ||
| 12039 | const classes = wasm_c_abi.classifyType(ty, zcu); | ||
| 12040 | if (classes[0] == .indirect) { | ||
| 12041 | return .byref; | ||
| 12042 | } | ||
| 12043 | return .abi_sized_int; | ||
| 12044 | }, | ||
| 12045 | .aarch64, .aarch64_be => { | ||
| 12046 | it.zig_index += 1; | ||
| 12047 | it.llvm_index += 1; | ||
| 12048 | switch (aarch64_c_abi.classifyType(ty, zcu)) { | ||
| 12049 | .memory => return .byref_mut, | ||
| 12050 | .float_array => |len| return Lowering{ .float_array = len }, | ||
| 12051 | .byval => return .byval, | ||
| 12052 | .integer => { | ||
| 12053 | it.types_len = 1; | ||
| 12054 | it.types_buffer[0] = .i64; | ||
| 12055 | return .multiple_llvm_types; | ||
| 12056 | }, | ||
| 12057 | .double_integer => return Lowering{ .i64_array = 2 }, | ||
| 12058 | } | ||
| 12059 | }, | ||
| 12060 | .arm, .armeb => { | ||
| 12061 | it.zig_index += 1; | ||
| 12062 | it.llvm_index += 1; | ||
| 12063 | switch (arm_c_abi.classifyType(ty, zcu, .arg)) { | ||
| 12064 | .memory => { | ||
| 12065 | it.byval_attr = true; | ||
| 12066 | return .byref; | ||
| 12067 | }, | ||
| 12068 | .byval => return .byval, | ||
| 12069 | .i32_array => |size| return Lowering{ .i32_array = size }, | ||
| 12070 | .i64_array => |size| return Lowering{ .i64_array = size }, | ||
| 12071 | } | ||
| 12072 | }, | ||
| 12073 | .riscv32, .riscv64 => { | ||
| 12074 | it.zig_index += 1; | ||
| 12075 | it.llvm_index += 1; | ||
| 12076 | switch (riscv_c_abi.classifyType(ty, zcu)) { | ||
| 12077 | .memory => return .byref_mut, | ||
| 12078 | .byval => return .byval, | ||
| 12079 | .integer => return .abi_sized_int, | ||
| 12080 | .double_integer => return Lowering{ .i64_array = 2 }, | ||
| 12081 | .fields => { | ||
| 12082 | it.types_len = 0; | ||
| 12083 | for (0..ty.structFieldCount(zcu)) |field_index| { | ||
| 12084 | const field_ty = ty.fieldType(field_index, zcu); | ||
| 12085 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | ||
| 12086 | it.types_buffer[it.types_len] = try it.object.lowerType(field_ty); | ||
| 12087 | it.types_len += 1; | ||
| 12088 | } | ||
| 12089 | it.llvm_index += it.types_len - 1; | ||
| 12090 | return .multiple_llvm_types; | ||
| 12091 | }, | ||
| 12092 | } | ||
| 12093 | }, | ||
| 12094 | // TODO investigate C ABI for other architectures | ||
| 12095 | else => { | ||
| 12096 | it.zig_index += 1; | ||
| 12097 | it.llvm_index += 1; | ||
| 12098 | return .byval; | ||
| 12099 | }, | ||
| 12100 | }, | ||
| 12101 | .Win64 => return it.nextWin64(ty), | ||
| 12102 | .SysV => return it.nextSystemV(ty), | ||
| 12103 | .Stdcall => { | ||
| 12104 | it.zig_index += 1; | 12136 | it.zig_index += 1; |
| 12105 | it.llvm_index += 1; | 12137 | it.llvm_index += 1; |
| 12106 | 12138 | ||
| ... | @@ -12111,6 +12143,80 @@ const ParamTypeIterator = struct { | ... | @@ -12111,6 +12143,80 @@ const ParamTypeIterator = struct { |
| 12111 | return .byref; | 12143 | return .byref; |
| 12112 | } | 12144 | } |
| 12113 | }, | 12145 | }, |
| 12146 | .aarch64_aapcs, .aarch64_aapcs_darwin, .aarch64_aapcs_win => { | ||
| 12147 | it.zig_index += 1; | ||
| 12148 | it.llvm_index += 1; | ||
| 12149 | switch (aarch64_c_abi.classifyType(ty, zcu)) { | ||
| 12150 | .memory => return .byref_mut, | ||
| 12151 | .float_array => |len| return Lowering{ .float_array = len }, | ||
| 12152 | .byval => return .byval, | ||
| 12153 | .integer => { | ||
| 12154 | it.types_len = 1; | ||
| 12155 | it.types_buffer[0] = .i64; | ||
| 12156 | return .multiple_llvm_types; | ||
| 12157 | }, | ||
| 12158 | .double_integer => return Lowering{ .i64_array = 2 }, | ||
| 12159 | } | ||
| 12160 | }, | ||
| 12161 | .arm_aapcs, .arm_aapcs_vfp => { | ||
| 12162 | it.zig_index += 1; | ||
| 12163 | it.llvm_index += 1; | ||
| 12164 | switch (arm_c_abi.classifyType(ty, zcu, .arg)) { | ||
| 12165 | .memory => { | ||
| 12166 | it.byval_attr = true; | ||
| 12167 | return .byref; | ||
| 12168 | }, | ||
| 12169 | .byval => return .byval, | ||
| 12170 | .i32_array => |size| return Lowering{ .i32_array = size }, | ||
| 12171 | .i64_array => |size| return Lowering{ .i64_array = size }, | ||
| 12172 | } | ||
| 12173 | }, | ||
| 12174 | .mips_o32 => { | ||
| 12175 | it.zig_index += 1; | ||
| 12176 | it.llvm_index += 1; | ||
| 12177 | switch (mips_c_abi.classifyType(ty, zcu, .arg)) { | ||
| 12178 | .memory => { | ||
| 12179 | it.byval_attr = true; | ||
| 12180 | return .byref; | ||
| 12181 | }, | ||
| 12182 | .byval => return .byval, | ||
| 12183 | .i32_array => |size| return Lowering{ .i32_array = size }, | ||
| 12184 | } | ||
| 12185 | }, | ||
| 12186 | .riscv64_lp64, .riscv32_ilp32 => { | ||
| 12187 | it.zig_index += 1; | ||
| 12188 | it.llvm_index += 1; | ||
| 12189 | switch (riscv_c_abi.classifyType(ty, zcu)) { | ||
| 12190 | .memory => return .byref_mut, | ||
| 12191 | .byval => return .byval, | ||
| 12192 | .integer => return .abi_sized_int, | ||
| 12193 | .double_integer => return Lowering{ .i64_array = 2 }, | ||
| 12194 | .fields => { | ||
| 12195 | it.types_len = 0; | ||
| 12196 | for (0..ty.structFieldCount(zcu)) |field_index| { | ||
| 12197 | const field_ty = ty.fieldType(field_index, zcu); | ||
| 12198 | if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; | ||
| 12199 | it.types_buffer[it.types_len] = try it.object.lowerType(field_ty); | ||
| 12200 | it.types_len += 1; | ||
| 12201 | } | ||
| 12202 | it.llvm_index += it.types_len - 1; | ||
| 12203 | return .multiple_llvm_types; | ||
| 12204 | }, | ||
| 12205 | } | ||
| 12206 | }, | ||
| 12207 | .wasm_watc => { | ||
| 12208 | it.zig_index += 1; | ||
| 12209 | it.llvm_index += 1; | ||
| 12210 | if (isScalar(zcu, ty)) { | ||
| 12211 | return .byval; | ||
| 12212 | } | ||
| 12213 | const classes = wasm_c_abi.classifyType(ty, zcu); | ||
| 12214 | if (classes[0] == .indirect) { | ||
| 12215 | return .byref; | ||
| 12216 | } | ||
| 12217 | return .abi_sized_int; | ||
| 12218 | }, | ||
| 12219 | // TODO investigate other callconvs | ||
| 12114 | else => { | 12220 | else => { |
| 12115 | it.zig_index += 1; | 12221 | it.zig_index += 1; |
| 12116 | it.llvm_index += 1; | 12222 | it.llvm_index += 1; |
| ... | @@ -12269,7 +12375,7 @@ fn ccAbiPromoteInt( | ... | @@ -12269,7 +12375,7 @@ fn ccAbiPromoteInt( |
| 12269 | ) ?std.builtin.Signedness { | 12375 | ) ?std.builtin.Signedness { |
| 12270 | const target = zcu.getTarget(); | 12376 | const target = zcu.getTarget(); |
| 12271 | switch (cc) { | 12377 | switch (cc) { |
| 12272 | .Unspecified, .Inline, .Async => return null, | 12378 | .auto, .@"inline", .@"async" => return null, |
| 12273 | else => {}, | 12379 | else => {}, |
| 12274 | } | 12380 | } |
| 12275 | const int_info = switch (ty.zigTypeTag(zcu)) { | 12381 | const int_info = switch (ty.zigTypeTag(zcu)) { |
src/codegen/llvm/Builder.zig+13| ... | @@ -2052,6 +2052,7 @@ pub const CallConv = enum(u10) { | ... | @@ -2052,6 +2052,7 @@ pub const CallConv = enum(u10) { |
| 2052 | x86_intrcc, | 2052 | x86_intrcc, |
| 2053 | avr_intrcc, | 2053 | avr_intrcc, |
| 2054 | avr_signalcc, | 2054 | avr_signalcc, |
| 2055 | avr_builtincc, | ||
| 2055 | 2056 | ||
| 2056 | amdgpu_vs = 87, | 2057 | amdgpu_vs = 87, |
| 2057 | amdgpu_gs, | 2058 | amdgpu_gs, |
| ... | @@ -2060,6 +2061,7 @@ pub const CallConv = enum(u10) { | ... | @@ -2060,6 +2061,7 @@ pub const CallConv = enum(u10) { |
| 2060 | amdgpu_kernel, | 2061 | amdgpu_kernel, |
| 2061 | x86_regcallcc, | 2062 | x86_regcallcc, |
| 2062 | amdgpu_hs, | 2063 | amdgpu_hs, |
| 2064 | msp430_builtincc, | ||
| 2063 | 2065 | ||
| 2064 | amdgpu_ls = 95, | 2066 | amdgpu_ls = 95, |
| 2065 | amdgpu_es, | 2067 | amdgpu_es, |
| ... | @@ -2068,9 +2070,15 @@ pub const CallConv = enum(u10) { | ... | @@ -2068,9 +2070,15 @@ pub const CallConv = enum(u10) { |
| 2068 | 2070 | ||
| 2069 | amdgpu_gfx = 100, | 2071 | amdgpu_gfx = 100, |
| 2070 | 2072 | ||
| 2073 | m68k_intrcc, | ||
| 2074 | |||
| 2071 | aarch64_sme_preservemost_from_x0 = 102, | 2075 | aarch64_sme_preservemost_from_x0 = 102, |
| 2072 | aarch64_sme_preservemost_from_x2, | 2076 | aarch64_sme_preservemost_from_x2, |
| 2073 | 2077 | ||
| 2078 | m68k_rtdcc = 106, | ||
| 2079 | |||
| 2080 | riscv_vectorcallcc = 110, | ||
| 2081 | |||
| 2074 | _, | 2082 | _, |
| 2075 | 2083 | ||
| 2076 | pub const default = CallConv.ccc; | 2084 | pub const default = CallConv.ccc; |
| ... | @@ -2115,6 +2123,7 @@ pub const CallConv = enum(u10) { | ... | @@ -2115,6 +2123,7 @@ pub const CallConv = enum(u10) { |
| 2115 | .x86_intrcc, | 2123 | .x86_intrcc, |
| 2116 | .avr_intrcc, | 2124 | .avr_intrcc, |
| 2117 | .avr_signalcc, | 2125 | .avr_signalcc, |
| 2126 | .avr_builtincc, | ||
| 2118 | .amdgpu_vs, | 2127 | .amdgpu_vs, |
| 2119 | .amdgpu_gs, | 2128 | .amdgpu_gs, |
| 2120 | .amdgpu_ps, | 2129 | .amdgpu_ps, |
| ... | @@ -2122,13 +2131,17 @@ pub const CallConv = enum(u10) { | ... | @@ -2122,13 +2131,17 @@ pub const CallConv = enum(u10) { |
| 2122 | .amdgpu_kernel, | 2131 | .amdgpu_kernel, |
| 2123 | .x86_regcallcc, | 2132 | .x86_regcallcc, |
| 2124 | .amdgpu_hs, | 2133 | .amdgpu_hs, |
| 2134 | .msp430_builtincc, | ||
| 2125 | .amdgpu_ls, | 2135 | .amdgpu_ls, |
| 2126 | .amdgpu_es, | 2136 | .amdgpu_es, |
| 2127 | .aarch64_vector_pcs, | 2137 | .aarch64_vector_pcs, |
| 2128 | .aarch64_sve_vector_pcs, | 2138 | .aarch64_sve_vector_pcs, |
| 2129 | .amdgpu_gfx, | 2139 | .amdgpu_gfx, |
| 2140 | .m68k_intrcc, | ||
| 2130 | .aarch64_sme_preservemost_from_x0, | 2141 | .aarch64_sme_preservemost_from_x0, |
| 2131 | .aarch64_sme_preservemost_from_x2, | 2142 | .aarch64_sme_preservemost_from_x2, |
| 2143 | .m68k_rtdcc, | ||
| 2144 | .riscv_vectorcallcc, | ||
| 2132 | => try writer.print(" {s}", .{@tagName(self)}), | 2145 | => try writer.print(" {s}", .{@tagName(self)}), |
| 2133 | _ => try writer.print(" cc{d}", .{@intFromEnum(self)}), | 2146 | _ => try writer.print(" cc{d}", .{@intFromEnum(self)}), |
| 2134 | } | 2147 | } |
src/codegen/spirv.zig+3-3| ... | @@ -1640,8 +1640,8 @@ const NavGen = struct { | ... | @@ -1640,8 +1640,8 @@ const NavGen = struct { |
| 1640 | 1640 | ||
| 1641 | comptime assert(zig_call_abi_ver == 3); | 1641 | comptime assert(zig_call_abi_ver == 3); |
| 1642 | switch (fn_info.cc) { | 1642 | switch (fn_info.cc) { |
| 1643 | .Unspecified, .Kernel, .Fragment, .Vertex, .C => {}, | 1643 | .auto, .spirv_kernel, .spirv_fragment, .spirv_vertex => {}, |
| 1644 | else => unreachable, // TODO | 1644 | else => @panic("TODO"), |
| 1645 | } | 1645 | } |
| 1646 | 1646 | ||
| 1647 | // TODO: Put this somewhere in Sema.zig | 1647 | // TODO: Put this somewhere in Sema.zig |
| ... | @@ -2970,7 +2970,7 @@ const NavGen = struct { | ... | @@ -2970,7 +2970,7 @@ const NavGen = struct { |
| 2970 | .id_result_type = return_ty_id, | 2970 | .id_result_type = return_ty_id, |
| 2971 | .id_result = result_id, | 2971 | .id_result = result_id, |
| 2972 | .function_control = switch (fn_info.cc) { | 2972 | .function_control = switch (fn_info.cc) { |
| 2973 | .Inline => .{ .Inline = true }, | 2973 | .@"inline" => .{ .Inline = true }, |
| 2974 | else => .{}, | 2974 | else => .{}, |
| 2975 | }, | 2975 | }, |
| 2976 | .function_type = prototype_ty_id, | 2976 | .function_type = prototype_ty_id, |
src/link/C.zig+1-1| ... | @@ -217,7 +217,7 @@ pub fn updateFunc( | ... | @@ -217,7 +217,7 @@ pub fn updateFunc( |
| 217 | .mod = zcu.navFileScope(func.owner_nav).mod, | 217 | .mod = zcu.navFileScope(func.owner_nav).mod, |
| 218 | .error_msg = null, | 218 | .error_msg = null, |
| 219 | .pass = .{ .nav = func.owner_nav }, | 219 | .pass = .{ .nav = func.owner_nav }, |
| 220 | .is_naked_fn = zcu.navValue(func.owner_nav).typeOf(zcu).fnCallingConvention(zcu) == .Naked, | 220 | .is_naked_fn = zcu.navValue(func.owner_nav).typeOf(zcu).fnCallingConvention(zcu) == .naked, |
| 221 | .fwd_decl = fwd_decl.toManaged(gpa), | 221 | .fwd_decl = fwd_decl.toManaged(gpa), |
| 222 | .ctype_pool = ctype_pool.*, | 222 | .ctype_pool = ctype_pool.*, |
| 223 | .scratch = .{}, | 223 | .scratch = .{}, |
src/link/Coff.zig+6-4| ... | @@ -1488,14 +1488,16 @@ pub fn updateExports( | ... | @@ -1488,14 +1488,16 @@ pub fn updateExports( |
| 1488 | const exported_nav = ip.getNav(exported_nav_index); | 1488 | const exported_nav = ip.getNav(exported_nav_index); |
| 1489 | const exported_ty = exported_nav.typeOf(ip); | 1489 | const exported_ty = exported_nav.typeOf(ip); |
| 1490 | if (!ip.isFunctionType(exported_ty)) continue; | 1490 | if (!ip.isFunctionType(exported_ty)) continue; |
| 1491 | const c_cc = target.cCallingConvention().?; | ||
| 1491 | const winapi_cc: std.builtin.CallingConvention = switch (target.cpu.arch) { | 1492 | const winapi_cc: std.builtin.CallingConvention = switch (target.cpu.arch) { |
| 1492 | .x86 => .Stdcall, | 1493 | .x86 => .{ .x86_stdcall = .{} }, |
| 1493 | else => .C, | 1494 | else => c_cc, |
| 1494 | }; | 1495 | }; |
| 1495 | const exported_cc = Type.fromInterned(exported_ty).fnCallingConvention(zcu); | 1496 | const exported_cc = Type.fromInterned(exported_ty).fnCallingConvention(zcu); |
| 1496 | if (exported_cc == .C and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) { | 1497 | const CcTag = std.builtin.CallingConvention.Tag; |
| 1498 | if (@as(CcTag, exported_cc) == @as(CcTag, c_cc) and exp.opts.name.eqlSlice("main", ip) and comp.config.link_libc) { | ||
| 1497 | zcu.stage1_flags.have_c_main = true; | 1499 | zcu.stage1_flags.have_c_main = true; |
| 1498 | } else if (exported_cc == winapi_cc and target.os.tag == .windows) { | 1500 | } else if (@as(CcTag, exported_cc) == @as(CcTag, winapi_cc) and target.os.tag == .windows) { |
| 1499 | if (exp.opts.name.eqlSlice("WinMain", ip)) { | 1501 | if (exp.opts.name.eqlSlice("WinMain", ip)) { |
| 1500 | zcu.stage1_flags.have_winmain = true; | 1502 | zcu.stage1_flags.have_winmain = true; |
| 1501 | } else if (exp.opts.name.eqlSlice("wWinMain", ip)) { | 1503 | } else if (exp.opts.name.eqlSlice("wWinMain", ip)) { |
src/link/Dwarf.zig+65-15| ... | @@ -3398,21 +3398,71 @@ fn updateType( | ... | @@ -3398,21 +3398,71 @@ fn updateType( |
| 3398 | const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args; | 3398 | const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args; |
| 3399 | try wip_nav.abbrevCode(if (is_nullary) .nullary_func_type else .func_type); | 3399 | try wip_nav.abbrevCode(if (is_nullary) .nullary_func_type else .func_type); |
| 3400 | try wip_nav.strp(name); | 3400 | try wip_nav.strp(name); |
| 3401 | try diw.writeByte(@intFromEnum(@as(DW.CC, switch (func_type.cc) { | 3401 | const cc: DW.CC = cc: { |
| 3402 | .Unspecified, .C => .normal, | 3402 | if (zcu.getTarget().cCallingConvention()) |cc| { |
| 3403 | .Naked, .Async, .Inline => .nocall, | 3403 | if (@as(std.builtin.CallingConvention.Tag, cc) == func_type.cc) { |
| 3404 | .Interrupt, .Signal => .nocall, | 3404 | break :cc .normal; |
| 3405 | .Stdcall => .BORLAND_stdcall, | 3405 | } |
| 3406 | .Fastcall => .BORLAND_fastcall, | 3406 | } |
| 3407 | .Vectorcall => .LLVM_vectorcall, | 3407 | // For better or worse, we try to match what Clang emits. |
| 3408 | .Thiscall => .BORLAND_thiscall, | 3408 | break :cc switch (func_type.cc) { |
| 3409 | .APCS => .nocall, | 3409 | .@"inline" => unreachable, |
| 3410 | .AAPCS => .LLVM_AAPCS, | 3410 | .@"async", .auto, .naked => .normal, |
| 3411 | .AAPCSVFP => .LLVM_AAPCS_VFP, | 3411 | .x86_64_sysv => .LLVM_X86_64SysV, |
| 3412 | .SysV => .LLVM_X86_64SysV, | 3412 | .x86_64_win => .LLVM_Win64, |
| 3413 | .Win64 => .LLVM_Win64, | 3413 | .x86_64_regcall_v3_sysv => .LLVM_X86RegCall, |
| 3414 | .Kernel, .Fragment, .Vertex => .nocall, | 3414 | .x86_64_regcall_v4_win => .LLVM_X86RegCall, |
| 3415 | }))); | 3415 | .x86_64_vectorcall => .LLVM_vectorcall, |
| 3416 | .x86_sysv => .nocall, | ||
| 3417 | .x86_win => .nocall, | ||
| 3418 | .x86_stdcall => .BORLAND_stdcall, | ||
| 3419 | .x86_fastcall => .BORLAND_msfastcall, | ||
| 3420 | .x86_thiscall => .BORLAND_thiscall, | ||
| 3421 | .x86_thiscall_mingw => .BORLAND_thiscall, | ||
| 3422 | .x86_regcall_v3 => .LLVM_X86RegCall, | ||
| 3423 | .x86_regcall_v4_win => .LLVM_X86RegCall, | ||
| 3424 | .x86_vectorcall => .LLVM_vectorcall, | ||
| 3425 | |||
| 3426 | .aarch64_aapcs => .LLVM_AAPCS, | ||
| 3427 | .aarch64_aapcs_darwin => .LLVM_AAPCS, | ||
| 3428 | .aarch64_aapcs_win => .LLVM_AAPCS, | ||
| 3429 | .aarch64_vfabi => .LLVM_AAPCS, | ||
| 3430 | .aarch64_vfabi_sve => .LLVM_AAPCS, | ||
| 3431 | |||
| 3432 | .arm_apcs => .nocall, | ||
| 3433 | .arm_aapcs => .LLVM_AAPCS, | ||
| 3434 | .arm_aapcs_vfp => .LLVM_AAPCS_VFP, | ||
| 3435 | .arm_aapcs16_vfp => .nocall, | ||
| 3436 | |||
| 3437 | .riscv64_lp64_v, | ||
| 3438 | .riscv32_ilp32_v, | ||
| 3439 | => .LLVM_RISCVVectorCall, | ||
| 3440 | |||
| 3441 | .m68k_rtd => .LLVM_M68kRTD, | ||
| 3442 | |||
| 3443 | .amdgcn_kernel, | ||
| 3444 | .nvptx_kernel, | ||
| 3445 | .spirv_kernel, | ||
| 3446 | => .LLVM_OpenCLKernel, | ||
| 3447 | |||
| 3448 | .x86_64_interrupt, | ||
| 3449 | .x86_interrupt, | ||
| 3450 | .arm_interrupt, | ||
| 3451 | .mips64_interrupt, | ||
| 3452 | .mips_interrupt, | ||
| 3453 | .riscv64_interrupt, | ||
| 3454 | .riscv32_interrupt, | ||
| 3455 | .avr_builtin, | ||
| 3456 | .avr_signal, | ||
| 3457 | .avr_interrupt, | ||
| 3458 | .csky_interrupt, | ||
| 3459 | .m68k_interrupt, | ||
| 3460 | => .normal, | ||
| 3461 | |||
| 3462 | else => .nocall, | ||
| 3463 | }; | ||
| 3464 | }; | ||
| 3465 | try diw.writeByte(@intFromEnum(cc)); | ||
| 3416 | try wip_nav.refType(Type.fromInterned(func_type.return_type)); | 3466 | try wip_nav.refType(Type.fromInterned(func_type.return_type)); |
| 3417 | for (0..func_type.param_types.len) |param_index| { | 3467 | for (0..func_type.param_types.len) |param_index| { |
| 3418 | try wip_nav.abbrevCode(.func_type_param); | 3468 | try wip_nav.abbrevCode(.func_type_param); |
src/link/SpirV.zig+3-4| ... | @@ -165,10 +165,9 @@ pub fn updateExports( | ... | @@ -165,10 +165,9 @@ pub fn updateExports( |
| 165 | const target = zcu.getTarget(); | 165 | const target = zcu.getTarget(); |
| 166 | const spv_decl_index = try self.object.resolveNav(zcu, nav_index); | 166 | const spv_decl_index = try self.object.resolveNav(zcu, nav_index); |
| 167 | const execution_model = switch (Type.fromInterned(nav_ty).fnCallingConvention(zcu)) { | 167 | const execution_model = switch (Type.fromInterned(nav_ty).fnCallingConvention(zcu)) { |
| 168 | .Vertex => spec.ExecutionModel.Vertex, | 168 | .spirv_vertex => spec.ExecutionModel.Vertex, |
| 169 | .Fragment => spec.ExecutionModel.Fragment, | 169 | .spirv_fragment => spec.ExecutionModel.Fragment, |
| 170 | .Kernel => spec.ExecutionModel.Kernel, | 170 | .spirv_kernel => spec.ExecutionModel.Kernel, |
| 171 | .C => return, // TODO: What to do here? | ||
| 172 | else => unreachable, | 171 | else => unreachable, |
| 173 | }; | 172 | }; |
| 174 | const is_vulkan = target.os.tag == .vulkan; | 173 | const is_vulkan = target.os.tag == .vulkan; |
src/print_zir.zig-1| ... | @@ -567,7 +567,6 @@ const Writer = struct { | ... | @@ -567,7 +567,6 @@ const Writer = struct { |
| 567 | .c_undef, | 567 | .c_undef, |
| 568 | .c_include, | 568 | .c_include, |
| 569 | .set_float_mode, | 569 | .set_float_mode, |
| 570 | .set_align_stack, | ||
| 571 | .wasm_memory_size, | 570 | .wasm_memory_size, |
| 572 | .int_from_error, | 571 | .int_from_error, |
| 573 | .error_from_int, | 572 | .error_from_int, |
src/target.zig+3-3| ... | @@ -544,13 +544,13 @@ pub fn compilerRtIntAbbrev(bits: u16) []const u8 { | ... | @@ -544,13 +544,13 @@ pub fn compilerRtIntAbbrev(bits: u16) []const u8 { |
| 544 | }; | 544 | }; |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | pub fn fnCallConvAllowsZigTypes(target: std.Target, cc: std.builtin.CallingConvention) bool { | 547 | pub fn fnCallConvAllowsZigTypes(cc: std.builtin.CallingConvention) bool { |
| 548 | return switch (cc) { | 548 | return switch (cc) { |
| 549 | .Unspecified, .Async, .Inline => true, | 549 | .auto, .@"async", .@"inline" => true, |
| 550 | // For now we want to authorize PTX kernel to use zig objects, even if | 550 | // For now we want to authorize PTX kernel to use zig objects, even if |
| 551 | // we end up exposing the ABI. The goal is to experiment with more | 551 | // we end up exposing the ABI. The goal is to experiment with more |
| 552 | // integrated CPU/GPU code. | 552 | // integrated CPU/GPU code. |
| 553 | .Kernel => target.cpu.arch == .nvptx or target.cpu.arch == .nvptx64, | 553 | .nvptx_kernel => true, |
| 554 | else => false, | 554 | else => false, |
| 555 | }; | 555 | }; |
| 556 | } | 556 | } |
src/translate_c.zig+16-14| ... | @@ -4,7 +4,6 @@ const assert = std.debug.assert; | ... | @@ -4,7 +4,6 @@ const assert = std.debug.assert; |
| 4 | const mem = std.mem; | 4 | const mem = std.mem; |
| 5 | const math = std.math; | 5 | const math = std.math; |
| 6 | const meta = std.meta; | 6 | const meta = std.meta; |
| 7 | const CallingConvention = std.builtin.CallingConvention; | ||
| 8 | const clang = @import("clang.zig"); | 7 | const clang = @import("clang.zig"); |
| 9 | const aro = @import("aro"); | 8 | const aro = @import("aro"); |
| 10 | const CToken = aro.Tokenizer.Token; | 9 | const CToken = aro.Tokenizer.Token; |
| ... | @@ -5001,17 +5000,20 @@ fn transCC( | ... | @@ -5001,17 +5000,20 @@ fn transCC( |
| 5001 | c: *Context, | 5000 | c: *Context, |
| 5002 | fn_ty: *const clang.FunctionType, | 5001 | fn_ty: *const clang.FunctionType, |
| 5003 | source_loc: clang.SourceLocation, | 5002 | source_loc: clang.SourceLocation, |
| 5004 | ) !CallingConvention { | 5003 | ) !ast.Payload.Func.CallingConvention { |
| 5005 | const clang_cc = fn_ty.getCallConv(); | 5004 | const clang_cc = fn_ty.getCallConv(); |
| 5006 | switch (clang_cc) { | 5005 | return switch (clang_cc) { |
| 5007 | .C => return CallingConvention.C, | 5006 | .C => .c, |
| 5008 | .X86StdCall => return CallingConvention.Stdcall, | 5007 | .X86_64SysV => .x86_64_sysv, |
| 5009 | .X86FastCall => return CallingConvention.Fastcall, | 5008 | .Win64 => .x86_64_win, |
| 5010 | .X86VectorCall, .AArch64VectorCall => return CallingConvention.Vectorcall, | 5009 | .X86StdCall => .x86_stdcall, |
| 5011 | .X86ThisCall => return CallingConvention.Thiscall, | 5010 | .X86FastCall => .x86_fastcall, |
| 5012 | .AAPCS => return CallingConvention.AAPCS, | 5011 | .X86ThisCall => .x86_thiscall, |
| 5013 | .AAPCS_VFP => return CallingConvention.AAPCSVFP, | 5012 | .X86VectorCall => .x86_vectorcall, |
| 5014 | .X86_64SysV => return CallingConvention.SysV, | 5013 | .AArch64VectorCall => .aarch64_vfabi, |
| 5014 | .AAPCS => .arm_aapcs, | ||
| 5015 | .AAPCS_VFP => .arm_aapcs_vfp, | ||
| 5016 | .M68kRTD => .m68k_rtd, | ||
| 5015 | else => return fail( | 5017 | else => return fail( |
| 5016 | c, | 5018 | c, |
| 5017 | error.UnsupportedType, | 5019 | error.UnsupportedType, |
| ... | @@ -5019,7 +5021,7 @@ fn transCC( | ... | @@ -5019,7 +5021,7 @@ fn transCC( |
| 5019 | "unsupported calling convention: {s}", | 5021 | "unsupported calling convention: {s}", |
| 5020 | .{@tagName(clang_cc)}, | 5022 | .{@tagName(clang_cc)}, |
| 5021 | ), | 5023 | ), |
| 5022 | } | 5024 | }; |
| 5023 | } | 5025 | } |
| 5024 | 5026 | ||
| 5025 | fn transFnProto( | 5027 | fn transFnProto( |
| ... | @@ -5056,7 +5058,7 @@ fn finishTransFnProto( | ... | @@ -5056,7 +5058,7 @@ fn finishTransFnProto( |
| 5056 | source_loc: clang.SourceLocation, | 5058 | source_loc: clang.SourceLocation, |
| 5057 | fn_decl_context: ?FnDeclContext, | 5059 | fn_decl_context: ?FnDeclContext, |
| 5058 | is_var_args: bool, | 5060 | is_var_args: bool, |
| 5059 | cc: CallingConvention, | 5061 | cc: ast.Payload.Func.CallingConvention, |
| 5060 | is_pub: bool, | 5062 | is_pub: bool, |
| 5061 | ) !*ast.Payload.Func { | 5063 | ) !*ast.Payload.Func { |
| 5062 | const is_export = if (fn_decl_context) |ctx| ctx.is_export else false; | 5064 | const is_export = if (fn_decl_context) |ctx| ctx.is_export else false; |
| ... | @@ -5104,7 +5106,7 @@ fn finishTransFnProto( | ... | @@ -5104,7 +5106,7 @@ fn finishTransFnProto( |
| 5104 | 5106 | ||
| 5105 | const alignment = if (fn_decl) |decl| ClangAlignment.forFunc(c, decl).zigAlignment() else null; | 5107 | const alignment = if (fn_decl) |decl| ClangAlignment.forFunc(c, decl).zigAlignment() else null; |
| 5106 | 5108 | ||
| 5107 | const explicit_callconv = if ((is_inline or is_export or is_extern) and cc == .C) null else cc; | 5109 | const explicit_callconv = if ((is_inline or is_export or is_extern) and cc == .c) null else cc; |
| 5108 | 5110 | ||
| 5109 | const return_type_node = blk: { | 5111 | const return_type_node = blk: { |
| 5110 | if (fn_ty.getNoReturnAttr()) { | 5112 | if (fn_ty.getNoReturnAttr()) { |
stage1/zig.h+35-25| ... | @@ -248,37 +248,55 @@ typedef char bool; | ... | @@ -248,37 +248,55 @@ typedef char bool; |
| 248 | 248 | ||
| 249 | #if zig_has_builtin(trap) | 249 | #if zig_has_builtin(trap) |
| 250 | #define zig_trap() __builtin_trap() | 250 | #define zig_trap() __builtin_trap() |
| 251 | #elif _MSC_VER && (_M_IX86 || _M_X64) | 251 | #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) |
| 252 | #define zig_trap() __ud2() | 252 | #define zig_trap() __ud2() |
| 253 | #elif _MSC_VER | 253 | #elif defined(_MSC_VER) |
| 254 | #define zig_trap() __fastfail(0) | 254 | #define zig_trap() __fastfail(7) |
| 255 | #elif defined(__i386__) || defined(__x86_64__) | 255 | #elif defined(__thumb__) |
| 256 | #define zig_trap() __asm__ volatile("ud2"); | 256 | #define zig_trap() __asm__ volatile("udf #0xfe") |
| 257 | #elif defined(__arm__) || defined(__aarch64__) | 257 | #elif defined(__arm__) || defined(__aarch64__) |
| 258 | #define zig_trap() __asm__ volatile("udf #0"); | 258 | #define zig_trap() __asm__ volatile("udf #0xfdee") |
| 259 | #elif defined(__loongarch__) || defined(__powerpc__) | ||
| 260 | #define zig_trap() __asm__ volatile(".word 0x0") | ||
| 261 | #elif defined(__mips__) | ||
| 262 | #define zig_trap() __asm__ volatile(".word 0x3d") | ||
| 263 | #elif defined(__riscv) | ||
| 264 | #define zig_trap() __asm__ volatile("unimp") | ||
| 265 | #elif defined(__s390__) | ||
| 266 | #define zig_trap() __asm__ volatile("j 0x2") | ||
| 267 | #elif defined(__sparc__) | ||
| 268 | #define zig_trap() __asm__ volatile("illtrap") | ||
| 269 | #elif defined(__i386__) || defined(__x86_64__) | ||
| 270 | #define zig_trap() __asm__ volatile("ud2") | ||
| 259 | #else | 271 | #else |
| 260 | #include <stdlib.h> | 272 | #define zig_trap() zig_trap_unavailable |
| 261 | #define zig_trap() abort() | ||
| 262 | #endif | 273 | #endif |
| 263 | 274 | ||
| 264 | #if zig_has_builtin(debugtrap) | 275 | #if zig_has_builtin(debugtrap) |
| 265 | #define zig_breakpoint() __builtin_debugtrap() | 276 | #define zig_breakpoint() __builtin_debugtrap() |
| 266 | #elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) | 277 | #elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) |
| 267 | #define zig_breakpoint() __debugbreak() | 278 | #define zig_breakpoint() __debugbreak() |
| 268 | #elif defined(__i386__) || defined(__x86_64__) | ||
| 269 | #define zig_breakpoint() __asm__ volatile("int $0x03"); | ||
| 270 | #elif defined(__arm__) | 279 | #elif defined(__arm__) |
| 271 | #define zig_breakpoint() __asm__ volatile("bkpt #0"); | 280 | #define zig_breakpoint() __asm__ volatile("bkpt #0x0") |
| 272 | #elif defined(__aarch64__) | 281 | #elif defined(__aarch64__) |
| 273 | #define zig_breakpoint() __asm__ volatile("brk #0"); | 282 | #define zig_breakpoint() __asm__ volatile("brk #0xf000") |
| 274 | #else | 283 | #elif defined(__loongarch__) |
| 275 | #include <signal.h> | 284 | #define zig_breakpoint() __asm__ volatile("break 0x0") |
| 276 | #if defined(SIGTRAP) | 285 | #elif defined(__mips__) |
| 277 | #define zig_breakpoint() raise(SIGTRAP) | 286 | #define zig_breakpoint() __asm__ volatile("break") |
| 287 | #elif defined(__powerpc__) | ||
| 288 | #define zig_breakpoint() __asm__ volatile("trap") | ||
| 289 | #elif defined(__riscv) | ||
| 290 | #define zig_breakpoint() __asm__ volatile("ebreak") | ||
| 291 | #elif defined(__s390__) | ||
| 292 | #define zig_breakpoint() __asm__ volatile("j 0x6") | ||
| 293 | #elif defined(__sparc__) | ||
| 294 | #define zig_breakpoint() __asm__ volatile("ta 0x1") | ||
| 295 | #elif defined(__i386__) || defined(__x86_64__) | ||
| 296 | #define zig_breakpoint() __asm__ volatile("int $0x3") | ||
| 278 | #else | 297 | #else |
| 279 | #define zig_breakpoint() zig_breakpoint_unavailable | 298 | #define zig_breakpoint() zig_breakpoint_unavailable |
| 280 | #endif | 299 | #endif |
| 281 | #endif | ||
| 282 | 300 | ||
| 283 | #if zig_has_builtin(return_address) || defined(zig_gnuc) | 301 | #if zig_has_builtin(return_address) || defined(zig_gnuc) |
| 284 | #define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0)) | 302 | #define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0)) |
| ... | @@ -3592,7 +3610,6 @@ typedef enum memory_order zig_memory_order; | ... | @@ -3592,7 +3610,6 @@ typedef enum memory_order zig_memory_order; |
| 3592 | #define zig_atomicrmw_add_float zig_atomicrmw_add | 3610 | #define zig_atomicrmw_add_float zig_atomicrmw_add |
| 3593 | #undef zig_atomicrmw_sub_float | 3611 | #undef zig_atomicrmw_sub_float |
| 3594 | #define zig_atomicrmw_sub_float zig_atomicrmw_sub | 3612 | #define zig_atomicrmw_sub_float zig_atomicrmw_sub |
| 3595 | #define zig_fence(order) atomic_thread_fence(order) | ||
| 3596 | #elif defined(__GNUC__) | 3613 | #elif defined(__GNUC__) |
| 3597 | typedef int zig_memory_order; | 3614 | typedef int zig_memory_order; |
| 3598 | #define zig_memory_order_relaxed __ATOMIC_RELAXED | 3615 | #define zig_memory_order_relaxed __ATOMIC_RELAXED |
| ... | @@ -3616,7 +3633,6 @@ typedef int zig_memory_order; | ... | @@ -3616,7 +3633,6 @@ typedef int zig_memory_order; |
| 3616 | #define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order) | 3633 | #define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order) |
| 3617 | #undef zig_atomicrmw_xchg_float | 3634 | #undef zig_atomicrmw_xchg_float |
| 3618 | #define zig_atomicrmw_xchg_float zig_atomicrmw_xchg | 3635 | #define zig_atomicrmw_xchg_float zig_atomicrmw_xchg |
| 3619 | #define zig_fence(order) __atomic_thread_fence(order) | ||
| 3620 | #elif _MSC_VER && (_M_IX86 || _M_X64) | 3636 | #elif _MSC_VER && (_M_IX86 || _M_X64) |
| 3621 | #define zig_memory_order_relaxed 0 | 3637 | #define zig_memory_order_relaxed 0 |
| 3622 | #define zig_memory_order_acquire 2 | 3638 | #define zig_memory_order_acquire 2 |
| ... | @@ -3637,11 +3653,6 @@ typedef int zig_memory_order; | ... | @@ -3637,11 +3653,6 @@ typedef int zig_memory_order; |
| 3637 | #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_max_ ##Type(obj, arg) | 3653 | #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_max_ ##Type(obj, arg) |
| 3638 | #define zig_atomic_store( obj, arg, order, Type, ReprType) zig_msvc_atomic_store_ ##Type(obj, arg) | 3654 | #define zig_atomic_store( obj, arg, order, Type, ReprType) zig_msvc_atomic_store_ ##Type(obj, arg) |
| 3639 | #define zig_atomic_load(res, obj, order, Type, ReprType) res = zig_msvc_atomic_load_ ##order##_##Type(obj) | 3655 | #define zig_atomic_load(res, obj, order, Type, ReprType) res = zig_msvc_atomic_load_ ##order##_##Type(obj) |
| 3640 | #if _M_X64 | ||
| 3641 | #define zig_fence(order) __faststorefence() | ||
| 3642 | #else | ||
| 3643 | #define zig_fence(order) zig_msvc_atomic_barrier() | ||
| 3644 | #endif | ||
| 3645 | /* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */ | 3656 | /* TODO: _MSC_VER && (_M_ARM || _M_ARM64) */ |
| 3646 | #else | 3657 | #else |
| 3647 | #define zig_memory_order_relaxed 0 | 3658 | #define zig_memory_order_relaxed 0 |
| ... | @@ -3663,7 +3674,6 @@ typedef int zig_memory_order; | ... | @@ -3663,7 +3674,6 @@ typedef int zig_memory_order; |
| 3663 | #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable | 3674 | #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable |
| 3664 | #define zig_atomic_store( obj, arg, order, Type, ReprType) zig_atomics_unavailable | 3675 | #define zig_atomic_store( obj, arg, order, Type, ReprType) zig_atomics_unavailable |
| 3665 | #define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable | 3676 | #define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable |
| 3666 | #define zig_fence(order) zig_fence_unavailable | ||
| 3667 | #endif | 3677 | #endif |
| 3668 | 3678 | ||
| 3669 | #if _MSC_VER && (_M_IX86 || _M_X64) | 3679 | #if _MSC_VER && (_M_IX86 || _M_X64) |
stage1/zig1.wasm| Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ | |||
test/behavior/align.zig-9| ... | @@ -210,15 +210,6 @@ test "alignment and size of structs with 128-bit fields" { | ... | @@ -210,15 +210,6 @@ test "alignment and size of structs with 128-bit fields" { |
| 210 | } | 210 | } |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | test "alignstack" { | ||
| 214 | try expect(fnWithAlignedStack() == 1234); | ||
| 215 | } | ||
| 216 | |||
| 217 | fn fnWithAlignedStack() i32 { | ||
| 218 | @setAlignStack(256); | ||
| 219 | return 1234; | ||
| 220 | } | ||
| 221 | |||
| 222 | test "implicitly decreasing slice alignment" { | 213 | test "implicitly decreasing slice alignment" { |
| 223 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 214 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 224 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 215 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/builtin_functions_returning_void_or_noreturn.zig-1| ... | @@ -20,7 +20,6 @@ test { | ... | @@ -20,7 +20,6 @@ test { |
| 20 | try testing.expectEqual({}, @memset(@as([*]u8, @ptrFromInt(1))[0..0], undefined)); | 20 | try testing.expectEqual({}, @memset(@as([*]u8, @ptrFromInt(1))[0..0], undefined)); |
| 21 | try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {})); | 21 | try testing.expectEqual(noreturn, @TypeOf(if (true) @panic("") else {})); |
| 22 | try testing.expectEqual({}, @prefetch(&val, .{})); | 22 | try testing.expectEqual({}, @prefetch(&val, .{})); |
| 23 | try testing.expectEqual({}, @setAlignStack(16)); | ||
| 24 | try testing.expectEqual({}, @setEvalBranchQuota(0)); | 23 | try testing.expectEqual({}, @setEvalBranchQuota(0)); |
| 25 | try testing.expectEqual({}, @setFloatMode(.optimized)); | 24 | try testing.expectEqual({}, @setFloatMode(.optimized)); |
| 26 | try testing.expectEqual({}, @setRuntimeSafety(true)); | 25 | try testing.expectEqual({}, @setRuntimeSafety(true)); |
test/behavior/type_info.zig+5-4| ... | @@ -350,6 +350,7 @@ fn testOpaque() !void { | ... | @@ -350,6 +350,7 @@ fn testOpaque() !void { |
| 350 | 350 | ||
| 351 | test "type info: function type info" { | 351 | test "type info: function type info" { |
| 352 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | 352 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; |
| 353 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 353 | 354 | ||
| 354 | try testFunction(); | 355 | try testFunction(); |
| 355 | try comptime testFunction(); | 356 | try comptime testFunction(); |
| ... | @@ -358,7 +359,7 @@ test "type info: function type info" { | ... | @@ -358,7 +359,7 @@ test "type info: function type info" { |
| 358 | fn testFunction() !void { | 359 | fn testFunction() !void { |
| 359 | const foo_fn_type = @TypeOf(typeInfoFoo); | 360 | const foo_fn_type = @TypeOf(typeInfoFoo); |
| 360 | const foo_fn_info = @typeInfo(foo_fn_type); | 361 | const foo_fn_info = @typeInfo(foo_fn_type); |
| 361 | try expect(foo_fn_info.@"fn".calling_convention == .C); | 362 | try expect(foo_fn_info.@"fn".calling_convention.eql(.c)); |
| 362 | try expect(!foo_fn_info.@"fn".is_generic); | 363 | try expect(!foo_fn_info.@"fn".is_generic); |
| 363 | try expect(foo_fn_info.@"fn".params.len == 2); | 364 | try expect(foo_fn_info.@"fn".params.len == 2); |
| 364 | try expect(foo_fn_info.@"fn".is_var_args); | 365 | try expect(foo_fn_info.@"fn".is_var_args); |
| ... | @@ -374,7 +375,7 @@ fn testFunction() !void { | ... | @@ -374,7 +375,7 @@ fn testFunction() !void { |
| 374 | 375 | ||
| 375 | const aligned_foo_fn_type = @TypeOf(typeInfoFooAligned); | 376 | const aligned_foo_fn_type = @TypeOf(typeInfoFooAligned); |
| 376 | const aligned_foo_fn_info = @typeInfo(aligned_foo_fn_type); | 377 | const aligned_foo_fn_info = @typeInfo(aligned_foo_fn_type); |
| 377 | try expect(aligned_foo_fn_info.@"fn".calling_convention == .C); | 378 | try expect(aligned_foo_fn_info.@"fn".calling_convention.eql(.c)); |
| 378 | try expect(!aligned_foo_fn_info.@"fn".is_generic); | 379 | try expect(!aligned_foo_fn_info.@"fn".is_generic); |
| 379 | try expect(aligned_foo_fn_info.@"fn".params.len == 2); | 380 | try expect(aligned_foo_fn_info.@"fn".params.len == 2); |
| 380 | try expect(aligned_foo_fn_info.@"fn".is_var_args); | 381 | try expect(aligned_foo_fn_info.@"fn".is_var_args); |
| ... | @@ -390,8 +391,8 @@ fn testFunction() !void { | ... | @@ -390,8 +391,8 @@ fn testFunction() !void { |
| 390 | try expect(aligned_foo_ptr_fn_info.pointer.sentinel == null); | 391 | try expect(aligned_foo_ptr_fn_info.pointer.sentinel == null); |
| 391 | } | 392 | } |
| 392 | 393 | ||
| 393 | extern fn typeInfoFoo(a: usize, b: bool, ...) callconv(.C) usize; | 394 | extern fn typeInfoFoo(a: usize, b: bool, ...) callconv(.c) usize; |
| 394 | extern fn typeInfoFooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; | 395 | extern fn typeInfoFooAligned(a: usize, b: bool, ...) align(4) callconv(.c) usize; |
| 395 | 396 | ||
| 396 | test "type info: generic function types" { | 397 | test "type info: generic function types" { |
| 397 | const G1 = @typeInfo(@TypeOf(generic1)); | 398 | const G1 = @typeInfo(@TypeOf(generic1)); |
test/behavior/typename.zig+3-3| ... | @@ -79,9 +79,9 @@ test "basic" { | ... | @@ -79,9 +79,9 @@ test "basic" { |
| 79 | try expectEqualStrings("fn (comptime u32) void", @typeName(fn (comptime u32) void)); | 79 | try expectEqualStrings("fn (comptime u32) void", @typeName(fn (comptime u32) void)); |
| 80 | try expectEqualStrings("fn (noalias []u8) void", @typeName(fn (noalias []u8) void)); | 80 | try expectEqualStrings("fn (noalias []u8) void", @typeName(fn (noalias []u8) void)); |
| 81 | 81 | ||
| 82 | try expectEqualStrings("fn () callconv(.C) void", @typeName(fn () callconv(.C) void)); | 82 | try expectEqualStrings("fn () callconv(.c) void", @typeName(fn () callconv(.c) void)); |
| 83 | try expectEqualStrings("fn (...) callconv(.C) void", @typeName(fn (...) callconv(.C) void)); | 83 | try expectEqualStrings("fn (...) callconv(.c) void", @typeName(fn (...) callconv(.c) void)); |
| 84 | try expectEqualStrings("fn (u32, ...) callconv(.C) void", @typeName(fn (u32, ...) callconv(.C) void)); | 84 | try expectEqualStrings("fn (u32, ...) callconv(.c) void", @typeName(fn (u32, ...) callconv(.c) void)); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | test "top level decl" { | 87 | test "top level decl" { |
test/cases/compile_errors/array_in_c_exported_function.zig+3-4| ... | @@ -7,10 +7,9 @@ export fn zig_return_array() [10]u8 { | ... | @@ -7,10 +7,9 @@ export fn zig_return_array() [10]u8 { |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | // error | 9 | // error |
| 10 | // backend=stage2 | 10 | // target=x86_64-linux |
| 11 | // target=native | ||
| 12 | // | 11 | // |
| 13 | // :1:21: error: parameter of type '[10]u8' not allowed in function with calling convention 'C' | 12 | // :1:21: error: parameter of type '[10]u8' not allowed in function with calling convention 'x86_64_sysv' |
| 14 | // :1:21: note: arrays are not allowed as a parameter type | 13 | // :1:21: note: arrays are not allowed as a parameter type |
| 15 | // :5:30: error: return type '[10]u8' not allowed in function with calling convention 'C' | 14 | // :5:30: error: return type '[10]u8' not allowed in function with calling convention 'x86_64_sysv' |
| 16 | // :5:30: note: arrays are not allowed as a return type | 15 | // :5:30: note: arrays are not allowed as a return type |
test/cases/compile_errors/assign_inline_fn_to_non-comptime_var.zig+1-1| ... | @@ -8,5 +8,5 @@ inline fn b() void {} | ... | @@ -8,5 +8,5 @@ inline fn b() void {} |
| 8 | // backend=stage2 | 8 | // backend=stage2 |
| 9 | // target=native | 9 | // target=native |
| 10 | // | 10 | // |
| 11 | // :2:9: error: variable of type '*const fn () callconv(.Inline) void' must be const or comptime | 11 | // :2:9: error: variable of type '*const fn () callconv(.@"inline") void' must be const or comptime |
| 12 | // :2:9: note: function has inline calling convention | 12 | // :2:9: note: function has inline calling convention |
test/cases/compile_errors/bitsize_of_packed_struct_checks_backing_int_ty.zig+1-1| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | const Foo = packed struct(u32) { | 1 | const Foo = packed struct(u32) { |
| 2 | x: u1, | 2 | x: u1, |
| 3 | }; | 3 | }; |
| 4 | fn bar(_: Foo) callconv(.C) void {} | 4 | fn bar(_: Foo) callconv(.c) void {} |
| 5 | pub export fn entry() void { | 5 | pub export fn entry() void { |
| 6 | bar(.{ .x = 0 }); | 6 | bar(.{ .x = 0 }); |
| 7 | } | 7 | } |
test/cases/compile_errors/callconv_apcs_aapcs_aapcsvfp_on_unsupported_platform.zig+3-4| ... | @@ -3,9 +3,8 @@ export fn entry2() callconv(.AAPCS) void {} | ... | @@ -3,9 +3,8 @@ export fn entry2() callconv(.AAPCS) void {} |
| 3 | export fn entry3() callconv(.AAPCSVFP) void {} | 3 | export fn entry3() callconv(.AAPCSVFP) void {} |
| 4 | 4 | ||
| 5 | // error | 5 | // error |
| 6 | // backend=stage2 | ||
| 7 | // target=x86_64-linux-none | 6 | // target=x86_64-linux-none |
| 8 | // | 7 | // |
| 9 | // :1:30: error: callconv 'APCS' is only available on ARM, not x86_64 | 8 | // :1:30: error: calling convention 'arm_apcs' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb' |
| 10 | // :2:30: error: callconv 'AAPCS' is only available on ARM, not x86_64 | 9 | // :2:30: error: calling convention 'arm_aapcs' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb' |
| 11 | // :3:30: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64 | 10 | // :3:30: error: calling convention 'arm_aapcs_vfp' only available on architectures 'arm', 'armeb', 'thumb', 'thumbeb' |
test/cases/compile_errors/callconv_interrupt_on_unsupported_platform.zig+1-1| ... | @@ -4,4 +4,4 @@ export fn entry() callconv(.Interrupt) void {} | ... | @@ -4,4 +4,4 @@ export fn entry() callconv(.Interrupt) void {} |
| 4 | // backend=stage2 | 4 | // backend=stage2 |
| 5 | // target=aarch64-linux-none | 5 | // target=aarch64-linux-none |
| 6 | // | 6 | // |
| 7 | // :1:29: error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64 | 7 | // :1:29: error: calling convention 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64 |
test/cases/compile_errors/callconv_signal_on_unsupported_platform.zig+2-2| ... | @@ -1,7 +1,7 @@ | ... | @@ -1,7 +1,7 @@ |
| 1 | export fn entry() callconv(.Signal) void {} | 1 | export fn entry() callconv(.avr_signal) void {} |
| 2 | 2 | ||
| 3 | // error | 3 | // error |
| 4 | // backend=stage2 | 4 | // backend=stage2 |
| 5 | // target=x86_64-linux-none | 5 | // target=x86_64-linux-none |
| 6 | // | 6 | // |
| 7 | // :1:29: error: callconv 'Signal' is only available on AVR, not x86_64 | 7 | // :1:29: error: calling convention 'avr_signal' only available on architectures 'avr' |
test/cases/compile_errors/callconv_stdcall_fastcall_thiscall_on_unsupported_platform.zig+6-6| ... | @@ -1,6 +1,6 @@ | ... | @@ -1,6 +1,6 @@ |
| 1 | const F1 = fn () callconv(.Stdcall) void; | 1 | const F1 = fn () callconv(.{ .x86_stdcall = .{} }) void; |
| 2 | const F2 = fn () callconv(.Fastcall) void; | 2 | const F2 = fn () callconv(.{ .x86_fastcall = .{} }) void; |
| 3 | const F3 = fn () callconv(.Thiscall) void; | 3 | const F3 = fn () callconv(.{ .x86_thiscall = .{} }) void; |
| 4 | export fn entry1() void { | 4 | export fn entry1() void { |
| 5 | const a: F1 = undefined; | 5 | const a: F1 = undefined; |
| 6 | _ = a; | 6 | _ = a; |
| ... | @@ -18,6 +18,6 @@ export fn entry3() void { | ... | @@ -18,6 +18,6 @@ export fn entry3() void { |
| 18 | // backend=stage2 | 18 | // backend=stage2 |
| 19 | // target=x86_64-linux-none | 19 | // target=x86_64-linux-none |
| 20 | // | 20 | // |
| 21 | // :1:28: error: callconv 'Stdcall' is only available on x86, not x86_64 | 21 | // :1:28: error: calling convention 'x86_stdcall' only available on architectures 'x86' |
| 22 | // :2:28: error: callconv 'Fastcall' is only available on x86, not x86_64 | 22 | // :2:28: error: calling convention 'x86_fastcall' only available on architectures 'x86' |
| 23 | // :3:28: error: callconv 'Thiscall' is only available on x86, not x86_64 | 23 | // :3:28: error: calling convention 'x86_thiscall' only available on architectures 'x86' |
test/cases/compile_errors/callconv_vectorcall_on_unsupported_platform.zig deleted-7| ... | @@ -1,7 +0,0 @@ | ||
| 1 | export fn entry() callconv(.Vectorcall) void {} | ||
| 2 | |||
| 3 | // error | ||
| 4 | // backend=stage2 | ||
| 5 | // target=x86_64-linux-none | ||
| 6 | // | ||
| 7 | // :1:29: error: callconv 'Vectorcall' is only available on x86 and AArch64, not x86_64 | ||
test/cases/compile_errors/closure_get_depends_on_failed_decl.zig+1-1| ... | @@ -4,7 +4,7 @@ pub inline fn requestAdapter( | ... | @@ -4,7 +4,7 @@ pub inline fn requestAdapter( |
| 4 | comptime callbackArg: fn () callconv(.Inline) void, | 4 | comptime callbackArg: fn () callconv(.Inline) void, |
| 5 | ) void { | 5 | ) void { |
| 6 | _ = &(struct { | 6 | _ = &(struct { |
| 7 | pub fn callback() callconv(.C) void { | 7 | pub fn callback() callconv(.c) void { |
| 8 | callbackArg(); | 8 | callbackArg(); |
| 9 | } | 9 | } |
| 10 | }).callback; | 10 | }).callback; |
test/cases/compile_errors/export_function_with_comptime_parameter.zig+2-3| ... | @@ -3,7 +3,6 @@ export fn foo(comptime x: anytype, y: i32) i32 { | ... | @@ -3,7 +3,6 @@ export fn foo(comptime x: anytype, y: i32) i32 { |
| 3 | } | 3 | } |
| 4 | 4 | ||
| 5 | // error | 5 | // error |
| 6 | // backend=stage2 | 6 | // target=x86_64-linux |
| 7 | // target=native | ||
| 8 | // | 7 | // |
| 9 | // :1:15: error: comptime parameters not allowed in function with calling convention 'C' | 8 | // :1:15: error: comptime parameters not allowed in function with calling convention 'x86_64_sysv' |
test/cases/compile_errors/export_generic_function.zig+2-3| ... | @@ -4,7 +4,6 @@ export fn foo(num: anytype) i32 { | ... | @@ -4,7 +4,6 @@ export fn foo(num: anytype) i32 { |
| 4 | } | 4 | } |
| 5 | 5 | ||
| 6 | // error | 6 | // error |
| 7 | // backend=stage2 | 7 | // target=x86_64-linux |
| 8 | // target=native | ||
| 9 | // | 8 | // |
| 10 | // :1:15: error: generic parameters not allowed in function with calling convention 'C' | 9 | // :1:15: error: generic parameters not allowed in function with calling convention 'x86_64_sysv' |
test/cases/compile_errors/extern_function_pointer_mismatch.zig+3-4| ... | @@ -14,8 +14,7 @@ export fn entry() usize { | ... | @@ -14,8 +14,7 @@ export fn entry() usize { |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | // error | 16 | // error |
| 17 | // backend=stage2 | 17 | // target=x86_64-linux |
| 18 | // target=native | ||
| 19 | // | 18 | // |
| 20 | // :1:38: error: expected type 'fn (i32) i32', found 'fn (i32) callconv(.C) i32' | 19 | // :1:38: error: expected type 'fn (i32) i32', found 'fn (i32) callconv(.c) i32' |
| 21 | // :1:38: note: calling convention 'C' cannot cast into calling convention 'Unspecified' | 20 | // :1:38: note: calling convention 'x86_64_sysv' cannot cast into calling convention 'auto' |
test/cases/compile_errors/extern_function_with_comptime_parameter.zig+4-5| ... | @@ -15,9 +15,8 @@ comptime { | ... | @@ -15,9 +15,8 @@ comptime { |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | // error | 17 | // error |
| 18 | // backend=stage2 | 18 | // target=x86_64-linux |
| 19 | // target=native | ||
| 20 | // | 19 | // |
| 21 | // :1:15: error: comptime parameters not allowed in function with calling convention 'C' | 20 | // :1:15: error: comptime parameters not allowed in function with calling convention 'x86_64_sysv' |
| 22 | // :5:30: error: comptime parameters not allowed in function with calling convention 'C' | 21 | // :5:30: error: comptime parameters not allowed in function with calling convention 'x86_64_sysv' |
| 23 | // :6:30: error: generic parameters not allowed in function with calling convention 'C' | 22 | // :6:30: error: generic parameters not allowed in function with calling convention 'x86_64_sysv' |
test/cases/compile_errors/function-only_builtins_outside_function.zig+12-17| ... | @@ -1,7 +1,3 @@ | ... | @@ -1,7 +1,3 @@ |
| 1 | comptime { | ||
| 2 | @setAlignStack(1); | ||
| 3 | } | ||
| 4 | |||
| 5 | comptime { | 1 | comptime { |
| 6 | @branchHint(.cold); | 2 | @branchHint(.cold); |
| 7 | } | 3 | } |
| ... | @@ -54,16 +50,15 @@ comptime { | ... | @@ -54,16 +50,15 @@ comptime { |
| 54 | // backend=stage2 | 50 | // backend=stage2 |
| 55 | // target=native | 51 | // target=native |
| 56 | // | 52 | // |
| 57 | // :2:5: error: '@setAlignStack' outside function scope | 53 | // :2:5: error: '@branchHint' outside function scope |
| 58 | // :6:5: error: '@branchHint' outside function scope | 54 | // :6:5: error: '@src' outside function scope |
| 59 | // :10:5: error: '@src' outside function scope | 55 | // :10:5: error: '@returnAddress' outside function scope |
| 60 | // :14:5: error: '@returnAddress' outside function scope | 56 | // :14:5: error: '@frameAddress' outside function scope |
| 61 | // :18:5: error: '@frameAddress' outside function scope | 57 | // :18:5: error: '@breakpoint' outside function scope |
| 62 | // :22:5: error: '@breakpoint' outside function scope | 58 | // :22:5: error: '@cVaArg' outside function scope |
| 63 | // :26:5: error: '@cVaArg' outside function scope | 59 | // :26:5: error: '@cVaCopy' outside function scope |
| 64 | // :30:5: error: '@cVaCopy' outside function scope | 60 | // :30:5: error: '@cVaEnd' outside function scope |
| 65 | // :34:5: error: '@cVaEnd' outside function scope | 61 | // :34:5: error: '@cVaStart' outside function scope |
| 66 | // :38:5: error: '@cVaStart' outside function scope | 62 | // :38:5: error: '@workItemId' outside function scope |
| 67 | // :42:5: error: '@workItemId' outside function scope | 63 | // :42:5: error: '@workGroupSize' outside function scope |
| 68 | // :46:5: error: '@workGroupSize' outside function scope | 64 | // :46:5: error: '@workGroupId' outside function scope |
| 69 | // :50:5: error: '@workGroupId' outside function scope |
test/cases/compile_errors/function_with_non-extern_non-packed_enum_parameter.zig+2-3| ... | @@ -4,10 +4,9 @@ export fn entry(foo: Foo) void { | ... | @@ -4,10 +4,9 @@ export fn entry(foo: Foo) void { |
| 4 | } | 4 | } |
| 5 | 5 | ||
| 6 | // error | 6 | // error |
| 7 | // backend=stage2 | 7 | // target=x86_64-linux |
| 8 | // target=native | ||
| 9 | // | 8 | // |
| 10 | // :2:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C' | 9 | // :2:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv' |
| 11 | // :2:17: note: enum tag type 'u2' is not extern compatible | 10 | // :2:17: note: enum tag type 'u2' is not extern compatible |
| 12 | // :2:17: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible | 11 | // :2:17: note: only integers with 0, 8, 16, 32, 64 and 128 bits are extern compatible |
| 13 | // :1:13: note: enum declared here | 12 | // :1:13: note: enum declared here |
test/cases/compile_errors/function_with_non-extern_non-packed_struct_parameter.zig+2-3| ... | @@ -8,9 +8,8 @@ export fn entry(foo: Foo) void { | ... | @@ -8,9 +8,8 @@ export fn entry(foo: Foo) void { |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | // error | 10 | // error |
| 11 | // backend=stage2 | 11 | // target=x86_64-linux |
| 12 | // target=native | ||
| 13 | // | 12 | // |
| 14 | // :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C' | 13 | // :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv' |
| 15 | // :6:17: note: only extern structs and ABI sized packed structs are extern compatible | 14 | // :6:17: note: only extern structs and ABI sized packed structs are extern compatible |
| 16 | // :1:13: note: struct declared here | 15 | // :1:13: note: struct declared here |
test/cases/compile_errors/function_with_non-extern_non-packed_union_parameter.zig+2-3| ... | @@ -8,9 +8,8 @@ export fn entry(foo: Foo) void { | ... | @@ -8,9 +8,8 @@ export fn entry(foo: Foo) void { |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | // error | 10 | // error |
| 11 | // backend=stage2 | 11 | // target=x86_64-linux |
| 12 | // target=native | ||
| 13 | // | 12 | // |
| 14 | // :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C' | 13 | // :6:17: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'x86_64_sysv' |
| 15 | // :6:17: note: only extern unions and ABI sized packed unions are extern compatible | 14 | // :6:17: note: only extern unions and ABI sized packed unions are extern compatible |
| 16 | // :1:13: note: union declared here | 15 | // :1:13: note: union declared here |
test/cases/compile_errors/invalid_extern_function_call.zig+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | const x = @extern(*const fn () callconv(.C) void, .{ .name = "foo" }); | 1 | const x = @extern(*const fn () callconv(.c) void, .{ .name = "foo" }); |
| 2 | 2 | ||
| 3 | export fn entry0() void { | 3 | export fn entry0() void { |
| 4 | comptime x(); | 4 | comptime x(); |
test/cases/compile_errors/invalid_func_for_callconv.zig+7-8| ... | @@ -9,12 +9,11 @@ export fn signal_param(_: u32) callconv(.Signal) void {} | ... | @@ -9,12 +9,11 @@ export fn signal_param(_: u32) callconv(.Signal) void {} |
| 9 | export fn signal_ret() callconv(.Signal) noreturn {} | 9 | export fn signal_ret() callconv(.Signal) noreturn {} |
| 10 | 10 | ||
| 11 | // error | 11 | // error |
| 12 | // backend=stage2 | ||
| 13 | // target=x86_64-linux | 12 | // target=x86_64-linux |
| 14 | // | 13 | // |
| 15 | // :1:28: error: first parameter of function with 'Interrupt' calling convention must be a pointer type | 14 | // :1:28: error: first parameter of function with 'x86_64_interrupt' calling convention must be a pointer type |
| 16 | // :2:43: error: second parameter of function with 'Interrupt' calling convention must be a 64-bit integer | 15 | // :2:43: error: second parameter of function with 'x86_64_interrupt' calling convention must be a 64-bit integer |
| 17 | // :3:51: error: 'Interrupt' calling convention supports up to 2 parameters, found 3 | 16 | // :3:51: error: 'x86_64_interrupt' calling convention supports up to 2 parameters, found 3 |
| 18 | // :4:69: error: function with calling convention 'Interrupt' must return 'void' or 'noreturn' | 17 | // :4:69: error: function with calling convention 'x86_64_interrupt' must return 'void' or 'noreturn' |
| 19 | // :8:24: error: parameters are not allowed with 'Signal' calling convention | 18 | // :8:24: error: parameters are not allowed with 'avr_signal' calling convention |
| 20 | // :9:34: error: callconv 'Signal' is only available on AVR, not x86_64 | 19 | // :9:34: error: calling convention 'avr_signal' only available on architectures 'avr' |
test/cases/compile_errors/invalid_tail_call.zig+1-1| ... | @@ -9,4 +9,4 @@ pub export fn entry() void { | ... | @@ -9,4 +9,4 @@ pub export fn entry() void { |
| 9 | // backend=llvm | 9 | // backend=llvm |
| 10 | // target=native | 10 | // target=native |
| 11 | // | 11 | // |
| 12 | // :5:5: error: unable to perform tail call: type of function being called 'fn (usize) void' does not match type of calling function 'fn () callconv(.C) void' | 12 | // :5:5: error: unable to perform tail call: type of function being called 'fn (usize) void' does not match type of calling function 'fn () callconv(.c) void' |
test/cases/compile_errors/invalid_variadic_function.zig+5-6| ... | @@ -13,11 +13,10 @@ comptime { | ... | @@ -13,11 +13,10 @@ comptime { |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | // error | 15 | // error |
| 16 | // backend=stage2 | 16 | // target=x86_64-linux |
| 17 | // target=native | ||
| 18 | // | 17 | // |
| 19 | // :1:1: error: variadic function does not support '.Unspecified' calling convention | 18 | // :1:1: error: variadic function does not support 'auto' calling convention |
| 20 | // :1:1: note: supported calling conventions: '.C' | 19 | // :1:1: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' |
| 21 | // :1:1: error: variadic function does not support '.Inline' calling convention | 20 | // :1:1: error: variadic function does not support 'inline' calling convention |
| 22 | // :1:1: note: supported calling conventions: '.C' | 21 | // :1:1: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' |
| 23 | // :2:1: error: generic function cannot be variadic | 22 | // :2:1: error: generic function cannot be variadic |
test/cases/compile_errors/noinline_fn_cc_inline.zig+2-3| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const cc = .Inline; | 1 | noinline fn foo() callconv(.@"inline") void {} |
| 2 | noinline fn foo() callconv(cc) void {} | ||
| 3 | 2 | ||
| 4 | comptime { | 3 | comptime { |
| 5 | _ = foo; | 4 | _ = foo; |
| ... | @@ -9,4 +8,4 @@ comptime { | ... | @@ -9,4 +8,4 @@ comptime { |
| 9 | // backend=stage2 | 8 | // backend=stage2 |
| 10 | // target=native | 9 | // target=native |
| 11 | // | 10 | // |
| 12 | // :2:28: error: 'noinline' function cannot have callconv 'Inline' | 11 | // :1:29: error: 'noinline' function cannot have calling convention 'inline' |
test/cases/compile_errors/old_fn_ptr_in_extern_context.zig+4-4| ... | @@ -1,20 +1,20 @@ | ... | @@ -1,20 +1,20 @@ |
| 1 | const S = extern struct { | 1 | const S = extern struct { |
| 2 | a: fn () callconv(.C) void, | 2 | a: fn () callconv(.c) void, |
| 3 | }; | 3 | }; |
| 4 | comptime { | 4 | comptime { |
| 5 | _ = @sizeOf(S) == 1; | 5 | _ = @sizeOf(S) == 1; |
| 6 | } | 6 | } |
| 7 | comptime { | 7 | comptime { |
| 8 | _ = [*c][4]fn () callconv(.C) void; | 8 | _ = [*c][4]fn () callconv(.c) void; |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | // error | 11 | // error |
| 12 | // backend=stage2 | 12 | // backend=stage2 |
| 13 | // target=native | 13 | // target=native |
| 14 | // | 14 | // |
| 15 | // :2:8: error: extern structs cannot contain fields of type 'fn () callconv(.C) void' | 15 | // :2:8: error: extern structs cannot contain fields of type 'fn () callconv(.c) void' |
| 16 | // :2:8: note: type has no guaranteed in-memory representation | 16 | // :2:8: note: type has no guaranteed in-memory representation |
| 17 | // :2:8: note: use '*const ' to make a function pointer type | 17 | // :2:8: note: use '*const ' to make a function pointer type |
| 18 | // :8:13: error: C pointers cannot point to non-C-ABI-compatible type '[4]fn () callconv(.C) void' | 18 | // :8:13: error: C pointers cannot point to non-C-ABI-compatible type '[4]fn () callconv(.c) void' |
| 19 | // :8:13: note: type has no guaranteed in-memory representation | 19 | // :8:13: note: type has no guaranteed in-memory representation |
| 20 | // :8:13: note: use '*const ' to make a function pointer type | 20 | // :8:13: note: use '*const ' to make a function pointer type |
test/cases/compile_errors/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig+3-4| ... | @@ -12,8 +12,7 @@ comptime { | ... | @@ -12,8 +12,7 @@ comptime { |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | // error | 14 | // error |
| 15 | // backend=stage2 | 15 | // target=x86_64-linux |
| 16 | // target=native | ||
| 17 | // | 16 | // |
| 18 | // :1:13: error: variadic function does not support '.Unspecified' calling convention | 17 | // :1:13: error: variadic function does not support 'auto' calling convention |
| 19 | // :1:13: note: supported calling conventions: '.C' | 18 | // :1:13: note: supported calling conventions: 'x86_64_sysv', 'x86_64_win' |
test/cases/compile_errors/runtime_@ptrFromInt_to_comptime_only_type.zig+2-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const GuSettings = struct { | 1 | const GuSettings = struct { |
| 2 | fin: ?fn (c_int) callconv(.C) void, | 2 | fin: ?fn (c_int) callconv(.c) void, |
| 3 | }; | 3 | }; |
| 4 | pub export fn callbackFin(id: c_int, arg: ?*anyopaque) void { | 4 | pub export fn callbackFin(id: c_int, arg: ?*anyopaque) void { |
| 5 | const settings: ?*GuSettings = @as(?*GuSettings, @ptrFromInt(@intFromPtr(arg))); | 5 | const settings: ?*GuSettings = @as(?*GuSettings, @ptrFromInt(@intFromPtr(arg))); |
| ... | @@ -13,4 +13,4 @@ pub export fn callbackFin(id: c_int, arg: ?*anyopaque) void { | ... | @@ -13,4 +13,4 @@ pub export fn callbackFin(id: c_int, arg: ?*anyopaque) void { |
| 13 | // | 13 | // |
| 14 | // :5:54: error: pointer to comptime-only type '?*tmp.GuSettings' must be comptime-known, but operand is runtime-known | 14 | // :5:54: error: pointer to comptime-only type '?*tmp.GuSettings' must be comptime-known, but operand is runtime-known |
| 15 | // :2:10: note: struct requires comptime because of this field | 15 | // :2:10: note: struct requires comptime because of this field |
| 16 | // :2:10: note: use '*const fn (c_int) callconv(.C) void' for a function pointer type | 16 | // :2:10: note: use '*const fn (c_int) callconv(.c) void' for a function pointer type |
test/cases/compile_errors/setAlignStack_in_naked_function.zig deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | export fn entry() callconv(.Naked) void { | ||
| 2 | @setAlignStack(16); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | ||
| 9 | // :2:5: error: @setAlignStack in naked function | ||
test/cases/compile_errors/setAlignStack_too_big.zig deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | export fn entry() void { | ||
| 2 | @setAlignStack(511 + 1); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | ||
| 9 | // :2:5: error: attempt to @setAlignStack(512); maximum is 256 | ||
test/cases/compile_errors/slice_used_as_extern_fn_param.zig+3-4| ... | @@ -1,11 +1,10 @@ | ... | @@ -1,11 +1,10 @@ |
| 1 | extern fn Text(str: []const u8, num: i32) callconv(.C) void; | 1 | extern fn Text(str: []const u8, num: i32) callconv(.c) void; |
| 2 | export fn entry() void { | 2 | export fn entry() void { |
| 3 | _ = Text; | 3 | _ = Text; |
| 4 | } | 4 | } |
| 5 | 5 | ||
| 6 | // error | 6 | // error |
| 7 | // backend=stage2 | 7 | // target=x86_64-linux |
| 8 | // target=native | ||
| 9 | // | 8 | // |
| 10 | // :1:16: error: parameter of type '[]const u8' not allowed in function with calling convention 'C' | 9 | // :1:16: error: parameter of type '[]const u8' not allowed in function with calling convention 'x86_64_sysv' |
| 11 | // :1:16: note: slices have no guaranteed in-memory representation | 10 | // :1:16: note: slices have no guaranteed in-memory representation |
test/cases/compile_errors/type_mismatch_in_C_prototype_with_varargs.zig+2-2| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void; | 1 | const fn_ty = ?fn ([*c]u8, ...) callconv(.c) void; |
| 2 | extern fn fn_decl(fmt: [*:0]u8, ...) void; | 2 | extern fn fn_decl(fmt: [*:0]u8, ...) void; |
| 3 | 3 | ||
| 4 | export fn main() void { | 4 | export fn main() void { |
| ... | @@ -10,6 +10,6 @@ export fn main() void { | ... | @@ -10,6 +10,6 @@ export fn main() void { |
| 10 | // backend=stage2 | 10 | // backend=stage2 |
| 11 | // target=native | 11 | // target=native |
| 12 | // | 12 | // |
| 13 | // :5:22: error: expected type '?fn ([*c]u8, ...) callconv(.C) void', found 'fn ([*:0]u8, ...) callconv(.C) void' | 13 | // :5:22: error: expected type '?fn ([*c]u8, ...) callconv(.c) void', found 'fn ([*:0]u8, ...) callconv(.c) void' |
| 14 | // :5:22: note: parameter 0 '[*:0]u8' cannot cast into '[*c]u8' | 14 | // :5:22: note: parameter 0 '[*:0]u8' cannot cast into '[*c]u8' |
| 15 | // :5:22: note: '[*c]u8' could have null values which are illegal in type '[*:0]u8' | 15 | // :5:22: note: '[*c]u8' could have null values which are illegal in type '[*:0]u8' |
test/cases/compile_errors/wrong_types_given_to_export.zig+1-1| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | fn entry() callconv(.C) void {} | 1 | fn entry() callconv(.c) void {} |
| 2 | comptime { | 2 | comptime { |
| 3 | @export(&entry, .{ .name = "entry", .linkage = @as(u32, 1234) }); | 3 | @export(&entry, .{ .name = "entry", .linkage = @as(u32, 1234) }); |
| 4 | } | 4 | } |
test/cases/translate_c/static empty struct.c	+1-1| ... | @@ -9,7 +9,7 @@ static inline void foo() { | ... | @@ -9,7 +9,7 @@ static inline void foo() { |
| 9 | // c_frontend=clang | 9 | // c_frontend=clang |
| 10 | // | 10 | // |
| 11 | // pub const struct_empty_struct = extern struct {}; | 11 | // pub const struct_empty_struct = extern struct {}; |
| 12 | // pub fn foo() callconv(.C) void { | 12 | // pub fn foo() callconv(.c) void { |
| 13 | // const bar = struct { | 13 | // const bar = struct { |
| 14 | // var static: struct_empty_struct = @import("std").mem.zeroes(struct_empty_struct); | 14 | // var static: struct_empty_struct = @import("std").mem.zeroes(struct_empty_struct); |
| 15 | // }; | 15 | // }; |
test/translate_c.zig+34-34| ... | @@ -484,11 +484,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -484,11 +484,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 484 | \\ fnptr_attr_ty qux; | 484 | \\ fnptr_attr_ty qux; |
| 485 | \\}; | 485 | \\}; |
| 486 | , &[_][]const u8{ | 486 | , &[_][]const u8{ |
| 487 | \\pub const fnptr_ty = ?*const fn () callconv(.C) void; | 487 | \\pub const fnptr_ty = ?*const fn () callconv(.c) void; |
| 488 | \\pub const fnptr_attr_ty = ?*const fn () callconv(.C) void; | 488 | \\pub const fnptr_attr_ty = ?*const fn () callconv(.c) void; |
| 489 | \\pub const struct_foo = extern struct { | 489 | \\pub const struct_foo = extern struct { |
| 490 | \\ foo: ?*const fn () callconv(.C) void = @import("std").mem.zeroes(?*const fn () callconv(.C) void), | 490 | \\ foo: ?*const fn () callconv(.c) void = @import("std").mem.zeroes(?*const fn () callconv(.c) void), |
| 491 | \\ bar: ?*const fn () callconv(.C) void = @import("std").mem.zeroes(?*const fn () callconv(.C) void), | 491 | \\ bar: ?*const fn () callconv(.c) void = @import("std").mem.zeroes(?*const fn () callconv(.c) void), |
| 492 | \\ baz: fnptr_ty = @import("std").mem.zeroes(fnptr_ty), | 492 | \\ baz: fnptr_ty = @import("std").mem.zeroes(fnptr_ty), |
| 493 | \\ qux: fnptr_attr_ty = @import("std").mem.zeroes(fnptr_attr_ty), | 493 | \\ qux: fnptr_attr_ty = @import("std").mem.zeroes(fnptr_attr_ty), |
| 494 | \\}; | 494 | \\}; |
| ... | @@ -735,7 +735,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -735,7 +735,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 735 | \\static void bar(void) {} | 735 | \\static void bar(void) {} |
| 736 | , &[_][]const u8{ | 736 | , &[_][]const u8{ |
| 737 | \\pub export fn foo() void {} | 737 | \\pub export fn foo() void {} |
| 738 | \\pub fn bar() callconv(.C) void {} | 738 | \\pub fn bar() callconv(.c) void {} |
| 739 | }); | 739 | }); |
| 740 | 740 | ||
| 741 | cases.add("typedef void", | 741 | cases.add("typedef void", |
| ... | @@ -769,7 +769,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -769,7 +769,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 769 | \\pub export fn bar() void { | 769 | \\pub export fn bar() void { |
| 770 | \\ var func_ptr: ?*anyopaque = @as(?*anyopaque, @ptrCast(&foo)); | 770 | \\ var func_ptr: ?*anyopaque = @as(?*anyopaque, @ptrCast(&foo)); |
| 771 | \\ _ = &func_ptr; | 771 | \\ _ = &func_ptr; |
| 772 | \\ var typed_func_ptr: ?*const fn () callconv(.C) void = @as(?*const fn () callconv(.C) void, @ptrFromInt(@as(c_ulong, @intCast(@intFromPtr(func_ptr))))); | 772 | \\ var typed_func_ptr: ?*const fn () callconv(.c) void = @as(?*const fn () callconv(.c) void, @ptrFromInt(@as(c_ulong, @intCast(@intFromPtr(func_ptr))))); |
| 773 | \\ _ = &typed_func_ptr; | 773 | \\ _ = &typed_func_ptr; |
| 774 | \\} | 774 | \\} |
| 775 | }); | 775 | }); |
| ... | @@ -839,9 +839,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -839,9 +839,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 839 | \\ lws_callback_function *callback_http; | 839 | \\ lws_callback_function *callback_http; |
| 840 | \\}; | 840 | \\}; |
| 841 | , &[_][]const u8{ | 841 | , &[_][]const u8{ |
| 842 | \\pub const lws_callback_function = fn () callconv(.C) void; | 842 | \\pub const lws_callback_function = fn () callconv(.c) void; |
| 843 | \\pub const struct_Foo = extern struct { | 843 | \\pub const struct_Foo = extern struct { |
| 844 | \\ func: ?*const fn () callconv(.C) void = @import("std").mem.zeroes(?*const fn () callconv(.C) void), | 844 | \\ func: ?*const fn () callconv(.c) void = @import("std").mem.zeroes(?*const fn () callconv(.c) void), |
| 845 | \\ callback_http: ?*const lws_callback_function = @import("std").mem.zeroes(?*const lws_callback_function), | 845 | \\ callback_http: ?*const lws_callback_function = @import("std").mem.zeroes(?*const lws_callback_function), |
| 846 | \\}; | 846 | \\}; |
| 847 | }); | 847 | }); |
| ... | @@ -867,7 +867,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -867,7 +867,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 867 | \\}; | 867 | \\}; |
| 868 | , &[_][]const u8{ | 868 | , &[_][]const u8{ |
| 869 | \\pub const struct_Foo = extern struct { | 869 | \\pub const struct_Foo = extern struct { |
| 870 | \\ derp: ?*const fn ([*c]struct_Foo) callconv(.C) void = @import("std").mem.zeroes(?*const fn ([*c]struct_Foo) callconv(.C) void), | 870 | \\ derp: ?*const fn ([*c]struct_Foo) callconv(.c) void = @import("std").mem.zeroes(?*const fn ([*c]struct_Foo) callconv(.c) void), |
| 871 | \\}; | 871 | \\}; |
| 872 | , | 872 | , |
| 873 | \\pub const Foo = struct_Foo; | 873 | \\pub const Foo = struct_Foo; |
| ... | @@ -1111,7 +1111,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1111,7 +1111,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1111 | cases.add("__cdecl doesn't mess up function pointers", | 1111 | cases.add("__cdecl doesn't mess up function pointers", |
| 1112 | \\void foo(void (__cdecl *fn_ptr)(void)); | 1112 | \\void foo(void (__cdecl *fn_ptr)(void)); |
| 1113 | , &[_][]const u8{ | 1113 | , &[_][]const u8{ |
| 1114 | \\pub extern fn foo(fn_ptr: ?*const fn () callconv(.C) void) void; | 1114 | \\pub extern fn foo(fn_ptr: ?*const fn () callconv(.c) void) void; |
| 1115 | }); | 1115 | }); |
| 1116 | 1116 | ||
| 1117 | cases.add("void cast", | 1117 | cases.add("void cast", |
| ... | @@ -1477,8 +1477,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1477,8 +1477,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1477 | \\typedef void (*fn0)(); | 1477 | \\typedef void (*fn0)(); |
| 1478 | \\typedef void (*fn1)(char); | 1478 | \\typedef void (*fn1)(char); |
| 1479 | , &[_][]const u8{ | 1479 | , &[_][]const u8{ |
| 1480 | \\pub const fn0 = ?*const fn (...) callconv(.C) void; | 1480 | \\pub const fn0 = ?*const fn (...) callconv(.c) void; |
| 1481 | \\pub const fn1 = ?*const fn (u8) callconv(.C) void; | 1481 | \\pub const fn1 = ?*const fn (u8) callconv(.c) void; |
| 1482 | }); | 1482 | }); |
| 1483 | 1483 | ||
| 1484 | cases.addWithTarget("Calling convention", .{ | 1484 | cases.addWithTarget("Calling convention", .{ |
| ... | @@ -1492,11 +1492,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1492,11 +1492,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1492 | \\void __attribute__((cdecl)) foo4(float *a); | 1492 | \\void __attribute__((cdecl)) foo4(float *a); |
| 1493 | \\void __attribute__((thiscall)) foo5(float *a); | 1493 | \\void __attribute__((thiscall)) foo5(float *a); |
| 1494 | , &[_][]const u8{ | 1494 | , &[_][]const u8{ |
| 1495 | \\pub extern fn foo1(a: [*c]f32) callconv(.Fastcall) void; | 1495 | \\pub extern fn foo1(a: [*c]f32) callconv(.{ .x86_fastcall = .{} }) void; |
| 1496 | \\pub extern fn foo2(a: [*c]f32) callconv(.Stdcall) void; | 1496 | \\pub extern fn foo2(a: [*c]f32) callconv(.{ .x86_stdcall = .{} }) void; |
| 1497 | \\pub extern fn foo3(a: [*c]f32) callconv(.Vectorcall) void; | 1497 | \\pub extern fn foo3(a: [*c]f32) callconv(.{ .x86_vectorcall = .{} }) void; |
| 1498 | \\pub extern fn foo4(a: [*c]f32) void; | 1498 | \\pub extern fn foo4(a: [*c]f32) void; |
| 1499 | \\pub extern fn foo5(a: [*c]f32) callconv(.Thiscall) void; | 1499 | \\pub extern fn foo5(a: [*c]f32) callconv(.{ .x86_thiscall = .{} }) void; |
| 1500 | }); | 1500 | }); |
| 1501 | 1501 | ||
| 1502 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ | 1502 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ |
| ... | @@ -1506,8 +1506,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1506,8 +1506,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1506 | \\void __attribute__((pcs("aapcs"))) foo1(float *a); | 1506 | \\void __attribute__((pcs("aapcs"))) foo1(float *a); |
| 1507 | \\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a); | 1507 | \\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a); |
| 1508 | , &[_][]const u8{ | 1508 | , &[_][]const u8{ |
| 1509 | \\pub extern fn foo1(a: [*c]f32) callconv(.AAPCS) void; | 1509 | \\pub extern fn foo1(a: [*c]f32) callconv(.{ .arm_aapcs = .{} }) void; |
| 1510 | \\pub extern fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void; | 1510 | \\pub extern fn foo2(a: [*c]f32) callconv(.{ .arm_aapcs_vfp = .{} }) void; |
| 1511 | }); | 1511 | }); |
| 1512 | 1512 | ||
| 1513 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ | 1513 | cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ |
| ... | @@ -1516,7 +1516,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1516,7 +1516,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1516 | }) catch unreachable, | 1516 | }) catch unreachable, |
| 1517 | \\void __attribute__((aarch64_vector_pcs)) foo1(float *a); | 1517 | \\void __attribute__((aarch64_vector_pcs)) foo1(float *a); |
| 1518 | , &[_][]const u8{ | 1518 | , &[_][]const u8{ |
| 1519 | \\pub extern fn foo1(a: [*c]f32) callconv(.Vectorcall) void; | 1519 | \\pub extern fn foo1(a: [*c]f32) callconv(.{ .aarch64_vfabi = .{} }) void; |
| 1520 | }); | 1520 | }); |
| 1521 | 1521 | ||
| 1522 | cases.add("Parameterless function prototypes", | 1522 | cases.add("Parameterless function prototypes", |
| ... | @@ -1533,8 +1533,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1533,8 +1533,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1533 | \\pub export fn b() void {} | 1533 | \\pub export fn b() void {} |
| 1534 | \\pub extern fn c(...) void; | 1534 | \\pub extern fn c(...) void; |
| 1535 | \\pub extern fn d() void; | 1535 | \\pub extern fn d() void; |
| 1536 | \\pub fn e() callconv(.C) void {} | 1536 | \\pub fn e() callconv(.c) void {} |
| 1537 | \\pub fn f() callconv(.C) void {} | 1537 | \\pub fn f() callconv(.c) void {} |
| 1538 | \\pub extern fn g() void; | 1538 | \\pub extern fn g() void; |
| 1539 | \\pub extern fn h() void; | 1539 | \\pub extern fn h() void; |
| 1540 | }); | 1540 | }); |
| ... | @@ -1555,7 +1555,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1555,7 +1555,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1555 | \\ char *arr1[10] ={0}; | 1555 | \\ char *arr1[10] ={0}; |
| 1556 | \\} | 1556 | \\} |
| 1557 | , &[_][]const u8{ | 1557 | , &[_][]const u8{ |
| 1558 | \\pub fn foo() callconv(.C) void { | 1558 | \\pub fn foo() callconv(.c) void { |
| 1559 | \\ var arr: [10]u8 = [1]u8{ | 1559 | \\ var arr: [10]u8 = [1]u8{ |
| 1560 | \\ 1, | 1560 | \\ 1, |
| 1561 | \\ } ++ [1]u8{0} ** 9; | 1561 | \\ } ++ [1]u8{0} ** 9; |
| ... | @@ -1686,13 +1686,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1686,13 +1686,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1686 | \\extern char (*fn_ptr2)(int, float); | 1686 | \\extern char (*fn_ptr2)(int, float); |
| 1687 | \\#define bar fn_ptr2 | 1687 | \\#define bar fn_ptr2 |
| 1688 | , &[_][]const u8{ | 1688 | , &[_][]const u8{ |
| 1689 | \\pub extern var fn_ptr: ?*const fn () callconv(.C) void; | 1689 | \\pub extern var fn_ptr: ?*const fn () callconv(.c) void; |
| 1690 | , | 1690 | , |
| 1691 | \\pub inline fn foo() void { | 1691 | \\pub inline fn foo() void { |
| 1692 | \\ return fn_ptr.?(); | 1692 | \\ return fn_ptr.?(); |
| 1693 | \\} | 1693 | \\} |
| 1694 | , | 1694 | , |
| 1695 | \\pub extern var fn_ptr2: ?*const fn (c_int, f32) callconv(.C) u8; | 1695 | \\pub extern var fn_ptr2: ?*const fn (c_int, f32) callconv(.c) u8; |
| 1696 | , | 1696 | , |
| 1697 | \\pub inline fn bar(arg_1: c_int, arg_2: f32) u8 { | 1697 | \\pub inline fn bar(arg_1: c_int, arg_2: f32) u8 { |
| 1698 | \\ return fn_ptr2.?(arg_1, arg_2); | 1698 | \\ return fn_ptr2.?(arg_1, arg_2); |
| ... | @@ -1714,8 +1714,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1714,8 +1714,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1714 | \\#define glClearPFN PFNGLCLEARPROC | 1714 | \\#define glClearPFN PFNGLCLEARPROC |
| 1715 | , &[_][]const u8{ | 1715 | , &[_][]const u8{ |
| 1716 | \\pub const GLbitfield = c_uint; | 1716 | \\pub const GLbitfield = c_uint; |
| 1717 | \\pub const PFNGLCLEARPROC = ?*const fn (GLbitfield) callconv(.C) void; | 1717 | \\pub const PFNGLCLEARPROC = ?*const fn (GLbitfield) callconv(.c) void; |
| 1718 | \\pub const OpenGLProc = ?*const fn () callconv(.C) void; | 1718 | \\pub const OpenGLProc = ?*const fn () callconv(.c) void; |
| 1719 | \\const struct_unnamed_1 = extern struct { | 1719 | \\const struct_unnamed_1 = extern struct { |
| 1720 | \\ Clear: PFNGLCLEARPROC = @import("std").mem.zeroes(PFNGLCLEARPROC), | 1720 | \\ Clear: PFNGLCLEARPROC = @import("std").mem.zeroes(PFNGLCLEARPROC), |
| 1721 | \\}; | 1721 | \\}; |
| ... | @@ -2691,9 +2691,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2691,9 +2691,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2691 | \\ return 0; | 2691 | \\ return 0; |
| 2692 | \\} | 2692 | \\} |
| 2693 | \\pub export fn bar() void { | 2693 | \\pub export fn bar() void { |
| 2694 | \\ var f: ?*const fn () callconv(.C) void = &foo; | 2694 | \\ var f: ?*const fn () callconv(.c) void = &foo; |
| 2695 | \\ _ = &f; | 2695 | \\ _ = &f; |
| 2696 | \\ var b: ?*const fn () callconv(.C) c_int = &baz; | 2696 | \\ var b: ?*const fn () callconv(.c) c_int = &baz; |
| 2697 | \\ _ = &b; | 2697 | \\ _ = &b; |
| 2698 | \\ f.?(); | 2698 | \\ f.?(); |
| 2699 | \\ f.?(); | 2699 | \\ f.?(); |
| ... | @@ -3048,8 +3048,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3048,8 +3048,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3048 | \\ baz(); | 3048 | \\ baz(); |
| 3049 | \\} | 3049 | \\} |
| 3050 | , &[_][]const u8{ | 3050 | , &[_][]const u8{ |
| 3051 | \\pub fn bar() callconv(.C) void {} | 3051 | \\pub fn bar() callconv(.c) void {} |
| 3052 | \\pub export fn foo(arg_baz: ?*const fn () callconv(.C) [*c]c_int) void { | 3052 | \\pub export fn foo(arg_baz: ?*const fn () callconv(.c) [*c]c_int) void { |
| 3053 | \\ var baz = arg_baz; | 3053 | \\ var baz = arg_baz; |
| 3054 | \\ _ = &baz; | 3054 | \\ _ = &baz; |
| 3055 | \\ bar(); | 3055 | \\ bar(); |
| ... | @@ -3112,7 +3112,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3112,7 +3112,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3112 | \\ do {} while (0); | 3112 | \\ do {} while (0); |
| 3113 | \\} | 3113 | \\} |
| 3114 | , &[_][]const u8{ | 3114 | , &[_][]const u8{ |
| 3115 | \\pub fn foo() callconv(.C) void { | 3115 | \\pub fn foo() callconv(.c) void { |
| 3116 | \\ if (true) while (true) { | 3116 | \\ if (true) while (true) { |
| 3117 | \\ if (!false) break; | 3117 | \\ if (!false) break; |
| 3118 | \\ }; | 3118 | \\ }; |
| ... | @@ -3212,10 +3212,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3212,10 +3212,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3212 | \\void c(void) {} | 3212 | \\void c(void) {} |
| 3213 | \\static void foo() {} | 3213 | \\static void foo() {} |
| 3214 | , &[_][]const u8{ | 3214 | , &[_][]const u8{ |
| 3215 | \\pub fn a() callconv(.C) void {} | 3215 | \\pub fn a() callconv(.c) void {} |
| 3216 | \\pub fn b() callconv(.C) void {} | 3216 | \\pub fn b() callconv(.c) void {} |
| 3217 | \\pub export fn c() void {} | 3217 | \\pub export fn c() void {} |
| 3218 | \\pub fn foo() callconv(.C) void {} | 3218 | \\pub fn foo() callconv(.c) void {} |
| 3219 | }); | 3219 | }); |
| 3220 | 3220 | ||
| 3221 | cases.add("casting away const and volatile", | 3221 | cases.add("casting away const and volatile", |