authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2024-10-28 13:51:11+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-10-28 13:51:11+01:00
log4c336705b9c27a7f7152ef51116121d6bf209ac4
tree1e21f91d42b06612b371967c2105cdd49619d9d0
parent6415ff29d717ad10cd9e2bdae9e77677f8e1f8fa
parent93e5ea033c8b92447ad074842a5497cae730437d
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21807 from Rexicon226/riscv-interupt

implement new interrupt calling conventions in the llvm backend

2 files changed, 60 insertions(+), 9 deletions(-)

lib/std/builtin.zig+1-1
......@@ -470,7 +470,7 @@ pub const CallingConvention = union(enum(u8)) {
470470 /// `null` means the default for this calling convention.
471471 incoming_stack_alignment: ?u64 = null,
472472 /// The privilege mode.
473 mode: PrivilegeMode = .machine,
473 mode: PrivilegeMode,
474474
475475 pub const PrivilegeMode = enum(u2) {
476476 supervisor,
src/codegen/llvm.zig+59-8
......@@ -3076,6 +3076,50 @@ pub const Object = struct {
30763076 for (cc_info.inreg_param_count..std.math.maxInt(u2)) |param_idx| {
30773077 _ = try attributes.removeParamAttr(param_idx, .inreg);
30783078 }
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 }
30793123 }
30803124
30813125 if (resolved.alignment != .none)
......@@ -11609,9 +11653,13 @@ pub fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: std.Target) ?Ca
1160911653 const incoming_stack_alignment: ?u64, const register_params: u2 = switch (cc) {
1161011654 inline else => |pl| switch (@TypeOf(pl)) {
1161111655 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 },
1161311661 std.builtin.CallingConvention.X86RegparmOptions => .{ pl.incoming_stack_alignment, pl.register_params },
11614 else => unreachable,
11662 else => @compileError("TODO: toLlvmCallConv" ++ @tagName(pl)),
1161511663 },
1161611664 };
1161711665 return .{
......@@ -11676,6 +11724,15 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
1167611724 .nvptx_device => .ptx_device,
1167711725 .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
1167911736 // All the calling conventions which LLVM does not have a general representation for.
1168011737 // Note that these are often still supported through the `cCallingConvention` path above via `ccc`.
1168111738 .x86_sysv,
......@@ -11685,16 +11742,11 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
1168511742 .aarch64_aapcs_darwin,
1168611743 .aarch64_aapcs_win,
1168711744 .arm_aapcs16_vfp,
11688 .arm_interrupt,
1168911745 .mips64_n64,
1169011746 .mips64_n32,
11691 .mips64_interrupt,
1169211747 .mips_o32,
11693 .mips_interrupt,
1169411748 .riscv64_lp64,
11695 .riscv64_interrupt,
1169611749 .riscv32_ilp32,
11697 .riscv32_interrupt,
1169811750 .sparc64_sysv,
1169911751 .sparc_sysv,
1170011752 .powerpc64_elf,
......@@ -11709,7 +11761,6 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: std.Targ
1170911761 .avr_gnu,
1171011762 .bpf_std,
1171111763 .csky_sysv,
11712 .csky_interrupt,
1171311764 .hexagon_sysv,
1171411765 .hexagon_sysv_hvx,
1171511766 .lanai_sysv,