zig
zig copied to clipboard
Unable to use `callconv(.Interrupt)` for riscv targets
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
Currently compiling this function for riscv targets will yield the following error:
export fn _irq() callconv(.Interrupt) void {
asm volatile ("nop");
}
error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not riscv32
irq routines in riscv requires a different mret instruction at the end and this is achieved in C as in the following:
void _irq() __attribute__((interrupt)) {
asm ("nop");
}
for which LLVM generates the following code:
000111e0 <_irq>:
111e0: 1141 addi sp,sp,-16
111e2: c606 sw ra,12(sp)
111e4: c422 sw s0,8(sp)
111e6: 0800 addi s0,sp,16
111e8: 0001 nop
111ea: 40b2 lw ra,12(sp)
111ec: 4422 lw s0,8(sp)
111ee: 0141 addi sp,sp,16
111f0: 30200073 mret
I dont know enough about zig/llvm internals to know if the zig callconv(.Interrupt) has anything to do with the way C's attributes are handled wrt llvm but it'll be useful to be able to implement riscv irq routines in pure zig.
Expected Behavior
Able to use callconv(.Interrupt) on riscv targets.
Looks like there are three modes of interrupts https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v
LLVM implements them as function attributes rather than calling conventions, I'm guessing we would add InterruptUser, InterruptSupervisor and InterruptMachine and have Interrupt alias InterruptMachine.
This should be easy to implement after #21697
Though currently LLVM doesn't seem to implement interrupt("user") correctly https://c.godbolt.org/z/58oP6Tdc9
I'm not sure how much that matters but maybe it should be a compile error for now?
This should be easy to implement after #21697
It's my understanding that the intent actually is for #21697 to implement this, no? @mlugg
Though currently LLVM doesn't seem to implement
interrupt("user")correctly https://c.godbolt.org/z/58oP6Tdc9
What's not correct about this?
It's my understanding that the intent actually is for #21697 to implement this, no?
I don't think I've added support for riscv{32,64}_interrupt to the LLVM backend yet, but I certainly can. I'll wait for you and Vexu to figure out the details before making the relevant changes.
Ah, it looks like user-mode interrupts were ultimately cut from the ISA. So yes, we should just exclude
user from std.builtin.CallingConvention.RiscvInterruptOptions.level.