Skip to content
This repository has been archived by the owner on Feb 15, 2024. It is now read-only.

Latest commit

 

History

History
230 lines (145 loc) · 7.87 KB

Zfinx_ISA_spec_addendum.adoc

File metadata and controls

230 lines (145 loc) · 7.87 KB

Zfinx ISA Specification Addendum

1. Addendum update history

version

change

0.10

initial version

2. Overview

This document gives additional information about Zfinx which is not included in the ISA specification.

3. Configurations

Each Z*inx extension is distinct and maps directly to an existing floating point extension. Once one floating point extension has been mapped to a Zfinx version then the F registers are not implemented so all must be mapped to a Zfinx version.

For example the Zfinx version of RV32IMCD_Zfh would be RV32IMC_Zdinx_Zhinx as D→Zdinx and Zfh→Zhinx.

RV32IMCD_Zhinx would not be legal.

4. Discovery

If any Zfinx extension is specified then the compiler will have the following #define set:

__riscv_zfinx

So software can use this to choose between Zfinx or normal versions of floating point code.

Non-privileged code can detect whether Zfinx is implemented as follows:

li a0, 0 # set a0 to zero

#ifdef __riscv_zfinx

fneg.s a0, a0 # this will invert a0

#else

fneg.s fa0, fa0 # this will invert fa0

#endif

If a0 is non-zero then it’s a Zfinx core, otherwise it’s a non-Zfinx core. Both branches result in the same encoding, but the assembly syntax is different for each variant.

5. Assembly Syntax and Code Porting

Any references to F registers, or removed instructions will cause assembler errors.

For example, the encoding for:

FMADD.S <1>, <2>, <3>, <4>

will disassemble and execute as:

FMADD.S f1, f2, f3, f4

on a non-Zfinx core, or:

FMADD.S x1, x2, x3, x4

on a Zfinx core.

We considered allowing pseudo-instructions for the deleted instructions for easier code porting. For example allowing FLW to be a pseudo-instruction for LW, but decided not to. Because the register specifiers must change to integer registers, it makes sense to also remove the use of FLW etc. In this way the user is forced to rewrite their code for a Zfinx core, reducing the chance of undiscovered porting bugs. This only affects assembly code, high level language code is unaffected as the compiler will target the correct architecture.

6. Modifications from extensions to the Zfinx versions

Because all floating point loads, stores and floating point to/from integer moves are removed on Zfinx cores, the following sections show the deleted instructions and give suggested replacements to get the same semantics.

Note
Where a floating point load loads fewer than XLEN bits software NaN-boxing in software is required to get the same semantics as a non-Zfinx core. This is specified for consistency but is unlikely to be necessary. The compiler should not NaN-box in software as there is no reason to do so. Assembly writers can choose whether to NaN-box in software to give better error detection.
Note
Where a floating point move moves fewer than XLEN bits then either sign extension (if the target is an X register) or NaN-boxing (if the target is an F register) is required in software to get the same semantics.

6.1. Modifications from F to Zfinx

The modifications to the ISA of the F extension are shown in Table 1.

Table 1. replacements for F extension floating point load/store/move instructions
Instruction RV32_Zfinx RV64_Zfinx

replacement to get the same semantics

FLW frd, offset(xrs1)

LW

LW[U] and NaN-box in software

C.FLW[SP] frd, uimm(x2)

C.LW[SP]

C.LW[SP] and NaN-box in software

FSW frd, offset(xrs1)

SW

SW

C.FSW[SP] frd, uimm(x2)

C.SW[SP]

C.SW[SP]

FMV.X.W xrd, frs1

MV

MV and sign extend in software

FMV.W.X frd, xrs1

MV

MV and NaN-box in software

6.2. Modifications from D to Zdinx

The modifications to the ISA of the D extension are shown in Table 2.

Table 2. replacements for D extension floating point load/store/move instructions
Instruction RV32_Zdinx RV64_Zdinx

replacement to get the same semantics

FLD frd, offset(xrs1)

LW,LW

LD

C.FLD[SP] frd, uimm(x2)

C.LW[SP], C.LW[SP]

C.LD[SP]

FSD frd, offset(xrs1)

SW,SW

SD

C.FSD frd, offset(xrs1)

C.SW,C.SW

C.SD

C.FSD[SP] frd, uimm(x2)

C.SW[SP],C.SW[SP]

C.SD[SP]

FMV.X.D xrd, frs1

FSGNJ.D xrd, xrs1, xrs1

MV

FMV.D.X frd, xrs1

FSGNJ.D xrd, xrs1, xrs1

MV

6.3. Modifications from Zfh to Zhinx

The modifications to the ISA of the Zfh extension are shown in Table 3, in addition to Table 1.

Table 3. replacements for D floating point load/store/move instructions
Instruction RV32_Zhinx RV64_Zhinx

replacement to get the same semantics

FLH frd, offset(xrs1)

LH[U] and NaN-box in software

FSH frd, offset(xrs1)

SH

FMV.X.H xrd, frs1

MV and sign extend in software

FMV.H.X frd, xrs1

MV and NaN-box in software

6.3.1. Use of the B-extension

The B-extension is useful for sign extending and NaN-boxing.

To sign-extend using the B-extension:

FMV.X.H rd, rs1

is replaced by:

SEXT.H rd, rs1

Without the B-extension two instructions are required: shift left 16 places, then arithmetic shift right 16 places.

NaN boxing in software is more involved, as the upper part of the register must be set to 1. The B-extension is also helpful in this case.

FMV.H.X a0, a1

is replaced by:

C.ADDI a2, zero, -1

PACK a0, a1, a2

7. Possible vector version of Zfinx

If the vector TG decide to specify a Zfinx version of the vector extension, the following instructions would be deleted, and the integer versions would be used instead:

Table 4. replacements for scalar floating point instructions
Instruction Integer version

vfmv.v.f

vmv.v.x

vfmv.f.s

vmv.x.s

vfmv.s.f

vmv.s.x

vfmerge.vfm

vmerge.vxm

Additionally, all instructions with funct3=OPFVF take the scalar floating point source from either a single or pair of X registers instead of a single F register.

8. GDB

When using GDB on a Zfinx core, GDB must report X registers instead of F registers when disassembling floating point opcodes. No other changes are required.

9. ABI

The Zfinx ABI is being defined by the pSABI TG.

10. Rationale, why implement Zfinx?

Zfinx allows small embedded cores to support floating point with:

  • Minimal area increase

    • RV32I_Zfinx saves 1/2 the register file state compared to RV32IF.

    • RV32E_Zfinx saves 2/3 the register file state compared to RV32EF.

  • Similar context switch time as an integer only core

    • there are no F registers to save/restore

  • Reduced code size by removing the floating point library

    • Implementing floating point purely in software can be an expensive choice as the floating point library can be large, and expensive in terms of ROM or flash storage.