zig icon indicating copy to clipboard operation
zig copied to clipboard

Unable to use `callconv(.Interrupt)` for riscv targets

Open akiroz opened this issue 1 year ago • 1 comments

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.

akiroz avatar Jul 18 '24 06:07 akiroz

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.

Vexu avatar Jul 18 '24 07:07 Vexu

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?

Vexu avatar Oct 15 '24 12:10 Vexu

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?

alexrp avatar Oct 15 '24 13:10 alexrp

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.

mlugg avatar Oct 15 '24 13:10 mlugg

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.

alexrp avatar Oct 15 '24 13:10 alexrp