fmax

SVE Floating-Point Maximum

FMAX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T>

Determines maximum value of active float elements.

Details

SVE floating-point maximum operation that computes element-wise maximum of two scalable vectors under predicate control. For each active element in the predicate mask, the larger of the two floating-point values is written to the destination. Inactive elements (where the predicate is false) are left unchanged in the destination register. NZCV flags are not affected by this instruction.

Pseudocode Operation

for i = 0 to VL/element_size-1:
  if Pg[i] then
    Zdn[i] ← max(Zdn[i], Zm[i])
  else
    Zdn[i] ← Zdn[i]

Example

FMAX z0.s.T, p0/m/M, z0.s.T, z2.s.T

Encoding

Binary Layout
01100101
size
00
011
0
100
Pg
Zm
Zdn
 
Format SVE FP Binary
Opcode 0x65068000
Extension SVE

Operands

  • Zdn
    Combined destination/source scalable vector register (SVE)
  • Pg
    Mask
  • Zm
    Second source scalable vector register (SVE)

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x0E403400 FMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 0 | 01110 | 0 | 10 | Rm | 00 | 110 | 1 | Rn | Rd
0x0E20F400 FMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 0 | 01110 | 0 | sz | 1 | Rm | 11110 | 1 | Rn | Rd
0x1EE04800 FMAX <Hd>, <Hn>, <Hm> A64 0 | 0 | 0 | 11110 | 11 | 1 | Rm | 01 | 00 | 10 | Rn | Rd
0x1E204800 FMAX <Sd>, <Sn>, <Sm> A64 0 | 0 | 0 | 11110 | 00 | 1 | Rm | 01 | 00 | 10 | Rn | Rd
0x1E604800 FMAX <Dd>, <Dn>, <Dm> A64 0 | 0 | 0 | 11110 | 01 | 1 | Rm | 01 | 00 | 10 | Rn | Rd
0xC120A100 FMAX { <Zdn1>.<T>-<Zdn2>.<T> }, { <Zdn1>.<T>-<Zdn2>.<T> }, <Zm>.<T> A64 11000001 | size | 10 | Zm | 101000 | 0100 | 0 | Zdn | 0
0xC120A900 FMAX { <Zdn1>.<T>-<Zdn4>.<T> }, { <Zdn1>.<T>-<Zdn4>.<T> }, <Zm>.<T> A64 11000001 | size | 10 | Zm | 101010 | 0100 | 0 | Zdn | 0 | 0
0xC120B100 FMAX { <Zdn1>.<T>-<Zdn2>.<T> }, { <Zdn1>.<T>-<Zdn2>.<T> }, { <Zm1>.<T>-<Zm2>.<T> } A64 11000001 | size | 1 | Zm | 0101100 | 010 | 0 | 0 | Zdn | 0
0xC120B900 FMAX { <Zdn1>.<T>-<Zdn4>.<T> }, { <Zdn1>.<T>-<Zdn4>.<T> }, { <Zm1>.<T>-<Zm4>.<T> } A64 11000001 | size | 1 | Zm | 00101110 | 010 | 0 | 0 | Zdn | 0 | 0
0x651E8000 FMAX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <const> A64 01100101 | size | 011 | 11 | 0 | 100 | Pg | 0000 | i1 | Zdn
0x65068000 FMAX <Zdn>.<T>, <Pg>/M, <Zdn>.<T>, <Zm>.<T> A64 01100101 | size | 00 | 011 | 0 | 100 | Pg | Zm | Zdn

Description

Determine the maximum of active floating-point elements of the second source vector and corresponding floating-point elements of the first source vector and destructively place the results in the corresponding elements of the first source vector. When FPCR.AH is 0, the behavior is as follows: When FPCR.AH is 1, the behavior is as follows: Inactive elements in the destination vector register remain unmodified.

Operation

CheckSVEEnabled();
constant integer VL = CurrentVL;
constant integer PL = VL DIV 8;
constant integer elements = VL DIV esize;
bits(PL) mask = P[g, PL];
bits(VL) operand1 = Z[dn, VL];
bits(VL) operand2 = if AnyActiveElement(mask, esize) then Z[m, VL] else Zeros(VL);
bits(VL) result;

for e = 0 to elements-1
    bits(esize) element1 = Elem[operand1, e, esize];
    if ActivePredicateElement(mask, e, esize) then
        bits(esize) element2 = Elem[operand2, e, esize];
        Elem[result, e, esize] = FPMax(element1, element2, FPCR);
    else
        Elem[result, e, esize] = element1;

Z[dn, VL] = result;