Commit 4fa453ce20

Alex Rønne Petersen <alex@alexrp.com>
2025-10-20 19:47:51
std.builtin: add CallingConvention.microblaze_interrupt
Only supported in CBE.
1 parent abf40ca
lib/std/builtin.zig
@@ -323,6 +323,7 @@ pub const CallingConvention = union(enum(u8)) {
 
     /// The standard `microblaze`/`microblazeel` calling convention.
     microblaze_std: CommonOptions,
+    microblaze_interrupt: MicroblazeInterruptOptions,
 
     /// The standard `msp430` calling convention.
     msp430_eabi: CommonOptions,
@@ -421,6 +422,25 @@ pub const CallingConvention = union(enum(u8)) {
         };
     };
 
+    /// Options for the `microblaze_interrupt` calling convention.
+    pub const MicroblazeInterruptOptions = struct {
+        /// The boundary the stack is aligned to when the function is called.
+        /// `null` means the default for this calling convention.
+        incoming_stack_alignment: ?u64 = null,
+        type: InterruptType = .regular,
+
+        pub const InterruptType = enum(u2) {
+            /// User exception; return with `rtsd`.
+            user,
+            /// Regular interrupt; return with `rtid`.
+            regular,
+            /// Fast interrupt; return with `rtid`.
+            fast,
+            /// Software breakpoint; return with `rtbd`.
+            breakpoint,
+        };
+    };
+
     /// Options for the `mips_interrupt` and `mips64_interrupt` calling conventions.
     pub const MipsInterruptOptions = struct {
         /// The boundary the stack is aligned to when the function is called.
lib/std/Target.zig
@@ -1904,6 +1904,7 @@ pub const Cpu = struct {
                 => &.{.m68k},
 
                 .microblaze_std,
+                .microblaze_interrupt,
                 => &.{ .microblaze, .microblazeel },
 
                 .msp430_eabi,
src/codegen/c.zig
@@ -8092,6 +8092,13 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8
 
         .avr_signal => "signal",
 
+        .microblaze_interrupt => |opts| switch (opts.type) {
+            .user => "save_volatiles",
+            .regular => "interrupt_handler",
+            .fast => "fast_interrupt",
+            .breakpoint => "break_handler",
+        },
+
         .mips_interrupt,
         .mips64_interrupt,
         => |opts| switch (opts.mode) {
src/codegen/llvm.zig
@@ -11837,6 +11837,7 @@ pub fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: *const std.Targ
             std.builtin.CallingConvention.ArcInterruptOptions,
             std.builtin.CallingConvention.ArmInterruptOptions,
             std.builtin.CallingConvention.RiscvInterruptOptions,
+            std.builtin.CallingConvention.MicroblazeInterruptOptions,
             std.builtin.CallingConvention.MipsInterruptOptions,
             std.builtin.CallingConvention.CommonOptions,
             => .{ pl.incoming_stack_alignment, 0 },
@@ -11926,6 +11927,7 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s
         .aarch64_aapcs_win,
         .alpha_osf,
         .microblaze_std,
+        .microblaze_interrupt,
         .mips64_n64,
         .mips64_n32,
         .mips_o32,
src/link/Dwarf.zig
@@ -3925,6 +3925,7 @@ fn updateLazyType(
                     .avr_interrupt,
                     .csky_interrupt,
                     .m68k_interrupt,
+                    .microblaze_interrupt,
                     .msp430_interrupt,
                     => .normal,
 
src/InternPool.zig
@@ -12960,6 +12960,11 @@ const PackedCallingConvention = packed struct(u18) {
                     .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
                     .extra = @intFromEnum(pl.type),
                 },
+                std.builtin.CallingConvention.MicroblazeInterruptOptions => .{
+                    .tag = tag,
+                    .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
+                    .extra = @intFromEnum(pl.type),
+                },
                 std.builtin.CallingConvention.MipsInterruptOptions => .{
                     .tag = tag,
                     .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0),
@@ -12997,6 +13002,10 @@ const PackedCallingConvention = packed struct(u18) {
                         .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
                         .type = @enumFromInt(cc.extra),
                     },
+                    std.builtin.CallingConvention.MicroblazeInterruptOptions => .{
+                        .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
+                        .type = @enumFromInt(cc.extra),
+                    },
                     std.builtin.CallingConvention.MipsInterruptOptions => .{
                         .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(),
                         .mode = @enumFromInt(cc.extra),
src/Sema.zig
@@ -9135,6 +9135,7 @@ fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {
         .avr_signal,
         .csky_interrupt,
         .m68k_interrupt,
+        .microblaze_interrupt,
         .mips_interrupt,
         .mips64_interrupt,
         .msp430_interrupt,
@@ -9295,6 +9296,7 @@ fn funcCommon(
             },
             .arc_interrupt,
             .arm_interrupt,
+            .microblaze_interrupt,
             .mips64_interrupt,
             .mips_interrupt,
             .riscv64_interrupt,
@@ -9530,6 +9532,7 @@ fn finishFunc(
         .avr_interrupt,
         .csky_interrupt,
         .m68k_interrupt,
+        .microblaze_interrupt,
         .msp430_interrupt,
         .avr_signal,
         => if (return_type.zigTypeTag(zcu) != .void and return_type.zigTypeTag(zcu) != .noreturn) {
@@ -30057,6 +30060,9 @@ fn callconvCoerceAllowed(
                 std.builtin.CallingConvention.ArmInterruptOptions => {
                     if (src_data.type != dest_data.type) return false;
                 },
+                std.builtin.CallingConvention.MicroblazeInterruptOptions => {
+                    if (src_data.type != dest_data.type) return false;
+                },
                 std.builtin.CallingConvention.MipsInterruptOptions => {
                     if (src_data.mode != dest_data.mode) return false;
                 },
src/Zcu.zig
@@ -4438,6 +4438,9 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu
                 .arm_interrupt,
                 => |opts| opts.incoming_stack_alignment == null,
 
+                .microblaze_interrupt,
+                => |opts| opts.incoming_stack_alignment == null,
+
                 .mips_interrupt,
                 .mips64_interrupt,
                 => |opts| opts.incoming_stack_alignment == null,