Skip to content

feat: add Zfinx, Zdinx, Zhinxmin extensions, modify check_f_ok for them #711

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions arch/ext/Zdinx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# yaml-language-server: $schema=../../schemas/ext_schema.json

$schema: "ext_schema.json#"
kind: extension
name: Zdinx
long_name: Double-precision floating-point instructions using integer registers
description:
- id: ext-zdinx-instructions
normative: true
text: |
The Zdinx extension adds all of the instructions that the D extension adds, except for the
transfer instructions FLD, FSD, FMV.D.X, FMV.X.D, C.FLD[SP], and C.FSD[SP].
- id: ext-zdinx-semantics
normative: true
text: |
The Zdinx variants of these D-extension instructions have the same semantics, except that whenever
such an instruction would have accessed an f register, it instead accesses the x register with the
same number.
- id: ext-zdinx-rv32regpair
normative: true
text: |
Double-precision operands in RV32Zdinx are held in aligned x-register pairs, i.e., register
numbers must be even. Use of misaligned (odd-numbered) registers for double-width
floating-point operands is reserved.
when(): return MXLEN == 32;

- id: ext-zdinx-rv32endianness
normative: true
text: |
Regardless of endianness, the lower-numbered register holds the low-order bits, and the
higher-numbered register holds the high-order bits: e.g., bits 31:0 of a double-precision
operand in RV32Zdinx might be held in register x14, with bits 63:32 of that operand held
in x15.
when(): return MXLEN == 32;

- id: ext-zdinx-rv32x0
normative: true
text: |
When a double-width floating-point result is written to x0, the entire write takes no effect:
e.g., for RV32Zdinx, writing a double-precision result to x0 does not cause x1 to be written.
when(): return MXLEN == 32;

- id: ext-zdinx-rv32x1
normative: true
text: |
When x0 is used as a double-width floating-point operand, the entire operand is zero—i.e.,
x1 is not accessed.
when(): return MXLEN == 32;

- id: ext-zdinx-rv32mempair
normative: false
text: |
Load-pair and store-pair instructions are not provided, so transferring double-precision
operands in RV32Zdinx from or to memory requires two loads or stores.
Register moves need only a single FSGNJ.D instruction, however.
when(): return MXLEN == 32;

type: unprivileged
versions:
- version: "1.0.0"
state: ratified
ratification_date: 2021-11
requires: Zfinx
1 change: 1 addition & 0 deletions arch/ext/Zfh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ versions:
- version: "1.0.0"
state: ratified
ratification_date: null
requires: F
27 changes: 27 additions & 0 deletions arch/ext/Zfinx.yaml
Copy link
Collaborator

Choose a reason for hiding this comment

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

Parameterization for mstateen0.FCSR probably needs to be added here, similar to what's been done for HSTATEEN_ENVCFG_TYPE that's coming in #592.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# yaml-language-server: $schema=../../schemas/ext_schema.json

$schema: "ext_schema.json#"
kind: extension
name: Zfinx
long_name: Single-precision floating-point instructions using integer registers
description:
- id: ext-zfinx-instructions
normative: true
text: |
The Zfinx extension adds all of the instructions that the F extension adds, except for the
transfer instructions FLW, FSW, FMV.W.X, FMV.X.W, C.FLW[SP], and C.FSW[SP].
- id: ext-zfinx-semantics
normative: true
text: |
The Zfinx variants of these F-extension instructions have the same semantics, except that
whenever such an instruction would have accessed an f register, it instead accesses the
x register with the same number.
type: unprivileged
versions:
- version: "1.0.0"
state: ratified
ratification_date: 2021-11
requires: Zicsr
conflicts: F
22 changes: 14 additions & 8 deletions arch/ext/Zhinx.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ $schema: "ext_schema.json#"
kind: extension
name: Zhinx
long_name: Half-precision floating-point instructions using integer registers
description: |
The Zhinx extension provides analogous half-precision floating-point instructions. The Zhinx extension
depends upon the Zfinx extension.
The Zhinx extension adds all of the instructions that the Zfh extension adds, except for the transfer
instructions FLH, FSH, FMV.H.X, and FMV.X.H.
The Zhinx variants of these Zfh-extension instructions have the same semantics, except that whenever
such an instruction would have accessed an f register, it instead accesses the x register with the same
number.
description:
- id: ext-zhinx-instructions
normative: true
text: |
The Zhinx extension adds all of the instructions that the Zfh extension adds, except for the
transfer instructions FLH, FSH, FMV.H.X, and FMV.X.H.
- id: ext-zhinx-semantics
normative: true
text: |
The Zhinx variants of these Zfh-extension instructions have the same semantics, except that
whenever such an instruction would have accessed an f register, it instead accesses the x
register with the same number.
type: unprivileged
versions:
- version: "1.0.0"
state: ratified
ratification_date: 2021-11
requires: Zfinx
27 changes: 27 additions & 0 deletions arch/ext/Zhinxmin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# yaml-language-server: $schema=../../schemas/ext_schema.json

$schema: "ext_schema.json#"
kind: extension
name: Zhinxmin
long_name: Minimal support for half-precision floating-point instructions using integer registers
description:
- id: ext-zhinxmin-instructions
normative: true
text: |
The Zhinxmin extension includes the following instructions from the Zhinx extension:
FCVT.S.H and FCVT.H.S.
when(): return !implemented?(Zdinx);

- id: ext-zhinxmin-instructions-with-zdinx
normative: true
text: |
The Zhinxmin extension includes the following instructions from the Zhinx extension:
FCVT.S.H, FCVT.H.S, FCVT.D.H, and FCVT.H.D.
when(): return implemented?(Zdinx);

type: unprivileged
versions:
- version: "1.0.0"
state: ratified
ratification_date: 2021-11
requires: Zfinx
38 changes: 32 additions & 6 deletions arch/isa/fp.idl
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,42 @@ function check_f_ok {
arguments
Bits<INSTR_ENC_SIZE> encoding
description {
Checks if instructions from the `F` extension can be executed, and, if not,
Checks if instructions from a floating point extension can be executed, and, if not,
raise an exception.
}
body {
if (MUTABLE_MISA_F && CSR[misa].F == 0) {
raise(ExceptionCode::IllegalInstruction, mode(), encoding);
}
# All Z*inx extensions depend on Zfinx, so we only have to check if Zfinx is implemented
if (implemented?(ExtensionName::Zfinx)) {
# mstateen0.FCSR disables all modes
if (implemented?(ExtensionName::Smstateen) && (CSR[mstateen0].FCSR == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), enoding);
}

if (CSR[mstatus].FS == 0) {
raise(ExceptionCode::IllegalInstruction, mode(), encoding);
# sstateen0.FCSR disables all modes except M
if (implemented?(ExtensionName::Sstateen) &&
(mode() != PrivilegeMode::M) &&
(CSR[sstateen0].FCSR == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), enoding);
}

# hstateen0.FCSR disables VS and VU
if (implemented?(ExtensionName::Sstateen) &&
implemented?(ExtensionName::H) &&
(CSR[misa].H == 1) &&
virtual_mode?() &&
(CSR[hstateen0].FCSR == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), enoding);
}
} else if (implemented?(ExtensionName::F)) {
if (MUTABLE_MISA_F && CSR[misa].F == 0) {
raise(ExceptionCode::IllegalInstruction, mode(), encoding);
}

if (CSR[mstatus].FS == 0) {
raise(ExceptionCode::IllegalInstruction, mode(), encoding);
}
} else {
assert(false, "check_f_ok called when no FP extension is implemented");
}
}
}
Expand Down
Loading