diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 257113f477..ebc3762bbc 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1904,6 +1904,7 @@ pub const Cpu = struct { => &.{.m68k}, .microblaze_std, + .microblaze_interrupt, => &.{ .microblaze, .microblazeel }, .msp430_eabi, diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index 84b228d685..983358ceeb 100644 --- a/lib/std/builtin.zig +++ b/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. diff --git a/src/InternPool.zig b/src/InternPool.zig index 445245fbe9..05ca2ae2c7 100644 --- a/src/InternPool.zig +++ b/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), diff --git a/src/Sema.zig b/src/Sema.zig index 62e6942a5b..398fb7e5bb 100644 --- a/src/Sema.zig +++ b/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; }, diff --git a/src/Zcu.zig b/src/Zcu.zig index 9839db6659..539a45d722 100644 --- a/src/Zcu.zig +++ b/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, diff --git a/src/codegen/c.zig b/src/codegen/c.zig index a47d031520..e531125a40 100644 --- a/src/codegen/c.zig +++ b/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) { diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 9d23178887..0bda369deb 100644 --- a/src/codegen/llvm.zig +++ b/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, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index cc440905f0..da39a2fa4e 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -3925,6 +3925,7 @@ fn updateLazyType( .avr_interrupt, .csky_interrupt, .m68k_interrupt, + .microblaze_interrupt, .msp430_interrupt, => .normal,