FCVTX

Double-precision convert to single-precision, rounding to odd (predicated)

This instruction converts active double-precision elements from the source vector to single-precision, rounding to Odd, and places the results in the even-numbered 32-bit elements of the destination vector, while setting the odd-numbered elements to zero. Inactive elements in the destination vector register remain unmodified or are set to zero, depending on whether merging or zeroing predication is selected.

Rounding to Odd (aka Von Neumann rounding) permits a two-step conversion from double-precision to half-precision without incurring intermediate rounding errors.

It has encodings from 2 classes: Double-precision to single-precision, merging and Double-precision to single-precision, zeroing

Double-precision to single-precision, merging
(FEAT_SVE2 || FEAT_SME)

313029282726252423222120191817161514131211109876543210
0110010100001010101PgZnZd
opcopc2

Encoding

FCVTX <Zd>.S, <Pg>/M, <Zn>.D

Decode for this encoding

if !IsFeatureImplemented(FEAT_SVE2) && !IsFeatureImplemented(FEAT_SME) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 64; let g : integer = UInt(Pg); let n : integer = UInt(Zn); let d : integer = UInt(Zd); let s_esize : integer{} = 64; let d_esize : integer{} = 32; let merging : boolean = TRUE;

Double-precision to single-precision, zeroing
(FEAT_SVE2p2 || FEAT_SME2p2)

313029282726252423222120191817161514131211109876543210
0110010000011010110PgZnZd
opcopc2

Encoding

FCVTX <Zd>.S, <Pg>/Z, <Zn>.D

Decode for this encoding

if !IsFeatureImplemented(FEAT_SVE2p2) && !IsFeatureImplemented(FEAT_SME2p2) then EndOfDecode(Decode_UNDEF); end; let esize : integer{} = 64; let g : integer = UInt(Pg); let n : integer = UInt(Zn); let d : integer = UInt(Zd); let s_esize : integer{} = 64; let d_esize : integer{} = 32; let merging : boolean = FALSE;

Assembler Symbols

<Zd>

Is the name of the destination scalable vector register, encoded in the "Zd" field.

<Pg>

Is the name of the governing scalable predicate register P0-P7, encoded in the "Pg" field.

<Zn>

Is the name of the source scalable vector register, encoded in the "Zn" field.

Operation

CheckSVEEnabled(); let VL : integer{} = CurrentVL(); let PL : integer{} = VL DIV 8; let elements : integer = VL DIV esize; let mask : bits(PL) = P{}(g); let operand : bits(VL) = if AnyActiveElement{PL}(mask, esize) then Z{VL}(n) else Zeros{VL}; var result : bits(VL) = if merging then Z{VL}(d) else Zeros{VL}; for e = 0 to elements-1 do if ActivePredicateElement{PL}(mask, e, esize) then let element : bits(esize) = operand[e*:esize]; let res : bits(d_esize) = FPConvertSVE{d_esize, s_esize}(element[s_esize-1:0], FPCR(), FPRounding_ODD); result[e*:esize] = ZeroExtend{esize}(res); end; end; Z{VL}(d) = result;

Operational information

For the "Double-precision to single-precision, merging" variant:

The merging variant of this instruction might be immediately preceded in program order by a MOVPRFX instruction. The MOVPRFX must conform to all of the following requirements, otherwise the behavior of the MOVPRFX and the merging variant of this instruction is CONSTRAINED UNPREDICTABLE:


2026-03_rel 2026-03-26 20:48:11

Copyright © 2010-2026 Arm Limited or its affiliates. All rights reserved. This document is Non-Confidential.