Introduction
The floating-point registers are f0 to f31. One mnemonic is written for each format,
ending .s (single, F), .d (double, D), .h (half, Zfh) or .q
(quad, Q); the two-bit fmt field (bits 26:25) is 00, 01, 10, 11 for them. The rounding mode
rm (bits 14:12) is written after the last register when it is not dyn (7, use the
frm CSR): rne (0), rtz (1), rdn (2), rup (3), rmm (4). 5 and 6 are
reserved. A conversion that cannot round (single to double,
word to double) leaves out rne. Results flow into fflags; see the
CSR list. Narrower values held in a wider register are NaN-boxed.
Loads and stores
| Instruction | Opcode | funct3 | Extension |
|---|---|---|---|
flh, fsh | 0000111 / 0100111 | 001 | Zfhmin (Zfh) |
flw, fsw | 0000111 / 0100111 | 010 | F |
fld, fsd | 0000111 / 0100111 | 011 | D |
flq, fsq | 0000111 / 0100111 | 100 | Q |
Operands frd, imm(rs1) and frs2, imm(rs1). The other funct3 values of these two opcodes
are the vector loads and stores.
Fused multiply-add
| Instruction | Opcode | What it does |
|---|---|---|
fmadd.s/d/h/q | 1000011 | (rs1 × rs2) + rs3 |
fmsub.s/d/h/q | 1000111 | (rs1 × rs2) − rs3 |
fnmsub.s/d/h/q | 1001011 | −(rs1 × rs2) + rs3 |
fnmadd.s/d/h/q | 1001111 | −(rs1 × rs2) − rs3 |
R4 format: rs3 in bits 31:27, fmt in 26:25. Operands frd, frs1, frs2, frs3[, rm].
Arithmetic, conversion and comparison (opcode 1010011)
Bits 31:27 select the operation and 26:25 the format. rs2 or funct3 narrow it where noted.
| Instruction (each of .s .d .h .q) | Bits 31:27 | rs2 | funct3 | What it does |
|---|---|---|---|---|
fadd | 00000 | rs2 | rm | Add. |
fsub | 00001 | rs2 | rm | Subtract. |
fmul | 00010 | rs2 | rm | Multiply. |
fdiv | 00011 | rs2 | rm | Divide. |
fsqrt | 01011 | 00000 | rm | Square root. |
fsgnj, fsgnjn, fsgnjx | 00100 | rs2 | 000, 001, 010 | Take the sign from rs2, its negation, or the xor of both signs: moves, negation and absolute value. |
fmin, fmax | 00101 | rs2 | 000, 001 | Minimum and maximum. |
fcvt.s.d, fcvt.d.s and the other float-to-float conversions | 01000 | the source format (0 s, 1 d, 2 h, 3 q) | rm | The destination format is the fmt field. |
fle, flt, feq | 10100 | rs2 | 000, 001, 010 | Compare; the result (0 or 1) goes to an integer register. |
fclass | 11100 | 00000 | 001 | Ten-bit class mask into an integer register. |
fmv.x.w, fmv.x.d (rv64), fmv.x.h | 11100 | 00000 | 000 | Move the bits to an integer register. |
fcvt.w.*, fcvt.wu.*, fcvt.l.* (rv64), fcvt.lu.* (rv64) | 11000 | 0, 1, 2, 3 | rm | Float to signed or unsigned 32 or 64-bit integer. |
fcvt.*.w, fcvt.*.wu, fcvt.*.l (rv64), fcvt.*.lu (rv64) | 11010 | 0, 1, 2, 3 | rm | Integer to float. |
fmv.w.x, fmv.d.x (rv64), fmv.h.x | 11110 | 00000 | 000 | Move the bits from an integer register. |
The Zfh instructions (.h) are all of these, in format 10; Zfhmin is only flh,
fsh, fmv.x.h, fmv.h.x and the conversions to and from single (and double
and quad where present).
Zfa: additional instructions
| Instruction | Encoding | What it does |
|---|---|---|
fli.s/d/h/q | bits 31:27 11110, rs2 = 00001, funct3 000; the constant is the rs1 field | Loads one of 32 constants: −1.0, the smallest normal number (min), 2−16, 2−15, 2−8, 2−7, 0.0625, 0.125, 0.25, 0.3125, 0.375, 0.4375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 4.0, 8.0, 16.0, 128.0, 256.0, 215, 216, inf, nan. |
fminm, fmaxm | 00101, funct3 010, 011 | Minimum and maximum that return NaN if either operand is NaN. |
fround, froundnx | 01000, rs2 = 00100, 00101 | Round to an integral value (the second raises inexact). |
fcvtmod.w.d | 11000, fmt d, rs2 = 01000, rm rtz | Double to a 32-bit integer modulo 232, as JavaScript does it. |
fleq, fltq | 10100, funct3 100, 101 | Quiet comparisons. |
fmvh.x.d, fmvp.d.x (rv32) | 11100 rs2 = 1 / 10110 | Move the high word of a double / build a double from two integer registers. |
Zfbfmin adds fcvt.bf16.s and fcvt.s.bf16 (BFloat16).