diff --git a/lib/std/Target.zig b/lib/std/Target.zig index eeb755aa2002d219890155fa854d25a9449abefe..3982794c7632825d9cb79ee135bab86ab41bd614 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1754,6 +1754,7 @@ pub const Cpu = struct { => &.{ .wasm64, .wasm32 }, .arc_sysv, + .arc_interrupt, => &.{.arc}, .avr_gnu, diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index a3f3e791e6bc837c1e966866f7891d408f0b09a2..fbd65c5574299096cfefb74080e0534ec1dd2b35 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -277,6 +277,7 @@ pub const CallingConvention = union(enum(u8)) { /// The standard `arc` calling convention. arc_sysv: CommonOptions, + arc_interrupt: ArcInterruptOptions, // Calling conventions for the `avr` architecture. avr_gnu, @@ -368,6 +369,22 @@ pub const CallingConvention = union(enum(u8)) { register_params: u2 = 0, }; + /// Options for the `arc_interrupt` calling convention. + pub const ArcInterruptOptions = 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, + /// The kind of interrupt being received. + type: InterruptType, + + pub const InterruptType = enum(u2) { + ilink1, + ilink2, + ilink, + firq, + }; + }; + /// Options for the `arm_interrupt` calling convention. pub const ArmInterruptOptions = struct { /// The boundary the stack is aligned to when the function is called. diff --git a/src/InternPool.zig b/src/InternPool.zig index 17fafe320e0af9d7d0819f604eb0fcd1be31ee2e..445245fbe912641b2cc68cea8af899261d7b3025 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -12950,6 +12950,11 @@ const PackedCallingConvention = packed struct(u18) { .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), .extra = pl.register_params, }, + std.builtin.CallingConvention.ArcInterruptOptions => .{ + .tag = tag, + .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), + .extra = @intFromEnum(pl.type), + }, std.builtin.CallingConvention.ArmInterruptOptions => .{ .tag = tag, .incoming_stack_alignment = .fromByteUnits(pl.incoming_stack_alignment orelse 0), @@ -12984,6 +12989,10 @@ const PackedCallingConvention = packed struct(u18) { .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), .register_params = @intCast(cc.extra), }, + std.builtin.CallingConvention.ArcInterruptOptions => .{ + .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), + .type = @enumFromInt(cc.extra), + }, std.builtin.CallingConvention.ArmInterruptOptions => .{ .incoming_stack_alignment = cc.incoming_stack_alignment.toByteUnits(), .type = @enumFromInt(cc.extra), diff --git a/src/Sema.zig b/src/Sema.zig index aef98a4dcd3820f520633cac6fbdfd93453c0594..3361d1a59cea6c484c8672df0d62e4fb0ab07a87 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9122,6 +9122,7 @@ fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool { return switch (cc) { .naked, + .arc_interrupt, .arm_interrupt, .avr_interrupt, .avr_signal, @@ -9284,6 +9285,7 @@ fn funcCommon( else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), i + 1 }), } }, + .arc_interrupt, .arm_interrupt, .mips64_interrupt, .mips_interrupt, @@ -9515,6 +9517,7 @@ fn finishFunc( .mips_interrupt, .riscv64_interrupt, .riscv32_interrupt, + .arc_interrupt, .avr_interrupt, .csky_interrupt, .m68k_interrupt, @@ -30038,6 +30041,9 @@ fn callconvCoerceAllowed( std.builtin.CallingConvention.X86RegparmOptions => { if (src_data.register_params != dest_data.register_params) return false; }, + std.builtin.CallingConvention.ArcInterruptOptions => { + if (src_data.type != dest_data.type) return false; + }, std.builtin.CallingConvention.ArmInterruptOptions => { if (src_data.type != dest_data.type) return false; }, diff --git a/src/Zcu.zig b/src/Zcu.zig index 8579eb39060adae3521d2cd12d78bb301946141e..ea030905ebbf737fae281daad917356db6f1d2a1 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -4475,6 +4475,9 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.builtin.CallingConvention) union(enu .arm_aapcs_vfp, => |opts| opts.incoming_stack_alignment == null, + .arc_interrupt, + => |opts| opts.incoming_stack_alignment == null, + .arm_interrupt, => |opts| opts.incoming_stack_alignment == null, diff --git a/src/codegen/c.zig b/src/codegen/c.zig index d47c7657e655655335212cc6e1817482b34dba4e..bf9be70529f1864cdf67cace0a478598941d47bb 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -8077,6 +8077,10 @@ fn toCallingConvention(cc: std.builtin.CallingConvention, zcu: *Zcu) ?[]const u8 .arm_aapcs => "pcs(\"aapcs\")", .arm_aapcs_vfp => "pcs(\"aapcs-vfp\")", + .arc_interrupt => |opts| switch (opts.type) { + inline else => |t| "interrupt(\"" ++ @tagName(t) ++ "\")", + }, + .arm_interrupt => |opts| switch (opts.type) { .generic => "interrupt", .irq => "interrupt(\"IRQ\")", diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 5d0b87baeed22c3351b1217218629453023ba678..8fae998492aa84af750dbda77c6aa9f07618860a 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -11816,6 +11816,7 @@ pub fn toLlvmCallConv(cc: std.builtin.CallingConvention, target: *const std.Targ const incoming_stack_alignment: ?u64, const register_params: u2 = switch (cc) { inline else => |pl| switch (@TypeOf(pl)) { void => .{ null, 0 }, + std.builtin.CallingConvention.ArcInterruptOptions, std.builtin.CallingConvention.ArmInterruptOptions, std.builtin.CallingConvention.RiscvInterruptOptions, std.builtin.CallingConvention.MipsInterruptOptions, @@ -11919,6 +11920,7 @@ fn toLlvmCallConvTag(cc_tag: std.builtin.CallingConvention.Tag, target: *const s .powerpc_aix_altivec, .wasm_mvp, .arc_sysv, + .arc_interrupt, .avr_gnu, .bpf_std, .csky_sysv, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 3aeffb03653f5111b33a635a684c49b7ea197034..a9cfefa2c4aca4c63cfc53c50b8bd34f786b2d03 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -3917,6 +3917,7 @@ fn updateLazyType( .mips_interrupt, .riscv64_interrupt, .riscv32_interrupt, + .arc_interrupt, .avr_builtin, .avr_signal, .avr_interrupt,