authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-10-26 08:25:16-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-10-27 13:33:27-07:00
log93e5ea033c8b92447ad074842a5497cae730437d
tree69e0b973b8fd9ddc16cae516f12644fcc3ffb7af
parentb122b9fbe0e4e63b97eb89dc5049baa3db1f1e1b
signaturelock-open Commit is signed but in an unrecognized format.

implement new interrupts in the llvm backend


1 files changed, 59 insertions(+), 8 deletions(-)

src/codegen/llvm.zig+59-8
...@@ -3076,6 +3076,50 @@ pub const Object = struct {...@@ -3076,6 +3076,50 @@ pub const Object = struct {
3076 for (cc_info.inreg_param_count..std.math.maxInt(u2)) |param_idx| {3076 for (cc_info.inreg_param_count..std.math.maxInt(u2)) |param_idx| {
3077 _ = try attributes.removeParamAttr(param_idx, .inreg);3077 _ = try attributes.removeParamAttr(param_idx, .inreg);
3078 }3078 }
3079
3080 switch (fn_info.cc) {
3081 inline .riscv64_interrupt,
3082 .riscv32_interrupt,
3083 .mips_interrupt,
3084 .mips64_interrupt,
3085 => |info| {
3086 try attributes.addFnAttr(.{ .string = .{
3087 .kind = try o.builder.string("interrupt"),
3088 .value = try o.builder.string(@tagName(info.mode)),
3089 } }, &o.builder);
3090 },
3091 .arm_interrupt,
3092 => |info| {
3093 try attributes.addFnAttr(.{ .string = .{
3094 .kind = try o.builder.string("interrupt"),
3095 .value = try o.builder.string(switch (info.type) {
3096 .generic => "",
3097 .irq => "IRQ",
3098 .fiq => "FIQ",
3099 .swi => "SWI",
3100 .abort => "ABORT",
3101 .undef => "UNDEF",
3102 }),
3103 } }, &o.builder);
3104 },
3105 // these function attributes serve as a backup against any mistakes LLVM makes.
3106 // clang sets both the function's calling convention and the function attributes
3107 // in its backend, so future patches to the AVR backend could end up checking only one,
3108 // possibly breaking our support. it's safer to just emit both.
3109 .avr_interrupt, .avr_signal, .csky_interrupt => {
3110 try attributes.addFnAttr(.{ .string = .{
3111 .kind = try o.builder.string(switch (fn_info.cc) {
3112 .avr_interrupt,
3113 .csky_interrupt,
3114 => "interrupt",
3115 .avr_signal => "signal",
3116 else => unreachable,
3117 }),
3118 .value = .empty,
3119 } }, &o.builder);
3120 },
3121 else => {},
3122 }
3079 }3123 }
30803124
3081 if (resolved.alignment != .none)3125 if (resolved.alignment != .none)
...@@ -11609,9 +11653,13 @@ pub fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) ?Ca...@@ -11609,9 +11653,13 @@ pub fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) ?Ca
11609 const incoming_stack_alignment: ?u64, const register_params: u2 = switch (cc) {11653 const incoming_stack_alignment: ?u64, const register_params: u2 = switch (cc) {
11610 inline else => |pl| switch (@TypeOf(pl)) {11654 inline else => |pl| switch (@TypeOf(pl)) {
11611 void => .{ null, 0 },11655 void => .{ null, 0 },
11612 std.builtin.CallingConvention.CommonOptions => .{ pl.incoming_stack_alignment, 0 },11656 std.builtin.CallingConvention.ArmInterruptOptions,
11657 std.builtin.CallingConvention.RiscvInterruptOptions,
11658 std.builtin.CallingConvention.MipsInterruptOptions,
11659 std.builtin.CallingConvention.CommonOptions,
11660 => .{ pl.incoming_stack_alignment, 0 },
11613 std.builtin.CallingConvention.X86RegparmOptions => .{ pl.incoming_stack_alignment, pl.register_params },11661 std.builtin.CallingConvention.X86RegparmOptions => .{ pl.incoming_stack_alignment, pl.register_params },
11614 else => unreachable,11662 else => @compileError("TODO: toLlvmCallConv" ++ @tagName(pl)),
11615 },11663 },
11616 };11664 };
11617 return .{11665 return .{
...@@ -11676,6 +11724,15 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ...@@ -11676,6 +11724,15 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
11676 .nvptx_device => .ptx_device,11724 .nvptx_device => .ptx_device,
11677 .nvptx_kernel => .ptx_kernel,11725 .nvptx_kernel => .ptx_kernel,
1167811726
11727 // Calling conventions which LLVM uses function attributes for.
11728 .riscv64_interrupt,
11729 .riscv32_interrupt,
11730 .arm_interrupt,
11731 .mips64_interrupt,
11732 .mips_interrupt,
11733 .csky_interrupt,
11734 => .ccc,
11735
11679 // All the calling conventions which LLVM does not have a general representation for.11736 // All the calling conventions which LLVM does not have a general representation for.
11680 // Note that these are often still supported through the `cCallingConvention` path above via `ccc`.11737 // Note that these are often still supported through the `cCallingConvention` path above via `ccc`.
11681 .x86_sysv,11738 .x86_sysv,
...@@ -11685,16 +11742,11 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ...@@ -11685,16 +11742,11 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
11685 .aarch64_aapcs_darwin,11742 .aarch64_aapcs_darwin,
11686 .aarch64_aapcs_win,11743 .aarch64_aapcs_win,
11687 .arm_aapcs16_vfp,11744 .arm_aapcs16_vfp,
11688 .arm_interrupt,
11689 .mips64_n64,11745 .mips64_n64,
11690 .mips64_n32,11746 .mips64_n32,
11691 .mips64_interrupt,
11692 .mips_o32,11747 .mips_o32,
11693 .mips_interrupt,
11694 .riscv64_lp64,11748 .riscv64_lp64,
11695 .riscv64_interrupt,
11696 .riscv32_ilp32,11749 .riscv32_ilp32,
11697 .riscv32_interrupt,
11698 .sparc64_sysv,11750 .sparc64_sysv,
11699 .sparc_sysv,11751 .sparc_sysv,
11700 .powerpc64_elf,11752 .powerpc64_elf,
...@@ -11709,7 +11761,6 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ...@@ -11709,7 +11761,6 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
11709 .avr_gnu,11761 .avr_gnu,
11710 .bpf_std,11762 .bpf_std,
11711 .csky_sysv,11763 .csky_sysv,
11712 .csky_interrupt,
11713 .hexagon_sysv,11764 .hexagon_sysv,
11714 .hexagon_sysv_hvx,11765 .hexagon_sysv_hvx,
11715 .lanai_sysv,11766 .lanai_sysv,