12 “D” Standard Extension for Double-Precision Floating-Point, Version 2.2
This chapter describes the standard double-precision floating-point instruction-set extension, which is named “D” and adds double-precision floating-point computational instructions compliant with the IEEE 754-2008 arithmetic standard. The D extension depends on the base single-precision instruction subset F.
12.1 D Register State
The D extension widens the 32 floating-point registers,
f31, to 64 bits (FLEN=64 in Figure [fprs]). The
registers can now hold either 32-bit or 64-bit floating-point values
as described below in Section 1.2.
12.2 NaN Boxing of Narrower Values
When multiple floating-point precisions are supported, then valid
values of narrower n-bit types, n< FLEN , are represented in
the lower n bits of an FLEN-bit NaN value, in a process termed
NaN-boxing. The upper bits of a valid NaN-boxed value must be all 1s.
Valid NaN-boxed n-bit values therefore appear as negative quiet NaNs
(qNaNs) when viewed as any wider m-bit value, n < m≤
FLEN . Any operation that writes a narrower result to an
register must write all 1s to the uppermost FLEN − n bits to yield a
legal NaN-boxed value.
Floating-point n-bit transfer operations move external values held
in IEEE standard formats into and out of the
f registers, and
comprise floating-point loads and stores (FLn/FSn) and
floating-point move instructions (FMV.n.X/FMV.X.n). A narrower
n-bit transfer, n< FLEN , into the
f registers will create a
valid NaN-boxed value. A narrower n-bit transfer out of
the floating-point registers will transfer the lower n bits of the
register ignoring the upper FLEN − n bits.
Apart from transfer operations described in the previous paragraph, all other floating-point operations on narrower n-bit operations, n< FLEN , check if the input operands are correctly NaN-boxed, i.e., all upper FLEN − n bits are 1. If so, the n least-significant bits of the input are used as the input value, otherwise the input value is treated as an n-bit canonical NaN.
12.3 Double-Precision Load and Store Instructions
The FLD instruction loads a double-precision floating-point value from memory into floating-point register rd. FSD stores a double-precision value from the floating-point registers to memory.
FLD and FSD are only guaranteed to execute atomically if the effective address is naturally aligned and XLEN≥64.
FLD and FSD do not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved.
12.4 Double-Precision Floating-Point Computational Instructions
The double-precision floating-point computational instructions are defined analogously to their single-precision counterparts, but operate on double-precision operands and produce double-precision results.
12.5 Double-Precision Floating-Point Conversion and Move Instructions
Floating-point-to-integer and integer-to-floating-point conversion instructions are encoded in the OP-FP major opcode space. FCVT.W.D or FCVT.L.D converts a double-precision floating-point number in floating-point register rs1 to a signed 32-bit or 64-bit integer, respectively, in integer register rd. FCVT.D.W or FCVT.D.L converts a 32-bit or 64-bit signed integer, respectively, in integer register rs1 into a double-precision floating-point number in floating-point register rd. FCVT.WU.D, FCVT.LU.D, FCVT.D.WU, and FCVT.D.LU variants convert to or from unsigned integer values. For RV64, FCVT.W[U].D sign-extends the 32-bit result. FCVT.L[U].D and FCVT.D.L[U] are RV64-only instructions. The range of valid inputs for FCVT.int.D and the behavior for invalid inputs are the same as for FCVT.int.S.
All floating-point to integer and integer to floating-point conversion instructions round according to the rm field. Note FCVT.D.W[U] always produces an exact result and is unaffected by rounding mode.
The double-precision to single-precision and single-precision to double-precision conversion instructions, FCVT.S.D and FCVT.D.S, are encoded in the OP-FP major opcode space and both the source and destination are floating-point registers. The rs2 field encodes the datatype of the source, and the fmt field encodes the datatype of the destination. FCVT.S.D rounds according to the RM field; FCVT.D.S will never round.
Floating-point to floating-point sign-injection instructions, FSGNJ.D, FSGNJN.D, and FSGNJX.D are defined analogously to the single-precision sign-injection instruction.
For XLEN≥64 only, instructions are provided to move bit patterns between the floating-point and integer registers. FMV.X.D moves the double-precision value in floating-point register rs1 to a representation in IEEE 754-2008 standard encoding in integer register rd. FMV.D.X moves the double-precision value encoded in IEEE 754-2008 standard encoding from the integer register rs1 to the floating-point register rd.
FMV.X.D and FMV.D.X do not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved.
12.6 Double-Precision Floating-Point Compare Instructions
The double-precision floating-point compare instructions are defined analogously to their single-precision counterparts, but operate on double-precision operands.
12.7 Double-Precision Floating-Point Classify Instruction
The double-precision floating-point classify instruction, FCLASS.D, is defined analogously to its single-precision counterpart, but operates on double-precision operands.