# instructions

platform: ARM
mnem: LD1
description:
       Load multiple 1-element structures to one, two, three or four registers       (C7.3.152)


       No offset


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15         12 11 10 9       5 4     0
            0 Q 0 0 1 1 0 0 0 1 0 0 0 0 0 0 x x 1 x size                            Rn     Rt
                                       L                      opcode


       One register variant

       Applies when opcode = 0111.

       LD1 { <Vt>.<T> }, [<Xn|SP>]


       Two registers variant

       Applies when opcode = 1010.

       LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]


       Three registers variant

       Applies when opcode = 0110.

       LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]


       Four registers variant

       Applies when opcode = 0010.

       LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]


       Decode for all variants of this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = integer UNKNOWN;
         boolean wback = FALSE;


       Post-index


           31 30 29 28 27 26 25 24 23 22 21 20          16 15         12 11 10 9       5 4     0
            0 Q 0 0 1 1 0 0 1 1 0                 Rm         x x 1 x size           Rn     Rt
                                       L                      opcode


       One register, immediate offset variant

       Applies when Rm = 11111 && opcode = 0111.

       LD1 { <Vt>.<T> }, [<Xn|SP>], <imm>


       One register, register offset variant

       Applies when Rm != 11111 && opcode = 0111.

       LD1 { <Vt>.<T> }, [<Xn|SP>], <Xm>


       Two registers, immediate offset variant

       Applies when Rm = 11111 && opcode = 1010.
LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>


Two registers, register offset variant

Applies when Rm != 11111 && opcode = 1010.

LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>


Three registers, immediate offset variant

Applies when Rm = 11111 && opcode = 0110.

LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>


Three registers, register offset variant

Applies when Rm != 11111 && opcode = 0110.

LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>


Four registers, immediate offset variant

Applies when Rm = 11111 && opcode = 0010.

LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>


Four registers, register offset variant

Applies when Rm != 11111 && opcode = 0010.

LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 boolean wback = TRUE;


Assembler symbols

<Vt>          Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              1D          when size = 11, Q = 0

              2D          when size = 11, Q = 1

<Vt2>         Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

<Vt3>         Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

<Vt4>         Is the name of the fourth SIMD&FP register to be transferred, encoded as "Rt" plus 3 modulo 32.

<Xn|SP>       Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.
       <imm>             For the one register, immediate offset variant: is the post-index immediate offset, encoded in the "Q"
                         field. It can have the following values:

                         #8           when Q = 0

                         #16          when Q = 1

                         For the two registers, immediate offset variant: is the post-index immediate offset, encoded in the
                         "Q" field. It can have the following values:

                         #16          when Q = 0

                         #32          when Q = 1

                         For the three registers, immediate offset variant: is the post-index immediate offset, encoded in the
                         "Q" field. It can have the following values:

                         #24          when Q = 0

                         #48          when Q = 1

                         For the four registers, immediate offset variant: is the post-index immediate offset, encoded in the
                         "Q" field. It can have the following values:

                         #32          when Q = 0

                         #64          when Q = 1

       <Xm>              Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
                         field.


       Shared decode for all encodings

         MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
         integer datasize = if Q == '1' then 128 else 64;
         integer esize = 8 << UInt(size);
         integer elements = datasize DIV esize;

         integer rpt;       // number of iterations
         integer selem;     // structure elements

         case opcode of
              when '0000' rpt = 1; selem = 4;          // LD/ST4 (4 registers)
              when '0010' rpt = 4; selem = 1;          // LD/ST1 (4 registers)
              when '0100' rpt = 1; selem = 3;          // LD/ST3 (3 registers)
              when '0110' rpt = 3; selem = 1;          // LD/ST1 (3 registers)
              when '0111' rpt = 1; selem = 1;          // LD/ST1 (1 register)
              when '1000' rpt = 1; selem = 2;          // LD/ST2 (2 registers)
              when '1010' rpt = 2; selem = 1;          // LD/ST1 (2 registers)
              otherwise UnallocatedEncoding();

         // .1D format only permitted with LD1 & ST1
         if size:Q == '110' && selem != 1 then ReservedValue();


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();

         bits(64) address;
         bits(64) offs;
         bits(datasize) rval;
         integer e, r, s, tt;
         constant integer ebytes = esize DIV 8;

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         else
              address = X[n];
 offs = Zeros();
 for r = 0 to rpt-1
     for e = 0 to elements-1
         tt = (t + r) MOD 32;
         for s = 0 to selem-1
             rval = V[tt];
             if memop == MemOp_LOAD then
                 Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                 V[tt] = rval;
             else // memop == MemOp_STORE
                 Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
             offs = offs + ebytes;
             tt = (tt + 1) MOD 32;

 if wback then
     if m != 31 then
         offs = X[m];
     if n == 31 then
         SP[] = address + offs;
     else
         X[n] = address + offs;


platform: ARM
mnem: LD1R
description:
Load single 1-element structure and replicate to all lanes (of one register)       (C7.3.154)


No offset


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15        13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 size                                   Rn             Rt
                              L R                      opcode S


No offset variant

LD1R { <Vt>.<T> }, [<Xn|SP>]


Decode for this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = integer UNKNOWN;
 boolean wback = FALSE;


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20             16 15     13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 1 1 0                    Rm         1 1 0 0 size               Rn             Rt
                              L R                      opcode S


Immediate offset variant

Applies when Rm = 11111.

LD1R { <Vt>.<T> }, [<Xn|SP>], <imm>


Register offset variant

Applies when Rm != 11111.

LD1R { <Vt>.<T> }, [<Xn|SP>], <Xm>


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 boolean wback = TRUE;


Assembler symbols

<Vt>           Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

<T>            Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1
                         1D           when size = 11, Q = 0

                         2D           when size = 11, Q = 1

       <Xn|SP>           Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

       <imm>             Is the post-index immediate offset, encoded in the "size" field. It can have the following values:

                         #1           when size = 00

                         #2           when size = 01

                         #4           when size = 10

                         #8           when size = 11

       <Xm>              Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
                         field.


       Shared decode for all encodings

         integer scale = UInt(opcode<2:1>);
         integer selem = UInt(opcode<0>:R) + 1;
         boolean replicate = FALSE;
         integer index;

         case scale of
              when 3
                   // load and replicate
                   if L == '0' || S == '1' then UnallocatedEncoding();
                   scale = UInt(size);
                   replicate = TRUE;
              when 0
                   index = UInt(Q:S:size);            // B[0-15]
              when 1
                   if size<0> == '1' then UnallocatedEncoding();
                   index = UInt(Q:S:size<1>);         // H[0-7]
              when 2
                   if size<1> == '1' then UnallocatedEncoding();
                   if size<0> == '0' then
                       index = UInt(Q:S);             // S[0-3]
                   else
                       if S == '1' then UnallocatedEncoding();
                       index = UInt(Q);               // D[0-1]
                       scale = 3;

         MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
         integer datasize = if Q == '1' then 128 else 64;
         integer esize = 8 << scale;


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();

         bits(64) address;
         bits(64) offs;
         bits(128) rval;
         bits(esize) element;
         integer s;
         constant integer ebytes = esize DIV 8;

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         else
              address = X[n];

         offs = Zeros();
 if replicate then
    // load and replicate to all elements
    for s = 0 to selem-1
        element = Mem[address + offs, ebytes, AccType_VEC];
        // replicate to fill 128- or 64-bit register
         V[t] = Replicate(element, datasize DIV esize);
        offs = offs + ebytes;
        t = (t + 1) MOD 32;
 else
    // load/store one element per register
    for s = 0 to selem-1
        rval = V[t];
        if memop == MemOp_LOAD then
            // insert into one lane of 128-bit register
             Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];
             V[t] = rval;
        else // memop == MemOp_STORE
            // extract from one lane of 128-bit register
             Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];
        offs = offs + ebytes;
        t = (t + 1) MOD 32;

 if wback then
    if m != 31 then
        offs = X[m];
    if n == 31 then
         SP[] = address + offs;
    else
         X[n] = address + offs;


platform: ARM
mnem: LD2
description:
       Load multiple 2-element structures to two registers       (C7.3.155)


       No offset


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15           12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 size                                 Rn              Rt
                                        L                       opcode


       No offset variant

       LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]


       Decode for this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = integer UNKNOWN;
         boolean wback = FALSE;


       Post-index


           31 30 29 28 27 26 25 24 23 22 21 20              16 15       12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 1 1 0                    Rm        1 0 0 0 size              Rn              Rt
                                        L                       opcode


       Immediate offset variant

       Applies when Rm = 11111.

       LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>


       Register offset variant

       Applies when Rm != 11111.

       LD2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>


       Decode for all variants of this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         boolean wback = TRUE;


       Assembler symbols

       <Vt>              Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1
              2D           when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vt2>         Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

<Xn|SP>       Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

<imm>         Is the post-index immediate offset, encoded in the "Q" field. It can have the following values:

              #16          when Q = 0

              #32          when Q = 1

<Xm>          Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
              field.


Shared decode for all encodings

 MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
 integer datasize = if Q == '1' then 128 else 64;
 integer esize = 8 << UInt(size);
 integer elements = datasize DIV esize;

 integer rpt;    // number of iterations
 integer selem;  // structure elements

 case opcode of
    when '0000' rpt = 1; selem = 4;        // LD/ST4 (4 registers)
    when '0010' rpt = 4; selem = 1;        // LD/ST1 (4 registers)
    when '0100' rpt = 1; selem = 3;        // LD/ST3 (3 registers)
    when '0110' rpt = 3; selem = 1;        // LD/ST1 (3 registers)
    when '0111' rpt = 1; selem = 1;        // LD/ST1 (1 register)
    when '1000' rpt = 1; selem = 2;        // LD/ST2 (2 registers)
    when '1010' rpt = 2; selem = 1;        // LD/ST1 (2 registers)
    otherwise UnallocatedEncoding();

 // .1D format only permitted with LD1 & ST1
 if size:Q == '110' && selem != 1 then ReservedValue();


Operation for all encodings

 CheckFPAdvSIMDEnabled64();

 bits(64) address;
 bits(64) offs;
 bits(datasize) rval;
 integer e, r, s, tt;
 constant integer ebytes = esize DIV 8;

 if n == 31 then
     CheckSPAlignment();
    address = SP[];
 else
    address = X[n];

 offs = Zeros();
 for r = 0 to rpt-1
     for e = 0 to elements-1
         tt = (t + r) MOD 32;
         for s = 0 to selem-1
             rval = V[tt];
             if memop == MemOp_LOAD then
                 Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                 V[tt] = rval;
             else // memop == MemOp_STORE
                 Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
             offs = offs + ebytes;
                       tt = (tt + 1) MOD 32;

         if wback then
              if m != 31 then
                   offs = X[m];
              if n == 31 then
                   SP[] = address + offs;
              else
                   X[n] = address + offs;


platform: ARM
mnem: LD2R
description:
Load single 2-element structure and replicate to all lanes of two registers       (C7.3.157)


No offset


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15        13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 0 1 1 0 0 0 0 0 1 1 0 0 size                                   Rn             Rt
                              L R                      opcode S


No offset variant

LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]


Decode for this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = integer UNKNOWN;
 boolean wback = FALSE;


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20             16 15     13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 1 1 1                    Rm         1 1 0 0 size               Rn             Rt
                              L R                      opcode S


Immediate offset variant

Applies when Rm = 11111.

LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>


Register offset variant

Applies when Rm != 11111.

LD2R { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 boolean wback = TRUE;


Assembler symbols

<Vt>           Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

<T>            Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1
                         1D           when size = 11, Q = 0

                         2D           when size = 11, Q = 1

       <Vt2>             Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

       <Xn|SP>           Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

       <imm>             Is the post-index immediate offset, encoded in the "size" field. It can have the following values:

                         #2           when size = 00

                         #4           when size = 01

                         #8           when size = 10

                         #16          when size = 11

       <Xm>              Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
                         field.


       Shared decode for all encodings

         integer scale = UInt(opcode<2:1>);
         integer selem = UInt(opcode<0>:R) + 1;
         boolean replicate = FALSE;
         integer index;

         case scale of
              when 3
                   // load and replicate
                   if L == '0' || S == '1' then UnallocatedEncoding();
                   scale = UInt(size);
                   replicate = TRUE;
              when 0
                   index = UInt(Q:S:size);            // B[0-15]
              when 1
                   if size<0> == '1' then UnallocatedEncoding();
                   index = UInt(Q:S:size<1>);         // H[0-7]
              when 2
                   if size<1> == '1' then UnallocatedEncoding();
                   if size<0> == '0' then
                       index = UInt(Q:S);             // S[0-3]
                   else
                       if S == '1' then UnallocatedEncoding();
                       index = UInt(Q);               // D[0-1]
                       scale = 3;

         MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
         integer datasize = if Q == '1' then 128 else 64;
         integer esize = 8 << scale;


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();

         bits(64) address;
         bits(64) offs;
         bits(128) rval;
         bits(esize) element;
         integer s;
         constant integer ebytes = esize DIV 8;

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         else
              address = X[n];

 offs = Zeros();
 if replicate then
    // load and replicate to all elements
    for s = 0 to selem-1
        element = Mem[address + offs, ebytes, AccType_VEC];
        // replicate to fill 128- or 64-bit register
         V[t] = Replicate(element, datasize DIV esize);
        offs = offs + ebytes;
        t = (t + 1) MOD 32;
 else
    // load/store one element per register
    for s = 0 to selem-1
        rval = V[t];
        if memop == MemOp_LOAD then
            // insert into one lane of 128-bit register
             Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];
             V[t] = rval;
        else // memop == MemOp_STORE
            // extract from one lane of 128-bit register
             Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];
        offs = offs + ebytes;
        t = (t + 1) MOD 32;

 if wback then
    if m != 31 then
        offs = X[m];
    if n == 31 then
         SP[] = address + offs;
    else
         X[n] = address + offs;


platform: ARM
mnem: LD3
description:
       Load multiple 3-element structures to three registers       (C7.3.158)


       No offset


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15           12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 size                                 Rn              Rt
                                        L                       opcode


       No offset variant

       LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]


       Decode for this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = integer UNKNOWN;
         boolean wback = FALSE;


       Post-index


           31 30 29 28 27 26 25 24 23 22 21 20              16 15       12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 1 1 0                    Rm        0 1 0 0 size              Rn              Rt
                                        L                       opcode


       Immediate offset variant

       Applies when Rm = 11111.

       LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>


       Register offset variant

       Applies when Rm != 11111.

       LD3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>


       Decode for all variants of this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         boolean wback = TRUE;


       Assembler symbols

       <Vt>              Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1
              2D           when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vt2>         Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

<Vt3>         Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

<Xn|SP>       Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

<imm>         Is the post-index immediate offset, encoded in the "Q" field. It can have the following values:

              #24          when Q = 0

              #48          when Q = 1

<Xm>          Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
              field.


Shared decode for all encodings

 MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
 integer datasize = if Q == '1' then 128 else 64;
 integer esize = 8 << UInt(size);
 integer elements = datasize DIV esize;

 integer rpt;    // number of iterations
 integer selem;  // structure elements

 case opcode of
    when '0000' rpt = 1; selem = 4;        // LD/ST4 (4 registers)
    when '0010' rpt = 4; selem = 1;        // LD/ST1 (4 registers)
    when '0100' rpt = 1; selem = 3;        // LD/ST3 (3 registers)
    when '0110' rpt = 3; selem = 1;        // LD/ST1 (3 registers)
    when '0111' rpt = 1; selem = 1;        // LD/ST1 (1 register)
    when '1000' rpt = 1; selem = 2;        // LD/ST2 (2 registers)
    when '1010' rpt = 2; selem = 1;        // LD/ST1 (2 registers)
    otherwise UnallocatedEncoding();

 // .1D format only permitted with LD1 & ST1
 if size:Q == '110' && selem != 1 then ReservedValue();


Operation for all encodings

 CheckFPAdvSIMDEnabled64();

 bits(64) address;
 bits(64) offs;
 bits(datasize) rval;
 integer e, r, s, tt;
 constant integer ebytes = esize DIV 8;

 if n == 31 then
     CheckSPAlignment();
    address = SP[];
 else
    address = X[n];

 offs = Zeros();
 for r = 0 to rpt-1
     for e = 0 to elements-1
         tt = (t + r) MOD 32;
         for s = 0 to selem-1
             rval = V[tt];
             if memop == MemOp_LOAD then
                 Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                 V[tt] = rval;
             else // memop == MemOp_STORE
                           Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
                       offs = offs + ebytes;
                       tt = (tt + 1) MOD 32;

         if wback then
              if m != 31 then
                   offs = X[m];
              if n == 31 then
                   SP[] = address + offs;
              else
                   X[n] = address + offs;


platform: ARM
mnem: LD3R
description:
Load single 3-element structure and replicate to all lanes of three registers       (C7.3.160)


No offset


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15        13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 0 1 0 0 0 0 0 0 1 1 1 0 size                                   Rn             Rt
                              L R                      opcode S


No offset variant

LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]


Decode for this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = integer UNKNOWN;
 boolean wback = FALSE;


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20             16 15     13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 1 1 0                    Rm         1 1 1 0 size               Rn             Rt
                              L R                      opcode S


Immediate offset variant

Applies when Rm = 11111.

LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>


Register offset variant

Applies when Rm != 11111.

LD3R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 boolean wback = TRUE;


Assembler symbols

<Vt>           Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

<T>            Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1
                         1D           when size = 11, Q = 0

                         2D           when size = 11, Q = 1

       <Vt2>             Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

       <Vt3>             Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

       <Xn|SP>           Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

       <imm>             Is the post-index immediate offset, encoded in the "size" field. It can have the following values:

                         #3           when size = 00

                         #6           when size = 01

                         #12          when size = 10

                         #24          when size = 11

       <Xm>              Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
                         field.


       Shared decode for all encodings

         integer scale = UInt(opcode<2:1>);
         integer selem = UInt(opcode<0>:R) + 1;
         boolean replicate = FALSE;
         integer index;

         case scale of
              when 3
                   // load and replicate
                   if L == '0' || S == '1' then UnallocatedEncoding();
                   scale = UInt(size);
                   replicate = TRUE;
              when 0
                   index = UInt(Q:S:size);            // B[0-15]
              when 1
                   if size<0> == '1' then UnallocatedEncoding();
                   index = UInt(Q:S:size<1>);         // H[0-7]
              when 2
                   if size<1> == '1' then UnallocatedEncoding();
                   if size<0> == '0' then
                       index = UInt(Q:S);             // S[0-3]
                   else
                       if S == '1' then UnallocatedEncoding();
                       index = UInt(Q);               // D[0-1]
                       scale = 3;

         MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
         integer datasize = if Q == '1' then 128 else 64;
         integer esize = 8 << scale;


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();

         bits(64) address;
         bits(64) offs;
         bits(128) rval;
         bits(esize) element;
         integer s;
         constant integer ebytes = esize DIV 8;

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
 else
    address = X[n];

 offs = Zeros();
 if replicate then
    // load and replicate to all elements
    for s = 0 to selem-1
        element = Mem[address + offs, ebytes, AccType_VEC];
        // replicate to fill 128- or 64-bit register
         V[t] = Replicate(element, datasize DIV esize);
        offs = offs + ebytes;
        t = (t + 1) MOD 32;
 else
    // load/store one element per register
    for s = 0 to selem-1
        rval = V[t];
        if memop == MemOp_LOAD then
            // insert into one lane of 128-bit register
             Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];
             V[t] = rval;
        else // memop == MemOp_STORE
            // extract from one lane of 128-bit register
             Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];
        offs = offs + ebytes;
        t = (t + 1) MOD 32;

 if wback then
    if m != 31 then
        offs = X[m];
    if n == 31 then
         SP[] = address + offs;
    else
         X[n] = address + offs;


platform: ARM
mnem: LD4
description:
       Load multiple 4-element structures to four registers       (C7.3.161)


       No offset


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15           12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 size                                 Rn              Rt
                                        L                       opcode


       No offset variant

       LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]


       Decode for this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = integer UNKNOWN;
         boolean wback = FALSE;


       Post-index


           31 30 29 28 27 26 25 24 23 22 21 20              16 15       12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 1 1 0                    Rm        0 0 0 0 size              Rn              Rt
                                        L                       opcode


       Immediate offset variant

       Applies when Rm = 11111.

       LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>


       Register offset variant

       Applies when Rm != 11111.

       LD4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>


       Decode for all variants of this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         boolean wback = TRUE;


       Assembler symbols

       <Vt>              Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1
              2D           when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vt2>         Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

<Vt3>         Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

<Vt4>         Is the name of the fourth SIMD&FP register to be transferred, encoded as "Rt" plus 3 modulo 32.

<Xn|SP>       Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

<imm>         Is the post-index immediate offset, encoded in the "Q" field. It can have the following values:

              #32          when Q = 0

              #64          when Q = 1

<Xm>          Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
              field.


Shared decode for all encodings

 MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
 integer datasize = if Q == '1' then 128 else 64;
 integer esize = 8 << UInt(size);
 integer elements = datasize DIV esize;

 integer rpt;    // number of iterations
 integer selem;  // structure elements

 case opcode of
    when '0000' rpt = 1; selem = 4;        // LD/ST4 (4 registers)
    when '0010' rpt = 4; selem = 1;        // LD/ST1 (4 registers)
    when '0100' rpt = 1; selem = 3;        // LD/ST3 (3 registers)
    when '0110' rpt = 3; selem = 1;        // LD/ST1 (3 registers)
    when '0111' rpt = 1; selem = 1;        // LD/ST1 (1 register)
    when '1000' rpt = 1; selem = 2;        // LD/ST2 (2 registers)
    when '1010' rpt = 2; selem = 1;        // LD/ST1 (2 registers)
    otherwise UnallocatedEncoding();

 // .1D format only permitted with LD1 & ST1
 if size:Q == '110' && selem != 1 then ReservedValue();


Operation for all encodings

 CheckFPAdvSIMDEnabled64();

 bits(64) address;
 bits(64) offs;
 bits(datasize) rval;
 integer e, r, s, tt;
 constant integer ebytes = esize DIV 8;

 if n == 31 then
     CheckSPAlignment();
    address = SP[];
 else
    address = X[n];

 offs = Zeros();
 for r = 0 to rpt-1
     for e = 0 to elements-1
         tt = (t + r) MOD 32;
         for s = 0 to selem-1
             rval = V[tt];
             if memop == MemOp_LOAD then
                 Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                           V[tt] = rval;
                       else // memop == MemOp_STORE
                           Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
                       offs = offs + ebytes;
                       tt = (tt + 1) MOD 32;

         if wback then
              if m != 31 then
                   offs = X[m];
              if n == 31 then
                   SP[] = address + offs;
              else
                   X[n] = address + offs;


platform: ARM
mnem: LD4R
description:
Load single 4-element structure and replicate to all lanes of four registers       (C7.3.163)


No offset


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15        13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 0 1 1 0 0 0 0 0 1 1 1 0 size                                   Rn             Rt
                              L R                      opcode S


No offset variant

LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]


Decode for this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = integer UNKNOWN;
 boolean wback = FALSE;


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20             16 15     13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 0 1 1 1 1                    Rm         1 1 1 0 size               Rn             Rt
                              L R                      opcode S


Immediate offset variant

Applies when Rm = 11111.

LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>


Register offset variant

Applies when Rm != 11111.

LD4R { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 boolean wback = TRUE;


Assembler symbols

<Vt>           Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

<T>            Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1
                         1D           when size = 11, Q = 0

                         2D           when size = 11, Q = 1

       <Vt2>             Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

       <Vt3>             Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

       <Vt4>             Is the name of the fourth SIMD&FP register to be transferred, encoded as "Rt" plus 3 modulo 32.

       <Xn|SP>           Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

       <imm>             Is the post-index immediate offset, encoded in the "size" field. It can have the following values:

                         #4           when size = 00

                         #8           when size = 01

                         #16          when size = 10

                         #32          when size = 11

       <Xm>              Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
                         field.


       Shared decode for all encodings

         integer scale = UInt(opcode<2:1>);
         integer selem = UInt(opcode<0>:R) + 1;
         boolean replicate = FALSE;
         integer index;

         case scale of
              when 3
                   // load and replicate
                   if L == '0' || S == '1' then UnallocatedEncoding();
                   scale = UInt(size);
                   replicate = TRUE;
              when 0
                   index = UInt(Q:S:size);            // B[0-15]
              when 1
                   if size<0> == '1' then UnallocatedEncoding();
                   index = UInt(Q:S:size<1>);         // H[0-7]
              when 2
                   if size<1> == '1' then UnallocatedEncoding();
                   if size<0> == '0' then
                       index = UInt(Q:S);             // S[0-3]
                   else
                       if S == '1' then UnallocatedEncoding();
                       index = UInt(Q);               // D[0-1]
                       scale = 3;

         MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
         integer datasize = if Q == '1' then 128 else 64;
         integer esize = 8 << scale;


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();

         bits(64) address;
         bits(64) offs;
         bits(128) rval;
         bits(esize) element;
         integer s;
         constant integer ebytes = esize DIV 8;

         if n == 31 then
              CheckSPAlignment();
    address = SP[];
 else
    address = X[n];

 offs = Zeros();
 if replicate then
    // load and replicate to all elements
    for s = 0 to selem-1
        element = Mem[address + offs, ebytes, AccType_VEC];
        // replicate to fill 128- or 64-bit register
         V[t] = Replicate(element, datasize DIV esize);
        offs = offs + ebytes;
        t = (t + 1) MOD 32;
 else
    // load/store one element per register
    for s = 0 to selem-1
        rval = V[t];
        if memop == MemOp_LOAD then
            // insert into one lane of 128-bit register
             Elem[rval, index, esize] = Mem[address + offs, ebytes, AccType_VEC];
             V[t] = rval;
        else // memop == MemOp_STORE
            // extract from one lane of 128-bit register
             Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, index, esize];
        offs = offs + ebytes;
        t = (t + 1) MOD 32;

 if wback then
    if m != 31 then
        offs = X[m];
    if n == 31 then
         SP[] = address + offs;
    else
         X[n] = address + offs;


platform: ARM
mnem: MLA
description:
       Multiply-add to accumulator (vector, by element)       (C7.3.170)




           31 30 29 28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11 10 9               5 4             0
            0 Q 1 0 1 1 1 1 size L M                  Rm       0 0 0 0 H 0               Rn              Rd
                                                                 o2


       Vector variant

       MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);       Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         boolean sub_op = (o2 == '1');


       Assembler symbols

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01

                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         Restricted to V0-V15 when element size <Ts> is H.
<Ts>          Is an element size specifier, encoded in the "size" field. It can have the following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       Is the element index encoded in the "size:L:H:M" field. It can have the following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(idxdsize) operand2 = V[m];
 bits(datasize) operand3 = V[d];
 bits(datasize) result;
 integer element1;
 integer element2;
 bits(esize) product;

 element2 = UInt(Elem[operand2, index, esize]);
 for e = 0 to elements-1
     element1 = UInt(Elem[operand1, e, esize]);
     product = (element1 * element2)<esize-1:0>;
     if sub_op then
         Elem[result, e, esize] = Elem[operand3, e, esize] - product;
     else
         Elem[result, e, esize] = Elem[operand3, e, esize] + product;
 V[d] = result;


platform: ARM
mnem: MLS
description:
       Multiply-subtract from accumulator (vector, by element)       (C7.3.172)




           31 30 29 28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11 10 9               5 4             0
            0 Q 1 0 1 1 1 1 size L M                  Rm       0 1 0 0 H 0               Rn              Rd
                                                                 o2


       Vector variant

       MLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);       Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         boolean sub_op = (o2 == '1');


       Assembler symbols

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01

                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         Restricted to V0-V15 when element size <Ts> is H.
<Ts>          Is an element size specifier, encoded in the "size" field. It can have the following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       Is the element index encoded in the "size:L:H:M" field. It can have the following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(idxdsize) operand2 = V[m];
 bits(datasize) operand3 = V[d];
 bits(datasize) result;
 integer element1;
 integer element2;
 bits(esize) product;

 element2 = UInt(Elem[operand2, index, esize]);
 for e = 0 to elements-1
     element1 = UInt(Elem[operand1, e, esize]);
     product = (element1 * element2)<esize-1:0>;
     if sub_op then
         Elem[result, e, esize] = Elem[operand3, e, esize] - product;
     else
         Elem[result, e, esize] = Elem[operand3, e, esize] + product;
 V[d] = result;


platform: ARM
mnem: MOVI
description:
Move immediate (vector)       (C7.3.179)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15       12 11 10 9 8 7 6 5 4                   0
  0 Q op 0 1 1 1 1 0 0 0 0 0 a b c                  cmode       0 1 d e f g h               Rd




8-bit variant

Applies when op = 0 && cmode = 1110.

MOVI <Vd>.<T>, #<imm8>{, LSL #0}


16-bit shifted immediate variant

Applies when op = 0 && cmode = 10x0.

MOVI <Vd>.<T>, #<imm8>{, LSL #<amount>}


32-bit shifted immediate variant

Applies when op = 0 && cmode = 0xx0.

MOVI <Vd>.<T>, #<imm8>{, LSL #<amount>}


32-bit shifting ones variant

Applies when op = 0 && cmode = 110x.

MOVI <Vd>.<T>, #<imm8>, MSL #<amount>


64-bit scalar variant

Applies when Q = 0 && op = 1 && cmode = 1110.

MOVI <Dd>, #<imm>


64-bit vector variant

Applies when Q = 1 && op = 1 && cmode = 1110.

MOVI <Vd>.2D, #<imm>


Decode for all variants of this encoding

 integer rd = UInt(Rd);

 integer datasize = if Q == '1' then 128 else 64;
 bits(datasize) imm;
 bits(64) imm64;

 ImmediateOp operation;
 case cmode:op of
     when '0xx00' operation = ImmediateOp_MOVI;
     when '0xx01' operation = ImmediateOp_MVNI;
     when '0xx10' operation = ImmediateOp_ORR;
     when '0xx11' operation = ImmediateOp_BIC;
     when '10x00' operation = ImmediateOp_MOVI;
     when '10x01' operation = ImmediateOp_MVNI;
     when '10x10' operation = ImmediateOp_ORR;
     when '10x11' operation = ImmediateOp_BIC;
     when '110x0' operation = ImmediateOp_MOVI;
              when '110x1' operation = ImmediateOp_MVNI;
              when '1110x' operation = ImmediateOp_MOVI;
              when '11110' operation = ImmediateOp_MOVI;
              when '11111'
                   // FMOV Dn,#imm is in main FP instruction set
                   if Q == '0' then UnallocatedEncoding();
                   operation = ImmediateOp_MOVI;

         imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h);
         imm = Replicate(imm64, datasize DIV 64);


       Assembler symbols

       <Dd>              Is the 64-bit name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <imm>             Is a 64-bit immediate 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
                         encoded in "a:b:c:d:e:f:g:h".

       <T>               For the 8-bit variant: is an arrangement specifier, encoded in the "Q" field. It can have the following
                         values:

                         8B           when Q = 0

                         16B          when Q = 1

                         For the 16-bit variant: is an arrangement specifier, encoded in the "Q" field. It can have the
                         following values:

                         4H           when Q = 0

                         8H           when Q = 1

                         For the 32-bit variant: is an arrangement specifier, encoded in the "Q" field. It can have the
                         following values:

                         2S           when Q = 0

                         4S           when Q = 1

       <imm8>            Is an 8-bit immediate encoded in "a:b:c:d:e:f:g:h".

       <amount>          For the 16-bit shifted immediate variant: is the shift amount encoded in the "cmode<1>" field. It can
                         have the following values:

                         0            when cmode<1> = 0

                         8            when cmode<1> = 1

                         defaulting to 0 if LSL is omitted.

                         For the 32-bit shifted immediate variant: is the shift amount encoded in the "cmode<2:1>" field. It
                         can have the following values:

                         0            when cmode<2:1> = 00

                         8            when cmode<2:1> = 01

                         16           when cmode<2:1> = 10

                         24           when cmode<2:1> = 11

                         defaulting to 0 if LSL is omitted.

                         For the 32-bit shifting ones variant: is the shift amount encoded in the "cmode<0>" field. It can have
                         the following values:

                         8            when cmode<0> = 0

                         16           when cmode<0> = 1
Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand;
 bits(datasize) result;

 case operation of
    when ImmediateOp_MOVI
         result = imm;
    when ImmediateOp_MVNI
         result = NOT(imm);
    when ImmediateOp_ORR
         operand = V[rd];
         result = operand OR imm;
    when ImmediateOp_BIC
        operand = V[rd];
        result = operand AND NOT(imm);

 V[rd] = result;


platform: ARM
mnem: MVNI
description:
Move inverted immediate (vector)       (C7.3.183)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15       12 11 10 9 8 7 6 5 4                   0
  0 Q 1 0 1 1 1 1 0 0 0 0 0 a b c                    cmode      0 1 d e f g h               Rd
        op


16-bit shifted immediate variant

Applies when cmode = 10x0.

MVNI <Vd>.<T>, #<imm8>{, LSL #<amount>}


32-bit shifted immediate variant

Applies when cmode = 0xx0.

MVNI <Vd>.<T>, #<imm8>{, LSL #<amount>}


32-bit shifting ones variant

Applies when cmode = 110x.

MVNI <Vd>.<T>, #<imm8>, MSL #<amount>


Decode for all variants of this encoding

 integer rd = UInt(Rd);

 integer datasize = if Q == '1' then 128 else 64;
 bits(datasize) imm;
 bits(64) imm64;

 ImmediateOp operation;
 case cmode:op of
     when '0xx00' operation = ImmediateOp_MOVI;
     when '0xx01' operation = ImmediateOp_MVNI;
     when '0xx10' operation = ImmediateOp_ORR;
     when '0xx11' operation = ImmediateOp_BIC;
     when '10x00' operation = ImmediateOp_MOVI;
     when '10x01' operation = ImmediateOp_MVNI;
     when '10x10' operation = ImmediateOp_ORR;
     when '10x11' operation = ImmediateOp_BIC;
     when '110x0' operation = ImmediateOp_MOVI;
     when '110x1' operation = ImmediateOp_MVNI;
     when '1110x' operation = ImmediateOp_MOVI;
     when '11110' operation = ImmediateOp_MOVI;
     when '11111'
         // FMOV Dn,#imm is in main FP instruction set
         if Q == '0' then UnallocatedEncoding();
         operation = ImmediateOp_MOVI;

 imm64 = AdvSIMDExpandImm(op, cmode, a:b:c:d:e:f:g:h);
 imm = Replicate(imm64, datasize DIV 64);


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.
       <T>               For the 16-bit variant: is an arrangement specifier, encoded in the "Q" field. It can have the
                         following values:

                         4H           when Q = 0

                         8H           when Q = 1

                         For the 32-bit variant: is an arrangement specifier, encoded in the "Q" field. It can have the
                         following values:

                         2S           when Q = 0

                         4S           when Q = 1

       <imm8>            Is an 8-bit immediate encoded in "a:b:c:d:e:f:g:h".

       <amount>          For the 16-bit shifted immediate variant: is the shift amount encoded in the "cmode<1>" field. It can
                         have the following values:

                         0            when cmode<1> = 0

                         8            when cmode<1> = 1

                         defaulting to 0 if LSL is omitted.

                         For the 32-bit shifted immediate variant: is the shift amount encoded in the "cmode<2:1>" field. It
                         can have the following values:

                         0            when cmode<2:1> = 00

                         8            when cmode<2:1> = 01

                         16           when cmode<2:1> = 10

                         24           when cmode<2:1> = 11

                         defaulting to 0 if LSL is omitted.

                         For the 32-bit shifting ones variant: is the shift amount encoded in the "cmode<0>" field. It can have
                         the following values:

                         8            when cmode<0> = 0

                         16           when cmode<0> = 1


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand;
         bits(datasize) result;

         case operation of
              when ImmediateOp_MOVI
                   result = imm;
              when ImmediateOp_MVNI
                   result = NOT(imm);
              when ImmediateOp_ORR
                   operand = V[rd];
                   result = operand OR imm;
              when ImmediateOp_BIC
                   operand = V[rd];
                   result = operand AND NOT(imm);

         V[rd] = result;


platform: ARM
mnem: NOT
description:
Bitwise NOT (vector)       (C7.3.185)

This instruction is used by the alias MVN. The alias is always the preferred disassembly.




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                   5 4          0
  0 Q 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 1 0 1 1 0                                   Rn             Rd




Vector variant

NOT <Vd>.<T>, <Vn>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 integer esize = 8;
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV 8;


Assembler symbols

<Vd>            Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>             Is an arrangement specifier, encoded in the "Q" field. It can have the following values:

                8B          when Q = 0

                16B         when Q = 1

<Vn>            Is the name of the SIMD&FP source register, encoded in the "Rn" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 bits(datasize) result;
 bits(esize) element;

 for e = 0 to elements-1
     element = Elem[operand, e, esize];
     Elem[result, e, esize] = NOT(element);

 V[d] = result;


platform: ARM
mnem: PMUL
description:
Polynomial multiply       (C7.3.189)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         1 0 0 1 1 1               Rn              Rd
        U


Three registers of the same type variant

PMUL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if U == '1' && size != '00' then ReservedValue();
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean poly = (U == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              It is RESERVED when:

              .      size = 01, Q = x.

              .      size = 1x, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 bits(esize) element1;
 bits(esize) element2;
 bits(esize) product;

 for e = 0 to elements-1
     element1 = Elem[operand1, e, esize];
     element2 = Elem[operand2, e, esize];
     if poly then
         product = PolynomialMult(element1, element2)<esize-1:0>;
     else
         product = (UInt(element1) * UInt(element2))<esize-1:0>;
              Elem[result, e, esize] = product;

         V[d] = result;


platform: ARM
mnem: PMULL
description:
Polynomial multiply long       (C7.3.190)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4             0
  0 Q 0 0 1 1 1 0 size 1                  Rm          1 1 1 0 0 0               Rn               Rd




Three registers, not all the same type variant

PMULL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '01' || size == '10' then ReservedValue();
 if size == '11' && ! HaveCryptoExt() then UnallocatedEncoding();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              1Q          when size = 11

              It is RESERVED when:

              .      size = 01.

              .      size = 10.

              The '1Q' arrangement is only allocated in an implementation that includes the Cryptographic
              Extension, and is otherwise RESERVED.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              1D          when size = 11, Q = 0

              2D          when size = 11, Q = 1

              It is RESERVED when:

              .      size = 01, Q = x.
                         .      size = 10, Q = x.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(datasize)      operand2 = Vpart[m, part];
         bits(2*datasize) result;
         bits(esize) element1;
         bits(esize) element2;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              Elem[result, e, 2*esize] = PolynomialMult(element1, element2);

         V[d] = result;


platform: ARM
mnem: RADDHN
description:
Rounding add returning high narrow       (C7.3.191)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 0 size 1                  Rm          0 1 0 0 0 0               Rn               Rd
        U                                                   o1


Three registers, not all the same type variant

RADDHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean sub_op = (o1 == '1');
 boolean round = (U == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when size = 11.
       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(2*datasize) operand1 = V[n];
         bits(2*datasize) operand2 = V[m];
         bits(datasize)      result;
         integer round_const = if round then 1 << (esize - 1) else 0;
         bits(2*esize) element1;
         bits(2*esize) element2;
         bits(2*esize) sum;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, 2*esize];
              element2 = Elem[operand2, e, 2*esize];
              if sub_op then
                   sum = element1 - element2;
              else
                   sum = element1 + element2;
              sum = sum + round_const;
              Elem[result, e, esize] = sum<2*esize-1:esize>;

         Vpart[d, part] = result;


platform: ARM
mnem: REV64
description:
       Reverse elements in 64-bit doublewords (vector)       (C7.3.195)




           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                 5 4             0
            0 Q 0 0 1 1 1 0 size 1 0 0 0 0 0 0 0 0 0 1 0                                 Rn              Rd
                  U                                                     o0


       Vector variant

       REV64 <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         // size=esize:      B(0),   H(1),  S(1), D(S)
         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         // op=REVx:        64(0), 32(1), 16(2)
         bits(2) op = o0:U;

         // => op+size:
         //        64+B = 0, 64+H = 1, 64+S = 2, 64+D = X
         //        32+B = 1, 32+H = 2, 32+S = X, 32+D = X
         //        16+B = 2, 16+H = X, 16+S = X, 16+D = X
         //         8+B = X,    8+H = X, 8+S = X,   8+D = X
         // => 3-(op+size) (index bits in group)
         //        64/B = 3, 64+H = 2, 64+S = 1, 64+D = X
         //        32+B = 2, 32+H = 1, 32+S = X, 32+D = X
         //        16+B = 1, 16+H = X, 16+S = X, 16+D = X
         //         8+B = X,    8+H = X, 8+S = X,   8+D = X

         // index bits within group: 1, 2, 3
         if UInt(op)+UInt(size) >= 3 then UnallocatedEncoding();
         integer ibits = 3-(UInt(op)+UInt(size));

         // invert mask to invert index bits within group (max index = 15)
         bits(4) revmask = Zeros(4-ibits):Ones(ibits);


       Assembler symbols

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when size = 11, Q = x.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.
Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 bits(datasize) result;
 integer e_rev;
 for e = 0 to elements-1
     e_rev = UInt(e<3:0> EOR revmask);
     Elem[result, e_rev, esize] = Elem[operand, e, esize];

 V[d] = result;


platform: ARM
mnem: RSHRN
description:
       Rounding shift right narrow (immediate)       (C7.3.196)




           31 30 29 28 27 26 25 24 23 22           19 18    16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 1 0              !=0000      immb      1 0 0 0 1 1               Rn               Rd
                                            immh                               op


       Vector variant

       RSHRN{2} <Vd>.<Tb>, <Vn>.<Ta>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then SEE "Advanced SIMD modified immediate";
         if immh<3> == '1' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         integer shift = (2 * esize) - UInt(immh:immb);
         boolean round = (op == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Tb>              Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B          when immh = 0001, Q = 0

                         16B         when immh = 0001, Q = 1

                         4H          when immh = 001x, Q = 0

                         8H          when immh = 001x, Q = 1

                         2S          when immh = 01xx, Q = 0

                         4S          when immh = 01xx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = x.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <Ta>              Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

                         8H          when immh = 0001

                         4S          when immh = 001x

                         2D          when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.
              It is RESERVED when immh = 1xxx.

<shift>       Is the right shift amount, in the range 1 to the destination element width in bits, encoded in the
              "immh:immb" field. It can have the following values:

              (16-UInt(immh:immb))when immh = 0001

              (32-UInt(immh:immb))when immh = 001x

              (64-UInt(immh:immb))when immh = 01xx

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

              It is RESERVED when immh = 1xxx.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize*2) operand = V[n];
 bits(datasize) result;
 integer round_const = if round then (1 << (shift - 1)) else 0;
 integer element;

 for e = 0 to elements-1
     element = (UInt(Elem[operand, e, 2*esize]) + round_const) >> shift;
     Elem[result, e, esize] = element<esize-1:0>;

 Vpart[d, part] = result;


platform: ARM
mnem: RSUBHN
description:
       Rounding subtract returning high narrow       (C7.3.197)




           31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4             0
            0 Q 1 0 1 1 1 0 size 1                   Rm          0 1 1 0 0 0               Rn               Rd
                  U                                                    o1


       Three registers, not all the same type variant

       RSUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean sub_op = (o1 == '1');
         boolean round = (U == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when size = 11, Q = x.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         8H          when size = 00

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when size = 11.
<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(2*datasize) operand1 = V[n];
 bits(2*datasize) operand2 = V[m];
 bits(datasize)   result;
 integer round_const = if round then 1 << (esize - 1) else 0;
 bits(2*esize) element1;
 bits(2*esize) element2;
 bits(2*esize) sum;

 for e = 0 to elements-1
     element1 = Elem[operand1, e, 2*esize];
     element2 = Elem[operand2, e, 2*esize];
     if sub_op then
         sum = element1 - element2;
     else
         sum = element1 + element2;
     sum = sum + round_const;
     Elem[result, e, esize] = sum<2*esize-1:esize>;

 Vpart[d, part] = result;


platform: ARM
mnem: SABA
description:
      Signed absolute difference and accumulate       (C7.3.198)




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
           0 Q 0 0 1 1 1 0 size 1                  Rm         0 1 1 1 1 1               Rn              Rd
                 U                                                        ac


      Three registers of the same type variant

      SABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean accumulate = (ac == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

      <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand1 = V[n];
        bits(datasize) operand2 = V[m];
        bits(datasize) result;
        integer element1;
        integer element2;
        bits(esize) absdiff;

        result = if accumulate then V[d] else Zeros();
        for e = 0 to elements-1
             element1 = Int(Elem[operand1, e, esize], unsigned);
             element2 = Int(Elem[operand2, e, esize], unsigned);
   absdiff = Abs(element1 - element2)<esize-1:0>;
   Elem[result, e, esize] = Elem[result, e, esize] + absdiff;
V[d] = result;


platform: ARM
mnem: SABAL
description:
       Signed absolute difference and accumulate long       (C7.3.199)




           31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 0 size 1                   Rm          0 1 0 1 0 0               Rn               Rd
                  U                                                    op


       Three registers, not all the same type variant

       SABAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean accumulate = (op == '0');
         boolean unsigned = (U == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         8H          when size = 00

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when size = 11, Q = x.
<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize)   operand1 = Vpart[n, part];
 bits(datasize)   operand2 = Vpart[m, part];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 bits(2*esize) absdiff;

 result = if accumulate then V[d] else Zeros();
 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     absdiff = Abs(element1 - element2)<2*esize-1:0>;
     Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff;
 V[d] = result;


platform: ARM
mnem: SABD
description:
      Signed absolute difference       (C7.3.200)




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
           0 Q 0 0 1 1 1 0 size 1                  Rm         0 1 1 1 0 1               Rn              Rd
                 U                                                        ac


      Three registers of the same type variant

      SABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean accumulate = (ac == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

      <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand1 = V[n];
        bits(datasize) operand2 = V[m];
        bits(datasize) result;
        integer element1;
        integer element2;
        bits(esize) absdiff;

        result = if accumulate then V[d] else Zeros();
        for e = 0 to elements-1
             element1 = Int(Elem[operand1, e, esize], unsigned);
             element2 = Int(Elem[operand2, e, esize], unsigned);
   absdiff = Abs(element1 - element2)<esize-1:0>;
   Elem[result, e, esize] = Elem[result, e, esize] + absdiff;
V[d] = result;


platform: ARM
mnem: SABDL
description:
       Signed absolute difference long       (C7.3.201)




           31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 0 size 1                   Rm          0 1 1 1 0 0               Rn               Rd
                  U                                                    op


       Three registers, not all the same type variant

       SABDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean accumulate = (op == '0');
         boolean unsigned = (U == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         8H          when size = 00

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when size = 11, Q = x.
<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize)   operand1 = Vpart[n, part];
 bits(datasize)   operand2 = Vpart[m, part];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 bits(2*esize) absdiff;

 result = if accumulate then V[d] else Zeros();
 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     absdiff = Abs(element1 - element2)<2*esize-1:0>;
     Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff;
 V[d] = result;


platform: ARM
mnem: SADALP
description:
      Signed add and accumulate long pairwise       (C7.3.202)




          31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                 5 4             0
           0 Q 0 0 1 1 1 0 size 1 0 0 0 0 0 0 1 1 0 1 0                                 Rn              Rd
                 U                                              op


      Vector variant

      SADALP <Vd>.<Ta>, <Vn>.<Tb>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);

        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV (2*esize);
        boolean acc = (op == '1');
        boolean unsigned = (U == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <Ta>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        4H          when size = 00, Q = 0

                        8H          when size = 00, Q = 1

                        2S          when size = 01, Q = 0

                        4S          when size = 01, Q = 1

                        1D          when size = 10, Q = 0

                        2D          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

      <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand = V[n];
        bits(datasize) result;

bits(2*esize) sum;
integer op1;
integer op2;

result = if acc then V[d] else Zeros();
for e = 0 to elements-1
    op1 = Int(Elem[operand, 2*e+0, esize], unsigned);
    op2 = Int(Elem[operand, 2*e+1, esize], unsigned);
    sum = (op1 + op2)<2*esize-1:0>;
    Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum;

V[d] = result;


platform: ARM
mnem: SADDL
description:
       Signed add long (vector)       (C7.3.203)




           31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 0 size 1                   Rm          0 0 0 0 0 0               Rn               Rd
                  U                                                    o1


       Three registers, not all the same type variant

       SADDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean sub_op = (o1 == '1');
         boolean unsigned = (U == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         8H          when size = 00

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when size = 11, Q = x.
<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize)   operand1 = Vpart[n, part];
 bits(datasize)   operand2 = Vpart[m, part];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 integer sum;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     if sub_op then
         sum = element1 - element2;
     else
         sum = element1 + element2;
     Elem[result, e, 2*esize] = sum<2*esize-1:0>;

 V[d] = result;


platform: ARM
mnem: SADDLP
description:
      Signed add long pairwise       (C7.3.204)




          31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                 5 4             0
           0 Q 0 0 1 1 1 0 size 1 0 0 0 0 0 0 0 1 0 1 0                                 Rn              Rd
                 U                                              op


      Vector variant

      SADDLP <Vd>.<Ta>, <Vn>.<Tb>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);

        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV (2*esize);
        boolean acc = (op == '1');
        boolean unsigned = (U == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <Ta>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        4H          when size = 00, Q = 0

                        8H          when size = 00, Q = 1

                        2S          when size = 01, Q = 0

                        4S          when size = 01, Q = 1

                        1D          when size = 10, Q = 0

                        2D          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

      <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand = V[n];
        bits(datasize) result;

bits(2*esize) sum;
integer op1;
integer op2;

result = if acc then V[d] else Zeros();
for e = 0 to elements-1
    op1 = Int(Elem[operand, 2*e+0, esize], unsigned);
    op2 = Int(Elem[operand, 2*e+1, esize], unsigned);
    sum = (op1 + op2)<2*esize-1:0>;
    Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum;

V[d] = result;


platform: ARM
mnem: SADDLV
description:
      Signed add long across vector       (C7.3.205)




          31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                    5 4            0
           0 Q 0 0 1 1 1 0 size 1 1 0 0 0 0 0 0 1 1 1 0                                  Rn               Rd
                 U


      Advanced SIMD variant

      SADDLV <V><d>, <Vn>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);

        if size:Q == '100' then ReservedValue();
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');


      Assembler symbols

      <V>               Is the destination width specifier, encoded in the "size" field. It can have the following values:

                        H           when size = 00

                        S           when size = 01

                        D           when size = 10

                        It is RESERVED when size = 11.

      <d>               Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

      <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        4S          when size = 10, Q = 1

                        It is RESERVED when:

                        .      size = 10, Q = 0.

                        .      size = 11, Q = x.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand = V[n];
        integer sum;

        sum = Int(Elem[operand, 0, esize], unsigned);
for e = 1 to elements-1
    sum = sum + Int(Elem[operand, e, esize], unsigned);

V[d] = sum<2*esize-1:0>;


platform: ARM
mnem: SADDW
description:
       Signed add wide       (C7.3.206)




           31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 0 size 1                   Rm          0 0 0 1 0 0               Rn               Rd
                  U                                                    o1


       Three registers, not all the same type variant

       SADDW{2} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean sub_op = (o1 == '1');
         boolean unsigned = (U == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         8H          when size = 00

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1
              It is RESERVED when size = 11, Q = x.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(2*datasize) operand1 = V[n];
 bits(datasize)   operand2 = Vpart[m, part];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 integer sum;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, 2*esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     if sub_op then
         sum = element1 - element2;
     else
         sum = element1 + element2;
     Elem[result, e, 2*esize] = sum<2*esize-1:0>;

 V[d] = result;


platform: ARM
mnem: SCVTF
description:
       Signed fixed-point convert to floating-point (vector)       (C7.3.207)


       Scalar


           31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9               5 4          0
            0 1 0 1 1 1 1 1 0              !=0000     immb      1 1 1 0 0 1             Rn             Rd
                  U                         immh


       Scalar variant

       SCVTF <V><d>, <V><n>, #<fbits>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '00xx' then ReservedValue();
         integer esize = 32 << UInt(immh<3>);
         integer datasize = esize;
         integer elements = 1;

         integer fracbits = (esize * 2) - UInt(immh:immb);
         boolean unsigned = (U == '1');
         FPRounding rounding = FPRoundingMode(FPCR);


       Vector


           31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9               5 4          0
            0 Q 0 0 1 1 1 1 0              !=0000     immb      1 1 1 0 0 1             Rn             Rd
                  U                         immh


       Vector variant

       SCVTF <Vd>.<T>, <Vn>.<T>, #<fbits>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then SEE "Advanced SIMD modified immediate";
         if immh == '00xx' then ReservedValue();
         if immh<3>:Q == '10' then ReservedValue();
         integer esize = 32 << UInt(immh<3>);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         integer fracbits = (esize * 2) - UInt(immh:immb);
         boolean unsigned = (U == '1');
         FPRounding rounding = FPRoundingMode(FPCR);


       Assembler symbols

       <V>               Is a width specifier, encoded in the "immh" field. It can have the following values:

                         S           when immh = 01xx

                         D           when immh = 1xxx
              It is RESERVED when immh = 00xx.

<d>           Is the number of the SIMD&FP destination register, in the "Rd" field.

<n>           Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

              2S          when immh = 01xx, Q = 0

              4S          when immh = 01xx, Q = 1

              2D          when immh = 1xxx, Q = 1

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

              It is RESERVED when:

              .      immh = 0001, Q = x.

              .      immh = 001x, Q = x.

              .      immh = 1xxx, Q = 0.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<fbits>       For the scalar variant: is the number of fractional bits, in the range 1 to the operand width, encoded
              in the "immh:immb" field. It can have the following values:

              (64-UInt(immh:immb))when immh = 01xx

              (128-UInt(immh:immb))when immh = 1xxx

              It is RESERVED when immh = 00xx.

              For the vector variant: is the number of fractional bits, in the range 1 to the element width, encoded
              in the "immh:immb" field. It can have the following values:

              (64-UInt(immh:immb))when immh = 01xx

              (128-UInt(immh:immb))when immh = 1xxx

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

              It is RESERVED when:

              .      immh = 0001.

              .      immh = 001x.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand  = V[n];
 bits(datasize) result;
 bits(esize) element;

 for e = 0 to elements-1
     element = Elem[operand, e, esize];
     Elem[result, e, esize] = FixedToFP(element, fracbits, unsigned, FPCR, rounding);

 V[d] = result;


platform: ARM
mnem: SHA1C
description:
SHA1 hash update (choose)       (C7.3.211)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9           5 4             0
     0 1 0 1 1 1 1 0 0 0 0                   Rm         0 0 0 0 0 0          Rn              Rd




Advanced SIMD variant

SHA1C <Qd>, <Sn>, <Vm>.4S


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Qd>              Is the 128-bit name of the SIMD&FP source and destination, encoded in the "Rd" field.

<Sn>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the third SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckCryptoEnabled64();

  bits(128) X = V[d];
  bits(32)    Y = V[n];      // Note: 32 not 128 bits wide
  bits(128) W = V[m];
  bits(32)    t;

  for e = 0 to 3
       t = SHAchoose(X<63:32>, X<95:64>, X<127:96>);
       Y = Y + ROL(X<31:0>, 5) + t + Elem[W, e, 32];
       X<63:32> = ROL(X<63:32>, 30);
       <Y, X> = ROL(Y : X, 32);
  V[d] = X;


platform: ARM
mnem: SHA1H
description:
SHA1 fixed rotate       (C7.3.212)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0                                Rn             Rd




Advanced SIMD variant

SHA1H <Sd>, <Sn>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Sd>          Is the 32-bit name of the SIMD&FP destination register, encoded in the "Rd" field.

<Sn>          Is the 32-bit name of the SIMD&FP source register, encoded in the "Rn" field.


Operation

 CheckCryptoEnabled64();

 bits(32) operand = V[n];        // read element [0] only,    [1-3] zeroed
 V[d] = ROL(operand, 30);


platform: ARM
mnem: SHA1M
description:
SHA1 hash update (majority)       (C7.3.213)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9           5 4             0
     0 1 0 1 1 1 1 0 0 0 0                   Rm         0 0 1 0 0 0          Rn              Rd




Advanced SIMD variant

SHA1M <Qd>, <Sn>, <Vm>.4S


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Qd>              Is the 128-bit name of the SIMD&FP source and destination, encoded in the "Rd" field.

<Sn>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the third SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckCryptoEnabled64();

  bits(128) X = V[d];
  bits(32)    Y = V[n];      // Note: 32 not 128 bits wide
  bits(128) W = V[m];
  bits(32)    t;

  for e = 0 to 3
       t = SHAmajority(X<63:32>, X<95:64>, X<127:96>);
       Y = Y + ROL(X<31:0>, 5) + t + Elem[W, e, 32];
       X<63:32> = ROL(X<63:32>, 30);
       <Y, X> = ROL(Y : X, 32);
  V[d] = X;


platform: ARM
mnem: SHA1P
description:
SHA1 hash update (parity)       (C7.3.214)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4          0
  0 1 0 1 1 1 1 0 0 0 0                  Rm         0 0 0 1 0 0               Rn             Rd




Advanced SIMD variant

SHA1P <Qd>, <Sn>, <Vm>.4S


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Qd>          Is the 128-bit name of the SIMD&FP source and destination, encoded in the "Rd" field.

<Sn>          Is the 32-bit name of the second SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the third SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckCryptoEnabled64();

 bits(128) X = V[d];
 bits(32)  Y = V[n];     // Note: 32 not 128 bits wide
 bits(128) W = V[m];
 bits(32)  t;

 for e = 0 to 3
     t = SHAparity(X<63:32>, X<95:64>, X<127:96>);
     Y = Y + ROL(X<31:0>, 5) + t + Elem[W, e, 32];
     X<63:32> = ROL(X<63:32>, 30);
     <Y, X> = ROL(Y : X, 32);
 V[d] = X;


platform: ARM
mnem: SHA1SU0
description:
SHA1 schedule update 0       (C7.3.215)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9           5 4             0
     0 1 0 1 1 1 1 0 0 0 0                   Rm         0 0 1 1 0 0           Rn             Rd




Advanced SIMD variant

SHA1SU0 <Vd>.4S, <Vn>.4S, <Vm>.4S


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Vd>              Is the name of the SIMD&FP source and destination register, encoded in the "Rd" field.

<Vn>              Is the name of the second SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the third SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckCryptoEnabled64();

  bits(128) operand1 = V[d];
  bits(128) operand2 = V[n];
  bits(128) operand3 = V[m];
  bits(128) result;

  result = operand2<63:0> : operand1<127:64>;
  result = result EOR operand1 EOR operand3;
  V[d] = result;


platform: ARM
mnem: SHA1SU1
description:
SHA1 schedule update 1       (C7.3.216)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0 0 1 1 0                                Rn             Rd




Advanced SIMD variant

SHA1SU1 <Vd>.4S, <Vn>.4S


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Vd>          Is the name of the SIMD&FP source and destination register, encoded in the "Rd" field.

<Vn>          Is the name of the second SIMD&FP source register, encoded in the "Rn" field.


Operation

 CheckCryptoEnabled64();

 bits(128) operand1 = V[d];
 bits(128) operand2 = V[n];
 bits(128) result;
 bits(128) T = operand1 EOR LSR(operand2, 32);
 result<31:0>   = ROL(T<31:0>,    1);
 result<63:32>  = ROL(T<63:32>,   1);
 result<95:64>  = ROL(T<95:64>,   1);
 result<127:96> = ROL(T<127:96>, 1) EOR ROL(T<31:0>, 2);
 V[d] = result;


platform: ARM
mnem: SHA256H2
description:
SHA256 hash update (part 2)       (C7.3.217)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9           5 4             0
     0 1 0 1 1 1 1 0 0 0 0                   Rm         0 1 0 1 0 0          Rn              Rd
                                                                P


Advanced SIMD variant

SHA256H2 <Qd>, <Qn>, <Vm>.4S


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if ! HaveCryptoExt() then UnallocatedEncoding();
  boolean part1 = (P == '0');


Assembler symbols

<Qd>              Is the 128-bit name of the SIMD&FP source and destination, encoded in the "Rd" field.

<Qn>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the third SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckCryptoEnabled64();

  bits(128) result;
  if part1 then
       result = SHA256hash(V[d], V[n], V[m], TRUE);
  else
       result = SHA256hash(V[n], V[d], V[m], FALSE);
  V[d] = result;


platform: ARM
mnem: SHA256H
description:
SHA256 hash update (part 1)       (C7.3.218)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4          0
  0 1 0 1 1 1 1 0 0 0 0                  Rm         0 1 0 0 0 0               Rn             Rd
                                                            P


Advanced SIMD variant

SHA256H <Qd>, <Qn>, <Vm>.4S


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if ! HaveCryptoExt() then UnallocatedEncoding();
 boolean part1 = (P == '0');


Assembler symbols

<Qd>          Is the 128-bit name of the SIMD&FP source and destination, encoded in the "Rd" field.

<Qn>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the third SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckCryptoEnabled64();

 bits(128) result;
 if part1 then
     result = SHA256hash(V[d], V[n], V[m], TRUE);
 else
     result = SHA256hash(V[n], V[d], V[m], FALSE);
 V[d] = result;


platform: ARM
mnem: SHA256SU0
description:
SHA256 schedule update 0       (C7.3.219)




    31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9             5 4             0
     0 1 0 1 1 1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0                              Rn             Rd




Advanced SIMD variant

SHA256SU0 <Vd>.4S, <Vn>.4S


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Vd>              Is the name of the SIMD&FP source and destination register, encoded in the "Rd" field.

<Vn>              Is the name of the second SIMD&FP source register, encoded in the "Rn" field.


Operation

  CheckCryptoEnabled64();

  bits(128) operand1 = V[d];
  bits(128) operand2 = V[n];
  bits(128) result;
  bits(128) T = operand2<31:0> : operand1<127:32>;
  bits(32) elt;

  for e = 0 to 3
       elt = Elem[T, e, 32];
       elt = ROR(elt, 7) EOR ROR(elt, 18) EOR LSR(elt, 3);
       Elem[result, e, 32] = elt + Elem[operand1, e, 32];
  V[d] = result;


platform: ARM
mnem: SHA256SU1
description:
SHA256 schedule update 1       (C7.3.220)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 0 0 0 0                  Rm         0 1 1 0 0 0              Rn             Rd




Advanced SIMD variant

SHA256SU1 <Vd>.4S, <Vn>.4S, <Vm>.4S


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if ! HaveCryptoExt() then UnallocatedEncoding();


Assembler symbols

<Vd>          Is the name of the SIMD&FP source and destination register, encoded in the "Rd" field.

<Vn>          Is the name of the second SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the third SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckCryptoEnabled64();

 bits(128) operand1 = V[d];
 bits(128) operand2 = V[n];
 bits(128) operand3 = V[m];
 bits(128) result;
 bits(128) T0 = operand3<31:0> : operand2<127:32>;
 bits(64) T1;
 bits(32) elt;

 T1 = operand3<127:64>;
 for e = 0 to 1
     elt = Elem[T1, e, 32];
     elt = ROR(elt, 17) EOR ROR(elt, 19) EOR LSR(elt, 10);
     elt = elt + Elem[operand1, e, 32] + Elem[T0, e, 32];
     Elem[result, e, 32] = elt;

 T1 = result<63:0>;
 for e = 2 to 3
     elt = Elem[T1, e - 2, 32];
     elt = ROR(elt, 17) EOR ROR(elt, 19) EOR LSR(elt, 10);
     elt = elt + Elem[operand1, e, 32] + Elem[T0, e, 32];
     Elem[result, e, 32] = elt;

 V[d] = result;


platform: ARM
mnem: SHADD
description:
Signed halving add       (C7.3.221)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
     0 Q 0 0 1 1 1 0 size 1                  Rm         0 0 0 0 0 1               Rn              Rd
           U


Three registers of the same type variant

SHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if size == '11' then ReservedValue();
  integer esize = 8 << UInt(size);
  integer datasize = if Q == '1' then 128 else 64;
  integer elements = datasize DIV esize;
  boolean unsigned = (U == '1');


Assembler symbols

<Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                  8B          when size = 00, Q = 0

                  16B         when size = 00, Q = 1

                  4H          when size = 01, Q = 0

                  8H          when size = 01, Q = 1

                  2S          when size = 10, Q = 0

                  4S          when size = 10, Q = 1

                  It is RESERVED when size = 11, Q = x.

<Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand1 = V[n];
  bits(datasize) operand2 = V[m];
  bits(datasize) result;
  integer element1;
  integer element2;
  integer sum;

  for e = 0 to elements-1
       element1 = Int(Elem[operand1, e, esize], unsigned);
       element2 = Int(Elem[operand2, e, esize], unsigned);
       sum = element1 + element2;
       Elem[result, e, esize] = sum<esize:1>;

  V[d] = result;


platform: ARM
mnem: SHL
description:
Shift left (immediate)       (C7.3.222)


Scalar


  31 30 29 28 27 26 25 24 23 22         19 18    16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 1 0              !=0000     immb      0 1 0 1 0 1              Rn             Rd
                                  immh


Scalar variant

SHL <V><d>, <V><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh<3> != '1' then ReservedValue();
 integer esize = 8 << 3;
 integer datasize = esize;
 integer elements = 1;

 integer shift = UInt(immh:immb) - esize;


Vector


  31 30 29 28 27 26 25 24 23 22         19 18    16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 1 0              !=0000     immb      0 1 0 1 0 1              Rn             Rd
                                  immh


Vector variant

SHL <Vd>.<T>, <Vn>.<T>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer shift = UInt(immh:immb) - esize;


Assembler symbols

<V>            Is a width specifier, encoded in the "immh" field. It can have the following values:

               D           when immh = 1xxx

               It is RESERVED when immh = 0xxx.

<d>            Is the number of the SIMD&FP destination register, in the "Rd" field.

<n>            Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<Vd>           Is the name of the SIMD&FP destination register, encoded in the "Rd" field.
       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B           when immh = 0001, Q = 0

                         16B          when immh = 0001, Q = 1

                         4H           when immh = 001x, Q = 0

                         8H           when immh = 001x, Q = 1

                         2S           when immh = 01xx, Q = 0

                         4S           when immh = 01xx, Q = 1

                         2D           when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the left shift amount, in the range 0 to 63, encoded in the "immh:immb"
                         field. It can have the following values:

                         (UInt(immh:immb)-64)when immh = 1xxx

                         It is RESERVED when immh = 0xxx.

                         For the vector variant: is the left shift amount, in the range 0 to the element width in bits minus 1,
                         encoded in the "immh:immb" field. It can have the following values:

                         (UInt(immh:immb)-8)when immh = 0001

                         (UInt(immh:immb)-16)when immh = 001x

                         (UInt(immh:immb)-32)when immh = 01xx

                         (UInt(immh:immb)-64)when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand      = V[n];
         bits(datasize) result;

         for e = 0 to elements-1
              Elem[result, e, esize] = LSL(Elem[operand, e, esize], shift);

         V[d] = result;


platform: ARM
mnem: SHLL
description:
Shift left long (by element size)       (C7.3.223)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                     5 4             0
  0 Q 1 0 1 1 1 0 size 1 0 0 0 0 1 0 0 1 1 1 0                                     Rn               Rd




Vector variant

SHLL{2} <Vd>.<Ta>, <Vn>.<Tb>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 integer shift = esize;
 boolean unsigned = FALSE; // Or TRUE without change of functionality


Assembler symbols

2                Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                 64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                 the following values:

                 [absent]    when Q = 0

                 [present]   when Q = 1

<Vd>             Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>             Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                 8H          when size = 00

                 4S          when size = 01

                 2D          when size = 10

                 It is RESERVED when size = 11.

<Vn>             Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Tb>             Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                 8B          when size = 00, Q = 0

                 16B         when size = 00, Q = 1

                 4H          when size = 01, Q = 0

                 8H          when size = 01, Q = 1

                 2S          when size = 10, Q = 0

                 4S          when size = 10, Q = 1

                 It is RESERVED when size = 11, Q = x.
       <shift>           Is the left shift amount, which must be equal to the source element width in bits, encoded in the
                         "size" field. It can have the following values:

                         8            when size = 00

                         16           when size = 01

                         32           when size = 10

                         It is RESERVED when size = 11.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand = Vpart[n, part];
         bits(2*datasize) result;
         integer element;

         for e = 0 to elements-1
              element = Int(Elem[operand, e, esize], unsigned) << shift;
              Elem[result, e, 2*esize] = element<2*esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SHRN
description:
Shift right narrow (immediate)       (C7.3.224)




  31 30 29 28 27 26 25 24 23 22           19 18    16 15 14 13 12 11 10 9                5 4             0
  0 Q 0 0 1 1 1 1 0               !=0000      immb      1 0 0 0 0 1               Rn               Rd
                                   immh                               op


Vector variant

SHRN{2} <Vd>.<Tb>, <Vn>.<Ta>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 integer shift = (2 * esize) - UInt(immh:immb);
 boolean round = (op == '1');


Assembler symbols

2               Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                the following values:

                [absent]    when Q = 0

                [present]   when Q = 1

<Vd>            Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Tb>            Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                8B          when immh = 0001, Q = 0

                16B         when immh = 0001, Q = 1

                4H          when immh = 001x, Q = 0

                8H          when immh = 001x, Q = 1

                2S          when immh = 01xx, Q = 0

                4S          when immh = 01xx, Q = 1

                See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                It is RESERVED when immh = 1xxx, Q = x.

<Vn>            Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Ta>            Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

                8H          when immh = 0001

                4S          when immh = 001x

                2D          when immh = 01xx

                See Advanced SIMD modified immediate on page C4-213 when immh = 0000.
                         It is RESERVED when immh = 1xxx.

       <shift>           Is the right shift amount, in the range 1 to the destination element width in bits, encoded in the
                         "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when immh = 1xxx.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize*2) operand = V[n];
         bits(datasize) result;
         integer round_const = if round then (1 << (shift - 1)) else 0;
         integer element;

         for e = 0 to elements-1
              element = (UInt(Elem[operand, e, 2*esize]) + round_const) >> shift;
              Elem[result, e, esize] = element<esize-1:0>;

         Vpart[d, part] = result;


platform: ARM
mnem: SHSUB
description:
Signed halving subtract       (C7.3.225)




  31 30 29 28 27 26 25 24 23 22 21 20           16 15 14 13 12 11 10 9                 5 4           0
  0 Q 0 0 1 1 1 0 size 1                  Rm         0 0 1 0 0 1               Rn              Rd
        U


Three registers of the same type variant

SHSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;
 boolean unsigned = (U == '1');


Assembler symbols

<Vd>           Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>            Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1

               It is RESERVED when size = 11, Q = x.

<Vn>           Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>           Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 integer diff;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     diff = element1 - element2;
     Elem[result, e, esize] = diff<esize:1>;

 V[d] = result;


platform: ARM
mnem: SLI
description:
       Shift left and insert (immediate)       (C7.3.226)


       Scalar


           31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9               5 4          0
            0 1 1 1 1 1 1 1 0              !=0000     immb      0 1 0 1 0 1             Rn             Rd
                                            immh


       Scalar variant

       SLI <V><d>, <V><n>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh<3> != '1' then ReservedValue();
         integer esize = 8 << 3;
         integer datasize = esize;
         integer elements = 1;

         integer shift = UInt(immh:immb) - esize;


       Vector


           31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9               5 4          0
            0 Q 1 0 1 1 1 1 0              !=0000     immb      0 1 0 1 0 1             Rn             Rd
                                            immh


       Vector variant

       SLI <Vd>.<T>, <Vn>.<T>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then SEE "Advanced SIMD modified immediate";
         if immh<3>:Q == '10' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         integer shift = UInt(immh:immb) - esize;


       Assembler symbols

       <V>               Is a width specifier, encoded in the "immh" field. It can have the following values:

                         D           when immh = 1xxx

                         It is RESERVED when immh = 0xxx.

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.
<T>           Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

              8B           when immh = 0001, Q = 0

              16B          when immh = 0001, Q = 1

              4H           when immh = 001x, Q = 0

              8H           when immh = 001x, Q = 1

              2S           when immh = 01xx, Q = 0

              4S           when immh = 01xx, Q = 1

              2D           when immh = 1xxx, Q = 1

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

              It is RESERVED when immh = 1xxx, Q = 0.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<shift>       For the scalar variant: is the left shift amount, in the range 0 to 63, encoded in the "immh:immb"
              field. It can have the following values:

              (UInt(immh:immb)-64)when immh = 1xxx

              It is RESERVED when immh = 0xxx.

              For the vector variant: is the left shift amount, in the range 0 to the element width in bits minus 1,
              encoded in the "immh:immb" field. It can have the following values:

              (UInt(immh:immb)-8)when immh = 0001

              (UInt(immh:immb)-16)when immh = 001x

              (UInt(immh:immb)-32)when immh = 01xx

              (UInt(immh:immb)-64)when immh = 1xxx

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand   = V[n];
 bits(datasize) operand2 = V[d];
 bits(datasize) result;
 bits(esize) mask = LSL(Ones(esize), shift);
 bits(esize) shifted;

 for e = 0 to elements-1
     shifted = LSL(Elem[operand, e, esize], shift);
     Elem[result, e, esize] = (Elem[operand2, e, esize] AND NOT(mask)) OR shifted;
 V[d] = result;


platform: ARM
mnem: SMAX
description:
      Signed maximum (vector)       (C7.3.227)




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
           0 Q 0 0 1 1 1 0 size 1                  Rm         0 1 1 0 0 1               Rn              Rd
                 U                                                        o1


      Three registers of the same type variant

      SMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean minimum = (o1 == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

      <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand1 = V[n];
        bits(datasize) operand2 = V[m];
        bits(datasize) result;
        integer element1;
        integer element2;
        integer maxmin;

        for e = 0 to elements-1
             element1 = Int(Elem[operand1, e, esize], unsigned);
             element2 = Int(Elem[operand2, e, esize], unsigned);
             maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
   Elem[result, e, esize] = maxmin<esize-1:0>;

V[d] = result;


platform: ARM
mnem: SMAXP
description:
      Signed maximum pairwise       (C7.3.228)




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
           0 Q 0 0 1 1 1 0 size 1                  Rm         1 0 1 0 0 1               Rn              Rd
                 U                                                        o1


      Three registers of the same type variant

      SMAXP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean minimum = (o1 == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

      <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand1 = V[n];
        bits(datasize) operand2 = V[m];
        bits(datasize) result;
        bits(2*datasize) concat = operand2:operand1;
        integer element1;
        integer element2;
        integer maxmin;

        for e = 0 to elements-1
             element1 = Int(Elem[concat, 2*e, esize], unsigned);
             element2 = Int(Elem[concat, (2*e)+1, esize], unsigned);
             maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
   Elem[result, e, esize] = maxmin<esize-1:0>;

V[d] = result;


platform: ARM
mnem: SMAXV
description:
      Signed maximum across vector       (C7.3.229)




          31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                    5 4            0
           0 Q 0 0 1 1 1 0 size 1 1 0 0 0 0 1 0 1 0 1 0                                  Rn               Rd
                 U                                         op


      Advanced SIMD variant

      SMAXV <V><d>, <Vn>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);

        if size:Q == '100' then ReservedValue();
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean min = (op == '1');


      Assembler symbols

      <V>               Is the destination width specifier, encoded in the "size" field. It can have the following values:

                        B           when size = 00

                        H           when size = 01

                        S           when size = 10

                        It is RESERVED when size = 11.

      <d>               Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

      <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        4S          when size = 10, Q = 1

                        It is RESERVED when:

                        .      size = 10, Q = 0.

                        .      size = 11, Q = x.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand = V[n];
        integer maxmin;
        integer element;

maxmin = Int(Elem[operand, 0, esize], unsigned);
for e = 1 to elements-1
    element = Int(Elem[operand, e, esize], unsigned);
    maxmin = if min then Min(maxmin, element) else Max(maxmin, element);

V[d] = maxmin<esize-1:0>;


platform: ARM
mnem: SMIN
description:
      Signed minimum (vector)       (C7.3.230)




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
           0 Q 0 0 1 1 1 0 size 1                  Rm         0 1 1 0 1 1               Rn              Rd
                 U                                                        o1


      Three registers of the same type variant

      SMIN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean minimum = (o1 == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

      <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand1 = V[n];
        bits(datasize) operand2 = V[m];
        bits(datasize) result;
        integer element1;
        integer element2;
        integer maxmin;

        for e = 0 to elements-1
             element1 = Int(Elem[operand1, e, esize], unsigned);
             element2 = Int(Elem[operand2, e, esize], unsigned);
             maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
   Elem[result, e, esize] = maxmin<esize-1:0>;

V[d] = result;


platform: ARM
mnem: SMINP
description:
      Signed minimum pairwise       (C7.3.231)




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
           0 Q 0 0 1 1 1 0 size 1                  Rm         1 0 1 0 1 1               Rn              Rd
                 U                                                        o1


      Three registers of the same type variant

      SMINP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean minimum = (o1 == '1');


      Assembler symbols

      <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        2S          when size = 10, Q = 0

                        4S          when size = 10, Q = 1

                        It is RESERVED when size = 11, Q = x.

      <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

      <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand1 = V[n];
        bits(datasize) operand2 = V[m];
        bits(datasize) result;
        bits(2*datasize) concat = operand2:operand1;
        integer element1;
        integer element2;
        integer maxmin;

        for e = 0 to elements-1
             element1 = Int(Elem[concat, 2*e, esize], unsigned);
             element2 = Int(Elem[concat, (2*e)+1, esize], unsigned);
             maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
   Elem[result, e, esize] = maxmin<esize-1:0>;

V[d] = result;


platform: ARM
mnem: SMINV
description:
      Signed minimum across vector       (C7.3.232)




          31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                    5 4            0
           0 Q 0 0 1 1 1 0 size 1 1 0 0 0 1 1 0 1 0 1 0                                  Rn               Rd
                 U                                         op


      Advanced SIMD variant

      SMINV <V><d>, <Vn>.<T>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);

        if size:Q == '100' then ReservedValue();
        if size == '11' then ReservedValue();
        integer esize = 8 << UInt(size);
        integer datasize = if Q == '1' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean unsigned = (U == '1');
        boolean min = (op == '1');


      Assembler symbols

      <V>               Is the destination width specifier, encoded in the "size" field. It can have the following values:

                        B           when size = 00

                        H           when size = 01

                        S           when size = 10

                        It is RESERVED when size = 11.

      <d>               Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

      <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

      <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                        8B          when size = 00, Q = 0

                        16B         when size = 00, Q = 1

                        4H          when size = 01, Q = 0

                        8H          when size = 01, Q = 1

                        4S          when size = 10, Q = 1

                        It is RESERVED when:

                        .      size = 10, Q = 0.

                        .      size = 11, Q = x.


      Operation

        CheckFPAdvSIMDEnabled64();
        bits(datasize) operand = V[n];
        integer maxmin;
        integer element;

maxmin = Int(Elem[operand, 0, esize], unsigned);
for e = 1 to elements-1
    element = Int(Elem[operand, e, esize], unsigned);
    maxmin = if min then Min(maxmin, element) else Max(maxmin, element);

V[d] = maxmin<esize-1:0>;


platform: ARM
mnem: SMLAL
description:
       Signed multiply-add long (vector, by element)       (C7.3.233)




           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 1 size L M                   Rm        0 0 1 0 H 0               Rn               Rd
                  U                                                 o2


       Vector variant

       SMLAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);        Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean unsigned = (U == '1');
         boolean sub_op = (o2 == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1
              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when:

              .      size = 00, Q = x.

              .      size = 11, Q = x.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
              the following values:

              0:Rm        when size = 01

              M:Rm        when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              Restricted to V0-V15 when element size <Ts> is H.

<Ts>          Is an element size specifier, encoded in the "size" field. It can have the following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       Is the element index encoded in the "size:L:H:M" field. It can have the following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize)   operand1 = Vpart[n, part];
 bits(idxdsize)   operand2 = V[m];
 bits(2*datasize) operand3 = V[d];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 bits(2*esize) product;

 element2 = Int(Elem[operand2, index, esize], unsigned);
 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     product = (element1 * element2)<2*esize-1:0>;
     if sub_op then
         Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product;
     else
         Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product;

 V[d] = result;


platform: ARM
mnem: SMLSL
description:
       Signed multiply-subtract long (vector, by element)       (C7.3.235)




           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 1 size L M                   Rm        0 1 1 0 H 0               Rn               Rd
                  U                                                 o2


       Vector variant

       SMLSL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);        Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean unsigned = (U == '1');
         boolean sub_op = (o2 == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1
              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when:

              .      size = 00, Q = x.

              .      size = 11, Q = x.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
              the following values:

              0:Rm        when size = 01

              M:Rm        when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              Restricted to V0-V15 when element size <Ts> is H.

<Ts>          Is an element size specifier, encoded in the "size" field. It can have the following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       Is the element index encoded in the "size:L:H:M" field. It can have the following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize)   operand1 = Vpart[n, part];
 bits(idxdsize)   operand2 = V[m];
 bits(2*datasize) operand3 = V[d];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 bits(2*esize) product;

 element2 = Int(Elem[operand2, index, esize], unsigned);
 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     product = (element1 * element2)<2*esize-1:0>;
     if sub_op then
         Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product;
     else
         Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product;

 V[d] = result;


platform: ARM
mnem: SMOV
description:
       Signed move vector element to general-purpose register       (C7.3.237)




           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9               5 4              0
            0 Q 0 0 1 1 1 0 0 0 0                   imm5        0 0 1 0 1 1              Rn             Rd




       32-bit variant

       Applies when Q = 0.

       SMOV <Wd>, <Vn>.<Ts>[<index>]


       64-bit variant

       Applies when Q = 1.

       SMOV <Xd>, <Vn>.<Ts>[<index>]


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         integer size;
         case Q:imm5 of
              when 'xxxxx1' size = 0;        // SMOV [WX]d, Vn.B
              when 'xxxx10' size = 1;        // SMOV [WX]d, Vn.H
              when '1xx100' size = 2;        // SMOV Xd, Vn.S
              otherwise        UnallocatedEncoding();

         integer idxdsize = if imm5<4> == '1' then 128 else 64;
         integer index = UInt(imm5<4:size+1>);
         integer esize = 8 << size;
         integer datasize = if Q == '1' then 64 else 32;


       Assembler symbols

       <Wd>              Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xd>              Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <Ts>              For the 32-bit variant: is an element size specifier, encoded in the "imm5" field. It can have the
                         following values:

                         B           when imm5 = xxxx1

                         H           when imm5 = xxx10

                         It is RESERVED when imm5 = xxx00.

                         For the 64-bit variant: is an element size specifier, encoded in the "imm5" field. It can have the
                         following values:

                         B           when imm5 = xxxx1

                         H           when imm5 = xxx10

                         S           when imm5 = xx100

                         It is RESERVED when imm5 = xx000.
<index>       For the 32-bit variant: is the element index encoded in the "imm5" field. It can have the following
              values:

              imm5<4:1>  when imm5 = xxxx1

              imm5<4:2>  when imm5 = xxx10

              It is RESERVED when imm5 = xxx00.

              For the 64-bit variant: is the element index encoded in the "imm5" field. It can have the following
              values:

              imm5<4:1>  when imm5 = xxxx1

              imm5<4:2>  when imm5 = xxx10

              imm5<4:3>  when imm5 = xx100

              It is RESERVED when imm5 = xx000.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(idxdsize) operand = V[n];

 X[d] = SignExtend(Elem[operand, index, esize], datasize);


platform: ARM
mnem: SMULL2
description:
       Signed multiply long (vector, by element)       (C7.3.238)




           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11 10 9                5 4             0
            0 Q 0 0 1 1 1 1 size L M                   Rm        1 0 1 0 H 0               Rn               Rd
                  U


       Vector variant

       SMULL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);        Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;
         boolean unsigned = (U == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1
              It is RESERVED when:

              .      size = 00, Q = x.

              .      size = 11, Q = x.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
              the following values:

              0:Rm        when size = 01

              M:Rm        when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              Restricted to V0-V15 when element size <Ts> is H.

<Ts>          Is an element size specifier, encoded in the "size" field. It can have the following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       Is the element index encoded in the "size:L:H:M" field. It can have the following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize)   operand1 = Vpart[n, part];
 bits(idxdsize)   operand2 = V[m];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 bits(2*esize) product;

 element2 = Int(Elem[operand2, index, esize], unsigned);
 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     product = (element1 * element2)<2*esize-1:0>;
     Elem[result, e, 2*esize] = product;

 V[d] = result;


platform: ARM
mnem: SQABS
description:
       Signed saturating absolute value       (C7.3.240)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                   5 4          0
            0 1 0 1 1 1 1 0 size 1 0 0 0 0 0 0 1 1 1 1 0                                  Rn             Rd
                  U


       Scalar variant

       SQABS <V><d>, <V><n>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer elements = 1;

         boolean neg = (U == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                   5 4          0
            0 Q 0 0 1 1 1 0 size 1 0 0 0 0 0 0 1 1 1 1 0                                  Rn             Rd
                  U


       Vector variant

       SQABS <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if size:Q == '110' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         boolean neg = (U == '1');


       Assembler symbols

       <V>               Is a width specifier, encoded in the "size" field. It can have the following values:

                         B           when size = 00

                         H           when size = 01

                         S           when size = 10

                         D           when size = 11

       <d>               Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

       <n>               Is the number of the SIMD&FP source register, encoded in the "Rn" field.
<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              2D          when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 bits(datasize) result;
 integer element;
 boolean sat;

 for e = 0 to elements-1
     element = SInt(Elem[operand, e, esize]);
     if neg then
         element = -element;
     else
         element = Abs(element);
     (Elem[result, e, esize], sat) = SignedSatQ(element, esize);
     if sat then FPSR.QC = '1';

 V[d] = result;


platform: ARM
mnem: SQADD
description:
       Signed saturating add       (C7.3.241)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
            0 1 0 1 1 1 1 0 size 1                   Rm         0 0 0 0 1 1               Rn             Rd
                  U


       Scalar variant

       SQADD <V><d>, <V><n>, <V><m>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer elements = 1;
         boolean unsigned = (U == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
            0 Q 0 0 1 1 1 0 size 1                   Rm         0 0 0 0 1 1               Rn             Rd
                  U


       Vector variant

       SQADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         if size:Q == '110' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;
         boolean unsigned = (U == '1');


       Assembler symbols

       <V>               Is a width specifier, encoded in the "size" field. It can have the following values:

                         B           when size = 00

                         H           when size = 01

                         S           when size = 10

                         D           when size = 11

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <m>               Is the number of the second SIMD&FP source register, encoded in the "Rm" field.
<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              2D          when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 integer sum;
 boolean sat;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     sum = element1 + element2;
     (Elem[result, e, esize], sat) = SatQ(sum, esize, unsigned);
    if sat then FPSR.QC = '1';

 V[d] = result;


platform: ARM
mnem: SQDMLAL
description:
       Signed saturating doubling multiply-add long (by element)       (C7.3.242)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20 19       16 15 14 13 12 11 10 9         5 4    0
            0 1 0 1 1 1 1 1 size L M                Rm       0 0 1 1 H 0            Rn     Rd
                                                               o2


       Scalar variant

       SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);     Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer elements = 1;
         integer part = 0;

         boolean sub_op = (o2 == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20 19       16 15 14 13 12 11 10 9         5 4    0
            0 Q 0 0 1 1 1 1 size L M                Rm       0 0 1 1 H 0            Rn     Rd
                                                               o2


       Vector variant

       SQDMLAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);     Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean sub_op = (o2 == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when:

              .      size = 00, Q = x.

              .      size = 11, Q = x.

<Va>          Is the destination width specifier, encoded in the "size" field. It can have the following values:

              S           when size = 01

              D           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<d>           Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<Vb>          Is the source width specifier, encoded in the "size" field. It can have the following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<n>           Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
              the following values:

              0:Rm        when size = 01
                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         Restricted to V0-V15 when element size <Ts> is H.

       <Ts>              For the scalar variant: is the element width specifier, encoded in the "size" field. It can have the
                         following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         For the vector variant: is an element size specifier, encoded in the "size" field. It can have the
                         following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <index>           For the scalar variant: is the element index, encoded in the "size:L:H:M" field. It can have the
                         following values:

                         H:L:M       when size = 01

                         H:L         when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         For the vector variant: is the element index encoded in the "size:L:H:M" field. It can have the
                         following values:

                         H:L:M       when size = 01

                         H:L         when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(idxdsize)      operand2 = V[m];
         bits(2*datasize) operand3 = V[d];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         bits(2*esize) product;
         integer accum;
         boolean sat1;
         boolean sat2;

         element2 = SInt(Elem[operand2, index, esize]);
         for e = 0 to elements-1
    element1 = SInt(Elem[operand1, e, esize]);
    (product, sat1) = SignedSatQ(2 * element1 * element2, 2*esize);
    if sub_op then
        accum = SInt(Elem[operand3, e, 2*esize]) - SInt(product);
    else
        accum = SInt(Elem[operand3, e, 2*esize]) + SInt(product);
    (Elem[result, e, 2*esize], sat2) = SignedSatQ(accum, 2*esize);
    if sat1 || sat2 then FPSR.QC = '1';

 V[d] = result;


platform: ARM
mnem: SQDMLSL
description:
Signed saturating doubling multiply-subtract long (by element)       (C7.3.244)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20 19        16 15 14 13 12 11 10 9                 5 4          0
  0 1 0 1 1 1 1 1 size L M                 Rm       0 1 1 1 H 0                Rn             Rd
                                                       o2


Scalar variant

SQDMLSL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);    Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;
 integer part = 0;

 boolean sub_op = (o2 == '1');


Vector


  31 30 29 28 27 26 25 24 23 22 21 20 19        16 15 14 13 12 11 10 9                 5 4          0
  0 Q 0 0 1 1 1 1 size L M                 Rm       0 1 1 1 H 0                Rn             Rd
                                                       o2


Vector variant

SQDMLSL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);    Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean sub_op = (o2 == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Va>              Is the destination width specifier, encoded in the "size" field. It can have the following values:

                         S           when size = 01

                         D           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <d>               Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

       <Vb>              Is the source width specifier, encoded in the "size" field. It can have the following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01
              M:Rm        when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              Restricted to V0-V15 when element size <Ts> is H.

<Ts>          For the scalar variant: is the element width specifier, encoded in the "size" field. It can have the
              following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              For the vector variant: is an element size specifier, encoded in the "size" field. It can have the
              following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       For the scalar variant: is the element index, encoded in the "size:L:H:M" field. It can have the
              following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              For the vector variant: is the element index encoded in the "size:L:H:M" field. It can have the
              following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize)   operand1 = Vpart[n, part];
 bits(idxdsize)   operand2 = V[m];
 bits(2*datasize) operand3 = V[d];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 bits(2*esize) product;
 integer accum;
 boolean sat1;
 boolean sat2;

 element2 = SInt(Elem[operand2, index, esize]);
 for e = 0 to elements-1
              element1 = SInt(Elem[operand1, e, esize]);
              (product, sat1) = SignedSatQ(2 * element1 * element2, 2*esize);
              if sub_op then
                   accum = SInt(Elem[operand3, e, 2*esize]) - SInt(product);
              else
                   accum = SInt(Elem[operand3, e, 2*esize]) + SInt(product);
              (Elem[result, e, 2*esize], sat2) = SignedSatQ(accum, 2*esize);
              if sat1 || sat2 then FPSR.QC = '1';

         V[d] = result;


platform: ARM
mnem: SQDMULH
description:
       Signed saturating doubling multiply returning high half (by element)       (C7.3.246)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20 19       16 15 14 13 12 11 10 9         5 4    0
            0 1 0 1 1 1 1 1 size L M                Rm       1 1 0 0 H 0            Rn     Rd
                                                                      op


       Scalar variant

       SQDMULH <V><d>, <V><n>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);     Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer elements = 1;

         boolean round = (op == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20 19       16 15 14 13 12 11 10 9         5 4    0
            0 Q 0 0 1 1 1 1 size L M                Rm       1 1 0 0 H 0            Rn     Rd
                                                                      op


       Vector variant

       SQDMULH <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]


       Decode for this encoding

         integer idxdsize = if H == '1' then 128 else 64;
         integer index;
         bit Rmhi;
         case size of
              when '01' index = UInt(H:L:M); Rmhi = '0';
              when '10' index = UInt(H:L);     Rmhi = M;
              otherwise UnallocatedEncoding();

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rmhi:Rm);

         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean round = (op == '1');


Assembler symbols

<V>           Is a width specifier, encoded in the "size" field. It can have the following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<d>           Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<n>           Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when:

              .      size = 00, Q = x.

              .      size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
              the following values:

              0:Rm        when size = 01

              M:Rm        when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              Restricted to V0-V15 when element size <Ts> is H.

<Ts>          For the scalar variant: is the element width specifier, encoded in the "size" field. It can have the
              following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              For the vector variant: is an element size specifier, encoded in the "size" field. It can have the
              following values:

              H           when size = 01

              S           when size = 10
                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <index>           For the scalar variant: is the element index, encoded in the "size:L:H:M" field. It can have the
                         following values:

                         H:L:M       when size = 01

                         H:L         when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         For the vector variant: is the element index encoded in the "size:L:H:M" field. It can have the
                         following values:

                         H:L:M       when size = 01

                         H:L         when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand1 = V[n];
         bits(idxdsize) operand2 = V[m];
         bits(datasize) result;
         integer round_const = if round then 1 << (esize - 1) else 0;
         integer element1;
         integer element2;
         integer product;
         boolean sat;

         element2 = SInt(Elem[operand2, index, esize]);
         for e = 0 to elements-1
              element1 = SInt(Elem[operand1, e, esize]);
              product = (2 * element1 * element2) + round_const;
              // The following only saturates if element1 and element2 equal -(2^(esize-1))
              (Elem[result, e, esize], sat) = SignedSatQ(product >> esize, esize);
              if sat then FPSR.QC = '1';

         V[d] = result;


platform: ARM
mnem: SQDMULL
description:
Signed saturating doubling multiply long (by element)       (C7.3.248)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20 19        16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 1 size L M                 Rm       1 0 1 1 H 0               Rn             Rd




Scalar variant

SQDMULL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);     Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;
 integer part = 0;


Vector


  31 30 29 28 27 26 25 24 23 22 21 20 19        16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 1 size L M                 Rm       1 0 1 1 H 0               Rn             Rd




Vector variant

SQDMULL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);     Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;
       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Ta>              Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                         4S          when size = 01

                         2D          when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Va>              Is the destination width specifier, encoded in the "size" field. It can have the following values:

                         S           when size = 01

                         D           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <d>               Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

       <Vb>              Is the source width specifier, encoded in the "size" field. It can have the following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01

                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.
              .      size = 11.

              Restricted to V0-V15 when element size <Ts> is H.

<Ts>          For the scalar variant: is the element width specifier, encoded in the "size" field. It can have the
              following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              For the vector variant: is an element size specifier, encoded in the "size" field. It can have the
              following values:

              H           when size = 01

              S           when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       For the scalar variant: is the element index, encoded in the "size:L:H:M" field. It can have the
              following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              For the vector variant: is the element index encoded in the "size:L:H:M" field. It can have the
              following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();

 bits(datasize)   operand1 = Vpart[n, part];
 bits(idxdsize)   operand2 = V[m];
 bits(2*datasize) result;
 integer element1;
 integer element2;
 bits(2*esize) product;
 boolean sat;

 element2 = SInt(Elem[operand2, index, esize]);
 for e = 0 to elements-1
     element1 = SInt(Elem[operand1, e, esize]);
     (product, sat) = SignedSatQ(2 * element1 * element2, 2*esize);
     Elem[result, e, 2*esize] = product;
     if sat then FPSR.QC = '1';

 V[d] = result;


platform: ARM
mnem: SQNEG
description:
Signed saturating negate       (C7.3.250)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                  5 4          0
  0 1 1 1 1 1 1 0 size 1 0 0 0 0 0 0 1 1 1 1 0                                  Rn             Rd
        U


Scalar variant

SQNEG <V><d>, <V><n>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;

 boolean neg = (U == '1');


Vector


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                  5 4          0
  0 Q 1 0 1 1 1 0 size 1 0 0 0 0 0 0 1 1 1 1 0                                  Rn             Rd
        U


Vector variant

SQNEG <Vd>.<T>, <Vn>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size:Q == '110' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean neg = (U == '1');


Assembler symbols

<V>            Is a width specifier, encoded in the "size" field. It can have the following values:

               B           when size = 00

               H           when size = 01

               S           when size = 10

               D           when size = 11

<d>            Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<n>            Is the number of the SIMD&FP source register, encoded in the "Rn" field.
       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         2D          when size = 11, Q = 1

                         It is RESERVED when size = 11, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand = V[n];
         bits(datasize) result;
         integer element;
         boolean sat;

         for e = 0 to elements-1
              element = SInt(Elem[operand, e, esize]);
              if neg then
                   element = -element;
              else
                   element = Abs(element);
              (Elem[result, e, esize], sat) = SignedSatQ(element, esize);
              if sat then FPSR.QC = '1';

         V[d] = result;


platform: ARM
mnem: SQRDMULH
description:
Signed saturating rounding doubling multiply returning high half (by element)       (C7.3.251)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20 19        16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 1 size L M                Rm        1 1 0 1 H 0               Rn             Rd
                                                            op


Scalar variant

SQRDMULH <V><d>, <V><n>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);    Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;

 boolean round = (op == '1');


Vector


  31 30 29 28 27 26 25 24 23 22 21 20 19        16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 1 size L M                Rm        1 1 0 1 H 0               Rn             Rd
                                                            op


Vector variant

SQRDMULH <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);    Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         boolean round = (op == '1');


       Assembler symbols

       <V>               Is a width specifier, encoded in the "size" field. It can have the following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <d>               Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01

                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         Restricted to V0-V15 when element size <Ts> is H.

       <Ts>              For the scalar variant: is the element width specifier, encoded in the "size" field. It can have the
                         following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         For the vector variant: is an element size specifier, encoded in the "size" field. It can have the
                         following values:

                         H           when size = 01

                         S           when size = 10
              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<index>       For the scalar variant: is the element index, encoded in the "size:L:H:M" field. It can have the
              following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

              For the vector variant: is the element index encoded in the "size:L:H:M" field. It can have the
              following values:

              H:L:M       when size = 01

              H:L         when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(idxdsize) operand2 = V[m];
 bits(datasize) result;
 integer round_const = if round then 1 << (esize - 1) else 0;
 integer element1;
 integer element2;
 integer product;
 boolean sat;

 element2 = SInt(Elem[operand2, index, esize]);
 for e = 0 to elements-1
     element1 = SInt(Elem[operand1, e, esize]);
     product = (2 * element1 * element2) + round_const;
     // The following only saturates if element1 and element2 equal -(2^(esize-1))
     (Elem[result, e, esize], sat) = SignedSatQ(product >> esize, esize);
     if sat then FPSR.QC = '1';

 V[d] = result;


platform: ARM
mnem: SQRSHL
description:
       Signed saturating rounding shift left (register)       (C7.3.253)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
            0 1 0 1 1 1 1 0 size 1                  Rm          0 1 0 1 1 1               Rn             Rd
                  U                                                       R S


       Scalar variant

       SQRSHL <V><d>, <V><n>, <V><m>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer elements = 1;
         boolean unsigned = (U == '1');
         boolean rounding = (R == '1');
         boolean saturating = (S == '1');
         if S == '0' && size != '11' then ReservedValue();


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
            0 Q 0 0 1 1 1 0 size 1                  Rm          0 1 0 1 1 1               Rn             Rd
                  U                                                       R S


       Vector variant

       SQRSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         if size:Q == '110' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;
         boolean unsigned = (U == '1');
         boolean rounding = (R == '1');
         boolean saturating = (S == '1');


       Assembler symbols

       <V>               Is a width specifier, encoded in the "size" field. It can have the following values:

                         B           when size = 00

                         H           when size = 01

                         S           when size = 10

                         D           when size = 11

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.
<n>           Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<m>           Is the number of the second SIMD&FP source register, encoded in the "Rm" field.

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              2D          when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;

 integer round_const = 0;
 integer shift;
 integer element;
 boolean sat;

 for e = 0 to elements-1
     shift = SInt(Elem[operand2, e, esize]<7:0>);
     if rounding then
         round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift
     element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift;
     if saturating then
         (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned);
         if sat then FPSR.QC = '1';
     else
         Elem[result, e, esize] = element<esize-1:0>;

 V[d] = result;


platform: ARM
mnem: SQRSHRN
description:
       Signed saturating rounded shift right narrow (immediate)       (C7.3.254)


       Scalar


           31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9        5 4    0
            0 1 0 1 1 1 1 1 0            !=0000      immb     1 0 0 1 1 1           Rn     Rd
                  U                       immh                            op


       Scalar variant

       SQRSHRN <Vb><d>, <Va><n>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then ReservedValue();
         if immh<3> == '1' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = esize;
         integer elements = 1;
         integer part = 0;

         integer shift = (2 * esize) - UInt(immh:immb);
         boolean round = (op == '1');
         boolean unsigned = (U == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9        5 4    0
            0 Q 0 0 1 1 1 1 0            !=0000      immb     1 0 0 1 1 1           Rn     Rd
                  U                       immh                            op


       Vector variant

       SQRSHRN{2} <Vd>.<Tb>, <Vn>.<Ta>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then SEE "Advanced SIMD modified immediate";
         if immh<3> == '1' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         integer shift = (2 * esize) - UInt(immh:immb);
         boolean round = (op == '1');
         boolean unsigned = (U == '1');
Assembler symbols

2         Is the second and upper half specifier. If present it causes the operation to be performed on the upper
          64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
          the following values:

          [absent]    when Q = 0

          [present]   when Q = 1

<Vd>      Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Tb>      Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

          8B          when immh = 0001, Q = 0

          16B         when immh = 0001, Q = 1

          4H          when immh = 001x, Q = 0

          8H          when immh = 001x, Q = 1

          2S          when immh = 01xx, Q = 0

          4S          when immh = 01xx, Q = 1

          See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

          It is RESERVED when immh = 1xxx, Q = x.

<Vn>      Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Ta>      Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

          8H          when immh = 0001

          4S          when immh = 001x

          2D          when immh = 01xx

          See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

          It is RESERVED when immh = 1xxx.

<Vb>      Is the destination width specifier, encoded in the "immh" field. It can have the following values:

          B           when immh = 0001

          H           when immh = 001x

          S           when immh = 01xx

          It is RESERVED when:

          .      immh = 0000.

          .      immh = 1xxx.

<d>       Is the number of the SIMD&FP destination register, in the "Rd" field.

<Va>      Is the source width specifier, encoded in the "immh" field. It can have the following values:

          H           when immh = 0001

          S           when immh = 001x

          D           when immh = 01xx

          It is RESERVED when:

          .      immh = 0000.

          .      immh = 1xxx.

<n>       Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<shift>   For the scalar variant: is the right shift amount, in the range 1 to the destination operand width in
          bits, encoded in the "immh:immb" field. It can have the following values:

          (16-UInt(immh:immb))when immh = 0001
                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

                         For the vector variant: is the right shift amount, in the range 1 to the destination element width in
                         bits, encoded in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when immh = 1xxx.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize*2) operand = V[n];
         bits(datasize) result;
         integer round_const = if round then (1 << (shift - 1)) else 0;
         integer element;
         boolean sat;

         for e = 0 to elements-1
              element = (Int(Elem[operand, e, 2*esize], unsigned) + round_const) >> shift;
              (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned);
              if sat then FPSR.QC = '1';

         Vpart[d, part] = result;


platform: ARM
mnem: SQRSHRUN
description:
Signed saturating rounded shift right unsigned narrow (immediate)       (C7.3.255)


Scalar


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4             0
  0 1 1 1 1 1 1 1 0              !=0000      immb      1 0 0 0 1 1               Rn               Rd
                                  immh                               op


Scalar variant

SQRSHRUN <Vb><d>, <Va><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then ReservedValue();
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = esize;
 integer elements = 1;
 integer part = 0;

 integer shift = (2 * esize) - UInt(immh:immb);
 boolean round = (op == '1');


Vector


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 1 0              !=0000      immb      1 0 0 0 1 1               Rn               Rd
                                  immh                               op


Vector variant

SQRSHRUN{2} <Vd>.<Tb>, <Vn>.<Ta>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 integer shift = (2 * esize) - UInt(immh:immb);
 boolean round = (op == '1');


Assembler symbols

2              Is the second and upper half specifier. If present it causes the operation to be performed on the upper
               64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
               the following values:

               [absent]    when Q = 0
                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Tb>              Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B          when immh = 0001, Q = 0

                         16B         when immh = 0001, Q = 1

                         4H          when immh = 001x, Q = 0

                         8H          when immh = 001x, Q = 1

                         2S          when immh = 01xx, Q = 0

                         4S          when immh = 01xx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = x.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <Ta>              Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

                         8H          when immh = 0001

                         4S          when immh = 001x

                         2D          when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when immh = 1xxx.

       <Vb>              Is the destination width specifier, encoded in the "immh" field. It can have the following values:

                         B           when immh = 0001

                         H           when immh = 001x

                         S           when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <Va>              Is the source width specifier, encoded in the "immh" field. It can have the following values:

                         H           when immh = 0001

                         S           when immh = 001x

                         D           when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to the destination operand width in
                         bits, encoded in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.
              For the vector variant: is the right shift amount, in the range 1 to the destination element width in
              bits, encoded in the "immh:immb" field. It can have the following values:

              (16-UInt(immh:immb))when immh = 0001

              (32-UInt(immh:immb))when immh = 001x

              (64-UInt(immh:immb))when immh = 01xx

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

              It is RESERVED when immh = 1xxx.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize*2) operand = V[n];
 bits(datasize) result;
 integer round_const = if round then (1 << (shift - 1)) else 0;
 integer element;
 boolean sat;

 for e = 0 to elements-1
     element = (SInt(Elem[operand, e, 2*esize]) + round_const) >> shift;
     (Elem[result, e, esize], sat) = UnsignedSatQ(element, esize);
    if sat then FPSR.QC = '1';

 Vpart[d, part] = result;


platform: ARM
mnem: SQSHL
description:
       Signed saturating shift left (immediate)       (C7.3.256)


       Scalar


           31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9        5 4    0
            0 1 0 1 1 1 1 1 0            !=0000      immb     0 1 1 1 0 1           Rn     Rd
                  U                       immh                        op


       Scalar variant

       SQSHL <V><d>, <V><n>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = esize;
         integer elements = 1;

         integer shift = UInt(immh:immb) - esize;

         boolean src_unsigned;
         boolean dst_unsigned;
         case op:U of
              when '00' UnallocatedEncoding();
              when '01' src_unsigned = FALSE; dst_unsigned = TRUE;
              when '10' src_unsigned = FALSE; dst_unsigned = FALSE;
              when '11' src_unsigned = TRUE;    dst_unsigned = TRUE;


       Vector


           31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9        5 4    0
            0 Q 0 0 1 1 1 1 0            !=0000      immb     0 1 1 1 0 1           Rn     Rd
                  U                       immh                        op


       Vector variant

       SQSHL <Vd>.<T>, <Vn>.<T>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then SEE "Advanced SIMD modified immediate";
         if immh<3>:Q == '10' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;

         integer shift = UInt(immh:immb) - esize;

         boolean src_unsigned;
         boolean dst_unsigned;
         case op:U of
              when '00' UnallocatedEncoding();
    when '01' src_unsigned = FALSE; dst_unsigned = TRUE;
    when '10' src_unsigned = FALSE; dst_unsigned = FALSE;
    when '11' src_unsigned = TRUE;      dst_unsigned = TRUE;


Assembler symbols

<V>           Is a width specifier, encoded in the "immh" field. It can have the following values:

              B           when immh = 0001

              H           when immh = 001x

              S           when immh = 01xx

              D           when immh = 1xxx

              It is RESERVED when immh = 0000.

<d>           Is the number of the SIMD&FP destination register, in the "Rd" field.

<n>           Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

              8B          when immh = 0001, Q = 0

              16B         when immh = 0001, Q = 1

              4H          when immh = 001x, Q = 0

              8H          when immh = 001x, Q = 1

              2S          when immh = 01xx, Q = 0

              4S          when immh = 01xx, Q = 1

              2D          when immh = 1xxx, Q = 1

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

              It is RESERVED when immh = 1xxx, Q = 0.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<shift>       For the scalar variant: is the left shift amount, in the range 0 to the operand width in bits minus 1,
              encoded in the "immh:immb" field. It can have the following values:

              (UInt(immh:immb)-8)when immh = 0001

              (UInt(immh:immb)-16)when immh = 001x

              (UInt(immh:immb)-32)when immh = 01xx

              (UInt(immh:immb)-64)when immh = 1xxx

              It is RESERVED when immh = 0000.

              For the vector variant: is the left shift amount, in the range 0 to the element width in bits minus 1,
              encoded in the "immh:immb" field. It can have the following values:

              (UInt(immh:immb)-8)when immh = 0001

              (UInt(immh:immb)-16)when immh = 001x

              (UInt(immh:immb)-32)when immh = 01xx

              (UInt(immh:immb)-64)when immh = 1xxx

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand  = V[n];
 bits(datasize) result;
         integer element;
         boolean sat;

         for e = 0 to elements-1
              element = Int(Elem[operand, e, esize], src_unsigned) << shift;
              (Elem[result, e, esize], sat) = SatQ(element, esize, dst_unsigned);
              if sat then FPSR.QC = '1';

         V[d] = result;


platform: ARM
mnem: SQSHLU
description:
Signed saturating shift left unsigned (immediate)       (C7.3.258)


Scalar


  31 30 29 28 27 26 25 24 23 22         19 18     16 15 14 13 12 11 10 9                5 4          0
  0 1 1 1 1 1 1 1 0               !=0000     immb      0 1 1 0 0 1              Rn             Rd
        U                          immh                       op


Scalar variant

SQSHLU <V><d>, <V><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = esize;
 integer elements = 1;

 integer shift = UInt(immh:immb) - esize;

 boolean src_unsigned;
 boolean dst_unsigned;
 case op:U of
     when '00' UnallocatedEncoding();
     when '01' src_unsigned = FALSE; dst_unsigned = TRUE;
     when '10' src_unsigned = FALSE; dst_unsigned = FALSE;
     when '11' src_unsigned = TRUE;     dst_unsigned = TRUE;


Vector


  31 30 29 28 27 26 25 24 23 22         19 18     16 15 14 13 12 11 10 9                5 4          0
  0 Q 1 0 1 1 1 1 0               !=0000     immb      0 1 1 0 0 1              Rn             Rd
        U                          immh                       op


Vector variant

SQSHLU <Vd>.<T>, <Vn>.<T>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer shift = UInt(immh:immb) - esize;

 boolean src_unsigned;
 boolean dst_unsigned;
 case op:U of
     when '00' UnallocatedEncoding();
              when '01' src_unsigned = FALSE; dst_unsigned = TRUE;
              when '10' src_unsigned = FALSE; dst_unsigned = FALSE;
              when '11' src_unsigned = TRUE;       dst_unsigned = TRUE;


       Assembler symbols

       <V>               Is a width specifier, encoded in the "immh" field. It can have the following values:

                         B           when immh = 0001

                         H           when immh = 001x

                         S           when immh = 01xx

                         D           when immh = 1xxx

                         It is RESERVED when immh = 0000.

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B          when immh = 0001, Q = 0

                         16B         when immh = 0001, Q = 1

                         4H          when immh = 001x, Q = 0

                         8H          when immh = 001x, Q = 1

                         2S          when immh = 01xx, Q = 0

                         4S          when immh = 01xx, Q = 1

                         2D          when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the left shift amount, in the range 0 to the operand width in bits minus 1,
                         encoded in the "immh:immb" field. It can have the following values:

                         (UInt(immh:immb)-8)when immh = 0001

                         (UInt(immh:immb)-16)when immh = 001x

                         (UInt(immh:immb)-32)when immh = 01xx

                         (UInt(immh:immb)-64)when immh = 1xxx

                         It is RESERVED when immh = 0000.

                         For the vector variant: is the left shift amount, in the range 0 to the element width in bits minus 1,
                         encoded in the "immh:immb" field. It can have the following values:

                         (UInt(immh:immb)-8)when immh = 0001

                         (UInt(immh:immb)-16)when immh = 001x

                         (UInt(immh:immb)-32)when immh = 01xx

                         (UInt(immh:immb)-64)when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand     = V[n];
         bits(datasize) result;
 integer element;
 boolean sat;

 for e = 0 to elements-1
     element = Int(Elem[operand, e, esize], src_unsigned) << shift;
     (Elem[result, e, esize], sat) = SatQ(element, esize, dst_unsigned);
    if sat then FPSR.QC = '1';

 V[d] = result;


platform: ARM
mnem: SQSHRN
description:
       Signed saturating shift right narrow (immediate)       (C7.3.259)


       Scalar


           31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9        5 4    0
            0 1 0 1 1 1 1 1 0            !=0000      immb     1 0 0 1 0 1           Rn     Rd
                  U                       immh                            op


       Scalar variant

       SQSHRN <Vb><d>, <Va><n>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then ReservedValue();
         if immh<3> == '1' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = esize;
         integer elements = 1;
         integer part = 0;

         integer shift = (2 * esize) - UInt(immh:immb);
         boolean round = (op == '1');
         boolean unsigned = (U == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9        5 4    0
            0 Q 0 0 1 1 1 1 0            !=0000      immb     1 0 0 1 0 1           Rn     Rd
                  U                       immh                            op


       Vector variant

       SQSHRN{2} <Vd>.<Tb>, <Vn>.<Ta>, #<shift>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if immh == '0000' then SEE "Advanced SIMD modified immediate";
         if immh<3> == '1' then ReservedValue();
         integer esize = 8 << HighestSetBit(immh);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         integer shift = (2 * esize) - UInt(immh:immb);
         boolean round = (op == '1');
         boolean unsigned = (U == '1');
Assembler symbols

2         Is the second and upper half specifier. If present it causes the operation to be performed on the upper
          64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
          the following values:

          [absent]    when Q = 0

          [present]   when Q = 1

<Vd>      Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Tb>      Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

          8B          when immh = 0001, Q = 0

          16B         when immh = 0001, Q = 1

          4H          when immh = 001x, Q = 0

          8H          when immh = 001x, Q = 1

          2S          when immh = 01xx, Q = 0

          4S          when immh = 01xx, Q = 1

          See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

          It is RESERVED when immh = 1xxx, Q = x.

<Vn>      Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Ta>      Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

          8H          when immh = 0001

          4S          when immh = 001x

          2D          when immh = 01xx

          See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

          It is RESERVED when immh = 1xxx.

<Vb>      Is the destination width specifier, encoded in the "immh" field. It can have the following values:

          B           when immh = 0001

          H           when immh = 001x

          S           when immh = 01xx

          It is RESERVED when:

          .      immh = 0000.

          .      immh = 1xxx.

<d>       Is the number of the SIMD&FP destination register, in the "Rd" field.

<Va>      Is the source width specifier, encoded in the "immh" field. It can have the following values:

          H           when immh = 0001

          S           when immh = 001x

          D           when immh = 01xx

          It is RESERVED when:

          .      immh = 0000.

          .      immh = 1xxx.

<n>       Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<shift>   For the scalar variant: is the right shift amount, in the range 1 to the destination operand width in
          bits, encoded in the "immh:immb" field. It can have the following values:

          (16-UInt(immh:immb))when immh = 0001
                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

                         For the vector variant: is the right shift amount, in the range 1 to the destination element width in
                         bits, encoded in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when immh = 1xxx.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize*2) operand = V[n];
         bits(datasize) result;
         integer round_const = if round then (1 << (shift - 1)) else 0;
         integer element;
         boolean sat;

         for e = 0 to elements-1
              element = (Int(Elem[operand, e, 2*esize], unsigned) + round_const) >> shift;
              (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned);
              if sat then FPSR.QC = '1';

         Vpart[d, part] = result;


platform: ARM
mnem: SQSHRUN
description:
Signed saturating shift right unsigned narrow (immediate)       (C7.3.260)


Scalar


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4             0
  0 1 1 1 1 1 1 1 0               !=0000     immb      1 0 0 0 0 1               Rn               Rd
                                   immh                              op


Scalar variant

SQSHRUN <Vb><d>, <Va><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then ReservedValue();
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = esize;
 integer elements = 1;
 integer part = 0;

 integer shift = (2 * esize) - UInt(immh:immb);
 boolean round = (op == '1');


Vector


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 1 0               !=0000     immb      1 0 0 0 0 1               Rn               Rd
                                   immh                              op


Vector variant

SQSHRUN{2} <Vd>.<Tb>, <Vn>.<Ta>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 integer shift = (2 * esize) - UInt(immh:immb);
 boolean round = (op == '1');


Assembler symbols

2              Is the second and upper half specifier. If present it causes the operation to be performed on the upper
               64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
               the following values:

               [absent]     when Q = 0
                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Tb>              Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B          when immh = 0001, Q = 0

                         16B         when immh = 0001, Q = 1

                         4H          when immh = 001x, Q = 0

                         8H          when immh = 001x, Q = 1

                         2S          when immh = 01xx, Q = 0

                         4S          when immh = 01xx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = x.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <Ta>              Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

                         8H          when immh = 0001

                         4S          when immh = 001x

                         2D          when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when immh = 1xxx.

       <Vb>              Is the destination width specifier, encoded in the "immh" field. It can have the following values:

                         B           when immh = 0001

                         H           when immh = 001x

                         S           when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <Va>              Is the source width specifier, encoded in the "immh" field. It can have the following values:

                         H           when immh = 0001

                         S           when immh = 001x

                         D           when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to the destination operand width in
                         bits, encoded in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.
              For the vector variant: is the right shift amount, in the range 1 to the destination element width in
              bits, encoded in the "immh:immb" field. It can have the following values:

              (16-UInt(immh:immb))when immh = 0001

              (32-UInt(immh:immb))when immh = 001x

              (64-UInt(immh:immb))when immh = 01xx

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

              It is RESERVED when immh = 1xxx.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize*2) operand = V[n];
 bits(datasize) result;
 integer round_const = if round then (1 << (shift - 1)) else 0;
 integer element;
 boolean sat;

 for e = 0 to elements-1
     element = (SInt(Elem[operand, e, 2*esize]) + round_const) >> shift;
     (Elem[result, e, esize], sat) = UnsignedSatQ(element, esize);
    if sat then FPSR.QC = '1';

 Vpart[d, part] = result;


platform: ARM
mnem: SQSUB
description:
       Signed saturating subtract       (C7.3.261)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
            0 1 0 1 1 1 1 0 size 1                   Rm         0 0 1 0 1 1               Rn             Rd
                  U


       Scalar variant

       SQSUB <V><d>, <V><n>, <V><m>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer elements = 1;
         boolean unsigned = (U == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
            0 Q 0 0 1 1 1 0 size 1                   Rm         0 0 1 0 1 1               Rn             Rd
                  U


       Vector variant

       SQSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         if size:Q == '110' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = if Q == '1' then 128 else 64;
         integer elements = datasize DIV esize;
         boolean unsigned = (U == '1');


       Assembler symbols

       <V>               Is a width specifier, encoded in the "size" field. It can have the following values:

                         B           when size = 00

                         H           when size = 01

                         S           when size = 10

                         D           when size = 11

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <m>               Is the number of the second SIMD&FP source register, encoded in the "Rm" field.
<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              2D          when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 integer diff;
 boolean sat;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     diff = element1 - element2;
     (Elem[result, e, esize], sat) = SatQ(diff, esize, unsigned);
    if sat then FPSR.QC = '1';

 V[d] = result;


platform: ARM
mnem: SQXTN
description:
       Signed saturating extract narrow       (C7.3.262)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                    5 4             0
            0 1 0 1 1 1 1 0 size 1 0 0 0 0 1 0 1 0 0 1 0                                   Rn               Rd
                  U


       Scalar variant

       SQXTN <Vb><d>, <Va><n>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer part = 0;
         integer elements = 1;

         boolean unsigned = (U == '1');


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                    5 4             0
            0 Q 0 0 1 1 1 0 size 1 0 0 0 0 1 0 1 0 0 1 0                                   Rn               Rd
                  U


       Vector variant

       SQXTN{2} <Vd>.<Tb>, <Vn>.<Ta>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;

         boolean unsigned = (U == '1');


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.
<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when size = 11.

<Vb>          Is the destination width specifier, encoded in the "size" field. It can have the following values:

              B           when size = 00

              H           when size = 01

              S           when size = 10

              It is RESERVED when size = 11.

<d>           Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<Va>          Is the source width specifier, encoded in the "size" field. It can have the following values:

              H           when size = 00

              S           when size = 01

              D           when size = 10

              It is RESERVED when size = 11.

<n>           Is the number of the SIMD&FP source register, encoded in the "Rn" field.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(2*datasize) operand = V[n];
 bits(datasize) result;
 bits(2*esize) element;
 boolean sat;

 for e = 0 to elements-1
     element = Elem[operand, e, 2*esize];
     (Elem[result, e, esize], sat) = SatQ(Int(element, unsigned), esize, unsigned);
     if sat then FPSR.QC = '1';

 Vpart[d, part] = result;


platform: ARM
mnem: SQXTUN
description:
       Signed saturating extract unsigned narrow       (C7.3.263)


       Scalar


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                    5 4             0
            0 1 1 1 1 1 1 0 size 1 0 0 0 0 1 0 0 1 0 1 0                                   Rn               Rd




       Scalar variant

       SQXTUN <Vb><d>, <Va><n>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = esize;
         integer part = 0;
         integer elements = 1;


       Vector


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                    5 4             0
            0 Q 1 0 1 1 1 0 size 1 0 0 0 0 1 0 0 1 0 1 0                                   Rn               Rd




       Vector variant

       SQXTUN{2} <Vd>.<Tb>, <Vn>.<Ta>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);

         if size == '11' then ReservedValue();
         integer esize = 8 << UInt(size);
         integer datasize = 64;
         integer part = UInt(Q);
         integer elements = datasize DIV esize;


       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Tb>              Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0
              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when size = 11.

<Vb>          Is the destination width specifier, encoded in the "size" field. It can have the following values:

              B           when size = 00

              H           when size = 01

              S           when size = 10

              It is RESERVED when size = 11.

<d>           Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<Va>          Is the source width specifier, encoded in the "size" field. It can have the following values:

              H           when size = 00

              S           when size = 01

              D           when size = 10

              It is RESERVED when size = 11.

<n>           Is the number of the SIMD&FP source register, encoded in the "Rn" field.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(2*datasize) operand = V[n];
 bits(datasize) result;
 bits(2*esize) element;
 boolean sat;

 for e = 0 to elements-1
     element = Elem[operand, e, 2*esize];
     (Elem[result, e, esize], sat) = UnsignedSatQ(SInt(element), esize);
    if sat then FPSR.QC = '1';

 Vpart[d, part] = result;


platform: ARM
mnem: SRHADD
description:
Signed rounding halving add       (C7.3.264)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
     0 Q 0 0 1 1 1 0 size 1                  Rm         0 0 0 1 0 1               Rn              Rd
           U


Three registers of the same type variant

SRHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if size == '11' then ReservedValue();
  integer esize = 8 << UInt(size);
  integer datasize = if Q == '1' then 128 else 64;
  integer elements = datasize DIV esize;

  boolean unsigned = (U == '1');


Assembler symbols

<Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                  8B          when size = 00, Q = 0

                  16B         when size = 00, Q = 1

                  4H          when size = 01, Q = 0

                  8H          when size = 01, Q = 1

                  2S          when size = 10, Q = 0

                  4S          when size = 10, Q = 1

                  It is RESERVED when size = 11, Q = x.

<Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand1 = V[n];
  bits(datasize) operand2 = V[m];
  bits(datasize) result;
  integer element1;
  integer element2;

  for e = 0 to elements-1
       element1 = Int(Elem[operand1, e, esize], unsigned);
       element2 = Int(Elem[operand2, e, esize], unsigned);
       Elem[result, e, esize] = (element1 + element2 + 1)<esize:1>;

  V[d] = result;


platform: ARM
mnem: SRI
description:
Shift right and insert (immediate)       (C7.3.265)


Scalar


  31 30 29 28 27 26 25 24 23 22           19 18    16 15 14 13 12 11 10 9                5 4          0
  0 1 1 1 1 1 1 1 0                !=0000     immb      0 1 0 0 0 1              Rn             Rd
                                    immh


Scalar variant

SRI <V><d>, <V><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh<3> != '1' then ReservedValue();
 integer esize = 8 << 3;
 integer datasize = esize;
 integer elements = 1;

 integer shift = (esize * 2) - UInt(immh:immb);


Vector


  31 30 29 28 27 26 25 24 23 22           19 18    16 15 14 13 12 11 10 9                5 4          0
  0 Q 1 0 1 1 1 1 0                !=0000     immb      0 1 0 0 0 1              Rn             Rd
                                    immh


Vector variant

SRI <Vd>.<T>, <Vn>.<T>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer shift = (esize * 2) - UInt(immh:immb);


Assembler symbols

<V>              Is a width specifier, encoded in the "immh" field. It can have the following values:

                 D           when immh = 1xxx

                 It is RESERVED when immh = 0xxx.

<d>              Is the number of the SIMD&FP destination register, in the "Rd" field.

<n>              Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<Vd>             Is the name of the SIMD&FP destination register, encoded in the "Rd" field.
       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B           when immh = 0001, Q = 0

                         16B          when immh = 0001, Q = 1

                         4H           when immh = 001x, Q = 0

                         8H           when immh = 001x, Q = 1

                         2S           when immh = 01xx, Q = 0

                         4S           when immh = 01xx, Q = 1

                         2D           when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to 64, encoded in the "immh:immb"
                         field. It can have the following values:

                         (128-UInt(immh:immb))when immh = 1xxx

                         It is RESERVED when immh = 0xxx.

                         For the vector variant: is the right shift amount, in the range 1 to the element width in bits, encoded
                         in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         (128-UInt(immh:immb))when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand      = V[n];
         bits(datasize) operand2 = V[d];
         bits(datasize) result;
         bits(esize) mask = LSR(Ones(esize), shift);
         bits(esize) shifted;

         for e = 0 to elements-1
              shifted = LSR(Elem[operand, e, esize], shift);
              Elem[result, e, esize] = (Elem[operand2, e, esize] AND NOT(mask)) OR shifted;
         V[d] = result;


platform: ARM
mnem: SRSHL
description:
Signed rounding shift left (register)       (C7.3.266)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 0 size 1                  Rm          0 1 0 1 0 1              Rn             Rd
        U                                                      R S


Scalar variant

SRSHL <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;
 boolean unsigned = (U == '1');
 boolean rounding = (R == '1');
 boolean saturating = (S == '1');
 if S == '0' && size != '11' then ReservedValue();


Vector


  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 0 size 1                  Rm          0 1 0 1 0 1              Rn             Rd
        U                                                      R S


Vector variant

SRSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size:Q == '110' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;
 boolean unsigned = (U == '1');
 boolean rounding = (R == '1');
 boolean saturating = (S == '1');


Assembler symbols

<V>           Is a width specifier, encoded in the "size" field. It can have the following values:

              D             when size = 11

              It is RESERVED when:

              .       size = 0x.

              .       size = 10.

<d>           Is the number of the SIMD&FP destination register, in the "Rd" field.
       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <m>               Is the number of the second SIMD&FP source register, encoded in the "Rm" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         2D          when size = 11, Q = 1

                         It is RESERVED when size = 11, Q = 0.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand1 = V[n];
         bits(datasize) operand2 = V[m];
         bits(datasize) result;

         integer round_const = 0;
         integer shift;
         integer element;
         boolean sat;

         for e = 0 to elements-1
              shift = SInt(Elem[operand2, e, esize]<7:0>);
              if rounding then
                   round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift
              element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift;
              if saturating then
                   (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned);
                   if sat then FPSR.QC = '1';
              else
                   Elem[result, e, esize] = element<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SRSHR
description:
Signed rounding shift right (immediate)       (C7.3.267)


Scalar


  31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 1 0             !=0000     immb      0 0 1 0 0 1              Rn             Rd
        U                        immh                    o1 o0


Scalar variant

SRSHR <V><d>, <V><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh<3> != '1' then ReservedValue();
 integer esize = 8 << 3;
 integer datasize = esize;
 integer elements = 1;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Vector


  31 30 29 28 27 26 25 24 23 22        19 18    16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 1 0             !=0000     immb      0 0 1 0 0 1              Rn             Rd
        U                        immh                    o1 o0


Vector variant

SRSHR <Vd>.<T>, <Vn>.<T>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Assembler symbols

<V>           Is a width specifier, encoded in the "immh" field. It can have the following values:

              D            when immh = 1xxx

              It is RESERVED when immh = 0xxx.
       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B           when immh = 0001, Q = 0

                         16B          when immh = 0001, Q = 1

                         4H           when immh = 001x, Q = 0

                         8H           when immh = 001x, Q = 1

                         2S           when immh = 01xx, Q = 0

                         4S           when immh = 01xx, Q = 1

                         2D           when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to 64, encoded in the "immh:immb"
                         field. It can have the following values:

                         (128-UInt(immh:immb))when immh = 1xxx

                         It is RESERVED when immh = 0xxx.

                         For the vector variant: is the right shift amount, in the range 1 to the element width in bits, encoded
                         in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         (128-UInt(immh:immb))when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand      = V[n];
         bits(datasize) operand2;
         bits(datasize) result;
         integer round_const = if round then (1 << (shift - 1)) else 0;
         integer element;

         operand2 = if accumulate then V[d] else Zeros();
         for e = 0 to elements-1
              element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift;
              Elem[result, e, esize] = Elem[operand2, e, esize] + element<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SRSRA
description:
Signed rounding shift right and accumulate (immediate)       (C7.3.268)


Scalar


  31 30 29 28 27 26 25 24 23 22        19 18     16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 1 0              !=0000     immb      0 0 1 1 0 1              Rn             Rd
        U                         immh                    o1 o0


Scalar variant

SRSRA <V><d>, <V><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh<3> != '1' then ReservedValue();
 integer esize = 8 << 3;
 integer datasize = esize;
 integer elements = 1;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Vector


  31 30 29 28 27 26 25 24 23 22        19 18     16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 1 0              !=0000     immb      0 0 1 1 0 1              Rn             Rd
        U                         immh                    o1 o0


Vector variant

SRSRA <Vd>.<T>, <Vn>.<T>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Assembler symbols

<V>           Is a width specifier, encoded in the "immh" field. It can have the following values:

              D            when immh = 1xxx

              It is RESERVED when immh = 0xxx.
       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B           when immh = 0001, Q = 0

                         16B          when immh = 0001, Q = 1

                         4H           when immh = 001x, Q = 0

                         8H           when immh = 001x, Q = 1

                         2S           when immh = 01xx, Q = 0

                         4S           when immh = 01xx, Q = 1

                         2D           when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to 64, encoded in the "immh:immb"
                         field. It can have the following values:

                         (128-UInt(immh:immb))when immh = 1xxx

                         It is RESERVED when immh = 0xxx.

                         For the vector variant: is the right shift amount, in the range 1 to the element width in bits, encoded
                         in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         (128-UInt(immh:immb))when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand      = V[n];
         bits(datasize) operand2;
         bits(datasize) result;
         integer round_const = if round then (1 << (shift - 1)) else 0;
         integer element;

         operand2 = if accumulate then V[d] else Zeros();
         for e = 0 to elements-1
              element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift;
              Elem[result, e, esize] = Elem[operand2, e, esize] + element<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SSHL
description:
Signed shift left (register)       (C7.3.269)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 0 size 1                   Rm          0 1 0 0 0 1               Rn             Rd
        U                                                        R S


Scalar variant

SSHL <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;
 boolean unsigned = (U == '1');
 boolean rounding = (R == '1');
 boolean saturating = (S == '1');
 if S == '0' && size != '11' then ReservedValue();


Vector


  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 0 size 1                   Rm          0 1 0 0 0 1               Rn             Rd
        U                                                        R S


Vector variant

SSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size:Q == '110' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;
 boolean unsigned = (U == '1');
 boolean rounding = (R == '1');
 boolean saturating = (S == '1');


Assembler symbols

<V>             Is a width specifier, encoded in the "size" field. It can have the following values:

                D            when size = 11

                It is RESERVED when:

                .       size = 0x.

                .       size = 10.

<d>             Is the number of the SIMD&FP destination register, in the "Rd" field.
       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <m>               Is the number of the second SIMD&FP source register, encoded in the "Rm" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         2D          when size = 11, Q = 1

                         It is RESERVED when size = 11, Q = 0.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand1 = V[n];
         bits(datasize) operand2 = V[m];
         bits(datasize) result;

         integer round_const = 0;
         integer shift;
         integer element;
         boolean sat;

         for e = 0 to elements-1
              shift = SInt(Elem[operand2, e, esize]<7:0>);
              if rounding then
                   round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift
              element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift;
              if saturating then
                   (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned);
                   if sat then FPSR.QC = '1';
              else
                   Elem[result, e, esize] = element<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SSHLL
description:
Signed shift left long (immediate)       (C7.3.270)

This instruction is used by the alias SXTL. See the Alias conditions table for details of when each alias is preferred.




  31 30 29 28 27 26 25 24 23 22           19 18    16 15 14 13 12 11 10 9                5 4             0
  0 Q 0 0 1 1 1 1 0                !=0000     immb      1 0 1 0 0 1               Rn               Rd
         U                          immh


Vector variant

SSHLL{2} <Vd>.<Ta>, <Vn>.<Tb>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 integer shift = UInt(immh:immb) - esize;
 boolean unsigned = (U == '1');


Alias conditions


                      Alias                   is preferred when

                      SXTL                     immb == '000' && BitCount(immh) == 1



Assembler symbols

2               Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                the following values:

                [absent]     when Q = 0

                [present]    when Q = 1

<Vd>            Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>            Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

                8H           when immh = 0001

                4S           when immh = 001x

                2D           when immh = 01xx

                See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                It is RESERVED when immh = 1xxx.

<Vn>            Is the name of the SIMD&FP source register, encoded in the "Rn" field.
       <Tb>              Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B           when immh = 0001, Q = 0

                         16B          when immh = 0001, Q = 1

                         4H           when immh = 001x, Q = 0

                         8H           when immh = 001x, Q = 1

                         2S           when immh = 01xx, Q = 0

                         4S           when immh = 01xx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = x.

       <shift>           Is the left shift amount, in the range 0 to the source element width in bits minus 1, encoded in the
                         "immh:immb" field. It can have the following values:

                         (UInt(immh:immb)-8)when immh = 0001

                         (UInt(immh:immb)-16)when immh = 001x

                         (UInt(immh:immb)-32)when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when immh = 1xxx.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand = Vpart[n, part];
         bits(datasize*2) result;
         integer element;

         for e = 0 to elements-1
              element = Int(Elem[operand, e, esize], unsigned) << shift;
              Elem[result, e, 2*esize] = element<2*esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SSHR
description:
Signed shift right (immediate)       (C7.3.271)


Scalar


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 1 0               !=0000     immb      0 0 0 0 0 1              Rn             Rd
        U                          immh                    o1 o0


Scalar variant

SSHR <V><d>, <V><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh<3> != '1' then ReservedValue();
 integer esize = 8 << 3;
 integer datasize = esize;
 integer elements = 1;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Vector


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 1 0               !=0000     immb      0 0 0 0 0 1              Rn             Rd
        U                          immh                    o1 o0


Vector variant

SSHR <Vd>.<T>, <Vn>.<T>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Assembler symbols

<V>             Is a width specifier, encoded in the "immh" field. It can have the following values:

                D           when immh = 1xxx

                It is RESERVED when immh = 0xxx.
       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B           when immh = 0001, Q = 0

                         16B          when immh = 0001, Q = 1

                         4H           when immh = 001x, Q = 0

                         8H           when immh = 001x, Q = 1

                         2S           when immh = 01xx, Q = 0

                         4S           when immh = 01xx, Q = 1

                         2D           when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to 64, encoded in the "immh:immb"
                         field. It can have the following values:

                         (128-UInt(immh:immb))when immh = 1xxx

                         It is RESERVED when immh = 0xxx.

                         For the vector variant: is the right shift amount, in the range 1 to the element width in bits, encoded
                         in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         (128-UInt(immh:immb))when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand      = V[n];
         bits(datasize) operand2;
         bits(datasize) result;
         integer round_const = if round then (1 << (shift - 1)) else 0;
         integer element;

         operand2 = if accumulate then V[d] else Zeros();
         for e = 0 to elements-1
              element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift;
              Elem[result, e, esize] = Elem[operand2, e, esize] + element<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SSRA
description:
Signed shift right and accumulate (immediate)       (C7.3.272)


Scalar


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4          0
  0 1 0 1 1 1 1 1 0               !=0000     immb      0 0 0 1 0 1              Rn             Rd
        U                          immh                    o1 o0


Scalar variant

SSRA <V><d>, <V><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh<3> != '1' then ReservedValue();
 integer esize = 8 << 3;
 integer datasize = esize;
 integer elements = 1;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Vector


  31 30 29 28 27 26 25 24 23 22          19 18    16 15 14 13 12 11 10 9                5 4          0
  0 Q 0 0 1 1 1 1 0               !=0000     immb      0 0 0 1 0 1              Rn             Rd
        U                          immh                    o1 o0


Vector variant

SSRA <Vd>.<T>, <Vn>.<T>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer shift = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 boolean round = (o1 == '1');
 boolean accumulate = (o0 == '1');


Assembler symbols

<V>             Is a width specifier, encoded in the "immh" field. It can have the following values:

                D           when immh = 1xxx

                It is RESERVED when immh = 0xxx.
       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B           when immh = 0001, Q = 0

                         16B          when immh = 0001, Q = 1

                         4H           when immh = 001x, Q = 0

                         8H           when immh = 001x, Q = 1

                         2S           when immh = 01xx, Q = 0

                         4S           when immh = 01xx, Q = 1

                         2D           when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to 64, encoded in the "immh:immb"
                         field. It can have the following values:

                         (128-UInt(immh:immb))when immh = 1xxx

                         It is RESERVED when immh = 0xxx.

                         For the vector variant: is the right shift amount, in the range 1 to the element width in bits, encoded
                         in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001

                         (32-UInt(immh:immb))when immh = 001x

                         (64-UInt(immh:immb))when immh = 01xx

                         (128-UInt(immh:immb))when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand      = V[n];
         bits(datasize) operand2;
         bits(datasize) result;
         integer round_const = if round then (1 << (shift - 1)) else 0;
         integer element;

         operand2 = if accumulate then V[d] else Zeros();
         for e = 0 to elements-1
              element = (Int(Elem[operand, e, esize], unsigned) + round_const) >> shift;
              Elem[result, e, esize] = Elem[operand2, e, esize] + element<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SSUBL
description:
Signed subtract long       (C7.3.273)




  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4             0
  0 Q 0 0 1 1 1 0 size 1                   Rm          0 0 1 0 0 0               Rn               Rd
        U                                                    o1


Three registers, not all the same type variant

SSUBL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean sub_op = (o1 == '1');
 boolean unsigned = (U == '1');


Assembler symbols

2              Is the second and upper half specifier. If present it causes the operation to be performed on the upper
               64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
               the following values:

               [absent]    when Q = 0

               [present]   when Q = 1

<Vd>           Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>           Is an arrangement specifier, encoded in the "size" field. It can have the following values:

               8H          when size = 00

               4S          when size = 01

               2D          when size = 10

               It is RESERVED when size = 11.

<Vn>           Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1

               It is RESERVED when size = 11, Q = x.
       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(datasize)      operand2 = Vpart[m, part];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         integer sum;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              if sub_op then
                   sum = element1 - element2;
              else
                   sum = element1 + element2;
              Elem[result, e, 2*esize] = sum<2*esize-1:0>;

         V[d] = result;


platform: ARM
mnem: SSUBW
description:
Signed subtract wide       (C7.3.274)




  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4             0
  0 Q 0 0 1 1 1 0 size 1                   Rm          0 0 1 1 0 0               Rn               Rd
        U                                                    o1


Three registers, not all the same type variant

SSUBW{2} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean sub_op = (o1 == '1');
 boolean unsigned = (U == '1');


Assembler symbols

2              Is the second and upper half specifier. If present it causes the operation to be performed on the upper
               64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
               the following values:

               [absent]    when Q = 0

               [present]   when Q = 1

<Vd>           Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>           Is an arrangement specifier, encoded in the "size" field. It can have the following values:

               8H          when size = 00

               4S          when size = 01

               2D          when size = 10

               It is RESERVED when size = 11.

<Vn>           Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>           Is the name of the second SIMD&FP source register, encoded in the "Rm" field.

<Tb>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1
                         It is RESERVED when size = 11, Q = x.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(2*datasize) operand1 = V[n];
         bits(datasize)      operand2 = Vpart[m, part];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         integer sum;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, 2*esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              if sub_op then
                   sum = element1 - element2;
              else
                   sum = element1 + element2;
              Elem[result, e, 2*esize] = sum<2*esize-1:0>;

         V[d] = result;


platform: ARM
mnem: ST1
description:
Store multiple 1-element structures from one, two three or four registers       (C7.3.275)


No offset


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15         12 11 10 9               5 4          0
  0 Q 0 0 1 1 0 0 0 0 0 0 0 0 0 0 x x 1 x size                                Rn             Rt
                               L                      opcode


One register variant

Applies when opcode = 0111.

ST1 { <Vt>.<T> }, [<Xn|SP>]


Two registers variant

Applies when opcode = 1010.

ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]


Three registers variant

Applies when opcode = 0110.

ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]


Four registers variant

Applies when opcode = 0010.

ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = integer UNKNOWN;
 boolean wback = FALSE;


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20           16 15        12 11 10 9               5 4          0
  0 Q 0 0 1 1 0 0 1 0 0                   Rm         x x 1 x size             Rn             Rt
                               L                      opcode


One register, immediate offset variant

Applies when Rm = 11111 && opcode = 0111.

ST1 { <Vt>.<T> }, [<Xn|SP>], <imm>


One register, register offset variant

Applies when Rm != 11111 && opcode = 0111.

ST1 { <Vt>.<T> }, [<Xn|SP>], <Xm>


Two registers, immediate offset variant

Applies when Rm = 11111 && opcode = 1010.
       ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>


       Two registers, register offset variant

       Applies when Rm != 11111 && opcode = 1010.

       ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>


       Three registers, immediate offset variant

       Applies when Rm = 11111 && opcode = 0110.

       ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>


       Three registers, register offset variant

       Applies when Rm != 11111 && opcode = 0110.

       ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>


       Four registers, immediate offset variant

       Applies when Rm = 11111 && opcode = 0010.

       ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>


       Four registers, register offset variant

       Applies when Rm != 11111 && opcode = 0010.

       ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>


       Decode for all variants of this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         boolean wback = TRUE;


       Assembler symbols

       <Vt>              Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         1D          when size = 11, Q = 0

                         2D          when size = 11, Q = 1

       <Vt2>             Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

       <Vt3>             Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

       <Vt4>             Is the name of the fourth SIMD&FP register to be transferred, encoded as "Rt" plus 3 modulo 32.

       <Xn|SP>           Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.
<imm>         For the one register, immediate offset variant: is the post-index immediate offset, encoded in the "Q"
              field. It can have the following values:

              #8           when Q = 0

              #16          when Q = 1

              For the two registers, immediate offset variant: is the post-index immediate offset, encoded in the
              "Q" field. It can have the following values:

              #16          when Q = 0

              #32          when Q = 1

              For the three registers, immediate offset variant: is the post-index immediate offset, encoded in the
              "Q" field. It can have the following values:

              #24          when Q = 0

              #48          when Q = 1

              For the four registers, immediate offset variant: is the post-index immediate offset, encoded in the
              "Q" field. It can have the following values:

              #32          when Q = 0

              #64          when Q = 1

<Xm>          Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
              field.


Shared decode for all encodings

 MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
 integer datasize = if Q == '1' then 128 else 64;
 integer esize = 8 << UInt(size);
 integer elements = datasize DIV esize;

 integer rpt;    // number of iterations
 integer selem;  // structure elements

 case opcode of
    when '0000' rpt = 1; selem = 4;         // LD/ST4 (4 registers)
    when '0010' rpt = 4; selem = 1;         // LD/ST1 (4 registers)
    when '0100' rpt = 1; selem = 3;         // LD/ST3 (3 registers)
    when '0110' rpt = 3; selem = 1;         // LD/ST1 (3 registers)
    when '0111' rpt = 1; selem = 1;         // LD/ST1 (1 register)
    when '1000' rpt = 1; selem = 2;         // LD/ST2 (2 registers)
    when '1010' rpt = 2; selem = 1;         // LD/ST1 (2 registers)
    otherwise UnallocatedEncoding();

 // .1D format only permitted with LD1 & ST1
 if size:Q == '110' && selem != 1 then ReservedValue();


Operation for all encodings

 CheckFPAdvSIMDEnabled64();

 bits(64) address;
 bits(64) offs;
 bits(datasize) rval;
 integer e, r, s, tt;
 constant integer ebytes = esize DIV 8;

 if n == 31 then
     CheckSPAlignment();
    address = SP[];
 else
    address = X[n];
         offs = Zeros();
         for r = 0 to rpt-1
              for e = 0 to elements-1
                   tt = (t + r) MOD 32;
                   for s = 0 to selem-1
                       rval = V[tt];
                       if memop == MemOp_LOAD then
                           Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                           V[tt] = rval;
                       else // memop == MemOp_STORE
                           Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
                       offs = offs + ebytes;
                       tt = (tt + 1) MOD 32;

         if wback then
              if m != 31 then
                   offs = X[m];
              if n == 31 then
                   SP[] = address + offs;
              else
                   X[n] = address + offs;


platform: ARM
mnem: ST2
description:
       Store multiple 2-element structures from two registers       (C7.3.277)


       No offset


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15           12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 size                                 Rn              Rt
                                        L                       opcode


       No offset variant

       ST2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]


       Decode for this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = integer UNKNOWN;
         boolean wback = FALSE;


       Post-index


           31 30 29 28 27 26 25 24 23 22 21 20              16 15       12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 1 0 0                    Rm        1 0 0 0 size              Rn              Rt
                                        L                       opcode


       Immediate offset variant

       Applies when Rm = 11111.

       ST2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>


       Register offset variant

       Applies when Rm != 11111.

       ST2 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <Xm>


       Decode for all variants of this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         boolean wback = TRUE;


       Assembler symbols

       <Vt>              Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1
              2D           when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vt2>         Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

<Xn|SP>       Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

<imm>         Is the post-index immediate offset, encoded in the "Q" field. It can have the following values:

              #16          when Q = 0

              #32          when Q = 1

<Xm>          Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
              field.


Shared decode for all encodings

 MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
 integer datasize = if Q == '1' then 128 else 64;
 integer esize = 8 << UInt(size);
 integer elements = datasize DIV esize;

 integer rpt;    // number of iterations
 integer selem;  // structure elements

 case opcode of
    when '0000' rpt = 1; selem = 4;        // LD/ST4 (4 registers)
    when '0010' rpt = 4; selem = 1;        // LD/ST1 (4 registers)
    when '0100' rpt = 1; selem = 3;        // LD/ST3 (3 registers)
    when '0110' rpt = 3; selem = 1;        // LD/ST1 (3 registers)
    when '0111' rpt = 1; selem = 1;        // LD/ST1 (1 register)
    when '1000' rpt = 1; selem = 2;        // LD/ST2 (2 registers)
    when '1010' rpt = 2; selem = 1;        // LD/ST1 (2 registers)
    otherwise UnallocatedEncoding();

 // .1D format only permitted with LD1 & ST1
 if size:Q == '110' && selem != 1 then ReservedValue();


Operation for all encodings

 CheckFPAdvSIMDEnabled64();

 bits(64) address;
 bits(64) offs;
 bits(datasize) rval;
 integer e, r, s, tt;
 constant integer ebytes = esize DIV 8;

 if n == 31 then
     CheckSPAlignment();
    address = SP[];
 else
    address = X[n];

 offs = Zeros();
 for r = 0 to rpt-1
     for e = 0 to elements-1
         tt = (t + r) MOD 32;
         for s = 0 to selem-1
             rval = V[tt];
             if memop == MemOp_LOAD then
                 Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                 V[tt] = rval;
             else // memop == MemOp_STORE
                 Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
             offs = offs + ebytes;
                       tt = (tt + 1) MOD 32;

         if wback then
              if m != 31 then
                   offs = X[m];
              if n == 31 then
                   SP[] = address + offs;
              else
                   X[n] = address + offs;


platform: ARM
mnem: ST3
description:
Store multiple 3-element structures from three registers       (C7.3.279)


No offset


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15          12 11 10 9                 5 4          0
  0 Q 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 size                                   Rn             Rt
                               L                       opcode


No offset variant

ST3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]


Decode for this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = integer UNKNOWN;
 boolean wback = FALSE;


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20             16 15       12 11 10 9                 5 4          0
  0 Q 0 0 1 1 0 0 1 0 0                    Rm        0 1 0 0 size                Rn             Rt
                               L                       opcode


Immediate offset variant

Applies when Rm = 11111.

ST3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>


Register offset variant

Applies when Rm != 11111.

ST3 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <Xm>


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 boolean wback = TRUE;


Assembler symbols

<Vt>           Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

<T>            Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

               8B          when size = 00, Q = 0

               16B         when size = 00, Q = 1

               4H          when size = 01, Q = 0

               8H          when size = 01, Q = 1

               2S          when size = 10, Q = 0

               4S          when size = 10, Q = 1
                         2D           when size = 11, Q = 1

                         It is RESERVED when size = 11, Q = 0.

       <Vt2>             Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

       <Vt3>             Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

       <Xn|SP>           Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

       <imm>             Is the post-index immediate offset, encoded in the "Q" field. It can have the following values:

                         #24          when Q = 0

                         #48          when Q = 1

       <Xm>              Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
                         field.


       Shared decode for all encodings

         MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
         integer datasize = if Q == '1' then 128 else 64;
         integer esize = 8 << UInt(size);
         integer elements = datasize DIV esize;

         integer rpt;       // number of iterations
         integer selem;     // structure elements

         case opcode of
              when '0000' rpt = 1; selem = 4;         // LD/ST4 (4 registers)
              when '0010' rpt = 4; selem = 1;         // LD/ST1 (4 registers)
              when '0100' rpt = 1; selem = 3;         // LD/ST3 (3 registers)
              when '0110' rpt = 3; selem = 1;         // LD/ST1 (3 registers)
              when '0111' rpt = 1; selem = 1;         // LD/ST1 (1 register)
              when '1000' rpt = 1; selem = 2;         // LD/ST2 (2 registers)
              when '1010' rpt = 2; selem = 1;         // LD/ST1 (2 registers)
              otherwise UnallocatedEncoding();

         // .1D format only permitted with LD1 & ST1
         if size:Q == '110' && selem != 1 then ReservedValue();


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();

         bits(64) address;
         bits(64) offs;
         bits(datasize) rval;
         integer e, r, s, tt;
         constant integer ebytes = esize DIV 8;

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         else
              address = X[n];

         offs = Zeros();
         for r = 0 to rpt-1
              for e = 0 to elements-1
                   tt = (t + r) MOD 32;
                   for s = 0 to selem-1
                       rval = V[tt];
                       if memop == MemOp_LOAD then
                            Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                            V[tt] = rval;
                       else // memop == MemOp_STORE
                Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
            offs = offs + ebytes;
            tt = (tt + 1) MOD 32;

 if wback then
    if m != 31 then
        offs = X[m];
    if n == 31 then
         SP[] = address + offs;
    else
         X[n] = address + offs;


platform: ARM
mnem: ST4
description:
       Store multiple 4-element structures from four registers       (C7.3.281)


       No offset


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15           12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 size                                 Rn              Rt
                                        L                       opcode


       No offset variant

       ST4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]


       Decode for this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = integer UNKNOWN;
         boolean wback = FALSE;


       Post-index


           31 30 29 28 27 26 25 24 23 22 21 20              16 15       12 11 10 9             5 4             0
            0 Q 0 0 1 1 0 0 1 0 0                    Rm        0 0 0 0 size              Rn              Rt
                                        L                       opcode


       Immediate offset variant

       Applies when Rm = 11111.

       ST4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>


       Register offset variant

       Applies when Rm != 11111.

       ST4 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <Xm>


       Decode for all variants of this encoding

         integer t = UInt(Rt);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         boolean wback = TRUE;


       Assembler symbols

       <Vt>              Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1
              2D           when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vt2>         Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.

<Vt3>         Is the name of the third SIMD&FP register to be transferred, encoded as "Rt" plus 2 modulo 32.

<Vt4>         Is the name of the fourth SIMD&FP register to be transferred, encoded as "Rt" plus 3 modulo 32.

<Xn|SP>       Is the 64-bit name of the general-purpose base register or stack pointer, encoded in the "Rn" field.

<imm>         Is the post-index immediate offset, encoded in the "Q" field. It can have the following values:

              #32          when Q = 0

              #64          when Q = 1

<Xm>          Is the 64-bit name of the general-purpose post-index register, excluding XZR, encoded in the "Rm"
              field.


Shared decode for all encodings

 MemOp memop = if L == '1' then MemOp_LOAD else MemOp_STORE;
 integer datasize = if Q == '1' then 128 else 64;
 integer esize = 8 << UInt(size);
 integer elements = datasize DIV esize;

 integer rpt;    // number of iterations
 integer selem;  // structure elements

 case opcode of
    when '0000' rpt = 1; selem = 4;        // LD/ST4 (4 registers)
    when '0010' rpt = 4; selem = 1;        // LD/ST1 (4 registers)
    when '0100' rpt = 1; selem = 3;        // LD/ST3 (3 registers)
    when '0110' rpt = 3; selem = 1;        // LD/ST1 (3 registers)
    when '0111' rpt = 1; selem = 1;        // LD/ST1 (1 register)
    when '1000' rpt = 1; selem = 2;        // LD/ST2 (2 registers)
    when '1010' rpt = 2; selem = 1;        // LD/ST1 (2 registers)
    otherwise UnallocatedEncoding();

 // .1D format only permitted with LD1 & ST1
 if size:Q == '110' && selem != 1 then ReservedValue();


Operation for all encodings

 CheckFPAdvSIMDEnabled64();

 bits(64) address;
 bits(64) offs;
 bits(datasize) rval;
 integer e, r, s, tt;
 constant integer ebytes = esize DIV 8;

 if n == 31 then
     CheckSPAlignment();
    address = SP[];
 else
    address = X[n];

 offs = Zeros();
 for r = 0 to rpt-1
     for e = 0 to elements-1
         tt = (t + r) MOD 32;
         for s = 0 to selem-1
             rval = V[tt];
             if memop == MemOp_LOAD then
                 Elem[rval, e, esize] = Mem[address + offs, ebytes, AccType_VEC];
                           V[tt] = rval;
                       else // memop == MemOp_STORE
                           Mem[address + offs, ebytes, AccType_VEC] = Elem[rval, e, esize];
                       offs = offs + ebytes;
                       tt = (tt + 1) MOD 32;

         if wback then
              if m != 31 then
                   offs = X[m];
              if n == 31 then
                   SP[] = address + offs;
              else
                   X[n] = address + offs;


platform: ARM
mnem: SUBHN
description:
Subtract returning high narrow       (C7.3.289)




  31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4             0
  0 Q 0 0 1 1 1 0 size 1                    Rm          0 1 1 0 0 0               Rn               Rd
        U                                                     o1


Three registers, not all the same type variant

SUBHN{2} <Vd>.<Tb>, <Vn>.<Ta>, <Vm>.<Ta>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean sub_op = (o1 == '1');
 boolean round = (U == '1');


Assembler symbols

2               Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                the following values:

                [absent]    when Q = 0

                [present]   when Q = 1

<Vd>            Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Tb>            Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                8B          when size = 00, Q = 0

                16B         when size = 00, Q = 1

                4H          when size = 01, Q = 0

                8H          when size = 01, Q = 1

                2S          when size = 10, Q = 0

                4S          when size = 10, Q = 1

                It is RESERVED when size = 11, Q = x.

<Vn>            Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Ta>            Is an arrangement specifier, encoded in the "size" field. It can have the following values:

                8H          when size = 00

                4S          when size = 01

                2D          when size = 10

                It is RESERVED when size = 11.
       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(2*datasize) operand1 = V[n];
         bits(2*datasize) operand2 = V[m];
         bits(datasize)      result;
         integer round_const = if round then 1 << (esize - 1) else 0;
         bits(2*esize) element1;
         bits(2*esize) element2;
         bits(2*esize) sum;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, 2*esize];
              element2 = Elem[operand2, e, 2*esize];
              if sub_op then
                   sum = element1 - element2;
              else
                   sum = element1 + element2;
              sum = sum + round_const;
              Elem[result, e, esize] = sum<2*esize-1:esize>;

         Vpart[d, part] = result;


platform: ARM
mnem: SUQADD
description:
Signed saturating accumulate of unsigned value       (C7.3.290)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                  5 4          0
  0 1 0 1 1 1 1 0 size 1 0 0 0 0 0 0 0 1 1 1 0                                  Rn             Rd
        U


Scalar variant

SUQADD <V><d>, <V><n>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;

 boolean unsigned = (U == '1');


Vector


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                  5 4          0
  0 Q 0 0 1 1 1 0 size 1 0 0 0 0 0 0 0 1 1 1 0                                  Rn             Rd
        U


Vector variant

SUQADD <Vd>.<T>, <Vn>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size:Q == '110' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');


Assembler symbols

<V>            Is a width specifier, encoded in the "size" field. It can have the following values:

               B           when size = 00

               H           when size = 01

               S           when size = 10

               D           when size = 11

<d>            Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<n>            Is the number of the SIMD&FP source register, encoded in the "Rn" field.
       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         2D          when size = 11, Q = 1

                         It is RESERVED when size = 11, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand = V[n];
         bits(datasize) result;

         bits(datasize) operand2 = V[d];
         integer op1;
         integer op2;
         boolean sat;

         for e = 0 to elements-1
              op1 = Int(Elem[operand, e, esize], !unsigned);
              op2 = Int(Elem[operand2, e, esize], unsigned);
              (Elem[result, e, esize], sat) = SatQ(op1 + op2, esize, unsigned);
              if sat then FPSR.QC = '1';
         V[d] = result;


platform: ARM
mnem: SXTL
description:
Signed extend long       (C7.3.291)

This instruction is an alias of the SSHLL, SSHLL2 instruction. This means that:

.      The encodings in this description are named to match the encodings of SSHLL, SSHLL2.

.      The description of SSHLL, SSHLL2 gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22           19 18    16 15 14 13 12 11 10 9                5 4             0
   0 Q 0 0 1 1 1 1 0               !=0000     0 0 0 1 0 1 0 0 1                   Rn               Rd
         U                          immh      immb


Vector variant

SXTL{2} <Vd>.<Ta>, <Vn>.<Tb>

is equivalent to

SSHLL{2}   <Vd>.<Ta>, <Vn>.<Tb>, #0

and is the preferred disassembly when BitCount(immh) == 1.


Assembler symbols

2               Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                the following values:

                [absent]     when Q = 0

                [present]    when Q = 1

<Vd>            Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>            Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

                8H           when immh = 0001

                4S           when immh = 001x

                2D           when immh = 01xx

                See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                It is RESERVED when immh = 1xxx.

<Vn>            Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Tb>            Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                8B           when immh = 0001, Q = 0

                16B          when immh = 0001, Q = 1

                4H           when immh = 001x, Q = 0

                8H           when immh = 001x, Q = 1

                2S           when immh = 01xx, Q = 0

                4S           when immh = 01xx, Q = 1

                See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                It is RESERVED when immh = 1xxx, Q = x.
       Operation

       The description of SSHLL, SSHLL2 gives the operational pseudocode for this instruction.


platform: ARM
mnem: TBL
description:
Table vector lookup       (C7.3.292)




  31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4              0
  0 Q 0 0 1 1 1 0 0 0 0                     Rm          0    len  0 0 0          Rn                Rd
                                                                 op


Two register table variant

Applies when len = 01.

TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>


Three register table variant

Applies when len = 10.

TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>


Four register table variant

Applies when len = 11.

TBL <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>


Single register table variant

Applies when len = 00.

TBL <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV 8;
 integer regs = UInt(len) + 1;
 boolean is_tbl = (op == '0');


Assembler symbols

<Vd>           Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>           Is an arrangement specifier, encoded in the "Q" field. It can have the following values:

               8B          when Q = 0

               16B         when Q = 1

<Vn>           For the four register table, three register table and two register table variant: is the name of the first
               SIMD&FP table register, encoded in the "Rn" field.

               For the single register table variant: is the name of the SIMD&FP table register, encoded in the "Rn"
               field.

<Vn+1>         Is the name of the second SIMD&FP table register, encoded as "Rn" plus 1 modulo 32.

<Vn+2>         Is the name of the third SIMD&FP table register, encoded as "Rn" plus 2 modulo 32.
       <Vn+3>            Is the name of the fourth SIMD&FP table register, encoded as "Rn" plus 3 modulo 32.

       <Vm>              Is the name of the SIMD&FP index register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize) indices = V[m];
         bits(128*regs) table = Zeros();
         bits(datasize) result;
         integer index;
         integer i;

         // Create table from registers
         for i = 0 to regs - 1
              table<128*i+127:128*i> = V[n];
              n = (n + 1) MOD 32;

         result = if is_tbl then Zeros() else V[d];
         for i = 0 to elements - 1
              index = UInt(Elem[indices, i, 8]);
              if index < 16 * regs then
                   Elem[result, i, 8] = Elem[table, index, 8];

         V[d] = result;


platform: ARM
mnem: TBX
description:
Table vector lookup extension       (C7.3.293)




  31 30 29 28 27 26 25 24 23 22 21 20              16 15 14 13 12 11 10 9                5 4              0
  0 Q 0 0 1 1 1 0 0 0 0                     Rm          0    len  1 0 0          Rn                Rd
                                                                 op


Two register table variant

Applies when len = 01.

TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B }, <Vm>.<Ta>


Three register table variant

Applies when len = 10.

TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B }, <Vm>.<Ta>


Four register table variant

Applies when len = 11.

TBX <Vd>.<Ta>, { <Vn>.16B, <Vn+1>.16B, <Vn+2>.16B, <Vn+3>.16B }, <Vm>.<Ta>


Single register table variant

Applies when len = 00.

TBX <Vd>.<Ta>, { <Vn>.16B }, <Vm>.<Ta>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV 8;
 integer regs = UInt(len) + 1;
 boolean is_tbl = (op == '0');


Assembler symbols

<Vd>           Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>           Is an arrangement specifier, encoded in the "Q" field. It can have the following values:

               8B          when Q = 0

               16B         when Q = 1

<Vn>           For the four register table, three register table and two register table variant: is the name of the first
               SIMD&FP table register, encoded in the "Rn" field.

               For the single register table variant: is the name of the SIMD&FP table register, encoded in the "Rn"
               field.

<Vn+1>         Is the name of the second SIMD&FP table register, encoded as "Rn" plus 1 modulo 32.

<Vn+2>         Is the name of the third SIMD&FP table register, encoded as "Rn" plus 2 modulo 32.
       <Vn+3>            Is the name of the fourth SIMD&FP table register, encoded as "Rn" plus 3 modulo 32.

       <Vm>              Is the name of the SIMD&FP index register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize) indices = V[m];
         bits(128*regs) table = Zeros();
         bits(datasize) result;
         integer index;
         integer i;

         // Create table from registers
         for i = 0 to regs - 1
              table<128*i+127:128*i> = V[n];
              n = (n + 1) MOD 32;

         result = if is_tbl then Zeros() else V[d];
         for i = 0 to elements - 1
              index = UInt(Elem[indices, i, 8]);
              if index < 16 * regs then
                   Elem[result, i, 8] = Elem[table, index, 8];

         V[d] = result;


platform: ARM
mnem: TRN1
description:
Transpose vectors (primary)       (C7.3.294)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 0 0 1 1 1 0 size 0                 Rm         0 0 1 0 1 0               Rn              Rd
                                                      op


Advanced SIMD variant

TRN1 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size:Q == '110' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;
 integer part = UInt(op);
 integer pairs = elements DIV 2;


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              2D          when size = 11, Q = 1

              It is RESERVED when size = 11, Q = 0.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer p;

 for p = 0 to pairs-1
     Elem[result, 2*p+0, esize] = Elem[operand1, 2*p+part, esize];
     Elem[result, 2*p+1, esize] = Elem[operand2, 2*p+part, esize];

 V[d] = result;


platform: ARM
mnem: TRN2
description:
Transpose vectors (secondary)       (C7.3.295)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
     0 Q 0 0 1 1 1 0 size 0                  Rm         0 1 1 0 1 0               Rn              Rd
                                                          op


Advanced SIMD variant

TRN2 <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);

  if size:Q == '110' then ReservedValue();
  integer esize = 8 << UInt(size);
  integer datasize = if Q == '1' then 128 else 64;
  integer elements = datasize DIV esize;
  integer part = UInt(op);
  integer pairs = elements DIV 2;


Assembler symbols

<Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                  8B          when size = 00, Q = 0

                  16B         when size = 00, Q = 1

                  4H          when size = 01, Q = 0

                  8H          when size = 01, Q = 1

                  2S          when size = 10, Q = 0

                  4S          when size = 10, Q = 1

                  2D          when size = 11, Q = 1

                  It is RESERVED when size = 11, Q = 0.

<Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand1 = V[n];
  bits(datasize) operand2 = V[m];
  bits(datasize) result;
  integer p;

  for p = 0 to pairs-1
       Elem[result, 2*p+0, esize] = Elem[operand1, 2*p+part, esize];
       Elem[result, 2*p+1, esize] = Elem[operand2, 2*p+part, esize];

  V[d] = result;


platform: ARM
mnem: UABA
description:
Unsigned absolute difference and accumulate       (C7.3.296)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         0 1 1 1 1 1               Rn              Rd
        U                                                       ac


Three registers of the same type variant

UABA <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean accumulate = (ac == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 bits(esize) absdiff;

 result = if accumulate then V[d] else Zeros();
 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
              absdiff = Abs(element1 - element2)<esize-1:0>;
              Elem[result, e, esize] = Elem[result, e, esize] + absdiff;
         V[d] = result;


platform: ARM
mnem: UABAL
description:
Unsigned absolute difference and accumulate long       (C7.3.297)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 0 size 1                  Rm          0 1 0 1 0 0               Rn               Rd
        U                                                   op


Three registers, not all the same type variant

UABAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean accumulate = (op == '0');
 boolean unsigned = (U == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.
       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(datasize)      operand2 = Vpart[m, part];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         bits(2*esize) absdiff;

         result = if accumulate then V[d] else Zeros();
         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              absdiff = Abs(element1 - element2)<2*esize-1:0>;
              Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff;
         V[d] = result;


platform: ARM
mnem: UABD
description:
Unsigned absolute difference (vector)       (C7.3.298)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         0 1 1 1 0 1               Rn              Rd
        U                                                       ac


Three registers of the same type variant

UABD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean accumulate = (ac == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 bits(esize) absdiff;

 result = if accumulate then V[d] else Zeros();
 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
              absdiff = Abs(element1 - element2)<esize-1:0>;
              Elem[result, e, esize] = Elem[result, e, esize] + absdiff;
         V[d] = result;


platform: ARM
mnem: UABDL
description:
Unsigned absolute difference long       (C7.3.299)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 0 size 1                  Rm          0 1 1 1 0 0               Rn               Rd
        U                                                   op


Three registers, not all the same type variant

UABDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean accumulate = (op == '0');
 boolean unsigned = (U == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.
       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(datasize)      operand2 = Vpart[m, part];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         bits(2*esize) absdiff;

         result = if accumulate then V[d] else Zeros();
         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              absdiff = Abs(element1 - element2)<2*esize-1:0>;
              Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + absdiff;
         V[d] = result;


platform: ARM
mnem: UADALP
description:
Unsigned add and accumulate long pairwise       (C7.3.300)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1 0 0 0 0 0 0 1 1 0 1 0                                Rn              Rd
        U                                             op


Vector variant

UADALP <Vd>.<Ta>, <Vn>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV (2*esize);
 boolean acc = (op == '1');
 boolean unsigned = (U == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              4H          when size = 00, Q = 0

              8H          when size = 00, Q = 1

              2S          when size = 01, Q = 0

              4S          when size = 01, Q = 1

              1D          when size = 10, Q = 0

              2D          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 bits(datasize) result;

         bits(2*esize) sum;
         integer op1;
         integer op2;

         result = if acc then V[d] else Zeros();
         for e = 0 to elements-1
              op1 = Int(Elem[operand, 2*e+0, esize], unsigned);
              op2 = Int(Elem[operand, 2*e+1, esize], unsigned);
              sum = (op1 + op2)<2*esize-1:0>;
              Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum;

         V[d] = result;


platform: ARM
mnem: UADDL
description:
Unsigned add long (vector)       (C7.3.301)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 0 size 1                  Rm          0 0 0 0 0 0               Rn               Rd
        U                                                   o1


Three registers, not all the same type variant

UADDL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean sub_op = (o1 == '1');
 boolean unsigned = (U == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.
       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(datasize)      operand2 = Vpart[m, part];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         integer sum;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              if sub_op then
                   sum = element1 - element2;
              else
                   sum = element1 + element2;
              Elem[result, e, 2*esize] = sum<2*esize-1:0>;

         V[d] = result;


platform: ARM
mnem: UADDLP
description:
Unsigned add long pairwise       (C7.3.302)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1 0 0 0 0 0 0 0 1 0 1 0                                Rn              Rd
        U                                             op


Vector variant

UADDLP <Vd>.<Ta>, <Vn>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV (2*esize);
 boolean acc = (op == '1');
 boolean unsigned = (U == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              4H          when size = 00, Q = 0

              8H          when size = 00, Q = 1

              2S          when size = 01, Q = 0

              4S          when size = 01, Q = 1

              1D          when size = 10, Q = 0

              2D          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 bits(datasize) result;

         bits(2*esize) sum;
         integer op1;
         integer op2;

         result = if acc then V[d] else Zeros();
         for e = 0 to elements-1
              op1 = Int(Elem[operand, 2*e+0, esize], unsigned);
              op2 = Int(Elem[operand, 2*e+1, esize], unsigned);
              sum = (op1 + op2)<2*esize-1:0>;
              Elem[result, e, 2*esize] = Elem[result, e, 2*esize] + sum;

         V[d] = result;


platform: ARM
mnem: UADDLV
description:
Unsigned sum long across vector       (C7.3.303)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                  5 4            0
  0 Q 1 0 1 1 1 0 size 1 1 0 0 0 0 0 0 1 1 1 0                                 Rn               Rd
        U


Advanced SIMD variant

UADDLV <V><d>, <Vn>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size:Q == '100' then ReservedValue();
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');


Assembler symbols

<V>           Is the destination width specifier, encoded in the "size" field. It can have the following values:

              H           when size = 00

              S           when size = 01

              D           when size = 10

              It is RESERVED when size = 11.

<d>           Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              4S          when size = 10, Q = 1

              It is RESERVED when:

              .      size = 10, Q = 0.

              .      size = 11, Q = x.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 integer sum;

 sum = Int(Elem[operand, 0, esize], unsigned);
         for e = 1 to elements-1
              sum = sum + Int(Elem[operand, e, esize], unsigned);

         V[d] = sum<2*esize-1:0>;


platform: ARM
mnem: UADDW
description:
Unsigned add wide       (C7.3.304)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 0 size 1                  Rm          0 0 0 1 0 0               Rn               Rd
        U                                                   o1


Three registers, not all the same type variant

UADDW{2} <Vd>.<Ta>, <Vn>.<Ta>, <Vm>.<Tb>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);

 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean sub_op = (o1 == '1');
 boolean unsigned = (U == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              8H          when size = 00

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1
                         It is RESERVED when size = 11, Q = x.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(2*datasize) operand1 = V[n];
         bits(datasize)      operand2 = Vpart[m, part];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         integer sum;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, 2*esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              if sub_op then
                   sum = element1 - element2;
              else
                   sum = element1 + element2;
              Elem[result, e, 2*esize] = sum<2*esize-1:0>;

         V[d] = result;


platform: ARM
mnem: UCVTF
description:
Unsigned fixed-point convert to floating-point (vector)       (C7.3.305)


Scalar


  31 30 29 28 27 26 25 24 23 22        19 18     16 15 14 13 12 11 10 9                5 4          0
  0 1 1 1 1 1 1 1 0             !=0000      immb     1 1 1 0 0 1               Rn             Rd
        U                        immh


Scalar variant

UCVTF <V><d>, <V><n>, #<fbits>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '00xx' then ReservedValue();
 integer esize = 32 << UInt(immh<3>);
 integer datasize = esize;
 integer elements = 1;

 integer fracbits = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 FPRounding rounding = FPRoundingMode(FPCR);


Vector


  31 30 29 28 27 26 25 24 23 22        19 18     16 15 14 13 12 11 10 9                5 4          0
  0 Q 1 0 1 1 1 1 0             !=0000      immb     1 1 1 0 0 1               Rn             Rd
        U                        immh


Vector variant

UCVTF <Vd>.<T>, <Vn>.<T>, #<fbits>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh == '00xx' then ReservedValue();
 if immh<3>:Q == '10' then ReservedValue();
 integer esize = 32 << UInt(immh<3>);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 integer fracbits = (esize * 2) - UInt(immh:immb);
 boolean unsigned = (U == '1');
 FPRounding rounding = FPRoundingMode(FPCR);


Assembler symbols

<V>           Is a width specifier, encoded in the "immh" field. It can have the following values:

              S           when immh = 01xx

              D           when immh = 1xxx
                         It is RESERVED when immh = 00xx.

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         2S          when immh = 01xx, Q = 0

                         4S          when immh = 01xx, Q = 1

                         2D          when immh = 1xxx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when:

                         .      immh = 0001, Q = x.

                         .      immh = 001x, Q = x.

                         .      immh = 1xxx, Q = 0.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <fbits>           For the scalar variant: is the number of fractional bits, in the range 1 to the operand width, encoded
                         in the "immh:immb" field. It can have the following values:

                         (64-UInt(immh:immb))when immh = 01xx

                         (128-UInt(immh:immb))when immh = 1xxx

                         It is RESERVED when immh = 00xx.

                         For the vector variant: is the number of fractional bits, in the range 1 to the element width, encoded
                         in the "immh:immb" field. It can have the following values:

                         (64-UInt(immh:immb))when immh = 01xx

                         (128-UInt(immh:immb))when immh = 1xxx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when:

                         .      immh = 0001.

                         .      immh = 001x.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand     = V[n];
         bits(datasize) result;
         bits(esize) element;

         for e = 0 to elements-1
              element = Elem[operand, e, esize];
              Elem[result, e, esize] = FixedToFP(element, fracbits, unsigned, FPCR, rounding);

         V[d] = result;


platform: ARM
mnem: UHADD
description:
Unsigned halving add       (C7.3.309)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         0 0 0 0 0 1               Rn              Rd
        U


Three registers of the same type variant

UHADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;
 boolean unsigned = (U == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 integer sum;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     sum = element1 + element2;
     Elem[result, e, esize] = sum<esize:1>;

 V[d] = result;


platform: ARM
mnem: UHSUB
description:
Unsigned halving subtract       (C7.3.310)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14 13 12 11 10 9               5 4             0
     0 Q 1 0 1 1 1 0 size 1                  Rm         0 0 1 0 0 1               Rn              Rd
           U


Three registers of the same type variant

UHSUB <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if size == '11' then ReservedValue();
  integer esize = 8 << UInt(size);
  integer datasize = if Q == '1' then 128 else 64;
  integer elements = datasize DIV esize;
  boolean unsigned = (U == '1');


Assembler symbols

<Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                  8B          when size = 00, Q = 0

                  16B         when size = 00, Q = 1

                  4H          when size = 01, Q = 0

                  8H          when size = 01, Q = 1

                  2S          when size = 10, Q = 0

                  4S          when size = 10, Q = 1

                  It is RESERVED when size = 11, Q = x.

<Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand1 = V[n];
  bits(datasize) operand2 = V[m];
  bits(datasize) result;
  integer element1;
  integer element2;
  integer diff;

  for e = 0 to elements-1
       element1 = Int(Elem[operand1, e, esize], unsigned);
       element2 = Int(Elem[operand2, e, esize], unsigned);
       diff = element1 - element2;
       Elem[result, e, esize] = diff<esize:1>;

  V[d] = result;


platform: ARM
mnem: UMAX
description:
Unsigned maximum (vector)       (C7.3.311)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         0 1 1 0 0 1               Rn              Rd
        U                                                       o1


Three registers of the same type variant

UMAX <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean minimum = (o1 == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 integer maxmin;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
              Elem[result, e, esize] = maxmin<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: UMAXP
description:
Unsigned maximum pairwise       (C7.3.312)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         1 0 1 0 0 1               Rn              Rd
        U                                                       o1


Three registers of the same type variant

UMAXP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean minimum = (o1 == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 bits(2*datasize) concat = operand2:operand1;
 integer element1;
 integer element2;
 integer maxmin;

 for e = 0 to elements-1
     element1 = Int(Elem[concat, 2*e, esize], unsigned);
     element2 = Int(Elem[concat, (2*e)+1, esize], unsigned);
     maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
              Elem[result, e, esize] = maxmin<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: UMAXV
description:
Unsigned maximum across vector       (C7.3.313)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                  5 4            0
  0 Q 1 0 1 1 1 0 size 1 1 0 0 0 0 1 0 1 0 1 0                                 Rn               Rd
        U                                        op


Advanced SIMD variant

UMAXV <V><d>, <Vn>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size:Q == '100' then ReservedValue();
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean min = (op == '1');


Assembler symbols

<V>           Is the destination width specifier, encoded in the "size" field. It can have the following values:

              B           when size = 00

              H           when size = 01

              S           when size = 10

              It is RESERVED when size = 11.

<d>           Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              4S          when size = 10, Q = 1

              It is RESERVED when:

              .      size = 10, Q = 0.

              .      size = 11, Q = x.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 integer maxmin;
 integer element;

         maxmin = Int(Elem[operand, 0, esize], unsigned);
         for e = 1 to elements-1
              element = Int(Elem[operand, e, esize], unsigned);
              maxmin = if min then Min(maxmin, element) else Max(maxmin, element);

         V[d] = maxmin<esize-1:0>;


platform: ARM
mnem: UMIN
description:
Unsigned minimum (vector)       (C7.3.314)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         0 1 1 0 1 1               Rn              Rd
        U                                                       o1


Three registers of the same type variant

UMIN <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean minimum = (o1 == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 integer element1;
 integer element2;
 integer maxmin;

 for e = 0 to elements-1
     element1 = Int(Elem[operand1, e, esize], unsigned);
     element2 = Int(Elem[operand2, e, esize], unsigned);
     maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
              Elem[result, e, esize] = maxmin<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: UMINP
description:
Unsigned minimum pairwise       (C7.3.315)




  31 30 29 28 27 26 25 24 23 22 21 20          16 15 14 13 12 11 10 9                 5 4           0
  0 Q 1 0 1 1 1 0 size 1                 Rm         1 0 1 0 1 1               Rn              Rd
        U                                                       o1


Three registers of the same type variant

UMINP <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean minimum = (o1 == '1');


Assembler symbols

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1

              It is RESERVED when size = 11, Q = x.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Vm>          Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];
 bits(datasize) result;
 bits(2*datasize) concat = operand2:operand1;
 integer element1;
 integer element2;
 integer maxmin;

 for e = 0 to elements-1
     element1 = Int(Elem[concat, 2*e, esize], unsigned);
     element2 = Int(Elem[concat, (2*e)+1, esize], unsigned);
     maxmin = if minimum then Min(element1, element2) else Max(element1, element2);
              Elem[result, e, esize] = maxmin<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: UMINV
description:
Unsigned minimum across vector       (C7.3.316)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9                  5 4            0
  0 Q 1 0 1 1 1 0 size 1 1 0 0 0 1 1 0 1 0 1 0                                 Rn               Rd
        U                                        op


Advanced SIMD variant

UMINV <V><d>, <Vn>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if size:Q == '100' then ReservedValue();
 if size == '11' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean min = (op == '1');


Assembler symbols

<V>           Is the destination width specifier, encoded in the "size" field. It can have the following values:

              B           when size = 00

              H           when size = 01

              S           when size = 10

              It is RESERVED when size = 11.

<d>           Is the number of the SIMD&FP destination register, encoded in the "Rd" field.

<Vn>          Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<T>           Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              8B          when size = 00, Q = 0

              16B         when size = 00, Q = 1

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              4S          when size = 10, Q = 1

              It is RESERVED when:

              .      size = 10, Q = 0.

              .      size = 11, Q = x.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 integer maxmin;
 integer element;

         maxmin = Int(Elem[operand, 0, esize], unsigned);
         for e = 1 to elements-1
              element = Int(Elem[operand, e, esize], unsigned);
              maxmin = if min then Min(maxmin, element) else Max(maxmin, element);

         V[d] = maxmin<esize-1:0>;


platform: ARM
mnem: UMLAL
description:
Unsigned multiply-add long (vector, by element)       (C7.3.317)




  31 30 29 28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 1 size L M                  Rm        0 0 1 0 H 0               Rn               Rd
        U                                                o2


Vector variant

UMLAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);      Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean sub_op = (o2 == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1
                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01

                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         Restricted to V0-V15 when element size <Ts> is H.

       <Ts>              Is an element size specifier, encoded in the "size" field. It can have the following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <index>           Is the element index encoded in the "size:L:H:M" field. It can have the following values:

                         H:L:M       when size = 01

                         H:L         when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(idxdsize)      operand2 = V[m];
         bits(2*datasize) operand3 = V[d];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         bits(2*esize) product;

         element2 = Int(Elem[operand2, index, esize], unsigned);
         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              product = (element1 * element2)<2*esize-1:0>;
              if sub_op then
                   Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product;
              else
                   Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product;

         V[d] = result;


platform: ARM
mnem: UMLSL
description:
Unsigned multiply-subtract long (vector, by element)       (C7.3.319)




  31 30 29 28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 1 size L M                  Rm        0 1 1 0 H 0               Rn               Rd
        U                                                o2


Vector variant

UMLSL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);      Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 boolean unsigned = (U == '1');
 boolean sub_op = (o2 == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1
                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01

                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         Restricted to V0-V15 when element size <Ts> is H.

       <Ts>              Is an element size specifier, encoded in the "size" field. It can have the following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <index>           Is the element index encoded in the "size:L:H:M" field. It can have the following values:

                         H:L:M       when size = 01

                         H:L         when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(idxdsize)      operand2 = V[m];
         bits(2*datasize) operand3 = V[d];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         bits(2*esize) product;

         element2 = Int(Elem[operand2, index, esize], unsigned);
         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              product = (element1 * element2)<2*esize-1:0>;
              if sub_op then
                   Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] - product;
              else
                   Elem[result, e, 2*esize] = Elem[operand3, e, 2*esize] + product;

         V[d] = result;


platform: ARM
mnem: UMOV
description:
Unsigned move vector element to general-purpose register       (C7.3.321)

This instruction is used by the alias MOV (to general). The alias is always the preferred disassembly.




  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                  5 4           0
  0 Q 0 0 1 1 1 0 0 0 0                    imm5        0 0 1 1 1 1                Rn             Rd




32-bit variant

Applies when Q = 0.

UMOV <Wd>, <Vn>.<Ts>[<index>]


64-bit variant

Applies when Q = 1.

UMOV <Xd>, <Vn>.<Ts>[<index>]


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 integer size;
 case Q:imm5 of
     when '0xxxx1' size = 0;         // UMOV Wd, Vn.B
     when '0xxx10' size = 1;         // UMOV Wd, Vn.H
     when '0xx100' size = 2;         // UMOV Wd, Vn.S
     when '1x1000' size = 3;         // UMOV Xd, Vn.D
     otherwise        UnallocatedEncoding();

 integer idxdsize = if imm5<4> == '1' then 128 else 64;
 integer index = UInt(imm5<4:size+1>);
 integer esize = 8 << size;
 integer datasize = if Q == '1' then 64 else 32;


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Vn>            Is the name of the SIMD&FP source register, encoded in the "Rn" field.

<Ts>            For the 32-bit variant: is an element size specifier, encoded in the "imm5" field. It can have the
                following values:

                B           when imm5 = xxxx1

                H           when imm5 = xxx10

                S           when imm5 = xx100

                It is RESERVED when imm5 = xx000.

                For the 64-bit variant: is an element size specifier, encoded in the "imm5" field. It can have the
                following values:

                D           when imm5 = x1000
                         It is RESERVED when:

                         .      imm5 = x0000.

                         .      imm5 = xxxx1.

                         .      imm5 = xxx10.

                         .      imm5 = xx100.

       <index>           For the 32-bit variant: is the element index encoded in the "imm5" field. It can have the following
                         values:

                         imm5<4:1>  when imm5 = xxxx1

                         imm5<4:2>  when imm5 = xxx10

                         imm5<4:3>  when imm5 = xx100

                         It is RESERVED when imm5 = xx000.

                         For the 64-bit variant: is the element index encoded in "imm5<4>".


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(idxdsize) operand = V[n];

         X[d] = ZeroExtend(Elem[operand, index, esize], datasize);


platform: ARM
mnem: UMULL2
description:
Unsigned multiply long (vector, by element)       (C7.3.322)




  31 30 29 28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11 10 9                5 4             0
  0 Q 1 0 1 1 1 1 size L M                  Rm        1 0 1 0 H 0               Rn               Rd
        U


Vector variant

UMULL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>]


Decode for this encoding

 integer idxdsize = if H == '1' then 128 else 64;
 integer index;
 bit Rmhi;
 case size of
     when '01' index = UInt(H:L:M); Rmhi = '0';
     when '10' index = UInt(H:L);      Rmhi = M;
     otherwise UnallocatedEncoding();

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rmhi:Rm);

 integer esize = 8 << UInt(size);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;
 boolean unsigned = (U == '1');


Assembler symbols

2             Is the second and upper half specifier. If present it causes the operation to be performed on the upper
              64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
              the following values:

              [absent]    when Q = 0

              [present]   when Q = 1

<Vd>          Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

<Ta>          Is an arrangement specifier, encoded in the "size" field. It can have the following values:

              4S          when size = 01

              2D          when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<Vn>          Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

<Tb>          Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

              4H          when size = 01, Q = 0

              8H          when size = 01, Q = 1

              2S          when size = 10, Q = 0

              4S          when size = 10, Q = 1
                         It is RESERVED when:

                         .      size = 00, Q = x.

                         .      size = 11, Q = x.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "size:M:Rm" field. It can have
                         the following values:

                         0:Rm        when size = 01

                         M:Rm        when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

                         Restricted to V0-V15 when element size <Ts> is H.

       <Ts>              Is an element size specifier, encoded in the "size" field. It can have the following values:

                         H           when size = 01

                         S           when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.

       <index>           Is the element index encoded in the "size:L:H:M" field. It can have the following values:

                         H:L:M       when size = 01

                         H:L         when size = 10

                         It is RESERVED when:

                         .      size = 00.

                         .      size = 11.


       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize)      operand1 = Vpart[n, part];
         bits(idxdsize)      operand2 = V[m];
         bits(2*datasize) result;
         integer element1;
         integer element2;
         bits(2*esize) product;

         element2 = Int(Elem[operand2, index, esize], unsigned);
         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              product = (element1 * element2)<2*esize-1:0>;
              Elem[result, e, 2*esize] = product;

         V[d] = result;


platform: ARM
mnem: UQADD
description:
Unsigned saturating add       (C7.3.324)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20           16 15 14 13 12 11 10 9                5 4          0
  0 1 1 1 1 1 1 0 size 1                  Rm         0 0 0 0 1 1               Rn             Rd
        U


Scalar variant

UQADD <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;
 boolean unsigned = (U == '1');


Vector


  31 30 29 28 27 26 25 24 23 22 21 20           16 15 14 13 12 11 10 9                5 4          0
  0 Q 1 0 1 1 1 0 size 1                  Rm         0 0 0 0 1 1               Rn             Rd
        U


Vector variant

UQADD <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size:Q == '110' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;
 boolean unsigned = (U == '1');


Assembler symbols

<V>           Is a width specifier, encoded in the "size" field. It can have the following values:

              B           when size = 00

              H           when size = 01

              S           when size = 10

              D           when size = 11

<d>           Is the number of the SIMD&FP destination register, in the "Rd" field.

<n>           Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

<m>           Is the number of the second SIMD&FP source register, encoded in the "Rm" field.
       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         2D          when size = 11, Q = 1

                         It is RESERVED when size = 11, Q = 0.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand1 = V[n];
         bits(datasize) operand2 = V[m];
         bits(datasize) result;
         integer element1;
         integer element2;
         integer sum;
         boolean sat;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              sum = element1 + element2;
              (Elem[result, e, esize], sat) = SatQ(sum, esize, unsigned);
              if sat then FPSR.QC = '1';

         V[d] = result;


platform: ARM
mnem: UQRSHL
description:
Unsigned saturating rounding shift left (register)       (C7.3.325)


Scalar


  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
  0 1 1 1 1 1 1 0 size 1                   Rm        0 1 0 1 1 1                Rn             Rd
        U                                                      R S


Scalar variant

UQRSHL <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 8 << UInt(size);
 integer datasize = esize;
 integer elements = 1;
 boolean unsigned = (U == '1');
 boolean rounding = (R == '1');
 boolean saturating = (S == '1');
 if S == '0' && size != '11' then ReservedValue();


Vector


  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14 13 12 11 10 9                5 4          0
  0 Q 1 0 1 1 1 0 size 1                   Rm        0 1 0 1 1 1                Rn             Rd
        U                                                      R S


Vector variant

UQRSHL <Vd>.<T>, <Vn>.<T>, <Vm>.<T>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if size:Q == '110' then ReservedValue();
 integer esize = 8 << UInt(size);
 integer datasize = if Q == '1' then 128 else 64;
 integer elements = datasize DIV esize;
 boolean unsigned = (U == '1');
 boolean rounding = (R == '1');
 boolean saturating = (S == '1');


Assembler symbols

<V>           Is a width specifier, encoded in the "size" field. It can have the following values:

              B           when size = 00

              H           when size = 01

              S           when size = 10

              D           when size = 11

<d>           Is the number of the SIMD&FP destination register, in the "Rd" field.
       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <m>               Is the number of the second SIMD&FP source register, encoded in the "Rm" field.

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <T>               Is an arrangement specifier, encoded in the "size:Q" field. It can have the following values:

                         8B          when size = 00, Q = 0

                         16B         when size = 00, Q = 1

                         4H          when size = 01, Q = 0

                         8H          when size = 01, Q = 1

                         2S          when size = 10, Q = 0

                         4S          when size = 10, Q = 1

                         2D          when size = 11, Q = 1

                         It is RESERVED when size = 11, Q = 0.

       <Vn>              Is the name of the first SIMD&FP source register, encoded in the "Rn" field.

       <Vm>              Is the name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand1 = V[n];
         bits(datasize) operand2 = V[m];
         bits(datasize) result;

         integer round_const = 0;
         integer shift;
         integer element;
         boolean sat;

         for e = 0 to elements-1
              shift = SInt(Elem[operand2, e, esize]<7:0>);
              if rounding then
                   round_const = 1 << (-shift - 1); // 0 for left shift, 2^(n-1) for right shift
              element = (Int(Elem[operand1, e, esize], unsigned) + round_const) << shift;
              if saturating then
                   (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned);
                   if sat then FPSR.QC = '1';
              else
                   Elem[result, e, esize] = element<esize-1:0>;

         V[d] = result;


platform: ARM
mnem: UQRSHRN
description:
Unsigned saturating rounded shift right narrow (immediate)       (C7.3.326)


Scalar


  31 30 29 28 27 26 25 24 23 22         19 18    16 15 14 13 12 11 10 9                5 4          0
  0 1 1 1 1 1 1 1 0            !=0000       immb    1 0 0 1 1 1                Rn             Rd
        U                       immh                             op


Scalar variant

UQRSHRN <Vb><d>, <Va><n>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then ReservedValue();
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = esize;
 integer elements = 1;
 integer part = 0;

 integer shift = (2 * esize) - UInt(immh:immb);
 boolean round = (op == '1');
 boolean unsigned = (U == '1');


Vector


  31 30 29 28 27 26 25 24 23 22         19 18    16 15 14 13 12 11 10 9                5 4          0
  0 Q 1 0 1 1 1 1 0            !=0000       immb    1 0 0 1 1 1                Rn             Rd
        U                       immh                             op


Vector variant

UQRSHRN{2} <Vd>.<Tb>, <Vn>.<Ta>, #<shift>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);

 if immh == '0000' then SEE "Advanced SIMD modified immediate";
 if immh<3> == '1' then ReservedValue();
 integer esize = 8 << HighestSetBit(immh);
 integer datasize = 64;
 integer part = UInt(Q);
 integer elements = datasize DIV esize;

 integer shift = (2 * esize) - UInt(immh:immb);
 boolean round = (op == '1');
 boolean unsigned = (U == '1');
       Assembler symbols

       2                 Is the second and upper half specifier. If present it causes the operation to be performed on the upper
                         64 bits of the registers holding the narrower elements, and is encoded in the "Q" field. It can have
                         the following values:

                         [absent]    when Q = 0

                         [present]   when Q = 1

       <Vd>              Is the name of the SIMD&FP destination register, encoded in the "Rd" field.

       <Tb>              Is an arrangement specifier, encoded in the "immh:Q" field. It can have the following values:

                         8B          when immh = 0001, Q = 0

                         16B         when immh = 0001, Q = 1

                         4H          when immh = 001x, Q = 0

                         8H          when immh = 001x, Q = 1

                         2S          when immh = 01xx, Q = 0

                         4S          when immh = 01xx, Q = 1

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000, Q = x.

                         It is RESERVED when immh = 1xxx, Q = x.

       <Vn>              Is the name of the SIMD&FP source register, encoded in the "Rn" field.

       <Ta>              Is an arrangement specifier, encoded in the "immh" field. It can have the following values:

                         8H          when immh = 0001

                         4S          when immh = 001x

                         2D          when immh = 01xx

                         See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

                         It is RESERVED when immh = 1xxx.

       <Vb>              Is the destination width specifier, encoded in the "immh" field. It can have the following values:

                         B           when immh = 0001

                         H           when immh = 001x

                         S           when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

       <d>               Is the number of the SIMD&FP destination register, in the "Rd" field.

       <Va>              Is the source width specifier, encoded in the "immh" field. It can have the following values:

                         H           when immh = 0001

                         S           when immh = 001x

                         D           when immh = 01xx

                         It is RESERVED when:

                         .      immh = 0000.

                         .      immh = 1xxx.

       <n>               Is the number of the first SIMD&FP source register, encoded in the "Rn" field.

       <shift>           For the scalar variant: is the right shift amount, in the range 1 to the destination operand width in
                         bits, encoded in the "immh:immb" field. It can have the following values:

                         (16-UInt(immh:immb))when immh = 0001
              (32-UInt(immh:immb))when immh = 001x

              (64-UInt(immh:immb))when immh = 01xx

              It is RESERVED when:

              .      immh = 0000.

              .      immh = 1xxx.

              For the vector variant: is the right shift amount, in the range 1 to the destination element width in
              bits, encoded in the "immh:immb" field. It can have the following values:

              (16-UInt(immh:immb))when immh = 0001

              (32-UInt(immh:immb))when immh = 001x

              (64-UInt(immh:immb))when immh = 01xx

              See Advanced SIMD modified immediate on page C4-213 when immh = 0000.

              It is RESERVED when immh = 1xxx.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize*2) operand = V[n];
 bits(datasize) result;
 integer round_const = if round then (1 << (shift - 1)) else 0;
 integer element;
 boolean sat;

 for e = 0 to elements-1
     element = (Int(Elem[operand, e, 2*esize], unsigned) + round_const) >> shift;
     (Elem[result, e, esize], sat) = SatQ(element, esize, unsigned);
    if sat then FPSR.QC = '1';

 Vpart[d, part] = result;


