Skip to content

Add FFLAGS and FRM CSRs #657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 8, 2025

Conversation

neverlandiz
Copy link
Contributor

@neverlandiz neverlandiz commented Apr 24, 2025

The PR addresses Issue #559 and adds the remaining F CSRs.

  • FFLAGS
  • FRM

Most of the information for the two CSRs is also included in fcsr.yaml since fcsr is frm + fflags.

@neverlandiz neverlandiz requested a review from dhower-qc as a code owner April 24, 2025 01:46
Copy link
Collaborator

@AFOliveira AFOliveira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than minor comments, all seems good, great work @neverlandiz!

@AFOliveira AFOliveira linked an issue Apr 24, 2025 that may be closed by this pull request
@neverlandiz
Copy link
Contributor Author

@AFOliveira Thank you so much for the feedback! I've made the changes that you requested.

Copy link
Collaborator

@AFOliveira AFOliveira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the second review, but this is mostly things that I don't understand. Your PR may be ready to merge but there are somethings I would like to ask so we may discuss them before merging.

This CSRs exist inside fcsr, but instead of making some type of connection between them we are just duplicating information in most of the description, I realize UDB may not have a way to tie CSRs in "pseudo-instruction" type of way, but this may be the case of opening an issue requesting that, right? Otherwise, we will have precisely the same information in two places, which does not seem very logical.

@ThinkOpenly
Copy link
Collaborator

This CSRs exist inside fcsr, but instead of making some type of connection between them we are just duplicating information in most of the description, I realize UDB may not have a way to tie CSRs in "pseudo-instruction" type of way, but this may be the case of opening an issue requesting that, right? Otherwise, we will have precisely the same information in two places, which does not seem very logical.

We do have an "alias" attribute for CSR fields. There are lots of examples in arch/csr, including arch/csr/sstatus.yaml:

fields:
  SD:
[...]
    alias: mstatus.SD

Copy link
Contributor

@jordancarlin jordancarlin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is handled elsewhere, but does something need to be done to make this CSR inaccessible if mstatus.FS is 0 (only for the F extension, for Zfinx this constraint is different).

@ThinkOpenly
Copy link
Collaborator

Not sure if this is handled elsewhere, but does something need to be done to make this CSR inaccessible if mstatus.FS is 0 (only for the F extension, for Zfinx this constraint is different).

We don't currently handle it anywhere, that I see, unless it's buried under select_instr_or_fcsr_rm, but I can't find the implementation for that anywhere. (?)

All of FCSR, FRM, FFLAGS needs that constraint added, as well as any instruction that might access it (which is why select_instr_or_fcsr_rm would be a good place to put the check).

@jordancarlin, is it true that with Zfinx, only the static (embedded in the opcode) rounding mode is supported? (That's my conclusion from reading the spec.)

@jordancarlin
Copy link
Contributor

Not sure if this is handled elsewhere, but does something need to be done to make this CSR inaccessible if mstatus.FS is 0 (only for the F extension, for Zfinx this constraint is different).

We don't currently handle it anywhere, that I see, unless it's buried under select_instr_or_fcsr_rm, but I can't find the implementation for that anywhere. (?)

All of FCSR, FRM, FFLAGS needs that constraint added, as well as any instruction that might access it (which is why select_instr_or_fcsr_rm would be a good place to put the check).

Not sure that select_instr_or_fcsr_rm is sufficient because it also needs to impact regular reads/writes to these CSRs.

@jordancarlin, is it true that with Zfinx, only the static (embedded in the opcode) rounding mode is supported? (That's my conclusion from reading the spec.)

I don't think so. With both F and Zfinx instructions the rounding mode can be statically determined from the opcode or dynamically driven by the FRM csr. When F is implemented, mstatus.FS controls whether FCSR, FRM, and FFLAGS are accessible by regular CSR read/write instructions (and whether F instructions are allowed, but that's a separate point). When Zfinx is implemented, mstatus.FS is tied to 0 and FCSR, FRM, and FFLAGS are always accessible irrespective of mstatus.FS.

From section 26.7 of the unprivileged spec:

In the standard privileged architecture defined in Volume II, the mstatus field FS is hardwired to 0 if the Zfinx extension is implemented, and FS no longer affects the trapping behavior of floating-point instructions or fcsr accesses.

Sail represents all of this as follows:

function clause currentlyEnabled(Ext_F) = hartSupports(Ext_F) & (misa[F] == 0b1) & (mstatus[FS] != 0b00)
function clause currentlyEnabled(Ext_Zfinx) = hartSupports(Ext_Zfinx)

function clause is_CSR_defined (0x001) = currentlyEnabled(Ext_F) | currentlyEnabled(Ext_Zfinx)
function clause is_CSR_defined (0x002) = currentlyEnabled(Ext_F) | currentlyEnabled(Ext_Zfinx)
function clause is_CSR_defined (0x003) = currentlyEnabled(Ext_F) | currentlyEnabled(Ext_Zfinx)

@jordancarlin
Copy link
Contributor

jordancarlin commented Apr 30, 2025

In the Zfinx case, I guess Smstateen also comes into play. For Zfinx (but not F), mstateen0.FCSR controls access to FCSR, FRM, and FFLAGS. Smstateen is still a work in progress in Sail.

So it seems like if F is supported, we need one set of checks for whether FCSR, FRM, and FFLAGS are supported, and if Zfinx is supported, we need a different set of checks.

@ThinkOpenly
Copy link
Collaborator

When Zfinx is implemented, mstatus.FS is tied to 0 and FCSR, FRM, and FFLAGS are always accessible irrespective of mstatus.FS.

From section 26.7 of the unprivileged spec:

In the standard privileged architecture defined in Volume II, the mstatus field FS is hardwired to 0 if the Zfinx extension is implemented, and FS no longer affects the trapping behavior of floating-point instructions or fcsr accesses.

I am confused by that and this (priv 3.1.6.6):

FS[1:0] [is] used to reduce the cost of context save and restore by setting and tracking the current state of the floating-point unit and any other user-mode extensions respectively.The FS field encodes the status of the floating-point unit state, including the floating-point registers f0–f31 and the CSRs fcsr, frm, and fflags.

If FS is 0, zero means "off", and the text above seems to apply to both f0-f31 and fcsr, frm, and fflags identically. What does it mean for the status of all of these registers to be identically "off"? If there is a fscr, but it's not saved/restored, how does that work?

@jordancarlin
Copy link
Contributor

There was a recent, somewhat related discussion on the tech-privileged mailing list: https://lists.riscv.org/g/tech-privileged/topic/smstateen_and_ssstateen/112508172.

If FS is 0, zero means "off", and the text above seems to apply to both f0-f31 and fcsr, frm, and fflags identically. What does it mean for the status of all of these registers to be identically "off"? If there is a fscr, but it's not saved/restored, how does that work?

My understanding of this all is that when (and only when) F is supported, mstatus.FS controls access to all state that is defined as part of the F extension. So when mstatus.FS is off, f0-f31, fcsr, frm, and fflags are all inaccessible and cause illegal instruction exceptions (or possibly other reserved behavior responses).

Zfinx is a completely separate extension with its own set of rules. There are no f0-f31 registers, and fcsr, frm, and fflags are always accessible. mstatus.FS essentially ceases to exist and is read-only zero. It no longer has any impact on whether the fcsr, frm, and fflags registers are "on" or "off".

When Smstateen is implemented in addition to Zfinx, there is yet another set of rules that governs this access. fcsr, frm, and fflags are only accessible when mstateen0.FCSR is one. When it is zero they are not accessible and will cause illegal instruction traps.

@dhower-qc
Copy link
Collaborator

we have a check_f_ok function used in IDL that checks (a) if F is implemented and (b) that CSR[mstatus].FS != 0. Otherwise, it raises an Illegal Instruction.

We need to call that from sw_read/sw_write, as so:

check_f_ok($encoding);

($encoding is the encoding of currently executing instruction, which is needed to report the exception data in mtval.)

@dhower-qc
Copy link
Collaborator

seems like we also need to update check_f_ok to account for the different checks with Z{f,d}inx.

@ThinkOpenly
Copy link
Collaborator

There was a recent, somewhat related discussion on the tech-privileged mailing list: https://lists.riscv.org/g/tech-privileged/topic/smstateen_and_ssstateen/112508172.

How timely! It's only missing a discussion about how "FS" fits in.

If FS is 0, zero means "off", and the text above seems to apply to both f0-f31 and fcsr, frm, and fflags identically. What does it mean for the status of all of these registers to be identically "off"? If there is a fscr, but it's not saved/restored, how does that work?

My understanding of this all is that when (and only when) F is supported, mstatus.FS controls access to all state that is defined as part of the F extension. So when mstatus.FS is off, f0-f31, fcsr, frm, and fflags are all inaccessible and cause illegal instruction exceptions (or possibly other reserved behavior responses).

OK

Zfinx is a completely separate extension with its own set of rules. There are no f0-f31 registers, and fcsr, frm, and fflags are always accessible.

Not explicitly stated, but OK.

mstatus.FS essentially ceases to exist and is read-only zero.

OK, not sure that zero was the best choice, but here we are.

It no longer has any impact on whether the fcsr, frm, and fflags registers are "on" or "off".

Important point there.

When Smstateen is implemented in addition to Zfinx, there is yet another set of rules that governs this access. fcsr, frm, and fflags are only accessible when mstateen0.FCSR is one. When it is zero they are not accessible and will cause illegal instruction traps.

Ack.

@dhower-qc
Copy link
Collaborator

I modified check_f_ok in #711

@neverlandiz
Copy link
Contributor Author

neverlandiz commented May 5, 2025

@dhower-qc The regression tests are running into a syntax error for this part (CSR[fcsr].NV `<< 4)

It doesn't seem to recognize the `<< operator?

@dhower-qc
Copy link
Collaborator

Sorry, just wait for #736 to come through.

@ThinkOpenly ThinkOpenly enabled auto-merge May 7, 2025 00:01
@ThinkOpenly ThinkOpenly requested a review from AFOliveira May 7, 2025 00:06
@ThinkOpenly ThinkOpenly added this pull request to the merge queue May 8, 2025
@AFOliveira
Copy link
Collaborator

I didn't notice I was the bottleneck for this PR until now. Great work @neverlandiz!

Merged via the queue into riscv-software-src:main with commit 00dbb73 May 8, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add remaining F CSRs
5 participants