riscv / riscv-isa-manual

RISC-V Instruction Set Manual
https://riscv.org/
Creative Commons Attribution 4.0 International
3.71k stars 643 forks source link

illegal instruction fault frcsr t0 #1674

Closed yf13 closed 1 month ago

yf13 commented 1 month ago

Dear experts,

I got exception Illegal instruction fault(2) with mepc=80004d44 and mtval=0 when running M-mode program on QEMU RiscV target. The code fragment looks like:

$ riscv64-unknown-elf-objdump -dS sample | fgrep 80004d44: -C1
80004d42: ad6e                  fsd fs11,152(sp)
80004d44: 003022f3              frcsr t0
80004d48: de16                  sw  t0,60(sp)

Could someone kindly teach what this exception means here?

aswaterman commented 1 month ago

There are only two possible explanations: the M-mode software forgot to set mstatus.FS to a nonzero value, or the QEMU instance had floating-point disabled.

allenjbaum commented 1 month ago

Except epc == 4d44 points to the frcsr, therefore the fsd must have executed without exception (so mstatus.FS must be nonzero)

On Sat, Oct 5, 2024 at 11:37 PM Andrew Waterman @.***> wrote:

There are only two possible explanations: the M-mode software forgot to set mstatus.FS to a nonzero value, or the QEMU instance had floating-point disabled.

— Reply to this email directly, view it on GitHub https://github.com/riscv/riscv-isa-manual/issues/1674#issuecomment-2395315611, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHPXVJXROLOG52IR3WGKR2TZ2DLB5AVCNFSM6AAAAABPOBCRKOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOJVGMYTKNRRGE . You are receiving this because you are subscribed to this thread.Message ID: @.***>

yf13 commented 1 month ago

many thanks @aswaterman and @allenjbaum. Here my FS field is 0, so it is case 1 above.

When saving context, we should:

When resuming context, we should:

I am wondering that mstatus.FS field may change implicitly when float registers are updated, so we should update mstatus after recovering the float registers?

aswaterman commented 1 month ago

The act of loading the float registers in the context-restore code will change FS to Dirty, so you should change FS to Clean after performing the loads.

yf13 commented 1 month ago

The act of loading the float registers in the context-restore code will change FS to Dirty, so you should change FS to Clean after performing the loads.

Thanks. Then if FS was Initial upon context resuming, we shall do fmv.w.x ft0, zero alike to set float registers to zero, then set FS to Clean afterwards?

aswaterman commented 1 month ago

That’s the right idea, but in that case, you can set it to Initial rather than Clean.

yf13 commented 1 month ago

thanks again. I'll continue check why FS became 0.