Introduction
These instructions work on one floating-point value at a time. The values are held in
the 32 SIMD and floating-point registers, V0 to V31. Each register has a name for each
size: h0 is the low 16 bits, s0 the low 32 and
d0 the low 64.
- S registers hold single precision and D registers double precision.
- H registers hold half precision. Every H form on this page needs the FP16
extension, except
fcvt. - A write to a scalar register normally clears the rest of the V register. With FPCR.NEP set (the Alternate Floating-point Behaviour extension) some scalar instructions keep those bits instead.
The FPCR register controls the rounding mode, NaN handling and traps. The FPSR register collects the cumulative exception flags: Invalid Operation, Divide by Zero, Overflow, Underflow, Inexact and Input Denormal.
The Flags column shows the NZCV condition flags only, and only the compares and
fjcvtzs change them. FPSR is not shown. The vector forms of these
instructions are on the
Advanced SIMD page.
The instructions
Arithmetic
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fadd, fsub | fadd Sd, Sn, Sm | Adds; subtracts Sm from Sn. | – |
fmul, fdiv | fmul Sd, Sn, Sm | Multiplies; divides Sn by Sm. | – |
fnmul | fnmul Sd, Sn, Sm | Multiplies and negates: −(Sn × Sm). | – |
fabs | fabs Sd, Sn | Absolute value. | – |
fneg | fneg Sd, Sn | Negates. | – |
fsqrt | fsqrt Sd, Sn | Square root. | – |
fmax, fmin | fmax Sd, Sn, Sm | The larger or smaller value. With FPCR.AH clear, a NaN operand gives a NaN result. | – |
fmaxnm, fminnm | fmaxnm Sd, Sn, Sm | The larger or smaller value, following IEEE 754-2008 maxNum and minNum: if one operand is a quiet NaN and the other a number, the result is the number. | – |
Fused multiply-add
These round once, at the end. Sa is the fourth operand.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fmadd | fmadd Sd, Sn, Sm, Sa | Sa + Sn × Sm. | – |
fmsub | fmsub Sd, Sn, Sm, Sa | Sa − Sn × Sm. | – |
fnmadd | fnmadd Sd, Sn, Sm, Sa | −Sa − Sn × Sm. | – |
fnmsub | fnmsub Sd, Sn, Sm, Sa | −Sa + Sn × Sm. | – |
Compares and conditional select
A compare writes its result to NZCV. If the first operand is less than the second, NZCV is 1000; if equal, 0110; if greater, 0010; if either is a NaN (unordered), 0011.
There are two kinds of compare. A quiet compare
(fcmp, fccmp) raises Invalid Operation only for a signalling
NaN. A signalling compare (fcmpe, fccmpe)
raises it for any NaN, quiet or signalling. An unordered result sets the same
flags in both.
After a floating-point compare, the condition codes read as follows:
eq equal; ne not equal or unordered; mi and
cc less than; ls less than or equal; gt greater
than; ge greater than or equal; hi greater than or unordered;
pl and cs greater than, equal or unordered; lt
less than or unordered; le less than, equal or unordered;
vs unordered; vc ordered.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fcmp | fcmp Sn, Sm; fcmp Sn, #0.0 | Quiet compare of two registers, or of a register with zero. | NZCV |
fcmpe | fcmpe Sn, Sm; fcmpe Sn, #0.0 | Signalling compare. | NZCV |
fccmp | fccmp Sn, Sm, #nzcv, cond | Quiet conditional compare. If the condition holds, compares the registers; otherwise sets NZCV to the immediate, with no compare and no exception. | NZCV |
fccmpe | fccmpe Sn, Sm, #nzcv, cond | Signalling conditional compare. Otherwise the same as fccmp. | NZCV |
fcsel | fcsel Sd, Sn, Sm, cond | Sd = Sn if the condition holds, otherwise Sm. Reads NZCV and leaves it unchanged. | – |
Moves
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fmov | fmov Sd, Sn; fmov Sd, Wn; fmov Xd, Dn; fmov Vd.d[1], Xn; fmov Xd, Vn.d[1]; fmov Sd, #imm | Copies a value between floating-point registers, or copies the bits unconverted between a floating-point and a general-purpose register. The two forms with Vn.d[1] reach the top half of a V register. The immediate form takes values of the form ±n/16 × 2r, with n from 16 to 31 and r from −3 to 4. | – |
Precision conversion
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fcvt | fcvt Sd, Dn | Converts between any two of half, single and double precision, using the FPCR rounding mode. | – |
Floating point to integer
The destination is a W or X register, and the source H, S or D. An out-of-range
value saturates to the limit of the destination type, and a NaN gives 0; both raise
Invalid Operation. The final letter of the mnemonic says signed (s) or
unsigned (u), and the letter before it gives the rounding.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fcvtas, fcvtau | fcvtas Wd, Sn | Rounds to nearest, with ties away from zero. | – |
fcvtms, fcvtmu | fcvtms Wd, Sn | Rounds towards minus infinity. | – |
fcvtns, fcvtnu | fcvtns Wd, Sn | Rounds to nearest, with ties to even. | – |
fcvtps, fcvtpu | fcvtps Wd, Sn | Rounds towards plus infinity. | – |
fcvtzs, fcvtzu | fcvtzs Wd, Sn; fcvtzs Wd, Sn, #fbits | Rounds towards zero. The form with #fbits converts to fixed point with that many fraction bits (1 to 32 for W, 1 to 64 for X). | – |
fjcvtzs | fjcvtzs Wd, Dn | JavaScript conversion: rounds towards zero and, if the value does not fit, keeps the low 32 bits of the integer. D source and W destination only. Needs the JSCVT extension. | NZCV: Z set only when the conversion is exact; N, C and V cleared |
Integer to floating point
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
scvtf, ucvtf | scvtf Sd, Wn; scvtf Sd, Wn, #fbits | Converts a signed or unsigned integer in a W or X register, rounding as FPCR says. With #fbits the integer is read as fixed point with that many fraction bits. | – |
Rounding to an integral value
The result is still floating point, and the source and destination are the same size.
The frint32 and frint64 mnemonics have only S and D
forms.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
frinta | frinta Sd, Sn | Rounds to nearest, with ties away from zero. | – |
frintm | frintm Sd, Sn | Rounds towards minus infinity. | – |
frintn | frintn Sd, Sn | Rounds to nearest, with ties to even. | – |
frintp | frintp Sd, Sn | Rounds towards plus infinity. | – |
frintz | frintz Sd, Sn | Rounds towards zero. | – |
frinti | frinti Sd, Sn | Uses the FPCR rounding mode, and does not raise Inexact. | – |
frintx | frintx Sd, Sn | Uses the FPCR rounding mode, and raises Inexact when the value changes. | – |
frint32x, frint64x | frint32x Sd, Sn | Rounds to an integral value that fits a 32-bit or 64-bit integer, using the FPCR rounding mode. A NaN, an infinity or an out-of-range value gives the most negative integer of that size and raises Invalid Operation. Raises Inexact when the value changes. Needs the FRINTTS extension. | – |
frint32z, frint64z | frint32z Sd, Sn | The same, rounding towards zero. | – |
Links
Reference
- Arm A64 Instruction Set Architecture – Arm’s description of each A64 instruction
- Arm Architecture Reference Manual for A-profile – the full architecture specification