PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE instructions (platform TEXT, mnem TEXT, description TEXT);
INSERT INTO "instructions" VALUES('ARM','ADC','Add with carry: Rd = Rn + Rm + C       (C6.6.1)




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


32-bit variant

Applies when sf = 0.

ADC <Wd>, <Wn>, <Wm>


64-bit variant

Applies when sf = 1.

ADC <Xd>, <Xn>, <Xm>


Decode for all variants of this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  integer datasize = if sf == ''1'' then 64 else 32;
  boolean sub_op = (op == ''1'');
  boolean setflags = (S == ''1'');


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.


Operation

  bits(datasize) result;
  bits(datasize) operand1 = X[n];
  bits(datasize) operand2 = X[m];
  bits(4) nzcv;

  if sub_op then
       operand2 = NOT(operand2);

  (result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C);

  if setflags then
       PSTATE.<N,Z,C,V> = nzcv;

  X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ADCS','Add with carry, setting the condition flags: Rd = Rn + Rm + C       (C6.6.2)




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


32-bit variant

Applies when sf = 0.

ADCS <Wd>, <Wn>, <Wm>


64-bit variant

Applies when sf = 1.

ADCS <Xd>, <Xn>, <Xm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean sub_op = (op == ''1'');
 boolean setflags = (S == ''1'');


Assembler symbols

<Wd>           Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>           Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>           Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>           Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>           Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>           Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.


Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];
 bits(4) nzcv;

 if sub_op then
     operand2 = NOT(operand2);

 (result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C);

 if setflags then
     PSTATE.<N,Z,C,V> = nzcv;

 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ADD','       Add (extended register): Rd = Rn + LSL(extend(Rm), amount)       (C6.6.3)




           31 30 29 28 27 26 25 24 23 22 21 20            16 15     13 12      10 9            5 4            0
           sf 0 0 0 1 0 1 1 0 0 1                  Rm          option    imm3           Rn              Rd
              op S


       32-bit variant

       Applies when sf = 0.

       ADD <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}


       64-bit variant

       Applies when sf = 1.

       ADD <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer datasize = if sf == ''1'' then 64 else 32;
         boolean sub_op = (op == ''1'');
         boolean setflags = (S == ''1'');
         ExtendType extend_type = DecodeRegExtend(option);
         integer shift = UInt(imm3);
         if shift > 4 then ReservedValue();


       Assembler symbols

       <Wd|WSP>        Is the 32-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
                       field.

       <Wn|WSP>        Is the 32-bit name of the first source general-purpose register or stack pointer, encoded in the "Rn"
                       field.

       <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <Xd|SP>         Is the 64-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
                       field.

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

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

                       W           when option = 00x

                       W           when option = 010

                       X           when option = x11

                       W           when option = 10x

                       W           when option = 110

       <m>             Is the number [0-30] of the second general-purpose source register or the name ZR (31), encoded in
                       the "Rm" field.
<extend>      For the 32-bit variant: is the extension to be applied to the second source operand, encoded in the
              "option" field. It can have the following values:

              UXTB         when option = 000

              UXTH         when option = 001

              LSL|UXTW     when option = 010

              UXTX         when option = 011

              SXTB         when option = 100

              SXTH         when option = 101

              SXTW         when option = 110

              SXTX         when option = 111

              If "Rd" or "Rn" is ''11111'' (WSP) and "option" is ''010'' then LSL is preferred, but may be omitted
              when "imm3" is ''000''. In all other cases <extend> is required and must be UXTW when "option" is
              ''010''.

              For the 64-bit variant: is the extension to be applied to the second source operand, encoded in the
              "option" field. It can have the following values:

              UXTB         when option = 000

              UXTH         when option = 001

              UXTW         when option = 010

              LSL|UXTX     when option = 011

              SXTB         when option = 100

              SXTH         when option = 101

              SXTW         when option = 110

              SXTX         when option = 111

              If "Rd" or "Rn" is ''11111'' (SP) and "option" is ''011'' then LSL is preferred, but may be omitted when
              "imm3" is ''000''. In all other cases <extend> is required and must be UXTX when "option" is ''011''.

<amount>      Is the left shift amount to be applied after extension in the range 0 to 4, defaulting to 0, encoded in
              the "imm3" field. It must be absent when <extend> is absent, is required when <extend> is LSL,
              and is optional when <extend> is present but not LSL.


Operation

 bits(datasize) result;
 bits(datasize) operand1 = if n == 31 then SP[] else X[n];
 bits(datasize) operand2 = ExtendReg(m, extend_type, shift);
 bits(4) nzcv;
 bit carry_in;

 if sub_op then
     operand2 = NOT(operand2);
     carry_in = ''1'';
 else
     carry_in = ''0'';

 (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);

 if setflags then
     PSTATE.<N,Z,C,V> = nzcv;

 if d == 31 && !setflags then
     SP[] = result;
 else
     X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ADDS','       Add (extended register), setting the condition flags: Rd = Rn + LSL(extend(Rm), amount)       (C6.6.6)

       This instruction is used by the alias CMN (extended register). See the Alias conditions table for details of when each
       alias is preferred.




           31 30 29 28 27 26 25 24 23 22 21 20             16 15     13 12      10 9            5 4             0
           sf 0 1 0 1 0 1 1 0 0 1                   Rm          option    imm3           Rn              Rd
              op S


       32-bit variant

       Applies when sf = 0.

       ADDS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}


       64-bit variant

       Applies when sf = 1.

       ADDS <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer datasize = if sf == ''1'' then 64 else 32;
         boolean sub_op = (op == ''1'');
         boolean setflags = (S == ''1'');
         ExtendType extend_type = DecodeRegExtend(option);
         integer shift = UInt(imm3);
         if shift > 4 then ReservedValue();


       Alias conditions


                             Alias                     is preferred when

                             CMN (extended             Rd == ''11111''
                             register)


       Assembler symbols

       <Wd>             Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn|WSP>         Is the 32-bit name of the first source general-purpose register or stack pointer, encoded in the "Rn"
                        field.

       <Wm>             Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

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

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

                        W           when option = 00x
              W            when option = 010

              X            when option = x11

              W            when option = 10x

              W            when option = 110

<m>           Is the number [0-30] of the second general-purpose source register or the name ZR (31), encoded in
              the "Rm" field.

<extend>      For the 32-bit variant: is the extension to be applied to the second source operand, encoded in the
              "option" field. It can have the following values:

              UXTB         when option = 000

              UXTH         when option = 001

              LSL|UXTW     when option = 010

              UXTX         when option = 011

              SXTB         when option = 100

              SXTH         when option = 101

              SXTW         when option = 110

              SXTX         when option = 111

              If "Rn" is ''11111'' (WSP) and "option" is ''010'' then LSL is preferred, but may be omitted when
              "imm3" is ''000''. In all other cases <extend> is required and must be UXTW when "option" is ''010''.

              For the 64-bit variant: is the extension to be applied to the second source operand, encoded in the
              "option" field. It can have the following values:

              UXTB         when option = 000

              UXTH         when option = 001

              UXTW         when option = 010

              LSL|UXTX     when option = 011

              SXTB         when option = 100

              SXTH         when option = 101

              SXTW         when option = 110

              SXTX         when option = 111

              If "Rn" is ''11111'' (SP) and "option" is ''011'' then LSL is preferred, but may be omitted when "imm3"
              is ''000''. In all other cases <extend> is required and must be UXTX when "option" is ''011''.

<amount>      Is the left shift amount to be applied after extension in the range 0 to 4, defaulting to 0, encoded in
              the "imm3" field. It must be absent when <extend> is absent, is required when <extend> is LSL,
              and is optional when <extend> is present but not LSL.


Operation

 bits(datasize) result;
 bits(datasize) operand1 = if n == 31 then SP[] else X[n];
 bits(datasize) operand2 = ExtendReg(m, extend_type, shift);
 bits(4) nzcv;
 bit carry_in;

 if sub_op then
     operand2 = NOT(operand2);
     carry_in = ''1'';
 else
     carry_in = ''0'';

 (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);

 if setflags then
              PSTATE.<N,Z,C,V> = nzcv;

         if d == 31 && !setflags then
              SP[] = result;
         else
              X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ADR','Address of label at a PC-relative offset       (C6.6.9)




  31 30 29 28 27 26 25 24 23                                                           5 4              0
  0 immlo 1 0 0 0 0                                   immhi                                     Rd
  op


Literal variant

ADR <Xd>, <label>


Decode for this encoding

 integer d = UInt(Rd);
 boolean page = (op == ''1'');
 bits(64) imm;

 if page then
     imm = SignExtend(immhi:immlo:Zeros(12), 64);
 else
     imm = SignExtend(immhi:immlo, 64);


Assembler symbols

<Xd>           Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<label>        Is the program label whose address is to be calculated. Its offset from the address of this instruction,
               in the range +/-1MB, is encoded in "immhi:immlo".


Operation

 bits(64) base = PC[];

 if page then
     base<11:0> = Zeros(12);

 X[d] = base + imm;');
INSERT INTO "instructions" VALUES('ARM','ADRP','Address of 4KB page at a PC-relative offset       (C6.6.10)




    31 30 29 28 27 26 25 24 23                                                        5 4             0
    1 immlo 1 0 0 0 0                                   immhi                                  Rd
    op


Literal variant

ADRP <Xd>, <label>


Decode for this encoding

  integer d = UInt(Rd);
  boolean page = (op == ''1'');
  bits(64) imm;

  if page then
       imm = SignExtend(immhi:immlo:Zeros(12), 64);
  else
       imm = SignExtend(immhi:immlo, 64);


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<label>         Is the program label whose 4KB page address is to be calculated. Its offset from the page address of
                this instruction, in the range +/-4GB, is encoded as "immhi:immlo" times 4096.


Operation

  bits(64) base = PC[];

  if page then
       base<11:0> = Zeros(12);

  X[d] = base + imm;');
INSERT INTO "instructions" VALUES('ARM','AND','Bitwise AND (immediate): Rd = Rn AND imm       (C6.6.11)




  31 30 29 28 27 26 25 24 23 22 21               16 15             10 9             5 4              0
  sf 0 0 1 0 0 1 0 0 N                 immr               imms               Rn               Rd
     opc


32-bit variant

Applies when sf = 0 && N = 0.

AND <Wd|WSP>, <Wn>, #<imm>


64-bit variant

Applies when sf = 1.

AND <Xd|SP>, <Xn>, #<imm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean setflags;
 LogicalOp op;
 case opc of
     when ''00'' op = LogicalOp_AND; setflags = FALSE;
     when ''01'' op = LogicalOp_ORR; setflags = FALSE;
     when ''10'' op = LogicalOp_EOR; setflags = FALSE;
     when ''11'' op = LogicalOp_AND; setflags = TRUE;

 bits(datasize) imm;
 if sf == ''0'' && N != ''0'' then ReservedValue();
 (imm, -) = DecodeBitMasks(N, imms, immr, TRUE);


Assembler symbols

<Wd|WSP>      Is the 32-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
              field.

<Wn>          Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd|SP>       Is the 64-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
              field.

<Xn>          Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<imm>         Is the bitmask immediate, encoded in "N:imms:immr".


Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = imm;

 case op of
     when LogicalOp_AND result = operand1 AND operand2;
     when LogicalOp_ORR result = operand1 OR     operand2;
     when LogicalOp_EOR result = operand1 EOR operand2;

         if setflags then
              PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

         if d == 31 && !setflags then
              SP[] = result;
         else
              X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ANDS','Bitwise AND (immediate), setting the condition flags: Rd = Rn AND imm       (C6.6.13)

This instruction is used by the alias TST (immediate). See the Alias conditions table for details of when each alias
is preferred.




  31 30 29 28 27 26 25 24 23 22 21                16 15              10 9             5 4              0
   sf 1 1 1 0 0 1 0 0 N                  immr              imms                Rn              Rd
       opc


32-bit variant

Applies when sf = 0 && N = 0.

ANDS <Wd>, <Wn>, #<imm>


64-bit variant

Applies when sf = 1.

ANDS <Xd>, <Xn>, #<imm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean setflags;
 LogicalOp op;
 case opc of
     when ''00'' op = LogicalOp_AND; setflags = FALSE;
     when ''01'' op = LogicalOp_ORR; setflags = FALSE;
     when ''10'' op = LogicalOp_EOR; setflags = FALSE;
     when ''11'' op = LogicalOp_AND; setflags = TRUE;

 bits(datasize) imm;
 if sf == ''0'' && N != ''0'' then ReservedValue();
 (imm, -) = DecodeBitMasks(N, imms, immr, TRUE);


Alias conditions


                     Alias                   is preferred when

                     TST (immediate)         Rd == ''11111''



Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<imm>           Is the bitmask immediate, encoded in "N:imms:immr".
       Operation

         bits(datasize) result;
         bits(datasize) operand1 = X[n];
         bits(datasize) operand2 = imm;

         case op of
              when LogicalOp_AND result = operand1 AND operand2;
              when LogicalOp_ORR result = operand1 OR  operand2;
              when LogicalOp_EOR result = operand1 EOR operand2;

         if setflags then
              PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

         if d == 31 && !setflags then
              SP[] = result;
         else
              X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ASR','Arithmetic shift right (register): Rd = ASR(Rn, Rm)       (C6.6.15)

This instruction is an alias of the ASRV instruction. This means that:

.      The encodings in this description are named to match the encodings of ASRV.

.      The description of ASRV gives the operational pseudocode for this instruction.




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


32-bit variant

Applies when sf = 0.

ASR <Wd>, <Wn>, <Wm>

is equivalent to

ASRV <Wd>, <Wn>, <Wm>

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

ASR <Xd>, <Xn>, <Xm>

is equivalent to

ASRV <Xd>, <Xn>, <Xm>

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding a shift amount from 0 to
                31 in its bottom 5 bits, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding a shift amount from 0 to
                63 in its bottom 6 bits, encoded in the "Rm" field.


Operation

The description of ASRV gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','ASRV','Arithmetic shift right variable : Rd = ASR(Rn, Rm)       (C6.6.17)

This instruction is used by the alias ASR (register). 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
  sf 0 0 1 1 0 1 0 1 1 0                    Rm         0 0 1 0 1 0              Rn              Rd
                                                                     op2


32-bit variant

Applies when sf = 0.

ASRV <Wd>, <Wn>, <Wm>


64-bit variant

Applies when sf = 1.

ASRV <Xd>, <Xn>, <Xm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 ShiftType shift_type = DecodeShift(op2);


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding a shift amount from 0 to
                31 in its bottom 5 bits, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding a shift amount from 0 to
                63 in its bottom 6 bits, encoded in the "Rm" field.


Operation

 bits(datasize) result;
 bits(datasize) operand2 = X[m];

 result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize);
 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','AT','Address translate       (C6.6.18)

This instruction is an alias of the SYS instruction. This means that:

.       The encodings in this description are named to match the encodings of SYS.

.       The description of SYS gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20 19 18      16 15       12 11        8 7      5 4             0
    1 1 0 1 0 1 0 1 0 0 0 0 1                  op1     0 1 1 1 1 0 0 0           op2           Rt
                                    L                     CRn         CRm


System variant

AT <at_op>, <Xt>

is equivalent to

SYS #<op1>, C7, C8, #<op2>, <Xt>

and is the preferred disassembly when SysOp(op1,''0111'',''1000'',op2) == Sys_AT.


Assembler symbols

<at_op>         Is an AT operation name, as listed for the AT system operation group, encoded in the "op1:op2"
                field. It can have the following values:

                S1E1R        when op1 = 000, op2 = 000

                S1E1W        when op1 = 000, op2 = 001

                S1E0R        when op1 = 000, op2 = 010

                S1E0W        when op1 = 000, op2 = 011

                S1E2R        when op1 = 100, op2 = 000

                S1E2W        when op1 = 100, op2 = 001

                S12E1R       when op1 = 100, op2 = 100

                S12E1W       when op1 = 100, op2 = 101

                S12E0R       when op1 = 100, op2 = 110

                S12E0W       when op1 = 100, op2 = 111

                S1E3R        when op1 = 110, op2 = 000

                S1E3W        when op1 = 110, op2 = 001

<op1>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op1" field.

<op2>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op2" field.

<Xt>            Is the 64-bit name of the general-purpose source register, encoded in the "Rt" field.


Operation

The description of SYS gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','B.cond','Branch conditionally to a label at a PC-relative offset, with a hint that this is not a subroutine call or return.       (C6.6.19)




  31 30 29 28 27 26 25 24 23                                                              5 4 3            0
  0 1 0 1 0 1 0 0                                      imm19                                 0     cond




19-bit signed PC-relative branch offset variant

B.<cond> <label>


Decode for this encoding

 bits(64) offset = SignExtend(imm19:''00'', 64);
 bits(4) condition = cond;


Assembler symbols

<cond>        Is one of the standard conditions, encoded in the "cond" field in the standard way.

<label>       Is the program label to be conditionally branched to. Its offset from the address of this instruction,
              in the range +/-1MB, is encoded as "imm19" times 4.


Operation

 if ConditionHolds(condition) then
     BranchTo(PC[] + offset, BranchType_JMP);');
INSERT INTO "instructions" VALUES('ARM','B','Branch causes an unconditional branch to a label at a PC-relative offset, with a hint that this is not a subroutine call       (C6.6.20)
or return.




    31 30 29 28 27 26 25                                                                                  0
    0 0 0 1 0 1                                            imm26
    op


26-bit signed PC-relative branch offset variant

B <label>


Decode for this encoding

  BranchType branch_type = if op == ''1'' then BranchType_CALL else BranchType_JMP;
  bits(64) offset = SignExtend(imm26:''00'', 64);


Assembler symbols

<label>         Is the program label to be unconditionally branched to. Its offset from the address of this instruction,
                in the range +/-128MB, is encoded as "imm26" times 4.


Operation

  if branch_type == BranchType_CALL then X[30] = PC[] + 4;

  BranchTo(PC[] + offset, branch_type);');
INSERT INTO "instructions" VALUES('ARM','BFI','Bitfield insert, leaving other bits unchanged       (C6.6.21)

This instruction is an alias of the BFM instruction. This means that:

.      The encodings in this description are named to match the encodings of BFM.

.      The description of BFM gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                    16 15                10 9            5 4               0
   sf 0 1 1 0 0 1 1 0 N                     immr                imms                Rn               Rd
      opc


32-bit variant

Applies when sf = 0 && N = 0.

BFI <Wd>, <Wn>, #<lsb>, #<width>

is equivalent to

BFM  <Wd>, <Wn>, #(-<lsb> MOD 32), #(<width>-1)

and is the preferred disassembly when UInt(imms) < UInt(immr).

64-bit variant

Applies when sf = 1 && N = 1.

BFI <Xd>, <Xn>, #<lsb>, #<width>

is equivalent to

BFM  <Xd>, <Xn>, #(-<lsb> MOD 64), #(<width>-1)

and is the preferred disassembly when UInt(imms) < UInt(immr).


Assembler symbols

<Wd>              Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>              Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>              Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>              Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<lsb>             For the 32-bit variant: is the bit number of the lsb of the destination bitfield, in the range 0 to 31.

                  For the 64-bit variant: is the bit number of the lsb of the destination bitfield, in the range 0 to 63.

<width>           For the 32-bit variant: is the width of the bitfield, in the range 1 to 32-<lsb>.

                  For the 64-bit variant: is the width of the bitfield, in the range 1 to 64-<lsb>.


Operation

The description of BFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','BFM','       Bitfield move, leaving other bits unchanged       (C6.6.22)

       This instruction is used by the aliases BFI and BFXIL. See the Alias conditions on page C6-433 table for details of
       when each alias is preferred.




           31 30 29 28 27 26 25 24 23 22 21              16 15              10 9            5 4            0
           sf 0 1 1 0 0 1 1 0 N                 immr               imms              Rn            Rd
               opc


       32-bit variant

       Applies when sf = 0 && N = 0.

       BFM <Wd>, <Wn>, #<immr>, #<imms>


       64-bit variant

       Applies when sf = 1 && N = 1.

       BFM <Xd>, <Xn>, #<immr>, #<imms>


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer datasize = if sf == ''1'' then 64 else 32;

         boolean inzero;
         boolean extend;
         integer R;
         integer S;
         bits(datasize) wmask;
         bits(datasize) tmask;

         case opc of
              when ''00'' inzero = TRUE;    extend = TRUE;      // SBFM
              when ''01'' inzero = FALSE; extend = FALSE;       // BFM
              when ''10'' inzero = TRUE;    extend = FALSE;     // UBFM
              when ''11'' UnallocatedEncoding();

         if sf == ''1'' && N != ''1'' then ReservedValue();
         if sf == ''0'' && (N != ''0'' || immr<5> != ''0'' || imms<5> != ''0'') then ReservedValue();

         R = UInt(immr);
         S = UInt(imms);
         (wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE);
Alias conditions


                   Alias                      is preferred when

                   BFI                        UInt(imms) < UInt(immr)

                   BFXIL                      UInt(imms) >= UInt(immr)



Assembler symbols

<Wd>          Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>          Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>          Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>          Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<immr>        For the 32-bit variant: is the right rotate amount, in the range 0 to 31, encoded in the "immr" field.

              For the 64-bit variant: is the right rotate amount, in the range 0 to 63, encoded in the "immr" field.

<imms>        For the 32-bit variant: is the leftmost bit number to be moved from the source, in the range 0 to 31,
              encoded in the "imms" field.

              For the 64-bit variant: is the leftmost bit number to be moved from the source, in the range 0 to 63,
              encoded in the "imms" field.


Operation

 bits(datasize) dst = if inzero then Zeros() else X[d];
 bits(datasize) src = X[n];

 // perform bitfield move on low bits
 bits(datasize) bot = (dst AND NOT(wmask)) OR (ROR(src, R) AND wmask);

 // determine extension bits (sign, zero or dest register)
 bits(datasize) top = if extend then Replicate(src<S>) else dst;

 // combine extension bits and result bits
 X[d] = (top AND NOT(tmask)) OR (bot AND tmask);');
INSERT INTO "instructions" VALUES('ARM','BFXIL','Bitfield extract and insert at low end, leaving other bits unchanged       (C6.6.23)

This instruction is an alias of the BFM instruction. This means that:

.       The encodings in this description are named to match the encodings of BFM.

.       The description of BFM gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21                 16 15                10 9            5 4              0
    sf 0 1 1 0 0 1 1 0 N                   immr                imms                Rn              Rd
        opc


32-bit variant

Applies when sf = 0 && N = 0.

BFXIL <Wd>, <Wn>, #<lsb>, #<width>

is equivalent to

BFM    <Wd>, <Wn>, #<lsb>, #(<lsb>+<width>-1)

and is the preferred disassembly when UInt(imms) >= UInt(immr).

64-bit variant

Applies when sf = 1 && N = 1.

BFXIL <Xd>, <Xn>, #<lsb>, #<width>

is equivalent to

BFM    <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1)

and is the preferred disassembly when UInt(imms) >= UInt(immr).


Assembler symbols

<Wd>             Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>             Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>             Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<lsb>            For the 32-bit variant: is the bit number of the lsb of the source bitfield, in the range 0 to 31.

                 For the 64-bit variant: is the bit number of the lsb of the source bitfield, in the range 0 to 63.

<width>          For the 32-bit variant: is the width of the bitfield, in the range 1 to 32-<lsb>.

                 For the 64-bit variant: is the width of the bitfield, in the range 1 to 64-<lsb>.


Operation

The description of BFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','BIC','Bitwise bit clear (shifted register): Rd = Rn AND NOT shift(Rm, amount)       (C6.6.24)




  31 30 29 28 27 26 25 24 23 22 21 20               16 15               10 9             5 4             0
  sf 0 0 0 1 0 1 0 shift 1                   Rm               imm6                Rn            Rd
     opc                            N


32-bit variant

Applies when sf = 0.

BIC <Wd>, <Wn>, <Wm>{, <shift> #<amount>}


64-bit variant

Applies when sf = 1.

BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}


Decode for all variants of this encoding

integer d = UInt(Rd);
integer n = UInt(Rn);
integer m = UInt(Rm);
integer datasize = if sf == ''1'' then 64 else 32;
boolean setflags;
 LogicalOp op;
case opc of
     when ''00'' op = LogicalOp_AND; setflags = FALSE;
     when ''01'' op = LogicalOp_ORR; setflags = FALSE;
     when ''10'' op = LogicalOp_EOR; setflags = FALSE;
     when ''11'' op = LogicalOp_AND; setflags = TRUE;

if sf == ''0'' && imm6<5> == ''1'' then ReservedValue();

 ShiftType shift_type = DecodeShift(shift);
integer shift_amount = UInt(imm6);
boolean invert = (N == ''1'');


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

<shift>         Is the optional shift to be applied to the final source, defaulting to LSL and encoded in the "shift"
                field. It can have the following values:

                LSL          when shift = 00

                LSR          when shift = 01

                ASR          when shift = 10

                ROR          when shift = 11
      <amount>        For the 32-bit variant: is the shift amount, in the range 0 to 31, defaulting to 0 and encoded in the
                      "imm6" field.

                      For the 64-bit variant: is the shift amount, in the range 0 to 63, defaulting to 0 and encoded in the
                      "imm6" field.


      Operation

        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);

        if invert then operand2 = NOT(operand2);

        case op of
             when LogicalOp_AND result = operand1 AND operand2;
             when LogicalOp_ORR result = operand1 OR       operand2;
             when LogicalOp_EOR result = operand1 EOR operand2;

        if setflags then
             PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

        X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','BICS','Bitwise bit clear (shifted register), setting the condition flags: Rd = Rn AND NOT shift(Rm, amount)       (C6.6.25)




  31 30 29 28 27 26 25 24 23 22 21 20                16 15              10 9             5 4             0
  sf 1 1 0 1 0 1 0 shift 1                    Rm               imm6               Rn            Rd
     opc                            N


32-bit variant

Applies when sf = 0.

BICS <Wd>, <Wn>, <Wm>{, <shift> #<amount>}


64-bit variant

Applies when sf = 1.

BICS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean setflags;
 LogicalOp op;
 case opc of
     when ''00'' op = LogicalOp_AND; setflags = FALSE;
     when ''01'' op = LogicalOp_ORR; setflags = FALSE;
     when ''10'' op = LogicalOp_EOR; setflags = FALSE;
     when ''11'' op = LogicalOp_AND; setflags = TRUE;

 if sf == ''0'' && imm6<5> == ''1'' then ReservedValue();

 ShiftType shift_type = DecodeShift(shift);
 integer shift_amount = UInt(imm6);
 boolean invert = (N == ''1'');


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

<shift>         Is the optional shift to be applied to the final source, defaulting to LSL and encoded in the "shift"
                field. It can have the following values:

                LSL          when shift = 00

                LSR          when shift = 01

                ASR          when shift = 10

                ROR          when shift = 11
       <amount>        For the 32-bit variant: is the shift amount, in the range 0 to 31, defaulting to 0 and encoded in the
                       "imm6" field.

                       For the 64-bit variant: is the shift amount, in the range 0 to 63, defaulting to 0 and encoded in the
                       "imm6" field.


       Operation

         bits(datasize) operand1 = X[n];
         bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);

         if invert then operand2 = NOT(operand2);

         case op of
              when LogicalOp_AND result = operand1 AND operand2;
              when LogicalOp_ORR result = operand1 OR       operand2;
              when LogicalOp_EOR result = operand1 EOR operand2;

         if setflags then
              PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

         X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','BL','Branch with Link calls a subroutine at a PC-relative offset, setting the register X30 to PC+4. It provides a hint that       (C6.6.26)
this is not a subroutine call or return.




  31 30 29 28 27 26 25                                                                                    0
   1 0 0 1 0 1                                              imm26
  op


26-bit signed PC-relative branch offset variant

BL <label>


Decode for this encoding

 BranchType branch_type = if op == ''1'' then BranchType_CALL else BranchType_JMP;
 bits(64) offset = SignExtend(imm26:''00'', 64);


Assembler symbols

<label>          Is the program label to be unconditionally branched to. Its offset from the address of this instruction,
                 in the range +/-128MB, is encoded as "imm26" times 4.


Operation

 if branch_type == BranchType_CALL then X[30] = PC[] + 4;

 BranchTo(PC[] + offset, branch_type);');
INSERT INTO "instructions" VALUES('ARM','BLR','Branch with Link to Register calls a subroutine at an address in a register, setting register X30 to PC+4.       (C6.6.27)




    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 3 2 1 0
    1 1 0 1 0 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0                                 Rn         0 0 0 0 0
                                op


Integer variant

BLR <Xn>


Decode for this encoding

  integer n = UInt(Rn);
  BranchType branch_type;

  case op of
       when ''00'' branch_type = BranchType_JMP;
       when ''01'' branch_type = BranchType_CALL;
       when ''10'' branch_type = BranchType_RET;
       otherwise UnallocatedEncoding();


Assembler symbols

<Xn>            Is the 64-bit name of the general-purpose register holding the address to be branched to, encoded in
                the "Rn" field.


Operation

  bits(64) target = X[n];

  if branch_type == BranchType_CALL then X[30] = PC[] + 4;
  BranchTo(target, branch_type);');
INSERT INTO "instructions" VALUES('ARM','BR','Branch to Register branches unconditionally to an address in a register, with a hint that this is not a subroutine return.       (C6.6.28)




  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 3 2 1 0
  1 1 0 1 0 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0                                   Rn           0 0 0 0 0
                               op


Integer variant

BR <Xn>


Decode for this encoding

 integer n = UInt(Rn);
 BranchType branch_type;

 case op of
     when ''00'' branch_type = BranchType_JMP;
     when ''01'' branch_type = BranchType_CALL;
     when ''10'' branch_type = BranchType_RET;
     otherwise UnallocatedEncoding();


Assembler symbols

<Xn>          Is the 64-bit name of the general-purpose register holding the address to be branched to, encoded in
              the "Rn" field.


Operation

 bits(64) target = X[n];

 if branch_type == BranchType_CALL then X[30] = PC[] + 4;
 BranchTo(target, branch_type);');
INSERT INTO "instructions" VALUES('ARM','BRK','Self-hosted debug breakpoint       (C6.6.29)




    31 30 29 28 27 26 25 24 23 22 21 20                                              5 4 3 2 1 0
    1 1 0 1 0 1 0 0 0 0 1                                 imm16                         0 0 0 0 0




System variant

BRK #<imm>


Decode for this encoding

  bits(16) comment = imm16;


Assembler symbols

<imm>           Is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.


Operation

  AArch64.SoftwareBreakpoint(comment);');
INSERT INTO "instructions" VALUES('ARM','CBNZ','Compare and Branch on Nonzero compares the value in a register with zero, and conditionally branches to a label       (C6.6.30)
at a PC-relative offset if the comparison is not equal. It provides a hint that this is not a subroutine call or return.
This instruction does not affect the condition flags.




  31 30 29 28 27 26 25 24 23                                                              5 4             0
   sf 0 1 1 0 1 0 1                                     imm19                                      Rt
                          op


32-bit variant

Applies when sf = 0.

CBNZ <Wt>, <label>


64-bit variant

Applies when sf = 1.

CBNZ <Xt>, <label>


Decode for all variants of this encoding

 integer t = UInt(Rt);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean iszero = (op == ''0'');
 bits(64) offset = SignExtend(imm19:''00'', 64);


Assembler symbols

<Wt>            Is the 32-bit name of the general-purpose register to be tested, encoded in the "Rt" field.

<Xt>            Is the 64-bit name of the general-purpose register to be tested, encoded in the "Rt" field.

<label>         Is the program label to be conditionally branched to. Its offset from the address of this instruction,
                in the range +/-1MB, is encoded as "imm19" times 4.


Operation

 bits(datasize) operand1 = X[t];

 if IsZero(operand1) == iszero then
     BranchTo(PC[] + offset, BranchType_JMP);');
INSERT INTO "instructions" VALUES('ARM','CBZ','Compare and Branch on Zero compares the value in a register with zero, and conditionally branches to a label at a       (C6.6.31)
PC-relative offset if the comparison is equal. It provides a hint that this is not a subroutine call or return. This
instruction does not affect condition flags.




    31 30 29 28 27 26 25 24 23                                                           5 4               0
    sf 0 1 1 0 1 0 0                                   imm19                                       Rt
                          op


32-bit variant

Applies when sf = 0.

CBZ <Wt>, <label>


64-bit variant

Applies when sf = 1.

CBZ <Xt>, <label>


Decode for all variants of this encoding

  integer t = UInt(Rt);
  integer datasize = if sf == ''1'' then 64 else 32;
  boolean iszero = (op == ''0'');
  bits(64) offset = SignExtend(imm19:''00'', 64);


Assembler symbols

<Wt>            Is the 32-bit name of the general-purpose register to be tested, encoded in the "Rt" field.

<Xt>            Is the 64-bit name of the general-purpose register to be tested, encoded in the "Rt" field.

<label>         Is the program label to be conditionally branched to. Its offset from the address of this instruction,
                in the range +/-1MB, is encoded as "imm19" times 4.


Operation

  bits(datasize) operand1 = X[t];

  if IsZero(operand1) == iszero then
       BranchTo(PC[] + offset, BranchType_JMP);');
INSERT INTO "instructions" VALUES('ARM','CCMN','Conditional compare negative (immediate), setting condition flags to result of comparison or an immediate value:       (C6.6.32)
flags = if cond then compare(Rn, #-imm) else #nzcv




  31 30 29 28 27 26 25 24 23 22 21 20            16 15         12 11 10 9             5 4 3            0
  sf 0 1 1 1 0 1 0 0 1 0                  imm5           cond     1 0          Rn         0     nzcv
     op


32-bit variant

Applies when sf = 0.

CCMN <Wn>, #<imm>, #<nzcv>, <cond>


64-bit variant

Applies when sf = 1.

CCMN <Xn>, #<imm>, #<nzcv>, <cond>


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean sub_op = (op == ''1'');
 bits(4) condition = cond;
 bits(4) flags = nzcv;
 bits(datasize) imm = ZeroExtend(imm5, datasize);


Assembler symbols

<Wn>          Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xn>          Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<imm>         Is a five bit unsigned (positive) immediate encoded in the "imm5" field.

<nzcv>        Is the flag bit specifier, an immediate in the range 0 to 15, giving the alternative state for the 4-bit
              NZCV condition flags, encoded in the "nzcv" field.

<cond>        Is one of the standard conditions, encoded in the "cond" field in the standard way.


Operation

 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = imm;
 bit carry_in = ''0'';

 if ConditionHolds(condition) then
     if sub_op then
         operand2 = NOT(operand2);
         carry_in = ''1'';
     (-, flags) = AddWithCarry(operand1, operand2, carry_in);
 PSTATE.<N,Z,C,V> = flags;');
INSERT INTO "instructions" VALUES('ARM','CCMP','Conditional compare (immediate), setting condition flags to result of comparison or an immediate value: flags =       (C6.6.34)
if cond then compare(Rn, #imm) else #nzcv




  31 30 29 28 27 26 25 24 23 22 21 20            16 15         12 11 10 9             5 4 3            0
  sf 1 1 1 1 0 1 0 0 1 0                  imm5           cond     1 0          Rn         0     nzcv
     op


32-bit variant

Applies when sf = 0.

CCMP <Wn>, #<imm>, #<nzcv>, <cond>


64-bit variant

Applies when sf = 1.

CCMP <Xn>, #<imm>, #<nzcv>, <cond>


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean sub_op = (op == ''1'');
 bits(4) condition = cond;
 bits(4) flags = nzcv;
 bits(datasize) imm = ZeroExtend(imm5, datasize);


Assembler symbols

<Wn>          Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xn>          Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<imm>         Is a five bit unsigned (positive) immediate encoded in the "imm5" field.

<nzcv>        Is the flag bit specifier, an immediate in the range 0 to 15, giving the alternative state for the 4-bit
              NZCV condition flags, encoded in the "nzcv" field.

<cond>        Is one of the standard conditions, encoded in the "cond" field in the standard way.


Operation

 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = imm;
 bit carry_in = ''0'';

 if ConditionHolds(condition) then
     if sub_op then
         operand2 = NOT(operand2);
         carry_in = ''1'';
     (-, flags) = AddWithCarry(operand1, operand2, carry_in);
 PSTATE.<N,Z,C,V> = flags;');
INSERT INTO "instructions" VALUES('ARM','CINC','Conditional increment: Rd = if cond then Rn+1 else Rn       (C6.6.36)

This instruction is an alias of the CSINC instruction. This means that:

.      The encodings in this description are named to match the encodings of CSINC.

.      The description of CSINC gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20              16 15      12 11 10 9              5 4              0
   sf 0 0 1 1 0 1 0 1 0 0                !=11111        !=111x    0 1       !=11111            Rd
     op                                    Rm            cond        o2        Rn


32-bit variant

Applies when sf = 0.

CINC <Wd>, <Wn>, <cond>

is equivalent to

CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)

and is the preferred disassembly when Rn == Rm.

64-bit variant

Applies when sf = 1.

CINC <Xd>, <Xn>, <cond>

is equivalent to

CSINC <Xd>, <Xn>, <Xn>, invert(<cond>)

and is the preferred disassembly when Rn == Rm.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<cond>          Is one of the standard conditions, excluding AL and NV, encoded in the "cond" field with its least
                significant bit inverted.


Operation

The description of CSINC gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','CINV','Conditional invert: Rd = if cond then NOT(Rn) else Rn       (C6.6.37)

This instruction is an alias of the CSINV instruction. This means that:

.       The encodings in this description are named to match the encodings of CSINV.

.       The description of CSINV gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20           16 15       12 11 10 9             5 4              0
    sf 1 0 1 1 0 1 0 1 0 0                !=11111       !=111x    0 0       !=11111            Rd
       op                                   Rm           cond       o2         Rn


32-bit variant

Applies when sf = 0.

CINV <Wd>, <Wn>, <cond>

is equivalent to

CSINV <Wd>, <Wn>, <Wn>, invert(<cond>)

and is the preferred disassembly when Rn == Rm.

64-bit variant

Applies when sf = 1.

CINV <Xd>, <Xn>, <cond>

is equivalent to

CSINV <Xd>, <Xn>, <Xn>, invert(<cond>)

and is the preferred disassembly when Rn == Rm.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<cond>          Is one of the standard conditions, excluding AL and NV, encoded in the "cond" field with its least
                significant bit inverted.


Operation

The description of CSINV gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','CLREX','Clear exclusive monitor       (C6.6.38)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11           8 7 6 5 4 3 2 1 0
  1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1                           CRm       0 1 0 1 1 1 1 1




System variant

CLREX {#<imm>}


Decode for this encoding

 // CRm field is ignored


Assembler symbols

<imm>          Is an optional 4-bit unsigned immediate, in the range 0 to 15, defaulting to 15 and encoded in the
               "CRm" field.


Operation

 ClearExclusiveLocal(ProcessorID());');
INSERT INTO "instructions" VALUES('ARM','CLS','Count leading sign bits: Rd = CLS(Rn)       (C6.6.39)




    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
    sf 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1                               Rn              Rd
                                                                    op


32-bit variant

Applies when sf = 0.

CLS <Wd>, <Wn>


64-bit variant

Applies when sf = 1.

CLS <Xd>, <Xn>


Decode for all variants of this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer datasize = if sf == ''1'' then 64 else 32;
  CountOp opcode = if op == ''0'' then CountOp_CLZ else CountOp_CLS;


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

  integer result;
  bits(datasize) operand1 = X[n];

  if opcode == CountOp_CLZ then
       result = CountLeadingZeroBits(operand1);
  else
       result = CountLeadingSignBits(operand1);

  X[d] = result<datasize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','CLZ','Count leading zero bits: Rd = CLZ(Rn)       (C6.6.40)




  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
  sf 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 0 0                               Rn              Rd
                                                                  op


32-bit variant

Applies when sf = 0.

CLZ <Wd>, <Wn>


64-bit variant

Applies when sf = 1.

CLZ <Xd>, <Xn>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;
 CountOp opcode = if op == ''0'' then CountOp_CLZ else CountOp_CLS;


Assembler symbols

<Wd>          Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>          Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>          Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>          Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

 integer result;
 bits(datasize) operand1 = X[n];

 if opcode == CountOp_CLZ then
     result = CountLeadingZeroBits(operand1);
 else
     result = CountLeadingSignBits(operand1);

 X[d] = result<datasize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','CMN','       Compare negative (extended register), setting the condition flags and discarding the result: Rn + LSL(extend(Rm),       (C6.6.41)
       amount)

       This instruction is an alias of the ADDS (extended register) instruction. This means that:

       .       The encodings in this description are named to match the encodings of ADDS (extended register).

       .       The description of ADDS (extended register) gives the operational pseudocode for this instruction.




           31 30 29 28 27 26 25 24 23 22 21 20            16 15     13 12      10 9            5 4            0
           sf 0 1 0 1 0 1 1 0 0 1                  Rm          option    imm3           Rn        1 1 1 1 1
              op S                                                                                      Rd


       32-bit variant

       Applies when sf = 0.

       CMN <Wn|WSP>, <Wm>{, <extend> {#<amount>}}

       is equivalent to

       ADDS WZR, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}

       and is always the preferred disassembly.

       64-bit variant

       Applies when sf = 1.

       CMN <Xn|SP>, <R><m>{, <extend> {#<amount>}}

       is equivalent to

       ADDS XZR, <Xn|SP>, <R><m>{, <extend> {#<amount>}}

       and is always the preferred disassembly.


       Assembler symbols

       <Wn|WSP>        Is the 32-bit name of the first source general-purpose register or stack pointer, encoded in the "Rn"
                       field.

       <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

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

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

                       W            when option = 00x

                       W            when option = 010

                       X            when option = x11

                       W            when option = 10x

                       W            when option = 110

       <m>             Is the number [0-30] of the second general-purpose source register or the name ZR (31), encoded in
                       the "Rm" field.
<extend>       For the 32-bit variant: is the extension to be applied to the second source operand, encoded in the
               "option" field. It can have the following values:

               UXTB         when option = 000

               UXTH         when option = 001

               LSL|UXTW     when option = 010

               UXTX         when option = 011

               SXTB         when option = 100

               SXTH         when option = 101

               SXTW         when option = 110

               SXTX         when option = 111

               If "Rn" is ''11111'' (WSP) and "option" is ''010'' then LSL is preferred, but may be omitted when
               "imm3" is ''000''. In all other cases <extend> is required and must be UXTW when "option" is ''010''.

               For the 64-bit variant: is the extension to be applied to the second source operand, encoded in the
               "option" field. It can have the following values:

               UXTB         when option = 000

               UXTH         when option = 001

               UXTW         when option = 010

               LSL|UXTX     when option = 011

               SXTB         when option = 100

               SXTH         when option = 101

               SXTW         when option = 110

               SXTX         when option = 111

               If "Rn" is ''11111'' (SP) and "option" is ''011'' then LSL is preferred, but may be omitted when "imm3"
               is ''000''. In all other cases <extend> is required and must be UXTX when "option" is ''011''.

<amount>       Is the left shift amount to be applied after extension in the range 0 to 4, defaulting to 0, encoded in
               the "imm3" field. It must be absent when <extend> is absent, is required when <extend> is LSL,
               and is optional when <extend> is present but not LSL.


Operation

The description of ADDS (extended register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','CMP','Compare (extended register), setting the condition flags and discarding the result: Rn - LSL(extend(Rm), amount)       (C6.6.44)

This instruction is an alias of the SUBS (extended register) instruction. This means that:

.      The encodings in this description are named to match the encodings of SUBS (extended register).

.      The description of SUBS (extended register) gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20              16 15     13 12      10 9            5 4             0
   sf 1 1 0 1 0 1 1 0 0 1                   Rm          option    imm3           Rn        1 1 1 1 1
     op S                                                                                        Rd


32-bit variant

Applies when sf = 0.

CMP <Wn|WSP>, <Wm>{, <extend> {#<amount>}}

is equivalent to

SUBS WZR, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

CMP <Xn|SP>, <R><m>{, <extend> {#<amount>}}

is equivalent to

SUBS XZR, <Xn|SP>, <R><m>{, <extend> {#<amount>}}

and is always the preferred disassembly.


Assembler symbols

<Wn|WSP>        Is the 32-bit name of the first source general-purpose register or stack pointer, encoded in the "Rn"
                field.

<Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

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

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

                W            when option = 00x

                W            when option = 010

                X            when option = x11

                W            when option = 10x

                W            when option = 110

<m>             Is the number [0-30] of the second general-purpose source register or the name ZR (31), encoded in
                the "Rm" field.
       <extend>        For the 32-bit variant: is the extension to be applied to the second source operand, encoded in the
                       "option" field. It can have the following values:

                       UXTB         when option = 000

                       UXTH         when option = 001

                       LSL|UXTW     when option = 010

                       UXTX         when option = 011

                       SXTB         when option = 100

                       SXTH         when option = 101

                       SXTW         when option = 110

                       SXTX         when option = 111

                       If "Rn" is ''11111'' (WSP) and "option" is ''010'' then LSL is preferred, but may be omitted when
                       "imm3" is ''000''. In all other cases <extend> is required and must be UXTW when "option" is ''010''.

                       For the 64-bit variant: is the extension to be applied to the second source operand, encoded in the
                       "option" field. It can have the following values:

                       UXTB         when option = 000

                       UXTH         when option = 001

                       UXTW         when option = 010

                       LSL|UXTX     when option = 011

                       SXTB         when option = 100

                       SXTH         when option = 101

                       SXTW         when option = 110

                       SXTX         when option = 111

                       If "Rn" is ''11111'' (SP) and "option" is ''011'' then LSL is preferred, but may be omitted when "imm3"
                       is ''000''. In all other cases <extend> is required and must be UXTX when "option" is ''011''.

       <amount>        Is the left shift amount to be applied after extension in the range 0 to 4, defaulting to 0, encoded in
                       the "imm3" field. It must be absent when <extend> is absent, is required when <extend> is LSL,
                       and is optional when <extend> is present but not LSL.


       Operation

       The description of SUBS (extended register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','CNEG','Conditional negate: Rd = if cond then -Rn else Rn       (C6.6.47)

This instruction is an alias of the CSNEG instruction. This means that:

.       The encodings in this description are named to match the encodings of CSNEG.

.       The description of CSNEG gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20           16 15       12 11 10 9             5 4              0
    sf 1 0 1 1 0 1 0 1 0 0                  Rm          !=111x    0 1          Rn              Rd
       op                                                cond       o2


32-bit variant

Applies when sf = 0.

CNEG <Wd>, <Wn>, <cond>

is equivalent to

CSNEG <Wd>, <Wn>, <Wn>, invert(<cond>)

and is the preferred disassembly when Rn == Rm.

64-bit variant

Applies when sf = 1.

CNEG <Xd>, <Xn>, <cond>

is equivalent to

CSNEG <Xd>, <Xn>, <Xn>, invert(<cond>)

and is the preferred disassembly when Rn == Rm.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<cond>          Is one of the standard conditions, excluding AL and NV, encoded in the "cond" field with its least
                significant bit inverted.


Operation

The description of CSNEG gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','CRC32B','CRC-32 checksum from byte, halfword, word or doubleword: Wd = CRC32(Wn, Rm<n:0>) // n = 7, 15, 31, 63       (C6.6.48)




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


CRC32B variant

Applies when sf = 0 && sz = 00.

CRC32B <Wd>, <Wn>, <Wm>


CRC32H variant

Applies when sf = 0 && sz = 01.

CRC32H <Wd>, <Wn>, <Wm>


CRC32W variant

Applies when sf = 0 && sz = 10.

CRC32W <Wd>, <Wn>, <Wm>


CRC32X variant

Applies when sf = 1 && sz = 11.

CRC32X <Wd>, <Wn>, <Xm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sf == ''1'' && sz != ''11'' then UnallocatedEncoding();
 if sf == ''0'' && sz == ''11'' then UnallocatedEncoding();
 integer size = 8 << UInt(sz);   // 2-bit size field -> 8, 16, 32, 64
 boolean crc32c = (C == ''1'');


Assembler symbols

<Wd>          Is the 32-bit name of the general-purpose accumulator output register, encoded in the "Rd" field.

<Wn>          Is the 32-bit name of the general-purpose accumulator input register, encoded in the "Rn" field.

<Xm>          Is the 64-bit name of the general-purpose data source register, encoded in the "Rm" field.

<Wm>          Is the 32-bit name of the general-purpose data source register, encoded in the "Rm" field.


Operation

 if !HaveCRCExt() then
     UnallocatedEncoding();

 bits(32)      acc     = X[n];   // accumulator
 bits(size)    val     = X[m];   // input value
 bits(32)      poly    = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)<31:0>;
         bits(32+size) tempacc = BitReverse(acc) : Zeros(size);
         bits(size+32) tempval = BitReverse(val) : Zeros(32);

         // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation
         X[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly));');
INSERT INTO "instructions" VALUES('ARM','CRC32H','-R:CRC32B');
INSERT INTO "instructions" VALUES('ARM','CRC32W','-R:CRC32B');
INSERT INTO "instructions" VALUES('ARM','CRC32X','-R:CRC32B');
INSERT INTO "instructions" VALUES('ARM','CRC32CB','CRC-32C checksum from byte, halfword, word, or doubleword: Wd = CRC32C(Wn, Rm<n:0>) // n = 7, 15, 31, 63       (C6.6.49)




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


CRC32CB variant

Applies when sf = 0 && sz = 00.

CRC32CB <Wd>, <Wn>, <Wm>


CRC32CH variant

Applies when sf = 0 && sz = 01.

CRC32CH <Wd>, <Wn>, <Wm>


CRC32CW variant

Applies when sf = 0 && sz = 10.

CRC32CW <Wd>, <Wn>, <Wm>


CRC32CX variant

Applies when sf = 1 && sz = 11.

CRC32CX <Wd>, <Wn>, <Xm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sf == ''1'' && sz != ''11'' then UnallocatedEncoding();
 if sf == ''0'' && sz == ''11'' then UnallocatedEncoding();
 integer size = 8 << UInt(sz);   // 2-bit size field -> 8, 16, 32, 64
 boolean crc32c = (C == ''1'');


Assembler symbols

<Wd>          Is the 32-bit name of the general-purpose accumulator output register, encoded in the "Rd" field.

<Wn>          Is the 32-bit name of the general-purpose accumulator input register, encoded in the "Rn" field.

<Xm>          Is the 64-bit name of the general-purpose data source register, encoded in the "Rm" field.

<Wm>          Is the 32-bit name of the general-purpose data source register, encoded in the "Rm" field.


Operation

 if !HaveCRCExt() then
     UnallocatedEncoding();

 bits(32)      acc     = X[n];   // accumulator
 bits(size)    val     = X[m];   // input value
 bits(32)      poly    = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)<31:0>;
         bits(32+size) tempacc = BitReverse(acc) : Zeros(size);
         bits(size+32) tempval = BitReverse(val) : Zeros(32);

         // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation
         X[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly));');
INSERT INTO "instructions" VALUES('ARM','CRC32CH','-R:CRC32CB');
INSERT INTO "instructions" VALUES('ARM','CRC32CW','-R:CRC32CB');
INSERT INTO "instructions" VALUES('ARM','CRC32CX','-R:CRC32CB');
INSERT INTO "instructions" VALUES('ARM','CSEL','Conditional select, returning the first or second input: Rd = if cond then Rn else Rm       (C6.6.50)




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


32-bit variant

Applies when sf = 0.

CSEL <Wd>, <Wn>, <Wm>, <cond>


64-bit variant

Applies when sf = 1.

CSEL <Xd>, <Xn>, <Xm>, <cond>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 bits(4) condition = cond;
 boolean else_inv = (op == ''1'');
 boolean else_inc = (o2 == ''1'');


Assembler symbols

<Wd>           Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>           Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>           Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>           Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>           Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>           Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

<cond>         Is one of the standard conditions, encoded in the "cond" field in the standard way.


Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];

 if ConditionHolds(condition) then
     result = operand1;
 else
     result = operand2;
     if else_inv then result = NOT(result);
     if else_inc then result = result + 1;

 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CSET','Conditional set: Rd = if cond then 1 else 0       (C6.6.51)

This instruction is an alias of the CSINC instruction. This means that:

.       The encodings in this description are named to match the encodings of CSINC.

.       The description of CSINC gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20            16 15      12 11 10 9             5 4              0
    sf 0 0 1 1 0 1 0 1 0 0 1 1 1 1 1                    !=111x    0 1 1 1 1 1 1                Rd
       op                                   Rm           cond        o2        Rn


32-bit variant

Applies when sf = 0.

CSET <Wd>, <cond>

is equivalent to

CSINC <Wd>, WZR, WZR, invert(<cond>)

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

CSET <Xd>, <cond>

is equivalent to

CSINC <Xd>, XZR, XZR, invert(<cond>)

and is always the preferred disassembly.


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.

<cond>          Is one of the standard conditions, excluding AL and NV, encoded in the "cond" field with its least
                significant bit inverted.


Operation

The description of CSINC gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','CSETM','Conditional set mask: Rd = if cond then -1 else 0       (C6.6.52)

This instruction is an alias of the CSINV instruction. This means that:

.      The encodings in this description are named to match the encodings of CSINV.

.      The description of CSINV gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20             16 15       12 11 10 9              5 4              0
   sf 1 0 1 1 0 1 0 1 0 0 1 1 1 1 1                     !=111x    0 0 1 1 1 1 1                Rd
     op                                    Rm            cond       o2         Rn


32-bit variant

Applies when sf = 0.

CSETM <Wd>, <cond>

is equivalent to

CSINV <Wd>, WZR, WZR, invert(<cond>)

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

CSETM <Xd>, <cond>

is equivalent to

CSINV <Xd>, XZR, XZR, invert(<cond>)

and is always the preferred disassembly.


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.

<cond>          Is one of the standard conditions, excluding AL and NV, encoded in the "cond" field with its least
                significant bit inverted.


Operation

The description of CSINV gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','CSINC','       Conditional select increment, returning the first input or incremented second input: Rd = if cond then Rn else (Rm       (C6.6.53)
       + 1)

       This instruction is used by the aliases CINC and CSET. See the Alias conditions table for details of when each alias
       is preferred.




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


       32-bit variant

       Applies when sf = 0.

       CSINC <Wd>, <Wn>, <Wm>, <cond>


       64-bit variant

       Applies when sf = 1.

       CSINC <Xd>, <Xn>, <Xm>, <cond>


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer datasize = if sf == ''1'' then 64 else 32;
         bits(4) condition = cond;
         boolean else_inv = (op == ''1'');
         boolean else_inc = (o2 == ''1'');


       Alias conditions


                            Alias                     is preferred when

                            CINC                      Rm != ''11111'' && cond != ''111x'' && Rn != ''11111'' && Rn == Rm

                            CSET                      Rm == ''11111'' && cond != ''111x'' && Rn == ''11111''



       Assembler symbols

       <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

       <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

       <Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <cond>          Is one of the standard conditions, encoded in the "cond" field in the standard way.
Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];

 if ConditionHolds(condition) then
    result = operand1;
 else
    result = operand2;
    if else_inv then result = NOT(result);
    if else_inc then result = result + 1;

 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CSINV','       Conditional select inversion, returning the first input or inverted second input: Rd = if cond then Rn else NOT (Rm)       (C6.6.54)

       This instruction is used by the aliases CINV and CSETM. See the Alias conditions table for details of when each
       alias is preferred.




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


       32-bit variant

       Applies when sf = 0.

       CSINV <Wd>, <Wn>, <Wm>, <cond>


       64-bit variant

       Applies when sf = 1.

       CSINV <Xd>, <Xn>, <Xm>, <cond>


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer datasize = if sf == ''1'' then 64 else 32;
         bits(4) condition = cond;
         boolean else_inv = (op == ''1'');
         boolean else_inc = (o2 == ''1'');


       Alias conditions


                             Alias                     is preferred when

                             CINV                      Rm != ''11111'' && cond != ''111x'' && Rn != ''11111'' && Rn == Rm

                             CSETM                     Rm == ''11111'' && cond != ''111x'' && Rn == ''11111''



       Assembler symbols

       <Wd>             Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>             Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

       <Wm>             Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>             Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

       <Xm>             Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <cond>           Is one of the standard conditions, encoded in the "cond" field in the standard way.
Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];

 if ConditionHolds(condition) then
    result = operand1;
 else
    result = operand2;
    if else_inv then result = NOT(result);
    if else_inc then result = result + 1;

 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CSNEG','      Conditional select negation, returning the first input or negated second input: Rd = if cond then Rn else -Rm       (C6.6.55)

      This instruction is used by the alias CNEG. See the Alias conditions table for details of when each alias is preferred.




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


      32-bit variant

      Applies when sf = 0.

      CSNEG <Wd>, <Wn>, <Wm>, <cond>


      64-bit variant

      Applies when sf = 1.

      CSNEG <Xd>, <Xn>, <Xm>, <cond>


      Decode for all variants of this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        integer datasize = if sf == ''1'' then 64 else 32;
        bits(4) condition = cond;
        boolean else_inv = (op == ''1'');
        boolean else_inc = (o2 == ''1'');


      Alias conditions


                           Alias                     is preferred when

                           CNEG                      cond != ''111x'' && Rn == Rm



      Assembler symbols

      <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

      <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

      <cond>          Is one of the standard conditions, encoded in the "cond" field in the standard way.


      Operation

        bits(datasize) result;
        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = X[m];

if ConditionHolds(condition) then
   result = operand1;
else
   result = operand2;
   if else_inv then result = NOT(result);
   if else_inc then result = result + 1;

X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','DC','Data cache operation       (C6.6.56)

This instruction is an alias of the SYS instruction. This means that:

.       The encodings in this description are named to match the encodings of SYS.

.       The description of SYS gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20 19 18      16 15        12 11       8 7      5 4             0
    1 1 0 1 0 1 0 1 0 0 0 0 1                  op1     0 1 1 1        CRm        op2           Rt
                                    L                     CRn


System variant

DC <dc_op>, <Xt>

is equivalent to

SYS #<op1>, C7, <Cm>, #<op2>, <Xt>

and is the preferred disassembly when SysOp(op1,''0111'',CRm,op2) == Sys_DC.


Assembler symbols

<dc_op>         Is a DC operation name, as listed for the DC system operation group, encoded in the
                "op1:CRm:op2" field. It can have the following values:

                IVAC         when op1 = 000, CRm = 0110, op2 = 001

                ISW          when op1 = 000, CRm = 0110, op2 = 010

                CSW          when op1 = 000, CRm = 1010, op2 = 010

                CISW         when op1 = 000, CRm = 1110, op2 = 010

                ZVA          when op1 = 011, CRm = 0100, op2 = 001

                CVAC         when op1 = 011, CRm = 1010, op2 = 001

                CVAU         when op1 = 011, CRm = 1011, op2 = 001

                CIVAC        when op1 = 011, CRm = 1110, op2 = 001

<op1>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op1" field.

<Cm>            Is a name ''Cm'', with ''m'' in the range 0 to 15, encoded in the "CRm" field.

<op2>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op2" field.

<Xt>            Is the 64-bit name of the general-purpose source register, encoded in the "Rt" field.


Operation

The description of SYS gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','DCPS1','Debug Change PE State to EL1 allows the debugger to move the PE into EL1 from a lower Exception Level or to       (C6.6.57)
a specific mode at the current Exception Level.

If the PE is at EL1 or lower, then the PE enters EL1h.

If the PE is at an Exception Level higher than EL1, then the PE does not change Exception Level but selects use of
the stack pointer for the current Exception Level by updating PSTATE.SP.

This instruction is always UNDEFINED in Non-debug state.

For more information on the operation of this instructions, see DCPS on page H2-4963.




  31 30 29 28 27 26 25 24 23 22 21 20                                                 5 4 3 2 1 0
   1 1 0 1 0 1 0 0 1 0 1                                   imm16                        0 0 0 0 1
                                                                                                    LL


System variant

DCPS1 {#<imm>}


Decode for this encoding

 bits(2) target_level = LL;
 if LL == ''00'' then UnallocatedEncoding();
 if !Halted() then AArch64.UndefinedFault();


Assembler symbols

<imm>            Is an optional 16-bit unsigned immediate, in the range 0 to 65535, defaulting to 0 and encoded in
                 the "imm16" field.


Operation

 DCPSInstruction(target_level);');
INSERT INTO "instructions" VALUES('ARM','DCPS2','Debug Change PE State to EL2 allows the debugger to move the PE into EL2 from a lower Exception Level or to       (C6.6.58)
a specific mode at the current Exception Level.

If the PE is at EL2 or lower, then the PE enters EL2h.

If the PE is at an Exception Level higher than EL2, then the PE does not change Exception Level but selects use of
the stack pointer for the current Exception Level by updating PSTATE.SP.

This instruction is always UNDEFINED in Non-debug state.

For more information on the operation of this instructions, see DCPS on page H2-4963.




    31 30 29 28 27 26 25 24 23 22 21 20                                               5 4 3 2 1 0
    1 1 0 1 0 1 0 0 1 0 1                                  imm16                        0 0 0 1 0
                                                                                                    LL


System variant

DCPS2 {#<imm>}


Decode for this encoding

  bits(2) target_level = LL;
  if LL == ''00'' then UnallocatedEncoding();
  if !Halted() then AArch64.UndefinedFault();


Assembler symbols

<imm>            Is an optional 16-bit unsigned immediate, in the range 0 to 65535, defaulting to 0 and encoded in
                 the "imm16" field.


Operation

  DCPSInstruction(target_level);');
INSERT INTO "instructions" VALUES('ARM','DCPS3','Debug Change PE State to EL3 allows the debugger to move the PE into EL3 from a lower Exception Level or to       (C6.6.59)
a specific mode at the current Exception Level. The PE enters EL3h.

This instruction is always UNDEFINED in Non-debug state.

For more information on the operation of this instructions, see DCPS on page H2-4963.




  31 30 29 28 27 26 25 24 23 22 21 20                                                5 4 3 2 1 0
   1 1 0 1 0 1 0 0 1 0 1                                   imm16                       0 0 0 1 1
                                                                                                   LL


System variant

DCPS3 {#<imm>}


Decode for this encoding

 bits(2) target_level = LL;
 if LL == ''00'' then UnallocatedEncoding();
 if !Halted() then AArch64.UndefinedFault();


Assembler symbols

<imm>           Is an optional 16-bit unsigned immediate, in the range 0 to 65535, defaulting to 0 and encoded in
                the "imm16" field.


Operation

 DCPSInstruction(target_level);');
INSERT INTO "instructions" VALUES('ARM','DMB','       Data memory barrier       (C6.6.60)




           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11            8 7 6 5 4 3 2 1 0
           1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1                            CRm       1 0 1 1 1 1 1 1
                                                                                            opc


       System variant

       DMB <option>|#<imm>


       Decode for this encoding

         MemBarrierOp op;
         MBReqDomain domain;
         MBReqTypes types;

         case opc of
              when ''00'' op = MemBarrierOp_DSB;
              when ''01'' op = MemBarrierOp_DMB;
              when ''10'' op = MemBarrierOp_ISB;
              otherwise UnallocatedEncoding();

         case CRm<3:2> of
              when ''00'' domain = MBReqDomain_OuterShareable;
              when ''01'' domain = MBReqDomain_Nonshareable;
              when ''10'' domain = MBReqDomain_InnerShareable;
              when ''11'' domain = MBReqDomain_FullSystem;

         case CRm<1:0> of
              when ''01'' types = MBReqTypes_Reads;
              when ''10'' types = MBReqTypes_Writes;
              when ''11'' types = MBReqTypes_All;
              otherwise
                   types = MBReqTypes_All;
                   domain = MBReqDomain_FullSystem;


       Assembler symbols

       <option>         Specifies the limitation on the barrier operation. Values are:

                        SY          Full system is the required shareability domain, reads and writes are the required access
                                    types in both Group A on page B2-85 and Group B on page B2-86. This option is
                                    referred to as the full system DMB. Encoded as CRm = 0b1111.

                        ST          Full system is the required shareability domain, writes are the required access type in
                                    both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b1110.

                        LD          Full system is the required shareability domain, reads are the required access type in
                                    Group A on page B2-85, and reads and writes are the required access types in both
                                    Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b1101.

                        ISH         Inner Shareable is the required shareability domain, reads and writes are the required
                                    access types in Group B on page B2-86. Encoded as CRm = 0b1011.

                        ISHST       Inner Shareable is the required shareability domain, writes are the required access type
                                    in both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b1010.

                        ISHLD       Inner Shareable is the required shareability domain, reads are the required access type
                                    in Group A on page B2-85. Encoded as CRm = 0b1001.

                        NSH         Non-shareable is the required shareability domain, reads and writes are the required
                                    access types in Group B on page B2-86. Encoded as CRm = 0b0111.
              NSHST       Non-shareable is the required shareability domain, writes are the required access type
                          in both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b0110.

              NSHLD       Non-shareable is the required shareability domain, reads are the required access type in
                          Group A on page B2-85. Encoded as CRm = 0b0101.

              OSH         Outer Shareable is the required shareability domain, reads and writes are the required
                          access types in Group B on page B2-86. Encoded as CRm = 0b0011.

              OSHST       Outer Shareable is the required shareability domain, writes are the required access type
                          in both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b0010.

              OSHLD       Outer Shareable is the required shareability domain, reads are the required access type
                          in Group A on page B2-85. Encoded as CRm = 0b0001.

               All other encodings of CRm that are not listed above are reserved, and can be encoded using the
              #<imm> syntax. It is IMPLEMENTATION DEFINED whether options other than SY are implemented. All
              unsupported and reserved options must execute as a full system operation, but software must not
              rely on this behavior.

<imm>         Is a 4-bit unsigned immediate, in the range 0 to 15, encoded in the "CRm" field.


Operation

 case op of
    when MemBarrierOp_DSB
         DataSynchronizationBarrier(domain, types);
    when MemBarrierOp_DMB
         DataMemoryBarrier(domain, types);
    when MemBarrierOp_ISB
         InstructionSynchronizationBarrier();');
INSERT INTO "instructions" VALUES('ARM','DRPS','Debug restore process state       (C6.6.61)




    31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    1 1 0 1 0 1 1 0 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0




System variant

DRPS


Decode for this encoding

  if !Halted() || PSTATE.EL == EL0 then UnallocatedEncoding();


Operation

  DRPSInstruction();');
INSERT INTO "instructions" VALUES('ARM','DSB','Data synchronization barrier       (C6.6.62)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11           8 7 6 5 4 3 2 1 0
  1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1                           CRm       1 0 0 1 1 1 1 1
                                                                                  opc


System variant

DSB <option>|#<imm>


Decode for this encoding

 MemBarrierOp op;
 MBReqDomain domain;
 MBReqTypes types;

 case opc of
     when ''00'' op = MemBarrierOp_DSB;
     when ''01'' op = MemBarrierOp_DMB;
     when ''10'' op = MemBarrierOp_ISB;
     otherwise UnallocatedEncoding();

 case CRm<3:2> of
     when ''00'' domain = MBReqDomain_OuterShareable;
     when ''01'' domain = MBReqDomain_Nonshareable;
     when ''10'' domain = MBReqDomain_InnerShareable;
     when ''11'' domain = MBReqDomain_FullSystem;

 case CRm<1:0> of
     when ''01'' types = MBReqTypes_Reads;
     when ''10'' types = MBReqTypes_Writes;
     when ''11'' types = MBReqTypes_All;
     otherwise
        types = MBReqTypes_All;
        domain = MBReqDomain_FullSystem;


Assembler symbols

<option>      Specifies the limitation on the barrier operation. Values are:

              SY          Full system is the required shareability domain, reads and writes are the required access
                          types in both Group A on page B2-85 and Group B on page B2-86. This option is
                          referred to as the full system DMB. Encoded as CRm = 0b1111.

              ST          Full system is the required shareability domain, writes are the required access type in
                          both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b1110.

              LD          Full system is the required shareability domain, reads are the required access type in
                          Group A on page B2-85, and reads and writes are the required access types in both
                          Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b1101.

              ISH         Inner Shareable is the required shareability domain, reads and writes are the required
                          access types in Group B on page B2-86. Encoded as CRm = 0b1011.

              ISHST       Inner Shareable is the required shareability domain, writes are the required access type
                          in both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b1010.

              ISHLD       Inner Shareable is the required shareability domain, reads are the required access type
                          in Group A on page B2-85. Encoded as CRm = 0b1001.

              NSH         Non-shareable is the required shareability domain, reads and writes are the required
                          access types in Group B on page B2-86. Encoded as CRm = 0b0111.
                        NSHST       Non-shareable is the required shareability domain, writes are the required access type
                                    in both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b0110.

                        NSHLD       Non-shareable is the required shareability domain, reads are the required access type in
                                    Group A on page B2-85. Encoded as CRm = 0b0101.

                        OSH         Outer Shareable is the required shareability domain, reads and writes are the required
                                    access types in Group B on page B2-86. Encoded as CRm = 0b0011.

                        OSHST       Outer Shareable is the required shareability domain, writes are the required access type
                                    in both Group A on page B2-85 and Group B on page B2-86. Encoded as CRm = 0b0010.

                        OSHLD       Outer Shareable is the required shareability domain, reads are the required access type
                                    in Group A on page B2-85. Encoded as CRm = 0b0001.

                         All other encodings of CRm that are not listed above are reserved, and can be encoded using the
                        #<imm> syntax. It is IMPLEMENTATION DEFINED whether options other than SY are implemented. All
                        unsupported and reserved options must execute as a full system operation, but software must not
                        rely on this behavior.

       <imm>            Is a 4-bit unsigned immediate, in the range 0 to 15, encoded in the "CRm" field.


       Operation

         case op of
              when MemBarrierOp_DSB
                   DataSynchronizationBarrier(domain, types);
              when MemBarrierOp_DMB
                   DataMemoryBarrier(domain, types);
              when MemBarrierOp_ISB
                   InstructionSynchronizationBarrier();');
INSERT INTO "instructions" VALUES('ARM','EON','Bitwise exclusive OR NOT (shifted register): Rd = Rn EOR NOT shift(Rm, amount)       (C6.6.63)




  31 30 29 28 27 26 25 24 23 22 21 20              16 15               10 9             5 4             0
  sf 1 0 0 1 0 1 0 shift 1                  Rm               imm6                Rn            Rd
     opc                           N


32-bit variant

Applies when sf = 0.

EON <Wd>, <Wn>, <Wm>{, <shift> #<amount>}


64-bit variant

Applies when sf = 1.

EON <Xd>, <Xn>, <Xm>{, <shift> #<amount>}


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean setflags;
 LogicalOp op;
 case opc of
     when ''00'' op = LogicalOp_AND; setflags = FALSE;
     when ''01'' op = LogicalOp_ORR; setflags = FALSE;
     when ''10'' op = LogicalOp_EOR; setflags = FALSE;
     when ''11'' op = LogicalOp_AND; setflags = TRUE;

 if sf == ''0'' && imm6<5> == ''1'' then ReservedValue();

 ShiftType shift_type = DecodeShift(shift);
 integer shift_amount = UInt(imm6);
 boolean invert = (N == ''1'');


Assembler symbols

<Wd>           Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>           Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>           Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>           Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>           Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>           Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

<shift>        Is the optional shift to be applied to the final source, defaulting to LSL and encoded in the "shift"
               field. It can have the following values:

               LSL          when shift = 00

               LSR          when shift = 01

               ASR          when shift = 10

               ROR          when shift = 11
       <amount>        For the 32-bit variant: is the shift amount, in the range 0 to 31, defaulting to 0 and encoded in the
                       "imm6" field.

                       For the 64-bit variant: is the shift amount, in the range 0 to 63, defaulting to 0 and encoded in the
                       "imm6" field.


       Operation

         bits(datasize) operand1 = X[n];
         bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);

         if invert then operand2 = NOT(operand2);

         case op of
              when LogicalOp_AND result = operand1 AND operand2;
              when LogicalOp_ORR result = operand1 OR       operand2;
              when LogicalOp_EOR result = operand1 EOR operand2;

         if setflags then
              PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

         X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','EOR','Bitwise exclusive OR (immediate): Rd = Rn EOR imm       (C6.6.64)




  31 30 29 28 27 26 25 24 23 22 21                16 15             10 9             5 4              0
  sf 1 0 1 0 0 1 0 0 N                  immr               imms               Rn               Rd
     opc


32-bit variant

Applies when sf = 0 && N = 0.

EOR <Wd|WSP>, <Wn>, #<imm>


64-bit variant

Applies when sf = 1.

EOR <Xd|SP>, <Xn>, #<imm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean setflags;
 LogicalOp op;
 case opc of
     when ''00'' op = LogicalOp_AND; setflags = FALSE;
     when ''01'' op = LogicalOp_ORR; setflags = FALSE;
     when ''10'' op = LogicalOp_EOR; setflags = FALSE;
     when ''11'' op = LogicalOp_AND; setflags = TRUE;

 bits(datasize) imm;
 if sf == ''0'' && N != ''0'' then ReservedValue();
 (imm, -) = DecodeBitMasks(N, imms, immr, TRUE);


Assembler symbols

<Wd|WSP>       Is the 32-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
               field.

<Wn>           Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd|SP>        Is the 64-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
               field.

<Xn>           Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<imm>          Is the bitmask immediate, encoded in "N:imms:immr".


Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = imm;

 case op of
     when LogicalOp_AND result = operand1 AND operand2;
     when LogicalOp_ORR result = operand1 OR      operand2;
     when LogicalOp_EOR result = operand1 EOR operand2;

         if setflags then
              PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

         if d == 31 && !setflags then
              SP[] = result;
         else
              X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ERET','Exception return using current ELR and SPSR       (C6.6.66)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  1 1 0 1 0 1 1 0 1 0 0 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0




System variant

ERET


Decode for this encoding

 if PSTATE.EL == EL0 then UnallocatedEncoding();


Operation

 AArch64.ExceptionReturn(ELR[], SPSR[]);');
INSERT INTO "instructions" VALUES('ARM','EXTR','       Extract register from pair of registers       (C6.6.67)

       This instruction is used by the alias ROR (immediate). See the Alias conditions table for details of when each alias
       is preferred.




           31 30 29 28 27 26 25 24 23 22 21 20              16 15                10 9            5 4               0
           sf 0 0 1 0 0 1 1 1 N 0                   Rm                imms                Rn              Rd




       32-bit variant

       Applies when sf = 0 && N = 0 && imms = 0xxxxx.

       EXTR <Wd>, <Wn>, <Wm>, #<lsb>


       64-bit variant

       Applies when sf = 1 && N = 1.

       EXTR <Xd>, <Xn>, <Xm>, #<lsb>


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer datasize = if sf == ''1'' then 64 else 32;
         integer lsb;

         if N != sf then UnallocatedEncoding();
         if sf == ''0'' && imms<5> == ''1'' then ReservedValue();
         lsb = UInt(imms);


       Alias conditions


                            Alias                      is preferred when

                            ROR (immediate)            Rn == Rm



       Assembler symbols

       <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

       <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

       <Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <lsb>           For the 32-bit variant: is the least significant bit position from which to extract, in the range 0 to 31,
                       encoded in the "imms" field.

                       For the 64-bit variant: is the least significant bit position from which to extract, in the range 0 to 63,
                       encoded in the "imms" field.
Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];
 bits(2*datasize) concat = operand1:operand2;

 result = concat<lsb+datasize-1:lsb>;

 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','HINT','    Hint instruction       (C6.6.68)

    This instruction is used by the aliases NOP, SEVL, SEV, WFE, WFI, and YIELD. See the Alias conditions table
    for details of when each alias is preferred.




        31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11          8 7      5 4 3 2 1 0
        1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0                            CRm        op2  1 1 1 1 1




    System variant

    HINT #<imm>


    Decode for this encoding

      SystemHintOp op;

      case CRm:op2 of
           when ''0000 000'' op = SystemHintOp_NOP;
           when ''0000 001'' op = SystemHintOp_YIELD;
           when ''0000 010'' op = SystemHintOp_WFE;
           when ''0000 011'' op = SystemHintOp_WFI;
           when ''0000 100'' op = SystemHintOp_SEV;
           when ''0000 101'' op = SystemHintOp_SEVL;
           otherwise   op = SystemHintOp_NOP;


    Alias conditions


                          Alias                  is preferred when

                          NOP                    CRm == ''0000'' && op2 == ''000''

                          SEVL                   CRm == ''0000'' && op2 == ''101''

                          SEV                    CRm == ''0000'' && op2 == ''100''

                          WFE                    CRm == ''0000'' && op2 == ''010''

                          WFI                    CRm == ''0000'' && op2 == ''011''

                          YIELD                  CRm == ''0000'' && op2 == ''001''



    Assembler symbols

    <imm>            Is a 7-bit unsigned immediate, in the range 0 to 127, encoded in "CRm:op2".


    Operation

      case op of
           when SystemHintOp_YIELD
                Hint_Yield();

           when SystemHintOp_WFE
                if EventRegistered() then
                    ClearEventRegister();
                else
                   if PSTATE.EL == EL0 then
            AArch64.CheckForWFxTrap(EL1, TRUE);
       if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} then
            AArch64.CheckForWFxTrap(EL2, TRUE);
       if HaveEL(EL3) && PSTATE.EL != EL3 then
            AArch64.CheckForWFxTrap(EL3, TRUE);
        WaitForEvent();

when SystemHintOp_WFI
   if !InterruptPending() then
       if PSTATE.EL == EL0 then
            AArch64.CheckForWFxTrap(EL1, FALSE);
       if HaveEL(EL2) && !IsSecure() && PSTATE.EL IN {EL0,EL1} then
            AArch64.CheckForWFxTrap(EL2, FALSE);
       if HaveEL(EL3) && PSTATE.EL != EL3 then
            AArch64.CheckForWFxTrap(EL3, FALSE);
        WaitForInterrupt();

when SystemHintOp_SEV
    SendEvent();

when SystemHintOp_SEVL
    EventRegisterSet();

otherwise // do nothing');
INSERT INTO "instructions" VALUES('ARM','HLT','External debug breakpoint       (C6.6.69)




    31 30 29 28 27 26 25 24 23 22 21 20                                              5 4 3 2 1 0
    1 1 0 1 0 1 0 0 0 1 0                                 imm16                         0 0 0 0 0




System variant

HLT #<imm>


Decode for this encoding

  if EDSCR.HDE == ''0'' || !HaltingAllowed() then UndefinedFault();


Assembler symbols

<imm>           Is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.


Operation

  Halt(DebugHalt_HaltInstruction);');
INSERT INTO "instructions" VALUES('ARM','HVC','Generate exception targeting exception level 2       (C6.6.70)




  31 30 29 28 27 26 25 24 23 22 21 20                                              5 4 3 2 1 0
  1 1 0 1 0 1 0 0 0 0 0                                 imm16                         0 0 0 1 0




System variant

HVC #<imm>


Decode for this encoding

 bits(16) imm = imm16;


Assembler symbols

<imm>         Is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.


Operation

 if !HaveEL(EL2) || PSTATE.EL == EL0 || (PSTATE.EL == EL1 && IsSecure()) then
     UnallocatedEncoding();

 hvc_enable = if HaveEL(EL3) then SCR_EL3.HCE else NOT(HCR_EL2.HCD);
 if hvc_enable == ''0'' then
     AArch64.UndefinedFault();
 else
     AArch64.CallHypervisor(imm);');
INSERT INTO "instructions" VALUES('ARM','IC','Instruction cache operation       (C6.6.71)

This instruction is an alias of the SYS instruction. This means that:

.       The encodings in this description are named to match the encodings of SYS.

.       The description of SYS gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20 19 18      16 15         12 11       8 7       5 4             0
    1 1 0 1 0 1 0 1 0 0 0 0 1                  op1      0 1 1 1        CRm        op2           Rt
                                    L                      CRn


System variant

IC <ic_op>{, <Xt>}

is equivalent to

SYS #<op1>, C7, <Cm>, #<op2>{, <Xt>}

and is the preferred disassembly when SysOp(op1,''0111'',CRm,op2) == Sys_IC.


Assembler symbols

<ic_op>         Is an IC operation name, as listed for the IC system operation pages, encoded in the "op1:CRm:op2"
                field. It can have the following values:

                IALLUIS      when op1 = 000, CRm = 0001, op2 = 000

                IALLU        when op1 = 000, CRm = 0101, op2 = 000

                IVAU         when op1 = 011, CRm = 0101, op2 = 001

<op1>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op1" field.

<Cm>            Is a name ''Cm'', with ''m'' in the range 0 to 15, encoded in the "CRm" field.

<op2>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op2" field.

<Xt>            Is the 64-bit name of the optional general-purpose source register, defaulting to ''11111'', encoded in
                the "Rt" field.


Operation

The description of SYS gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','ISB','Instruction synchronization barrier       (C6.6.72)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11           8 7 6 5 4 3 2 1 0
  1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1                            CRm       1 1 0 1 1 1 1 1
                                                                                   opc


System variant

ISB {<option>|#<imm>}


Decode for this encoding

 MemBarrierOp op;
 MBReqDomain domain;
 MBReqTypes types;

 case opc of
     when ''00'' op = MemBarrierOp_DSB;
     when ''01'' op = MemBarrierOp_DMB;
     when ''10'' op = MemBarrierOp_ISB;
     otherwise UnallocatedEncoding();

 case CRm<3:2> of
     when ''00'' domain = MBReqDomain_OuterShareable;
     when ''01'' domain = MBReqDomain_Nonshareable;
     when ''10'' domain = MBReqDomain_InnerShareable;
     when ''11'' domain = MBReqDomain_FullSystem;

 case CRm<1:0> of
     when ''01'' types = MBReqTypes_Reads;
     when ''10'' types = MBReqTypes_Writes;
     when ''11'' types = MBReqTypes_All;
     otherwise
          types = MBReqTypes_All;
          domain = MBReqDomain_FullSystem;


Assembler symbols

<option>       Specifies an optional limitation on the barrier operation. Values are:

               SY          Full system barrier operation, encoded as CRm = 0b1111. Can be omitted.

                All other encodings of CRm are reserved. The corresponding instructions execute as full system
               barrier operations, but must not be relied upon by software.

<imm>          Is an optional 4-bit unsigned immediate, in the range 0 to 15, defaulting to 15 and encoded in the
               "CRm" field.


Operation

 case op of
     when MemBarrierOp_DSB
          DataSynchronizationBarrier(domain, types);
     when MemBarrierOp_DMB
          DataMemoryBarrier(domain, types);
     when MemBarrierOp_ISB
          InstructionSynchronizationBarrier();');
INSERT INTO "instructions" VALUES('ARM','LDAR','      Load-Acquire Register loads a 32-bit word or 64-bit doubleword from memory, and writes it to a register. The       (C6.6.73)
      instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For
      information about memory accesses see Load/Store addressing modes on page C1-122.




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4            0
          1 x 0 0 1 0 0 0 1 1 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)             Rn              Rt
          size                     o2 L o1        Rs        o0       Rt2


      32-bit variant

      Applies when size = 10.

      LDAR <Wt>, [<Xn|SP>{,#0}]


      64-bit variant

      Applies when size = 11.

      LDAR <Xt>, [<Xn|SP>{,#0}]


      Decode for all variants of this encoding

        integer n = UInt(Rn);
        integer t = UInt(Rt);
        integer t2 = UInt(Rt2); // ignored by load/store single register
        integer s = UInt(Rs);     // ignored by all loads and store-release

        if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
        if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

        AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
        boolean excl = (o2 == ''0'');
        boolean pair = (o1 == ''1'');
        MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
        integer elsize = 8 << UInt(size);
        integer regsize = if elsize == 64 then 64 else 32;
        integer datasize = if pair then elsize * 2 else elsize;


      Assembler symbols

      <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

      <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


      Operation

        bits(64) address;
        bits(datasize) data;
        constant integer dbytes = datasize DIV 8;
        boolean rt_unknown = FALSE;
        boolean rn_unknown = FALSE;

        if memop == MemOp_LOAD && pair && t == t2 then
             Constraint c = ConstrainUnpredictable();
             assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
             case c of
                  when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
        when Constraint_UNDEF      UnallocatedEncoding();
        when Constraint_NOP        EndOfInstruction();

if memop == MemOp_STORE && excl then
   if s == t || (pair && s == t2) then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
           when Constraint_NONE       rt_unknown = FALSE;       // store original value
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();
   if s == n && n != 31 then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
           when Constraint_NONE       rn_unknown = FALSE;       // address is original base
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();

if n == 31 then
    CheckSPAlignment();
   address = SP[];
elsif rn_unknown then
   address = bits(64) UNKNOWN;
else
   address = X[n];

case memop of
   when MemOp_STORE
       if rt_unknown then
           data = bits(datasize) UNKNOWN;
       elsif pair then
           assert excl;
           bits(datasize DIV 2) el1 = X[t];
           bits(datasize DIV 2) el2 = X[t2];
           data = if BigEndian() then el1 : el2 else el2 : el1;
       else
           data = X[t];

        if excl then
           // store {release} exclusive register|pair (atomic)
           bit status = ''1'';
           // Check whether the Exclusive Monitors are set to include the
           // physical memory locations corresponding to virtual address
           // range [address, address+dbytes-1].
           if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                // This atomic write will be rejected if it does not refer
                // to the same physical locations after address translation.
                Mem[address, dbytes, acctype] = data;
                status = ExclusiveMonitorsStatus();
            X[s] = ZeroExtend(status, 32);
        else
           // store release register (atomic)
            Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
        if excl then
           // Tell the Exclusive Monitors to record a sequence of one or more atomic
           // memory reads from virtual address range [address, address+dbytes-1].
           // The Exclusive Monitor will only be set if all the reads are from the
           // same dbytes-aligned physical address, to allow for the possibility of
           // an atomicity break if the translation is changed between reads.
            AArch64.SetExclusiveMonitors(address, dbytes);

        if pair then
           // load exclusive pair
                     assert excl;
                     if rt_unknown then
                         // ConstrainedUNPREDICTABLE case
                         X[t]   = bits(datasize) UNKNOWN;
                     elsif elsize == 32 then
                         // 32-bit load exclusive pair (atomic)
                         data = Mem[address, dbytes, acctype];
                         if BigEndian() then
                              X[t]  = data<datasize-1:elsize>;
                              X[t2] = data<elsize-1:0>;
                         else
                              X[t]  = data<elsize-1:0>;
                              X[t2] = data<datasize-1:elsize>;
                     else // elsize == 64
                         // 64-bit load exclusive pair (not atomic),
                         // but must be 128-bit aligned
                         if address != Align(address, dbytes) then
                             iswrite = FALSE;
                             secondstage = FALSE;
                             AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                         X[t]   = Mem[address + 0, 8, acctype];
                         X[t2] = Mem[address + 8, 8, acctype];
                  else
                     // load {acquire} {exclusive} single register
                     data = Mem[address, dbytes, acctype];
                      X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDARB','Load-Acquire Register Byte loads a byte from memory, zero-extends it and writes it to a register. The instruction       (C6.6.74)
also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For information
about memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20           16 15 14            10 9             5 4             0
   0 0 0 0 1 0 0 0 1 1 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)           Rn              Rt
   size                   o2 L o1        Rs        o0       Rt2


No offset variant

LDARB <Wt>, [<Xn|SP>{,#0}]


Decode for this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);   // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Assembler symbols

<Wt>          Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
     assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
     case c of
         when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
         when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP         EndOfInstruction();

 if memop == MemOp_STORE && excl then
     if s == t || (pair && s == t2) then
         Constraint c = ConstrainUnpredictable();
         assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
         case c of
            when Constraint_UNKNOWN       rt_unknown = TRUE;      // store UNKNOWN value
            when Constraint_NONE          rt_unknown = FALSE;     // store original value
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
                      when Constraint_NONE       rn_unknown = FALSE;       // address is original base
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
                               X[t2] = data<elsize-1:0>;
          else
               X[t]  = data<elsize-1:0>;
               X[t2] = data<datasize-1:elsize>;
      else // elsize == 64
          // 64-bit load exclusive pair (not atomic),
          // but must be 128-bit aligned
          if address != Align(address, dbytes) then
              iswrite = FALSE;
              secondstage = FALSE;
              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
          X[t]   = Mem[address + 0, 8, acctype];
          X[t2] = Mem[address + 8, 8, acctype];
   else
      // load {acquire} {exclusive} single register
      data = Mem[address, dbytes, acctype];
       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDARH','      Load-Acquire Register Halfword loads a halfword from memory, zero-extends it, and writes it to a register. The       (C6.6.75)
      instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For
      information about memory accesses see Load/Store addressing modes on page C1-122.




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4            0
          0 1 0 0 1 0 0 0 1 1 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)             Rn              Rt
          size                     o2 L o1        Rs        o0       Rt2


      No offset variant

      LDARH <Wt>, [<Xn|SP>{,#0}]


      Decode for this encoding

        integer n = UInt(Rn);
        integer t = UInt(Rt);
        integer t2 = UInt(Rt2); // ignored by load/store single register
        integer s = UInt(Rs);     // ignored by all loads and store-release

        if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
        if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

        AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
        boolean excl = (o2 == ''0'');
        boolean pair = (o1 == ''1'');
        MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
        integer elsize = 8 << UInt(size);
        integer regsize = if elsize == 64 then 64 else 32;
        integer datasize = if pair then elsize * 2 else elsize;


      Assembler symbols

      <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


      Operation

        bits(64) address;
        bits(datasize) data;
        constant integer dbytes = datasize DIV 8;
        boolean rt_unknown = FALSE;
        boolean rn_unknown = FALSE;

        if memop == MemOp_LOAD && pair && t == t2 then
             Constraint c = ConstrainUnpredictable();
             assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
             case c of
                  when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
                  when Constraint_UNDEF       UnallocatedEncoding();
                  when Constraint_NOP         EndOfInstruction();

        if memop == MemOp_STORE && excl then
             if s == t || (pair && s == t2) then
                  Constraint c = ConstrainUnpredictable();
                  assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                  case c of
                     when Constraint_UNKNOWN      rt_unknown = TRUE;       // store UNKNOWN value
                     when Constraint_NONE         rt_unknown = FALSE;      // store original value
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();
   if s == n && n != 31 then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
           when Constraint_NONE       rn_unknown = FALSE;       // address is original base
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();

if n == 31 then
    CheckSPAlignment();
   address = SP[];
elsif rn_unknown then
   address = bits(64) UNKNOWN;
else
   address = X[n];

case memop of
   when MemOp_STORE
       if rt_unknown then
           data = bits(datasize) UNKNOWN;
       elsif pair then
           assert excl;
           bits(datasize DIV 2) el1 = X[t];
           bits(datasize DIV 2) el2 = X[t2];
           data = if BigEndian() then el1 : el2 else el2 : el1;
       else
           data = X[t];

       if excl then
           // store {release} exclusive register|pair (atomic)
           bit status = ''1'';
           // Check whether the Exclusive Monitors are set to include the
           // physical memory locations corresponding to virtual address
           // range [address, address+dbytes-1].
           if AArch64.ExclusiveMonitorsPass(address, dbytes) then
               // This atomic write will be rejected if it does not refer
               // to the same physical locations after address translation.
               Mem[address, dbytes, acctype] = data;
               status = ExclusiveMonitorsStatus();
           X[s] = ZeroExtend(status, 32);
       else
           // store release register (atomic)
           Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
       if excl then
           // Tell the Exclusive Monitors to record a sequence of one or more atomic
           // memory reads from virtual address range [address, address+dbytes-1].
           // The Exclusive Monitor will only be set if all the reads are from the
           // same dbytes-aligned physical address, to allow for the possibility of
           // an atomicity break if the translation is changed between reads.
           AArch64.SetExclusiveMonitors(address, dbytes);

       if pair then
           // load exclusive pair
           assert excl;
           if rt_unknown then
               // ConstrainedUNPREDICTABLE case
               X[t]   = bits(datasize) UNKNOWN;
           elsif elsize == 32 then
               // 32-bit load exclusive pair (atomic)
               data = Mem[address, dbytes, acctype];
               if BigEndian() then
                   X[t]   = data<datasize-1:elsize>;
                   X[t2] = data<elsize-1:0>;
                         else
                              X[t]  = data<elsize-1:0>;
                              X[t2] = data<datasize-1:elsize>;
                     else // elsize == 64
                         // 64-bit load exclusive pair (not atomic),
                         // but must be 128-bit aligned
                         if address != Align(address, dbytes) then
                             iswrite = FALSE;
                             secondstage = FALSE;
                             AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                         X[t]   = Mem[address + 0, 8, acctype];
                         X[t2] = Mem[address + 8, 8, acctype];
                  else
                     // load {acquire} {exclusive} single register
                     data = Mem[address, dbytes, acctype];
                      X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDAXP','Load-Acquire Exclusive Pair of Registers loads two 32-bit words or two 64-bit doublewords from memory, and       (C6.6.76)
writes them to two registers. A 32-bit pair requires the address to be doubleword aligned and is single-copy atomic
at doubleword granularity. A 64-bit pair requires the address to be quadword aligned and is single-copy atomic for
each doubleword at doubleword granularity. The PE marks the physical address being accessed as an exclusive
access. This exclusive access mark is checked by Store Exclusive instructions. See Synchronization and semaphores
on page B2-103. The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release
on page B2-88. For information about memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20              16 15 14            10 9             5 4             0
   1 x 0 0 1 0 0 0 0 1 1 (1) (1) (1) (1) (1) 1                 Rt2               Rn             Rt
   size                     o2 L o1          Rs       o0


32-bit variant

Applies when size = 10.

LDAXP <Wt1>, <Wt2>, [<Xn|SP>{,#0}]


64-bit variant

Applies when size = 11.

LDAXP <Xt1>, <Xt2>, [<Xn|SP>{,#0}]


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);     // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDAXP on page J1-5407.


Assembler symbols

<Wt1>           Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

<Wt2>           Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                field.

<Xt1>           Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

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


       Operation

         bits(64) address;
         bits(datasize) data;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;
         boolean rn_unknown = FALSE;

         if memop == MemOp_LOAD && pair && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN     rt_unknown = TRUE;     // result is UNKNOWN
                   when Constraint_UNDEF       UnallocatedEncoding();
                   when Constraint_NOP         EndOfInstruction();

         if memop == MemOp_STORE && excl then
              if s == t || (pair && s == t2) then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN      rt_unknown = TRUE;      // store UNKNOWN value
                      when Constraint_NONE         rt_unknown = FALSE;     // store original value
                      when Constraint_UNDEF        UnallocatedEncoding();
                      when Constraint_NOP          EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN      rn_unknown = TRUE;      // address is UNKNOWN
                      when Constraint_NONE         rn_unknown = FALSE;     // address is original base
                      when Constraint_UNDEF        UnallocatedEncoding();
                      when Constraint_NOP          EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
          X[s] = ZeroExtend(status, 32);
      else
          // store release register (atomic)
          Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
      if excl then
          // Tell the Exclusive Monitors to record a sequence of one or more atomic
          // memory reads from virtual address range [address, address+dbytes-1].
          // The Exclusive Monitor will only be set if all the reads are from the
          // same dbytes-aligned physical address, to allow for the possibility of
          // an atomicity break if the translation is changed between reads.
          AArch64.SetExclusiveMonitors(address, dbytes);

      if pair then
          // load exclusive pair
          assert excl;
          if rt_unknown then
              // ConstrainedUNPREDICTABLE case
              X[t]  = bits(datasize) UNKNOWN;
          elsif elsize == 32 then
              // 32-bit load exclusive pair (atomic)
              data = Mem[address, dbytes, acctype];
              if BigEndian() then
                  X[t]  = data<datasize-1:elsize>;
                  X[t2] = data<elsize-1:0>;
              else
                  X[t]  = data<elsize-1:0>;
                  X[t2] = data<datasize-1:elsize>;
          else // elsize == 64
              // 64-bit load exclusive pair (not atomic),
              // but must be 128-bit aligned
              if address != Align(address, dbytes) then
                  iswrite = FALSE;
                  secondstage = FALSE;
                  AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
              X[t]  = Mem[address + 0, 8, acctype];
              X[t2] = Mem[address + 8, 8, acctype];
      else
          // load {acquire} {exclusive} single register
          data = Mem[address, dbytes, acctype];
          X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDAXR','      Load-Acquire Exclusive Register loads a 32-bit word or 64-bit doubleword from memory, and writes it to a register.       (C6.6.77)
      The memory access is atomic. The PE marks the physical address being accessed as an exclusive access. This
      exclusive access mark is checked by Store Exclusive instructions. See Synchronization and semaphores on
      page B2-103. The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on
      page B2-88. For information about memory accesses see Load/Store addressing modes on page C1-122.




          31 30 29 28 27 26 25 24 23 22 21 20           16 15 14            10 9             5 4            0
          1 x 0 0 1 0 0 0 0 1 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)            Rn              Rt
          size                    o2 L o1        Rs        o0       Rt2


      32-bit variant

      Applies when size = 10.

      LDAXR <Wt>, [<Xn|SP>{,#0}]


      64-bit variant

      Applies when size = 11.

      LDAXR <Xt>, [<Xn|SP>{,#0}]


      Decode for all variants of this encoding

        integer n = UInt(Rn);
        integer t = UInt(Rt);
        integer t2 = UInt(Rt2); // ignored by load/store single register
        integer s = UInt(Rs);    // ignored by all loads and store-release

        if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
        if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

        AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
        boolean excl = (o2 == ''0'');
        boolean pair = (o1 == ''1'');
        MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
        integer elsize = 8 << UInt(size);
        integer regsize = if elsize == 64 then 64 else 32;
        integer datasize = if pair then elsize * 2 else elsize;


      Assembler symbols

      <Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

      <Xt>            Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


      Operation

        bits(64) address;
        bits(datasize) data;
        constant integer dbytes = datasize DIV 8;
        boolean rt_unknown = FALSE;
        boolean rn_unknown = FALSE;

        if memop == MemOp_LOAD && pair && t == t2 then
             Constraint c = ConstrainUnpredictable();
             assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
   case c of
        when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
        when Constraint_UNDEF      UnallocatedEncoding();
        when Constraint_NOP        EndOfInstruction();

if memop == MemOp_STORE && excl then
   if s == t || (pair && s == t2) then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
           when Constraint_NONE       rt_unknown = FALSE;       // store original value
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();
   if s == n && n != 31 then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
           when Constraint_NONE       rn_unknown = FALSE;       // address is original base
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();

if n == 31 then
    CheckSPAlignment();
   address = SP[];
elsif rn_unknown then
   address = bits(64) UNKNOWN;
else
   address = X[n];

case memop of
   when MemOp_STORE
       if rt_unknown then
           data = bits(datasize) UNKNOWN;
       elsif pair then
           assert excl;
           bits(datasize DIV 2) el1 = X[t];
           bits(datasize DIV 2) el2 = X[t2];
           data = if BigEndian() then el1 : el2 else el2 : el1;
        else
           data = X[t];

        if excl then
           // store {release} exclusive register|pair (atomic)
           bit status = ''1'';
           // Check whether the Exclusive Monitors are set to include the
           // physical memory locations corresponding to virtual address
           // range [address, address+dbytes-1].
           if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                // This atomic write will be rejected if it does not refer
                // to the same physical locations after address translation.
                Mem[address, dbytes, acctype] = data;
                status = ExclusiveMonitorsStatus();
            X[s] = ZeroExtend(status, 32);
        else
           // store release register (atomic)
            Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
        if excl then
           // Tell the Exclusive Monitors to record a sequence of one or more atomic
           // memory reads from virtual address range [address, address+dbytes-1].
           // The Exclusive Monitor will only be set if all the reads are from the
           // same dbytes-aligned physical address, to allow for the possibility of
           // an atomicity break if the translation is changed between reads.
            AArch64.SetExclusiveMonitors(address, dbytes);
                  if pair then
                     // load exclusive pair
                     assert excl;
                     if rt_unknown then
                          // ConstrainedUNPREDICTABLE case
                          X[t]  = bits(datasize) UNKNOWN;
                     elsif elsize == 32 then
                          // 32-bit load exclusive pair (atomic)
                          data = Mem[address, dbytes, acctype];
                          if BigEndian() then
                              X[t]  = data<datasize-1:elsize>;
                              X[t2] = data<elsize-1:0>;
                          else
                              X[t]  = data<elsize-1:0>;
                              X[t2] = data<datasize-1:elsize>;
                     else // elsize == 64
                          // 64-bit load exclusive pair (not atomic),
                          // but must be 128-bit aligned
                          if address != Align(address, dbytes) then
                             iswrite = FALSE;
                             secondstage = FALSE;
                             AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                          X[t]  = Mem[address + 0, 8, acctype];
                          X[t2] = Mem[address + 8, 8, acctype];
                  else
                     // load {acquire} {exclusive} single register
                     data = Mem[address, dbytes, acctype];
                      X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDAXRB','Load-Acquire Exclusive Register Byte loads a byte from memory, zero-extends it and writes it to a register. The       (C6.6.78)
memory access is atomic. The PE marks the physical address being accessed as an exclusive access. This exclusive
access mark is checked by Store Exclusive instructions. See Synchronization and semaphores on page B2-103. The
instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For
information about memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20             16 15 14            10 9             5 4             0
   0 0 0 0 1 0 0 0 0 1 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)             Rn              Rt
   size                     o2 L o1        Rs        o0       Rt2


No offset variant

LDAXRB <Wt>, [<Xn|SP>{,#0}]


Decode for this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);     // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Assembler symbols

<Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
     assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
     case c of
          when Constraint_UNKNOWN      rt_unknown = TRUE;      // result is UNKNOWN
          when Constraint_UNDEF        UnallocatedEncoding();
          when Constraint_NOP          EndOfInstruction();

 if memop == MemOp_STORE && excl then
     if s == t || (pair && s == t2) then
          Constraint c = ConstrainUnpredictable();
          assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
          case c of
                      when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
                      when Constraint_NONE       rt_unknown = FALSE;       // store original value
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
                      when Constraint_NONE       rn_unknown = FALSE;       // address is original base
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
               X[t]  = data<datasize-1:elsize>;
               X[t2] = data<elsize-1:0>;
          else
               X[t]  = data<elsize-1:0>;
               X[t2] = data<datasize-1:elsize>;
      else // elsize == 64
          // 64-bit load exclusive pair (not atomic),
          // but must be 128-bit aligned
          if address != Align(address, dbytes) then
              iswrite = FALSE;
              secondstage = FALSE;
              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
          X[t]   = Mem[address + 0, 8, acctype];
          X[t2] = Mem[address + 8, 8, acctype];
   else
      // load {acquire} {exclusive} single register
      data = Mem[address, dbytes, acctype];
       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDAXRH','      Load-Acquire Exclusive Register Halfword loads a halfword from memory, zero-extends it and writes it to a       (C6.6.79)
      register. The memory access is atomic. The PE marks the physical address being accessed as an exclusive access.
      This exclusive access mark is checked by Store Exclusive instructions. See Synchronization and semaphores on
      page B2-103. The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on
      page B2-88. For information about memory accesses see Load/Store addressing modes on page C1-122.




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4            0
          0 1 0 0 1 0 0 0 0 1 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)             Rn              Rt
          size                     o2 L o1        Rs        o0       Rt2


      No offset variant

      LDAXRH <Wt>, [<Xn|SP>{,#0}]


      Decode for this encoding

        integer n = UInt(Rn);
        integer t = UInt(Rt);
        integer t2 = UInt(Rt2); // ignored by load/store single register
        integer s = UInt(Rs);     // ignored by all loads and store-release

        if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
        if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

        AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
        boolean excl = (o2 == ''0'');
        boolean pair = (o1 == ''1'');
        MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
        integer elsize = 8 << UInt(size);
        integer regsize = if elsize == 64 then 64 else 32;
        integer datasize = if pair then elsize * 2 else elsize;


      Assembler symbols

      <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


      Operation

        bits(64) address;
        bits(datasize) data;
        constant integer dbytes = datasize DIV 8;
        boolean rt_unknown = FALSE;
        boolean rn_unknown = FALSE;

        if memop == MemOp_LOAD && pair && t == t2 then
             Constraint c = ConstrainUnpredictable();
             assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
             case c of
                  when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
                  when Constraint_UNDEF       UnallocatedEncoding();
                  when Constraint_NOP         EndOfInstruction();

        if memop == MemOp_STORE && excl then
             if s == t || (pair && s == t2) then
                  Constraint c = ConstrainUnpredictable();
                  assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                  case c of
           when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
           when Constraint_NONE       rt_unknown = FALSE;       // store original value
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP         EndOfInstruction();
   if s == n && n != 31 then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
           when Constraint_NONE       rn_unknown = FALSE;       // address is original base
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP         EndOfInstruction();

if n == 31 then
    CheckSPAlignment();
   address = SP[];
elsif rn_unknown then
   address = bits(64) UNKNOWN;
else
   address = X[n];

case memop of
   when MemOp_STORE
       if rt_unknown then
           data = bits(datasize) UNKNOWN;
       elsif pair then
           assert excl;
           bits(datasize DIV 2) el1 = X[t];
           bits(datasize DIV 2) el2 = X[t2];
           data = if BigEndian() then el1 : el2 else el2 : el1;
       else
           data = X[t];

       if excl then
           // store {release} exclusive register|pair (atomic)
           bit status = ''1'';
           // Check whether the Exclusive Monitors are set to include the
           // physical memory locations corresponding to virtual address
           // range [address, address+dbytes-1].
           if AArch64.ExclusiveMonitorsPass(address, dbytes) then
               // This atomic write will be rejected if it does not refer
               // to the same physical locations after address translation.
                Mem[address, dbytes, acctype] = data;
               status = ExclusiveMonitorsStatus();
           X[s] = ZeroExtend(status, 32);
       else
           // store release register (atomic)
           Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
       if excl then
           // Tell the Exclusive Monitors to record a sequence of one or more atomic
           // memory reads from virtual address range [address, address+dbytes-1].
           // The Exclusive Monitor will only be set if all the reads are from the
           // same dbytes-aligned physical address, to allow for the possibility of
           // an atomicity break if the translation is changed between reads.
           AArch64.SetExclusiveMonitors(address, dbytes);

        if pair then
           // load exclusive pair
           assert excl;
           if rt_unknown then
                // ConstrainedUNPREDICTABLE case
                X[t]  = bits(datasize) UNKNOWN;
           elsif elsize == 32 then
                // 32-bit load exclusive pair (atomic)
                data = Mem[address, dbytes, acctype];
                if BigEndian() then
                              X[t]  = data<datasize-1:elsize>;
                              X[t2] = data<elsize-1:0>;
                         else
                              X[t]  = data<elsize-1:0>;
                              X[t2] = data<datasize-1:elsize>;
                     else // elsize == 64
                         // 64-bit load exclusive pair (not atomic),
                         // but must be 128-bit aligned
                         if address != Align(address, dbytes) then
                             iswrite = FALSE;
                             secondstage = FALSE;
                             AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                         X[t]   = Mem[address + 0, 8, acctype];
                         X[t2] = Mem[address + 8, 8, acctype];
                  else
                     // load {acquire} {exclusive} single register
                     data = Mem[address, dbytes, acctype];
                      X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDNP','Load pair of registers, with non-temporal hint       (C6.6.80)




  31 30 29 28 27 26 25 24 23 22 21                     15 14         10 9              5 4               0
  x 0 1 0 1 0 0 0 0 1                      imm7                Rt2              Rn              Rt
  opc                          L


32-bit variant

Applies when opc = 00.

LDNP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]


64-bit variant

Applies when opc = 10.

LDNP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]


Decode for all variants of this encoding

 boolean wback   = FALSE;
 boolean postindex = FALSE;


Assembler symbols

<Wt1>          Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

<Wt2>          Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
               field.

<Xt1>          Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

<Xt2>          Is the 64-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
               field.

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

<imm>          For the 32-bit variant: is the optional signed immediate byte offset, a multiple of 4 in the range -256
               to 252, defaulting to 0 and encoded in the "imm7" field as <imm>/4.

               For the 64-bit variant: is the optional signed immediate byte offset, a multiple of 8 in the range -512
               to 504, defaulting to 0 and encoded in the "imm7" field as <imm>/8.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2);
 AccType acctype = AccType_STREAM;
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 if opc<0> == ''1'' then UnallocatedEncoding();
 integer scale = 2 + UInt(opc<1>);
 integer datasize = 8 << scale;
 bits(64) offset = LSL(SignExtend(imm7, 64), scale);
       Operation

         bits(64) address;
         bits(datasize) data1;
         bits(datasize) data2;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown && t == n then
                      data1 = bits(datasize) UNKNOWN;
                   else
                      data1 = X[t];
                   if rt_unknown && t2 == n then
                      data2 = bits(datasize) UNKNOWN;
                   else
                      data2 = X[t2];
                   Mem[address + 0     , dbytes, acctype] = data1;
                   Mem[address + dbytes, dbytes, acctype] = data2;

              when MemOp_LOAD
                   data1 = Mem[address + 0     , dbytes, acctype];
                   data2 = Mem[address + dbytes, dbytes, acctype];
                   if rt_unknown then
                      data1 = bits(datasize) UNKNOWN;
                      data2 = bits(datasize) UNKNOWN;
                   X[t]  = data1;
                   X[t2] = data2;

         if wback then
              if postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDP','Load Pair of Registers calculates an address from a base register value and an immediate offset, loads two 32-bit       (C6.6.81)
words or two 64-bit doublewords from memory, and writes them to two registers. For information about memory
accesses see Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21                  15 14            10 9            5 4              0
  x 0 1 0 1 0 0 0 1 1                    imm7                Rt2              Rn             Rt
  opc                          L


32-bit variant

Applies when opc = 00.

LDP <Wt1>, <Wt2>, [<Xn|SP>], #<imm>


64-bit variant

Applies when opc = 10.

LDP <Xt1>, <Xt2>, [<Xn|SP>], #<imm>


Decode for all variants of this encoding

 boolean wback  = TRUE;
 boolean postindex = TRUE;


Pre-index


  31 30 29 28 27 26 25 24 23 22 21                  15 14            10 9            5 4              0
  x 0 1 0 1 0 0 1 1 1                    imm7                Rt2              Rn             Rt
  opc                          L


32-bit variant

Applies when opc = 00.

LDP <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!


64-bit variant

Applies when opc = 10.

LDP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!


Decode for all variants of this encoding

 boolean wback  = TRUE;
 boolean postindex = FALSE;


Signed offset


  31 30 29 28 27 26 25 24 23 22 21                  15 14            10 9            5 4              0
  x 0 1 0 1 0 0 1 0 1                    imm7                Rt2              Rn             Rt
  opc                          L
       32-bit variant

       Applies when opc = 00.

       LDP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]


       64-bit variant

       Applies when opc = 10.

       LDP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]


       Decode for all variants of this encoding

         boolean wback  = FALSE;
         boolean postindex = FALSE;


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDP on page J1-5406.


       Assembler symbols

       <Wt1>           Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Wt2>           Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                       field.

       <Xt1>           Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt2>           Is the 64-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                       field.

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

       <imm>           For the 32-bit post-index and 32-bit pre-index variant: is the signed immediate byte offset, a
                       multiple of 4 in the range -256 to 252, encoded in the "imm7" field as <imm>/4.

                       For the 32-bit signed offset variant: is the optional signed immediate byte offset, a multiple of 4 in
                       the range -256 to 252, defaulting to 0 and encoded in the "imm7" field as <imm>/4.

                       For the 64-bit post-index and 64-bit pre-index variant: is the signed immediate byte offset, a
                       multiple of 8 in the range -512 to 504, encoded in the "imm7" field as <imm>/8.

                       For the 64-bit signed offset variant: is the optional signed immediate byte offset, a multiple of 8 in
                       the range -512 to 504, defaulting to 0 and encoded in the "imm7" field as <imm>/8.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2);
         AccType acctype = AccType_NORMAL;
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         if L:opc<0> == ''01'' || opc == ''11'' then UnallocatedEncoding();
         boolean signed = (opc<0> != ''0'');
         integer scale = 2 + UInt(opc<1>);
         integer datasize = 8 << scale;
         bits(64) offset = LSL(SignExtend(imm7, 64), scale);
Operation for all encodings

 bits(64) address;
 bits(datasize) data1;
 bits(datasize) data2;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean wb_unknown = FALSE;

 if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;          // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;      // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;     // value stored is pre-writeback
         when Constraint_UNKNOWN    rt_unknown = TRUE;      // value stored is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_LOAD && t == t2 then
     Constraint c = ConstrainUnpredictable();
    assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
         if rt_unknown && t == n then
            data1 = bits(datasize) UNKNOWN;
         else
            data1 = X[t];
         if rt_unknown && t2 == n then
            data2 = bits(datasize) UNKNOWN;
         else
            data2 = X[t2];
         Mem[address + 0     , dbytes, acctype] = data1;
         Mem[address + dbytes, dbytes, acctype] = data2;

    when MemOp_LOAD
         data1 = Mem[address + 0     , dbytes, acctype];
         data2 = Mem[address + dbytes, dbytes, acctype];
         if rt_unknown then
            data1 = bits(datasize) UNKNOWN;
            data2 = bits(datasize) UNKNOWN;
         if signed then
             X[t]  = SignExtend(data1, 64);
             X[t2] = SignExtend(data2, 64);
         else
             X[t]  = data1;
                       X[t2] = data2;

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDPSW','Load Pair of Registers Signed Word calculates an address from a base register value and an immediate offset, loads       (C6.6.82)
two 32-bit words from memory, sign-extends them, and writes them to two registers. For information about memory
accesses see Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21                 15 14           10 9              5 4             0
  0 1 1 0 1 0 0 0 1 1                   imm7                Rt2               Rn             Rt
  opc                         L


Post-index variant

LDPSW <Xt1>, <Xt2>, [<Xn|SP>], #<imm>


Decode for this encoding

 boolean wback   = TRUE;
 boolean postindex = TRUE;


Pre-index


  31 30 29 28 27 26 25 24 23 22 21                 15 14           10 9              5 4             0
  0 1 1 0 1 0 0 1 1 1                   imm7                Rt2               Rn             Rt
  opc                         L


Pre-index variant

LDPSW <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!


Decode for this encoding

 boolean wback   = TRUE;
 boolean postindex = FALSE;


Signed offset


  31 30 29 28 27 26 25 24 23 22 21                 15 14           10 9              5 4             0
  0 1 1 0 1 0 0 1 0 1                   imm7                Rt2               Rn             Rt
  opc                         L


Signed offset variant

LDPSW <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]


Decode for this encoding

 boolean wback   = FALSE;
 boolean postindex = FALSE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDPSW on page J1-5406.
       Assembler symbols

       <Xt1>            Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt2>            Is the 64-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                        field.

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

       <imm>            For the post-index and pre-index variant: is the signed immediate byte offset, a multiple of 4 in the
                        range -256 to 252, encoded in the "imm7" field as <imm>/4.

                        For the signed offset variant: is the optional signed immediate byte offset, a multiple of 4 in the
                        range -256 to 252, defaulting to 0 and encoded in the "imm7" field as <imm>/4.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2);
         AccType acctype = AccType_NORMAL;
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         if L:opc<0> == ''01'' || opc == ''11'' then UnallocatedEncoding();
         boolean signed = (opc<0> != ''0'');
         integer scale = 2 + UInt(opc<1>);
         integer datasize = 8 << scale;
         bits(64) offset = LSL(SignExtend(imm7, 64), scale);


       Operation for all encodings

         bits(64) address;
         bits(datasize) data1;
         bits(datasize) data2;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;
         boolean wb_unknown = FALSE;

         if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;             // writeback is suppressed
                   when Constraint_UNKNOWN     wb_unknown = TRUE;        // writeback is UNKNOWN
                   when Constraint_UNDEF       UnallocatedEncoding();
                   when Constraint_NOP         EndOfInstruction();

         if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE        rt_unknown = FALSE;       // value stored is pre-writeback
                   when Constraint_UNKNOWN     rt_unknown = TRUE;        // value stored is UNKNOWN
                   when Constraint_UNDEF       UnallocatedEncoding();
                   when Constraint_NOP         EndOfInstruction();

         if memop == MemOp_LOAD && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN     rt_unknown = TRUE;        // result is UNKNOWN
                   when Constraint_UNDEF       UnallocatedEncoding();
                   when Constraint_NOP         EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown && t == n then
            data1 = bits(datasize) UNKNOWN;
        else
            data1 = X[t];
        if rt_unknown && t2 == n then
            data2 = bits(datasize) UNKNOWN;
        else
            data2 = X[t2];
         Mem[address + 0     , dbytes, acctype] = data1;
         Mem[address + dbytes, dbytes, acctype] = data2;

    when MemOp_LOAD
        data1 = Mem[address + 0      , dbytes, acctype];
        data2 = Mem[address + dbytes, dbytes, acctype];
        if rt_unknown then
            data1 = bits(datasize) UNKNOWN;
            data2 = bits(datasize) UNKNOWN;
        if signed then
             X[t]  = SignExtend(data1, 64);
             X[t2] = SignExtend(data2, 64);
        else
             X[t]  = data1;
             X[t2] = data2;

 if wback then
    if wb_unknown then
        address = bits(64) UNKNOWN;
    elsif postindex then
        address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDR','       Load Register (immediate) calculates an address from a base register value and an immediate offset, loads a 32-bit       (C6.6.83)
       word or 64-bit doubleword from memory, and writes it to a register. For information about memory accesses see
       Load/Store addressing modes on page C1-122. The Unsigned offset variant scales the immediate offset value by the
       size of the value accessed before adding it to the base register value.


       Post-index


           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9         5 4              0
           1 x 1 1 1 0 0 0 0 1 0                        imm9               0 1      Rn             Rt
           size                    opc


       32-bit variant

       Applies when size = 10.

       LDR <Wt>, [<Xn|SP>], #<simm>


       64-bit variant

       Applies when size = 11.

       LDR <Xt>, [<Xn|SP>], #<simm>


       Decode for all variants of this encoding

         boolean wback = TRUE;
         boolean postindex = TRUE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Pre-index


           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9         5 4              0
           1 x 1 1 1 0 0 0 0 1 0                        imm9               1 1      Rn             Rt
           size                    opc


       32-bit variant

       Applies when size = 10.

       LDR <Wt>, [<Xn|SP>, #<simm>]!


       64-bit variant

       Applies when size = 11.

       LDR <Xt>, [<Xn|SP>, #<simm>]!


       Decode for all variants of this encoding

         boolean wback = TRUE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);
Unsigned offset


  31 30 29 28 27 26 25 24 23 22 21                                   10 9              5 4             0
  1 x 1 1 1 0 0 1 0 1                             imm12                       Rn                Rt
  size                      opc


32-bit variant

Applies when size = 10.

LDR <Wt>, [<Xn|SP>{, #<pimm>}]


64-bit variant

Applies when size = 11.

LDR <Xt>, [<Xn|SP>{, #<pimm>}]


Decode for all variants of this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDR (immediate) on page J1-5404.


Assembler symbols

<Wt>           Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

<Xt>           Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

<simm>         Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

<pimm>         For the 32-bit variant: is the optional positive immediate byte offset, a multiple of 4 in the range 0
               to 16380, defaulting to 0 and encoded in the "imm12" field as <pimm>/4.

               For the 64-bit variant: is the optional positive immediate byte offset, a multiple of 8 in the range 0
               to 32760, defaulting to 0 and encoded in the "imm12" field as <pimm>/8.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_NORMAL;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
     // store or zero-extending load
     memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
     regsize = if size == ''11'' then 64 else 32;
     signed = FALSE;
 else
     if size == ''11'' then
         UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation for all encodings

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
                   when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   else
                      data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
       SP[] = address;
   else
       X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDRB','Load Register Byte (immediate) calculates an address from a base register value and an immediate offset, loads a       (C6.6.86)
byte from memory, zero-extends it, and writes it to a register. For information about memory accesses see
Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                           12 11 10 9            5 4             0
  0 0 1 1 1 0 0 0 0 1 0                        imm9                 0 1        Rn            Rt
  size                    opc


Post-index variant

LDRB <Wt>, [<Xn|SP>], #<simm>


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                           12 11 10 9            5 4             0
  0 0 1 1 1 0 0 0 0 1 0                        imm9                 1 1        Rn            Rt
  size                    opc


Pre-index variant

LDRB <Wt>, [<Xn|SP>, #<simm>]!


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Unsigned offset


  31 30 29 28 27 26 25 24 23 22 21                                    10 9            5 4             0
  0 0 1 1 1 0 0 1 0 1                            imm12                         Rn            Rt
  size                    opc


Unsigned offset variant

LDRB <Wt>, [<Xn|SP>{, #<pimm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);
       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRB (immediate) on page J1-5404.


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           Is the optional positive immediate byte offset, in the range 0 to 4095, defaulting to 0 and encoded
                        in the "imm12" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation for all encodings

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;           // writeback is suppressed
                   when Constraint_UNKNOWN      wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
                   when Constraint_NOP          EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE         rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN      rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
             X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
        address = bits(64) UNKNOWN;
    elsif postindex then
        address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDRH','Load Register Halfword (immediate) calculates an address from a base register value and an immediate offset, loads       (C6.6.88)
a halfword from memory, zero-extends it, and writes it to a register. For information about memory accesses see
Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
  0 1 1 1 1 0 0 0 0 1 0                       imm9                0 1          Rn            Rt
   size                   opc


Post-index variant

LDRH <Wt>, [<Xn|SP>], #<simm>


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
  0 1 1 1 1 0 0 0 0 1 0                       imm9                1 1          Rn            Rt
   size                   opc


Pre-index variant

LDRH <Wt>, [<Xn|SP>, #<simm>]!


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Unsigned offset


  31 30 29 28 27 26 25 24 23 22 21                                    10 9            5 4             0
  0 1 1 1 1 0 0 1 0 1                          imm12                           Rn            Rt
   size                   opc


Unsigned offset variant

LDRH <Wt>, [<Xn|SP>{, #<pimm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);
       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRH (immediate) on page J1-5405.


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           Is the optional positive immediate byte offset, a multiple of 2 in the range 0 to 8190, defaulting to 0
                        and encoded in the "imm12" field as <pimm>/2.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation for all encodings

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;           // writeback is suppressed
                   when Constraint_UNKNOWN      wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
                   when Constraint_NOP          EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE         rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN      rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
             X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
        address = bits(64) UNKNOWN;
    elsif postindex then
        address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDRSB','Load Register Signed Byte (immediate) calculates an address from a base register value and an immediate byte       (C6.6.90)
offset, loads a byte from memory, sign-extends it to either 32 or 64 bits, and writes it to a register. For information
about memory accesses see Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9               5 4               0
  0 0 1 1 1 0 0 0 1 x 0                        imm9                0 1         Rn                 Rt
   size                      opc


32-bit variant

Applies when opc = 11.

LDRSB <Wt>, [<Xn|SP>], #<simm>


64-bit variant

Applies when opc = 10.

LDRSB <Xt>, [<Xn|SP>], #<simm>


Decode for all variants of this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9               5 4               0
  0 0 1 1 1 0 0 0 1 x 0                        imm9                1 1         Rn                 Rt
   size                      opc


32-bit variant

Applies when opc = 11.

LDRSB <Wt>, [<Xn|SP>, #<simm>]!


64-bit variant

Applies when opc = 10.

LDRSB <Xt>, [<Xn|SP>, #<simm>]!


Decode for all variants of this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);
       Unsigned offset


           31 30 29 28 27 26 25 24 23 22 21                                   10 9             5 4              0
           0 0 1 1 1 0 0 1 1 x                           imm12                          Rn              Rt
           size                      opc


       32-bit variant

       Applies when opc = 11.

       LDRSB <Wt>, [<Xn|SP>{, #<pimm>}]


       64-bit variant

       Applies when opc = 10.

       LDRSB <Xt>, [<Xn|SP>{, #<pimm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRSB (immediate) on page J1-5405.


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           Is the optional positive immediate byte offset, in the range 0 to 4095, defaulting to 0 and encoded
                        in the "imm12" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation for all encodings

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
         else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDRSH','Load Register Signed Halfword (immediate) calculates an address from a base register value and an immediate       (C6.6.92)
offset, loads a halfword from memory, sign-extends it, and writes it to a register. For information about memory
accesses see Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9               5 4             0
  0 1 1 1 1 0 0 0 1 x 0                       imm9                 0 1         Rn               Rt
   size                      opc


32-bit variant

Applies when opc = 11.

LDRSH <Wt>, [<Xn|SP>], #<simm>


64-bit variant

Applies when opc = 10.

LDRSH <Xt>, [<Xn|SP>], #<simm>


Decode for all variants of this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9               5 4             0
  0 1 1 1 1 0 0 0 1 x 0                       imm9                 1 1         Rn               Rt
   size                      opc


32-bit variant

Applies when opc = 11.

LDRSH <Wt>, [<Xn|SP>, #<simm>]!


64-bit variant

Applies when opc = 10.

LDRSH <Xt>, [<Xn|SP>, #<simm>]!


Decode for all variants of this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);
       Unsigned offset


           31 30 29 28 27 26 25 24 23 22 21                                   10 9               5 4            0
           0 1 1 1 1 0 0 1 1 x                           imm12                           Rn               Rt
           size                      opc


       32-bit variant

       Applies when opc = 11.

       LDRSH <Wt>, [<Xn|SP>{, #<pimm>}]


       64-bit variant

       Applies when opc = 10.

       LDRSH <Xt>, [<Xn|SP>{, #<pimm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRSH (immediate) on page J1-5405.


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           Is the optional positive immediate byte offset, a multiple of 2 in the range 0 to 8190, defaulting to 0
                        and encoded in the "imm12" field as <pimm>/2.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation for all encodings

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
         else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDRSW','Load Register Signed Word (immediate) calculates an address from a base register value and an immediate offset,       (C6.6.94)
loads a word from memory, sign-extends it, and writes it to a register. For information about memory accesses see
Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9             5 4              0
  1 0 1 1 1 0 0 0 1 0 0                       imm9                0 1          Rn             Rt
  size                    opc


Post-index variant

LDRSW <Xt>, [<Xn|SP>], #<simm>


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9             5 4              0
  1 0 1 1 1 0 0 0 1 0 0                       imm9                1 1          Rn             Rt
  size                    opc


Pre-index variant

LDRSW <Xt>, [<Xn|SP>, #<simm>]!


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Unsigned offset


  31 30 29 28 27 26 25 24 23 22 21                                   10 9             5 4              0
  1 0 1 1 1 0 0 1 1 0                          imm12                           Rn             Rt
  size                    opc


Unsigned offset variant

LDRSW <Xt>, [<Xn|SP>{, #<pimm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);
       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRSW (immediate) on page J1-5406.


       Assembler symbols

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           Is the optional positive immediate byte offset, a multiple of 4 in the range 0 to 16380, defaulting to
                        0 and encoded in the "imm12" field as <pimm>/4.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation for all encodings

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;           // writeback is suppressed
                   when Constraint_UNKNOWN      wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
                   when Constraint_NOP          EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE         rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN      rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
             X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
        address = bits(64) UNKNOWN;
    elsif postindex then
        address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDTR','       Load Register (unprivileged) calculates an address from a base register and an immediate byte offset, loads a word       (C6.6.97)
       or doubleword from memory, zero-extends it, and writes it to a register. For information about memory accesses see
       Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           1 x 1 1 1 0 0 0 0 1 0                        imm9               1 0         Rn               Rt
           size                      opc


       32-bit variant

       Applies when size = 10.

       LDTR <Wt>, [<Xn|SP>{, #<simm>}]


       64-bit variant

       Applies when size = 11.

       LDTR <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_UNPRIV;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
            X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDTRB','       Load Register Byte (unprivileged) calculates an address from a base register and an immediate byte offset, loads a       (C6.6.98)
       byte from memory, zero-extends it, and writes it to a register. For information about memory accesses see
       Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 0 1 1 1 0 0 0 0 1 0                        imm9               1 0         Rn               Rt
           size                      opc


       Unscaled offset variant

       LDTRB <Wt>, [<Xn|SP>{, #<simm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_UNPRIV;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;
Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDTRH','       Load Register Halfword (unprivileged) calculates an address from a base register value and an immediate offset,       (C6.6.99)
       loads a halfword from memory, zero-extends it, and writes it to a register. For information about memory accesses
       see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 1 1 1 1 0 0 0 0 1 0                        imm9               1 0         Rn               Rt
           size                      opc


       Unscaled offset variant

       LDTRH <Wt>, [<Xn|SP>{, #<simm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_UNPRIV;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;
Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDTRSB','       Load Register Signed Byte (unprivileged) calculates an address from a base register and an immediate byte offset,       (C6.6.100)
       loads a signed byte from memory, sign-extends it, and writes it to a register. For information about memory accesses
       see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 0 1 1 1 0 0 0 1 x 0                        imm9                1 0         Rn              Rt
           size                      opc


       32-bit variant

       Applies when opc = 11.

       LDTRSB <Wt>, [<Xn|SP>{, #<simm>}]


       64-bit variant

       Applies when opc = 10.

       LDTRSB <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_UNPRIV;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
            X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDTRSH','       Load Register Signed Halfword (unprivileged) calculates an address from a base register and an immediate offset,       (C6.6.101)
       loads a signed byte from memory, sign-extends it, and writes it to a register. For information about memory accesses
       see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 1 1 1 1 0 0 0 1 x 0                        imm9                1 0         Rn              Rt
           size                      opc


       32-bit variant

       Applies when opc = 11.

       LDTRSH <Wt>, [<Xn|SP>{, #<simm>}]


       64-bit variant

       Applies when opc = 10.

       LDTRSH <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_UNPRIV;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
            X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDTRSW','       Load Register Signed Word (unprivileged) calculates an address from a base register and an immediate offset, loads       (C6.6.102)
       a signed byte from memory, sign-extends it, and writes it to a register. For information about memory accesses see
       Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           1 0 1 1 1 0 0 0 1 0 0                        imm9               1 0         Rn               Rt
           size                      opc


       Unscaled offset variant

       LDTRSW <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_UNPRIV;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;
Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDUR','       Load Register (unscaled) calculates an address from a base register and an immediate offset, loads a 32-bit word or       (C6.6.103)
       64-bit doubleword from memory, zero-extends it, and writes it to a register. For information about memory accesses
       see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           1 x 1 1 1 0 0 0 0 1 0                        imm9               0 0         Rn               Rt
           size                      opc


       32-bit variant

       Applies when size = 10.

       LDUR <Wt>, [<Xn|SP>{, #<simm>}]


       64-bit variant

       Applies when size = 11.

       LDUR <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   memop = MemOp_PREFETCH;
                   if opc<0> == ''1'' then UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
         else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDURB','       Load Register Byte (unscaled) calculates an address from a base register and an immediate offset, loads a byte from       (C6.6.104)
       memory, zero-extends it, and writes it to a register. For information about memory accesses see Load/Store
       addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 0 1 1 1 0 0 0 0 1 0                        imm9               0 0         Rn               Rt
           size                      opc


       Unscaled offset variant

       LDURB <Wt>, [<Xn|SP>{, #<simm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   memop = MemOp_PREFETCH;
                   if opc<0> == ''1'' then UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;
Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDURH','       Load Register Halfword (unscaled) calculates an address from a base register and an immediate offset, loads a       (C6.6.105)
       halfword from memory, zero-extends it, and writes it to a register. For information about memory accesses see
       Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 1 1 1 1 0 0 0 0 1 0                        imm9               0 0         Rn               Rt
           size                      opc


       Unscaled offset variant

       LDURH <Wt>, [<Xn|SP>{, #<simm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   memop = MemOp_PREFETCH;
                   if opc<0> == ''1'' then UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;
Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDURSB','       Load Register Signed Byte (unscaled) calculates an address from a base register and an immediate offset, loads a       (C6.6.106)
       signed byte from memory, sign-extends it, and writes it to a register. For information about memory accesses see
       Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 0 1 1 1 0 0 0 1 x 0                        imm9               0 0         Rn               Rt
           size                      opc


       32-bit variant

       Applies when opc = 11.

       LDURSB <Wt>, [<Xn|SP>{, #<simm>}]


       64-bit variant

       Applies when opc = 10.

       LDURSB <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   memop = MemOp_PREFETCH;
                   if opc<0> == ''1'' then UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
         else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDURSH','       Load Register Signed Halfword (unscaled) calculates an address from a base register and an immediate offset, loads       (C6.6.107)
       a signed halfword from memory, sign-extends it, and writes it to a register. For information about memory accesses
       see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           0 1 1 1 1 0 0 0 1 x 0                        imm9               0 0         Rn               Rt
           size                      opc


       32-bit variant

       Applies when opc = 11.

       LDURSH <Wt>, [<Xn|SP>{, #<simm>}]


       64-bit variant

       Applies when opc = 10.

       LDURSH <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   memop = MemOp_PREFETCH;
                   if opc<0> == ''1'' then UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
         else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDURSW','       Load Register Signed Word (unscaled) calculates an address from a base register and an immediate offset, loads a       (C6.6.108)
       signed word from memory, sign-extends it, and writes it to a register. For information about memory accesses see
       Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
           1 0 1 1 1 0 0 0 1 0 0                        imm9               0 0         Rn               Rt
           size                      opc


       Unscaled offset variant

       LDURSW <Xt>, [<Xn|SP>{, #<simm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                        in the "imm9" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   memop = MemOp_PREFETCH;
                   if opc<0> == ''1'' then UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;
Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','LDXP','       Load Exclusive Pair of Registers loads two 32-bit words or two 64-bit doublewords from memory, and writes them       (C6.6.109)
       to two registers. A 32-bit pair requires the address to be doubleword aligned and is single-copy atomic at
       doubleword granularity. A 64-bit pair requires the address to be quadword aligned and is single-copy atomic for
       each doubleword at doubleword granularity. The PE marks the physical address being accessed as an exclusive
       access. This exclusive access mark is checked by Store Exclusive instructions. See Synchronization and semaphores
       on page B2-103. For information about memory accesses see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20            16 15 14           10 9              5 4             0
           1 x 0 0 1 0 0 0 0 1 1 (1) (1) (1) (1) (1) 0                Rt2               Rn             Rt
           size                    o2 L o1          Rs        o0


       32-bit variant

       Applies when size = 10.

       LDXP <Wt1>, <Wt2>, [<Xn|SP>{,#0}]


       64-bit variant

       Applies when size = 11.

       LDXP <Xt1>, <Xt2>, [<Xn|SP>{,#0}]


       Decode for all variants of this encoding

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2); // ignored by load/store single register
         integer s = UInt(Rs);     // ignored by all loads and store-release

         if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
         if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

         AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
         boolean excl = (o2 == ''0'');
         boolean pair = (o1 == ''1'');
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         integer elsize = 8 << UInt(size);
         integer regsize = if elsize == 64 then 64 else 32;
         integer datasize = if pair then elsize * 2 else elsize;


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDXP on page J1-5407.


       Assembler symbols

       <Wt1>           Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Wt2>           Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                       field.

       <Xt1>           Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

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


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
    assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_UNKNOWN     rt_unknown = TRUE;     // result is UNKNOWN
         when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP         EndOfInstruction();

 if memop == MemOp_STORE && excl then
    if s == t || (pair && s == t2) then
         Constraint c = ConstrainUnpredictable();
         assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
        case c of
            when Constraint_UNKNOWN      rt_unknown = TRUE;      // store UNKNOWN value
            when Constraint_NONE         rt_unknown = FALSE;     // store original value
            when Constraint_UNDEF        UnallocatedEncoding();
            when Constraint_NOP          EndOfInstruction();
    if s == n && n != 31 then
         Constraint c = ConstrainUnpredictable();
         assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
        case c of
            when Constraint_UNKNOWN      rn_unknown = TRUE;      // address is UNKNOWN
            when Constraint_NONE         rn_unknown = FALSE;     // address is original base
            when Constraint_UNDEF        UnallocatedEncoding();
            when Constraint_NOP          EndOfInstruction();

 if n == 31 then
     CheckSPAlignment();
    address = SP[];
 elsif rn_unknown then
    address = bits(64) UNKNOWN;
 else
    address = X[n];

 case memop of
    when MemOp_STORE
         if rt_unknown then
            data = bits(datasize) UNKNOWN;
         elsif pair then
            assert excl;
            bits(datasize DIV 2) el1 = X[t];
            bits(datasize DIV 2) el2 = X[t2];
            data = if BigEndian() then el1 : el2 else el2 : el1;
         else
            data = X[t];

         if excl then
            // store {release} exclusive register|pair (atomic)
            bit status = ''1'';
            // Check whether the Exclusive Monitors are set to include the
            // physical memory locations corresponding to virtual address
            // range [address, address+dbytes-1].
            if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                 // This atomic write will be rejected if it does not refer
                 // to the same physical locations after address translation.
                 Mem[address, dbytes, acctype] = data;
                 status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
                               X[t2] = data<elsize-1:0>;
                           else
                               X[t]  = data<elsize-1:0>;
                               X[t2] = data<datasize-1:elsize>;
                      else // elsize == 64
                           // 64-bit load exclusive pair (not atomic),
                           // but must be 128-bit aligned
                           if address != Align(address, dbytes) then
                              iswrite = FALSE;
                              secondstage = FALSE;
                              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                           X[t]  = Mem[address + 0, 8, acctype];
                           X[t2] = Mem[address + 8, 8, acctype];
                   else
                      // load {acquire} {exclusive} single register
                      data = Mem[address, dbytes, acctype];
                       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDXR','Load Exclusive Register loads a 32-bit word or a 64-bit doubleword from memory, and writes it to a register. The       (C6.6.110)
memory access is atomic. The PE marks the physical address being accessed as an exclusive access. This exclusive
access mark is checked by Store Exclusive instructions. See Synchronization and semaphores on page B2-103. For
information about memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4             0
   1 x 0 0 1 0 0 0 0 1 0 (1) (1) (1) (1) (1) 0 (1) (1) (1) (1) (1)            Rn              Rt
   size                    o2 L o1        Rs        o0       Rt2


32-bit variant

Applies when size = 10.

LDXR <Wt>, [<Xn|SP>{,#0}]


64-bit variant

Applies when size = 11.

LDXR <Xt>, [<Xn|SP>{,#0}]


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);    // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Assembler symbols

<Wt>           Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

<Xt>           Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
     assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
     case c of
                   when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && excl then
              if s == t || (pair && s == t2) then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
                      when Constraint_NONE       rt_unknown = FALSE;       // store original value
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP        EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
                      when Constraint_NONE       rn_unknown = FALSE;       // address is original base
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP        EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
      // load exclusive pair
      assert excl;
      if rt_unknown then
          // ConstrainedUNPREDICTABLE case
          X[t]   = bits(datasize) UNKNOWN;
      elsif elsize == 32 then
          // 32-bit load exclusive pair (atomic)
          data = Mem[address, dbytes, acctype];
          if BigEndian() then
               X[t]  = data<datasize-1:elsize>;
               X[t2] = data<elsize-1:0>;
          else
               X[t]  = data<elsize-1:0>;
               X[t2] = data<datasize-1:elsize>;
      else // elsize == 64
          // 64-bit load exclusive pair (not atomic),
          // but must be 128-bit aligned
          if address != Align(address, dbytes) then
              iswrite = FALSE;
              secondstage = FALSE;
              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
          X[t]   = Mem[address + 0, 8, acctype];
          X[t2] = Mem[address + 8, 8, acctype];
   else
      // load {acquire} {exclusive} single register
      data = Mem[address, dbytes, acctype];
       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDXRB','      Load Exclusive Register Byte loads a byte from memory, zero-extends it and writes it to a register. The memory       (C6.6.111)
      access is atomic. The PE marks the physical address being accessed as an exclusive access. This exclusive access
      mark is checked by Store Exclusive instructions. See Synchronization and semaphores on page B2-103. For
      information about memory accesses see Load/Store addressing modes on page C1-122.




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4            0
          0 0 0 0 1 0 0 0 0 1 0 (1) (1) (1) (1) (1) 0 (1) (1) (1) (1) (1)             Rn              Rt
          size                     o2 L o1        Rs        o0       Rt2


      No offset variant

      LDXRB <Wt>, [<Xn|SP>{,#0}]


      Decode for this encoding

        integer n = UInt(Rn);
        integer t = UInt(Rt);
        integer t2 = UInt(Rt2); // ignored by load/store single register
        integer s = UInt(Rs);     // ignored by all loads and store-release

        if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
        if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

        AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
        boolean excl = (o2 == ''0'');
        boolean pair = (o1 == ''1'');
        MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
        integer elsize = 8 << UInt(size);
        integer regsize = if elsize == 64 then 64 else 32;
        integer datasize = if pair then elsize * 2 else elsize;


      Assembler symbols

      <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


      Operation

        bits(64) address;
        bits(datasize) data;
        constant integer dbytes = datasize DIV 8;
        boolean rt_unknown = FALSE;
        boolean rn_unknown = FALSE;

        if memop == MemOp_LOAD && pair && t == t2 then
             Constraint c = ConstrainUnpredictable();
             assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
             case c of
                  when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
                  when Constraint_UNDEF       UnallocatedEncoding();
                  when Constraint_NOP         EndOfInstruction();

        if memop == MemOp_STORE && excl then
             if s == t || (pair && s == t2) then
                  Constraint c = ConstrainUnpredictable();
                  assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                  case c of
                     when Constraint_UNKNOWN      rt_unknown = TRUE;       // store UNKNOWN value
           when Constraint_NONE       rt_unknown = FALSE;       // store original value
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();
   if s == n && n != 31 then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
           when Constraint_NONE       rn_unknown = FALSE;       // address is original base
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();

if n == 31 then
    CheckSPAlignment();
   address = SP[];
elsif rn_unknown then
   address = bits(64) UNKNOWN;
else
   address = X[n];

case memop of
   when MemOp_STORE
       if rt_unknown then
           data = bits(datasize) UNKNOWN;
       elsif pair then
           assert excl;
           bits(datasize DIV 2) el1 = X[t];
           bits(datasize DIV 2) el2 = X[t2];
           data = if BigEndian() then el1 : el2 else el2 : el1;
       else
           data = X[t];

       if excl then
           // store {release} exclusive register|pair (atomic)
           bit status = ''1'';
           // Check whether the Exclusive Monitors are set to include the
           // physical memory locations corresponding to virtual address
           // range [address, address+dbytes-1].
           if AArch64.ExclusiveMonitorsPass(address, dbytes) then
               // This atomic write will be rejected if it does not refer
               // to the same physical locations after address translation.
               Mem[address, dbytes, acctype] = data;
               status = ExclusiveMonitorsStatus();
           X[s] = ZeroExtend(status, 32);
       else
           // store release register (atomic)
           Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
       if excl then
           // Tell the Exclusive Monitors to record a sequence of one or more atomic
           // memory reads from virtual address range [address, address+dbytes-1].
           // The Exclusive Monitor will only be set if all the reads are from the
           // same dbytes-aligned physical address, to allow for the possibility of
           // an atomicity break if the translation is changed between reads.
           AArch64.SetExclusiveMonitors(address, dbytes);

       if pair then
           // load exclusive pair
           assert excl;
           if rt_unknown then
               // ConstrainedUNPREDICTABLE case
               X[t]   = bits(datasize) UNKNOWN;
           elsif elsize == 32 then
               // 32-bit load exclusive pair (atomic)
               data = Mem[address, dbytes, acctype];
               if BigEndian() then
                   X[t]   = data<datasize-1:elsize>;
                              X[t2] = data<elsize-1:0>;
                         else
                              X[t]  = data<elsize-1:0>;
                              X[t2] = data<datasize-1:elsize>;
                     else // elsize == 64
                         // 64-bit load exclusive pair (not atomic),
                         // but must be 128-bit aligned
                         if address != Align(address, dbytes) then
                             iswrite = FALSE;
                             secondstage = FALSE;
                             AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                         X[t]   = Mem[address + 0, 8, acctype];
                         X[t2] = Mem[address + 8, 8, acctype];
                  else
                     // load {acquire} {exclusive} single register
                     data = Mem[address, dbytes, acctype];
                      X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LDXRH','Load Exclusive Register Halfword loads a halfword from memory, zero-extends it and writes it to a register. The       (C6.6.112)
memory access is atomic. The PE marks the physical address being accessed as an exclusive access. This exclusive
access mark is checked by Store Exclusive instructions. See Synchronization and semaphores on page B2-103. For
information about memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4             0
   0 1 0 0 1 0 0 0 0 1 0 (1) (1) (1) (1) (1) 0 (1) (1) (1) (1) (1)            Rn              Rt
   size                    o2 L o1        Rs        o0       Rt2


No offset variant

LDXRH <Wt>, [<Xn|SP>{,#0}]


Decode for this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);    // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Assembler symbols

<Wt>           Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
     assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
     case c of
         when Constraint_UNKNOWN      rt_unknown = TRUE;      // result is UNKNOWN
         when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP          EndOfInstruction();

 if memop == MemOp_STORE && excl then
     if s == t || (pair && s == t2) then
         Constraint c = ConstrainUnpredictable();
         assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
         case c of
             when Constraint_UNKNOWN      rt_unknown = TRUE;       // store UNKNOWN value
                      when Constraint_NONE       rt_unknown = FALSE;       // store original value
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
                      when Constraint_NONE       rn_unknown = FALSE;       // address is original base
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
               X[t2] = data<elsize-1:0>;
          else
               X[t]  = data<elsize-1:0>;
               X[t2] = data<datasize-1:elsize>;
      else // elsize == 64
          // 64-bit load exclusive pair (not atomic),
          // but must be 128-bit aligned
          if address != Align(address, dbytes) then
              iswrite = FALSE;
              secondstage = FALSE;
              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
          X[t]   = Mem[address + 0, 8, acctype];
          X[t2] = Mem[address + 8, 8, acctype];
   else
      // load {acquire} {exclusive} single register
      data = Mem[address, dbytes, acctype];
       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','LSL','Logical shift left (register): Rd = LSL(Rn, Rm)       (C6.6.113)

This instruction is an alias of the LSLV instruction. This means that:

.       The encodings in this description are named to match the encodings of LSLV.

.       The description of LSLV gives the operational pseudocode for this instruction.




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


32-bit variant

Applies when sf = 0.

LSL <Wd>, <Wn>, <Wm>

is equivalent to

LSLV <Wd>, <Wn>, <Wm>

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

LSL <Xd>, <Xn>, <Xm>

is equivalent to

LSLV <Xd>, <Xn>, <Xm>

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding a shift amount from 0 to
                31 in its bottom 5 bits, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding a shift amount from 0 to
                63 in its bottom 6 bits, encoded in the "Rm" field.


Operation

The description of LSLV gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','LSLV','Logical shift left variable: Rd = LSL(Rn, Rm)       (C6.6.115)

This instruction is used by the alias LSL (register). 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
    sf 0 0 1 1 0 1 0 1 1 0                  Rm         0 0 1 0 0 0              Rn              Rd
                                                                     op2


32-bit variant

Applies when sf = 0.

LSLV <Wd>, <Wn>, <Wm>


64-bit variant

Applies when sf = 1.

LSLV <Xd>, <Xn>, <Xm>


Decode for all variants of this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  integer datasize = if sf == ''1'' then 64 else 32;
  ShiftType shift_type = DecodeShift(op2);


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding a shift amount from 0 to
                31 in its bottom 5 bits, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding a shift amount from 0 to
                63 in its bottom 6 bits, encoded in the "Rm" field.


Operation

  bits(datasize) result;
  bits(datasize) operand2 = X[m];

  result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize);
  X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','LSR','Logical shift right (register): Rd = LSR(Rn, Rm)       (C6.6.116)

This instruction is an alias of the LSRV instruction. This means that:

.      The encodings in this description are named to match the encodings of LSRV.

.      The description of LSRV gives the operational pseudocode for this instruction.




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


32-bit variant

Applies when sf = 0.

LSR <Wd>, <Wn>, <Wm>

is equivalent to

LSRV <Wd>, <Wn>, <Wm>

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

LSR <Xd>, <Xn>, <Xm>

is equivalent to

LSRV <Xd>, <Xn>, <Xm>

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding a shift amount from 0 to
                31 in its bottom 5 bits, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding a shift amount from 0 to
                63 in its bottom 6 bits, encoded in the "Rm" field.


Operation

The description of LSRV gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','LSRV','Logical shift right variable: Rd = LSR(Rn, Rm)       (C6.6.118)

This instruction is used by the alias LSR (register). 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
  sf 0 0 1 1 0 1 0 1 1 0                    Rm         0 0 1 0 0 1              Rn              Rd
                                                                     op2


32-bit variant

Applies when sf = 0.

LSRV <Wd>, <Wn>, <Wm>


64-bit variant

Applies when sf = 1.

LSRV <Xd>, <Xn>, <Xm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 ShiftType shift_type = DecodeShift(op2);


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding a shift amount from 0 to
                31 in its bottom 5 bits, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding a shift amount from 0 to
                63 in its bottom 6 bits, encoded in the "Rm" field.


Operation

 bits(datasize) result;
 bits(datasize) operand2 = X[m];

 result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize);
 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','MADD','       Multiply-add: Rd = Ra + Rn * Rm       (C6.6.119)

       This instruction is used by the alias MUL. See the Alias conditions table for details of when each alias is preferred.




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


       32-bit variant

       Applies when sf = 0.

       MADD <Wd>, <Wn>, <Wm>, <Wa>


       64-bit variant

       Applies when sf = 1.

       MADD <Xd>, <Xn>, <Xm>, <Xa>


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer a = UInt(Ra);
         integer destsize = if sf == ''1'' then 64 else 32;
         integer datasize = destsize;
         boolean sub_op = (o0 == ''1'');


       Alias conditions


                            Alias                     is preferred when

                            MUL                       Ra == ''11111''



       Assembler symbols

       <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                       the "Rn" field.

       <Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                       the "Rm" field.

       <Wa>            Is the 32-bit name of the third general-purpose source register holding the addend, encoded in the
                       "Ra" field.

       <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>            Is the 64-bit name of the first general-purpose source register holding the multiplicand, encoded in
                       the "Rn" field.

       <Xm>            Is the 64-bit name of the second general-purpose source register holding the multiplier, encoded in
                       the "Rm" field.
<Xa>          Is the 64-bit name of the third general-purpose source register holding the addend, encoded in the
              "Ra" field.


Operation

 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];
 bits(destsize) operand3 = X[a];

 integer result;

 if sub_op then
    result = UInt(operand3) - (UInt(operand1) * UInt(operand2));
 else
    result = UInt(operand3) + (UInt(operand1) * UInt(operand2));

 X[d] = result<destsize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','MNEG','Multiply-negate: Rd = -(Rn * Rm)       (C6.6.120)

This instruction is an alias of the MSUB instruction. This means that:

.       The encodings in this description are named to match the encodings of MSUB.

.       The description of MSUB gives the operational pseudocode for this instruction.




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


32-bit variant

Applies when sf = 0.

MNEG <Wd>, <Wn>, <Wm>

is equivalent to

MSUB <Wd>, <Wn>, <Wm>, WZR

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

MNEG <Xd>, <Xn>, <Xm>

is equivalent to

MSUB <Xd>, <Xn>, <Xm>, XZR

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

The description of MSUB gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','MOV','Move between register and stack pointer: Rd = Rn       (C6.6.121)

This instruction is an alias of the ADD (immediate) instruction. This means that:

.      The encodings in this description are named to match the encodings of ADD (immediate).

.      The description of ADD (immediate) gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                                   10 9              5 4              0
   sf 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0                                 Rn              Rd
     op S                     shift               imm12


32-bit variant

Applies when sf = 0.

MOV <Wd|WSP>, <Wn|WSP>

is equivalent to

ADD <Wd|WSP>, <Wn|WSP>, #0

and is the preferred disassembly when (Rd == ''11111'' || Rn == ''11111'').

64-bit variant

Applies when sf = 1.

MOV <Xd|SP>, <Xn|SP>

is equivalent to

ADD <Xd|SP>, <Xn|SP>, #0

and is the preferred disassembly when (Rd == ''11111'' || Rn == ''11111'').


Assembler symbols

<Wd|WSP>        Is the 32-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
                field.

<Wn|WSP>        Is the 32-bit name of the source general-purpose register or stack pointer, encoded in the "Rn" field.

<Xd|SP>         Is the 64-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
                field.

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


Operation

The description of ADD (immediate) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','MOVK','      Move 16-bit immediate into register, keeping other bits unchanged: Rd<shift+15:shift> = imm16       (C6.6.126)




          31 30 29 28 27 26 25 24 23 22 21 20                                               5 4               0
          sf 1 1 1 0 0 1 0 1           hw                        imm16                                Rd
              opc


      32-bit variant

      Applies when sf = 0.

      MOVK <Wd>, #<imm>{, LSL #<shift>}


      64-bit variant

      Applies when sf = 1.

      MOVK <Xd>, #<imm>{, LSL #<shift>}


      Decode for all variants of this encoding

        integer d = UInt(Rd);
        integer datasize = if sf == ''1'' then 64 else 32;
        bits(16) imm = imm16;
        integer pos;
        MoveWideOp opcode;

        case opc of
             when ''00'' opcode = MoveWideOp_N;
             when ''10'' opcode = MoveWideOp_Z;
             when ''11'' opcode = MoveWideOp_K;
             otherwise UnallocatedEncoding();

        if sf == ''0'' && hw<1> == ''1'' then UnallocatedEncoding();
        pos = UInt(hw:''0000'');


      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.

      <imm>           Is the 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.

      <shift>         For the 32-bit variant: is the amount by which to shift the immediate left, either 0 (the default) or
                      16, encoded in the "hw" field as <shift>/16.

                      For the 64-bit variant: is the amount by which to shift the immediate left, either 0 (the default), 16,
                      32 or 48, encoded in the "hw" field as <shift>/16.


      Operation

        bits(datasize) result;

        if opcode == MoveWideOp_K then
             result = X[d];
        else
             result = Zeros();

        result<pos+15:pos> = imm;
if opcode == MoveWideOp_N then
   result = NOT(result);
X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','MOVN','       Move inverse of shifted 16-bit immediate to register: Rd = NOT (LSL (imm16, shift))       (C6.6.127)

       This instruction is used by the alias MOV (inverted wide immediate). See the Alias conditions table for details of
       when each alias is preferred.




           31 30 29 28 27 26 25 24 23 22 21 20                                              5 4              0
           sf 0 0 1 0 0 1 0 1           hw                        imm16                               Rd
               opc


       32-bit variant

       Applies when sf = 0.

       MOVN <Wd>, #<imm>{, LSL #<shift>}


       64-bit variant

       Applies when sf = 1.

       MOVN <Xd>, #<imm>{, LSL #<shift>}


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer datasize = if sf == ''1'' then 64 else 32;
         bits(16) imm = imm16;
         integer pos;
         MoveWideOp opcode;

         case opc of
              when ''00'' opcode = MoveWideOp_N;
              when ''10'' opcode = MoveWideOp_Z;
              when ''11'' opcode = MoveWideOp_K;
              otherwise UnallocatedEncoding();

         if sf == ''0'' && hw<1> == ''1'' then UnallocatedEncoding();
         pos = UInt(hw:''0000'');


       Alias conditions


          Alias                  of variant         is preferred when

          MOV (inverted wide     64-bit             ! (IsZero(imm16) && hw != ''00'')
          immediate)

          MOV (inverted wide     32-bit             ! (IsZero(imm16) && hw != ''00'') && ! IsOnes(imm16)
          immediate)


       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.

       <imm>           Is the 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.
<shift>       For the 32-bit variant: is the amount by which to shift the immediate left, either 0 (the default) or
              16, encoded in the "hw" field as <shift>/16.

              For the 64-bit variant: is the amount by which to shift the immediate left, either 0 (the default), 16,
              32 or 48, encoded in the "hw" field as <shift>/16.


Operation

 bits(datasize) result;

 if opcode == MoveWideOp_K then
    result = X[d];
 else
    result = Zeros();

 result<pos+15:pos> = imm;
 if opcode == MoveWideOp_N then
    result = NOT(result);
 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','MOVZ','       Move shifted 16-bit immediate to register: Rd = LSL (imm16, shift)       (C6.6.128)

       This instruction is used by the alias MOV (wide immediate). See the Alias conditions table for details of when each
       alias is preferred.




           31 30 29 28 27 26 25 24 23 22 21 20                                                5 4               0
           sf 1 0 1 0 0 1 0 1            hw                        imm16                                Rd
               opc


       32-bit variant

       Applies when sf = 0.

       MOVZ <Wd>, #<imm>{, LSL #<shift>}


       64-bit variant

       Applies when sf = 1.

       MOVZ <Xd>, #<imm>{, LSL #<shift>}


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer datasize = if sf == ''1'' then 64 else 32;
         bits(16) imm = imm16;
         integer pos;
         MoveWideOp opcode;

         case opc of
              when ''00'' opcode = MoveWideOp_N;
              when ''10'' opcode = MoveWideOp_Z;
              when ''11'' opcode = MoveWideOp_K;
              otherwise UnallocatedEncoding();

         if sf == ''0'' && hw<1> == ''1'' then UnallocatedEncoding();
         pos = UInt(hw:''0000'');


       Alias conditions


                             Alias                     is preferred when

                             MOV (wide                 ! (IsZero(imm16) && hw != ''00'')
                             immediate)


       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.

       <imm>            Is the 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.

       <shift>          For the 32-bit variant: is the amount by which to shift the immediate left, either 0 (the default) or
                        16, encoded in the "hw" field as <shift>/16.

                        For the 64-bit variant: is the amount by which to shift the immediate left, either 0 (the default), 16,
                        32 or 48, encoded in the "hw" field as <shift>/16.
Operation

 bits(datasize) result;

 if opcode == MoveWideOp_K then
    result = X[d];
 else
    result = Zeros();

 result<pos+15:pos> = imm;
 if opcode == MoveWideOp_N then
    result = NOT(result);
 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','MRS','Move from system register       (C6.6.129)




    31 30 29 28 27 26 25 24 23 22 21 20 19 18     16 15       12 11         8 7      5 4              0
    1 1 0 1 0 1 0 1 0 0 1 1 o0                op1        CRn         CRm          op2          Rt
                                   L


System variant

MRS <Xt>, <systemreg>


Decode for this encoding

  CheckSystemAccess(''1'':o0, op1, CRn, CRm, op2, Rt, L);

  integer t = UInt(Rt);

  integer sys_op0 = 2 + UInt(o0);
  integer sys_op1 = UInt(op1);
  integer sys_op2 = UInt(op2);
  integer sys_crn = UInt(CRn);
  integer sys_crm = UInt(CRm);
  boolean read = (L == ''1'');


Assembler symbols

<Xt>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rt" field.

<systemreg>     Is a system register name, encoded in the "o0:op1:CRn:CRm:op2".


Operation

  if read then
       X[t] = System_Get(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2);
  else
       System_Put(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2, X[t]);');
INSERT INTO "instructions" VALUES('ARM','MSR','Move immediate to process state field       (C6.6.130)




  31 30 29 28 27 26 25 24 23 22 21 20 19 18     16 15 14 13 12 11        8 7       5 4 3 2 1 0
  1 1 0 1 0 1 0 1 0 0 0 0 0                op1      0 1 0 0         CRm        op2    1 1 1 1 1




System variant

MSR <pstatefield>, #<imm>


Decode for this encoding

 CheckSystemAccess(''00'', op1, ''0100'', CRm, op2, ''11111'', ''0'');

 bits(4) operand = CRm;
 PSTATEField field;
 case op1:op2 of
     when ''000 101'' field = PSTATEField_SP;
     when ''011 110'' field = PSTATEField_DAIFSet;
     when ''011 111'' field = PSTATEField_DAIFClr;
     otherwise       UnallocatedEncoding();

 // Check that an AArch64 MSR/MRS access to the DAIF flags is permitted
 if op1 == ''011'' && PSTATE.EL == EL0 && SCTLR_EL1.UMA == ''0'' then
     AArch64.SystemRegisterTrap(EL1, ''00'', op2, op1, ''0100'', ''11111'', CRm, ''0'');


Assembler symbols

<pstatefield> Is a PSTATE field name, encoded in the "op1:op2" field. It can have the following values:

              SPSel       when op1 = 000, op2 = 101

              DAIFSet     when op1 = 011, op2 = 110

              DAIFClr     when op1 = 011, op2 = 111

              It is RESERVED when:

              .      op1 = 000, op2 = 0xx.

              .      op1 = 000, op2 = 100.

              .      op1 = 000, op2 = 11x.

              .      op1 = 001, op2 = xxx.

              .      op1 = 010, op2 = xxx.

              .      op1 = 011, op2 = 0xx.

              .      op1 = 011, op2 = 10x.

              .      op1 = 1xx, op2 = xxx.

<imm>         Is a 4-bit unsigned immediate, in the range 0 to 15, encoded in the "CRm" field.


Operation

 case field of
     when PSTATEField_SP
        PSTATE.SP = operand<0>;
     when PSTATEField_DAIFSet
        PSTATE.D = PSTATE.D OR operand<3>;
        PSTATE.A = PSTATE.A OR operand<2>;
                   PSTATE.I = PSTATE.I OR operand<1>;
                   PSTATE.F = PSTATE.F OR operand<0>;
              when PSTATEField_DAIFClr
                   PSTATE.D = PSTATE.D AND NOT(operand<3>);
                   PSTATE.A = PSTATE.A AND NOT(operand<2>);
                   PSTATE.I = PSTATE.I AND NOT(operand<1>);
                   PSTATE.F = PSTATE.F AND NOT(operand<0>);');
INSERT INTO "instructions" VALUES('ARM','MSUB','       Multiply-subtract: Rd = Ra - Rn * Rm       (C6.6.132)

       This instruction is used by the alias MNEG. See the Alias conditions table for details of when each alias is preferred.




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


       32-bit variant

       Applies when sf = 0.

       MSUB <Wd>, <Wn>, <Wm>, <Wa>


       64-bit variant

       Applies when sf = 1.

       MSUB <Xd>, <Xn>, <Xm>, <Xa>


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer a = UInt(Ra);
         integer destsize = if sf == ''1'' then 64 else 32;
         integer datasize = destsize;
         boolean sub_op = (o0 == ''1'');


       Alias conditions


                             Alias                    is preferred when

                             MNEG                     Ra == ''11111''



       Assembler symbols

       <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                       the "Rn" field.

       <Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                       the "Rm" field.

       <Wa>            Is the 32-bit name of the third general-purpose source register holding the minuend, encoded in the
                       "Ra" field.

       <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>            Is the 64-bit name of the first general-purpose source register holding the multiplicand, encoded in
                       the "Rn" field.

       <Xm>            Is the 64-bit name of the second general-purpose source register holding the multiplier, encoded in
                       the "Rm" field.
<Xa>          Is the 64-bit name of the third general-purpose source register holding the minuend, encoded in the
              "Ra" field.


Operation

 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];
 bits(destsize) operand3 = X[a];

 integer result;

 if sub_op then
    result = UInt(operand3) - (UInt(operand1) * UInt(operand2));
 else
    result = UInt(operand3) + (UInt(operand1) * UInt(operand2));

 X[d] = result<destsize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','MUL','Multiply: Rd = Rn * Rm       (C6.6.133)

This instruction is an alias of the MADD instruction. This means that:

.       The encodings in this description are named to match the encodings of MADD.

.       The description of MADD gives the operational pseudocode for this instruction.




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


32-bit variant

Applies when sf = 0.

MUL <Wd>, <Wn>, <Wm>

is equivalent to

MADD <Wd>, <Wn>, <Wm>, WZR

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

MUL <Xd>, <Xn>, <Xm>

is equivalent to

MADD <Xd>, <Xn>, <Xm>, XZR

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

The description of MADD gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','MVN','Bitwise NOT (shifted register): Rd = NOT shift(Rm, amount)       (C6.6.134)

This instruction is an alias of the ORN (shifted register) instruction. This means that:

.      The encodings in this description are named to match the encodings of ORN (shifted register).

.      The description of ORN (shifted register) gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20                16 15              10 9             5 4             0
   sf 0 1 0 1 0 1 0 shift 1                  Rm               imm6          1 1 1 1 1             Rd
      opc                           N                                             Rn


32-bit variant

Applies when sf = 0.

MVN <Wd>, <Wm>{, <shift> #<amount>}

is equivalent to

ORN <Wd>, WZR, <Wm>{, <shift> #<amount>}

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

MVN <Xd>, <Xm>{, <shift> #<amount>}

is equivalent to

ORN <Xd>, XZR, <Xm>{, <shift> #<amount>}

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wm>            Is the 32-bit name of the general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

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

<shift>         Is the optional shift to be applied to the final source, defaulting to LSL and encoded in the "shift"
                field. It can have the following values:

                LSL          when shift = 00

                LSR          when shift = 01

                ASR          when shift = 10

                ROR          when shift = 11

<amount>        For the 32-bit variant: is the shift amount, in the range 0 to 31, defaulting to 0 and encoded in the
                "imm6" field.

                For the 64-bit variant: is the shift amount, in the range 0 to 63, defaulting to 0 and encoded in the
                "imm6" field.
       Operation

       The description of ORN (shifted register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','NEG','Negate: Rd = 0 - shift(Rm, amount)       (C6.6.135)

This instruction is an alias of the SUB (shifted register) instruction. This means that:

.      The encodings in this description are named to match the encodings of SUB (shifted register).

.      The description of SUB (shifted register) gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20                16 15              10 9            5 4              0
   sf 1 0 0 1 0 1 1 shift 0                   Rm               imm6        1 1 1 1 1              Rd
     op S                                                                        Rn


32-bit variant

Applies when sf = 0.

NEG <Wd>, <Wm>{, <shift> #<amount>}

is equivalent to

SUB  <Wd>, WZR, <Wm> {, <shift> #<amount>}

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

NEG <Xd>, <Xm>{, <shift> #<amount>}

is equivalent to

SUB  <Xd>, XZR, <Xm> {, <shift> #<amount>}

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wm>            Is the 32-bit name of the general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

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

<shift>         Is the optional shift type to be applied to the second source operand, defaulting to LSL and encoded
                in the "shift" field. It can have the following values:

                LSL          when shift = 00

                LSR          when shift = 01

                ASR          when shift = 10

                It is RESERVED when shift = 11.

<amount>        For the 32-bit variant: is the shift amount, in the range 0 to 31, defaulting to 0 and encoded in the
                "imm6" field.

                For the 64-bit variant: is the shift amount, in the range 0 to 63, defaulting to 0 and encoded in the
                "imm6" field.
       Operation

       The description of SUB (shifted register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','NEGS','Negate, setting the condition flags: Rd = 0 - shift(Rm, amount)       (C6.6.136)

This instruction is an alias of the SUBS (shifted register) instruction. This means that:

.      The encodings in this description are named to match the encodings of SUBS (shifted register).

.      The description of SUBS (shifted register) gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20                16 15              10 9            5 4              0
   sf 1 1 0 1 0 1 1 shift 0                   Rm               imm6        1 1 1 1 1              Rd
     op S                                                                        Rn


32-bit variant

Applies when sf = 0.

NEGS <Wd>, <Wm>{, <shift> #<amount>}

is equivalent to

SUBS <Wd>, WZR, <Wm> {, <shift> #<amount>}

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

NEGS <Xd>, <Xm>{, <shift> #<amount>}

is equivalent to

SUBS <Xd>, XZR, <Xm> {, <shift> #<amount>}

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wm>            Is the 32-bit name of the general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

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

<shift>         Is the optional shift type to be applied to the second source operand, defaulting to LSL and encoded
                in the "shift" field. It can have the following values:

                LSL          when shift = 00

                LSR          when shift = 01

                ASR          when shift = 10

                It is RESERVED when shift = 11.

<amount>        For the 32-bit variant: is the shift amount, in the range 0 to 31, defaulting to 0 and encoded in the
                "imm6" field.

                For the 64-bit variant: is the shift amount, in the range 0 to 63, defaulting to 0 and encoded in the
                "imm6" field.
       Operation

       The description of SUBS (shifted register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','NGC','Negate with carry: Rd = 0 - Rm - 1 + C       (C6.6.137)

This instruction is an alias of the SBC instruction. This means that:

.      The encodings in this description are named to match the encodings of SBC.

.      The description of SBC gives the operational pseudocode for this instruction.




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


32-bit variant

Applies when sf = 0.

NGC <Wd>, <Wm>

is equivalent to

SBC <Wd>, WZR, <Wm>

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

NGC <Xd>, <Xm>

is equivalent to

SBC <Xd>, XZR, <Xm>

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wm>            Is the 32-bit name of the general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

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


Operation

The description of SBC gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','NGCS','Negate with carry, setting the condition flags: Rd = 0 - Rm - 1 + C       (C6.6.138)

This instruction is an alias of the SBCS instruction. This means that:

.       The encodings in this description are named to match the encodings of SBCS.

.       The description of SBCS gives the operational pseudocode for this instruction.




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


32-bit variant

Applies when sf = 0.

NGCS <Wd>, <Wm>

is equivalent to

SBCS <Wd>, WZR, <Wm>

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

NGCS <Xd>, <Xm>

is equivalent to

SBCS <Xd>, XZR, <Xm>

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wm>            Is the 32-bit name of the general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

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


Operation

The description of SBCS gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','NOP','No operation       (C6.6.139)

This instruction is an alias of the HINT instruction. This means that:

.      The encodings in this description are named to match the encodings of HINT.

.      The description of HINT gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11          8 7       5 4 3 2 1 0
   1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1
                                                                      CRm      op2


System variant

NOP

is equivalent to

HINT #0

and is always the preferred disassembly.


Operation

The description of HINT gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','ORN','       Bitwise inclusive OR NOT (shifted register): Rd = Rn OR NOT shift(Rm, amount)       (C6.6.140)

       This instruction is used by the alias MVN. See the Alias conditions table for details of when each alias is preferred.




           31 30 29 28 27 26 25 24 23 22 21 20            16 15             10 9              5 4             0
           sf 0 1 0 1 0 1 0 shift 1                Rm              imm6                Rn              Rd
               opc                         N


       32-bit variant

       Applies when sf = 0.

       ORN <Wd>, <Wn>, <Wm>{, <shift> #<amount>}


       64-bit variant

       Applies when sf = 1.

       ORN <Xd>, <Xn>, <Xm>{, <shift> #<amount>}


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer datasize = if sf == ''1'' then 64 else 32;
         boolean setflags;
         LogicalOp op;
         case opc of
              when ''00'' op = LogicalOp_AND; setflags = FALSE;
              when ''01'' op = LogicalOp_ORR; setflags = FALSE;
              when ''10'' op = LogicalOp_EOR; setflags = FALSE;
              when ''11'' op = LogicalOp_AND; setflags = TRUE;

         if sf == ''0'' && imm6<5> == ''1'' then ReservedValue();

         ShiftType shift_type = DecodeShift(shift);
         integer shift_amount = UInt(imm6);
         boolean invert = (N == ''1'');


       Alias conditions


                            Alias                     is preferred when

                            MVN                       Rn == ''11111''



       Assembler symbols

       <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

       <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

       <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.
<Xm>          Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.

<shift>       Is the optional shift to be applied to the final source, defaulting to LSL and encoded in the "shift"
              field. It can have the following values:

              LSL          when shift = 00

              LSR          when shift = 01

              ASR          when shift = 10

              ROR          when shift = 11

<amount>      For the 32-bit variant: is the shift amount, in the range 0 to 31, defaulting to 0 and encoded in the
              "imm6" field.

              For the 64-bit variant: is the shift amount, in the range 0 to 63, defaulting to 0 and encoded in the
              "imm6" field.


Operation

 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = ShiftReg(m, shift_type, shift_amount);

 if invert then operand2 = NOT(operand2);

 case op of
    when LogicalOp_AND result = operand1 AND operand2;
    when LogicalOp_ORR result = operand1 OR        operand2;
    when LogicalOp_EOR result = operand1 EOR operand2;

 if setflags then
    PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ORR','       Bitwise inclusive OR (immediate): Rd = Rn OR imm       (C6.6.141)

       This instruction is used by the alias MOV (bitmask immediate). See the Alias conditions table for details of when
       each alias is preferred.




           31 30 29 28 27 26 25 24 23 22 21               16 15             10 9             5 4             0
           sf 0 1 1 0 0 1 0 0 N                 immr               imms               Rn               Rd
               opc


       32-bit variant

       Applies when sf = 0 && N = 0.

       ORR <Wd|WSP>, <Wn>, #<imm>


       64-bit variant

       Applies when sf = 1.

       ORR <Xd|SP>, <Xn>, #<imm>


       Decode for all variants of this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer datasize = if sf == ''1'' then 64 else 32;
         boolean setflags;
         LogicalOp op;
         case opc of
              when ''00'' op = LogicalOp_AND; setflags = FALSE;
              when ''01'' op = LogicalOp_ORR; setflags = FALSE;
              when ''10'' op = LogicalOp_EOR; setflags = FALSE;
              when ''11'' op = LogicalOp_AND; setflags = TRUE;

         bits(datasize) imm;
         if sf == ''0'' && N != ''0'' then ReservedValue();
         (imm, -) = DecodeBitMasks(N, imms, immr, TRUE);


       Alias conditions


                            Alias                    is preferred when

                            MOV (bitmask             Rn == ''11111'' && ! MoveWidePreferred(sf, N, imms, immr)
                            immediate)


       Assembler symbols

       <Wd|WSP>        Is the 32-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
                       field.

       <Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

       <Xd|SP>         Is the 64-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
                       field.

       <Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.
<imm>         Is the bitmask immediate, encoded in "N:imms:immr".


Operation

 bits(datasize) result;
 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = imm;

 case op of
    when LogicalOp_AND result = operand1 AND operand2;
    when LogicalOp_ORR result = operand1 OR   operand2;
    when LogicalOp_EOR result = operand1 EOR operand2;

 if setflags then
    PSTATE.<N,Z,C,V> = result<datasize-1>:IsZeroBit(result):''00'';

 if d == 31 && !setflags then
     SP[] = result;
 else
     X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','PRFM','       Prefetch memory (immediate offset)       (C6.6.143)




           31 30 29 28 27 26 25 24 23 22 21                                   10 9             5 4             0
           1 1 1 1 1 0 0 1 1 0                          imm12                           Rn               Rt
           size                     opc


       Unsigned offset variant

       PRFM <prfop>, [<Xn|SP>{, #<pimm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);


       Assembler symbols

       <prfop>         Is the prefetch operation, encoded in the "Rt" field. It can have the following values:

                       PLDL1KEEP   when Rt = 00000

                       PLDL1STRM   when Rt = 00001

                       PLDL2KEEP   when Rt = 00010

                       PLDL2STRM   when Rt = 00011

                       PLDL3KEEP   when Rt = 00100

                       PLDL3STRM   when Rt = 00101

                       #uimm5      when Rt = 0011x

                       PLIL1KEEP   when Rt = 01000

                       PLIL1STRM   when Rt = 01001

                       PLIL2KEEP   when Rt = 01010

                       PLIL2STRM   when Rt = 01011

                       PLIL3KEEP   when Rt = 01100

                       PLIL3STRM   when Rt = 01101

                       #uimm5      when Rt = 0111x

                       PSTL1KEEP   when Rt = 10000

                       PSTL1STRM   when Rt = 10001

                       PSTL2KEEP   when Rt = 10010

                       PSTL2STRM   when Rt = 10011

                       PSTL3KEEP   when Rt = 10100

                       PSTL3STRM   when Rt = 10101

                       #uimm5      when Rt = 1011x

                       #uimm5      when Rt = 11xxx

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

       <pimm>          Is the optional positive immediate byte offset, a multiple of 8 in the range 0 to 32760, defaulting to
                       0 and encoded in the "imm12" field as <pimm>/8.
Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_NORMAL;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
    // store or zero-extending load
    memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
    regsize = if size == ''11'' then 64 else 32;
    signed = FALSE;
 else
    if size == ''11'' then
         memop = MemOp_PREFETCH;
         if opc<0> == ''1'' then UnallocatedEncoding();
    else
         // sign-extending load
         memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','PRFUM','       Prefetch memory (unscaled offset)       (C6.6.146)




           31 30 29 28 27 26 25 24 23 22 21 20                        12 11 10 9              5 4             0
           1 1 1 1 1 0 0 0 1 0 0                       imm9               0 0          Rn              Rt
           size                     opc


       Unscaled offset variant

       PRFUM <prfop>, [<Xn|SP>{, #<simm>}]


       Decode for this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = SignExtend(imm9, 64);


       Assembler symbols

       <prfop>         Is the prefetch operation, encoded in the "Rt" field. It can have the following values:

                       PLDL1KEEP   when Rt = 00000

                       PLDL1STRM   when Rt = 00001

                       PLDL2KEEP   when Rt = 00010

                       PLDL2STRM   when Rt = 00011

                       PLDL3KEEP   when Rt = 00100

                       PLDL3STRM   when Rt = 00101

                       #uimm5      when Rt = 0011x

                       PLIL1KEEP   when Rt = 01000

                       PLIL1STRM   when Rt = 01001

                       PLIL2KEEP   when Rt = 01010

                       PLIL2STRM   when Rt = 01011

                       PLIL3KEEP   when Rt = 01100

                       PLIL3STRM   when Rt = 01101

                       #uimm5      when Rt = 0111x

                       PSTL1KEEP   when Rt = 10000

                       PSTL1STRM   when Rt = 10001

                       PSTL2KEEP   when Rt = 10010

                       PSTL2STRM   when Rt = 10011

                       PSTL3KEEP   when Rt = 10100

                       PSTL3STRM   when Rt = 10101

                       #uimm5      when Rt = 1011x

                       #uimm5      when Rt = 11xxx

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

       <simm>          Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                       in the "imm9" field.
Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_NORMAL;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
    // store or zero-extending load
    memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
    regsize = if size == ''11'' then 64 else 32;
    signed = FALSE;
 else
    if size == ''11'' then
         memop = MemOp_PREFETCH;
         if opc<0> == ''1'' then UnallocatedEncoding();
    else
         // sign-extending load
         memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','RBIT','Reverse bit order       (C6.6.147)




  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
  sf 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0                                Rn              Rd
                                                                  opc


32-bit variant

Applies when sf = 0.

RBIT <Wd>, <Wn>


64-bit variant

Applies when sf = 1.

RBIT <Xd>, <Xn>


Decode for all variants of this encoding

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

 integer datasize = if sf == ''1'' then 64 else 32;

 RevOp op;
 case opc of
     when ''00''
         op = RevOp_RBIT;
     when ''01''
        op = RevOp_REV16;
     when ''10''
        op = RevOp_REV32;
     when ''11''
        if sf == ''0'' then UnallocatedEncoding();
        op = RevOp_REV64;


Assembler symbols

<Wd>           Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>           Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>           Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>           Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

 bits(datasize) result;
 bits(6) V;
 integer vbit;

 case op of
     when RevOp_REV16 V = ''001000'';
     when RevOp_REV32 V = ''011000'';
     when RevOp_REV64 V = ''111000'';
     when RevOp_RBIT   V = if datasize == 64 then ''111111'' else ''011111'';
         result = X[n];
         for vbit = 0 to 5
              // Swap pairs of 2^vbit bits in result
              if V<vbit> == ''1'' then
                   bits(datasize) tmp = result;
                   integer vsize = 1 << vbit;
                   integer base = 0;
                   while base < datasize do
                      result<base+vsize-1:base> = tmp<base+(2*vsize)-1:base+vsize>;
                      result<base+(2*vsize)-1:base+vsize> = tmp<base+vsize-1:base>;
                      base = base + (2 * vsize);
         X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','RET','Return from subroutine branches unconditionally to an address in a register, with a hint that this is a subroutine       (C6.6.148)
return.




  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 3 2 1 0
   1 1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 0 0 0 0 0 0                               Rn          0 0 0 0 0
                              op


Integer variant

RET {<Xn>}


Decode for this encoding

 integer n = UInt(Rn);
 BranchType branch_type;

 case op of
     when ''00'' branch_type = BranchType_JMP;
     when ''01'' branch_type = BranchType_CALL;
     when ''10'' branch_type = BranchType_RET;
     otherwise UnallocatedEncoding();


Assembler symbols

<Xn>          Is the 64-bit name of the general-purpose register holding the address to be branched to, encoded in
              the "Rn" field. Defaults to X30 if absent.


Operation

 bits(64) target = X[n];

 if branch_type == BranchType_CALL then X[30] = PC[] + 4;
 BranchTo(target, branch_type);');
INSERT INTO "instructions" VALUES('ARM','REV','      Reverse bytes       (C6.6.149)




          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
          sf 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 x                                Rn              Rd
                                                                          opc


      32-bit variant

      Applies when sf = 0 && opc = 10.

      REV <Wd>, <Wn>


      64-bit variant

      Applies when sf = 1 && opc = 11.

      REV <Xd>, <Xn>


      Decode for all variants of this encoding

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

        integer datasize = if sf == ''1'' then 64 else 32;

        RevOp op;
        case opc of
             when ''00''
                  op = RevOp_RBIT;
             when ''01''
                  op = RevOp_REV16;
             when ''10''
                  op = RevOp_REV32;
             when ''11''
                  if sf == ''0'' then UnallocatedEncoding();
                  op = RevOp_REV64;


      Assembler symbols

      <Wd>             Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>             Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

      <Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Xn>             Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.


      Operation

        bits(datasize) result;
        bits(6) V;
        integer vbit;

        case op of
             when RevOp_REV16 V = ''001000'';
             when RevOp_REV32 V = ''011000'';
             when RevOp_REV64 V = ''111000'';
             when RevOp_RBIT   V = if datasize == 64 then ''111111'' else ''011111'';
result = X[n];
for vbit = 0 to 5
    // Swap pairs of 2^vbit bits in result
    if V<vbit> == ''1'' then
       bits(datasize) tmp = result;
       integer vsize = 1 << vbit;
       integer base = 0;
       while base < datasize do
            result<base+vsize-1:base> = tmp<base+(2*vsize)-1:base+vsize>;
            result<base+(2*vsize)-1:base+vsize> = tmp<base+vsize-1:base>;
            base = base + (2 * vsize);
X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','REV16','      Reverse bytes in 16-bit halfwords       (C6.6.150)




          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
          sf 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1                                Rn              Rd
                                                                          opc


      32-bit variant

      Applies when sf = 0.

      REV16 <Wd>, <Wn>


      64-bit variant

      Applies when sf = 1.

      REV16 <Xd>, <Xn>


      Decode for all variants of this encoding

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

        integer datasize = if sf == ''1'' then 64 else 32;

        RevOp op;
        case opc of
             when ''00''
                  op = RevOp_RBIT;
             when ''01''
                  op = RevOp_REV16;
             when ''10''
                  op = RevOp_REV32;
             when ''11''
                  if sf == ''0'' then UnallocatedEncoding();
                  op = RevOp_REV64;


      Assembler symbols

      <Wd>             Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>             Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

      <Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Xn>             Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.


      Operation

        bits(datasize) result;
        bits(6) V;
        integer vbit;

        case op of
             when RevOp_REV16 V = ''001000'';
             when RevOp_REV32 V = ''011000'';
             when RevOp_REV64 V = ''111000'';
             when RevOp_RBIT   V = if datasize == 64 then ''111111'' else ''011111'';
result = X[n];
for vbit = 0 to 5
    // Swap pairs of 2^vbit bits in result
    if V<vbit> == ''1'' then
       bits(datasize) tmp = result;
       integer vsize = 1 << vbit;
       integer base = 0;
       while base < datasize do
            result<base+vsize-1:base> = tmp<base+(2*vsize)-1:base+vsize>;
            result<base+(2*vsize)-1:base+vsize> = tmp<base+vsize-1:base>;
            base = base + (2 * vsize);
X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','REV32','Reverse bytes in 32-bit words       (C6.6.151)




    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
    1 1 0 1 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0                                 Rn              Rd
    sf                                                              opc


64-bit variant

REV32 <Xd>, <Xn>


Decode for this encoding

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

  integer datasize = if sf == ''1'' then 64 else 32;

  RevOp op;
  case opc of
       when ''00''
            op = RevOp_RBIT;
       when ''01''
            op = RevOp_REV16;
       when ''10''
            op = RevOp_REV32;
       when ''11''
            if sf == ''0'' then UnallocatedEncoding();
            op = RevOp_REV64;


Assembler symbols

<Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>             Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

  bits(datasize) result;
  bits(6) V;
  integer vbit;

  case op of
       when RevOp_REV16 V = ''001000'';
       when RevOp_REV32 V = ''011000'';
       when RevOp_REV64 V = ''111000'';
       when RevOp_RBIT   V = if datasize == 64 then ''111111'' else ''011111'';

  result = X[n];
  for vbit = 0 to 5
       // Swap pairs of 2^vbit bits in result
       if V<vbit> == ''1'' then
            bits(datasize) tmp = result;
            integer vsize = 1 << vbit;
            integer base = 0;
            while base < datasize do
               result<base+vsize-1:base> = tmp<base+(2*vsize)-1:base+vsize>;
               result<base+(2*vsize)-1:base+vsize> = tmp<base+vsize-1:base>;
               base = base + (2 * vsize);
  X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ROR','Rotate right (immediate): Rd = ROR(Rs, shift)       (C6.6.152)

This instruction is an alias of the EXTR instruction. This means that:

.      The encodings in this description are named to match the encodings of EXTR.

.      The description of EXTR gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20              16 15              10 9              5 4              0
   sf 0 0 1 0 0 1 1 1 N 0                    Rm             imms                 Rn              Rd




32-bit variant

Applies when sf = 0 && N = 0 && imms = 0xxxxx.

ROR <Wd>, <Ws>, #<shift>

is equivalent to

EXTR <Wd>, <Ws>, <Ws>, #<shift>

and is the preferred disassembly when Rn == Rm.

64-bit variant

Applies when sf = 1 && N = 1.

ROR <Xd>, <Xs>, #<shift>

is equivalent to

EXTR <Xd>, <Xs>, <Xs>, #<shift>

and is the preferred disassembly when Rn == Rm.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Ws>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xs>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" and "Rm" fields.

<shift>         For the 32-bit variant: is the amount by which to rotate, in the range 0 to 31, encoded in the "imms"
                field.

                For the 64-bit variant: is the amount by which to rotate, in the range 0 to 63, encoded in the "imms"
                field.


Operation

The description of EXTR gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','RORV','Rotate right variable: Rd = ROR(Rn, Rm)       (C6.6.154)

This instruction is used by the alias ROR (register). 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
  sf 0 0 1 1 0 1 0 1 1 0                    Rm         0 0 1 0 1 1              Rn              Rd
                                                                     op2


32-bit variant

Applies when sf = 0.

RORV <Wd>, <Wn>, <Wm>


64-bit variant

Applies when sf = 1.

RORV <Xd>, <Xn>, <Xm>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 ShiftType shift_type = DecodeShift(op2);


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding a shift amount from 0 to
                31 in its bottom 5 bits, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding a shift amount from 0 to
                63 in its bottom 6 bits, encoded in the "Rm" field.


Operation

 bits(datasize) result;
 bits(datasize) operand2 = X[m];

 result = ShiftReg(n, shift_type, UInt(operand2) MOD datasize);
 X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','SBC','      Subtract with carry: Rd = Rn - Rm - 1 + C       (C6.6.155)

      This instruction is used by the alias NGC. See the Alias conditions table for details of when each alias is preferred.




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


      32-bit variant

      Applies when sf = 0.

      SBC <Wd>, <Wn>, <Wm>


      64-bit variant

      Applies when sf = 1.

      SBC <Xd>, <Xn>, <Xm>


      Decode for all variants of this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        integer datasize = if sf == ''1'' then 64 else 32;
        boolean sub_op = (op == ''1'');
        boolean setflags = (S == ''1'');


      Alias conditions


                           Alias                     is preferred when

                           NGC                       Rn == ''11111''



      Assembler symbols

      <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

      <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.


      Operation

        bits(datasize) result;
        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = X[m];
        bits(4) nzcv;

        if sub_op then
   operand2 = NOT(operand2);

(result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C);

if setflags then
   PSTATE.<N,Z,C,V> = nzcv;

X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','SBCS','      Subtract with carry, setting the condition flags: Rd = Rn - Rm - 1 + C       (C6.6.156)

      This instruction is used by the alias NGCS. See the Alias conditions table for details of when each alias is preferred.




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


      32-bit variant

      Applies when sf = 0.

      SBCS <Wd>, <Wn>, <Wm>


      64-bit variant

      Applies when sf = 1.

      SBCS <Xd>, <Xn>, <Xm>


      Decode for all variants of this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        integer datasize = if sf == ''1'' then 64 else 32;
        boolean sub_op = (op == ''1'');
        boolean setflags = (S == ''1'');


      Alias conditions


                           Alias                     is preferred when

                           NGCS                      Rn == ''11111''



      Assembler symbols

      <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

      <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.


      Operation

        bits(datasize) result;
        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = X[m];
        bits(4) nzcv;

        if sub_op then
   operand2 = NOT(operand2);

(result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C);

if setflags then
   PSTATE.<N,Z,C,V> = nzcv;

X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','SBFIZ','Signed bitfield insert in zero, with sign replication to left and zeros to right       (C6.6.157)

This instruction is an alias of the SBFM instruction. This means that:

.       The encodings in this description are named to match the encodings of SBFM.

.       The description of SBFM gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21                16 15                10 9            5 4               0
    sf 0 0 1 0 0 1 1 0 N                  immr                 imms               Rn               Rd
        opc


32-bit variant

Applies when sf = 0 && N = 0.

SBFIZ <Wd>, <Wn>, #<lsb>, #<width>

is equivalent to

SBFM <Wd>, <Wn>, #(-<lsb> MOD 32), #(<width>-1)

and is the preferred disassembly when UInt(imms) < UInt(immr).

64-bit variant

Applies when sf = 1 && N = 1.

SBFIZ <Xd>, <Xn>, #<lsb>, #<width>

is equivalent to

SBFM <Xd>, <Xn>, #(-<lsb> MOD 64), #(<width>-1)

and is the preferred disassembly when UInt(imms) < UInt(immr).


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<lsb>           For the 32-bit variant: is the bit number of the lsb of the destination bitfield, in the range 0 to 31.

                For the 64-bit variant: is the bit number of the lsb of the destination bitfield, in the range 0 to 63.

<width>         For the 32-bit variant: is the width of the bitfield, in the range 1 to 32-<lsb>.

                For the 64-bit variant: is the width of the bitfield, in the range 1 to 64-<lsb>.


Operation

The description of SBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SBFM','Signed bitfield move, with sign replication to left and zeros to right       (C6.6.158)

This instruction is used by the aliases ASR (immediate), SBFIZ, SBFX, SXTB, SXTH, and SXTW. See the Alias
conditions on page C6-678 table for details of when each alias is preferred.




  31 30 29 28 27 26 25 24 23 22 21                 16 15              10 9         5 4              0
  sf 0 0 1 0 0 1 1 0 N                   immr               imms             Rn            Rd
      opc


32-bit variant

Applies when sf = 0 && N = 0.

SBFM <Wd>, <Wn>, #<immr>, #<imms>


64-bit variant

Applies when sf = 1 && N = 1.

SBFM <Xd>, <Xn>, #<immr>, #<imms>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;

 boolean inzero;
 boolean extend;
 integer R;
 integer S;
 bits(datasize) wmask;
 bits(datasize) tmask;

 case opc of
     when ''00'' inzero = TRUE;      extend = TRUE;      // SBFM
     when ''01'' inzero = FALSE; extend = FALSE;         // BFM
     when ''10'' inzero = TRUE;      extend = FALSE;     // UBFM
     when ''11'' UnallocatedEncoding();

 if sf == ''1'' && N != ''1'' then ReservedValue();
 if sf == ''0'' && (N != ''0'' || immr<5> != ''0'' || imms<5> != ''0'') then ReservedValue();

 R = UInt(immr);
 S = UInt(imms);
 (wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE);
       Alias conditions


          Alias                  of variant            is preferred when

          ASR (immediate)        32-bit                imms == ''011111''

          ASR (immediate)        64-bit                imms == ''111111''

          SBFIZ                  -                     UInt(imms) < UInt(immr)

          SBFX                   -                     BFXPreferred(sf, opc<1>, imms, immr)

          SXTB                   -                     immr == ''000000'' && imms == ''000111''

          SXTH                   -                     immr == ''000000'' && imms == ''001111''

          SXTW                   -                     immr == ''000000'' && imms == ''011111''



       Assembler symbols

       <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

       <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

       <immr>          For the 32-bit variant: is the right rotate amount, in the range 0 to 31, encoded in the "immr" field.

                       For the 64-bit variant: is the right rotate amount, in the range 0 to 63, encoded in the "immr" field.

       <imms>          For the 32-bit variant: is the leftmost bit number to be moved from the source, in the range 0 to 31,
                       encoded in the "imms" field.

                       For the 64-bit variant: is the leftmost bit number to be moved from the source, in the range 0 to 63,
                       encoded in the "imms" field.


       Operation

         bits(datasize) dst = if inzero then Zeros() else X[d];
         bits(datasize) src = X[n];

         // perform bitfield move on low bits
         bits(datasize) bot = (dst AND NOT(wmask)) OR (ROR(src, R) AND wmask);

         // determine extension bits (sign, zero or dest register)
         bits(datasize) top = if extend then Replicate(src<S>) else dst;

         // combine extension bits and result bits
         X[d] = (top AND NOT(tmask)) OR (bot AND tmask);');
INSERT INTO "instructions" VALUES('ARM','SBFX','Signed bitfield extract       (C6.6.159)

This instruction is an alias of the SBFM instruction. This means that:

.      The encodings in this description are named to match the encodings of SBFM.

.      The description of SBFM gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                  16 15                10 9            5 4              0
   sf 0 0 1 0 0 1 1 0 N                   immr                imms                Rn              Rd
      opc


32-bit variant

Applies when sf = 0 && N = 0.

SBFX <Wd>, <Wn>, #<lsb>, #<width>

is equivalent to

SBFM <Wd>, <Wn>, #<lsb>, #(<lsb>+<width>-1)

and is the preferred disassembly when BFXPreferred(sf, opc<1>, imms, immr).

64-bit variant

Applies when sf = 1 && N = 1.

SBFX <Xd>, <Xn>, #<lsb>, #<width>

is equivalent to

SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1)

and is the preferred disassembly when BFXPreferred(sf, opc<1>, imms, immr).


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<lsb>           For the 32-bit variant: is the bit number of the lsb of the source bitfield, in the range 0 to 31.

                For the 64-bit variant: is the bit number of the lsb of the source bitfield, in the range 0 to 63.

<width>         For the 32-bit variant: is the width of the bitfield, in the range 1 to 32-<lsb>.

                For the 64-bit variant: is the width of the bitfield, in the range 1 to 64-<lsb>.


Operation

The description of SBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SDIV','      Signed Divide divides a signed integer register value by a signed integer register value, and writes the result to the       (C6.6.160)
      destination register of the same size as source registers, 32-bit or 64-bit. The condition flags are not affected. That
      is, it performs a signed divide: Rd = Rn / Rm.




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


      32-bit variant

      Applies when sf = 0.

      SDIV <Wd>, <Wn>, <Wm>


      64-bit variant

      Applies when sf = 1.

      SDIV <Xd>, <Xn>, <Xm>


      Decode for all variants of this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        integer datasize = if sf == ''1'' then 64 else 32;
        boolean unsigned = (o1 == ''0'');


      Assembler symbols

      <Wd>             Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>             Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Wm>             Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

      <Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Xn>             Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

      <Xm>             Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.


      Overflow

      When using the 32-bit form of the instruction, if the signed integer division 0x8000 0000 / 0xFFFF FFFF is performed,
      the pseudocode produces the intermediate integer result +231, that overflows the 32-bit signed integer range. No
      indication of this overflow case is produced, and the 32-bit result written to <Rd> must be the bottom 32 bits of the
      binary representation of +231. So the result of the division is 0x8000 0000.

      Similarly, when using the 64-bit form of the instruction, if the signed integer division 0x8000 0000 0000 0000 /
      0xFFFF FFFF FFFF FFFF is performed, the result of the division is 0x8000 0000 0000 0000.


      Operation

        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = X[m];
        integer result;
if IsZero(operand2) then
   result = 0;
else
   result = RoundTowardsZero (Int(operand1, unsigned) / Int(operand2, unsigned));

X[d] = result<datasize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','SEV','Send event       (C6.6.161)

This instruction is an alias of the HINT instruction. This means that:

.       The encodings in this description are named to match the encodings of HINT.

.       The description of HINT gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11         8 7       5 4 3 2 1 0
    1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 0 1 1 1 1 1
                                                                      CRm       op2


System variant

SEV

is equivalent to

HINT #4

and is always the preferred disassembly.


Operation

The description of HINT gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SEVL','Send event locally       (C6.6.162)

This instruction is an alias of the HINT instruction. This means that:

.      The encodings in this description are named to match the encodings of HINT.

.      The description of HINT gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11          8 7       5 4 3 2 1 0
   1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 0 1 1 1 1 1 1
                                                                      CRm      op2


System variant

SEVL

is equivalent to

HINT #5

and is always the preferred disassembly.


Operation

The description of HINT gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SMADDL','      Signed multiply-add long: Xd = Xa + Wn * Wm       (C6.6.163)

      This instruction is used by the alias SMULL. See the Alias conditions table for details of when each alias is
      preferred.




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


      64-bit variant

      SMADDL <Xd>, <Wn>, <Wm>, <Xa>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        integer a = UInt(Ra);
        integer destsize = 64;
        integer datasize = 32;
        boolean sub_op = (o0 == ''1'');
        boolean unsigned = (U == ''1'');


      Alias conditions


                           Alias                     is preferred when

                           SMULL                     Ra == ''11111''



      Assembler symbols

      <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                      the "Rn" field.

      <Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                      the "Rm" field.

      <Xa>            Is the 64-bit name of the third general-purpose source register holding the addend, encoded in the
                      "Ra" field.


      Operation

        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = X[m];
        bits(destsize) operand3 = X[a];

        integer result;

        if sub_op then
             result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned));
        else
   result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned));

X[d] = result<63:0>;');
INSERT INTO "instructions" VALUES('ARM','SMC','Generate exception targeting exception level 3       (C6.6.164)




    31 30 29 28 27 26 25 24 23 22 21 20                                              5 4 3 2 1 0
    1 1 0 1 0 1 0 0 0 0 0                                 imm16                         0 0 0 1 1




System variant

SMC #<imm>


Decode for this encoding

  bits(16) imm = imm16;


Assembler symbols

<imm>           Is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.


Operation

  if !HaveEL(EL3) || PSTATE.EL == EL0 then
       UnallocatedEncoding();

  AArch64.CheckForSMCTrap(imm);

  if SCR_EL3.SMD == ''1'' then
       // SMC disabled
       AArch64.UndefinedFault();
  else
       AArch64.CallSecureMonitor(imm);');
INSERT INTO "instructions" VALUES('ARM','SMNEGL','Signed multiply-negate long: Xd = -(Wn * Wm)       (C6.6.165)

This instruction is an alias of the SMSUBL instruction. This means that:

.      The encodings in this description are named to match the encodings of SMSUBL.

.      The description of SMSUBL gives the operational pseudocode for this instruction.




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


64-bit variant

SMNEGL <Xd>, <Wn>, <Wm>

is equivalent to

SMSUBL <Xd>, <Wn>, <Wm>, XZR

and is always the preferred disassembly.


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

The description of SMSUBL gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SMSUBL','      Signed multiply-subtract long: Xd = Xa - Wn * Wm       (C6.6.166)

      This instruction is used by the alias SMNEGL. See the Alias conditions table for details of when each alias is
      preferred.




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


      64-bit variant

      SMSUBL <Xd>, <Wn>, <Wm>, <Xa>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        integer a = UInt(Ra);
        integer destsize = 64;
        integer datasize = 32;
        boolean sub_op = (o0 == ''1'');
        boolean unsigned = (U == ''1'');


      Alias conditions


                           Alias                     is preferred when

                           SMNEGL                    Ra == ''11111''



      Assembler symbols

      <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                      the "Rn" field.

      <Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                      the "Rm" field.

      <Xa>            Is the 64-bit name of the third general-purpose source register holding the minuend, encoded in the
                      "Ra" field.


      Operation

        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = X[m];
        bits(destsize) operand3 = X[a];

        integer result;

        if sub_op then
             result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned));
        else
   result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned));

X[d] = result<63:0>;');
INSERT INTO "instructions" VALUES('ARM','SMULH','Signed multiply high: Xd = bits<127:64> of Xn * Xm       (C6.6.167)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14              10 9         5 4              0
    1 0 0 1 1 0 1 1 0 1 0                   Rm         0 (1) (1) (1) (1) (1)    Rn             Rd
                             U                                  Ra


64-bit variant

SMULH <Xd>, <Xn>, <Xm>


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  integer a = UInt(Ra);             // ignored by UMULH/SMULH
  integer destsize = 64;
  integer datasize = destsize;
  boolean unsigned = (U == ''1'');


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

  bits(datasize) operand1 = X[n];
  bits(datasize) operand2 = X[m];

  integer result;

  result = Int(operand1, unsigned) * Int(operand2, unsigned);

  X[d] = result<127:64>;');
INSERT INTO "instructions" VALUES('ARM','SMULL','Signed multiply long: Xd = Wn * Wm       (C6.6.168)

This instruction is an alias of the SMADDL instruction. This means that:

.      The encodings in this description are named to match the encodings of SMADDL.

.      The description of SMADDL gives the operational pseudocode for this instruction.




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


64-bit variant

SMULL <Xd>, <Wn>, <Wm>

is equivalent to

SMADDL <Xd>, <Wn>, <Wm>, XZR

and is always the preferred disassembly.


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

The description of SMADDL gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','STLR','      Store-Release Register stores a 32-bit word or a 64-bit doubleword to a memory location, from a register. The       (C6.6.169)
      instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For
      information about memory accesses see Load/Store addressing modes on page C1-122.




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4            0
          1 x 0 0 1 0 0 0 1 0 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)             Rn              Rt
          size                     o2 L o1        Rs        o0       Rt2


      32-bit variant

      Applies when size = 10.

      STLR <Wt>, [<Xn|SP>{,#0}]


      64-bit variant

      Applies when size = 11.

      STLR <Xt>, [<Xn|SP>{,#0}]


      Decode for all variants of this encoding

        integer n = UInt(Rn);
        integer t = UInt(Rt);
        integer t2 = UInt(Rt2); // ignored by load/store single register
        integer s = UInt(Rs);     // ignored by all loads and store-release

        if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
        if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

        AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
        boolean excl = (o2 == ''0'');
        boolean pair = (o1 == ''1'');
        MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
        integer elsize = 8 << UInt(size);
        integer regsize = if elsize == 64 then 64 else 32;
        integer datasize = if pair then elsize * 2 else elsize;


      Assembler symbols

      <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

      <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


      Operation

        bits(64) address;
        bits(datasize) data;
        constant integer dbytes = datasize DIV 8;
        boolean rt_unknown = FALSE;
        boolean rn_unknown = FALSE;

        if memop == MemOp_LOAD && pair && t == t2 then
             Constraint c = ConstrainUnpredictable();
             assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
             case c of
                  when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
        when Constraint_UNDEF      UnallocatedEncoding();
        when Constraint_NOP        EndOfInstruction();

if memop == MemOp_STORE && excl then
   if s == t || (pair && s == t2) then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
           when Constraint_NONE       rt_unknown = FALSE;       // store original value
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();
   if s == n && n != 31 then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
           when Constraint_NONE       rn_unknown = FALSE;       // address is original base
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();

if n == 31 then
    CheckSPAlignment();
   address = SP[];
elsif rn_unknown then
   address = bits(64) UNKNOWN;
else
   address = X[n];

case memop of
   when MemOp_STORE
       if rt_unknown then
           data = bits(datasize) UNKNOWN;
       elsif pair then
           assert excl;
           bits(datasize DIV 2) el1 = X[t];
           bits(datasize DIV 2) el2 = X[t2];
           data = if BigEndian() then el1 : el2 else el2 : el1;
       else
           data = X[t];

        if excl then
           // store {release} exclusive register|pair (atomic)
           bit status = ''1'';
           // Check whether the Exclusive Monitors are set to include the
           // physical memory locations corresponding to virtual address
           // range [address, address+dbytes-1].
           if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                // This atomic write will be rejected if it does not refer
                // to the same physical locations after address translation.
                Mem[address, dbytes, acctype] = data;
                status = ExclusiveMonitorsStatus();
            X[s] = ZeroExtend(status, 32);
        else
           // store release register (atomic)
            Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
        if excl then
           // Tell the Exclusive Monitors to record a sequence of one or more atomic
           // memory reads from virtual address range [address, address+dbytes-1].
           // The Exclusive Monitor will only be set if all the reads are from the
           // same dbytes-aligned physical address, to allow for the possibility of
           // an atomicity break if the translation is changed between reads.
            AArch64.SetExclusiveMonitors(address, dbytes);

        if pair then
           // load exclusive pair
                     assert excl;
                     if rt_unknown then
                         // ConstrainedUNPREDICTABLE case
                         X[t]   = bits(datasize) UNKNOWN;
                     elsif elsize == 32 then
                         // 32-bit load exclusive pair (atomic)
                         data = Mem[address, dbytes, acctype];
                         if BigEndian() then
                              X[t]  = data<datasize-1:elsize>;
                              X[t2] = data<elsize-1:0>;
                         else
                              X[t]  = data<elsize-1:0>;
                              X[t2] = data<datasize-1:elsize>;
                     else // elsize == 64
                         // 64-bit load exclusive pair (not atomic),
                         // but must be 128-bit aligned
                         if address != Align(address, dbytes) then
                             iswrite = FALSE;
                             secondstage = FALSE;
                             AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                         X[t]   = Mem[address + 0, 8, acctype];
                         X[t2] = Mem[address + 8, 8, acctype];
                  else
                     // load {acquire} {exclusive} single register
                     data = Mem[address, dbytes, acctype];
                      X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STLRB','Store-Release Register Byte stores a byte from a 32-bit register to a memory location. The instruction also has       (C6.6.170)
memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For information about
memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14             10 9           5 4             0
  0 0 0 0 1 0 0 0 1 0 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)            Rn              Rt
  size                    o2 L o1          Rs       o0        Rt2


No offset variant

STLRB <Wt>, [<Xn|SP>{,#0}]


Decode for this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);   // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Assembler symbols

<Wt>          Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
     assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
     case c of
         when Constraint_UNKNOWN      rt_unknown = TRUE;       // result is UNKNOWN
         when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP          EndOfInstruction();

 if memop == MemOp_STORE && excl then
     if s == t || (pair && s == t2) then
         Constraint c = ConstrainUnpredictable();
         assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
         case c of
             when Constraint_UNKNOWN       rt_unknown = TRUE;       // store UNKNOWN value
             when Constraint_NONE          rt_unknown = FALSE;      // store original value
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
                      when Constraint_NONE       rn_unknown = FALSE;       // address is original base
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP         EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
                               X[t2] = data<elsize-1:0>;
          else
               X[t]  = data<elsize-1:0>;
               X[t2] = data<datasize-1:elsize>;
      else // elsize == 64
          // 64-bit load exclusive pair (not atomic),
          // but must be 128-bit aligned
          if address != Align(address, dbytes) then
              iswrite = FALSE;
              secondstage = FALSE;
              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
          X[t]   = Mem[address + 0, 8, acctype];
          X[t2] = Mem[address + 8, 8, acctype];
   else
      // load {acquire} {exclusive} single register
      data = Mem[address, dbytes, acctype];
       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STLRH','      Store-Release Register Halfword stores a halfword from a 32-bit register to a memory location. The instruction also       (C6.6.171)
      has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For information about
      memory accesses see Load/Store addressing modes on page C1-122.




          31 30 29 28 27 26 25 24 23 22 21 20            16 15 14            10 9             5 4            0
          0 1 0 0 1 0 0 0 1 0 0 (1) (1) (1) (1) (1) 1 (1) (1) (1) (1) (1)             Rn              Rt
          size                     o2 L o1        Rs        o0       Rt2


      No offset variant

      STLRH <Wt>, [<Xn|SP>{,#0}]


      Decode for this encoding

        integer n = UInt(Rn);
        integer t = UInt(Rt);
        integer t2 = UInt(Rt2); // ignored by load/store single register
        integer s = UInt(Rs);     // ignored by all loads and store-release

        if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
        if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

        AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
        boolean excl = (o2 == ''0'');
        boolean pair = (o1 == ''1'');
        MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
        integer elsize = 8 << UInt(size);
        integer regsize = if elsize == 64 then 64 else 32;
        integer datasize = if pair then elsize * 2 else elsize;


      Assembler symbols

      <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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


      Operation

        bits(64) address;
        bits(datasize) data;
        constant integer dbytes = datasize DIV 8;
        boolean rt_unknown = FALSE;
        boolean rn_unknown = FALSE;

        if memop == MemOp_LOAD && pair && t == t2 then
             Constraint c = ConstrainUnpredictable();
             assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
             case c of
                  when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
                  when Constraint_UNDEF       UnallocatedEncoding();
                  when Constraint_NOP         EndOfInstruction();

        if memop == MemOp_STORE && excl then
             if s == t || (pair && s == t2) then
                  Constraint c = ConstrainUnpredictable();
                  assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                  case c of
                     when Constraint_UNKNOWN      rt_unknown = TRUE;       // store UNKNOWN value
                     when Constraint_NONE         rt_unknown = FALSE;      // store original value
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();
   if s == n && n != 31 then
        Constraint c = ConstrainUnpredictable();
        assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
       case c of
           when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
           when Constraint_NONE       rn_unknown = FALSE;       // address is original base
           when Constraint_UNDEF      UnallocatedEncoding();
           when Constraint_NOP        EndOfInstruction();

if n == 31 then
    CheckSPAlignment();
   address = SP[];
elsif rn_unknown then
   address = bits(64) UNKNOWN;
else
   address = X[n];

case memop of
   when MemOp_STORE
       if rt_unknown then
           data = bits(datasize) UNKNOWN;
       elsif pair then
           assert excl;
           bits(datasize DIV 2) el1 = X[t];
           bits(datasize DIV 2) el2 = X[t2];
           data = if BigEndian() then el1 : el2 else el2 : el1;
       else
           data = X[t];

       if excl then
           // store {release} exclusive register|pair (atomic)
           bit status = ''1'';
           // Check whether the Exclusive Monitors are set to include the
           // physical memory locations corresponding to virtual address
           // range [address, address+dbytes-1].
           if AArch64.ExclusiveMonitorsPass(address, dbytes) then
               // This atomic write will be rejected if it does not refer
               // to the same physical locations after address translation.
               Mem[address, dbytes, acctype] = data;
               status = ExclusiveMonitorsStatus();
           X[s] = ZeroExtend(status, 32);
       else
           // store release register (atomic)
           Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
       if excl then
           // Tell the Exclusive Monitors to record a sequence of one or more atomic
           // memory reads from virtual address range [address, address+dbytes-1].
           // The Exclusive Monitor will only be set if all the reads are from the
           // same dbytes-aligned physical address, to allow for the possibility of
           // an atomicity break if the translation is changed between reads.
           AArch64.SetExclusiveMonitors(address, dbytes);

       if pair then
           // load exclusive pair
           assert excl;
           if rt_unknown then
               // ConstrainedUNPREDICTABLE case
               X[t]   = bits(datasize) UNKNOWN;
           elsif elsize == 32 then
               // 32-bit load exclusive pair (atomic)
               data = Mem[address, dbytes, acctype];
               if BigEndian() then
                   X[t]   = data<datasize-1:elsize>;
                   X[t2] = data<elsize-1:0>;
                         else
                              X[t]  = data<elsize-1:0>;
                              X[t2] = data<datasize-1:elsize>;
                     else // elsize == 64
                         // 64-bit load exclusive pair (not atomic),
                         // but must be 128-bit aligned
                         if address != Align(address, dbytes) then
                             iswrite = FALSE;
                             secondstage = FALSE;
                             AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                         X[t]   = Mem[address + 0, 8, acctype];
                         X[t2] = Mem[address + 8, 8, acctype];
                  else
                     // load {acquire} {exclusive} single register
                     data = Mem[address, dbytes, acctype];
                      X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STLXP','Store-Release Exclusive Pair Of Registers stores two 32-bit words or two 64-bit doublewords to a memory location       (C6.6.172)
if the PE has exclusive access to the memory address, from two registers, and returns a status value of 0 if the store
was successful, or of 1 if no store was performed. See Synchronization and semaphores on page B2-103. A 32-bit
pair requires the address to be doubleword aligned and is single-copy atomic at doubleword granularity. A 64-bit
pair requires the address to be quadword aligned and is single-copy atomic for each doubleword at doubleword
granularity. The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on
page B2-88. For information about memory accesses see Load/Store addressing modes on page C1-122.




   31 30 29 28 27 26 25 24 23 22 21 20               16 15 14         10 9              5 4              0
    1 x 0 0 1 0 0 0 0 0 1                    Rs         1       Rt2              Rn             Rt
    size                    o2 L o1                     o0


32-bit variant

Applies when size = 10.

STLXP <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]


64-bit variant

Applies when size = 11.

STLXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);      // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly STLXP on page J1-5411.


Assembler symbols

<Ws>            Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                is written, encoded in the "Rs" field. The value returned is:

                0            If the operation updates memory.

                1            If the operation fails to update memory.



<Xt1>           Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.
       <Xt2>            Is the 64-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                        field.

       <Wt1>            Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Wt2>            Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                        field.

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

       Aborts and alignment

       If a synchronous Data Abort exception is generated by the execution of this instruction:

       .       Memory is not updated.

       .       <Ws> is not updated.

       Accessing an address that is not aligned to the size of the data being accessed causes an Alignment fault Data Abort
       exception to be generated, subject to the following rules:

       .       If AArch64.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

       .       Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

       If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
       synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


       Operation

         bits(64) address;
         bits(datasize) data;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;
         boolean rn_unknown = FALSE;

         if memop == MemOp_LOAD && pair && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN     rt_unknown = TRUE;        // result is UNKNOWN
                   when Constraint_UNDEF       UnallocatedEncoding();
                   when Constraint_NOP         EndOfInstruction();

         if memop == MemOp_STORE && excl then
              if s == t || (pair && s == t2) then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                       when Constraint_UNKNOWN      rt_unknown = TRUE;       // store UNKNOWN value
                       when Constraint_NONE         rt_unknown = FALSE;      // store original value
                       when Constraint_UNDEF        UnallocatedEncoding();
                       when Constraint_NOP          EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                       when Constraint_UNKNOWN      rn_unknown = TRUE;       // address is UNKNOWN
                       when Constraint_NONE         rn_unknown = FALSE;      // address is original base
                       when Constraint_UNDEF        UnallocatedEncoding();
                       when Constraint_NOP          EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
 else
    address = X[n];

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        elsif pair then
            assert excl;
            bits(datasize DIV 2) el1 = X[t];
            bits(datasize DIV 2) el2 = X[t2];
            data = if BigEndian() then el1 : el2 else el2 : el1;
        else
            data = X[t];

        if excl then
            // store {release} exclusive register|pair (atomic)
            bit status = ''1'';
            // Check whether the Exclusive Monitors are set to include the
            // physical memory locations corresponding to virtual address
            // range [address, address+dbytes-1].
            if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                // This atomic write will be rejected if it does not refer
                // to the same physical locations after address translation.
                Mem[address, dbytes, acctype] = data;
                status = ExclusiveMonitorsStatus();
            X[s] = ZeroExtend(status, 32);
        else
            // store release register (atomic)
            Mem[address, dbytes, acctype] = data;

    when MemOp_LOAD
        if excl then
            // Tell the Exclusive Monitors to record a sequence of one or more atomic
            // memory reads from virtual address range [address, address+dbytes-1].
            // The Exclusive Monitor will only be set if all the reads are from the
            // same dbytes-aligned physical address, to allow for the possibility of
            // an atomicity break if the translation is changed between reads.
            AArch64.SetExclusiveMonitors(address, dbytes);

        if pair then
            // load exclusive pair
            assert excl;
            if rt_unknown then
                // ConstrainedUNPREDICTABLE case
                X[t]  = bits(datasize) UNKNOWN;
            elsif elsize == 32 then
                // 32-bit load exclusive pair (atomic)
                data = Mem[address, dbytes, acctype];
                if BigEndian() then
                    X[t]  = data<datasize-1:elsize>;
                    X[t2] = data<elsize-1:0>;
                else
                    X[t]  = data<elsize-1:0>;
                    X[t2] = data<datasize-1:elsize>;
            else // elsize == 64
                // 64-bit load exclusive pair (not atomic),
                // but must be 128-bit aligned
                if address != Align(address, dbytes) then
                   iswrite = FALSE;
                   secondstage = FALSE;
                   AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                X[t]  = Mem[address + 0, 8, acctype];
                X[t2] = Mem[address + 8, 8, acctype];
        else
            // load {acquire} {exclusive} single register
            data = Mem[address, dbytes, acctype];
            X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STLXR','       Store-Release Exclusive Register stores a 32-bit word or a 64-bit doubleword to memory if the PE has exclusive       (C6.6.173)
       access to the memory address, from two registers, and returns a status value of 0 if the store was successful, or of 1
       if no store was performed. See Synchronization and semaphores on page B2-103. The memory access is atomic.
       The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.
       For information about memory accesses see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20              16 15 14             10 9         5 4               0
           1 x 0 0 1 0 0 0 0 0 0                    Rs         1 (1) (1) (1) (1) (1)  Rn               Rt
           size                    o2 L o1                     o0       Rt2


       32-bit variant

       Applies when size = 10.

       STLXR <Ws>, <Wt>, [<Xn|SP>{,#0}]


       64-bit variant

       Applies when size = 11.

       STLXR <Ws>, <Xt>, [<Xn|SP>{,#0}]


       Decode for all variants of this encoding

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2); // ignored by load/store single register
         integer s = UInt(Rs);     // ignored by all loads and store-release

         if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
         if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

         AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
         boolean excl = (o2 == ''0'');
         boolean pair = (o1 == ''1'');
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         integer elsize = 8 << UInt(size);
         integer regsize = if elsize == 64 then 64 else 32;
         integer datasize = if pair then elsize * 2 else elsize;


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly STLXR on page J1-5409.


       Assembler symbols

       <Ws>            Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                       is written, encoded in the "Rs" field. The value returned is:

                       0            If the operation updates memory.

                       1            If the operation fails to update memory.



       <Xt>            Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

Aborts and alignment

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Ws> is not updated.

Accessing an address that is not aligned to the size of the data being accessed causes an Alignment fault Data Abort
exception to be generated, subject to the following rules:

.      If AArch64.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

.      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
      Constraint c = ConstrainUnpredictable();
      assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
      case c of
          when Constraint_UNKNOWN      rt_unknown = TRUE;         // result is UNKNOWN
          when Constraint_UNDEF        UnallocatedEncoding();
          when Constraint_NOP          EndOfInstruction();

 if memop == MemOp_STORE && excl then
      if s == t || (pair && s == t2) then
          Constraint c = ConstrainUnpredictable();
          assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
          case c of
               when Constraint_UNKNOWN       rt_unknown = TRUE;       // store UNKNOWN value
               when Constraint_NONE          rt_unknown = FALSE;      // store original value
               when Constraint_UNDEF         UnallocatedEncoding();
               when Constraint_NOP           EndOfInstruction();
      if s == n && n != 31 then
          Constraint c = ConstrainUnpredictable();
          assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
          case c of
               when Constraint_UNKNOWN       rn_unknown = TRUE;       // address is UNKNOWN
               when Constraint_NONE          rn_unknown = FALSE;      // address is original base
               when Constraint_UNDEF         UnallocatedEncoding();
               when Constraint_NOP           EndOfInstruction();

 if n == 31 then
      CheckSPAlignment();
      address = SP[];
 elsif rn_unknown then
      address = bits(64) UNKNOWN;
 else
      address = X[n];

 case memop of
      when MemOp_STORE
          if rt_unknown then
               data = bits(datasize) UNKNOWN;
          elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
                               X[t2] = data<elsize-1:0>;
                           else
                               X[t]  = data<elsize-1:0>;
                               X[t2] = data<datasize-1:elsize>;
                      else // elsize == 64
                           // 64-bit load exclusive pair (not atomic),
                           // but must be 128-bit aligned
                           if address != Align(address, dbytes) then
                              iswrite = FALSE;
                              secondstage = FALSE;
                              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                           X[t]  = Mem[address + 0, 8, acctype];
                           X[t2] = Mem[address + 8, 8, acctype];
                   else
                      // load {acquire} {exclusive} single register
                      data = Mem[address, dbytes, acctype];
                       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STLXRB','Store-Release Exclusive Register Byte stores a byte from a 32-bit register to memory if the PE has exclusive access       (C6.6.174)
to the memory address, and returns a status value of 0 if the store was successful, or of 1 if no store was performed.
See Synchronization and semaphores on page B2-103. The memory access is atomic. The instruction also has
memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For information about
memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                16 15 14             10 9          5 4              0
   0 0 0 0 1 0 0 0 0 0 0                     Rs         1 (1) (1) (1) (1) (1)   Rn                Rt
   size                     o2 L o1                     o0       Rt2


No offset variant

STLXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]


Decode for this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);      // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly STLXRB on page J1-5409.


Assembler symbols

<Ws>            Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                is written, encoded in the "Rs" field. The value returned is:

                0            If the operation updates memory.

                1            If the operation fails to update memory.



<Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

Aborts

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Ws> is not updated.
       If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
       synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


       Operation

         bits(64) address;
         bits(datasize) data;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;
         boolean rn_unknown = FALSE;

         if memop == MemOp_LOAD && pair && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && excl then
              if s == t || (pair && s == t2) then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
                      when Constraint_NONE       rt_unknown = FALSE;       // store original value
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP        EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
                      when Constraint_NONE       rn_unknown = FALSE;       // address is original base
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP        EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
              status = ExclusiveMonitorsStatus();
          X[s] = ZeroExtend(status, 32);
      else
          // store release register (atomic)
          Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
      if excl then
          // Tell the Exclusive Monitors to record a sequence of one or more atomic
          // memory reads from virtual address range [address, address+dbytes-1].
          // The Exclusive Monitor will only be set if all the reads are from the
          // same dbytes-aligned physical address, to allow for the possibility of
          // an atomicity break if the translation is changed between reads.
          AArch64.SetExclusiveMonitors(address, dbytes);

      if pair then
          // load exclusive pair
          assert excl;
          if rt_unknown then
              // ConstrainedUNPREDICTABLE case
              X[t]  = bits(datasize) UNKNOWN;
          elsif elsize == 32 then
              // 32-bit load exclusive pair (atomic)
              data = Mem[address, dbytes, acctype];
              if BigEndian() then
                  X[t]  = data<datasize-1:elsize>;
                  X[t2] = data<elsize-1:0>;
              else
                  X[t]  = data<elsize-1:0>;
                  X[t2] = data<datasize-1:elsize>;
          else // elsize == 64
              // 64-bit load exclusive pair (not atomic),
              // but must be 128-bit aligned
              if address != Align(address, dbytes) then
                  iswrite = FALSE;
                  secondstage = FALSE;
                  AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
              X[t]  = Mem[address + 0, 8, acctype];
              X[t2] = Mem[address + 8, 8, acctype];
      else
          // load {acquire} {exclusive} single register
          data = Mem[address, dbytes, acctype];
          X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STLXRH','       Store-Release Exclusive Register Halfword stores a halfword from a 32-bit register to memory if the PE has       (C6.6.175)
       exclusive access to the memory address, and returns a status value of 0 if the store was successful, or of 1 if no store
       was performed. See Synchronization and semaphores on page B2-103. The memory access is atomic. The
       instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88. For
       information about memory accesses see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20               16 15 14             10 9         5 4               0
           0 1 0 0 1 0 0 0 0 0 0                     Rs         1 (1) (1) (1) (1) (1)   Rn              Rt
           size                     o2 L o1                     o0       Rt2


       No offset variant

       STLXRH <Ws>, <Wt>, [<Xn|SP>{,#0}]


       Decode for this encoding

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2); // ignored by load/store single register
         integer s = UInt(Rs);      // ignored by all loads and store-release

         if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
         if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

         AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
         boolean excl = (o2 == ''0'');
         boolean pair = (o1 == ''1'');
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         integer elsize = 8 << UInt(size);
         integer regsize = if elsize == 64 then 64 else 32;
         integer datasize = if pair then elsize * 2 else elsize;


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly STLXRH on page J1-5409.


       Assembler symbols

       <Ws>             Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                        is written, encoded in the "Rs" field. The value returned is:

                        0            If the operation updates memory.

                        1            If the operation fails to update memory.



       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       Aborts and alignment

       If a synchronous Data Abort exception is generated by the execution of this instruction:

       .       Memory is not updated.

       .       <Ws> is not updated.
A non halfword-aligned memory address causes an Alignment fault Data Abort exception to be generated, subject
to the following rules:

.      If AArch64.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

.      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
     assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
     case c of
          when Constraint_UNKNOWN     rt_unknown = TRUE;      // result is UNKNOWN
          when Constraint_UNDEF       UnallocatedEncoding();
          when Constraint_NOP         EndOfInstruction();

 if memop == MemOp_STORE && excl then
     if s == t || (pair && s == t2) then
           Constraint c = ConstrainUnpredictable();
          assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
          case c of
              when Constraint_UNKNOWN     rt_unknown = TRUE;       // store UNKNOWN value
              when Constraint_NONE        rt_unknown = FALSE;      // store original value
              when Constraint_UNDEF       UnallocatedEncoding();
              when Constraint_NOP         EndOfInstruction();
     if s == n && n != 31 then
           Constraint c = ConstrainUnpredictable();
          assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
          case c of
              when Constraint_UNKNOWN     rn_unknown = TRUE;       // address is UNKNOWN
              when Constraint_NONE        rn_unknown = FALSE;      // address is original base
              when Constraint_UNDEF       UnallocatedEncoding();
              when Constraint_NOP         EndOfInstruction();

 if n == 31 then
     CheckSPAlignment();
     address = SP[];
 elsif rn_unknown then
     address = bits(64) UNKNOWN;
 else
     address = X[n];

 case memop of
     when MemOp_STORE
          if rt_unknown then
              data = bits(datasize) UNKNOWN;
          elsif pair then
              assert excl;
              bits(datasize DIV 2) el1 = X[t];
              bits(datasize DIV 2) el2 = X[t2];
              data = if BigEndian() then el1 : el2 else el2 : el1;
          else
              data = X[t];

          if excl then
              // store {release} exclusive register|pair (atomic)
              bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
                               X[t2] = data<elsize-1:0>;
                           else
                               X[t]  = data<elsize-1:0>;
                               X[t2] = data<datasize-1:elsize>;
                      else // elsize == 64
                           // 64-bit load exclusive pair (not atomic),
                           // but must be 128-bit aligned
                           if address != Align(address, dbytes) then
                              iswrite = FALSE;
                              secondstage = FALSE;
                              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                           X[t]  = Mem[address + 0, 8, acctype];
                           X[t2] = Mem[address + 8, 8, acctype];
                   else
                      // load {acquire} {exclusive} single register
                      data = Mem[address, dbytes, acctype];
                       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STNP','Store pair of registers, with non-temporal hint       (C6.6.176)




  31 30 29 28 27 26 25 24 23 22 21                      15 14         10 9              5 4               0
  x 0 1 0 1 0 0 0 0 0                       imm7                Rt2              Rn              Rt
  opc                           L


32-bit variant

Applies when opc = 00.

STNP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]


64-bit variant

Applies when opc = 10.

STNP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]


Decode for all variants of this encoding

 boolean wback    = FALSE;
 boolean postindex = FALSE;


Assembler symbols

<Wt1>           Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

<Wt2>           Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                field.

<Xt1>           Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

<Xt2>           Is the 64-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                field.

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

<imm>           For the 32-bit variant: is the optional signed immediate byte offset, a multiple of 4 in the range -256
                to 252, defaulting to 0 and encoded in the "imm7" field as <imm>/4.

                For the 64-bit variant: is the optional signed immediate byte offset, a multiple of 8 in the range -512
                to 504, defaulting to 0 and encoded in the "imm7" field as <imm>/8.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2);
 AccType acctype = AccType_STREAM;
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 if opc<0> == ''1'' then UnallocatedEncoding();
 integer scale = 2 + UInt(opc<1>);
 integer datasize = 8 << scale;
 bits(64) offset = LSL(SignExtend(imm7, 64), scale);
       Operation

         bits(64) address;
         bits(datasize) data1;
         bits(datasize) data2;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown && t == n then
                      data1 = bits(datasize) UNKNOWN;
                   else
                      data1 = X[t];
                   if rt_unknown && t2 == n then
                      data2 = bits(datasize) UNKNOWN;
                   else
                      data2 = X[t2];
                   Mem[address + 0     , dbytes, acctype] = data1;
                   Mem[address + dbytes, dbytes, acctype] = data2;

              when MemOp_LOAD
                   data1 = Mem[address + 0     , dbytes, acctype];
                   data2 = Mem[address + dbytes, dbytes, acctype];
                   if rt_unknown then
                      data1 = bits(datasize) UNKNOWN;
                      data2 = bits(datasize) UNKNOWN;
                   X[t]  = data1;
                   X[t2] = data2;

         if wback then
              if postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STP','Store Pair of Registers calculates an address from a base register value and an immediate offset, and stores two       (C6.6.177)
32-bit words or two 64-bit doublewords to the calculated address, from two registers. For information about
memory accesses see Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21                   15 14            10 9            5 4              0
  x 0 1 0 1 0 0 0 1 0                     imm7                Rt2             Rn              Rt
  opc                           L


32-bit variant

Applies when opc = 00.

STP <Wt1>, <Wt2>, [<Xn|SP>], #<imm>


64-bit variant

Applies when opc = 10.

STP <Xt1>, <Xt2>, [<Xn|SP>], #<imm>


Decode for all variants of this encoding

 boolean wback   = TRUE;
 boolean postindex = TRUE;


Pre-index


  31 30 29 28 27 26 25 24 23 22 21                   15 14            10 9            5 4              0
  x 0 1 0 1 0 0 1 1 0                     imm7                Rt2             Rn              Rt
  opc                           L


32-bit variant

Applies when opc = 00.

STP <Wt1>, <Wt2>, [<Xn|SP>, #<imm>]!


64-bit variant

Applies when opc = 10.

STP <Xt1>, <Xt2>, [<Xn|SP>, #<imm>]!


Decode for all variants of this encoding

 boolean wback   = TRUE;
 boolean postindex = FALSE;


Signed offset


  31 30 29 28 27 26 25 24 23 22 21                   15 14            10 9            5 4              0
  x 0 1 0 1 0 0 1 0 0                     imm7                Rt2             Rn              Rt
  opc                           L
       32-bit variant

       Applies when opc = 00.

       STP <Wt1>, <Wt2>, [<Xn|SP>{, #<imm>}]


       64-bit variant

       Applies when opc = 10.

       STP <Xt1>, <Xt2>, [<Xn|SP>{, #<imm>}]


       Decode for all variants of this encoding

         boolean wback  = FALSE;
         boolean postindex = FALSE;


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly STP on page J1-5409.


       Assembler symbols

       <Wt1>           Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Wt2>           Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                       field.

       <Xt1>           Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt2>           Is the 64-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                       field.

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

       <imm>           For the 32-bit post-index and 32-bit pre-index variant: is the signed immediate byte offset, a
                       multiple of 4 in the range -256 to 252, encoded in the "imm7" field as <imm>/4.

                       For the 32-bit signed offset variant: is the optional signed immediate byte offset, a multiple of 4 in
                       the range -256 to 252, defaulting to 0 and encoded in the "imm7" field as <imm>/4.

                       For the 64-bit post-index and 64-bit pre-index variant: is the signed immediate byte offset, a
                       multiple of 8 in the range -512 to 504, encoded in the "imm7" field as <imm>/8.

                       For the 64-bit signed offset variant: is the optional signed immediate byte offset, a multiple of 8 in
                       the range -512 to 504, defaulting to 0 and encoded in the "imm7" field as <imm>/8.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2);
         AccType acctype = AccType_NORMAL;
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         if L:opc<0> == ''01'' || opc == ''11'' then UnallocatedEncoding();
         boolean signed = (opc<0> != ''0'');
         integer scale = 2 + UInt(opc<1>);
         integer datasize = 8 << scale;
         bits(64) offset = LSL(SignExtend(imm7, 64), scale);
Operation for all encodings

 bits(64) address;
 bits(datasize) data1;
 bits(datasize) data2;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean wb_unknown = FALSE;

 if memop == MemOp_LOAD && wback && (t == n || t2 == n) && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;          // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;      // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && (t == n || t2 == n) && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;     // value stored is pre-writeback
         when Constraint_UNKNOWN    rt_unknown = TRUE;      // value stored is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_LOAD && t == t2 then
     Constraint c = ConstrainUnpredictable();
    assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
         if rt_unknown && t == n then
            data1 = bits(datasize) UNKNOWN;
         else
            data1 = X[t];
         if rt_unknown && t2 == n then
            data2 = bits(datasize) UNKNOWN;
         else
            data2 = X[t2];
         Mem[address + 0     , dbytes, acctype] = data1;
         Mem[address + dbytes, dbytes, acctype] = data2;

    when MemOp_LOAD
         data1 = Mem[address + 0     , dbytes, acctype];
         data2 = Mem[address + dbytes, dbytes, acctype];
         if rt_unknown then
            data1 = bits(datasize) UNKNOWN;
            data2 = bits(datasize) UNKNOWN;
         if signed then
             X[t]  = SignExtend(data1, 64);
             X[t2] = SignExtend(data2, 64);
         else
             X[t]  = data1;
                       X[t2] = data2;

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STR','Store Register (immediate) calculates an address from a base register value and an immediate offset, and stores a       (C6.6.178)
32-bit word or a 64-bit doubleword to the calculated address, from a register. For information about memory
accesses see Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
  1 x 1 1 1 0 0 0 0 0 0                        imm9              0 1           Rn             Rt
  size                      opc


32-bit variant

Applies when size = 10.

STR <Wt>, [<Xn|SP>], #<simm>


64-bit variant

Applies when size = 11.

STR <Xt>, [<Xn|SP>], #<simm>


Decode for all variants of this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                         12 11 10 9              5 4             0
  1 x 1 1 1 0 0 0 0 0 0                        imm9              1 1           Rn             Rt
  size                      opc


32-bit variant

Applies when size = 10.

STR <Wt>, [<Xn|SP>, #<simm>]!


64-bit variant

Applies when size = 11.

STR <Xt>, [<Xn|SP>, #<simm>]!


Decode for all variants of this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);
       Unsigned offset


           31 30 29 28 27 26 25 24 23 22 21                                   10 9              5 4             0
           1 x 1 1 1 0 0 1 0 0                             imm12                       Rn                Rt
           size                      opc


       32-bit variant

       Applies when size = 10.

       STR <Wt>, [<Xn|SP>{, #<pimm>}]


       64-bit variant

       Applies when size = 11.

       STR <Xt>, [<Xn|SP>{, #<pimm>}]


       Decode for all variants of this encoding

         boolean wback = FALSE;
         boolean postindex = FALSE;
         integer scale = UInt(size);
         bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Xt>             Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           For the 32-bit variant: is the optional positive immediate byte offset, a multiple of 4 in the range 0
                        to 16380, defaulting to 0 and encoded in the "imm12" field as <pimm>/4.

                        For the 64-bit variant: is the optional positive immediate byte offset, a multiple of 8 in the range 0
                        to 32760, defaulting to 0 and encoded in the "imm12" field as <pimm>/8.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;


Operation for all encodings

 bits(64) address;
 bits(datasize) data;
 boolean wb_unknown = FALSE;
 boolean rt_unknown = FALSE;

 if memop == MemOp_LOAD && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
         when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
         when Constraint_UNDEF      UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

 if memop == MemOp_STORE && wback && n == t && n != 31 then
    c = ConstrainUnpredictable();
    assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
    case c of
         when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
         when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
        when Constraint_UNDEF       UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
            X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
         address = bits(64) UNKNOWN;
    elsif postindex then
         address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STRB','Store Register Byte (immediate) calculates an address from a base register value and an immediate offset, and stores       (C6.6.180)
a byte from a 32-bit register to the calculated address. For information about memory accesses see Load/Store
addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                           12 11 10 9            5 4             0
  0 0 1 1 1 0 0 0 0 0 0                           imm9             0 1         Rn            Rt
   size                      opc


Post-index variant

STRB <Wt>, [<Xn|SP>], #<simm>


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                           12 11 10 9            5 4             0
  0 0 1 1 1 0 0 0 0 0 0                           imm9             1 1         Rn            Rt
   size                      opc


Pre-index variant

STRB <Wt>, [<Xn|SP>, #<simm>]!


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Unsigned offset


  31 30 29 28 27 26 25 24 23 22 21                                    10 9            5 4             0
  0 0 1 1 1 0 0 1 0 0                              imm12                       Rn            Rt
   size                      opc


Unsigned offset variant

STRB <Wt>, [<Xn|SP>{, #<pimm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);
       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly STRB (immediate) on page J1-5408.


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           Is the optional positive immediate byte offset, in the range 0 to 4095, defaulting to 0 and encoded
                        in the "imm12" field.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation for all encodings

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;           // writeback is suppressed
                   when Constraint_UNKNOWN      wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
                   when Constraint_NOP          EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE         rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN      rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
             X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
        address = bits(64) UNKNOWN;
    elsif postindex then
        address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STRH','Store Register Halfword (immediate) calculates an address from a base register value and an immediate offset, and       (C6.6.182)
stores a halfword from a 32-bit register to the calculated address. For information about memory accesses see
Load/Store addressing modes on page C1-122.


Post-index


  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9             5 4              0
  0 1 1 1 1 0 0 0 0 0 0                          imm9               0 1        Rn             Rt
   size                     opc


Post-index variant

STRH <Wt>, [<Xn|SP>], #<simm>


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = TRUE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Pre-index


  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9             5 4              0
  0 1 1 1 1 0 0 0 0 0 0                          imm9               1 1        Rn             Rt
   size                     opc


Pre-index variant

STRH <Wt>, [<Xn|SP>, #<simm>]!


Decode for this encoding

 boolean wback = TRUE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Unsigned offset


  31 30 29 28 27 26 25 24 23 22 21                                    10 9            5 4              0
  0 1 1 1 1 0 0 1 0 0                              imm12                       Rn             Rt
   size                     opc


Unsigned offset variant

STRH <Wt>, [<Xn|SP>{, #<pimm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = LSL(ZeroExtend(imm12, 64), scale);
       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly STRH (immediate) on page J1-5408.


       Assembler symbols

       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       <simm>           Is the signed immediate byte offset, in the range -256 to 255, encoded in the "imm9" field.

       <pimm>           Is the optional positive immediate byte offset, a multiple of 2 in the range 0 to 8190, defaulting to 0
                        and encoded in the "imm12" field as <pimm>/2.


       Shared decode for all encodings

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         AccType acctype = AccType_NORMAL;
         MemOp memop;
         boolean signed;
         integer regsize;

         if opc<1> == ''0'' then
              // store or zero-extending load
              memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
              regsize = if size == ''11'' then 64 else 32;
              signed = FALSE;
         else
              if size == ''11'' then
                   UnallocatedEncoding();
              else
                   // sign-extending load
                   memop = MemOp_LOAD;
                   if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation for all encodings

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;           // writeback is suppressed
                   when Constraint_UNKNOWN      wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
                   when Constraint_NOP          EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE         rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN      rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP        EndOfInstruction();

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

 if ! postindex then
    address = address + offset;

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        else
            data = X[t];
         Mem[address, datasize DIV 8, acctype] = data;

    when MemOp_LOAD
        data = Mem[address, datasize DIV 8, acctype];
        if signed then
             X[t] = SignExtend(data, regsize);
        else
             X[t] = ZeroExtend(data, regsize);

    when MemOp_PREFETCH
         Prefetch(address, t<4:0>);

 if wback then
    if wb_unknown then
        address = bits(64) UNKNOWN;
    elsif postindex then
        address = address + offset;
    if n == 31 then
         SP[] = address;
    else
         X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STTR','Store Register (unprivileged) calculates an address from a base register value and an immediate offset, and stores a       (C6.6.184)
32-bit word or a 64-bit doubleword to the calculated address, from a register. For information about memory
accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9              5 4             0
  1 x 1 1 1 0 0 0 0 0 0                         imm9               1 0         Rn               Rt
  size                       opc


32-bit variant

Applies when size = 10.

STTR <Wt>, [<Xn|SP>{, #<simm>}]


64-bit variant

Applies when size = 11.

STTR <Xt>, [<Xn|SP>{, #<simm>}]


Decode for all variants of this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Assembler symbols

<Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

<Xt>            Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

<simm>          Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                in the "imm9" field.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_UNPRIV;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
     // store or zero-extending load
     memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
     regsize = if size == ''11'' then 64 else 32;
     signed = FALSE;
 else
     if size == ''11'' then
         UnallocatedEncoding();
     else
         // sign-extending load
         memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
                   regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
                   when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   else
                      data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STTRB','Store Register Byte (unprivileged) calculates an address from a base register value and an immediate offset, and       (C6.6.185)
stores a byte from a 32-bit register to the calculated address. For information about memory accesses see Load/Store
addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                             12 11 10 9            5 4              0
  0 0 1 1 1 0 0 0 0 0 0                             imm9              1 0        Rn              Rt
   size                       opc


Unscaled offset variant

STTRB <Wt>, [<Xn|SP>{, #<simm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Assembler symbols

<Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

<simm>           Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                 in the "imm9" field.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_UNPRIV;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
     // store or zero-extending load
     memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
     regsize = if size == ''11'' then 64 else 32;
     signed = FALSE;
 else
     if size == ''11'' then
          UnallocatedEncoding();
     else
          // sign-extending load
          memop = MemOp_LOAD;
          if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
          regsize = if opc<0> == ''1'' then 32 else 64;
          signed = TRUE;

 integer datasize = 8 << scale;
       Operation

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
                   when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   else
                      data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STTRH','Store Register Halfword (unprivileged) calculates an address from a base register value and an immediate offset,       (C6.6.186)
and stores a halfword from a 32-bit register to the calculated address. For information about memory accesses see
Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9              5 4             0
  0 1 1 1 1 0 0 0 0 0 0                          imm9              1 0         Rn               Rt
  size                       opc


Unscaled offset variant

STTRH <Wt>, [<Xn|SP>{, #<simm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Assembler symbols

<Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

<simm>          Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                in the "imm9" field.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_UNPRIV;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
     // store or zero-extending load
     memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
     regsize = if size == ''11'' then 64 else 32;
     signed = FALSE;
 else
     if size == ''11'' then
         UnallocatedEncoding();
     else
         // sign-extending load
         memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
         signed = TRUE;

 integer datasize = 8 << scale;
       Operation

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
                   when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   else
                      data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STUR','Store register (unscaled offset)       (C6.6.187)




  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9              5 4             0
  1 x 1 1 1 0 0 0 0 0 0                         imm9               0 0         Rn               Rt
  size                       opc


32-bit variant

Applies when size = 10.

STUR <Wt>, [<Xn|SP>{, #<simm>}]


64-bit variant

Applies when size = 11.

STUR <Xt>, [<Xn|SP>{, #<simm>}]


Decode for all variants of this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Assembler symbols

<Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

<Xt>            Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

<simm>          Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                in the "imm9" field.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_NORMAL;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
     // store or zero-extending load
     memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
     regsize = if size == ''11'' then 64 else 32;
     signed = FALSE;
 else
     if size == ''11'' then
         memop = MemOp_PREFETCH;
         if opc<0> == ''1'' then UnallocatedEncoding();
     else
         // sign-extending load
         memop = MemOp_LOAD;
         if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
         regsize = if opc<0> == ''1'' then 32 else 64;
                   signed = TRUE;

         integer datasize = 8 << scale;


       Operation

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
                   when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   else
                      data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STURB','Store Register Byte (unscaled) calculates an address from a base register value and an immediate offset, and stores       (C6.6.188)
a byte to the calculated address, from a 32-bit register. For information about memory accesses see Load/Store
addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                            12 11 10 9            5 4             0
  0 0 1 1 1 0 0 0 0 0 0                          imm9               0 0         Rn              Rt
   size                      opc


Unscaled offset variant

STURB <Wt>, [<Xn|SP>{, #<simm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Assembler symbols

<Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

<simm>          Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
                in the "imm9" field.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_NORMAL;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
     // store or zero-extending load
     memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
     regsize = if size == ''11'' then 64 else 32;
     signed = FALSE;
 else
     if size == ''11'' then
          memop = MemOp_PREFETCH;
          if opc<0> == ''1'' then UnallocatedEncoding();
     else
          // sign-extending load
          memop = MemOp_LOAD;
          if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
          regsize = if opc<0> == ''1'' then 32 else 64;
          signed = TRUE;

 integer datasize = 8 << scale;
       Operation

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
                   when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   else
                      data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STURH','Store Register Halfword (unscaled) calculates an address from a base register value and an immediate offset, and       (C6.6.189)
stores a halfword to the calculated address, from a 32-bit register. For information about memory accesses see
Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                          12 11 10 9             5 4              0
  0 1 1 1 1 0 0 0 0 0 0                         imm9                0 0        Rn              Rt
   size                      opc


Unscaled offset variant

STURH <Wt>, [<Xn|SP>{, #<simm>}]


Decode for this encoding

 boolean wback = FALSE;
 boolean postindex = FALSE;
 integer scale = UInt(size);
 bits(64) offset = SignExtend(imm9, 64);


Assembler symbols

<Wt>           Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

<simm>         Is the optional signed immediate byte offset, in the range -256 to 255, defaulting to 0 and encoded
               in the "imm9" field.


Shared decode for all encodings

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 AccType acctype = AccType_NORMAL;
 MemOp memop;
 boolean signed;
 integer regsize;

 if opc<1> == ''0'' then
     // store or zero-extending load
     memop = if opc<0> == ''1'' then MemOp_LOAD else MemOp_STORE;
     regsize = if size == ''11'' then 64 else 32;
     signed = FALSE;
 else
     if size == ''11'' then
          memop = MemOp_PREFETCH;
          if opc<0> == ''1'' then UnallocatedEncoding();
     else
          // sign-extending load
          memop = MemOp_LOAD;
          if size == ''10'' && opc<0> == ''1'' then UnallocatedEncoding();
          regsize = if opc<0> == ''1'' then 32 else 64;
          signed = TRUE;

 integer datasize = 8 << scale;
       Operation

         bits(64) address;
         bits(datasize) data;
         boolean wb_unknown = FALSE;
         boolean rt_unknown = FALSE;

         if memop == MemOp_LOAD && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_WBSUPPRESS, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_WBSUPPRESS wback = FALSE;         // writeback is suppressed
                   when Constraint_UNKNOWN    wb_unknown = TRUE;     // writeback is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && wback && n == t && n != 31 then
              c = ConstrainUnpredictable();
              assert c IN {Constraint_NONE, Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_NONE       rt_unknown = FALSE;    // value stored is original value
                   when Constraint_UNKNOWN    rt_unknown = TRUE;     // value stored is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

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

         if ! postindex then
              address = address + offset;

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   else
                      data = X[t];
                   Mem[address, datasize DIV 8, acctype] = data;

              when MemOp_LOAD
                   data = Mem[address, datasize DIV 8, acctype];
                   if signed then
                       X[t] = SignExtend(data, regsize);
                   else
                       X[t] = ZeroExtend(data, regsize);

              when MemOp_PREFETCH
                   Prefetch(address, t<4:0>);

         if wback then
              if wb_unknown then
                   address = bits(64) UNKNOWN;
              elsif postindex then
                   address = address + offset;
              if n == 31 then
                   SP[] = address;
              else
                   X[n] = address;');
INSERT INTO "instructions" VALUES('ARM','STXP','Store Exclusive Pair Of Registers stores two 32-bit words or two 64-bit doublewords from two registers to a       (C6.6.190)
memory location if the PE has exclusive access to the memory address, and returns a status value of 0 if the store
was successful, or of 1 if no store was performed. See Synchronization and semaphores on page B2-103. A 32-bit
pair requires the address to be doubleword aligned and is single-copy atomic at doubleword granularity. A 64-bit
pair requires the address to be quadword aligned and is single-copy atomic for each doubleword at doubleword
granularity. For information about memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                16 15 14         10 9              5 4              0
  1 x 0 0 1 0 0 0 0 0 1                      Rs         0       Rt2              Rn             Rt
  size                      o2 L o1                     o0


32-bit variant

Applies when size = 10.

STXP <Ws>, <Wt1>, <Wt2>, [<Xn|SP>{,#0}]


64-bit variant

Applies when size = 11.

STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);      // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly STXP on page J1-5411.


Assembler symbols

<Ws>            Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                is written, encoded in the "Rs" field. The value returned is:

                0            If the operation updates memory.

                1            If the operation fails to update memory.



<Xt1>           Is the 64-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.
       <Xt2>            Is the 64-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                        field.

       <Wt1>            Is the 32-bit name of the first general-purpose register to be transferred, encoded in the "Rt" field.

       <Wt2>            Is the 32-bit name of the second general-purpose register to be transferred, encoded in the "Rt2"
                        field.

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

       Aborts and alignment

       If a synchronous Data Abort exception is generated by the execution of this instruction:

       .       Memory is not updated.

       .       <Ws> is not updated.

       Accessing an address that is not aligned to the size of the data being accessed causes an Alignment fault Data Abort
       exception to be generated, subject to the following rules:

       .       If AArch64.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

       .       Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

       If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
       synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


       Operation

         bits(64) address;
         bits(datasize) data;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;
         boolean rn_unknown = FALSE;

         if memop == MemOp_LOAD && pair && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN     rt_unknown = TRUE;        // result is UNKNOWN
                   when Constraint_UNDEF       UnallocatedEncoding();
                   when Constraint_NOP         EndOfInstruction();

         if memop == MemOp_STORE && excl then
              if s == t || (pair && s == t2) then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                       when Constraint_UNKNOWN      rt_unknown = TRUE;       // store UNKNOWN value
                       when Constraint_NONE         rt_unknown = FALSE;      // store original value
                       when Constraint_UNDEF        UnallocatedEncoding();
                       when Constraint_NOP          EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                       when Constraint_UNKNOWN      rn_unknown = TRUE;       // address is UNKNOWN
                       when Constraint_NONE         rn_unknown = FALSE;      // address is original base
                       when Constraint_UNDEF        UnallocatedEncoding();
                       when Constraint_NOP          EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
 else
    address = X[n];

 case memop of
    when MemOp_STORE
        if rt_unknown then
            data = bits(datasize) UNKNOWN;
        elsif pair then
            assert excl;
            bits(datasize DIV 2) el1 = X[t];
            bits(datasize DIV 2) el2 = X[t2];
            data = if BigEndian() then el1 : el2 else el2 : el1;
        else
            data = X[t];

        if excl then
            // store {release} exclusive register|pair (atomic)
            bit status = ''1'';
            // Check whether the Exclusive Monitors are set to include the
            // physical memory locations corresponding to virtual address
            // range [address, address+dbytes-1].
            if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                // This atomic write will be rejected if it does not refer
                // to the same physical locations after address translation.
                Mem[address, dbytes, acctype] = data;
                status = ExclusiveMonitorsStatus();
            X[s] = ZeroExtend(status, 32);
        else
            // store release register (atomic)
            Mem[address, dbytes, acctype] = data;

    when MemOp_LOAD
        if excl then
            // Tell the Exclusive Monitors to record a sequence of one or more atomic
            // memory reads from virtual address range [address, address+dbytes-1].
            // The Exclusive Monitor will only be set if all the reads are from the
            // same dbytes-aligned physical address, to allow for the possibility of
            // an atomicity break if the translation is changed between reads.
            AArch64.SetExclusiveMonitors(address, dbytes);

        if pair then
            // load exclusive pair
            assert excl;
            if rt_unknown then
                // ConstrainedUNPREDICTABLE case
                X[t]  = bits(datasize) UNKNOWN;
            elsif elsize == 32 then
                // 32-bit load exclusive pair (atomic)
                data = Mem[address, dbytes, acctype];
                if BigEndian() then
                    X[t]  = data<datasize-1:elsize>;
                    X[t2] = data<elsize-1:0>;
                else
                    X[t]  = data<elsize-1:0>;
                    X[t2] = data<datasize-1:elsize>;
            else // elsize == 64
                // 64-bit load exclusive pair (not atomic),
                // but must be 128-bit aligned
                if address != Align(address, dbytes) then
                   iswrite = FALSE;
                   secondstage = FALSE;
                   AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                X[t]  = Mem[address + 0, 8, acctype];
                X[t2] = Mem[address + 8, 8, acctype];
        else
            // load {acquire} {exclusive} single register
            data = Mem[address, dbytes, acctype];
            X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STXR','       Store Exclusive Register stores a 32-bit word or a 64-bit doubleword from a register to memory if the PE has       (C6.6.191)
       exclusive access to the memory address, and returns a status value of 0 if the store was successful, or of 1 if no store
       was performed. See Synchronization and semaphores on page B2-103. For information about memory accesses see
       Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20              16 15 14             10 9         5 4               0
           1 x 0 0 1 0 0 0 0 0 0                    Rs         0 (1) (1) (1) (1) (1)    Rn             Rt
           size                    o2 L o1                     o0       Rt2


       32-bit variant

       Applies when size = 10.

       STXR <Ws>, <Wt>, [<Xn|SP>{,#0}]


       64-bit variant

       Applies when size = 11.

       STXR <Ws>, <Xt>, [<Xn|SP>{,#0}]


       Decode for all variants of this encoding

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2); // ignored by load/store single register
         integer s = UInt(Rs);     // ignored by all loads and store-release

         if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
         if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

         AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
         boolean excl = (o2 == ''0'');
         boolean pair = (o1 == ''1'');
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         integer elsize = 8 << UInt(size);
         integer regsize = if elsize == 64 then 64 else 32;
         integer datasize = if pair then elsize * 2 else elsize;


       Notes for all encodings

       For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
       Architectural Constraints on UNPREDICTABLE behaviors, and particularly STXR on page J1-5410.


       Assembler symbols

       <Ws>            Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                       is written, encoded in the "Rs" field. The value returned is:

                       0            If the operation updates memory.

                       1            If the operation fails to update memory.



       <Xt>            Is the 64-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

       <Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Ws> is not updated.

Accessing an address that is not aligned to the size of the data being accessed causes an Alignment fault Data Abort
exception to be generated, subject to the following rules:

.      If AArch64.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

.      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
      Constraint c = ConstrainUnpredictable();
      assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
      case c of
          when Constraint_UNKNOWN      rt_unknown = TRUE;         // result is UNKNOWN
          when Constraint_UNDEF        UnallocatedEncoding();
          when Constraint_NOP          EndOfInstruction();

 if memop == MemOp_STORE && excl then
      if s == t || (pair && s == t2) then
          Constraint c = ConstrainUnpredictable();
          assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
          case c of
               when Constraint_UNKNOWN       rt_unknown = TRUE;       // store UNKNOWN value
               when Constraint_NONE          rt_unknown = FALSE;      // store original value
               when Constraint_UNDEF         UnallocatedEncoding();
               when Constraint_NOP           EndOfInstruction();
      if s == n && n != 31 then
          Constraint c = ConstrainUnpredictable();
          assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
          case c of
               when Constraint_UNKNOWN       rn_unknown = TRUE;       // address is UNKNOWN
               when Constraint_NONE          rn_unknown = FALSE;      // address is original base
               when Constraint_UNDEF         UnallocatedEncoding();
               when Constraint_NOP           EndOfInstruction();

 if n == 31 then
      CheckSPAlignment();
      address = SP[];
 elsif rn_unknown then
      address = bits(64) UNKNOWN;
 else
      address = X[n];

 case memop of
      when MemOp_STORE
          if rt_unknown then
               data = bits(datasize) UNKNOWN;
          elsif pair then
               assert excl;
               bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
                               X[t2] = data<elsize-1:0>;
                           else
                               X[t]  = data<elsize-1:0>;
                               X[t2] = data<datasize-1:elsize>;
                      else // elsize == 64
                           // 64-bit load exclusive pair (not atomic),
                           // but must be 128-bit aligned
                           if address != Align(address, dbytes) then
                              iswrite = FALSE;
                              secondstage = FALSE;
                              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                           X[t]  = Mem[address + 0, 8, acctype];
                           X[t2] = Mem[address + 8, 8, acctype];
                   else
                      // load {acquire} {exclusive} single register
                      data = Mem[address, dbytes, acctype];
                       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STXRB','Store Exclusive Register Byte stores a byte from a register to memory if the PE has exclusive access to the memory       (C6.6.192)
address, and returns a status value of 0 if the store was successful, or of 1 if no store was performed. See
Synchronization and semaphores on page B2-103. The memory access is atomic.

For information about memory accesses see Load/Store addressing modes on page C1-122.




  31 30 29 28 27 26 25 24 23 22 21 20                16 15 14             10 9            5 4             0
   0 0 0 0 1 0 0 0 0 0 0                     Rs         0 (1) (1) (1) (1) (1)     Rn              Rt
   size                     o2 L o1                     o0       Rt2


No offset variant

STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]


Decode for this encoding

 integer n = UInt(Rn);
 integer t = UInt(Rt);
 integer t2 = UInt(Rt2); // ignored by load/store single register
 integer s = UInt(Rs);      // ignored by all loads and store-release

 if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
 if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

 AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
 boolean excl = (o2 == ''0'');
 boolean pair = (o1 == ''1'');
 MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
 integer elsize = 8 << UInt(size);
 integer regsize = if elsize == 64 then 64 else 32;
 integer datasize = if pair then elsize * 2 else elsize;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly STXRB on page J1-5410.


Assembler symbols

<Ws>            Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                is written, encoded in the "Rs" field. The value returned is:

                0            If the operation updates memory.

                1            If the operation fails to update memory.



<Wt>            Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

Aborts

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Ws> is not updated.
       If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
       synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


       Operation

         bits(64) address;
         bits(datasize) data;
         constant integer dbytes = datasize DIV 8;
         boolean rt_unknown = FALSE;
         boolean rn_unknown = FALSE;

         if memop == MemOp_LOAD && pair && t == t2 then
              Constraint c = ConstrainUnpredictable();
              assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
              case c of
                   when Constraint_UNKNOWN    rt_unknown = TRUE;      // result is UNKNOWN
                   when Constraint_UNDEF      UnallocatedEncoding();
                   when Constraint_NOP        EndOfInstruction();

         if memop == MemOp_STORE && excl then
              if s == t || (pair && s == t2) then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rt_unknown = TRUE;        // store UNKNOWN value
                      when Constraint_NONE       rt_unknown = FALSE;       // store original value
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP        EndOfInstruction();
              if s == n && n != 31 then
                   Constraint c = ConstrainUnpredictable();
                   assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
                   case c of
                      when Constraint_UNKNOWN    rn_unknown = TRUE;        // address is UNKNOWN
                      when Constraint_NONE       rn_unknown = FALSE;       // address is original base
                      when Constraint_UNDEF      UnallocatedEncoding();
                      when Constraint_NOP        EndOfInstruction();

         if n == 31 then
              CheckSPAlignment();
              address = SP[];
         elsif rn_unknown then
              address = bits(64) UNKNOWN;
         else
              address = X[n];

         case memop of
              when MemOp_STORE
                   if rt_unknown then
                      data = bits(datasize) UNKNOWN;
                   elsif pair then
                      assert excl;
                      bits(datasize DIV 2) el1 = X[t];
                      bits(datasize DIV 2) el2 = X[t2];
                      data = if BigEndian() then el1 : el2 else el2 : el1;
                   else
                      data = X[t];

                   if excl then
                      // store {release} exclusive register|pair (atomic)
                      bit status = ''1'';
                      // Check whether the Exclusive Monitors are set to include the
                      // physical memory locations corresponding to virtual address
                      // range [address, address+dbytes-1].
                      if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                           // This atomic write will be rejected if it does not refer
                           // to the same physical locations after address translation.
                           Mem[address, dbytes, acctype] = data;
              status = ExclusiveMonitorsStatus();
          X[s] = ZeroExtend(status, 32);
      else
          // store release register (atomic)
          Mem[address, dbytes, acctype] = data;

   when MemOp_LOAD
      if excl then
          // Tell the Exclusive Monitors to record a sequence of one or more atomic
          // memory reads from virtual address range [address, address+dbytes-1].
          // The Exclusive Monitor will only be set if all the reads are from the
          // same dbytes-aligned physical address, to allow for the possibility of
          // an atomicity break if the translation is changed between reads.
          AArch64.SetExclusiveMonitors(address, dbytes);

      if pair then
          // load exclusive pair
          assert excl;
          if rt_unknown then
              // ConstrainedUNPREDICTABLE case
              X[t]  = bits(datasize) UNKNOWN;
          elsif elsize == 32 then
              // 32-bit load exclusive pair (atomic)
              data = Mem[address, dbytes, acctype];
              if BigEndian() then
                  X[t]  = data<datasize-1:elsize>;
                  X[t2] = data<elsize-1:0>;
              else
                  X[t]  = data<elsize-1:0>;
                  X[t2] = data<datasize-1:elsize>;
          else // elsize == 64
              // 64-bit load exclusive pair (not atomic),
              // but must be 128-bit aligned
              if address != Align(address, dbytes) then
                  iswrite = FALSE;
                  secondstage = FALSE;
                  AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
              X[t]  = Mem[address + 0, 8, acctype];
              X[t2] = Mem[address + 8, 8, acctype];
      else
          // load {acquire} {exclusive} single register
          data = Mem[address, dbytes, acctype];
          X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','STXRH','       Store Exclusive Register Halfword stores a halfword from a register to memory if the PE has exclusive access to       (C6.6.193)
       the memory address, and returns a status value of 0 if the store was successful, or of 1 if no store was performed.
       See Synchronization and semaphores on page B2-103. The memory access is atomic.

       For information about memory accesses see Load/Store addressing modes on page C1-122.




           31 30 29 28 27 26 25 24 23 22 21 20               16 15 14             10 9         5 4               0
           0 1 0 0 1 0 0 0 0 0 0                     Rs         0 (1) (1) (1) (1) (1)  Rn               Rt
           size                     o2 L o1                     o0       Rt2


       No offset variant

       STXRH <Ws>, <Wt>, [<Xn|SP>{,#0}]


       Decode for this encoding

         integer n = UInt(Rn);
         integer t = UInt(Rt);
         integer t2 = UInt(Rt2); // ignored by load/store single register
         integer s = UInt(Rs);      // ignored by all loads and store-release

         if o2:o1:o0 == ''100'' || o2:o1:o0 == ''11x'' then UnallocatedEncoding();
         if o1 == ''1'' && size<1> == ''0'' then UnallocatedEncoding();

         AccType acctype = if o0 == ''1'' then AccType_ORDERED else AccType_ATOMIC;
         boolean excl = (o2 == ''0'');
         boolean pair = (o1 == ''1'');
         MemOp memop = if L == ''1'' then MemOp_LOAD else MemOp_STORE;
         integer elsize = 8 << UInt(size);
         integer regsize = if elsize == 64 then 64 else 32;
         integer datasize = if pair then elsize * 2 else elsize;


       Assembler symbols

       <Ws>             Is the 32-bit name of the general-purpose register into which the status result of the store exclusive
                        is written, encoded in the "Rs" field. The value returned is:

                        0            If the operation updates memory.

                        1            If the operation fails to update memory.



       <Wt>             Is the 32-bit name of the general-purpose register to be transferred, encoded in the "Rt" field.

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

       Aborts and alignment

       If a synchronous Data Abort exception is generated by the execution of this instruction:

       .       Memory is not updated.

       .       <Ws> is not updated.

       A non halfword-aligned memory address causes an Alignment fault Data Abort exception to be generated, subject
       to the following rules:

       .       If AArch64.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

       .       Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.
If AArch64.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation

 bits(64) address;
 bits(datasize) data;
 constant integer dbytes = datasize DIV 8;
 boolean rt_unknown = FALSE;
 boolean rn_unknown = FALSE;

 if memop == MemOp_LOAD && pair && t == t2 then
     Constraint c = ConstrainUnpredictable();
     assert c IN {Constraint_UNKNOWN, Constraint_UNDEF, Constraint_NOP};
     case c of
         when Constraint_UNKNOWN      rt_unknown = TRUE;     // result is UNKNOWN
         when Constraint_UNDEF        UnallocatedEncoding();
         when Constraint_NOP          EndOfInstruction();

 if memop == MemOp_STORE && excl then
     if s == t || (pair && s == t2) then
         Constraint c = ConstrainUnpredictable();
         assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
         case c of
             when Constraint_UNKNOWN      rt_unknown = TRUE;      // store UNKNOWN value
             when Constraint_NONE         rt_unknown = FALSE;     // store original value
             when Constraint_UNDEF        UnallocatedEncoding();
             when Constraint_NOP          EndOfInstruction();
     if s == n && n != 31 then
         Constraint c = ConstrainUnpredictable();
         assert c IN {Constraint_UNKNOWN, Constraint_NONE, Constraint_UNDEF, Constraint_NOP};
         case c of
             when Constraint_UNKNOWN      rn_unknown = TRUE;      // address is UNKNOWN
             when Constraint_NONE         rn_unknown = FALSE;     // address is original base
             when Constraint_UNDEF        UnallocatedEncoding();
             when Constraint_NOP          EndOfInstruction();

 if n == 31 then
     CheckSPAlignment();
     address = SP[];
 elsif rn_unknown then
     address = bits(64) UNKNOWN;
 else
     address = X[n];

 case memop of
     when MemOp_STORE
         if rt_unknown then
             data = bits(datasize) UNKNOWN;
         elsif pair then
             assert excl;
             bits(datasize DIV 2) el1 = X[t];
             bits(datasize DIV 2) el2 = X[t2];
             data = if BigEndian() then el1 : el2 else el2 : el1;
         else
             data = X[t];

         if excl then
             // store {release} exclusive register|pair (atomic)
             bit status = ''1'';
             // Check whether the Exclusive Monitors are set to include the
             // physical memory locations corresponding to virtual address
             // range [address, address+dbytes-1].
             if AArch64.ExclusiveMonitorsPass(address, dbytes) then
                 // This atomic write will be rejected if it does not refer
                 // to the same physical locations after address translation.
                 Mem[address, dbytes, acctype] = data;
                           status = ExclusiveMonitorsStatus();
                       X[s] = ZeroExtend(status, 32);
                   else
                      // store release register (atomic)
                       Mem[address, dbytes, acctype] = data;

              when MemOp_LOAD
                   if excl then
                      // Tell the Exclusive Monitors to record a sequence of one or more atomic
                      // memory reads from virtual address range [address, address+dbytes-1].
                      // The Exclusive Monitor will only be set if all the reads are from the
                      // same dbytes-aligned physical address, to allow for the possibility of
                      // an atomicity break if the translation is changed between reads.
                       AArch64.SetExclusiveMonitors(address, dbytes);

                   if pair then
                      // load exclusive pair
                      assert excl;
                      if rt_unknown then
                           // ConstrainedUNPREDICTABLE case
                           X[t]  = bits(datasize) UNKNOWN;
                      elsif elsize == 32 then
                           // 32-bit load exclusive pair (atomic)
                           data = Mem[address, dbytes, acctype];
                           if BigEndian() then
                               X[t]  = data<datasize-1:elsize>;
                               X[t2] = data<elsize-1:0>;
                           else
                               X[t]  = data<elsize-1:0>;
                               X[t2] = data<datasize-1:elsize>;
                      else // elsize == 64
                           // 64-bit load exclusive pair (not atomic),
                           // but must be 128-bit aligned
                           if address != Align(address, dbytes) then
                              iswrite = FALSE;
                              secondstage = FALSE;
                              AArch64.Abort(address, AArch64.AlignmentFault(acctype, iswrite, secondstage));
                           X[t]  = Mem[address + 0, 8, acctype];
                           X[t2] = Mem[address + 8, 8, acctype];
                   else
                      // load {acquire} {exclusive} single register
                      data = Mem[address, dbytes, acctype];
                       X[t] = ZeroExtend(data, regsize);');
INSERT INTO "instructions" VALUES('ARM','SUB','Subtract (extended register): Rd = Rn - LSL(extend(Rm), amount)       (C6.6.194)




  31 30 29 28 27 26 25 24 23 22 21 20             16 15     13 12      10 9            5 4             0
  sf 1 0 0 1 0 1 1 0 0 1                   Rm          option    imm3           Rn              Rd
     op S


32-bit variant

Applies when sf = 0.

SUB <Wd|WSP>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}


64-bit variant

Applies when sf = 1.

SUB <Xd|SP>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean sub_op = (op == ''1'');
 boolean setflags = (S == ''1'');
 ExtendType extend_type = DecodeRegExtend(option);
 integer shift = UInt(imm3);
 if shift > 4 then ReservedValue();


Assembler symbols

<Wd|WSP>       Is the 32-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
               field.

<Wn|WSP>       Is the 32-bit name of the first source general-purpose register or stack pointer, encoded in the "Rn"
               field.

<Wm>           Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd|SP>        Is the 64-bit name of the destination general-purpose register or stack pointer, encoded in the "Rd"
               field.

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

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

               W           when option = 00x

               W           when option = 010

               X           when option = x11

               W           when option = 10x

               W           when option = 110

<m>            Is the number [0-30] of the second general-purpose source register or the name ZR (31), encoded in
               the "Rm" field.
       <extend>        For the 32-bit variant: is the extension to be applied to the second source operand, encoded in the
                       "option" field. It can have the following values:

                       UXTB         when option = 000

                       UXTH         when option = 001

                       LSL|UXTW     when option = 010

                       UXTX         when option = 011

                       SXTB         when option = 100

                       SXTH         when option = 101

                       SXTW         when option = 110

                       SXTX         when option = 111

                       If "Rd" or "Rn" is ''11111'' (WSP) and "option" is ''010'' then LSL is preferred, but may be omitted
                       when "imm3" is ''000''. In all other cases <extend> is required and must be UXTW when "option" is
                       ''010''.

                       For the 64-bit variant: is the extension to be applied to the second source operand, encoded in the
                       "option" field. It can have the following values:

                       UXTB         when option = 000

                       UXTH         when option = 001

                       UXTW         when option = 010

                       LSL|UXTX     when option = 011

                       SXTB         when option = 100

                       SXTH         when option = 101

                       SXTW         when option = 110

                       SXTX         when option = 111

                       If "Rd" or "Rn" is ''11111'' (SP) and "option" is ''011'' then LSL is preferred, but may be omitted when
                       "imm3" is ''000''. In all other cases <extend> is required and must be UXTX when "option" is ''011''.

       <amount>        Is the left shift amount to be applied after extension in the range 0 to 4, defaulting to 0, encoded in
                       the "imm3" field. It must be absent when <extend> is absent, is required when <extend> is LSL,
                       and is optional when <extend> is present but not LSL.


       Operation

         bits(datasize) result;
         bits(datasize) operand1 = if n == 31 then SP[] else X[n];
         bits(datasize) operand2 = ExtendReg(m, extend_type, shift);
         bits(4) nzcv;
         bit carry_in;

         if sub_op then
              operand2 = NOT(operand2);
              carry_in = ''1'';
         else
              carry_in = ''0'';

         (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);

         if setflags then
              PSTATE.<N,Z,C,V> = nzcv;

         if d == 31 && !setflags then
              SP[] = result;
         else
              X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','SUBS','Subtract (extended register), setting the condition flags: Rd = Rn - LSL(extend(Rm), amount)       (C6.6.197)

This instruction is used by the alias CMP (extended register). See the Alias conditions table for details of when each
alias is preferred.




  31 30 29 28 27 26 25 24 23 22 21 20               16 15     13 12      10 9            5 4             0
   sf 1 1 0 1 0 1 1 0 0 1                    Rm          option    imm3           Rn              Rd
      op S


32-bit variant

Applies when sf = 0.

SUBS <Wd>, <Wn|WSP>, <Wm>{, <extend> {#<amount>}}


64-bit variant

Applies when sf = 1.

SUBS <Xd>, <Xn|SP>, <R><m>{, <extend> {#<amount>}}


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer datasize = if sf == ''1'' then 64 else 32;
 boolean sub_op = (op == ''1'');
 boolean setflags = (S == ''1'');
 ExtendType extend_type = DecodeRegExtend(option);
 integer shift = UInt(imm3);
 if shift > 4 then ReservedValue();


Alias conditions


                      Alias                     is preferred when

                      CMP (extended             Rd == ''11111''
                      register)


Assembler symbols

<Wd>             Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn|WSP>         Is the 32-bit name of the first source general-purpose register or stack pointer, encoded in the "Rn"
                 field.

<Wm>             Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>             Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

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

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

                 W           when option = 00x
                       W            when option = 010

                       X            when option = x11

                       W            when option = 10x

                       W            when option = 110

       <m>             Is the number [0-30] of the second general-purpose source register or the name ZR (31), encoded in
                       the "Rm" field.

       <extend>        For the 32-bit variant: is the extension to be applied to the second source operand, encoded in the
                       "option" field. It can have the following values:

                       UXTB         when option = 000

                       UXTH         when option = 001

                       LSL|UXTW     when option = 010

                       UXTX         when option = 011

                       SXTB         when option = 100

                       SXTH         when option = 101

                       SXTW         when option = 110

                       SXTX         when option = 111

                       If "Rn" is ''11111'' (WSP) and "option" is ''010'' then LSL is preferred, but may be omitted when
                       "imm3" is ''000''. In all other cases <extend> is required and must be UXTW when "option" is ''010''.

                       For the 64-bit variant: is the extension to be applied to the second source operand, encoded in the
                       "option" field. It can have the following values:

                       UXTB         when option = 000

                       UXTH         when option = 001

                       UXTW         when option = 010

                       LSL|UXTX     when option = 011

                       SXTB         when option = 100

                       SXTH         when option = 101

                       SXTW         when option = 110

                       SXTX         when option = 111

                       If "Rn" is ''11111'' (SP) and "option" is ''011'' then LSL is preferred, but may be omitted when "imm3"
                       is ''000''. In all other cases <extend> is required and must be UXTX when "option" is ''011''.

       <amount>        Is the left shift amount to be applied after extension in the range 0 to 4, defaulting to 0, encoded in
                       the "imm3" field. It must be absent when <extend> is absent, is required when <extend> is LSL,
                       and is optional when <extend> is present but not LSL.


       Operation

         bits(datasize) result;
         bits(datasize) operand1 = if n == 31 then SP[] else X[n];
         bits(datasize) operand2 = ExtendReg(m, extend_type, shift);
         bits(4) nzcv;
         bit carry_in;

         if sub_op then
              operand2 = NOT(operand2);
              carry_in = ''1'';
         else
              carry_in = ''0'';

         (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);

         if setflags then
    PSTATE.<N,Z,C,V> = nzcv;

 if d == 31 && !setflags then
     SP[] = result;
 else
     X[d] = result;');
INSERT INTO "instructions" VALUES('ARM','SVC','Generate exception targeting exception level 1       (C6.6.200)




    31 30 29 28 27 26 25 24 23 22 21 20                                              5 4 3 2 1 0
    1 1 0 1 0 1 0 0 0 0 0                                 imm16                         0 0 0 0 1




System variant

SVC #<imm>


Decode for this encoding

  bits(16) imm = imm16;


Assembler symbols

<imm>           Is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the "imm16" field.


Operation

  AArch64.CallSupervisor(imm);');
INSERT INTO "instructions" VALUES('ARM','SXTB','Signed extend byte: Rd = SignExtend(Wn<7:0>)       (C6.6.201)

This instruction is an alias of the SBFM instruction. This means that:

.      The encodings in this description are named to match the encodings of SBFM.

.      The description of SBFM gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                16 15              10 9             5 4              0
   sf 0 0 1 0 0 1 1 0 N 0 0 0 0 0 0 0 0 0 1 1 1                                Rn              Rd
      opc                                immr              imms


32-bit variant

Applies when sf = 0 && N = 0.

SXTB <Wd>, <Wn>

is equivalent to

SBFM <Wd>, <Wn>, #0, #7

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1 && N = 1.

SXTB <Xd>, <Wn>

is equivalent to

SBFM <Xd>, <Xn>, #0, #7

and is always the preferred disassembly.


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.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

The description of SBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SXTH','Signed extend halfword: Rd = SignExtend(Wn<15:0>)       (C6.6.202)

This instruction is an alias of the SBFM instruction. This means that:

.       The encodings in this description are named to match the encodings of SBFM.

.       The description of SBFM gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21              16 15              10 9            5 4              0
    sf 0 0 1 0 0 1 1 0 N 0 0 0 0 0 0 0 0 1 1 1 1                               Rn              Rd
        opc                              immr              imms


32-bit variant

Applies when sf = 0 && N = 0.

SXTH <Wd>, <Wn>

is equivalent to

SBFM <Wd>, <Wn>, #0, #15

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1 && N = 1.

SXTH <Xd>, <Wn>

is equivalent to

SBFM <Xd>, <Xn>, #0, #15

and is always the preferred disassembly.


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.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

The description of SBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SXTW','Signed extend word: Xd = SignExtend(Wn<31:0>)       (C6.6.203)

This instruction is an alias of the SBFM instruction. This means that:

.      The encodings in this description are named to match the encodings of SBFM.

.      The description of SBFM gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                16 15              10 9             5 4              0
   1 0 0 1 0 0 1 1 0 1 0 0 0 0 0 0 0 1 1 1 1 1                                 Rn              Rd
   sf opc                        N       immr              imms


64-bit variant

SXTW <Xd>, <Wn>

is equivalent to

SBFM <Xd>, <Xn>, #0, #31

and is always the preferred disassembly.


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

The description of SBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','SYS','       System instruction       (C6.6.204)

       This instruction is used by the aliases AT, DC, IC, and TLBI. See the Alias conditions table for details of when each
       alias is preferred.




           31 30 29 28 27 26 25 24 23 22 21 20 19 18       16 15         12 11        8 7      5 4             0
           1 1 0 1 0 1 0 1 0 0 0 0 1                    op1        CRn         CRm        op2           Rt
                                           L


       System variant

       SYS #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>}


       Decode for this encoding

         CheckSystemAccess(''01'', op1, CRn, CRm, op2, Rt, L);

         integer t = UInt(Rt);

         integer sys_op0 = 1;
         integer sys_op1 = UInt(op1);
         integer sys_op2 = UInt(op2);
         integer sys_crn = UInt(CRn);
         integer sys_crm = UInt(CRm);
         boolean has_result = (L == ''1'');


       Alias conditions


                             Alias                     is preferred when

                             AT                        CRn == ''0111'' && CRm == ''1000'' &&
                                                       SysOp(op1,''0111'',''1000'',op2) == Sys_AT

                             DC                        CRn == ''0111'' && SysOp(op1,''0111'',CRm,op2) == Sys_DC

                             IC                        CRn == ''0111'' && SysOp(op1,''0111'',CRm,op2) == Sys_IC

                             TLBI                      CRn == ''1000'' && SysOp(op1,''1000'',CRm,op2) == Sys_TLBI



       Assembler symbols

       <op1>            Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op1" field.

       <Cn>             Is a name ''Cn'', with ''n'' in the range 0 to 15, encoded in the "CRn" field.

       <Cm>             Is a name ''Cm'', with ''m'' in the range 0 to 15, encoded in the "CRm" field.

       <op2>            Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op2" field.

       <Xt>             Is the 64-bit name of the optional general-purpose source register, defaulting to ''11111'', encoded in
                        the "Rt" field.
Operation

 if has_result then
     X[t] = SysOp_R(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2);
 else
     SysOp_W(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2, X[t]);');
INSERT INTO "instructions" VALUES('ARM','SYSL','System instruction with result       (C6.6.205)




    31 30 29 28 27 26 25 24 23 22 21 20 19 18      16 15         12 11        8 7      5 4            0
    1 1 0 1 0 1 0 1 0 0 1 0 1                   op1        CRn         CRm        op2          Rt
                                   L


System variant

SYSL <Xt>, #<op1>, <Cn>, <Cm>, #<op2>


Decode for this encoding

  CheckSystemAccess(''01'', op1, CRn, CRm, op2, Rt, L);

  integer t = UInt(Rt);

  integer sys_op0 = 1;
  integer sys_op1 = UInt(op1);
  integer sys_op2 = UInt(op2);
  integer sys_crn = UInt(CRn);
  integer sys_crm = UInt(CRm);
  boolean has_result = (L == ''1'');


Assembler symbols

<Xt>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rt" field.

<op1>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op1" field.

<Cn>            Is a name ''Cn'', with ''n'' in the range 0 to 15, encoded in the "CRn" field.

<Cm>            Is a name ''Cm'', with ''m'' in the range 0 to 15, encoded in the "CRm" field.

<op2>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op2" field.


Operation

  if has_result then
       X[t] = SysOp_R(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2);
  else
       SysOp_W(sys_op0, sys_op1, sys_crn, sys_crm, sys_op2, X[t]);');
INSERT INTO "instructions" VALUES('ARM','TBNZ','Test bit and Branch if Nonzero compares the value of a bit in a general-purpose register with zero, and conditionally       (C6.6.206)
branches to a label at a PC-relative offset if the comparison is not equal. It provides a hint that this is not a subroutine
call or return. This instruction does not affect condition flags.




  31 30 29 28 27 26 25 24 23              19 18                                            5 4                0
  b5 0 1 1 0 1 1 1                 b40                           imm14                                Rt
                          op


14-bit signed PC-relative branch offset variant

TBNZ <R><t>, #<imm>, <label>


Decode for this encoding

 integer t = UInt(Rt);

 integer datasize = if b5 == ''1'' then 64 else 32;
 integer bit_pos = UInt(b5:b40);
 bit bit_val = op;
 bits(64) offset = SignExtend(imm14:''00'', 64);


Assembler symbols

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

                 W            when b5 = 0

                 X            when b5 = 1

                 In assembler source code an ''X'' specifier is always permitted, but a ''W'' specifier is only permitted
                 when the bit number is less than 32.

<t>              Is the number [0-30] of the general-purpose register to be tested or the name ZR (31), encoded in
                 the "Rt" field.

<imm>            Is the bit number to be tested, in the range 0 to 63, encoded in "b5:b40".

<label>          Is the program label to be conditionally branched to. Its offset from the address of this instruction,
                 in the range +/-32KB, is encoded as "imm14" times 4.


Operation

 bits(datasize) operand = X[t];

 if operand<bit_pos> == bit_val then
     BranchTo(PC[] + offset, BranchType_JMP);');
INSERT INTO "instructions" VALUES('ARM','TBZ','Test bit and Branch if Zero compares the value of a test bit with zero, and conditionally branches to a label at a       (C6.6.207)
PC-relative offset if the comparison is equal. It provides a hint that this is not a subroutine call or return. This
instruction does not affect condition flags.




    31 30 29 28 27 26 25 24 23           19 18                                           5 4               0
    b5 0 1 1 0 1 1 0              b40                           imm14                              Rt
                          op


14-bit signed PC-relative branch offset variant

TBZ <R><t>, #<imm>, <label>


Decode for this encoding

  integer t = UInt(Rt);

  integer datasize = if b5 == ''1'' then 64 else 32;
  integer bit_pos = UInt(b5:b40);
  bit bit_val = op;
  bits(64) offset = SignExtend(imm14:''00'', 64);


Assembler symbols

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

                W           when b5 = 0

                X           when b5 = 1

                In assembler source code an ''X'' specifier is always permitted, but a ''W'' specifier is only permitted
                when the bit number is less than 32.

<t>             Is the number [0-30] of the general-purpose register to be tested or the name ZR (31), encoded in
                the "Rt" field.

<imm>           Is the bit number to be tested, in the range 0 to 63, encoded in "b5:b40".

<label>         Is the program label to be conditionally branched to. Its offset from the address of this instruction,
                in the range +/-32KB, is encoded as "imm14" times 4.


Operation

  bits(datasize) operand = X[t];

  if operand<bit_pos> == bit_val then
       BranchTo(PC[] + offset, BranchType_JMP);');
INSERT INTO "instructions" VALUES('ARM','TLBI','TLB invalidate operation       (C6.6.208)

This instruction is an alias of the SYS instruction. This means that:

.      The encodings in this description are named to match the encodings of SYS.

.      The description of SYS gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20 19 18        16 15        12 11       8 7      5 4              0
   1 1 0 1 0 1 0 1 0 0 0 0 1                   op1     1 0 0 0        CRm        op2           Rt
                                    L                     CRn


System variant

TLBI <tlbi_op>{, <Xt>}

is equivalent to

SYS #<op1>, C8, <Cm>, #<op2>{, <Xt>}

and is the preferred disassembly when SysOp(op1,''1000'',CRm,op2) == Sys_TLBI.


Assembler symbols

<op1>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op1" field.

<Cm>            Is a name ''Cm'', with ''m'' in the range 0 to 15, encoded in the "CRm" field.

<op2>           Is a 3-bit unsigned immediate, in the range 0 to 7, encoded in the "op2" field.

<tlbi_op>       Is a TLBI operation name, as listed for the TLBI system operation group, encoded in the
                "op1:CRm:op2" field. It can have the following values:

                VMALLE1IS    when op1 = 000, CRm = 0011, op2 = 000

                VAE1IS       when op1 = 000, CRm = 0011, op2 = 001

                ASIDE1IS     when op1 = 000, CRm = 0011, op2 = 010

                VAAE1IS      when op1 = 000, CRm = 0011, op2 = 011

                VALE1IS      when op1 = 000, CRm = 0011, op2 = 101

                VAALE1IS     when op1 = 000, CRm = 0011, op2 = 111

                VMALLE1      when op1 = 000, CRm = 0111, op2 = 000

                VAE1         when op1 = 000, CRm = 0111, op2 = 001

                ASIDE1       when op1 = 000, CRm = 0111, op2 = 010

                VAAE1        when op1 = 000, CRm = 0111, op2 = 011

                VALE1        when op1 = 000, CRm = 0111, op2 = 101

                VAALE1       when op1 = 000, CRm = 0111, op2 = 111

                IPAS2E1IS    when op1 = 100, CRm = 0000, op2 = 001

                IPAS2LE1IS when op1 = 100, CRm = 0000, op2 = 101

                ALLE2IS      when op1 = 100, CRm = 0011, op2 = 000

                VAE2IS       when op1 = 100, CRm = 0011, op2 = 001

                ALLE1IS      when op1 = 100, CRm = 0011, op2 = 100

                VALE2IS      when op1 = 100, CRm = 0011, op2 = 101
                       VMALLS12E1ISwhen op1 = 100, CRm = 0011, op2 = 110

                       IPAS2E1     when op1 = 100, CRm = 0100, op2 = 001

                       IPAS2LE1    when op1 = 100, CRm = 0100, op2 = 101

                       ALLE2       when op1 = 100, CRm = 0111, op2 = 000

                       VAE2        when op1 = 100, CRm = 0111, op2 = 001

                       ALLE1       when op1 = 100, CRm = 0111, op2 = 100

                       VALE2       when op1 = 100, CRm = 0111, op2 = 101

                       VMALLS12E1 when op1 = 100, CRm = 0111, op2 = 110

                       ALLE3IS     when op1 = 110, CRm = 0011, op2 = 000

                       VAE3IS      when op1 = 110, CRm = 0011, op2 = 001

                       VALE3IS     when op1 = 110, CRm = 0011, op2 = 101

                       ALLE3       when op1 = 110, CRm = 0111, op2 = 000

                       VAE3        when op1 = 110, CRm = 0111, op2 = 001

                       VALE3       when op1 = 110, CRm = 0111, op2 = 101

       <Xt>            Is the 64-bit name of the optional general-purpose source register, defaulting to ''11111'', encoded in
                       the "Rt" field.


       Operation

       The description of SYS gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','TST','Test bits (immediate), setting the condition flags and discarding the result: Rn AND imm       (C6.6.209)

This instruction is an alias of the ANDS (immediate) instruction. This means that:

.      The encodings in this description are named to match the encodings of ANDS (immediate).

.      The description of ANDS (immediate) gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                 16 15              10 9             5 4             0
   sf 1 1 1 0 0 1 0 0 N                  immr               imms                Rn       1 1 1 1 1
      opc                                                                                     Rd


32-bit variant

Applies when sf = 0 && N = 0.

TST <Wn>, #<imm>

is equivalent to

ANDS WZR, <Wn>, #<imm>

and is always the preferred disassembly.

64-bit variant

Applies when sf = 1.

TST <Xn>, #<imm>

is equivalent to

ANDS XZR, <Xn>, #<imm>

and is always the preferred disassembly.


Assembler symbols

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<imm>           Is the bitmask immediate, encoded in "N:imms:immr".


Operation

The description of ANDS (immediate) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','UBFIZ','Unsigned bitfield insert in zero, with zeros to left and right       (C6.6.211)

This instruction is an alias of the UBFM instruction. This means that:

.       The encodings in this description are named to match the encodings of UBFM.

.       The description of UBFM gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21                16 15                10 9            5 4               0
    sf 1 0 1 0 0 1 1 0 N                  immr                imms                Rn               Rd
        opc


32-bit variant

Applies when sf = 0 && N = 0.

UBFIZ <Wd>, <Wn>, #<lsb>, #<width>

is equivalent to

UBFM <Wd>, <Wn>, #(-<lsb> MOD 32), #(<width>-1)

and is the preferred disassembly when UInt(imms) < UInt(immr).

64-bit variant

Applies when sf = 1 && N = 1.

UBFIZ <Xd>, <Xn>, #<lsb>, #<width>

is equivalent to

UBFM <Xd>, <Xn>, #(-<lsb> MOD 64), #(<width>-1)

and is the preferred disassembly when UInt(imms) < UInt(immr).


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<lsb>           For the 32-bit variant: is the bit number of the lsb of the destination bitfield, in the range 0 to 31.

                For the 64-bit variant: is the bit number of the lsb of the destination bitfield, in the range 0 to 63.

<width>         For the 32-bit variant: is the width of the bitfield, in the range 1 to 32-<lsb>.

                For the 64-bit variant: is the width of the bitfield, in the range 1 to 64-<lsb>.


Operation

The description of UBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','UBFM','Unsigned bitfield move, with zeros to left and right       (C6.6.212)

This instruction is used by the aliases LSL (immediate), LSR (immediate), UBFIZ, UBFX, UXTB, and UXTH. See
the Alias conditions on page C6-790 table for details of when each alias is preferred.




  31 30 29 28 27 26 25 24 23 22 21                16 15             10 9              5 4             0
  sf 1 0 1 0 0 1 1 0 N                    immr              imms              Rn             Rd
      opc


32-bit variant

Applies when sf = 0 && N = 0.

UBFM <Wd>, <Wn>, #<immr>, #<imms>


64-bit variant

Applies when sf = 1 && N = 1.

UBFM <Xd>, <Xn>, #<immr>, #<imms>


Decode for all variants of this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer datasize = if sf == ''1'' then 64 else 32;

 boolean inzero;
 boolean extend;
 integer R;
 integer S;
 bits(datasize) wmask;
 bits(datasize) tmask;

 case opc of
     when ''00'' inzero = TRUE;      extend = TRUE;      // SBFM
     when ''01'' inzero = FALSE; extend = FALSE;         // BFM
     when ''10'' inzero = TRUE;      extend = FALSE;     // UBFM
     when ''11'' UnallocatedEncoding();

 if sf == ''1'' && N != ''1'' then ReservedValue();
 if sf == ''0'' && (N != ''0'' || immr<5> != ''0'' || imms<5> != ''0'') then ReservedValue();

 R = UInt(immr);
 S = UInt(imms);
 (wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE);
       Alias conditions


          Alias                  of variant            is preferred when

          LSL (immediate)        32-bit                imms != ''011111'' && imms + 1 == immr

          LSL (immediate)        64-bit                imms != ''111111'' && imms + 1 == immr

          LSR (immediate)        32-bit                imms == ''011111''

          LSR (immediate)        64-bit                imms == ''111111''

          UBFIZ                  -                     UInt(imms) < UInt(immr)

          UBFX                   -                     BFXPreferred(sf, opc<1>, imms, immr)

          UXTB                   -                     immr == ''000000'' && imms == ''000111''

          UXTH                   -                     immr == ''000000'' && imms == ''001111''



       Assembler symbols

       <Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

       <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

       <Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

       <immr>          For the 32-bit variant: is the right rotate amount, in the range 0 to 31, encoded in the "immr" field.

                       For the 64-bit variant: is the right rotate amount, in the range 0 to 63, encoded in the "immr" field.

       <imms>          For the 32-bit variant: is the leftmost bit number to be moved from the source, in the range 0 to 31,
                       encoded in the "imms" field.

                       For the 64-bit variant: is the leftmost bit number to be moved from the source, in the range 0 to 63,
                       encoded in the "imms" field.


       Operation

         bits(datasize) dst = if inzero then Zeros() else X[d];
         bits(datasize) src = X[n];

         // perform bitfield move on low bits
         bits(datasize) bot = (dst AND NOT(wmask)) OR (ROR(src, R) AND wmask);

         // determine extension bits (sign, zero or dest register)
         bits(datasize) top = if extend then Replicate(src<S>) else dst;

         // combine extension bits and result bits
         X[d] = (top AND NOT(tmask)) OR (bot AND tmask);');
INSERT INTO "instructions" VALUES('ARM','UBFX','Unsigned bitfield extract       (C6.6.213)

This instruction is an alias of the UBFM instruction. This means that:

.      The encodings in this description are named to match the encodings of UBFM.

.      The description of UBFM gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                  16 15                10 9            5 4              0
   sf 1 0 1 0 0 1 1 0 N                   immr                imms                Rn              Rd
      opc


32-bit variant

Applies when sf = 0 && N = 0.

UBFX <Wd>, <Wn>, #<lsb>, #<width>

is equivalent to

UBFM <Wd>, <Wn>, #<lsb>, #(<lsb>+<width>-1)

and is the preferred disassembly when BFXPreferred(sf, opc<1>, imms, immr).

64-bit variant

Applies when sf = 1 && N = 1.

UBFX <Xd>, <Xn>, #<lsb>, #<width>

is equivalent to

UBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1)

and is the preferred disassembly when BFXPreferred(sf, opc<1>, imms, immr).


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the general-purpose source register, encoded in the "Rn" field.

<lsb>           For the 32-bit variant: is the bit number of the lsb of the source bitfield, in the range 0 to 31.

                For the 64-bit variant: is the bit number of the lsb of the source bitfield, in the range 0 to 63.

<width>         For the 32-bit variant: is the width of the bitfield, in the range 1 to 32-<lsb>.

                For the 64-bit variant: is the width of the bitfield, in the range 1 to 64-<lsb>.


Operation

The description of UBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','UDIV','Unsigned Divide divides an unsigned integer register value by an unsigned integer register value, and writes the       (C6.6.214)
result to the destination register of the same size as source registers, 32-bit or 64-bit. The condition flags are not
affected. That is, it performs n unsigned divide: Rd = Rn / Rm.




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


32-bit variant

Applies when sf = 0.

UDIV <Wd>, <Wn>, <Wm>


64-bit variant

Applies when sf = 1.

UDIV <Xd>, <Xn>, <Xm>


Decode for all variants of this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  integer datasize = if sf == ''1'' then 64 else 32;
  boolean unsigned = (o1 == ''0'');


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register, encoded in the "Rm" field.

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register, encoded in the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register, encoded in the "Rm" field.


Operation

  bits(datasize) operand1 = X[n];
  bits(datasize) operand2 = X[m];
  integer result;

  if IsZero(operand2) then
       result = 0;
  else
       result = RoundTowardsZero (Int(operand1, unsigned) / Int(operand2, unsigned));

  X[d] = result<datasize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','UMADDL','Unsigned multiply-add long: Xd = Xa + Wn * Wm       (C6.6.215)

This instruction is used by the alias UMULL. See the Alias conditions table for details of when each alias is
preferred.




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


64-bit variant

UMADDL <Xd>, <Wn>, <Wm>, <Xa>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer a = UInt(Ra);
 integer destsize = 64;
 integer datasize = 32;
 boolean sub_op = (o0 == ''1'');
 boolean unsigned = (U == ''1'');


Alias conditions


                     Alias                     is preferred when

                     UMULL                     Ra == ''11111''



Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.

<Xa>            Is the 64-bit name of the third general-purpose source register holding the addend, encoded in the
                "Ra" field.


Operation

 bits(datasize) operand1 = X[n];
 bits(datasize) operand2 = X[m];
 bits(destsize) operand3 = X[a];

 integer result;

 if sub_op then
     result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned));
 else
              result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned));

         X[d] = result<63:0>;');
INSERT INTO "instructions" VALUES('ARM','UMNEGL','Unsigned multiply-negate long: Xd = -(Wn * Wm)       (C6.6.216)

This instruction is an alias of the UMSUBL instruction. This means that:

.      The encodings in this description are named to match the encodings of UMSUBL.

.      The description of UMSUBL gives the operational pseudocode for this instruction.




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


64-bit variant

UMNEGL <Xd>, <Wn>, <Wm>

is equivalent to

UMSUBL <Xd>, <Wn>, <Wm>, XZR

and is always the preferred disassembly.


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

The description of UMSUBL gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','UMSUBL','      Unsigned multiply-subtract long: Xd = Xa - Wn * Wm       (C6.6.217)

      This instruction is used by the alias UMNEGL. See the Alias conditions table for details of when each alias is
      preferred.




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


      64-bit variant

      UMSUBL <Xd>, <Wn>, <Wm>, <Xa>


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        integer a = UInt(Ra);
        integer destsize = 64;
        integer datasize = 32;
        boolean sub_op = (o0 == ''1'');
        boolean unsigned = (U == ''1'');


      Alias conditions


                           Alias                     is preferred when

                           UMNEGL                    Ra == ''11111''



      Assembler symbols

      <Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

      <Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                      the "Rn" field.

      <Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                      the "Rm" field.

      <Xa>            Is the 64-bit name of the third general-purpose source register holding the minuend, encoded in the
                      "Ra" field.


      Operation

        bits(datasize) operand1 = X[n];
        bits(datasize) operand2 = X[m];
        bits(destsize) operand3 = X[a];

        integer result;

        if sub_op then
             result = Int(operand3, unsigned) - (Int(operand1, unsigned) * Int(operand2, unsigned));
        else
   result = Int(operand3, unsigned) + (Int(operand1, unsigned) * Int(operand2, unsigned));

X[d] = result<63:0>;');
INSERT INTO "instructions" VALUES('ARM','UMULH','Unsigned multiply high: Xd = bits<127:64> of Xn * Xm       (C6.6.218)




    31 30 29 28 27 26 25 24 23 22 21 20            16 15 14              10 9         5 4              0
    1 0 0 1 1 0 1 1 1 1 0                   Rm         0 (1) (1) (1) (1) (1)    Rn             Rd
                             U                                  Ra


64-bit variant

UMULH <Xd>, <Xn>, <Xm>


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  integer a = UInt(Ra);             // ignored by UMULH/SMULH
  integer destsize = 64;
  integer datasize = destsize;
  boolean unsigned = (U == ''1'');


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Xn>            Is the 64-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Xm>            Is the 64-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

  bits(datasize) operand1 = X[n];
  bits(datasize) operand2 = X[m];

  integer result;

  result = Int(operand1, unsigned) * Int(operand2, unsigned);

  X[d] = result<127:64>;');
INSERT INTO "instructions" VALUES('ARM','UMULL','Unsigned multiply long: Xd = Wn * Wm       (C6.6.219)

This instruction is an alias of the UMADDL instruction. This means that:

.      The encodings in this description are named to match the encodings of UMADDL.

.      The description of UMADDL gives the operational pseudocode for this instruction.




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


64-bit variant

UMULL <Xd>, <Wn>, <Wm>

is equivalent to

UMADDL <Xd>, <Wn>, <Wm>, XZR

and is always the preferred disassembly.


Assembler symbols

<Xd>            Is the 64-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the first general-purpose source register holding the multiplicand, encoded in
                the "Rn" field.

<Wm>            Is the 32-bit name of the second general-purpose source register holding the multiplier, encoded in
                the "Rm" field.


Operation

The description of UMADDL gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','UXTB','Unsigned extend byte: Wd = ZeroExtend(Wn<7:0>)       (C6.6.220)

This instruction is an alias of the UBFM instruction. This means that:

.       The encodings in this description are named to match the encodings of UBFM.

.       The description of UBFM gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21              16 15             10 9             5 4              0
    0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1                                Rn              Rd
    sf opc                       N       immr              imms


32-bit variant

UXTB <Wd>, <Wn>

is equivalent to

UBFM <Wd>, <Wn>, #0, #7

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

The description of UBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','UXTH','Unsigned extend halfword: Wd = ZeroExtend(Wn<15:0>)       (C6.6.221)

This instruction is an alias of the UBFM instruction. This means that:

.      The encodings in this description are named to match the encodings of UBFM.

.      The description of UBFM gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21                16 15             10 9              5 4              0
   0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1                                 Rn              Rd
   sf opc                        N       immr              imms


32-bit variant

UXTH <Wd>, <Wn>

is equivalent to

UBFM <Wd>, <Wn>, #0, #15

and is always the preferred disassembly.


Assembler symbols

<Wd>            Is the 32-bit name of the general-purpose destination register, encoded in the "Rd" field.

<Wn>            Is the 32-bit name of the general-purpose source register, encoded in the "Rn" field.


Operation

The description of UBFM gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','WFE','Wait for event       (C6.6.222)

This instruction is an alias of the HINT instruction. This means that:

.       The encodings in this description are named to match the encodings of HINT.

.       The description of HINT gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11         8 7       5 4 3 2 1 0
    1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 1 1 1 1 1
                                                                      CRm       op2


System variant

WFE

is equivalent to

HINT #2

and is always the preferred disassembly.


Operation

The description of HINT gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','WFI','Wait for interrupt       (C6.6.223)

This instruction is an alias of the HINT instruction. This means that:

.      The encodings in this description are named to match the encodings of HINT.

.      The description of HINT gives the operational pseudocode for this instruction.




  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11          8 7       5 4 3 2 1 0
   1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1
                                                                      CRm      op2


System variant

WFI

is equivalent to

HINT #3

and is always the preferred disassembly.


Operation

The description of HINT gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','YIELD','Yield hint       (C6.6.224)

This instruction is an alias of the HINT instruction. This means that:

.       The encodings in this description are named to match the encodings of HINT.

.       The description of HINT gives the operational pseudocode for this instruction.




    31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11         8 7       5 4 3 2 1 0
    1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 1
                                                                      CRm       op2


System variant

YIELD

is equivalent to

HINT #1

and is always the preferred disassembly.


Operation

The description of HINT gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','ABS','       Absolute value (vector)       (C7.3.1)


       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 1 0 1 1 1 0                                  Rn             Rd
                  U


       Scalar variant

       ABS <V><d>, <V><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 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 1 0 1 1 1 0                                  Rn             Rd
                  U


       Vector variant

       ABS <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:

                         D           when size = 11

                         It is RESERVED when:

                         .      size = 0x.

                         .      size = 10.

       <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;

 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] = element<esize-1:0>;

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ADDHN','       Add returning high narrow       (C7.3.3)




           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 0               Rn               Rd
                  U                                                    o1


       Three registers, not all the same type variant

       ADDHN{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;');
INSERT INTO "instructions" VALUES('ARM','ADDHN2','-R:ADDHN');
INSERT INTO "instructions" VALUES('ARM','ADDP','Add pair of elements (scalar)       (C7.3.4)




    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 1 0 0 0 1 1 0 1 1 1 0                                  Rn               Rd




Advanced SIMD variant

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


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 * 2;
  integer elements = 2;

  ReduceOp op = ReduceOp_ADD;


Assembler symbols

<V>               Is the destination 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, encoded in the "Rd" field.

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

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

                  2D          when size = 11

                  It is RESERVED when:

                  .      size = 0x.

                  .      size = 10.


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand = V[n];
  V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','ADDV','Add across vector       (C7.3.6)




    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 1 1 0                                  Rn               Rd




Advanced SIMD variant

ADDV <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;

  ReduceOp op = ReduceOp_ADD;


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];
  V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','AESD','AES single round decryption       (C7.3.7)




  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 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 0 1 1 0                                Rn             Rd
                                                           D


Advanced SIMD variant

AESD <Vd>.16B, <Vn>.16B


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 if ! HaveCryptoExt() then UnallocatedEncoding();
 boolean decrypt = (D == ''1'');


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;
 result = operand1 EOR operand2;
 if decrypt then
     result = AESInvSubBytes(AESInvShiftRows(result));
 else
     result = AESSubBytes(AESShiftRows(result));

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','AESE','AES single round encryption       (C7.3.8)




    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 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0                              Rn             Rd
                                                               D


Advanced SIMD variant

AESE <Vd>.16B, <Vn>.16B


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  if ! HaveCryptoExt() then UnallocatedEncoding();
  boolean decrypt = (D == ''1'');


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;
  result = operand1 EOR operand2;
  if decrypt then
       result = AESInvSubBytes(AESInvShiftRows(result));
  else
       result = AESSubBytes(AESShiftRows(result));

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','AESIMC','AES inverse mix columns       (C7.3.9)




  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 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 1 1 1 0                                Rn             Rd
                                                           D


Advanced SIMD variant

AESIMC <Vd>.16B, <Vn>.16B


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 if ! HaveCryptoExt() then UnallocatedEncoding();
 boolean decrypt = (D == ''1'');


Assembler symbols

<Vd>          Is the name 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.


Operation

 CheckCryptoEnabled64();

 bits(128) operand = V[n];
 bits(128) result;
 if decrypt then
     result = AESInvMixColumns(operand);
 else
     result = AESMixColumns(operand);
 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','AESMC','AES mix columns       (C7.3.10)




    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 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 1 0 1 0                              Rn             Rd
                                                               D


Advanced SIMD variant

AESMC <Vd>.16B, <Vn>.16B


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  if ! HaveCryptoExt() then UnallocatedEncoding();
  boolean decrypt = (D == ''1'');


Assembler symbols

<Vd>              Is the name 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.


Operation

  CheckCryptoEnabled64();

  bits(128) operand = V[n];
  bits(128) result;
  if decrypt then
       result = AESInvMixColumns(operand);
  else
       result = AESMixColumns(operand);
  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','BIF','Bitwise insert if false       (C7.3.14)




  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 1 1 1                    Rm         0 0 0 1 1 1               Rn             Rd
                             opc2


Three registers of the same type variant

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


Decode for this encoding

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

 VBitOp op;

 case opc2 of
     when ''00'' op = VBitOp_VEOR;
     when ''01'' op = VBitOp_VBSL;
     when ''10'' op = VBitOp_VBIT;
     when ''11'' op = VBitOp_VBIF;


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 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;
 bits(datasize) operand2;
 bits(datasize) operand3;
 bits(datasize) operand4 = V[n];

 case op of
     when VBitOp_VEOR
         operand1 = V[m];
         operand2 = Zeros();
         operand3 = Ones();
     when VBitOp_VBSL
         operand1 = V[m];
         operand2 = operand1;
         operand3 = V[d];
     when VBitOp_VBIT
         operand1 = V[d];
                   operand2 = operand1;
                   operand3 = V[m];
              when VBitOp_VBIF
                   operand1 = V[d];
                   operand2 = operand1;
                   operand3 = NOT(V[m]);

         V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3);');
INSERT INTO "instructions" VALUES('ARM','BIT','Bitwise insert if true       (C7.3.15)




  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 1 0 1                    Rm         0 0 0 1 1 1               Rn             Rd
                             opc2


Three registers of the same type variant

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


Decode for this encoding

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

 VBitOp op;

 case opc2 of
     when ''00'' op = VBitOp_VEOR;
     when ''01'' op = VBitOp_VBSL;
     when ''10'' op = VBitOp_VBIT;
     when ''11'' op = VBitOp_VBIF;


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 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;
 bits(datasize) operand2;
 bits(datasize) operand3;
 bits(datasize) operand4 = V[n];

 case op of
     when VBitOp_VEOR
         operand1 = V[m];
         operand2 = Zeros();
         operand3 = Ones();
     when VBitOp_VBSL
         operand1 = V[m];
         operand2 = operand1;
         operand3 = V[d];
     when VBitOp_VBIT
         operand1 = V[d];
                   operand2 = operand1;
                   operand3 = V[m];
              when VBitOp_VBIF
                   operand1 = V[d];
                   operand2 = operand1;
                   operand3 = NOT(V[m]);

         V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3);');
INSERT INTO "instructions" VALUES('ARM','BSL','Bitwise select       (C7.3.16)




  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 0 1 1                  Rm         0 0 0 1 1 1               Rn             Rd
                          opc2


Three registers of the same type variant

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


Decode for this encoding

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

 VBitOp op;

 case opc2 of
     when ''00'' op = VBitOp_VEOR;
     when ''01'' op = VBitOp_VBSL;
     when ''10'' op = VBitOp_VBIT;
     when ''11'' op = VBitOp_VBIF;


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 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;
 bits(datasize) operand2;
 bits(datasize) operand3;
 bits(datasize) operand4 = V[n];

 case op of
     when VBitOp_VEOR
         operand1 = V[m];
         operand2 = Zeros();
         operand3 = Ones();
     when VBitOp_VBSL
         operand1 = V[m];
         operand2 = operand1;
         operand3 = V[d];
     when VBitOp_VBIT
         operand1 = V[d];
                   operand2 = operand1;
                   operand3 = V[m];
              when VBitOp_VBIF
                   operand1 = V[d];
                   operand2 = operand1;
                   operand3 = NOT(V[m]);

         V[d] = operand1 EOR ((operand2 EOR operand4) AND operand3);');
INSERT INTO "instructions" VALUES('ARM','CMEQ','Compare bitwise equal (vector), setting destination vector element to all ones if the condition holds, else zero       (C7.3.19)


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         1 0 0 0 1 1                Rn             Rd
        U


Scalar variant

CMEQ <V><d>, <V><n>, <V><m>


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 = esize;
 integer elements = 1;
 boolean and_test = (U == ''0'');


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         1 0 0 0 1 1                Rn             Rd
        U


Vector variant

CMEQ <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 and_test = (U == ''0'');


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;
         bits(esize) element1;
         bits(esize) element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              if and_test then
                   test_passed = !IsZero(element1 AND element2);
              else
                   test_passed = (element1 == element2);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CMGE','Compare signed greater than or equal (vector)       (C7.3.21)


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 1 1 1               Rn             Rd
        U                                                          eq


Scalar variant

CMGE <V><d>, <V><n>, <V><m>


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 = esize;
 integer elements = 1;
 boolean unsigned = (U == ''1'');
 boolean cmp_eq = (eq == ''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 1 1 1               Rn             Rd
        U                                                          eq


Vector variant

CMGE <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 cmp_eq = (eq == ''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 element1;
         integer element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              test_passed = if cmp_eq then element1 >= element2 else element1 > element2;
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CMGT','Compare signed greater than (vector), setting destination vector element to all ones if the condition holds, else zero       (C7.3.23)


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 1 0 1               Rn              Rd
        U                                                          eq


Scalar variant

CMGT <V><d>, <V><n>, <V><m>


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 = esize;
 integer elements = 1;
 boolean unsigned = (U == ''1'');
 boolean cmp_eq = (eq == ''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 1 0 1               Rn              Rd
        U                                                          eq


Vector variant

CMGT <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 cmp_eq = (eq == ''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 element1;
         integer element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              test_passed = if cmp_eq then element1 >= element2 else element1 > element2;
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CMHI','Compare unsigned higher (vector), setting destination vector element to all ones if the condition holds, else zero       (C7.3.25)


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 1 1 0 1               Rn             Rd
        U                                                          eq


Scalar variant

CMHI <V><d>, <V><n>, <V><m>


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 = esize;
 integer elements = 1;
 boolean unsigned = (U == ''1'');
 boolean cmp_eq = (eq == ''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 1 1 0 1               Rn             Rd
        U                                                          eq


Vector variant

CMHI <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 cmp_eq = (eq == ''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 element1;
         integer element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              test_passed = if cmp_eq then element1 >= element2 else element1 > element2;
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CMHS','Compare unsigned higher or same (vector), setting destination vector element to all ones if the condition holds, else       (C7.3.26)
zero


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 1 1 1 1               Rn               Rd
        U                                                          eq


Scalar variant

CMHS <V><d>, <V><n>, <V><m>


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 = esize;
 integer elements = 1;
 boolean unsigned = (U == ''1'');
 boolean cmp_eq = (eq == ''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 1 1 1 1               Rn               Rd
        U                                                          eq


Vector variant

CMHS <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 cmp_eq = (eq == ''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 element1;
         integer element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Int(Elem[operand1, e, esize], unsigned);
              element2 = Int(Elem[operand2, e, esize], unsigned);
              test_passed = if cmp_eq then element1 >= element2 else element1 > element2;
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CMLE','Compare signed less than or equal to zero (vector), setting destination vector element to all ones if the condition       (C7.3.27)
holds, else zero


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 1 0 0 1 1 0                                 Rn              Rd
         U                                                    op


Scalar variant

CMLE <V><d>, <V><n>, #0


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 elements = 1;

 CompareOp comparison;
 case op:U of
     when ''00'' comparison = CompareOp_GT;
     when ''01'' comparison = CompareOp_GE;
     when ''10'' comparison = CompareOp_EQ;
     when ''11'' comparison = CompareOp_LE;


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 1 0 0 1 1 0                                 Rn              Rd
         U                                                    op


Vector variant

CMLE <Vd>.<T>, <Vn>.<T>, #0


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;

 CompareOp comparison;
 case op:U of
     when ''00'' comparison = CompareOp_GT;
     when ''01'' comparison = CompareOp_GE;
     when ''10'' comparison = CompareOp_EQ;
     when ''11'' comparison = CompareOp_LE;
       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, 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 test_passed;

         for e = 0 to elements-1
              element = SInt(Elem[operand, e, esize]);
              case comparison of
                   when CompareOp_GT test_passed = element > 0;
                   when CompareOp_GE test_passed = element >= 0;
                   when CompareOp_EQ test_passed = element == 0;
                   when CompareOp_LE test_passed = element <= 0;
                   when CompareOp_LT test_passed = element < 0;
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CMLT','Compare signed less than zero (vector), setting destination vector element to all ones if the condition holds, else zero       (C7.3.28)


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 1 0 1 0 1 0                                  Rn               Rd




Scalar variant

CMLT <V><d>, <V><n>, #0


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 elements = 1;

 CompareOp comparison = CompareOp_LT;


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 1 0 1 0 1 0                                  Rn               Rd




Vector variant

CMLT <Vd>.<T>, <Vn>.<T>, #0


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;

 CompareOp comparison = CompareOp_LT;


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, 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 test_passed;

         for e = 0 to elements-1
              element = SInt(Elem[operand, e, esize]);
              case comparison of
                   when CompareOp_GT test_passed = element > 0;
                   when CompareOp_GE test_passed = element >= 0;
                   when CompareOp_EQ test_passed = element == 0;
                   when CompareOp_LE test_passed = element <= 0;
                   when CompareOp_LT test_passed = element < 0;
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CMTST','Compare bitwise test bits nonzero (vector), setting destination vector element to all ones if the condition holds, else       (C7.3.29)
zero


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         1 0 0 0 1 1               Rn                Rd
        U


Scalar variant

CMTST <V><d>, <V><n>, <V><m>


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 = esize;
 integer elements = 1;
 boolean and_test = (U == ''0'');


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         1 0 0 0 1 1               Rn                Rd
        U


Vector variant

CMTST <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 and_test = (U == ''0'');


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;
         bits(esize) element1;
         bits(esize) element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              if and_test then
                   test_passed = !IsZero(element1 AND element2);
              else
                   test_passed = (element1 == element2);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','CNT','Population count per byte       (C7.3.30)




  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 0 1 1 0                                Rn              Rd




Vector variant

CNT <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if size != ''00'' then ReservedValue();
 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 "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 SIMD&FP source register, encoded in the "Rn" field.


Operation

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

 integer count;
 for e = 0 to elements-1
     count = BitCount(Elem[operand, e, esize]);
     Elem[result, e, esize] = count<esize-1:0>;
 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','DUP','       Duplicate vector element to vector or scalar       (C7.3.31)

       This instruction is used by the alias MOV (scalar). The alias is always the preferred disassembly.


       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 0 0 0                imm5         0 0 0 0 0 1             Rn             Rd




       Scalar variant

       DUP <V><d>, <Vn>.<T>[<index>]


       Decode for this encoding

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

         integer size = LowestSetBit(imm5);
         if size > 3 then UnallocatedEncoding();

         integer index = UInt(imm5<4:size+1>);
         integer idxdsize = if imm5<4> == ''1'' then 128 else 64;

         integer esize = 8 << size;
         integer datasize = esize;
         integer elements = 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 0 0 0                imm5         0 0 0 0 0 1             Rn             Rd




       Vector variant

       DUP <Vd>.<T>, <Vn>.<Ts>[<index>]


       Decode for this encoding

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

         integer size = LowestSetBit(imm5);
         if size > 3 then UnallocatedEncoding();

         integer index = UInt(imm5<4:size+1>);
         integer idxdsize = if imm5<4> == ''1'' then 128 else 64;

         if size == 3 && Q == ''0'' then ReservedValue();
         integer esize = 8 << size;
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;
Assembler symbols

<T>       For the scalar variant: is the element width specifier, encoded in the "imm5" field. It can have the
          following values:

          B           when imm5 = xxxx1

          H           when imm5 = xxx10

          S           when imm5 = xx100

          D           when imm5 = x1000

          It is RESERVED when imm5 = x0000.

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

          8B          when imm5 = xxxx1, Q = 0

          16B         when imm5 = xxxx1, Q = 1

          4H          when imm5 = xxx10, Q = 0

          8H          when imm5 = xxx10, Q = 1

          2S          when imm5 = xx100, Q = 0

          4S          when imm5 = xx100, Q = 1

          2D          when imm5 = x1000, Q = 1

          It is RESERVED when:

          .      imm5 = x0000, Q = x.

          .      imm5 = x1000, Q = 0.

<Ts>      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

          D           when imm5 = x1000

          It is RESERVED when imm5 = x0000.

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

          B           when imm5 = xxxx1

          H           when imm5 = xxx10

          S           when imm5 = xx100

          D           when imm5 = x1000

          It is RESERVED when imm5 = x0000.

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

<index>   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

          imm5<4>     when imm5 = x1000

          It is RESERVED when imm5 = x0000.

<d>       Is the number 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.
       Operation for all encodings

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

         element = Elem[operand, index, esize];
         for e = 0 to elements-1
              Elem[result, e, esize] = element;
         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','EXT','Extract vector from pair of vectors       (C7.3.34)




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




Advanced SIMD variant

EXT <Vd>.<T>, <Vn>.<T>, <Vm>.<T>, #<index>


Decode for this encoding

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

 if Q == ''0'' && imm4<3> == ''1'' then UnallocatedEncoding();

 integer datasize = if Q == ''1'' then 128 else 64;
 integer position = UInt(imm4) << 3;


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 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.

<index>         Is the lowest numbered byte element to be extracted, encoded in the "Q:imm4" field. It can have the
                following values:

                imm4<2:0>   when Q = 0, imm4<3> = 0

                imm4        when Q = 1, imm4<3> = x

                It is RESERVED when Q = 0, imm4<3> = 1.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) hi = V[m];
 bits(datasize) lo = V[n];
 bits(datasize*2) concat = hi : lo;

 V[d] = concat<position+datasize-1:position>;');
INSERT INTO "instructions" VALUES('ARM','FABD','       Floating-point absolute difference (vector)       (C7.3.35)


       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 1 sz 1                   Rm         1 1 0 1 0 1               Rn             Rd




       Scalar variant

       FABD <V><d>, <V><n>, <V><m>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;
         boolean abs = TRUE;


       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 1 sz 1                   Rm         1 1 0 1 0 1               Rn             Rd
                  U


       Vector variant

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


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;
         boolean abs = (U == ''1'');


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

              2S          when sz = 0, Q = 0

              4S          when sz = 0, Q = 1

              2D          when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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;
 bits(esize) element1;
 bits(esize) element2;
 bits(esize) diff;

 for e = 0 to elements-1
     element1 = Elem[operand1, e, esize];
     element2 = Elem[operand2, e, esize];
     diff = FPSub(element1, element2, FPCR);
     Elem[result, e, esize] = if abs then FPAbs(diff) else diff;

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FABS','Floating-point absolute value (vector)       (C7.3.36)




    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 1 sz 1 0 0 0 0 0 1 1 1 1 1 0                                Rn              Rd
           U


Vector variant

FABS <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

  if sz:Q == ''10'' then ReservedValue();
  integer esize = 32 << UInt(sz);
  integer datasize = if Q == ''1'' then 128 else 64;
  integer elements = datasize DIV esize;

  boolean neg = (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 "sz:Q" field. It can have the following values:

                  2S          when sz = 0, Q = 0

                  4S          when sz = 0, Q = 1

                  2D          when sz = 1, Q = 1

                  It is RESERVED when sz = 1, Q = 0.

<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];
       if neg then
            element = FPNeg(element);
       else
            element = FPAbs(element);
       Elem[result, e, esize] = element;

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FACGE','Floating-point absolute compare greater than or equal (vector)       (C7.3.38)


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 0 sz 1                  Rm        1 1 1 0 1 1               Rn             Rd
        U                  E                                    ac


Scalar variant

FACGE <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();


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 0 sz 1                  Rm        1 1 1 0 1 1               Rn             Rd
        U                  E                                    ac


Vector variant

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


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();
       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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;
         bits(esize) element1;
         bits(esize) element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              if abs then
                   element1 = FPAbs(element1);
                   element2 = FPAbs(element2);
              case cmp of
                   when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);
                   when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);
                   when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FACGT','Floating-point absolute compare greater than (vector)       (C7.3.39)


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 1 sz 1                  Rm        1 1 1 0 1 1               Rn             Rd
        U                  E                                    ac


Scalar variant

FACGT <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();


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 1 sz 1                  Rm        1 1 1 0 1 1               Rn             Rd
        U                  E                                    ac


Vector variant

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


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();
       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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;
         bits(esize) element1;
         bits(esize) element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              if abs then
                   element1 = FPAbs(element1);
                   element2 = FPAbs(element2);
              case cmp of
                   when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);
                   when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);
                   when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FADD','Floating-point add (vector)       (C7.3.40)




  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 sz 1                  Rm         1 1 0 1 0 1               Rn             Rd
        U


Three registers of the same type variant

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


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean pair = (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 "sz:Q" field. It can have the following values:

               2S          when sz = 0, Q = 0

               4S          when sz = 0, Q = 1

               2D          when sz = 1, Q = 1

               It is RESERVED when sz = 1, 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;
 bits(2*datasize) concat = operand2:operand1;
 bits(esize) element1;
 bits(esize) element2;

 for e = 0 to elements-1
     if pair then
         element1 = Elem[concat, 2*e, esize];
         element2 = Elem[concat, (2*e)+1, esize];
     else
         element1 = Elem[operand1, e, esize];
         element2 = Elem[operand2, e, esize];
     Elem[result, e, esize] = FPAdd(element1, element2, FPCR);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FADDP','Floating-point add pair of elements (scalar)       (C7.3.42)




  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 0 sz 1 1 0 0 0 0 1 1 0 1 1 0                                   Rn              Rd




Advanced SIMD variant

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


Decode for this encoding

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

 integer esize = 32 << UInt(sz);
 integer datasize = esize * 2;
 integer elements = 2;

 ReduceOp op = ReduceOp_FADD;


Assembler symbols

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

               S            when sz = 0

               D            when sz = 1

<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 the source arrangement specifier, encoded in the "sz" field. It can have the following values:

               2S           when sz = 0

               2D           when sz = 1


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FCCMP','Floating-point conditional quiet compare (scalar), setting condition flags to result of comparison or an immediate       (C7.3.44)
value: flags = if cond then compareQuiet(Vn,Vm) else #nzcv




  31 30 29 28 27 26 25 24 23 22 21 20             16 15         12 11 10 9               5 4 3          0
  0 0 0 1 1 1 1 0 0 x 1                      Rm           cond      0 1          Rn         0    nzcv
                            type                                                           op


Single-precision variant

Applies when type = 00.

FCCMP <Sn>, <Sm>, #<nzcv>, <cond>


Double-precision variant

Applies when type = 01.

FCCMP <Dn>, <Dm>, #<nzcv>, <cond>


Decode for all variants of this encoding

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

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 boolean signal_all_nans = (op == ''1'');
 bits(4) condition = cond;
 bits(4) flags = nzcv;


Assembler symbols

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

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "Rm" field.

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

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

<nzcv>         Is the flag bit specifier, an immediate in the range 0 to 15, giving the alternative state for the 4-bit
               NZCV condition flags, encoded in the "nzcv" field.

<cond>         Is one of the standard conditions, encoded in the "cond" field in the standard way.


Operation

 CheckFPAdvSIMDEnabled64();

 bits(datasize) operand1 = V[n];
 bits(datasize) operand2;

 operand2 = V[m];
         if ConditionHolds(condition) then
              flags = FPCompare(operand1, operand2, signal_all_nans, FPCR);
         PSTATE.<N,Z,C,V> = flags;');
INSERT INTO "instructions" VALUES('ARM','FCCMPE','Floating-point conditional signaling compare (scalar), setting condition flags to result of comparison or an       (C7.3.45)
immediate value: flags = if cond then compareSignaling(Vn,Vm) else #nzcv




  31 30 29 28 27 26 25 24 23 22 21 20             16 15         12 11 10 9               5 4 3          0
  0 0 0 1 1 1 1 0 0 x 1                      Rm           cond      0 1          Rn         1    nzcv
                            type                                                           op


Single-precision variant

Applies when type = 00.

FCCMPE <Sn>, <Sm>, #<nzcv>, <cond>


Double-precision variant

Applies when type = 01.

FCCMPE <Dn>, <Dm>, #<nzcv>, <cond>


Decode for all variants of this encoding

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

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 boolean signal_all_nans = (op == ''1'');
 bits(4) condition = cond;
 bits(4) flags = nzcv;


Assembler symbols

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

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "Rm" field.

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

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

<nzcv>         Is the flag bit specifier, an immediate in the range 0 to 15, giving the alternative state for the 4-bit
               NZCV condition flags, encoded in the "nzcv" field.

<cond>         Is one of the standard conditions, encoded in the "cond" field in the standard way.


Operation

 CheckFPAdvSIMDEnabled64();

 bits(datasize) operand1 = V[n];
 bits(datasize) operand2;

 operand2 = V[m];
         if ConditionHolds(condition) then
              flags = FPCompare(operand1, operand2, signal_all_nans, FPCR);
         PSTATE.<N,Z,C,V> = flags;');
INSERT INTO "instructions" VALUES('ARM','FCMEQ','Floating-point compare equal (vector), setting destination vector element to all ones if the condition holds, else zero       (C7.3.46)


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 0 sz 1                   Rm         1 1 1 0 0 1               Rn              Rd
        U                  E                                      ac


Scalar variant

FCMEQ <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();


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 0 sz 1                   Rm         1 1 1 0 0 1               Rn              Rd
        U                  E                                      ac


Vector variant

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


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();
       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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;
         bits(esize) element1;
         bits(esize) element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              if abs then
                   element1 = FPAbs(element1);
                   element2 = FPAbs(element2);
              case cmp of
                   when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);
                   when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);
                   when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCMGE','Floating-point compare greater than or equal (vector), setting destination vector element to all ones if the condition       (C7.3.48)
holds, else zero


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 0 sz 1                  Rm         1 1 1 0 0 1               Rn               Rd
         U                 E                                       ac


Scalar variant

FCMGE <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();


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 0 sz 1                  Rm         1 1 1 0 0 1               Rn               Rd
         U                 E                                       ac


Vector variant

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


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
              when ''110'' cmp = CompareOp_GT; abs = FALSE;
              when ''111'' cmp = CompareOp_GT; abs = TRUE;
              otherwise    UnallocatedEncoding();


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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;
         bits(esize) element1;
         bits(esize) element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              if abs then
                   element1 = FPAbs(element1);
                   element2 = FPAbs(element2);
              case cmp of
                   when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);
                   when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);
                   when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCMGT','Floating-point compare greater than (vector), setting destination vector element to all ones if the condition holds,       (C7.3.50)
else zero


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 1 sz 1                Rm           1 1 1 0 0 1              Rn               Rd
         U                 E                                      ac


Scalar variant

FCMGT <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
     when ''110'' cmp = CompareOp_GT; abs = FALSE;
     when ''111'' cmp = CompareOp_GT; abs = TRUE;
     otherwise   UnallocatedEncoding();


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 1 sz 1                Rm           1 1 1 0 0 1              Rn               Rd
         U                 E                                      ac


Vector variant

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


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;
 CompareOp cmp;
 boolean abs;

 case E:U:ac of
     when ''000'' cmp = CompareOp_EQ; abs = FALSE;
     when ''010'' cmp = CompareOp_GE; abs = FALSE;
     when ''011'' cmp = CompareOp_GE; abs = TRUE;
              when ''110'' cmp = CompareOp_GT; abs = FALSE;
              when ''111'' cmp = CompareOp_GT; abs = TRUE;
              otherwise    UnallocatedEncoding();


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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;
         bits(esize) element1;
         bits(esize) element2;
         boolean test_passed;

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              element2 = Elem[operand2, e, esize];
              if abs then
                   element1 = FPAbs(element1);
                   element2 = FPAbs(element2);
              case cmp of
                   when CompareOp_EQ test_passed = FPCompareEQ(element1, element2, FPCR);
                   when CompareOp_GE test_passed = FPCompareGE(element1, element2, FPCR);
                   when CompareOp_GT test_passed = FPCompareGT(element1, element2, FPCR);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCMLE','Floating-point compare less than or equal to zero (vector), setting destination vector element to all ones if the       (C7.3.52)
condition holds, else zero


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 1 sz 1 0 0 0 0 0 1 1 0 1 1 0                                  Rn             Rd
        U                                                      op


Scalar variant

FCMLE <V><d>, <V><n>, #0.0


Decode for this encoding

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

 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;

 CompareOp comparison;
 case op:U of
     when ''00'' comparison = CompareOp_GT;
     when ''01'' comparison = CompareOp_GE;
     when ''10'' comparison = CompareOp_EQ;
     when ''11'' comparison = CompareOp_LE;


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 1 sz 1 0 0 0 0 0 1 1 0 1 1 0                                  Rn             Rd
        U                                                      op


Vector variant

FCMLE <Vd>.<T>, <Vn>.<T>, #0.0


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 CompareOp comparison;
 case op:U of
     when ''00'' comparison = CompareOp_GT;
     when ''01'' comparison = CompareOp_GE;
     when ''10'' comparison = CompareOp_EQ;
     when ''11'' comparison = CompareOp_LE;
       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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(esize) zero = FPZero(''0'');
         bits(esize) element;
         boolean test_passed;

         for e = 0 to elements-1
              element = Elem[operand, e, esize];
              case comparison of
                   when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR);
                   when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR);
                   when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR);
                   when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR);
                   when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCMLT','Floating-point compare less than zero (vector), setting destination vector element to all ones if the condition holds,       (C7.3.53)
else zero


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 1 sz 1 0 0 0 0 0 1 1 1 0 1 0                                 Rn              Rd




Scalar variant

FCMLT <V><d>, <V><n>, #0.0


Decode for this encoding

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

 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;

 CompareOp comparison = CompareOp_LT;


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 1 sz 1 0 0 0 0 0 1 1 1 0 1 0                                 Rn              Rd




Vector variant

FCMLT <Vd>.<T>, <Vn>.<T>, #0.0


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 CompareOp comparison = CompareOp_LT;


Assembler symbols

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

               S           when sz = 0

               D           when sz = 1

<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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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(esize) zero = FPZero(''0'');
         bits(esize) element;
         boolean test_passed;

         for e = 0 to elements-1
              element = Elem[operand, e, esize];
              case comparison of
                   when CompareOp_GT test_passed = FPCompareGT(element, zero, FPCR);
                   when CompareOp_GE test_passed = FPCompareGE(element, zero, FPCR);
                   when CompareOp_EQ test_passed = FPCompareEQ(element, zero, FPCR);
                   when CompareOp_LE test_passed = FPCompareGE(zero, element, FPCR);
                   when CompareOp_LT test_passed = FPCompareGT(zero, element, FPCR);
              Elem[result, e, esize] = if test_passed then Ones() else Zeros();

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCMP','Floating-point quiet compare (scalar): flags = compareQuiet(Vn, Vm) // with register       (C7.3.54)




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


Single-precision variant

Applies when type = 00 && opc = 00.

FCMP <Sn>, <Sm>


Single-precision, zero variant

Applies when type = 00 && Rm = (00000) && opc = 01.

FCMP <Sn>, #0.0


Double-precision variant

Applies when type = 01 && opc = 00.

FCMP <Dn>, <Dm>


Double-precision, zero variant

Applies when type = 01 && Rm = (00000) && opc = 01.

FCMP <Dn>, #0.0


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer m = UInt(Rm);    // ignored when opc<0> == ''1''

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 boolean signal_all_nans = (opc<1> == ''1'');
 boolean cmp_with_zero = (opc<0> == ''1'');


Assembler symbols

<Dn>           For the double-precision variant: is the 64-bit name of the first SIMD&FP source register, encoded
               in the "Rn" field.

               For the double-precision, zero variant: is the 64-bit name of the SIMD&FP source register, encoded
               in the "Rn" field.

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "Rm" field.

<Sn>           For the single-precision variant: is the 32-bit name of the first SIMD&FP source register, encoded
               in the "Rn" field.

               For the single-precision, zero variant: is the 32-bit name of the SIMD&FP source register, encoded
               in the "Rn" field.
       <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();

         bits(datasize) operand1 = V[n];
         bits(datasize) operand2;

         operand2 = if cmp_with_zero then FPZero(''0'') else V[m];

         PSTATE.<N,Z,C,V> = FPCompare(operand1, operand2, signal_all_nans, FPCR);');
INSERT INTO "instructions" VALUES('ARM','FCMPE','Floating-point signaling compare (scalar): flags = compareSignaling(Vn, Vm) // with register       (C7.3.55)




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


Single-precision variant

Applies when type = 00 && opc = 10.

FCMPE <Sn>, <Sm>


Single-precision, zero variant

Applies when type = 00 && Rm = (00000) && opc = 11.

FCMPE <Sn>, #0.0


Double-precision variant

Applies when type = 01 && opc = 10.

FCMPE <Dn>, <Dm>


Double-precision, zero variant

Applies when type = 01 && Rm = (00000) && opc = 11.

FCMPE <Dn>, #0.0


Decode for all variants of this encoding

 integer n = UInt(Rn);
 integer m = UInt(Rm);    // ignored when opc<0> == ''1''

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 boolean signal_all_nans = (opc<1> == ''1'');
 boolean cmp_with_zero = (opc<0> == ''1'');


Assembler symbols

<Dn>           For the double-precision variant: is the 64-bit name of the first SIMD&FP source register, encoded
               in the "Rn" field.

               For the double-precision, zero variant: is the 64-bit name of the SIMD&FP source register, encoded
               in the "Rn" field.

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "Rm" field.

<Sn>           For the single-precision variant: is the 32-bit name of the first SIMD&FP source register, encoded
               in the "Rn" field.

               For the single-precision, zero variant: is the 32-bit name of the SIMD&FP source register, encoded
               in the "Rn" field.
       <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Rm" field.


       Operation

         CheckFPAdvSIMDEnabled64();

         bits(datasize) operand1 = V[n];
         bits(datasize) operand2;

         operand2 = if cmp_with_zero then FPZero(''0'') else V[m];

         PSTATE.<N,Z,C,V> = FPCompare(operand1, operand2, signal_all_nans, FPCR);');
INSERT INTO "instructions" VALUES('ARM','FCSEL','Floating-point conditional select (scalar): Vd = if cond then Vn else Vm       (C7.3.56)




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


Single-precision variant

Applies when type = 00.

FCSEL <Sd>, <Sn>, <Sm>, <cond>


Double-precision variant

Applies when type = 01.

FCSEL <Dd>, <Dn>, <Dm>, <cond>


Decode for all variants of this encoding

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

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 bits(4) condition = cond;


Assembler symbols

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

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

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "Rm" field.

<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 first SIMD&FP source register, encoded in the "Rn" field.

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

<cond>         Is one of the standard conditions, encoded in the "cond" field in the standard way.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) result;

 result = if ConditionHolds(condition) then V[n] else V[m];

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVT','       Floating-point convert precision (scalar): Vd = convertFormat(Vn)       (C7.3.57)




           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 0 0 1 1 1 1 0 type 1 0 0 0 1 opc 1 0 0 0 0                            Rn     Rd




       Half-precision to single-precision variant

       Applies when type = 11 && opc = 00.

       FCVT <Sd>, <Hn>


       Half-precision to double-precision variant

       Applies when type = 11 && opc = 01.

       FCVT <Dd>, <Hn>


       Single-precision to half-precision variant

       Applies when type = 00 && opc = 11.

       FCVT <Hd>, <Sn>


       Single-precision to double-precision variant

       Applies when type = 00 && opc = 01.

       FCVT <Dd>, <Sn>


       Double-precision to half-precision variant

       Applies when type = 01 && opc = 11.

       FCVT <Hd>, <Dn>


       Double-precision to single-precision variant

       Applies when type = 01 && opc = 00.

       FCVT <Sd>, <Dn>


       Decode for all variants of this encoding

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

         if type == opc then UnallocatedEncoding();

         integer srcsize;
         case type of
              when ''00'' srcsize = 32;
              when ''01'' srcsize = 64;
              when ''10'' UnallocatedEncoding();
              when ''11'' srcsize = 16;
         integer dstsize;
         case opc of
              when ''00'' dstsize = 32;
              when ''01'' dstsize = 64;
              when ''10'' UnallocatedEncoding();
              when ''11'' dstsize = 16;
Assembler symbols

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

<Hd>          Is the 16-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.

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

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

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


Operation

 CheckFPAdvSIMDEnabled64();

 bits(dstsize) result;
 bits(srcsize) operand = V[n];

 result = FPConvert(operand, FPCR);
 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTAS','       Floating-point convert to signed integer, rounding to nearest with ties to away (vector)       (C7.3.58)


       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 0 sz 1 0 0 0 0 1 1 1 0 0 1 0                                  Rn             Rd
                  U


       Scalar variant

       FCVTAS <V><d>, <V><n>


       Decode for this encoding

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;

         FPRounding rounding = FPRounding_TIEAWAY;
         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 0 sz 1 0 0 0 0 1 1 1 0 0 1 0                                  Rn             Rd
                  U


       Vector variant

       FCVTAS <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;

         FPRounding rounding = FPRounding_TIEAWAY;
         boolean unsigned = (U == ''1'');


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

              2S          when sz = 0, Q = 0

              4S          when sz = 0, Q = 1

              2D          when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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(esize) element;

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

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTAU','       Floating-point convert to unsigned integer, rounding to nearest with ties to away (vector)       (C7.3.60)


       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 0 sz 1 0 0 0 0 1 1 1 0 0 1 0                                  Rn             Rd
                  U


       Scalar variant

       FCVTAU <V><d>, <V><n>


       Decode for this encoding

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;

         FPRounding rounding = FPRounding_TIEAWAY;
         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 1 0 1 1 1 0 0 sz 1 0 0 0 0 1 1 1 0 0 1 0                                  Rn             Rd
                  U


       Vector variant

       FCVTAU <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;

         FPRounding rounding = FPRounding_TIEAWAY;
         boolean unsigned = (U == ''1'');


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

              2S          when sz = 0, Q = 0

              4S          when sz = 0, Q = 1

              2D          when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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(esize) element;

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

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTL','Floating-point convert to higher precision long (vector)       (C7.3.62)




    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 0 sz 1 0 0 0 0 1 0 1 1 1 1 0                                   Rn               Rd




Vector variant

FCVTL{2} <Vd>.<Ta>, <Vn>.<Tb>


Decode for this encoding

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

  integer esize = 16 << UInt(sz);
  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 "sz" field. It can have the following values:

                  4S          when sz = 0

                  2D          when sz = 1

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

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

                  4H          when sz = 0, Q = 0

                  8H          when sz = 0, Q = 1

                  2S          when sz = 1, Q = 0

                  4S          when sz = 1, Q = 1


Operation

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

  for e = 0 to elements-1
       Elem[result, e, 2*esize] = FPConvert(Elem[operand, e, esize], FPCR);

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTL2','-R:FCVTL');
INSERT INTO "instructions" VALUES('ARM','FCVTMS','Floating-point convert to signed integer, rounding toward minus infinity (vector)       (C7.3.63)


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 0 sz 1 0 0 0 0 1 1 0 1 1 1 0                                  Rn             Rd
        U                   o2                                  o1


Scalar variant

FCVTMS <V><d>, <V><n>


Decode for this encoding

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

 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;

 FPRounding rounding = FPDecodeRounding(o1:o2);
 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 0 sz 1 0 0 0 0 1 1 0 1 1 1 0                                  Rn             Rd
        U                   o2                                  o1


Vector variant

FCVTMS <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 FPRounding rounding = FPDecodeRounding(o1:o2);
 boolean unsigned = (U == ''1'');


Assembler symbols

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

               S            when sz = 0

               D            when sz = 1

<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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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(esize) element;

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

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTMU','Floating-point convert to unsigned integer, rounding toward minus infinity (vector)       (C7.3.65)


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 0 sz 1 0 0 0 0 1 1 0 1 1 1 0                                  Rn             Rd
        U                  o2                                   o1


Scalar variant

FCVTMU <V><d>, <V><n>


Decode for this encoding

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

 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;

 FPRounding rounding = FPDecodeRounding(o1:o2);
 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 1 0 1 1 1 0 0 sz 1 0 0 0 0 1 1 0 1 1 1 0                                  Rn             Rd
        U                  o2                                   o1


Vector variant

FCVTMU <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 FPRounding rounding = FPDecodeRounding(o1:o2);
 boolean unsigned = (U == ''1'');


Assembler symbols

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

               S           when sz = 0

               D           when sz = 1

<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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1

                         2D          when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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(esize) element;

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

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTN','Floating-point convert to lower precision narrow (vector)       (C7.3.67)




  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 0 sz 1 0 0 0 0 1 0 1 1 0 1 0                                   Rn               Rd




Vector variant

FCVTN{2} <Vd>.<Tb>, <Vn>.<Ta>


Decode for this encoding

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

 integer esize = 16 << UInt(sz);
 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 "sz:Q" field. It can have the following values:

               4H           when sz = 0, Q = 0

               8H           when sz = 0, Q = 1

               2S           when sz = 1, Q = 0

               4S           when sz = 1, Q = 1

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

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

               4S           when sz = 0

               2D           when sz = 1


Operation

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

 for e = 0 to elements-1
     Elem[result, e, esize] = FPConvert(Elem[operand, e, 2*esize], FPCR);

 Vpart[d, part] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTN2','-R:FCVTN');
INSERT INTO "instructions" VALUES('ARM','FCVTNS','       Floating-point convert to signed integer, rounding to nearest with ties to even (vector)       (C7.3.68)


       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 0 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Scalar variant

       FCVTNS <V><d>, <V><n>


       Decode for this encoding

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         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 0 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Vector variant

       FCVTNS <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         boolean unsigned = (U == ''1'');


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

              2S          when sz = 0, Q = 0

              4S          when sz = 0, Q = 1

              2D          when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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(esize) element;

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

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTNU','       Floating-point convert to unsigned integer, rounding to nearest with ties to even (vector)       (C7.3.70)


       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 0 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Scalar variant

       FCVTNU <V><d>, <V><n>


       Decode for this encoding

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         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 1 0 1 1 1 0 0 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Vector variant

       FCVTNU <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         boolean unsigned = (U == ''1'');


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

              2S          when sz = 0, Q = 0

              4S          when sz = 0, Q = 1

              2D          when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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(esize) element;

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

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTPS','       Floating-point convert to signed integer, rounding toward positive infinity (vector)       (C7.3.72)


       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 1 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Scalar variant

       FCVTPS <V><d>, <V><n>


       Decode for this encoding

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         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 1 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Vector variant

       FCVTPS <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         boolean unsigned = (U == ''1'');


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

              2S          when sz = 0, Q = 0

              4S          when sz = 0, Q = 1

              2D          when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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(esize) element;

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

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTPU','       Floating-point convert to unsigned integer, rounding toward positive infinity (vector)       (C7.3.74)


       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 1 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Scalar variant

       FCVTPU <V><d>, <V><n>


       Decode for this encoding

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         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 1 0 1 1 1 0 1 sz 1 0 0 0 0 1 1 0 1 0 1 0                                  Rn             Rd
                  U                  o2                                   o1


       Vector variant

       FCVTPU <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;

         FPRounding rounding = FPDecodeRounding(o1:o2);
         boolean unsigned = (U == ''1'');


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

              2S          when sz = 0, Q = 0

              4S          when sz = 0, Q = 1

              2D          when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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(esize) element;

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

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTXN','       Floating-point convert to lower precision narrow, rounding to odd (vector)       (C7.3.76)


       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 0 sz 1 0 0 0 0 1 0 1 1 0 1 0                                   Rn               Rd




       Scalar variant

       FCVTXN <Vb><d>, <Va><n>


       Decode for this encoding

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

         if sz == ''0'' then ReservedValue();
         integer esize = 32;
         integer datasize = esize;
         integer elements = 1;
         integer part = 0;


       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 0 sz 1 0 0 0 0 1 0 1 1 0 1 0                                   Rn               Rd




       Vector variant

       FCVTXN{2} <Vd>.<Tb>, <Vn>.<Ta>


       Decode for this encoding

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

         if sz == ''0'' then ReservedValue();
         integer esize = 32;
         integer datasize = 64;
         integer elements = 2;
         integer part = UInt(Q);


       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 "sz:Q" field. It can have the following values:

                         2S          when sz = 1, Q = 0
              4S          when sz = 1, Q = 1

              It is RESERVED when sz = 0, 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 "sz" field. It can have the following values:

              2D          when sz = 1

              It is RESERVED when sz = 0.

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

              S           when sz = 1

              It is RESERVED when sz = 0.

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

<Va>          Is the source width specifier, encoded in the "sz" field. It can have the following values:

              D           when sz = 1

              It is RESERVED when sz = 0.

<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;

 for e = 0 to elements-1
     Elem[result, e, esize] = FPConvert(Elem[operand, e, 2*esize], FPCR, FPRounding_ODD);

 Vpart[d, part] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTXN2','-R:FCVTXN');
INSERT INTO "instructions" VALUES('ARM','FCVTZS','       Floating-point convert to signed fixed-point, rounding toward zero (vector)       (C7.3.77)


       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 1 1 1             Rn             Rd
                  U                         immh


       Scalar variant

       FCVTZS <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 = FPRounding_ZERO;


       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 1 1 1             Rn             Rd
                  U                         immh


       Vector variant

       FCVTZS <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 = FPRounding_ZERO;


       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] = FPToFixed(element, fracbits, unsigned, FPCR, rounding);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FCVTZU','       Floating-point convert to unsigned fixed-point, rounding toward zero (vector)       (C7.3.81)


       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 1 1 1             Rn             Rd
                  U                         immh


       Scalar variant

       FCVTZU <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 = FPRounding_ZERO;


       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 1 1 1             Rn             Rd
                  U                         immh


       Vector variant

       FCVTZU <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 = FPRounding_ZERO;


       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] = FPToFixed(element, fracbits, unsigned, FPCR, rounding);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FDIV','Floating-point divide (vector)       (C7.3.85)




    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 0 sz 1                  Rm         1 1 1 1 1 1              Rn              Rd




Three registers of the same type variant

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


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if sz:Q == ''10'' then ReservedValue();
  integer esize = 32 << UInt(sz);
  integer datasize = if Q == ''1'' then 128 else 64;
  integer elements = datasize DIV esize;


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 "sz:Q" field. It can have the following values:

                  2S          when sz = 0, Q = 0

                  4S          when sz = 0, Q = 1

                  2D          when sz = 1, Q = 1

                  It is RESERVED when sz = 1, 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;
  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, esize] = FPDiv(element1, element2, FPCR);

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMADD','       Floating-point fused multiply-add (scalar): Vd = Va + Vn*Vm       (C7.3.87)




           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14          10 9            5 4            0
            0 0 0 1 1 1 1 1 0 x 0                    Rm       0       Ra              Rn              Rd
                                      type o1                 o0


       Single-precision variant

       Applies when type = 00.

       FMADD <Sd>, <Sn>, <Sm>, <Sa>


       Double-precision variant

       Applies when type = 01.

       FMADD <Dd>, <Dn>, <Dm>, <Da>


       Decode for all variants of this encoding

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

         integer datasize;
         case type of
              when ''00'' datasize = 32;
              when ''01'' datasize = 64;
              when ''1x'' UnallocatedEncoding();

         boolean opa_neg = (o1 == ''1'');
         boolean op1_neg = (o0 != o1);


       Assembler symbols

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

       <Dn>              Is the 64-bit name of the first SIMD&FP source register holding the multiplicand, encoded in the
                         "Rn" field.

       <Dm>              Is the 64-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
                         "Rm" field.

       <Da>              Is the 64-bit name of the third SIMD&FP source register holding the addend, encoded in the "Ra"
                         field.

       <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 first SIMD&FP source register holding the multiplicand, encoded in the
                         "Rn" field.

       <Sm>              Is the 32-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
                         "Rm" field.

       <Sa>              Is the 32-bit name of the third SIMD&FP source register holding the addend, encoded in the "Ra"
                         field.
Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) result;
 bits(datasize) operanda = V[a];
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];

 if opa_neg then operanda = FPNeg(operanda);
 if op1_neg then operand1 = FPNeg(operand1);
 result = FPMulAdd(operanda, operand1, operand2, FPCR);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMAX','      Floating-point maximum (vector)       (C7.3.88)




          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 sz 1                  Rm         1 1 1 1 0 1              Rn              Rd
                 U                 o1


      Three registers of the same type variant

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


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if sz:Q == ''10'' then ReservedValue();
        integer esize = 32 << UInt(sz);
        integer datasize = if Q == ''1'' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean pair = (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 "sz:Q" field. It can have the following values:

                        2S          when sz = 0, Q = 0

                        4S          when sz = 0, Q = 1

                        2D          when sz = 1, Q = 1

                        It is RESERVED when sz = 1, 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;
        bits(2*datasize) concat = operand2:operand1;
        bits(esize) element1;
        bits(esize) element2;

        for e = 0 to elements-1
             if pair then
                  element1 = Elem[concat, 2*e, esize];
                  element2 = Elem[concat, (2*e)+1, esize];
             else
                  element1 = Elem[operand1, e, esize];
                  element2 = Elem[operand2, e, esize];

             if minimum then
                  Elem[result, e, esize] = FPMin(element1, element2, FPCR);
   else
        Elem[result, e, esize] = FPMax(element1, element2, FPCR);

V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMAXNM','      Floating-point maximum number (vector)       (C7.3.90)




          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 sz 1                  Rm         1 1 0 0 0 1              Rn              Rd
                 U                 o1


      Three registers of the same type variant

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


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if sz:Q == ''10'' then ReservedValue();
        integer esize = 32 << UInt(sz);
        integer datasize = if Q == ''1'' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean pair = (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 "sz:Q" field. It can have the following values:

                        2S          when sz = 0, Q = 0

                        4S          when sz = 0, Q = 1

                        2D          when sz = 1, Q = 1

                        It is RESERVED when sz = 1, 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;
        bits(2*datasize) concat = operand2:operand1;
        bits(esize) element1;
        bits(esize) element2;

        for e = 0 to elements-1
             if pair then
                  element1 = Elem[concat, 2*e, esize];
                  element2 = Elem[concat, (2*e)+1, esize];
             else
                  element1 = Elem[operand1, e, esize];
                  element2 = Elem[operand2, e, esize];

             if minimum then
                  Elem[result, e, esize] = FPMinNum(element1, element2, FPCR);
   else
       Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR);

V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMAXNMP','Floating-point maximum number of pair of elements (scalar)       (C7.3.92)




    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 0 sz 1 1 0 0 0 0 1 1 0 0 1 0                                   Rn              Rd
                              o1


Advanced SIMD variant

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


Decode for this encoding

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

  integer esize = 32 << UInt(sz);
  integer datasize = esize * 2;
  integer elements = 2;

  ReduceOp op = if o1 == ''1'' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;


Assembler symbols

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

                  S           when sz = 0

                  D           when sz = 1

<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 the source arrangement specifier, encoded in the "sz" field. It can have the following values:

                  2S          when sz = 0

                  2D          when sz = 1


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand = V[n];
  V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMAXNMV','Floating-point maximum number across vector       (C7.3.94)




  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 sz 1 1 0 0 0 0 1 1 0 0 1 0                                   Rn              Rd
                           o1


Advanced SIMD variant

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


Decode for this encoding

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

 if sz:Q != ''01'' then ReservedValue();      // .4S only

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

 ReduceOp op = if o1 == ''1'' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;


Assembler symbols

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

               S           when sz = 0

               It is RESERVED when sz = 1.

<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 "Q:sz" field. It can have the following values:

               4S          when Q = 1, sz = 0

               It is RESERVED when:

               .      Q = 0, sz = x.

               .      Q = 1, sz = 1.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMAXP','Floating-point maximum of pair of elements (scalar)       (C7.3.95)




    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 0 sz 1 1 0 0 0 0 1 1 1 1 1 0                                   Rn              Rd
                              o1


Advanced SIMD variant

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


Decode for this encoding

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

  integer esize = 32 << UInt(sz);
  integer datasize = esize * 2;
  integer elements = 2;

  ReduceOp op = if o1 == ''1'' then ReduceOp_FMIN else ReduceOp_FMAX;


Assembler symbols

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

                  S           when sz = 0

                  D           when sz = 1

<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 the source arrangement specifier, encoded in the "sz" field. It can have the following values:

                  2S          when sz = 0

                  2D          when sz = 1


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand = V[n];
  V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMAXV','Floating-point maximum across vector       (C7.3.97)




  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 sz 1 1 0 0 0 0 1 1 1 1 1 0                                   Rn              Rd
                           o1


Advanced SIMD variant

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


Decode for this encoding

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

 if sz:Q != ''01'' then ReservedValue();

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

 ReduceOp op = if o1 == ''1'' then ReduceOp_FMIN else ReduceOp_FMAX;


Assembler symbols

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

               S           when sz = 0

               It is RESERVED when sz = 1.

<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 "Q:sz" field. It can have the following values:

               4S          when Q = 1, sz = 0

               It is RESERVED when:

               .      Q = 0, sz = x.

               .      Q = 1, sz = 1.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMIN','      Floating-point minimum (vector)       (C7.3.98)




          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 1 sz 1                  Rm         1 1 1 1 0 1              Rn              Rd
                 U                 o1


      Three registers of the same type variant

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


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if sz:Q == ''10'' then ReservedValue();
        integer esize = 32 << UInt(sz);
        integer datasize = if Q == ''1'' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean pair = (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 "sz:Q" field. It can have the following values:

                        2S          when sz = 0, Q = 0

                        4S          when sz = 0, Q = 1

                        2D          when sz = 1, Q = 1

                        It is RESERVED when sz = 1, 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;
        bits(2*datasize) concat = operand2:operand1;
        bits(esize) element1;
        bits(esize) element2;

        for e = 0 to elements-1
             if pair then
                  element1 = Elem[concat, 2*e, esize];
                  element2 = Elem[concat, (2*e)+1, esize];
             else
                  element1 = Elem[operand1, e, esize];
                  element2 = Elem[operand2, e, esize];

             if minimum then
                  Elem[result, e, esize] = FPMin(element1, element2, FPCR);
   else
        Elem[result, e, esize] = FPMax(element1, element2, FPCR);

V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMINNM','      Floating-point minimum number (vector)       (C7.3.100)




          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 1 sz 1                  Rm         1 1 0 0 0 1              Rn              Rd
                 U                 o1


      Three registers of the same type variant

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


      Decode for this encoding

        integer d = UInt(Rd);
        integer n = UInt(Rn);
        integer m = UInt(Rm);
        if sz:Q == ''10'' then ReservedValue();
        integer esize = 32 << UInt(sz);
        integer datasize = if Q == ''1'' then 128 else 64;
        integer elements = datasize DIV esize;

        boolean pair = (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 "sz:Q" field. It can have the following values:

                        2S          when sz = 0, Q = 0

                        4S          when sz = 0, Q = 1

                        2D          when sz = 1, Q = 1

                        It is RESERVED when sz = 1, 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;
        bits(2*datasize) concat = operand2:operand1;
        bits(esize) element1;
        bits(esize) element2;

        for e = 0 to elements-1
             if pair then
                  element1 = Elem[concat, 2*e, esize];
                  element2 = Elem[concat, (2*e)+1, esize];
             else
                  element1 = Elem[operand1, e, esize];
                  element2 = Elem[operand2, e, esize];

             if minimum then
                  Elem[result, e, esize] = FPMinNum(element1, element2, FPCR);
   else
       Elem[result, e, esize] = FPMaxNum(element1, element2, FPCR);

V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMINNMP','Floating-point minimum number of pair of elements (scalar)       (C7.3.102)




    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 1 sz 1 1 0 0 0 0 1 1 0 0 1 0                                   Rn              Rd
                              o1


Advanced SIMD variant

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


Decode for this encoding

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

  integer esize = 32 << UInt(sz);
  integer datasize = esize * 2;
  integer elements = 2;

  ReduceOp op = if o1 == ''1'' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;


Assembler symbols

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

                  S           when sz = 0

                  D           when sz = 1

<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 the source arrangement specifier, encoded in the "sz" field. It can have the following values:

                  2S          when sz = 0

                  2D          when sz = 1


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand = V[n];
  V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMINNMV','Floating-point minimum number across vector       (C7.3.104)




  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 1 sz 1 1 0 0 0 0 1 1 0 0 1 0                                   Rn              Rd
                           o1


Advanced SIMD variant

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


Decode for this encoding

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

 if sz:Q != ''01'' then ReservedValue();      // .4S only

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

 ReduceOp op = if o1 == ''1'' then ReduceOp_FMINNUM else ReduceOp_FMAXNUM;


Assembler symbols

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

               S           when sz = 0

               It is RESERVED when sz = 1.

<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 "Q:sz" field. It can have the following values:

               4S          when Q = 1, sz = 0

               It is RESERVED when:

               .      Q = 0, sz = x.

               .      Q = 1, sz = 1.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMINP','Floating-point minimum of pair of elements (scalar)       (C7.3.105)




    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 1 sz 1 1 0 0 0 0 1 1 1 1 1 0                                   Rn              Rd
                              o1


Advanced SIMD variant

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


Decode for this encoding

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

  integer esize = 32 << UInt(sz);
  integer datasize = esize * 2;
  integer elements = 2;

  ReduceOp op = if o1 == ''1'' then ReduceOp_FMIN else ReduceOp_FMAX;


Assembler symbols

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

                  S           when sz = 0

                  D           when sz = 1

<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 the source arrangement specifier, encoded in the "sz" field. It can have the following values:

                  2S          when sz = 0

                  2D          when sz = 1


Operation

  CheckFPAdvSIMDEnabled64();
  bits(datasize) operand = V[n];
  V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMINV','Floating-point minimum across vector       (C7.3.107)




  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 1 sz 1 1 0 0 0 0 1 1 1 1 1 0                                   Rn              Rd
                           o1


Advanced SIMD variant

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


Decode for this encoding

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

 if sz:Q != ''01'' then ReservedValue();

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

 ReduceOp op = if o1 == ''1'' then ReduceOp_FMIN else ReduceOp_FMAX;


Assembler symbols

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

               S           when sz = 0

               It is RESERVED when sz = 1.

<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 "Q:sz" field. It can have the following values:

               4S          when Q = 1, sz = 0

               It is RESERVED when:

               .      Q = 0, sz = x.

               .      Q = 1, sz = 1.


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 V[d] = Reduce(op, operand, esize);');
INSERT INTO "instructions" VALUES('ARM','FMLA','       Floating-point fused multiply-add to accumulator (by element)       (C7.3.108)


       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 1 sz L M                Rm       0 0 0 1 H 0            Rn     Rd
                                                               o2


       Scalar variant

       FMLA <V><d>, <V><n>, <Vm>.<Ts>[<index>]


       Decode for this encoding

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

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;
         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 1 sz L M                Rm       0 0 0 1 H 0            Rn     Rd
                                                               o2


       Vector variant

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


       Decode for this encoding

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

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;
         boolean sub_op = (o2 == ''1'');
Assembler symbols

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

              S           when sz = 0

              D           when sz = 1

<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 "Q:sz" field. It can have the following values:

              2S          when Q = 0, sz = 0

              4S          when Q = 1, sz = 0

              2D          when Q = 1, sz = 1

              It is RESERVED when Q = 0, sz = 1.

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

<Vm>          For the scalar variant: is the name of the SIMD&FP source register, encoded in the "M:Rm" fields.

              For the vector variant: is the name of the second SIMD&FP source register, encoded in the "M:Rm"
              fields.

<Ts>          For the scalar variant: is the element width specifier, encoded in the "sz" field. It can have the
              following values:

              S           when sz = 0

              D           when sz = 1

              For the vector variant: is an element size specifier, encoded in the "sz" field. It can have the
              following values:

              S           when sz = 0

              D           when sz = 1

<index>       For the scalar variant: is the element index, encoded in the "sz:L:H" field. It can have the following
              values:

              H:L         when sz = 0, L = x

              H           when sz = 1, L = 0

              It is RESERVED when sz = 1, L = 1.

              For the vector variant: is the element index encoded in the "sz:L:H" field. It can have the following
              values:

              H:L         when sz = 0, L = x

              H           when sz = 1, L = 0

              It is RESERVED when sz = 1, L = 1.


Operation for all encodings

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

 for e = 0 to elements-1
     element1 = Elem[operand1, e, esize];
              if sub_op then element1 = FPNeg(element1);
              Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR);
         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMLS','       Floating-point fused multiply-subtract from accumulator (by element)       (C7.3.110)


       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 1 sz L M                Rm       0 1 0 1 H 0            Rn     Rd
                                                               o2


       Scalar variant

       FMLS <V><d>, <V><n>, <Vm>.<Ts>[<index>]


       Decode for this encoding

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

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;
         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 1 sz L M                Rm       0 1 0 1 H 0            Rn     Rd
                                                               o2


       Vector variant

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


       Decode for this encoding

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

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;
         boolean sub_op = (o2 == ''1'');
Assembler symbols

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

              S           when sz = 0

              D           when sz = 1

<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 "Q:sz" field. It can have the following values:

              2S          when Q = 0, sz = 0

              4S          when Q = 1, sz = 0

              2D          when Q = 1, sz = 1

              It is RESERVED when Q = 0, sz = 1.

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

<Vm>          For the scalar variant: is the name of the SIMD&FP source register, encoded in the "M:Rm" fields.

              For the vector variant: is the name of the second SIMD&FP source register, encoded in the "M:Rm"
              fields.

<Ts>          For the scalar variant: is the element width specifier, encoded in the "sz" field. It can have the
              following values:

              S           when sz = 0

              D           when sz = 1

              For the vector variant: is an element size specifier, encoded in the "sz" field. It can have the
              following values:

              S           when sz = 0

              D           when sz = 1

<index>       For the scalar variant: is the element index, encoded in the "sz:L:H" field. It can have the following
              values:

              H:L         when sz = 0, L = x

              H           when sz = 1, L = 0

              It is RESERVED when sz = 1, L = 1.

              For the vector variant: is the element index encoded in the "sz:L:H" field. It can have the following
              values:

              H:L         when sz = 0, L = x

              H           when sz = 1, L = 0

              It is RESERVED when sz = 1, L = 1.


Operation for all encodings

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

 for e = 0 to elements-1
     element1 = Elem[operand1, e, esize];
              if sub_op then element1 = FPNeg(element1);
              Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR);
         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMOV','       Floating-point move immediate (vector)       (C7.3.112)




           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 1 1 1 1 0 1 d e f g h                                       Rd
                                                                  cmode


       Single-precision variant

       Applies when op = 0.

       FMOV <Vd>.<T>, #<imm>


       Double-precision variant

       Applies when Q = 1 && op = 1.

       FMOV <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

       <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:

                         2S           when Q = 0

                         4S           when Q = 1

       <imm>             Is a floating-point constant with sign, 3-bit exponent and normalized 4 bits of precision, encoded in
                         "a:b:c:d:e:f:g:h".
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;');
INSERT INTO "instructions" VALUES('ARM','FMSUB','       Floating-point fused multiply-subtract (scalar): Vd = Va + (-Vn)*Vm       (C7.3.116)




           31 30 29 28 27 26 25 24 23 22 21 20             16 15 14          10 9            5 4            0
            0 0 0 1 1 1 1 1 0 x 0                    Rm        1      Ra              Rn              Rd
                                      type o1                 o0


       Single-precision variant

       Applies when type = 00.

       FMSUB <Sd>, <Sn>, <Sm>, <Sa>


       Double-precision variant

       Applies when type = 01.

       FMSUB <Dd>, <Dn>, <Dm>, <Da>


       Decode for all variants of this encoding

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

         integer datasize;
         case type of
              when ''00'' datasize = 32;
              when ''01'' datasize = 64;
              when ''1x'' UnallocatedEncoding();

         boolean opa_neg = (o1 == ''1'');
         boolean op1_neg = (o0 != o1);


       Assembler symbols

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

       <Dn>              Is the 64-bit name of the first SIMD&FP source register holding the multiplicand, encoded in the
                         "Rn" field.

       <Dm>              Is the 64-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
                         "Rm" field.

       <Da>              Is the 64-bit name of the third SIMD&FP source register holding the minuend, encoded in the "Ra"
                         field.

       <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 first SIMD&FP source register holding the multiplicand, encoded in the
                         "Rn" field.

       <Sm>              Is the 32-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
                         "Rm" field.

       <Sa>              Is the 32-bit name of the third SIMD&FP source register holding the minuend, encoded in the "Ra"
                         field.
Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) result;
 bits(datasize) operanda = V[a];
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];

 if opa_neg then operanda = FPNeg(operanda);
 if op1_neg then operand1 = FPNeg(operand1);
 result = FPMulAdd(operanda, operand1, operand2, FPCR);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMUL','       Floating-point multiply (by element)       (C7.3.117)


       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 1 sz L M                Rm       1 0 0 1 H 0            Rn     Rd
                  U


       Scalar variant

       FMUL <V><d>, <V><n>, <Vm>.<Ts>[<index>]


       Decode for this encoding

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

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 1;
         boolean mulx_op = (U == ''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 1 sz L M                Rm       1 0 0 1 H 0            Rn     Rd
                  U


       Vector variant

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


       Decode for this encoding

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

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;
         boolean mulx_op = (U == ''1'');
Assembler symbols

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

              S           when sz = 0

              D           when sz = 1

<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 "Q:sz" field. It can have the following values:

              2S          when Q = 0, sz = 0

              4S          when Q = 1, sz = 0

              2D          when Q = 1, sz = 1

              It is RESERVED when Q = 0, sz = 1.

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

<Vm>          For the scalar variant: is the name of the SIMD&FP source register, encoded in the "M:Rm" fields.

              For the vector variant: is the name of the second SIMD&FP source register, encoded in the "M:Rm"
              fields.

<Ts>          For the scalar variant: is the element width specifier, encoded in the "sz" field. It can have the
              following values:

              S           when sz = 0

              D           when sz = 1

              For the vector variant: is an element size specifier, encoded in the "sz" field. It can have the
              following values:

              S           when sz = 0

              D           when sz = 1

<index>       For the scalar variant: is the element index, encoded in the "sz:L:H" field. It can have the following
              values:

              H:L         when sz = 0, L = x

              H           when sz = 1, L = 0

              It is RESERVED when sz = 1, L = 1.

              For the vector variant: is the element index encoded in the "sz:L:H" field. It can have the following
              values:

              H:L         when sz = 0, L = x

              H           when sz = 1, L = 0

              It is RESERVED when sz = 1, L = 1.


Operation for all encodings

 CheckFPAdvSIMDEnabled64();
 bits(datasize) operand1 = V[n];
 bits(idxdsize) operand2 = V[m];
 bits(datasize) result;
 bits(esize) element1;
 bits(esize) element2 = Elem[operand2, index, esize];

 for e = 0 to elements-1
     element1 = Elem[operand1, e, esize];
     if mulx_op then
                   Elem[result, e, esize] = FPMulX(element1, element2, FPCR);
              else
                   Elem[result, e, esize] = FPMul(element1, element2, FPCR);

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FMULX','Floating-point multiply extended (by element)       (C7.3.120)


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 1 1 1 1 1 1 1 sz L M                Rm        1 0 0 1 H 0              Rn             Rd
        U


Scalar variant

FMULX <V><d>, <V><n>, <Vm>.<Ts>[<index>]


Decode for this encoding

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

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

 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 1;
 boolean mulx_op = (U == ''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 1 0 1 1 1 1 1 sz L M                Rm        1 0 0 1 H 0              Rn             Rd
        U


Vector variant

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


Decode for this encoding

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

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;
 boolean mulx_op = (U == ''1'');
       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "Q:sz" field. It can have the following values:

                         2S          when Q = 0, sz = 0

                         4S          when Q = 1, sz = 0

                         2D          when Q = 1, sz = 1

                         It is RESERVED when Q = 0, sz = 1.

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

       <Vm>              For the scalar variant: is the name of the SIMD&FP source register, encoded in the "M:Rm" fields.

                         For the vector variant: is the name of the second SIMD&FP source register, encoded in the "M:Rm"
                         fields.

       <Ts>              For the scalar variant: is the element width specifier, encoded in the "sz" field. It can have the
                         following values:

                         S           when sz = 0

                         D           when sz = 1

                         For the vector variant: is an element size specifier, encoded in the "sz" field. It can have the
                         following values:

                         S           when sz = 0

                         D           when sz = 1

       <index>           For the scalar variant: is the element index, encoded in the "sz:L:H" field. It can have the following
                         values:

                         H:L         when sz = 0, L = x

                         H           when sz = 1, L = 0

                         It is RESERVED when sz = 1, L = 1.

                         For the vector variant: is the element index encoded in the "sz:L:H" field. It can have the following
                         values:

                         H:L         when sz = 0, L = x

                         H           when sz = 1, L = 0

                         It is RESERVED when sz = 1, L = 1.


       Operation for all encodings

         CheckFPAdvSIMDEnabled64();
         bits(datasize) operand1 = V[n];
         bits(idxdsize) operand2 = V[m];
         bits(datasize) result;
         bits(esize) element1;
         bits(esize) element2 = Elem[operand2, index, esize];

         for e = 0 to elements-1
              element1 = Elem[operand1, e, esize];
              if mulx_op then
        Elem[result, e, esize] = FPMulX(element1, element2, FPCR);
    else
         Elem[result, e, esize] = FPMul(element1, element2, FPCR);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FNEG','Floating-point negate (vector)       (C7.3.122)




    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 1 sz 1 0 0 0 0 0 1 1 1 1 1 0                                Rn              Rd
           U


Vector variant

FNEG <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

  if sz:Q == ''10'' then ReservedValue();
  integer esize = 32 << UInt(sz);
  integer datasize = if Q == ''1'' then 128 else 64;
  integer elements = datasize DIV esize;

  boolean neg = (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 "sz:Q" field. It can have the following values:

                  2S          when sz = 0, Q = 0

                  4S          when sz = 0, Q = 1

                  2D          when sz = 1, Q = 1

                  It is RESERVED when sz = 1, Q = 0.

<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];
       if neg then
            element = FPNeg(element);
       else
            element = FPAbs(element);
       Elem[result, e, esize] = element;

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FNMADD','Floating-point negated fused multiply-add (scalar): Vd = (-Va) + (-Vn)*Vm       (C7.3.124)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14             10 9              5 4          0
  0 0 0 1 1 1 1 1 0 x 1                    Rm        0       Ra                 Rn             Rd
                            type o1                 o0


Single-precision variant

Applies when type = 00.

FNMADD <Sd>, <Sn>, <Sm>, <Sa>


Double-precision variant

Applies when type = 01.

FNMADD <Dd>, <Dn>, <Dm>, <Da>


Decode for all variants of this encoding

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

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 boolean opa_neg = (o1 == ''1'');
 boolean op1_neg = (o0 != o1);


Assembler symbols

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

<Dn>           Is the 64-bit name of the first SIMD&FP source register holding the multiplicand, encoded in the
               "Rn" field.

<Dm>           Is the 64-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
               "Rm" field.

<Da>           Is the 64-bit name of the third SIMD&FP source register holding the addend, encoded in the "Ra"
               field.

<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 first SIMD&FP source register holding the multiplicand, encoded in the
               "Rn" field.

<Sm>           Is the 32-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
               "Rm" field.

<Sa>           Is the 32-bit name of the third SIMD&FP source register holding the addend, encoded in the "Ra"
               field.
       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize) result;
         bits(datasize) operanda = V[a];
         bits(datasize) operand1 = V[n];
         bits(datasize) operand2 = V[m];

         if opa_neg then operanda = FPNeg(operanda);
         if op1_neg then operand1 = FPNeg(operand1);
         result = FPMulAdd(operanda, operand1, operand2, FPCR);

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FNMSUB','Floating-point negated fused multiply-subtract (scalar): Vd = (-Va) + Vn*Vm       (C7.3.125)




  31 30 29 28 27 26 25 24 23 22 21 20            16 15 14             10 9              5 4          0
  0 0 0 1 1 1 1 1 0 x 1                    Rm        1        Ra                Rn             Rd
                            type o1                 o0


Single-precision variant

Applies when type = 00.

FNMSUB <Sd>, <Sn>, <Sm>, <Sa>


Double-precision variant

Applies when type = 01.

FNMSUB <Dd>, <Dn>, <Dm>, <Da>


Decode for all variants of this encoding

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

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 boolean opa_neg = (o1 == ''1'');
 boolean op1_neg = (o0 != o1);


Assembler symbols

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

<Dn>           Is the 64-bit name of the first SIMD&FP source register holding the multiplicand, encoded in the
               "Rn" field.

<Dm>           Is the 64-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
               "Rm" field.

<Da>           Is the 64-bit name of the third SIMD&FP source register holding the minuend, encoded in the "Ra"
               field.

<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 first SIMD&FP source register holding the multiplicand, encoded in the
               "Rn" field.

<Sm>           Is the 32-bit name of the second SIMD&FP source register holding the multiplier, encoded in the
               "Rm" field.

<Sa>           Is the 32-bit name of the third SIMD&FP source register holding the minuend, encoded in the "Ra"
               field.
       Operation

         CheckFPAdvSIMDEnabled64();
         bits(datasize) result;
         bits(datasize) operanda = V[a];
         bits(datasize) operand1 = V[n];
         bits(datasize) operand2 = V[m];

         if opa_neg then operanda = FPNeg(operanda);
         if op1_neg then operand1 = FPNeg(operand1);
         result = FPMulAdd(operanda, operand1, operand2, FPCR);

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FNMUL','Floating-point multiply-negate (scalar): Vd = -(Vn * Vm)       (C7.3.126)




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


Single-precision variant

Applies when type = 00.

FNMUL <Sd>, <Sn>, <Sm>


Double-precision variant

Applies when type = 01.

FNMUL <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

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

 integer datasize;
 case type of
     when ''00'' datasize = 32;
     when ''01'' datasize = 64;
     when ''1x'' UnallocatedEncoding();

 boolean negated = (op == ''1'');


Assembler symbols

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

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

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "Rm" field.

<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 first SIMD&FP source register, encoded in the "Rn" field.

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


Operation

 CheckFPAdvSIMDEnabled64();
 bits(datasize) result;
 bits(datasize) operand1 = V[n];
 bits(datasize) operand2 = V[m];

 result = FPMul(operand1, operand2, FPCR);

 if negated then result = FPNeg(result);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRECPE','       Floating-point reciprocal estimate       (C7.3.127)


       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 1 sz 1 0 0 0 0 1 1 1 0 1 1 0                                  Rn             Rd




       Scalar variant

       FRECPE <V><d>, <V><n>


       Decode for this encoding

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

         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         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 0 0 1 1 1 0 1 sz 1 0 0 0 0 1 1 1 0 1 1 0                                  Rn             Rd




       Vector variant

       FRECPE <Vd>.<T>, <Vn>.<T>


       Decode for this encoding

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

         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0

                         4S          when sz = 0, Q = 1
              2D         when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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(esize) element;

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

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRECPS','       Floating-point reciprocal step       (C7.3.128)


       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 0 sz 1                   Rm         1 1 1 1 1 1               Rn             Rd




       Scalar variant

       FRECPS <V><d>, <V><n>, <V><m>


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         integer esize = 32 << UInt(sz);
         integer datasize = esize;
         integer elements = 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 0 sz 1                   Rm         1 1 1 1 1 1               Rn             Rd




       Vector variant

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


       Decode for this encoding

         integer d = UInt(Rd);
         integer n = UInt(Rn);
         integer m = UInt(Rm);
         if sz:Q == ''10'' then ReservedValue();
         integer esize = 32 << UInt(sz);
         integer datasize = if Q == ''1'' then 128 else 64;
         integer elements = datasize DIV esize;


       Assembler symbols

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

                         S           when sz = 0

                         D           when sz = 1

       <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 "sz:Q" field. It can have the following values:

                         2S          when sz = 0, Q = 0
              4S         when sz = 0, Q = 1

              2D         when sz = 1, Q = 1

              It is RESERVED when sz = 1, 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;
 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, esize] = FPRecipStepFused(element1, element2);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRECPX','Floating-point reciprocal exponent (scalar)       (C7.3.129)




    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 1 sz 1 0 0 0 0 1 1 1 1 1 1 0                                  Rn             Rd




Scalar variant

FRECPX <V><d>, <V><n>


Decode for this encoding

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

  integer esize = 32 << UInt(sz);
  integer datasize = esize;
  integer elements = 1;


Assembler symbols

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

                  S           when sz = 0

                  D           when sz = 1

<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.


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] = FPRecpX(element, FPCR);

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRINTA','Floating-point round to integral, to nearest with ties to away (vector)       (C7.3.130)




  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 sz 1 0 0 0 0 1 1 0 0 0 1 0                                  Rn             Rd
        U                  o2                                   o1


Vector variant

FRINTA <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean exact = FALSE;
 FPRounding rounding;
 case U:o1:o2 of
     when ''0xx'' rounding = FPDecodeRounding(o1:o2);
     when ''100'' rounding = FPRounding_TIEAWAY;
     when ''101'' UnallocatedEncoding();
     when ''110'' rounding = FPRoundingMode(FPCR); exact = TRUE;
     when ''111'' rounding = FPRoundingMode(FPCR);


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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1

                2D          when sz = 1, Q = 1

                It is RESERVED when sz = 1, Q = 0.

<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] = FPRoundInt(element, FPCR, rounding, exact);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRINTI','Floating-point round to integral, using current rounding mode (vector)       (C7.3.132)




  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 1 sz 1 0 0 0 0 1 1 0 0 1 1 0                                  Rn             Rd
        U                  o2                                 o1


Vector variant

FRINTI <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean exact = FALSE;
 FPRounding rounding;
 case U:o1:o2 of
     when ''0xx'' rounding = FPDecodeRounding(o1:o2);
     when ''100'' rounding = FPRounding_TIEAWAY;
     when ''101'' UnallocatedEncoding();
     when ''110'' rounding = FPRoundingMode(FPCR); exact = TRUE;
     when ''111'' rounding = FPRoundingMode(FPCR);


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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1

                2D          when sz = 1, Q = 1

                It is RESERVED when sz = 1, Q = 0.

<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] = FPRoundInt(element, FPCR, rounding, exact);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRINTM','Floating-point round to integral, toward minus infinity (vector)       (C7.3.134)




  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 0 sz 1 0 0 0 0 1 1 0 0 1 1 0                                  Rn             Rd
        U                  o2                                 o1


Vector variant

FRINTM <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean exact = FALSE;
 FPRounding rounding;
 case U:o1:o2 of
     when ''0xx'' rounding = FPDecodeRounding(o1:o2);
     when ''100'' rounding = FPRounding_TIEAWAY;
     when ''101'' UnallocatedEncoding();
     when ''110'' rounding = FPRoundingMode(FPCR); exact = TRUE;
     when ''111'' rounding = FPRoundingMode(FPCR);


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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1

                2D          when sz = 1, Q = 1

                It is RESERVED when sz = 1, Q = 0.

<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] = FPRoundInt(element, FPCR, rounding, exact);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRINTN','Floating-point round to integral, to nearest with ties to even (vector)       (C7.3.136)




  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 0 sz 1 0 0 0 0 1 1 0 0 0 1 0                                  Rn             Rd
        U                  o2                                   o1


Vector variant

FRINTN <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean exact = FALSE;
 FPRounding rounding;
 case U:o1:o2 of
     when ''0xx'' rounding = FPDecodeRounding(o1:o2);
     when ''100'' rounding = FPRounding_TIEAWAY;
     when ''101'' UnallocatedEncoding();
     when ''110'' rounding = FPRoundingMode(FPCR); exact = TRUE;
     when ''111'' rounding = FPRoundingMode(FPCR);


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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1

                2D          when sz = 1, Q = 1

                It is RESERVED when sz = 1, Q = 0.

<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] = FPRoundInt(element, FPCR, rounding, exact);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRINTP','Floating-point round to integral, toward positive infinity (vector)       (C7.3.138)




  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 1 sz 1 0 0 0 0 1 1 0 0 0 1 0                                  Rn             Rd
        U                  o2                                   o1


Vector variant

FRINTP <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean exact = FALSE;
 FPRounding rounding;
 case U:o1:o2 of
     when ''0xx'' rounding = FPDecodeRounding(o1:o2);
     when ''100'' rounding = FPRounding_TIEAWAY;
     when ''101'' UnallocatedEncoding();
     when ''110'' rounding = FPRoundingMode(FPCR); exact = TRUE;
     when ''111'' rounding = FPRoundingMode(FPCR);


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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1

                2D          when sz = 1, Q = 1

                It is RESERVED when sz = 1, Q = 0.

<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] = FPRoundInt(element, FPCR, rounding, exact);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRINTX','Floating-point round to integral exact, using current rounding mode (vector)       (C7.3.140)




  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 sz 1 0 0 0 0 1 1 0 0 1 1 0                                   Rn             Rd
        U                  o2                                 o1


Vector variant

FRINTX <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean exact = FALSE;
 FPRounding rounding;
 case U:o1:o2 of
     when ''0xx'' rounding = FPDecodeRounding(o1:o2);
     when ''100'' rounding = FPRounding_TIEAWAY;
     when ''101'' UnallocatedEncoding();
     when ''110'' rounding = FPRoundingMode(FPCR); exact = TRUE;
     when ''111'' rounding = FPRoundingMode(FPCR);


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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1

                2D          when sz = 1, Q = 1

                It is RESERVED when sz = 1, Q = 0.

<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] = FPRoundInt(element, FPCR, rounding, exact);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRINTZ','Floating-point round to integral, toward zero (vector)       (C7.3.142)




  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 1 sz 1 0 0 0 0 1 1 0 0 1 1 0                                  Rn             Rd
        U                  o2                                 o1


Vector variant

FRINTZ <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;

 boolean exact = FALSE;
 FPRounding rounding;
 case U:o1:o2 of
     when ''0xx'' rounding = FPDecodeRounding(o1:o2);
     when ''100'' rounding = FPRounding_TIEAWAY;
     when ''101'' UnallocatedEncoding();
     when ''110'' rounding = FPRoundingMode(FPCR); exact = TRUE;
     when ''111'' rounding = FPRoundingMode(FPCR);


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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1

                2D          when sz = 1, Q = 1

                It is RESERVED when sz = 1, Q = 0.

<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] = FPRoundInt(element, FPCR, rounding, exact);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRSQRTE','Floating-point reciprocal square root estimate       (C7.3.144)


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 1 sz 1 0 0 0 0 1 1 1 0 1 1 0                                   Rn             Rd




Scalar variant

FRSQRTE <V><d>, <V><n>


Decode for this encoding

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

 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 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 1 sz 1 0 0 0 0 1 1 1 0 1 1 0                                   Rn             Rd




Vector variant

FRSQRTE <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;


Assembler symbols

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

                S           when sz = 0

                D           when sz = 1

<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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0

                4S          when sz = 0, Q = 1
                         2D         when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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(esize) element;

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

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FRSQRTS','Floating-point reciprocal square root step       (C7.3.145)


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 1 sz 1                    Rm         1 1 1 1 1 1               Rn             Rd




Scalar variant

FRSQRTS <V><d>, <V><n>, <V><m>


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 integer esize = 32 << UInt(sz);
 integer datasize = esize;
 integer elements = 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 1 sz 1                    Rm         1 1 1 1 1 1               Rn             Rd




Vector variant

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


Decode for this encoding

 integer d = UInt(Rd);
 integer n = UInt(Rn);
 integer m = UInt(Rm);
 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;


Assembler symbols

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

                S           when sz = 0

                D           when sz = 1

<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 "sz:Q" field. It can have the following values:

                2S          when sz = 0, Q = 0
                         4S         when sz = 0, Q = 1

                         2D         when sz = 1, Q = 1

                         It is RESERVED when sz = 1, 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;
         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, esize] = FPRSqrtStepFused(element1, element2);

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FSQRT','Floating-point square root (vector)       (C7.3.146)




  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 1 sz 1 0 0 0 0 1 1 1 1 1 1 0                                 Rn             Rd




Vector variant

FSQRT <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

 if sz:Q == ''10'' then ReservedValue();
 integer esize = 32 << UInt(sz);
 integer datasize = if Q == ''1'' then 128 else 64;
 integer elements = datasize DIV esize;


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 "sz:Q" field. It can have the following values:

               2S           when sz = 0, Q = 0

               4S           when sz = 0, Q = 1

               2D           when sz = 1, Q = 1

               It is RESERVED when sz = 1, Q = 0.

<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] = FPSqrt(element, FPCR);

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','FSUB','Floating-point subtract (vector)       (C7.3.148)




    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 1 sz 1                  Rm         1 1 0 1 0 1              Rn              Rd
           U


Three registers of the same type variant

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


Decode for this encoding

  integer d = UInt(Rd);
  integer n = UInt(Rn);
  integer m = UInt(Rm);
  if sz:Q == ''10'' then ReservedValue();
  integer esize = 32 << UInt(sz);
  integer datasize = if Q == ''1'' then 128 else 64;
  integer elements = datasize DIV esize;
  boolean abs = (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 "sz:Q" field. It can have the following values:

                  2S          when sz = 0, Q = 0

                  4S          when sz = 0, Q = 1

                  2D          when sz = 1, Q = 1

                  It is RESERVED when sz = 1, 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;
  bits(esize) element1;
  bits(esize) element2;
  bits(esize) diff;

  for e = 0 to elements-1
       element1 = Elem[operand1, e, esize];
       element2 = Elem[operand2, e, esize];
       diff = FPSub(element1, element2, FPCR);
       Elem[result, e, esize] = if abs then FPAbs(diff) else diff;

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','INS','       Insert vector element from another vector element       (C7.3.150)

       This instruction is used by the alias MOV (element). The alias is always the preferred disassembly.




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




       Advanced SIMD variant

       INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]


       Decode for this encoding

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

         integer size = LowestSetBit(imm5);
         if size > 3 then UnallocatedEncoding();

         integer dst_index = UInt(imm5<4:size+1>);
         integer src_index = UInt(imm4<3:size>);
         integer idxdsize = if imm4<3> == ''1'' then 128 else 64;
         // imm4<size-1:0> is IGNORED

         integer esize = 8 << size;


       Assembler symbols

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

       <Ts>              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

                         D           when imm5 = x1000

                         It is RESERVED when imm5 = x0000.

       <index1>          Is the destination 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

                         imm5<4>     when imm5 = x1000

                         It is RESERVED when imm5 = x0000.

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

       <index2>          Is the source element index encoded in the "imm5:imm4" field. It can have the following values:

                         imm4<3:0>   when imm5 = xxxx1

                         imm4<3:1>   when imm5 = xxx10

                         imm4<3:2>   when imm5 = xx100

                         imm4<3>     when imm5 = x1000
              It is RESERVED when imm5 = x0000.

              Unspecified bits in "imm4" are ignored but should be set to zero by an assembler.


Operation

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

 result = V[d];
 Elem[result, dst_index, esize] = Elem[operand, src_index, esize];
 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','LD1','       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;');
INSERT INTO "instructions" VALUES('ARM','LD1R','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;');
INSERT INTO "instructions" VALUES('ARM','LD2','       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;');
INSERT INTO "instructions" VALUES('ARM','LD2R','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;');
INSERT INTO "instructions" VALUES('ARM','LD3','       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;');
INSERT INTO "instructions" VALUES('ARM','LD3R','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;');
INSERT INTO "instructions" VALUES('ARM','LD4','       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;');
INSERT INTO "instructions" VALUES('ARM','LD4R','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;');
INSERT INTO "instructions" VALUES('ARM','MLA','       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;');
INSERT INTO "instructions" VALUES('ARM','MLS','       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;');
INSERT INTO "instructions" VALUES('ARM','MOVI','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;');
INSERT INTO "instructions" VALUES('ARM','MVNI','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;');
INSERT INTO "instructions" VALUES('ARM','NOT','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;');
INSERT INTO "instructions" VALUES('ARM','PMUL','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;');
INSERT INTO "instructions" VALUES('ARM','PMULL','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;');
INSERT INTO "instructions" VALUES('ARM','PMULL2','-R:PMULL');
INSERT INTO "instructions" VALUES('ARM','RADDHN','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;');
INSERT INTO "instructions" VALUES('ARM','RADDHN2','-R:RADDHN');
INSERT INTO "instructions" VALUES('ARM','REV64','       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;');
INSERT INTO "instructions" VALUES('ARM','RSHRN','       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;');
INSERT INTO "instructions" VALUES('ARM','RSHRN2','-R:RSHRN');
INSERT INTO "instructions" VALUES('ARM','RSUBHN','       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;');
INSERT INTO "instructions" VALUES('ARM','RSUBHN2','-R:RSUBHN');
INSERT INTO "instructions" VALUES('ARM','SABA','      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;');
INSERT INTO "instructions" VALUES('ARM','SABAL','       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;');
INSERT INTO "instructions" VALUES('ARM','SABAL2','-R:SABAL');
INSERT INTO "instructions" VALUES('ARM','SABD','      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;');
INSERT INTO "instructions" VALUES('ARM','SABDL','       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;');
INSERT INTO "instructions" VALUES('ARM','SABDL2','-R:SABDL');
INSERT INTO "instructions" VALUES('ARM','SADALP','      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;');
INSERT INTO "instructions" VALUES('ARM','SADDL','       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;');
INSERT INTO "instructions" VALUES('ARM','SADDL2','-R:SADDL');
INSERT INTO "instructions" VALUES('ARM','SADDLP','      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;');
INSERT INTO "instructions" VALUES('ARM','SADDLV','      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>;');
INSERT INTO "instructions" VALUES('ARM','SADDW','       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;');
INSERT INTO "instructions" VALUES('ARM','SADDW2','-R:SADDW');
INSERT INTO "instructions" VALUES('ARM','SCVTF','       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;');
INSERT INTO "instructions" VALUES('ARM','SHA1C','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;');
INSERT INTO "instructions" VALUES('ARM','SHA1H','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);');
INSERT INTO "instructions" VALUES('ARM','SHA1M','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;');
INSERT INTO "instructions" VALUES('ARM','SHA1P','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;');
INSERT INTO "instructions" VALUES('ARM','SHA1SU0','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;');
INSERT INTO "instructions" VALUES('ARM','SHA1SU1','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;');
INSERT INTO "instructions" VALUES('ARM','SHA256H2','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;');
INSERT INTO "instructions" VALUES('ARM','SHA256H','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;');
INSERT INTO "instructions" VALUES('ARM','SHA256SU0','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;');
INSERT INTO "instructions" VALUES('ARM','SHA256SU1','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;');
INSERT INTO "instructions" VALUES('ARM','SHADD','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;');
INSERT INTO "instructions" VALUES('ARM','SHL','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;');
INSERT INTO "instructions" VALUES('ARM','SHLL','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;');
INSERT INTO "instructions" VALUES('ARM','SHLL2','-R:SHLL');
INSERT INTO "instructions" VALUES('ARM','SHRN','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;');
INSERT INTO "instructions" VALUES('ARM','SHRN2','-R:SHRN');
INSERT INTO "instructions" VALUES('ARM','SHSUB','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;');
INSERT INTO "instructions" VALUES('ARM','SLI','       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;');
INSERT INTO "instructions" VALUES('ARM','SMAX','      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;');
INSERT INTO "instructions" VALUES('ARM','SMAXP','      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;');
INSERT INTO "instructions" VALUES('ARM','SMAXV','      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>;');
INSERT INTO "instructions" VALUES('ARM','SMIN','      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;');
INSERT INTO "instructions" VALUES('ARM','SMINP','      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;');
INSERT INTO "instructions" VALUES('ARM','SMINV','      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>;');
INSERT INTO "instructions" VALUES('ARM','SMLAL','       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;');
INSERT INTO "instructions" VALUES('ARM','SMLAL2','-R:SMLAL');
INSERT INTO "instructions" VALUES('ARM','SMLSL','       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;');
INSERT INTO "instructions" VALUES('ARM','SMLSL2','-R:SMLSL');
INSERT INTO "instructions" VALUES('ARM','SMOV','       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);');
INSERT INTO "instructions" VALUES('ARM','SMULL2','       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;');
INSERT INTO "instructions" VALUES('ARM','SQABS','       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;');
INSERT INTO "instructions" VALUES('ARM','SQADD','       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;');
INSERT INTO "instructions" VALUES('ARM','SQDMLAL','       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;');
INSERT INTO "instructions" VALUES('ARM','SQDMLAL2','-R:SQDMLAL');
INSERT INTO "instructions" VALUES('ARM','SQDMLSL','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;');
INSERT INTO "instructions" VALUES('ARM','SQDMLSL2','-R:SQDMLSL');
INSERT INTO "instructions" VALUES('ARM','SQDMULH','       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;');
INSERT INTO "instructions" VALUES('ARM','SQDMULL','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;');
INSERT INTO "instructions" VALUES('ARM','SQDMULL2','-R:SQDMULL');
INSERT INTO "instructions" VALUES('ARM','SQNEG','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;');
INSERT INTO "instructions" VALUES('ARM','SQRDMULH','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;');
INSERT INTO "instructions" VALUES('ARM','SQRSHL','       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;');
INSERT INTO "instructions" VALUES('ARM','SQRSHRN','       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;');
INSERT INTO "instructions" VALUES('ARM','SQRSHRN2','-R:SQRSHRN');
INSERT INTO "instructions" VALUES('ARM','SQRSHRUN','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;');
INSERT INTO "instructions" VALUES('ARM','SQRSHRUN2','-R:SQRSHRUN');
INSERT INTO "instructions" VALUES('ARM','SQSHL','       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;');
INSERT INTO "instructions" VALUES('ARM','SQSHLU','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;');
INSERT INTO "instructions" VALUES('ARM','SQSHRN','       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;');
INSERT INTO "instructions" VALUES('ARM','SQSHRN2','-R:SQSHRN');
INSERT INTO "instructions" VALUES('ARM','SQSHRUN','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;');
INSERT INTO "instructions" VALUES('ARM','SQSHRUN2','-R:SQSHRUN');
INSERT INTO "instructions" VALUES('ARM','SQSUB','       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;');
INSERT INTO "instructions" VALUES('ARM','SQXTN','       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;');
INSERT INTO "instructions" VALUES('ARM','SQXTN2','-R:SQXTN');
INSERT INTO "instructions" VALUES('ARM','SQXTUN','       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;');
INSERT INTO "instructions" VALUES('ARM','SQXTUN2','-R:SQXTUN');
INSERT INTO "instructions" VALUES('ARM','SRHADD','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;');
INSERT INTO "instructions" VALUES('ARM','SRI','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;');
INSERT INTO "instructions" VALUES('ARM','SRSHL','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;');
INSERT INTO "instructions" VALUES('ARM','SRSHR','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;');
INSERT INTO "instructions" VALUES('ARM','SRSRA','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;');
INSERT INTO "instructions" VALUES('ARM','SSHL','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;');
INSERT INTO "instructions" VALUES('ARM','SSHLL','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;');
INSERT INTO "instructions" VALUES('ARM','SSHLL2','-R:SSHLL');
INSERT INTO "instructions" VALUES('ARM','SSHR','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;');
INSERT INTO "instructions" VALUES('ARM','SSRA','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;');
INSERT INTO "instructions" VALUES('ARM','SSUBL','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;');
INSERT INTO "instructions" VALUES('ARM','SSUBL2','-R:SSUBL');
INSERT INTO "instructions" VALUES('ARM','SSUBW','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;');
INSERT INTO "instructions" VALUES('ARM','SSUBW2','-R:SSUBW');
INSERT INTO "instructions" VALUES('ARM','ST1','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;');
INSERT INTO "instructions" VALUES('ARM','ST2','       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;');
INSERT INTO "instructions" VALUES('ARM','ST3','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;');
INSERT INTO "instructions" VALUES('ARM','ST4','       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;');
INSERT INTO "instructions" VALUES('ARM','SUBHN','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;');
INSERT INTO "instructions" VALUES('ARM','SUBHN2','-R:SUBHN');
INSERT INTO "instructions" VALUES('ARM','SUQADD','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;');
INSERT INTO "instructions" VALUES('ARM','SXTL','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.');
INSERT INTO "instructions" VALUES('ARM','TBL','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;');
INSERT INTO "instructions" VALUES('ARM','TBX','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;');
INSERT INTO "instructions" VALUES('ARM','TRN1','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;');
INSERT INTO "instructions" VALUES('ARM','TRN2','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;');
INSERT INTO "instructions" VALUES('ARM','UABA','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;');
INSERT INTO "instructions" VALUES('ARM','UABAL','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;');
INSERT INTO "instructions" VALUES('ARM','UABAL2','-R:UABAL');
INSERT INTO "instructions" VALUES('ARM','UABD','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;');
INSERT INTO "instructions" VALUES('ARM','UABDL','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;');
INSERT INTO "instructions" VALUES('ARM','UABDL2','-R:UABDL');
INSERT INTO "instructions" VALUES('ARM','UADALP','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;');
INSERT INTO "instructions" VALUES('ARM','UADDL','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;');
INSERT INTO "instructions" VALUES('ARM','UADDL2','-R:UADDL');
INSERT INTO "instructions" VALUES('ARM','UADDLP','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;');
INSERT INTO "instructions" VALUES('ARM','UADDLV','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>;');
INSERT INTO "instructions" VALUES('ARM','UADDW','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;');
INSERT INTO "instructions" VALUES('ARM','UADDW2','-R:UADDW');
INSERT INTO "instructions" VALUES('ARM','UCVTF','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;');
INSERT INTO "instructions" VALUES('ARM','UHADD','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;');
INSERT INTO "instructions" VALUES('ARM','UHSUB','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;');
INSERT INTO "instructions" VALUES('ARM','UMAX','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;');
INSERT INTO "instructions" VALUES('ARM','UMAXP','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;');
INSERT INTO "instructions" VALUES('ARM','UMAXV','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>;');
INSERT INTO "instructions" VALUES('ARM','UMIN','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;');
INSERT INTO "instructions" VALUES('ARM','UMINP','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;');
INSERT INTO "instructions" VALUES('ARM','UMINV','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>;');
INSERT INTO "instructions" VALUES('ARM','UMLAL','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;');
INSERT INTO "instructions" VALUES('ARM','UMLAL2','-R:UMLAL');
INSERT INTO "instructions" VALUES('ARM','UMLSL','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;');
INSERT INTO "instructions" VALUES('ARM','UMLSL2','-R:UMLSL');
INSERT INTO "instructions" VALUES('ARM','UMOV','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);');
INSERT INTO "instructions" VALUES('ARM','UMULL2','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;');
INSERT INTO "instructions" VALUES('ARM','UQADD','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;');
INSERT INTO "instructions" VALUES('ARM','UQRSHL','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;');
INSERT INTO "instructions" VALUES('ARM','UQRSHRN','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;');
INSERT INTO "instructions" VALUES('ARM','UQRSHRN2','-R:UQRSHRN');
INSERT INTO "instructions" VALUES('ARM','UQSHL','       Unsigned saturating shift left (immediate)       (C7.3.327)


       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 1 0 1           Rn     Rd
                  U                       immh                        op


       Scalar variant

       UQSHL <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 1 0 1           Rn     Rd
                  U                       immh                        op


       Vector variant

       UQSHL <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;');
INSERT INTO "instructions" VALUES('ARM','UQSHRN','Unsigned saturating shift right narrow (immediate)       (C7.3.329)


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 0 1              Rn             Rd
        U                         immh                           op


Scalar variant

UQSHRN <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 0 1              Rn             Rd
        U                         immh                           op


Vector variant

UQSHRN{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;');
INSERT INTO "instructions" VALUES('ARM','UQSUB','       Unsigned saturating subtract       (C7.3.330)


       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 1 0 1 1               Rn             Rd
                  U


       Scalar variant

       UQSUB <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 1 0 1 1               Rn             Rd
                  U


       Vector variant

       UQSUB <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;');
INSERT INTO "instructions" VALUES('ARM','UQXTN','       Unsigned saturating extract narrow       (C7.3.331)


       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 1 0 0 1 0                                   Rn               Rd
                  U


       Scalar variant

       UQXTN <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 1 0 1 1 1 0 size 1 0 0 0 0 1 0 1 0 0 1 0                                   Rn               Rd
                  U


       Vector variant

       UQXTN{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;');
INSERT INTO "instructions" VALUES('ARM','UQXTN2','-R:UQXTN');
INSERT INTO "instructions" VALUES('ARM','URECPE','Unsigned reciprocal estimate       (C7.3.332)




    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 1 sz 1 0 0 0 0 1 1 1 0 0 1 0                                Rn              Rd




Vector variant

URECPE <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

  if sz == ''1'' then ReservedValue();
  integer esize = 32;
  integer datasize = if Q == ''1'' then 128 else 64;
  integer elements = datasize DIV esize;


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 "sz:Q" field. It can have the following values:

                  2S          when sz = 0, Q = 0

                  4S          when sz = 0, Q = 1

                  It is RESERVED when sz = 1, 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;
  bits(32) element;

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

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','URHADD','Unsigned rounding halving add       (C7.3.333)




  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 1               Rn              Rd
        U


Three registers of the same type variant

URHADD <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;');
INSERT INTO "instructions" VALUES('ARM','URSHL','       Unsigned rounding shift left (register)       (C7.3.334)


       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 0 1               Rn             Rd
                  U                                                       R S


       Scalar variant

       URSHL <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 0 1               Rn             Rd
                  U                                                       R S


       Vector variant

       URSHL <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;');
INSERT INTO "instructions" VALUES('ARM','URSHR','       Unsigned rounding shift right (immediate)       (C7.3.335)


       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 0 1 0 0 1             Rn             Rd
                  U                         immh                    o1 o0


       Scalar variant

       URSHR <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 1 0 1 1 1 1 0              !=0000     immb      0 0 1 0 0 1             Rn             Rd
                  U                         immh                    o1 o0


       Vector variant

       URSHR <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;');
INSERT INTO "instructions" VALUES('ARM','URSQRTE','Unsigned reciprocal square root estimate       (C7.3.336)




    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 1 sz 1 0 0 0 0 1 1 1 0 0 1 0                                Rn              Rd




Vector variant

URSQRTE <Vd>.<T>, <Vn>.<T>


Decode for this encoding

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

  if sz == ''1'' then ReservedValue();
  integer esize = 32;
  integer datasize = if Q == ''1'' then 128 else 64;
  integer elements = datasize DIV esize;


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 "sz:Q" field. It can have the following values:

                  2S          when sz = 0, Q = 0

                  4S          when sz = 0, Q = 1

                  It is RESERVED when sz = 1, 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;
  bits(32) element;

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

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','URSRA','Unsigned rounding shift right and accumulate (immediate)       (C7.3.337)


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 0 1 1 0 1              Rn             Rd
        U                        immh                    o1 o0


Scalar variant

URSRA <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 1 0 1 1 1 1 0             !=0000     immb      0 0 1 1 0 1              Rn             Rd
        U                        immh                    o1 o0


Vector variant

URSRA <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;');
INSERT INTO "instructions" VALUES('ARM','USHL','Unsigned shift left (register)       (C7.3.338)


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 0 0 1               Rn             Rd
        U                                                       R S


Scalar variant

USHL <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 0 0 1               Rn             Rd
        U                                                       R S


Vector variant

USHL <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;');
INSERT INTO "instructions" VALUES('ARM','USHLL','Unsigned shift left long (immediate)       (C7.3.339)

This instruction is used by the alias UXTL. 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 1 0 1 1 1 1 0                !=0000     immb      1 0 1 0 0 1               Rn               Rd
         U                          immh


Vector variant

USHLL{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

                      UXTL                     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;');
INSERT INTO "instructions" VALUES('ARM','USHLL2','-R:USHLL');
INSERT INTO "instructions" VALUES('ARM','USHR','Unsigned shift right (immediate)       (C7.3.340)


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 0 0 0 0 1              Rn             Rd
        U                         immh                    o1 o0


Scalar variant

USHR <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 1 0 1 1 1 1 0              !=0000     immb      0 0 0 0 0 1              Rn             Rd
        U                         immh                    o1 o0


Vector variant

USHR <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;');
INSERT INTO "instructions" VALUES('ARM','USQADD','Unsigned saturating accumulate of signed value       (C7.3.341)


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 0 1 1 1 0                                 Rn             Rd
        U


Scalar variant

USQADD <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 1 0 1 1 1 0 size 1 0 0 0 0 0 0 0 1 1 1 0                                 Rn             Rd
        U


Vector variant

USQADD <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;');
INSERT INTO "instructions" VALUES('ARM','USRA','Unsigned shift right and accumulate (immediate)       (C7.3.342)


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 0 0 1 0 1              Rn             Rd
        U                         immh                    o1 o0


Scalar variant

USRA <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 1 0 1 1 1 1 0              !=0000     immb      0 0 0 1 0 1              Rn             Rd
        U                         immh                    o1 o0


Vector variant

USRA <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;');
INSERT INTO "instructions" VALUES('ARM','USUBL','Unsigned subtract long       (C7.3.343)




  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 0               Rn               Rd
        U                                                   o1


Three registers, not all the same type variant

USUBL{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;');
INSERT INTO "instructions" VALUES('ARM','USUBL2','-R:USUBL');
INSERT INTO "instructions" VALUES('ARM','USUBW','Unsigned subtract wide       (C7.3.344)




  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 1 0 0               Rn               Rd
        U                                                   o1


Three registers, not all the same type variant

USUBW{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;');
INSERT INTO "instructions" VALUES('ARM','USUBW2','-R:USUBW');
INSERT INTO "instructions" VALUES('ARM','UXTL','Unsigned extend long       (C7.3.345)

This instruction is an alias of the USHLL, USHLL2 instruction. This means that:

.      The encodings in this description are named to match the encodings of USHLL, USHLL2.

.      The description of USHLL, USHLL2 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 1 0 1 1 1 1 0               !=0000     0 0 0 1 0 1 0 0 1                   Rn               Rd
         U                          immh      immb


Vector variant

UXTL{2} <Vd>.<Ta>, <Vn>.<Tb>

is equivalent to

USHLL{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 USHLL, USHLL2 gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','UZP1','Unzip vectors (primary)       (C7.3.346)




  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 0 1 1 0               Rn              Rd
                                                       op


Advanced SIMD variant

UZP1 <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);


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) operandl = V[n];
 bits(datasize) operandh = V[m];
 bits(datasize) result;
 integer e;

 bits(datasize*2) zipped = operandh:operandl;
 for e = 0 to elements-1
     Elem[result, e, esize] = Elem[zipped, 2*e+part, esize];

 V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','UZP2','Unzip vectors (secondary)       (C7.3.347)




    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 0 1 1 0               Rn              Rd
                                                          op


Advanced SIMD variant

UZP2 <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);


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) operandl = V[n];
  bits(datasize) operandh = V[m];
  bits(datasize) result;
  integer e;

  bits(datasize*2) zipped = operandh:operandl;
  for e = 0 to elements-1
       Elem[result, e, esize] = Elem[zipped, 2*e+part, esize];

  V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','XTN','Extract narrow       (C7.3.348)




  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 0 1 0 1 0                                  Rn               Rd




Vector variant

XTN{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.
       Operation

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

         for e = 0 to elements-1
              element = Elem[operand, e, 2*esize];
              Elem[result, e, esize] = element<esize-1:0>;
         Vpart[d, part] = result;');
INSERT INTO "instructions" VALUES('ARM','XTN2','-R:XTN');
INSERT INTO "instructions" VALUES('ARM','ZIP1','Zip vectors (primary)       (C7.3.349)




  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 1 1 0               Rn              Rd
                                                        op


Advanced SIMD variant

ZIP1 <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 base = part * pairs;
 integer p;

 for p = 0 to pairs-1
     Elem[result, 2*p+0, esize] = Elem[operand1, base+p, esize];
              Elem[result, 2*p+1, esize] = Elem[operand2, base+p, esize];

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ZIP2','Zip vectors (secondary)       (C7.3.350)




  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 1 1 0               Rn              Rd
                                                       op


Advanced SIMD variant

ZIP2 <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 base = part * pairs;
 integer p;

 for p = 0 to pairs-1
     Elem[result, 2*p+0, esize] = Elem[operand1, base+p, esize];
              Elem[result, 2*p+1, esize] = Elem[operand2, base+p, esize];

         V[d] = result;');
INSERT INTO "instructions" VALUES('ARM','ASRS','Arithmetic Shift Right, setting flags (immediate) shifts a register value right by an immediate number of bits,       (F7.1.16)
shifting in copies of its sign bit, and writes the result to the destination register.

If the destination register is not the PC, this instruction updates the condition flags based on the result.

The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
deprecates any use of these encodings. However, when the destination register is the PC:

.      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

.      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from AArch32
       state on page G1-3845.

.      The instruction is UNDEFINED in Hyp mode.

.      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.

This instruction is an alias of the MOV, MOVS (register) instruction. This means that:

.      The encodings in this description are named to match the encodings of MOV, MOVS (register).

.      The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.


A1


  31        28 27 26 25 24 23 22 21 20 19 18 17 16 15              12 11             7 6 5 4 3           0
     !=1111     0 0 0 1 1 0 1 1 (0) (0) (0) (0)               Rd            imm5       1 0 0       Rm
      cond                              S                                              type


MOVS, shift or rotate by value variant

ASRS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

is equivalent to

MOVS{<c>}{<q>} <Rd>, <Rm>, ASR #<imm>

and is always the preferred disassembly.


T2


  15 14 13 12 11 10               6 5       3 2       0
   0 0 0 1 0            imm5            Rn        Rd
              op


T2 variant

ASRS{<q>} {<Rd>,} <Rm>, #<imm>// Outside IT block

is equivalent to

MOVS{<q>} <Rd>, <Rm>, ASR #<imm>

and is the preferred disassembly when !InITBlock().
        T3


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                  12 11           8 7 6 5 4 3                0
           1 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 (0) imm3                             Rd       imm2 1 0           Rm
                                              S                                                  type


        MOVS, shift or rotate by value variant

        ASRS.W {<Rd>,} <Rm>, #<imm>// Outside IT block, and <Rd>, <Rm>, <imm> can be represented in T2

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, ASR #<imm>

        and is always the preferred disassembly.

        ASRS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, ASR #<imm>

        and is always the preferred disassembly.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
                        deprecates using the PC as the destination register, but if the PC is used, the instruction performs an
                        exception return, that restores PSTATE from SPSR_<current_mode>.

                        For encoding T2 and T3: is the general-purpose destination register, encoded in the "Rd" field.

        <Rm>            For encoding A1: is the general-purpose source register, encoded in the "Rm" field. The PC can be
                        used.

                        For encoding T2 and T3: is the general-purpose source register, encoded in the "Rm" field.

        <imm>           For encoding A1 and T2: is the shift amount, in the range 1 to 32, encoded in the "imm5" field as
                        <imm> modulo 32.

                        For encoding T3: is the shift amount, in the range 1 to 32, encoded in the "imm3:imm2" field as
                        <imm> modulo 32.


        Operation for all encodings

        The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','BFC','        Bit Field Clear clears any number of adjacent bits at any position in a register, without affecting the other bits in the       (F7.1.19)
        register.


        A1


          31        28 27 26 25 24 23 22 21 20             16 15         12 11             7 6 5 4 3 2 1 0
             !=1111     0 1 1 1 1 1 0               msb            Rd               lsb        0 0 1 1 1 1 1
              cond


        A1 variant

        BFC{<c>}{<q>} <Rd>, #<lsb>, #<width>


        Decode for this encoding

         d = UInt(Rd);    msbit = UInt(msb);    lsbit = UInt(lsb);
         if d == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                    12 11          8 7 6 5 4                   0
           1 1 1 1 0 (0) 1 1 0 1 1 0 1 1 1 1 0                      imm3          Rd      imm2 (0)         msb




        T1 variant

        BFC{<c>}{<q>} <Rd>, #<lsb>, #<width>


        Decode for this encoding

         d = UInt(Rd);    msbit = UInt(msb);    lsbit = UInt(imm3:imm2);
         if d == 15 then UNPREDICTABLE;     // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly BFC on page J1-5332.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

        <lsb>           For encoding A1: is the least significant bit to be cleared, in the range 0 to 31, encoded in the "lsb"
                        field.

                        For encoding T1: is the least significant bit that is to be cleared, in the range 0 to 31, encoded in the
                        "imm3:imm2" field.

        <width>         Is the number of bits to be cleared, in the range 1 to 32-<lsb>, encoded in the "msb" field as
                        <lsb>+<width>-1.
Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    if msbit >= lsbit then
        R[d]<msbit:lsbit> = Replicate(''0'', msbit-lsbit+1);
        // Other bits of R[d] are unchanged
    else
        UNPREDICTABLE;');
INSERT INTO "instructions" VALUES('ARM','BKPT','Breakpoint causes a Software Breakpoint Instruction exception.       (F7.1.24)

Breakpoint is always unconditional, even when inside an IT block.


A1


  31       28 27 26 25 24 23 22 21 20 19                                    8 7 6 5 4 3              0
     !=1111    0 0 0 1 0 0 1 0                         imm12                   0 1 1 1        imm4
      cond


A1 variant

BKPT{<q>} {#}<imm>


Decode for this encoding

 imm16 = imm12:imm4;
 if cond != ''1110'' then UNPREDICTABLE;     // BKPT must be encoded with AL condition


T1


  15 14 13 12 11 10 9 8 7                        0
  1 0 1 1 1 1 1 0                   imm8




T1 variant

BKPT{<q>} {#}<imm>


Decode for this encoding

 imm16 = ZeroExtend(imm8, 16);


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly BKPT on page J1-5332.


Assembler symbols

<q>            See Standard assembler syntax fields on page F2-2506. An BKPT instruction must be unconditional.

<imm>          For encoding A1: is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the
               "imm12:imm4" field. The PE:

               .     Records this value in the Comment field of ESR_ELx.ISS if the Software Breakpoint
                     Instruction exception is taken to an exception level that is using AArch64.

               .     Ignores this value otherwise.

               For encoding T1: is a 8-bit unsigned immediate, in the range 0 to 255, encoded in the "imm8" field.
               The PE:

               .     Records this value in the Comment field of ESR_ELx.ISS if the Software Breakpoint
                     Instruction exception is taken to an exception level that is using AArch64.

               .     Ignores this value otherwise.
        Operation for all encodings

         EncodingSpecificOperations();
         AArch32.SoftwareBreakpoint(imm16);');
INSERT INTO "instructions" VALUES('ARM','BLX','Branch with Link calls a subroutine at a PC-relative address.       (F7.1.25)

Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine at a PC-relative address, and
changes instruction set from A32 to T32, or from T32 to A32.


A1


  31       28 27 26 25 24 23                                                                         0
    !=1111    1 0 1 1                                        imm24
     cond


A1 variant

BL{<c>}{<q>} <label>


Decode for this encoding

 imm32 = SignExtend(imm24:''00'', 32);     targetInstrSet = InstrSet_A32;


A2


  31       28 27 26 25 24 23                                                                         0
  1 1 1 1 1 0 1 H                                            imm24
     cond


A2 variant

BLX{<c>}{<q>} <label>


Decode for this encoding

 imm32 = SignExtend(imm24:H:''0'', 32);     targetInstrSet = InstrSet_T32;


T1


  15 14 13 12 11 10 9                             0 15 14 13 12 11 10                                0
  1 1 1 1 0 S                   imm10                1 1 J1 1 J2                   imm11




T1 variant

BL{<c>}{<q>} <label>


Decode for this encoding

 I1 = NOT(J1 EOR S);    I2 = NOT(J2 EOR S);   imm32 = SignExtend(S:I1:I2:imm10:imm11:''0'', 32);
 targetInstrSet = CurrentInstrSet();
 if InITBlock() && !LastInITBlock() then UNPREDICTABLE;


T2


  15 14 13 12 11 10 9                             0 15 14 13 12 11 10                                0
  1 1 1 1 0 S                  imm10H                1 1 J1 0 J2                  imm10L             H
        T2 variant

        BLX{<c>}{<q>} <label>


        Decode for this encoding

         if H == ''1'' then UNDEFINED;
         I1 = NOT(J1 EOR S);   I2 = NOT(J2 EOR S);     imm32 = SignExtend(S:I1:I2:imm10H:imm10L:''00'', 32);
         targetInstrSet = InstrSet_A32;
         if InITBlock() && !LastInITBlock() then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
        UNPREDICTABLE behaviors.


        Assembler symbols

        <c>            For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

                       For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <label>        For encoding A1: the label of the instruction that is to be branched to. The assembler calculates the
                       required value of the offset from the PC value of the BL instruction to this label, then selects an
                       encoding that sets imm32 to that offset. Permitted offsets are multiples of 4 in the range 33554432 to 33554428.

                       For encoding A2: the label of the instruction that is to be branched to. The assembler calculates the
                       required value of the offset from the PC value of the BLX instruction to this label, then selects an
                       encoding with imm32 set to that offset. Permitted offsets are even numbers in the range 33554432
                       to 33554430.

                       For encoding T1: the label of the instruction that is to be branched to. The assembler calculates the
                       required value of the offset from the PC value of the BL instruction to this label, then selects an
                       encoding with imm32 set to that offset. Permitted offsets are even numbers in the range 16777216
                       to 16777214.

                       For encoding T2: the label of the instruction that is to be branched to. The assembler calculates the
                       required value of the offset from the Align(PC, 4) value of the BLX instruction to this label, then
                       selects an encoding with imm32 set to that offset. Permitted offsets are multiples of 4 in the range
                       16777216 to 16777212.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             if CurrentInstrSet() == InstrSet_A32 then
                 LR = PC - 4;
             else
                 LR = PC<31:1> : ''1'';
             if targetInstrSet == InstrSet_A32 then
                 targetAddress = Align(PC,4) + imm32;
             else
                 targetAddress = PC + imm32;
             SelectInstrSet(targetInstrSet);
             BranchWritePC(targetAddress);');
INSERT INTO "instructions" VALUES('ARM','BX','Branch and Exchange causes a branch to an address and instruction set specified by a register.       (F7.1.27)


A1


  31       28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3                  0
     !=1111   0 0 0 1 0 0 1 0 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) 0 0 0 1         Rm
      cond


A1 variant

BX{<c>}{<q>} <Rm>


Decode for this encoding

 m = UInt(Rm);


T1


  15 14 13 12 11 10 9 8 7 6           3 2 1 0
  0 1 0 0 0 1 1 1 0              Rm     (0) (0) (0)




T1 variant

BX{<c>}{<q>} <Rm>


Decode for this encoding

 m = UInt(Rm);
 if InITBlock() && !LastInITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rm>          For encoding A1: is the general-purpose register holding the address to be branched to, encoded in
              the "Rm" field. The SP can be used, but this is deprecated. The PC can be used.

              For encoding T1: is the general-purpose register holding the address to be branched to, encoded in
              the "Rm" field. The SP can be used, but this is deprecated. The PC can be used. Note: If <Rm> is the
              PC at a non word-aligned address, it results in UNPREDICTABLE behavior because the address passed
              to the BXWritePC() pseudocode function has bits<1:0> = ''10''.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     BXWritePC(R[m]);');
INSERT INTO "instructions" VALUES('ARM','BXJ','Branch and Exchange, previously Branch and Exchange Jazelle.       (F7.1.28)

In ARMv8, BXJ behaves as a BX instruction, see BX. This means it causes a branch to an address and instruction set
specified by a register.


A1


  31       28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3                           0
     !=1111     0 0 0 1 0 0 1 0 (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) 0 0 1 0              Rm
      cond


A1 variant

BXJ{<c>}{<q>} <Rm>


Decode for this encoding

 m = UInt(Rm);
 if m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 1 0 0 1 1 1 1 0 0                    Rn      1 0 (0) 0 (1) (1) (1) (1) (0) (0) (0) (0) (0) (0) (0) (0)




T1 variant

BXJ{<c>}{<q>} <Rm>


Decode for this encoding

 m = UInt(Rm);
 if m == 15 then UNPREDICTABLE;     // ARMv8-A removes UNPREDICTABLE for R13
 if InITBlock() && !LastInITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rm>            Is the general-purpose register holding the address to be branched to, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     BXWritePC(R[m]);');
INSERT INTO "instructions" VALUES('ARM','CDP','        Coprocessor Data Processing is a generic coprocessor instruction. The coproc field identifies the target conceptual       (F7.1.30)
        coprocessor. This must be one of CP10, CP11, CP14, or CP15, and for these CP values, this manual defines the opc1,
        opc2, CRd, CRn, and CRm field values that are valid CDP and CDP2 instructions. Other encodings are UNDEFINED. For more
        information see Conceptual coprocessor support on page E1-2414 and General behavior of System registers on
        page G4-4172.


        A1


          31        28 27 26 25 24 23           20 19         16 15        12 11         8 7      5 4 3          0
             !=1111      1 1 1 0         opc1           CRn          CRd          !=101x      opc2   0      CRm
              cond                                                                coproc


        A1 variant

        CDP{<c>}{<q>} <coproc>, {#}<opc1>, <CRd>, <CRn>, <CRm> {, {#}<opc2>}


        Decode for this encoding

         if coproc == ''101x'' then SEE "Floating-point instructions";
         cp = UInt(coproc);


        A2


          31        28 27 26 25 24 23           20 19         16 15        12 11         8 7      5 4 3          0
           1 1 1 1 1 1 1 0               opc1           CRn          CRd          !=101x      opc2   0      CRm
              cond                                                                coproc


        A2 variant

        CDP2{<c>}{<q>} <coproc>, {#}<opc1>, <CRd>, <CRn>, <CRm> {, {#}<opc2>}


        Decode for this encoding

         if coproc == ''101x'' then SEE "Floating-point instructions";
         cp = UInt(coproc);


        T1


          15 14 13 12 11 10 9 8 7                4 3           0 15        12 11         8 7      5 4 3          0
           1 1 1 0 1 1 1 0               opc1           CRn          CRd          !=101x      opc2   0      CRm
                                                                                  coproc


        T1 variant

        CDP{<c>}{<q>} <coproc>, {#}<opc1>, <CRd>, <CRn>, <CRm> {, {#}<opc2>}


        Decode for this encoding

         if coproc == ''101x'' then SEE "Floating-point instructions";
         cp = UInt(coproc);
T2


  15 14 13 12 11 10 9 8 7             4 3          0 15          12 11        8 7       5 4 3          0
  1 1 1 1 1 1 1 0               opc1         CRn          CRd          !=101x      opc2    0    CRm
                                                                       coproc


T2 variant

CDP2{<c>}{<q>} <coproc>, {#}<opc1>, <CRd>, <CRn>, <CRm> {, {#}<opc2>}


Decode for this encoding

 if coproc == ''101x'' then SEE "Floating-point instructions";
 cp = UInt(coproc);


Notes for all encodings

Floating-point instructions: Floating-point data-processing instructions on page F5-2599.


Assembler symbols

<c>             For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

                For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

<q>             See Standard assembler syntax fields on page F2-2506.

<coproc>        Is the name of the coprocessor, encoded in the "coproc" field. The valid coprocessor names are p10,
                p11, p14, and p15.

<opc1>          Is a coprocessor-specific opcode, in the range 0 to 15, encoded in the "opc1" field.

<CRd>           Is the destination coprocessor register, encoded in the "CRd" field.

<CRn>           Is the coprocessor register that contains the first operand, encoded in the "CRn" field.

<CRm>           Is the coprocessor register that contains the second operand, encoded in the "CRm" field.

<opc2>          Is a coprocessor-specific opcode in the range 0 to 7, defaulting to 0 and encoded in the "opc2" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     Coproc_CheckInstr(cp, ThisInstr());
     Coproc_InternalOperation(cp, ThisInstr());');
INSERT INTO "instructions" VALUES('ARM','CDP2','-R:CDP');
INSERT INTO "instructions" VALUES('ARM','CPS','Change PE State changes one or more of the PSTATE.{A, I, F} interrupt mask bits and, optionally, the PSTATE.M       (F7.1.39)
mode field, without changing any other PSTATE bits.

CPS is treated as NOP if executed in User mode unless it is defined as being CONSTRAINED UNPREDICTABLE elsewhere
in this section.

The PE checks whether the value being written to PSTATE.M is legal. See Illegal changes to PSTATE.M on
page G1-3822.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4                         0
   1 1 1 1 0 0 0 1 0 0 0 0 imod M 0 (0) (0) (0) (0) (0) (0) (0) A I F 0                        mode




CPS variant

Applies when imod = 00 && M = 1.

CPS{<q>} #<mode>// Cannot be conditional


CPSID variant

Applies when imod = 11 && M = 0.

CPSID{<q>} <iflags>// Cannot be conditional


CPSID variant

Applies when imod = 11 && M = 1.

CPSID{<q>} <iflags> , #<mode>// Cannot be conditional


CPSIE variant

Applies when imod = 10 && M = 0.

CPSIE{<q>} <iflags>// Cannot be conditional


CPSIE variant

Applies when imod = 10 && M = 1.

CPSIE{<q>} <iflags> , #<mode>// Cannot be conditional


Decode for all variants of this encoding

 if mode != ''00000'' && M == ''0'' then UNPREDICTABLE;
 if (imod<1> == ''1'' && A:I:F == ''000'') || (imod<1> == ''0'' && A:I:F != ''000'') then UNPREDICTABLE;
 enable = (imod == ''10'');      disable = (imod == ''11'');      changemode = (M == ''1'');
 affectA = (A == ''1'');      affectI = (I == ''1'');   affectF = (F == ''1'');
 if (imod == ''00'' && M == ''0'') || imod == ''01'' then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
   1 0 1 1 0 1 1 0 0 1 1 im (0) A I F
        CPSID variant

        Applies when im = 1.

        CPSID{<q>} <iflags>// Not permitted in IT block


        CPSIE variant

        Applies when im = 0.

        CPSIE{<q>} <iflags>// Not permitted in IT block


        Decode for all variants of this encoding

         if A:I:F == ''000'' then UNPREDICTABLE;
         enable = (im == ''0'');   disable = (im == ''1'');     changemode = FALSE;
         affectA = (A == ''1'');   affectI = (I == ''1'');    affectF = (F == ''1'');
         if InITBlock() then UNPREDICTABLE;


        T2


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 7 6 5 4                        0
           1 1 1 1 0 0 1 1 1 0 1 0 (1) (1) (1) (1) 1 0 (0) 0 (0) imod M A I F                mode




        CPS variant

        Applies when imod = 00 && M = 1.

        CPS{<q>} #<mode>// Not permitted in IT block


        CPSID variant

        Applies when imod = 11 && M = 0.

        CPSID.W <iflags>// Not permitted in IT block


        CPSID variant

        Applies when imod = 11 && M = 1.

        CPSID{<q>} <iflags>, #<mode>// Not permitted in IT block


        CPSIE variant

        Applies when imod = 10 && M = 0.

        CPSIE.W <iflags>// Not permitted in IT block


        CPSIE variant

        Applies when imod = 10 && M = 1.

        CPSIE{<q>} <iflags>, #<mode>// Not permitted in IT block


        Decode for all variants of this encoding

         if imod == ''00'' && M == ''0'' then SEE "Hint instructions";
         if mode != ''00000'' && M == ''0'' then UNPREDICTABLE;
         if (imod<1> == ''1'' && A:I:F == ''000'') || (imod<1> == ''0'' && A:I:F != ''000'') then UNPREDICTABLE;
         enable = (imod == ''10'');    disable = (imod == ''11'');    changemode = (M == ''1'');
         affectA = (A == ''1'');   affectI = (I == ''1'');    affectF = (F == ''1'');
         if imod == ''01'' || InITBlock() then UNPREDICTABLE;
Notes for all encodings

Hint instructions: In encoding T2, if the imod field is 00 and the M bit is 0, a hint instruction is encoded. To determine
which hint instruction, see Change PE State, and hints on page F3-2534.

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly CPS (T32) on page J1-5378 and CPS
(A32) on page J1-5377.


Assembler symbols

<q>             See Standard assembler syntax fields on page F2-2506.

<iflags>        Is a sequence of one or more of the following, specifying which interrupt mask bits are affected:

                a           Sets the A bit in the instruction, causing the specified effect on PSTATE.A, the
                            asynchronous abort mask bit.

                i           Sets the I bit in the instruction, causing the specified effect on PSTATE.I, the IRQ
                            interrupt mask bit.

                f           Sets the F bit in the instruction, causing the specified effect on PSTATE.F, the FIQ
                            interrupt mask bit.

<mode>          Is the number of the mode to change to, in the range 0 to 31, encoded in the "mode" field.


Operation for all encodings

 if CurrentInstrSet() == InstrSet_A32 then
     EncodingSpecificOperations();
     if PSTATE.EL != EL0 then
          if enable then
              if affectA then PSTATE.A = ''0'';
              if affectI then PSTATE.I = ''0'';
              if affectF then PSTATE.F = ''0'';
          if disable then
              if affectA then PSTATE.A = ''1'';
              if affectI then PSTATE.I = ''1'';
              if affectF then PSTATE.F = ''1'';
          if changemode then
              // WriteMode will set PSTATE.IL if ''mode'' is not legal.
              AArch32.WriteMode(mode);
 else
     EncodingSpecificOperations();
     if PSTATE.EL != EL0 then
          if enable then
              if affectA then PSTATE.A = ''0'';
              if affectI then PSTATE.I = ''0'';
              if affectF then PSTATE.F = ''0'';
          if disable then
              if affectA then PSTATE.A = ''1'';
              if affectI then PSTATE.I = ''1'';
              if affectF then PSTATE.F = ''1'';
          if changemode then
              // WriteMode will set PSTATE.IL if ''mode'' is not legal.
              AArch32.WriteMode(mode);');
INSERT INTO "instructions" VALUES('ARM','CPSID','-R:CPS');
INSERT INTO "instructions" VALUES('ARM','CPSIE','-R:CPS');
INSERT INTO "instructions" VALUES('ARM','CRC32','        CRC32 performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It is an       (F7.1.40)
        OPTIONAL instruction. It takes an input CRC value in the first source operand, and performs a CRC on an input value
        in the second source operand that can be 8, 16, or 32 bits, and returns the output CRC value. To align with common
        usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x04C11DB7 is used for the
        CRC calculation.

                 Note
        ID_ISAR5.CRC32 indicates whether this instruction is supported in the T32 and A32 instruction sets.



        A1


          31       28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                 0
             !=1111     0 0 0 1 0        sz     0      Rn           Rd       (0) (0) 0 (0) 0 1 0 0       Rm
              cond                                                                  C


        CRC32B variant

        Applies when sz = 00.

        CRC32B{<q>} <Rd>, <Rn>, <Rm>


        CRC32H variant

        Applies when sz = 01.

        CRC32H{<q>} <Rd>, <Rn>, <Rm>


        CRC32W variant

        Applies when sz = 10.

        CRC32W{<q>} <Rd>, <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd); n = UInt(Rn); m = UInt(Rm);
         size = 8 << UInt(sz);
         crc32c = (C == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         if size == 64 then UNPREDICTABLE;
         if cond != ''1110'' then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11            8 7 6 5 4 3             0
           1 1 1 1 1 0 1 0 1 1 0 0                     Rn       1 1 1 1           Rd       1 0  sz       Rm
                                                C


        CRC32B variant

        Applies when sz = 00.

        CRC32B{<q>} <Rd>, <Rn>, <Rm>


        CRC32H variant

        Applies when sz = 01.
CRC32H{<q>} <Rd>, <Rn>, <Rm>


CRC32W variant

Applies when sz = 10.

CRC32W{<q>} <Rd>, <Rn>, <Rm>


Decode for all variants of this encoding

 d = UInt(Rd); n = UInt(Rn); m = UInt(Rm);
 size = 8 << UInt(sz);
 crc32c = (C == ''1'');
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 if size == 64 then UNPREDICTABLE;
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors, and particularly CRC32, CRC32C on page J1-5333.


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506. An CRC32 instruction must be unconditional.

<Rd>          Is the general-purpose accumulator output register, encoded in the "Rd" field.

<Rn>          Is the general-purpose accumulator input register, encoded in the "Rn" field.

<Rm>          Is the general-purpose data source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();

     if !HaveCRCExt() then
         UNDEFINED;

     acc = R[n];              // accumulator
     val = R[m]<size-1:0>;    // input value
     poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)<31:0>;
     tempacc = BitReverse(acc):Zeros(size);
     tempval = BitReverse(val):Zeros(32);
     // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation
     R[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly));');
INSERT INTO "instructions" VALUES('ARM','CRC32C','        CRC32C performs a cyclic redundancy check (CRC) calculation on a value held in a general-purpose register. It is an       (F7.1.41)
        OPTIONAL instruction. It takes an input CRC value in the first source operand, and performs a CRC on an input value
        in the second source operand that can be 8, 16, or 32 bits, and returns the output CRC value. To align with common
        usage, the bit order of the values is reversed as part of the operation, and the polynomial 0x1EDC6F41 is used for the
        CRC calculation.

                 Note
        ID_ISAR5.CRC32 indicates whether this instruction is supported in the T32 and A32 instruction sets.



        A1


          31       28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                 0
             !=1111     0 0 0 1 0        sz     0      Rn           Rd       (0) (0) 1 (0) 0 1 0 0       Rm
              cond                                                                  C


        CRC32CB variant

        Applies when sz = 00.

        CRC32CB{<q>} <Rd>, <Rn>, <Rm>


        CRC32CH variant

        Applies when sz = 01.

        CRC32CH{<q>} <Rd>, <Rn>, <Rm>


        CRC32CW variant

        Applies when sz = 10.

        CRC32CW{<q>} <Rd>, <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd); n = UInt(Rn); m = UInt(Rm);
         size = 8 << UInt(sz);
         crc32c = (C == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         if size == 64 then UNPREDICTABLE;
         if cond != ''1110'' then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11            8 7 6 5 4 3             0
           1 1 1 1 1 0 1 0 1 1 0 1                     Rn       1 1 1 1           Rd       1 0  sz       Rm
                                                C


        CRC32CB variant

        Applies when sz = 00.

        CRC32CB{<q>} <Rd>, <Rn>, <Rm>


        CRC32CH variant

        Applies when sz = 01.
CRC32CH{<q>} <Rd>, <Rn>, <Rm>


CRC32CW variant

Applies when sz = 10.

CRC32CW{<q>} <Rd>, <Rn>, <Rm>


Decode for all variants of this encoding

 d = UInt(Rd); n = UInt(Rn); m = UInt(Rm);
 size = 8 << UInt(sz);
 crc32c = (C == ''1'');
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 if size == 64 then UNPREDICTABLE;
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors, and particularly CRC32, CRC32C on page J1-5333.


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506. An CRC32C instruction must be
              unconditional.

<Rd>          Is the general-purpose accumulator output register, encoded in the "Rd" field.

<Rn>          Is the general-purpose accumulator input register, encoded in the "Rn" field.

<Rm>          Is the general-purpose data source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();

     if !HaveCRCExt() then
         UNDEFINED;

     acc = R[n];              // accumulator
     val = R[m]<size-1:0>;    // input value
     poly = (if crc32c then 0x1EDC6F41 else 0x04C11DB7)<31:0>;
     tempacc = BitReverse(acc):Zeros(size);
     tempval = BitReverse(val):Zeros(32);
     // Poly32Mod2 on a bitstring does a polynomial Modulus over {0,1} operation
     R[d] = BitReverse(Poly32Mod2(tempacc EOR tempval, poly));');
INSERT INTO "instructions" VALUES('ARM','DBG','Debug Hint provides a hint to debug and related systems. See the system documentation for what use (if any) is       (F7.1.42)
made of this instruction.


A1


  31       28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3                   0
     !=1111    0 0 1 1 0 0 1 0 0 0 0 0 (1) (1) (1) (1) (0) (0) (0) (0) 1 1 1 1                option
      cond


A1 variant

DBG{<c>}{<q>} #<option>


Decode for this encoding

 // Any decoding of ''option'' is specified by the debug system


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 7 6 5 4 3                             0
   1 1 1 1 0 0 1 1 1 0 1 0 (1) (1) (1) (1) 1 0 (0) 0 (0) 0 0 0 1 1 1 1                        option




T1 variant

DBG{<c>}{<q>} #<option>


Decode for this encoding

 // Any decoding of ''option'' is specified by the debug system


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<option>       Is a 4-bit unsigned immediate, in the range 0 to 15, encoded in the "option" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     Hint_Debug(option);');
INSERT INTO "instructions" VALUES('ARM','EORS','        Bitwise Exclusive OR (immediate) performs a bitwise Exclusive OR of a register value and an immediate value,       (F7.1.46)
        and writes the result to the destination register.

        If the destination register is not the PC, the EORS variant of the instruction updates the condition flags based on the
        result.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The EOR variant of the instruction is an interworking branch, see Pseudocode description of operations on
               the AArch32 general-purpose registers and the PC on page E1-2378.

        .      The EORS variant of the instruction performs an exception return without the use of the stack. In this case:

               --      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

               --      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from
                      AArch32 state on page G1-3845.

               --      The instruction is UNDEFINED in Hyp mode.

               --      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.


        A1


           31       28 27 26 25 24 23 22 21 20 19           16 15        12 11                                   0
             !=1111     0 0 1 0 0 0 1 S                 Rn          Rd                      imm12
              cond


        EOR variant

        Applies when S = 0.

        EOR{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        EORS variant

        Applies when S = 1.

        EORS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        Decode for all variants of this encoding

         d = UInt(Rd);     n = UInt(Rn);     setflags = (S == ''1'');
         (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14      12 11         8 7                       0
           1 1 1 1 0 i 0 0 1 0 0 S                      Rn       0   imm3        Rd                 imm8




        EOR variant

        Applies when S = 0.

        EOR{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        EORS variant

        Applies when S = 1 && Rd != 1111.
EORS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


Decode for all variants of this encoding

 if Rd == ''1111'' && S == ''1'' then SEE TEQ (immediate);
 d = UInt(Rd);  n = UInt(Rn);     setflags = (S == ''1'');
 (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C);
 if (d == 15 && !setflags) || n == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. If omitted,
              this register is the same as <Rn>. ARM deprecates using the PC as the destination register, but if the
              PC is used:

              .      For the EOR variant, the instruction is a branch to the address calculated by the operation.
                     This is an interworking branch, see Pseudocode description of operations on the AArch32
                     general-purpose registers and the PC on page E1-2378.

              .      For the EORS variant, the instruction performs an exception return, that restores PSTATE
                     from SPSR_<current_mode>.

              For encoding T1: is the general-purpose destination register, encoded in the "Rd" field. If omitted,
              this register is the same as <Rn>.

<Rn>          For encoding A1: is the general-purpose source register, encoded in the "Rn" field. The PC can be
              used.

              For encoding T1: is the general-purpose source register, encoded in the "Rn" field.

<const>       For encoding A1: an immediate value. See Modified immediate constants in A32 instructions on
              page F4-2559 for the range of values.

              For encoding T1: an immediate value. See Modified immediate constants in T32 instructions on
              page F3-2530 for the range of values.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     result = R[n] EOR imm32;
     if d == 15 then             // Can only occur for A32 encoding
         if setflags then
             ALUExceptionReturn(result);
         else
             ALUWritePC(result);
     else
         R[d] = result;
         if setflags then
             PSTATE.N = result<31>;
             PSTATE.Z = IsZeroBit(result);
             PSTATE.C = carry;
             // PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','IT','If-Then makes up to four following instructions (the IT block) conditional. The conditions for the instructions in the       (F7.1.53)
IT block are the same as, or the inverse of, the condition the IT instruction specifies for the first instruction in the
block.

The IT instruction itself does not affect the condition flags, but the execution of the instructions in the IT block can
change the condition flags.

16-bit instructions in the IT block, other than CMP, CMN and TST, do not set the condition flags. An IT instruction with
the AL condition can change the behavior without conditional execution.

The architecture permits exception return to an instruction in the IT block only if the restoration of the CPSR
restores ITSTATE to a state consistent with the conditions specified by the IT instruction. Any other exception
return to an instruction in an IT block is UNPREDICTABLE. Any branch to a target instruction in an IT block is not
permitted, and if such a branch is made it is UNPREDICTABLE what condition is used when executing that target
instruction and any subsequent instruction in the IT block.

See also Conditional instructions on page F1-2469 and Conditional execution on page F2-2507.


T1


  15 14 13 12 11 10 9 8 7                4 3           0
   1 0 1 1 1 1 1 1              firstcond       !=0000
                                                 mask


T1 variant

IT{<x>{<y>{<z>}}}{<q>} <cond>


Decode for this encoding

 if mask == ''0000'' then SEE "Related encodings";
 if firstcond == ''1111'' || (firstcond == ''1110'' && BitCount(mask) != 1) then UNPREDICTABLE;
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly IT on page J1-5334.

Related encodings: If-Then, and hints on page F3-2527.


Assembler symbols

<x>             The condition for the second instruction in the IT block. If omitted, the "mask" field is set to 0b1000.
                If present it is encoded in the "mask[3]" field:

                T             firstcond[0]

                E             NOT firstcond[0]

<y>             The condition for the third instruction in the IT block. If omitted and <x> is present, the "mask[2:0]"
                field is set to 0b100. If <y> is present it is encoded in the "mask[2]" field:

                T             firstcond[0]

                E             NOT firstcond[0]

<z>             The condition for the fourth instruction in the IT block. If omitted and <y> is present, the "mask[1:0]"
                field is set to 0b10. If <z> is present, the "mask[0]" field is set to 1, and it is encoded in the "mask[1]"
                field:

                T             firstcond[0]
                       E            NOT firstcond[0]

        <q>            See Standard assembler syntax fields on page F2-2506.

        <cond>         The condition for the first instruction in the IT block, encoded in the "firstcond" field. See
                       Table F2-1 on page F2-2507 for the range of conditions available, and the encodings.

        The conditions specified in an IT instruction must match those specified in the syntax of the instructions in its IT
        block. When assembling to A32 code, assemblers check IT instruction syntax for validity but do not generate
        assembled instructions for them. See Conditional instructions on page F1-2469.


        Operation

         EncodingSpecificOperations();
         AArch32.CheckITEnabled(mask);
         PSTATE.IT<7:0> = firstcond:mask;');
INSERT INTO "instructions" VALUES('ARM','LDA','Load-Acquire Word loads a word from memory and writes it to a register. The instruction also has memory ordering       (F7.1.54)
semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111   0 0 0 1 1 0 0 1               Rn            Rt      (1) (1) 0 0 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDA{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                  Rn            Rt      (1) (1) (1) (1) 1 0 1 0 (1) (1) (1) (1)




T1 variant

LDA{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n];
     R[t] = MemO[address, 4];');
INSERT INTO "instructions" VALUES('ARM','LDAB','Load-Acquire Byte loads a byte from memory, zero-extends it to form a 32-bit word and writes it to a register. The       (F7.1.55)
instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111     0 0 0 1 1 1 0 1               Rn           Rt      (1) (1) 0 0 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDAB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                    Rn           Rt      (1) (1) (1) (1) 1 0 0 0 (1) (1) (1) (1)




T1 variant

LDAB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n];
     R[t] = ZeroExtend(MemO[address, 1], 32);');
INSERT INTO "instructions" VALUES('ARM','LDAEX','Load-Acquire Exclusive Word loads a word from memory, writes it to a register and:       (F7.1.56)

.     If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
      executing PE in a global monitor.

.     Causes the executing PE to indicate an active exclusive access in the local monitor.

The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111    0 0 0 1 1 0 0 1              Rn            Rt      (1) (1) 1 0 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDAEX{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                  Rn            Rt      (1) (1) (1) (1) 1 1 1 0 (1) (1) (1) (1)




T1 variant

LDAEX{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDAEX on page J1-5349.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             AArch32.SetExclusiveMonitors(address, 4);
             R[t] = MemO[address, 4];');
INSERT INTO "instructions" VALUES('ARM','LDAEXB','Load-Acquire Exclusive Byte loads a byte from memory, zero-extends it to form a 32-bit word, writes it to a register       (F7.1.57)
and:

.     If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
      executing PE in a global monitor.

.     Causes the executing PE to indicate an active exclusive access in the local monitor.

The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111    0 0 0 1 1 1 0 1              Rn            Rt      (1) (1) 1 0 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDAEXB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                  Rn            Rt      (1) (1) (1) (1) 1 1 0 0 (1) (1) (1) (1)




T1 variant

LDAEXB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDAEXB on page J1-5349.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             AArch32.SetExclusiveMonitors(address, 1);
             R[t] = ZeroExtend(MemO[address, 1], 32);');
INSERT INTO "instructions" VALUES('ARM','LDAEXD','Load-Acquire Exclusive Doubleword loads a doubleword from memory, writes it to two registers and:       (F7.1.58)

.     If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
      executing PE in a global monitor.

.     Causes the executing PE to indicate an active exclusive access in the local monitor.

The instruction also acts as a barrier instruction with the ordering requirements described in Load-Acquire,
Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111    0 0 0 1 1 0 1 1                 Rn           Rt       (1) (1) 1 0 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   t2 = t + 1;    n = UInt(Rn);
 if Rt<0> == ''1'' || t2 == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11         8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                     Rn           Rt            Rt2     1 1 1 1 (1) (1) (1) (1)




T1 variant

LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   t2 = UInt(Rt2);     n = UInt(Rn);
 if t == 15 || t2 == 15 || t == t2 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDAEXD on page J1-5350.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           For encoding A1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
               <Rt> must be even-numbered and not R14.

               For encoding T1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
        <Rt2>          For encoding A1: is the second general-purpose register to be transferred. <Rt2> must be <R(t+1)>.

                       For encoding T1: is the second general-purpose register to be transferred, encoded in the "Rt2" field.

        <Rn>           Is the general-purpose base register, encoded in the "Rn" field.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             AArch32.SetExclusiveMonitors(address, 8);
             value = MemO[address, 8];
             // Extract words from 64-bit loaded value such that R[t] is
             // loaded from address and R[t2] from address+4.
             R[t]  = if BigEndian() then value<63:32> else value<31:0>;
             R[t2] = if BigEndian() then value<31:0>     else value<63:32>;');
INSERT INTO "instructions" VALUES('ARM','LDAEXH','Load-Acquire Exclusive Halfword loads a halfword from memory, zero-extends it to form a 32-bit word, writes it       (F7.1.59)
to a register and:

.      If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
       executing PE in a global monitor.

.      Causes the executing PE to indicate an active exclusive access in the local monitor.

The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111     0 0 0 1 1 1 1 1              Rn            Rt      (1) (1) 1 0 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDAEXH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                   Rn            Rt      (1) (1) (1) (1) 1 1 0 1 (1) (1) (1) (1)




T1 variant

LDAEXH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDAEXH on page J1-5349.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             AArch32.SetExclusiveMonitors(address, 2);
             R[t] = ZeroExtend(MemO[address, 2], 32);');
INSERT INTO "instructions" VALUES('ARM','LDAH','Load-Acquire Halfword loads a halfword from memory, zero-extends it to form a 32-bit word and writes it to a       (F7.1.60)
register. The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on
page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111     0 0 0 1 1 1 1 1              Rn            Rt      (1) (1) 0 0 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDAH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                   Rn            Rt      (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1)




T1 variant

LDAH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior, see Appendix J1 Architectural Constraints on
UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             R[t] = ZeroExtend(MemO[address, 2], 32);');
INSERT INTO "instructions" VALUES('ARM','LDC','Load Coprocessor (immediate) loads data from consecutive memory addresses to a conceptual coprocessor.       (F7.1.61)

This is a generic coprocessor instruction. The coproc field identifies the target conceptual coprocessor. This must be
one of CP10, CP11, CP14, or CP15, and for these CP values, this manual defines the imm8, CRd, and D field values
that are valid LDC and LDC2 instructions. Other encodings are UNDEFINED. For more information see Conceptual
coprocessor support on page E1-2414 and General behavior of System registers on page G4-4172.

In an implementation that includes EL2, the permitted LDC access to a system control register can be trapped to Hyp
mode, meaning that an attempt to execute an LDC instruction in a Non-secure mode other than Hyp mode, that would
be permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see
Trapping general CP14 accesses to debug registers on page G1-3923.

For simplicity, the LDC pseudocode does not show this possible trap to Hyp mode.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15        12 11          8 7                      0
     !=1111     1 1 0 P U D W 1             !=1111        CRd          !=101x              imm8
      cond                                    Rn                        coproc


Offset variant

Applies when P = 1 && W = 0.

LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


Post-indexed variant

Applies when P = 0 && W = 1.

LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


Pre-indexed variant

Applies when P = 1 && W = 1.

LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


Unindexed variant

Applies when P = 0 && U = 1 && W = 0.

LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>


Decode for all variants of this encoding

 if Rn == ''1111'' then SEE LDC (literal);
 if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
 if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MRRC, MRRC2;
 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 n = UInt(Rn);    cp = UInt(coproc);
 imm32 = ZeroExtend(imm8:''00'', 32);       index = (P == ''1'');    add = (U == ''1'');     wback = (W == ''1'');


A2


  31        28 27 26 25 24 23 22 21 20 19          16 15        12 11          8 7                      0
   1 1 1 1 1 1 0 P U D W 1                  !=1111        CRd          !=101x              imm8
      cond                                    Rn                        coproc
        Offset variant

        Applies when P = 1 && W = 0.

        LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


        Post-indexed variant

        Applies when P = 0 && W = 1.

        LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


        Pre-indexed variant

        Applies when P = 1 && W = 1.

        LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


        Unindexed variant

        Applies when P = 0 && U = 1 && W = 0.

        LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>


        Decode for all variants of this encoding

         if Rn == ''1111'' then SEE LDC (literal);
         if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
         if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MRRC, MRRC2;
         if coproc == ''101x'' then UNDEFINED;
         n = UInt(Rn); cp = UInt(coproc);
         imm32 = ZeroExtend(imm8:''00'', 32);      index = (P == ''1'');add = (U == ''1'');wback = (W == ''1'');


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15      12 11       8 7                  0
           1 1 1 0 1 1 0 P U D W 1                  !=1111       CRd     !=101x         imm8
                                                      Rn                 coproc


        Offset variant

        Applies when P = 1 && W = 0.

        LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


        Post-indexed variant

        Applies when P = 0 && W = 1.

        LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


        Pre-indexed variant

        Applies when P = 1 && W = 1.

        LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


        Unindexed variant

        Applies when P = 0 && U = 1 && W = 0.

        LDC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>
Decode for all variants of this encoding

 if Rn == ''1111'' then SEE LDC (literal);
 if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
 if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MRRC, MRRC2;
 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 n = UInt(Rn);  cp = UInt(coproc);
 imm32 = ZeroExtend(imm8:''00'', 32);     index = (P == ''1'');   add = (U == ''1'');    wback = (W == ''1'');


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15       12 11         8 7                       0
  1 1 1 1 1 1 0 P U D W 1                 !=1111        CRd         !=101x              imm8
                                            Rn                      coproc


Offset variant

Applies when P = 1 && W = 0.

LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


Post-indexed variant

Applies when P = 0 && W = 1.

LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


Pre-indexed variant

Applies when P = 1 && W = 1.

LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


Unindexed variant

Applies when P = 0 && U = 1 && W = 0.

LDC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>


Decode for all variants of this encoding

 if Rn == ''1111'' then SEE LDC (literal);
 if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
 if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MRRC, MRRC2;
 if coproc == ''101x'' then UNDEFINED;
 n = UInt(Rn); cp = UInt(coproc);
 imm32 = ZeroExtend(imm8:''00'', 32);     index = (P == ''1'');   add = (U == ''1'');    wback = (W == ''1'');


Notes for all encodings

Advanced SIMD and floating-point: Advanced SIMD and floating-point register load/store instructions on
page F5-2602.


Assembler symbols

L             If specified, selects the D == 1 form of the encoding. If omitted, selects the D == 0 form.

<c>           For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

              For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

<q>           See Standard assembler syntax fields on page F2-2506.
        <coproc>       Is the name of the coprocessor, encoded in the "coproc" field. The valid coprocessor names are p10,
                       p11, p14, and p15.

        <CRd>          Is the coprocessor register to be transferred, encoded in the "CRd" field.

        <Rn>           Is the general-purpose base register, encoded in the "Rn" field. If the PC is used, see LDC, LDC2
                       (literal).

        <option>       Is a coprocessor option, in the range 0 to 255 enclosed in { }, encoded in the "imm8" field.

        +/-            Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
                       encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <imm>          Is the immediate offset used for forming the address, a multiple of 4 in the range 0-1020, defaulting
                       to 0 and encoded in the "imm8" field, as <imm>/4.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             Coproc_CheckInstr(cp, ThisInstr());
             offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
             address = if index then offset_addr else R[n];
             repeat
                 Coproc_SendLoadedWord(MemA[address,4], cp, ThisInstr());
                 address = address + 4;
             until Coproc_DoneLoading(cp, ThisInstr());
             if wback then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','LDC2','-R:LDC');
INSERT INTO "instructions" VALUES('ARM','LDM','        Load Multiple (Increment After, Full Descending) loads multiple registers from consecutive memory locations       (F7.1.63)
        using an address from a base register. The consecutive memory locations start at this address, and the address just
        above the highest of those locations can optionally be written back to the base register.

        The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
        from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
        page F2-2514.

        The registers loaded can include the PC, causing a branch to a loaded address. This is an interworking branch, see
        Pseudocode description of operations on the AArch32 general-purpose registers and the PC on page E1-2378.

        Related system instructions are LDM (User registers) and LDM (exception return).

        This instruction is used by the alias POP (multiple registers). See the Alias conditions on page F7-2761 table for
        details of when each alias is preferred.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15                                              0
             !=1111    1 0 0 0 1 0 W 1                Rn                          register_list
              cond


        A1 variant

        LDM{IA}{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
        LDMFD{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Full Descending stack


        Decode for this encoding

         n = UInt(Rn);    registers = register_list;    wback = (W == ''1'');
         if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
         if wback && registers<n> == ''1'' then UNPREDICTABLE;


        T1


          15 14 13 12 11 10      8 7                      0
           1 1 0 0 1          Rn           register_list




        T1 variant

        LDM{IA}{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
        LDMFD{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Full Descending stack


        Decode for this encoding

         n = UInt(Rn);    registers = ''00000000'':register_list;      wback = (registers<n> == ''0'');
         if BitCount(registers) < 1 then UNPREDICTABLE;


        T2


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12                                      0
           1 1 1 0 1 0 0 0 1 0 W 1                    Rn       P M (0)                 register_list
T2 variant

LDM{IA}{<c>}.W <Rn>{!}, <registers>// Preferred syntax, if <Rn>, ''!'' and <registers> can be represented
in T1
LDMFD{<c>}.W <Rn>{!}, <registers>// Alternate syntax, Full Descending stack, if <Rn>, ''!'' and <registers>
can be represented in T1
LDM{IA}{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
LDMFD{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Full Descending stack


Decode for this encoding

 n = UInt(Rn);  registers = P:M:''0'':register_list;         wback = (W == ''1'');
 if n == 15 || BitCount(registers) < 2 || (P == ''1'' && M == ''1'') then UNPREDICTABLE;
 if wback && registers<n> == ''1'' then UNPREDICTABLE;
 if registers<15> == ''1'' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDM/LDMIA/LDMFD (T32) on
page J1-5334 and LDM/LDMIA/LDMFD (A32) on page J1-5335.


Alias conditions


                Alias                           is preferred when

                POP (multiple registers)        W == ''1'' && Rn == ''1101'' && BitCount(register_list) > 1



Assembler symbols

IA             Is an optional suffix for the Increment After form.

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.

!              For encoding A1 and T2: the address adjusted by the size of the data loaded is written back to the
               base register. If specified, it is encoded in the "W" field as 1, otherwise this field defaults to 0.

               For encoding T1: the address adjusted by the size of the data loaded is written back to the base
               register. It is omitted if <Rn> is included in <registers>, otherwise it must be present.

<registers>    For encoding A1: is a list of one or more registers to be loaded, separated by commas and
               surrounded by { and }. The PC can be in the list. ARM deprecates using these instructions with both
               the LR and the PC in the list.

               For encoding T1: is a list of one or more registers to be loaded, separated by commas and surrounded
               by { and }. The registers in the list must be in the range R0-R7, encoded in the "register_list" field.

               For encoding T2: is a list of one or more registers to be loaded, separated by commas and surrounded
               by { and }. The registers in the list must be in the range R0-R12, encoded in the "register_list" field,
               and can optionally contain one of the LR or the PC. If the LR is in the list, the "M" field is set to 1,
               otherwise it defaults to 0. If the PC is in the list, the "P" field is set to 1, otherwise it defaults to 0.
               If the PC is in the list:

               .      The LR must not be in the list.

               .      The instruction must be either outside any IT block, or the last instruction in an IT block.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             for i = 0 to 14
                 if registers<i> == ''1'' then
                     R[i] = MemA[address,4];      address = address + 4;
             if registers<15> == ''1'' then
                 LoadWritePC(MemA[address,4]);
             if wback && registers<n> == ''0'' then R[n] = R[n] + 4*BitCount(registers);
             if wback && registers<n> == ''1'' then R[n] = bits(32) UNKNOWN;');
INSERT INTO "instructions" VALUES('ARM','LDMIA','-R:LDM');
INSERT INTO "instructions" VALUES('ARM','LDMFD','-R:LDM');
INSERT INTO "instructions" VALUES('ARM','LDMDA','Load Multiple Decrement After (Full Ascending) loads multiple registers from consecutive memory locations using       (F7.1.66)
an address from a base register. The consecutive memory locations end at this address, and the address just below
the lowest of those locations can optionally be written back to the base register.

The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
page F2-2514.

The registers loaded can include the PC, causing a branch to a loaded address. This is an interworking branch, see
Pseudocode description of operations on the AArch32 general-purpose registers and the PC on page E1-2378.

Related system instructions are LDM (User registers) and LDM (exception return).


A1


  31       28 27 26 25 24 23 22 21 20 19             16 15                                              0
     !=1111    1 0 0 0 0 0 W 1                 Rn                           register_list
      cond


A1 variant

LDMDA{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
LDMFA{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Full Ascending stack


Decode for this encoding

 n = UInt(Rn);    registers = register_list;       wback = (W == ''1'');
 if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
 if wback && registers<n> == ''1'' then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDMDA/LDMFA on page J1-5336.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.

!               The address adjusted by the size of the data loaded is written back to the base register. If specified,
                it is encoded in the "W" field as 1, otherwise this field defaults to 0.

<registers>     Is a list of one or more registers to be loaded, separated by commas and surrounded by { and }. The
                PC can be in the list. ARM deprecates using these instructions with both the LR and the PC in the
                list.


Operation

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n] - 4*BitCount(registers) + 4;
     for i = 0 to 14
         if registers<i> == ''1'' then
              R[i] = MemA[address,4];      address = address + 4;
     if registers<15> == ''1'' then
                 LoadWritePC(MemA[address,4]);
             if wback && registers<n> == ''0'' then R[n] = R[n] - 4*BitCount(registers);
             if wback && registers<n> == ''1'' then R[n] = bits(32) UNKNOWN;');
INSERT INTO "instructions" VALUES('ARM','LDMFA','-R:LDMDA');
INSERT INTO "instructions" VALUES('ARM','LDMDB','Load Multiple Decrement Before (Empty Ascending) loads multiple registers from consecutive memory locations       (F7.1.67)
using an address from a base register. The consecutive memory locations end just below this address, and the
address of the lowest of those locations can optionally be written back to the base register.

The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
page F2-2514.

The registers loaded can include the PC, causing a branch to a loaded address. This is an interworking branch, see
Pseudocode description of operations on the AArch32 general-purpose registers and the PC on page E1-2378.

Related system instructions are LDM (User registers) and LDM (exception return).


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15                                              0
     !=1111     1 0 0 1 0 0 W 1              Rn                          register_list
      cond


A1 variant

LDMDB{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
LDMEA{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Empty Ascending stack


Decode for this encoding

 n = UInt(Rn);   registers = register_list;     wback = (W == ''1'');
 if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
 if wback && registers<n> == ''1'' then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12                                      0
  1 1 1 0 1 0 0 1 0 0 W 1                    Rn       P M (0)                 register_list




T1 variant

LDMDB{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
LDMEA{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Empty Ascending stack


Decode for this encoding

 n = UInt(Rn);   registers = P:M:''0'':register_list;      wback = (W == ''1'');
 if n == 15 || BitCount(registers) < 2 || (P == ''1'' && M == ''1'') then UNPREDICTABLE;
 if wback && registers<n> == ''1'' then UNPREDICTABLE;
 if registers<15> == ''1'' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDMDB/LDMEA on page J1-5336.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.
        <Rn>           Is the general-purpose base register, encoded in the "Rn" field.

        !              The address adjusted by the size of the data loaded is written back to the base register. If specified,
                       it is encoded in the "W" field as 1, otherwise this field defaults to 0.

        <registers>    For encoding A1: is a list of one or more registers to be loaded, separated by commas and
                       surrounded by { and }. The PC can be in the list. ARM deprecates using these instructions with both
                       the LR and the PC in the list.

                       For encoding T1: is a list of one or more registers to be loaded, separated by commas and surrounded
                       by { and }. The registers in the list must be in the range R0-R12, encoded in the "register_list" field,
                       and can optionally contain one of the LR or the PC. If the LR is in the list, the "M" field is set to 1,
                       otherwise it defaults to 0. If the PC is in the list, the "P" field is set to 1, otherwise it defaults to 0.
                       If the PC is in the list:

                       .      The LR must not be in the list.

                       .      The instruction must be either outside any IT block, or the last instruction in an IT block.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n] - 4*BitCount(registers);
             for i = 0 to 14
                 if registers<i> == ''1'' then
                     R[i] = MemA[address,4];      address = address + 4;
             if registers<15> == ''1'' then
                 LoadWritePC(MemA[address,4]);
             if wback && registers<n> == ''0'' then R[n] = R[n] - 4*BitCount(registers);
             if wback && registers<n> == ''1'' then R[n] = bits(32) UNKNOWN;');
INSERT INTO "instructions" VALUES('ARM','LDMEA','-R:LDMDB');
INSERT INTO "instructions" VALUES('ARM','LDMIB','Load Multiple Increment Before (Empty Descending) loads multiple registers from consecutive memory locations       (F7.1.68)
using an address from a base register. The consecutive memory locations start just above this address, and the
address of the last of those locations can optionally be written back to the base register.

The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
page F2-2514.

The registers loaded can include the PC, causing a branch to a loaded address. This is an interworking branch, see
Pseudocode description of operations on the AArch32 general-purpose registers and the PC on page E1-2378.

Related system instructions are LDM (User registers) and LDM (exception return).


A1


  31        28 27 26 25 24 23 22 21 20 19            16 15                                              0
     !=1111     1 0 0 1 1 0 W 1                Rn                           register_list
      cond


A1 variant

LDMIB{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
LDMED{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Empty Descending stack


Decode for this encoding

 n = UInt(Rn);    registers = register_list;       wback = (W == ''1'');
 if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;
 if wback && registers<n> == ''1'' then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDMIB/LDMED on page J1-5336.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.

!               The address adjusted by the size of the data loaded is written back to the base register. If specified,
                it is encoded in the "W" field as 1, otherwise this field defaults to 0.

<registers>     Is a list of one or more registers to be loaded, separated by commas and surrounded by { and }. The
                PC can be in the list. ARM deprecates using these instructions with both the LR and the PC in the
                list.


Operation

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n] + 4;
     for i = 0 to 14
         if registers<i> == ''1'' then
              R[i] = MemA[address,4];      address = address + 4;
     if registers<15> == ''1'' then
                 LoadWritePC(MemA[address,4]);
             if wback && registers<n> == ''0'' then R[n] = R[n] + 4*BitCount(registers);
             if wback && registers<n> == ''1'' then R[n] = bits(32) UNKNOWN;');
INSERT INTO "instructions" VALUES('ARM','LDMED','-R:LDMIB');
INSERT INTO "instructions" VALUES('ARM','LDRBT','        Load Register Byte Unprivileged loads a byte from memory, zero-extends it to form a 32-bit word, and writes it to       (F7.1.75)
        a register. For information about memory accesses see Memory accesses on page F2-2513.

        The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
        actually running in User mode.

        LDRBT is UNPREDICTABLE in Hyp mode.

        The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
        base register value and an immediate offset, and leaves the base register unchanged.

        The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
        memory access, and calculates a new address from a base register value and an offset and writes it back to the base
        register. The offset can be an immediate value or an optionally-shifted register value.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15       12 11                                  0
             !=1111      0 1 0 0 U 1 1 1              Rn          Rt                      imm12
              cond


        A1 variant

        LDRBT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


        Decode for this encoding

         t = UInt(Rt);     n = UInt(Rn);  postindex = TRUE;   add = (U == ''1'');
         register_form = FALSE;     imm32 = ZeroExtend(imm12, 32);
         if t == 15 || n == 15 || n == t then UNPREDICTABLE;


        A2


          31        28 27 26 25 24 23 22 21 20 19         16 15       12 11             7 6 5 4 3            0
             !=1111      0 1 1 0 U 1 1 1              Rn          Rt           imm5        type 0      Rm
              cond


        A2 variant

        LDRBT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>}


        Decode for this encoding

         t = UInt(Rt);     n = UInt(Rn);  m = UInt(Rm);   postindex = TRUE;    add = (U == ''1'');
         register_form = TRUE;     (shift_t, shift_n) = DecodeImmShift(type, imm5);
         if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15        12 11 10 9 8 7                         0
           1 1 1 1 1 0 0 0 0 0 0 1                  !=1111        Rt       1 1 1 0              imm8
                                                      Rn


        T1 variant

        LDRBT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
Decode for this encoding

 if Rn == ''1111'' then SEE LDRB (literal);
 t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;   add = TRUE;
 register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
 if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRBT on page J1-5339.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           For encoding A1: is the general-purpose register to be transferred, encoded in the "Rt" field. The PC
               can be used, but this is deprecated.

               For encoding A2 and T1: is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           For encoding A1: is the general-purpose base register, encoded in the "Rn" field. The SP can be
               used.

               For encoding A2 and T1: is the general-purpose base register, encoded in the "Rn" field.

+/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
               + if omitted and encoded in the "U" field. It can have the following values:

               -           when U = 0

               +           when U = 1

               For encoding A2: specifies the index register is added to or subtracted from the base register,
               defaulting to + if omitted and encoded in the "U" field. It can have the following values:

               -           when U = 0

               +           when U = 1

<Rm>           Is the general-purpose index register, encoded in the "Rm" field.

<shift>        The shift to apply to the value read from <Rm>. If absent, no shift is applied. Otherwise, see Shifts
               applied to a register on page F2-2510.

+              Specifies the offset is added to the base register.

<imm>          For encoding A1: is the optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
               defaulting to 0 and encoded in the "imm12" field.

               For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
               defaulting to 0 and encoded in the "imm8" field.


Operation for all encodings

 if ConditionPassed() then
     if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
     EncodingSpecificOperations();
     offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32;
     offset_addr = if add then (R[n] + offset) else (R[n] - offset);
     address = if postindex then R[n] else offset_addr;
     R[t] = ZeroExtend(MemU_unpriv[address,1],32);
     if postindex then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','LDRD','        Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two       (F7.1.76)
        words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing.
        For information about memory accesses see Memory accesses on page F2-2513.


        A1


          31       28 27 26 25 24 23 22 21 20 19          16 15      12 11         8 7 6 5 4 3              0
             !=1111   0 0 0 P U 1 W 0               !=1111        Rt       imm4H      1 1 0 1        imm4L
              cond                                    Rn


        Offset variant

        Applies when P = 1 && W = 0.

        LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn> {, #{+/-}<imm>}]


        Post-indexed variant

        Applies when P = 0 && W = 0.

        LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm>


        Pre-indexed variant

        Applies when P = 1 && W = 1.

        LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<imm>]!


        Decode for all variants of this encoding

         if Rn == ''1111'' then SEE LDRD (literal);
         if Rt<0> == ''1'' then UNPREDICTABLE;
         t = UInt(Rt);  t2 = t+1;    n = UInt(Rn);    imm32 = ZeroExtend(imm4H:imm4L, 32);
         index = (P == ''1'');   add = (U == ''1'');     wback = (P == ''0'') || (W == ''1'');
         if P == ''0'' && W == ''1'' then UNPREDICTABLE;
         if wback && (n == t || n == t2) then UNPREDICTABLE;
         if t2 == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15       12 11         8 7                      0
           1 1 1 0 1 0 0 P U 1 W 1                  !=1111        Rt        Rt2                 imm8
                                                      Rn


        Offset variant

        Applies when P = 1 && W = 0.

        LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn> {, #{+/-}<imm>}]


        Post-indexed variant

        Applies when P = 0 && W = 1.

        LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm>


        Pre-indexed variant

        Applies when P = 1 && W = 1.
LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<imm>]!


Decode for all variants of this encoding

 if P == ''0'' && W == ''0'' then SEE "Related encodings";
 if Rn == ''1111'' then SEE LDRD (literal);
 t = UInt(Rt);  t2 = UInt(Rt2);     n = UInt(Rn);   imm32 = ZeroExtend(imm8:''00'', 32);
 index = (P == ''1'');   add = (U == ''1'');    wback = (W == ''1'');
 if wback && (n == t || n == t2) then UNPREDICTABLE;
 if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRD (immediate) on page J1-5346.

Related encodings: Load/Store dual, Load/Store-Exclusive, Load-Acquire/Store-Release, table branch on
page F3-2536.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           For encoding A1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
               This register must be even-numbered and not R14.

               For encoding T1: is the first general-purpose register to be transferred, encoded in the "Rt" field.

<Rt2>          For encoding A1: is the second general-purpose register to be transferred. This register must be
               <R(t+1)>.

               For encoding T1: is the second general-purpose register to be transferred, encoded in the "Rt2" field.

<Rn>           For encoding A1 or T1: is the general-purpose base register, encoded in the "Rn" field. For PC use
               see LDRD (literal).

               For the post-indexed or pre-indexed variant: is the general-purpose base register, encoded in the
               "Rn" field.

+/-            Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
               encoded in the "U" field. It can have the following values:

               -           when U = 0

               +           when U = 1

<imm>          For encoding A1: is the optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
               defaulting to 0 and encoded in the "imm4H:imm4L" field.

               For the post-indexed or pre-indexed variant: is the unsigned immediate byte offset, a multiple of 4,
               in the range 0 to 1020, encoded in the "imm8" field as <imm>/4.

               For the post-indexed or pre-indexed variant: is the 8-bit unsigned immediate byte offset, in the range
               0 to 255, encoded in the "imm4H:imm4L" field.

               For encoding T1: is the optional unsigned immediate byte offset, a multiple of 4, in the range 0 to
               1020, defaulting to 0 and encoded in the "imm8" field as <imm>/4.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
     address = if index then offset_addr else R[n];
     if address == Align(address, 8) then
         data = MemA[address,8];
                 if BigEndian()   then
                     R[t] = data<63:32>;
                     R[t2] = data<31:0>;
                 else
                     R[t] = data<31:0>;
                     R[t2] = data<63:32>;
             else
                 R[t] = MemA[address,4];
                 R[t2] = MemA[address+4,4];
             if wback then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','LDREX','Load Register Exclusive calculates an address from a base register value and an immediate offset, loads a word from       (F7.1.79)
memory, writes it to a register and:

.     If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
      executing PE in a global monitor.

.     Causes the executing PE to indicate an active exclusive access in the local monitor.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111    0 0 0 1 1 0 0 1              Rn            Rt      (1) (1) 1 1 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDREX{<c>}{<q>} <Rt>, [<Rn> {, {#}<imm>}]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);    imm32 = Zeros(32); // Zero offset
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7                         0
   1 1 1 0 1 0 0 0 0 1 0 1                  Rn            Rt      (1) (1) (1) (1)        imm8




T1 variant

LDREX{<c>}{<q>} <Rt>, [<Rn> {, #<imm>}]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);    imm32 = ZeroExtend(imm8:''00'', 32);
 if t == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDREX on page J1-5348.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.

<imm>          For encoding A1: the immediate offset added to the value of <Rn> to calculate the address. <imm> can
               only be 0 or omitted.
                       For encoding T1: the immediate offset added to the value of <Rn> to calculate the address. <imm> can
                       be omitted, meaning an offset of 0. Values are multiples of 4 in the range 0-1020.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n] + imm32;
             AArch32.SetExclusiveMonitors(address,4);
             R[t] = MemA[address,4];');
INSERT INTO "instructions" VALUES('ARM','LDREXB','Load Register Exclusive Byte derives an address from a base register value, loads a byte from memory, zero-extends       (F7.1.80)
it to form a 32-bit word, writes it to a register and:

.       If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
        executing PE in a global monitor.

.       Causes the executing PE to indicate an active exclusive access in the local monitor.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


   31        28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
      !=1111     0 0 0 1 1 1 0 1                Rn          Rt        (1) (1) 1 1 1 0 0 1 (1) (1) (1) (1)
       cond


A1 variant

LDREXB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);     n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


   15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3 2 1 0
    1 1 1 0 1 0 0 0 1 1 0 1                     Rn          Rt        (1) (1) (1) (1) 0 1 0 0 (1) (1) (1) (1)




T1 variant

LDREXB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);     n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDREXB on page J1-5349.


Assembler symbols

<c>              See Standard assembler syntax fields on page F2-2506.

<q>              See Standard assembler syntax fields on page F2-2506.

<Rt>             Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>             Is the general-purpose base register, encoded in the "Rn" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             AArch32.SetExclusiveMonitors(address,1);
             R[t] = ZeroExtend(MemA[address,1], 32);');
INSERT INTO "instructions" VALUES('ARM','LDREXD','Load Register Exclusive Doubleword derives an address from a base register value, loads a 64-bit doubleword from       (F7.1.81)
memory, writes it to two registers and:

.     If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
      executing PE in a global monitor.

.     Causes the executing PE to indicate an active exclusive access in the local monitor.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111    0 0 0 1 1 0 1 1               Rn           Rt      (1) (1) 1 1 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   t2 = t + 1;   n = UInt(Rn);
 if Rt<0> == ''1'' || t2 == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15        12 11         8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                   Rn           Rt           Rt2     0 1 1 1 (1) (1) (1) (1)




T1 variant

LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   t2 = UInt(Rt2);    n = UInt(Rn);
 if t == 15 || t2 == 15 || t == t2 || n == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDREXD on page J1-5349.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           For encoding A1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
               <Rt> must be even-numbered and not R14.

               For encoding T1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
        <Rt2>          For encoding A1: is the second general-purpose register to be transferred. <Rt2> must be <R(t+1)>.

                       For encoding T1: is the second general-purpose register to be transferred, encoded in the "Rt2" field.

        <Rn>           Is the general-purpose base register, encoded in the "Rn" field.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             AArch32.SetExclusiveMonitors(address,8);
             value = MemA[address,8];
             // Extract words from 64-bit loaded value such that R[t] is
             // loaded from address and R[t2] from address+4.
             R[t]  = if BigEndian() then value<63:32> else value<31:0>;
             R[t2] = if BigEndian() then value<31:0> else value<63:32>;');
INSERT INTO "instructions" VALUES('ARM','LDREXH','Load Register Exclusive Halfword derives an address from a base register value, loads a halfword from memory,       (F7.1.82)
zero-extends it to form a 32-bit word, writes it to a register and:

.     If the address has the Shared Memory attribute, marks the physical address as exclusive access for the
      executing PE in a global monitor.

.     Causes the executing PE to indicate an active exclusive access in the local monitor.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
     !=1111     0 0 0 1 1 1 1 1              Rn             Rt      (1) (1) 1 1 1 0 0 1 (1) (1) (1) (1)
      cond


A1 variant

LDREXH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 1                   Rn             Rt      (1) (1) (1) (1) 0 1 0 1 (1) (1) (1) (1)




T1 variant

LDREXH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt);   n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDREXH on page J1-5348.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             address = R[n];
             AArch32.SetExclusiveMonitors(address,2);
             R[t] = ZeroExtend(MemA[address,2], 32);');
INSERT INTO "instructions" VALUES('ARM','LDRHT','        Load Register Halfword Unprivileged loads a halfword from memory, zero-extends it to form a 32-bit word, and       (F7.1.86)
        writes it to a register. For information about memory accesses see Memory accesses on page F2-2513.

        The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
        actually running in User mode.

        LDRHT is UNPREDICTABLE in Hyp mode.

        The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
        base register value and an immediate offset, and leaves the base register unchanged.

        The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
        memory access, and calculates a new address from a base register value and an offset and writes it back to the base
        register. The offset can be an immediate value or a register value.


        A1


          31         28 27 26 25 24 23 22 21 20 19         16 15       12 11          8 7 6 5 4 3            0
             !=1111      0 0 0 0 U 1 1 1               Rn           Rt      imm4H        1 0 1 1     imm4L
              cond


        A1 variant

        LDRHT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


        Decode for this encoding

         t = UInt(Rt);     n = UInt(Rn);    postindex = TRUE;   add = (U == ''1'');
         register_form = FALSE;       imm32 = ZeroExtend(imm4H:imm4L, 32);
         if t == 15 || n == 15 || n == t then UNPREDICTABLE;


        A2


          31         28 27 26 25 24 23 22 21 20 19         16 15       12 11 10 9 8 7 6 5 4 3                0
             !=1111      0 0 0 0 U 0 1 1               Rn           Rt    (0) (0) (0) (0) 1 0 1 1      Rm
              cond


        A2 variant

        LDRHT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>


        Decode for this encoding

         t = UInt(Rt);     n = UInt(Rn);    m = UInt(Rm);  postindex = TRUE;   add = (U == ''1'');
         register_form = TRUE;
         if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7                        0
           1 1 1 1 1 0 0 0 0 0 1 1                  !=1111          Rt     1 1 1 0              imm8
                                                       Rn


        T1 variant

        LDRHT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
Decode for this encoding

 if Rn == ''1111'' then SEE LDRH (literal);
 t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;    add = TRUE;
 register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
 if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRHT on page J1-5341.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.

+/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
               + if omitted and encoded in the "U" field. It can have the following values:

               -           when U = 0

               +           when U = 1

               For encoding A2: specifies the index register is added to or subtracted from the base register,
               defaulting to + if omitted and encoded in the "U" field. It can have the following values:

               -           when U = 0

               +           when U = 1

<Rm>           Is the general-purpose index register, encoded in the "Rm" field.

+              Specifies the offset is added to the base register.

<imm>          For encoding A1: is the optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
               defaulting to 0 and encoded in the "imm4H:imm4L" field.

               For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
               defaulting to 0 and encoded in the "imm8" field.


Operation for all encodings

 if ConditionPassed() then
     if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
     EncodingSpecificOperations();
     offset = if register_form then R[m] else imm32;
     offset_addr = if add then (R[n] + offset) else (R[n] - offset);
     address = if postindex then R[n] else offset_addr;
     data = MemU_unpriv[address,2];
     if postindex then R[n] = offset_addr;
     R[t] = ZeroExtend(data, 32);');
INSERT INTO "instructions" VALUES('ARM','LDRSBT','Load Register Signed Byte Unprivileged loads a byte from memory, sign-extends it to form a 32-bit word, and       (F7.1.90)
writes it to a register. For information about memory accesses see Memory accesses on page F2-2513.

The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
actually running in User mode.

LDRSBT is UNPREDICTABLE in Hyp mode.

The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
base register value and an immediate offset, and leaves the base register unchanged.

The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
memory access, and calculates a new address from a base register value and an offset and writes it back to the base
register. The offset can be an immediate value or a register value.


A1


  31         28 27 26 25 24 23 22 21 20 19         16 15       12 11            8 7 6 5 4 3            0
     !=1111      0 0 0 0 U 1 1 1               Rn           Rt         imm4H       1 1 0 1      imm4L
      cond


A1 variant

LDRSBT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


Decode for this encoding

 t = UInt(Rt);     n = UInt(Rn);    postindex = TRUE;   add = (U == ''1'');
 register_form = FALSE;       imm32 = ZeroExtend(imm4H:imm4L, 32);
 if t == 15 || n == 15 || n == t then UNPREDICTABLE;


A2


  31         28 27 26 25 24 23 22 21 20 19         16 15       12 11 10 9 8 7 6 5 4 3                  0
     !=1111      0 0 0 0 U 0 1 1               Rn           Rt      (0) (0) (0) (0) 1 1 0 1      Rm
      cond


A2 variant

LDRSBT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>


Decode for this encoding

 t = UInt(Rt);     n = UInt(Rn);    m = UInt(Rm);  postindex = TRUE;      add = (U == ''1'');
 register_form = TRUE;
 if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7                          0
  1 1 1 1 1 0 0 1 0 0 0 1                   !=1111          Rt       1 1 1 0             imm8
                                               Rn


T1 variant

LDRSBT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
        Decode for this encoding

         if Rn == ''1111'' then SEE LDRSB (literal);
         t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;    add = TRUE;
         register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRSBT on page J1-5342.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>           Is the general-purpose base register, encoded in the "Rn" field.

        +/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
                       + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

                       For encoding A2: specifies the index register is added to or subtracted from the base register,
                       defaulting to + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <Rm>           Is the general-purpose index register, encoded in the "Rm" field.

        +              Specifies the offset is added to the base register.

        <imm>          For encoding A1: is the optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm4H:imm4L" field.

                       For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm8" field.


        Operation for all encodings

         if ConditionPassed() then
             if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
             EncodingSpecificOperations();
             offset = if register_form then R[m] else imm32;
             offset_addr = if add then (R[n] + offset) else (R[n] - offset);
             address = if postindex then R[n] else offset_addr;
             R[t] = SignExtend(MemU_unpriv[address,1], 32);
             if postindex then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','LDRSHT','Load Register Signed Halfword Unprivileged loads a halfword from memory, sign-extends it to form a 32-bit word,       (F7.1.94)
and writes it to a register. For information about memory accesses see Memory accesses on page F2-2513.

The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
actually running in User mode.

LDRSHT is UNPREDICTABLE in Hyp mode.

The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
base register value and an immediate offset, and leaves the base register unchanged.

The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
memory access, and calculates a new address from a base register value and an offset and writes it back to the base
register. The offset can be an immediate value or a register value.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15       12 11            8 7 6 5 4 3            0
     !=1111     0 0 0 0 U 1 1 1               Rn            Rt         imm4H       1 1 1 1      imm4L
      cond


A1 variant

LDRSHT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);     postindex = TRUE;   add = (U == ''1'');
 register_form = FALSE;      imm32 = ZeroExtend(imm4H:imm4L, 32);
 if t == 15 || n == 15 || n == t then UNPREDICTABLE;


A2


  31        28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3                  0
     !=1111     0 0 0 0 U 0 1 1               Rn            Rt      (0) (0) (0) (0) 1 1 1 1      Rm
      cond


A2 variant

LDRSHT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);     m = UInt(Rm);  postindex = TRUE;      add = (U == ''1'');
 register_form = TRUE;
 if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7                          0
  1 1 1 1 1 0 0 1 0 0 1 1                    !=1111         Rt       1 1 1 0             imm8
                                              Rn


T1 variant

LDRSHT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
        Decode for this encoding

         if Rn == ''1111'' then SEE LDRSH (literal);
         t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;    add = TRUE;
         register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRSHT on page J1-5343.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>           Is the general-purpose base register, encoded in the "Rn" field.

        +/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
                       + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

                       For encoding A2: specifies the index register is added to or subtracted from the base register,
                       defaulting to + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <Rm>           Is the general-purpose index register, encoded in the "Rm" field.

        +              Specifies the offset is added to the base register.

        <imm>          For encoding A1: is the optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm4H:imm4L" field.

                       For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm8" field.


        Operation for all encodings

         if ConditionPassed() then
             if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
             EncodingSpecificOperations();
             offset = if register_form then R[m] else imm32;
             offset_addr = if add then (R[n] + offset) else (R[n] - offset);
             address = if postindex then R[n] else offset_addr;
             data = MemU_unpriv[address,2];
             if postindex then R[n] = offset_addr;
             R[t] = SignExtend(data, 32);');
INSERT INTO "instructions" VALUES('ARM','LDRT','Load Register Unprivileged loads a word from memory, and writes it to a register. For information about memory       (F7.1.95)
accesses see Memory accesses on page F2-2513.

The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
actually running in User mode.

LDRT is UNPREDICTABLE in Hyp mode.

The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
base register value and an immediate offset, and leaves the base register unchanged.

The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
memory access, and calculates a new address from a base register value and an offset and writes it back to the base
register. The offset can be an immediate value or an optionally-shifted register value.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15       12 11                                  0
     !=1111     0 1 0 0 U 0 1 1              Rn           Rt                      imm12
      cond


A1 variant

LDRT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   postindex = TRUE;   add = (U == ''1'');
 register_form = FALSE;     imm32 = ZeroExtend(imm12, 32);
 if t == 15 || n == 15 || n == t then UNPREDICTABLE;


A2


  31        28 27 26 25 24 23 22 21 20 19         16 15       12 11             7 6 5 4 3            0
     !=1111     0 1 1 0 U 0 1 1              Rn           Rt            imm5       type 0      Rm
      cond


A2 variant

LDRT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   m = UInt(Rm);   postindex = TRUE;     add = (U == ''1'');
 register_form = TRUE;     (shift_t, shift_n) = DecodeImmShift(type, imm5);
 if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15        12 11 10 9 8 7                         0
  1 1 1 1 1 0 0 0 0 1 0 1                  !=1111         Rt      1 1 1 0               imm8
                                             Rn


T1 variant

LDRT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
        Decode for this encoding

         if Rn == ''1111'' then SEE LDR (literal);
         t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;   add = TRUE;
         register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly LDRT on page J1-5343.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rt>           For encoding A1: is the general-purpose register to be transferred, encoded in the "Rt" field. The PC
                       can be used, but this is deprecated.

                       For encoding A2 and T1: is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>           For encoding A1: is the general-purpose base register, encoded in the "Rn" field. The SP can be
                       used.

                       For encoding A2 and T1: is the general-purpose base register, encoded in the "Rn" field.

        +/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
                       + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

                       For encoding A2: specifies the index register is added to or subtracted from the base register,
                       defaulting to + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <Rm>           Is the general-purpose index register, encoded in the "Rm" field.

        <shift>        The shift to apply to the value read from <Rm>. If absent, no shift is applied. Otherwise, see Shifts
                       applied to a register on page F2-2510.

        +              Specifies the offset is added to the base register.

        <imm>          For encoding A1: is the optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
                       defaulting to 0 and encoded in the "imm12" field.

                       For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm8" field.


        Operation for all encodings

         if ConditionPassed() then
             if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
             EncodingSpecificOperations();
             offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32;
             offset_addr = if add then (R[n] + offset) else (R[n] - offset);
             address = if postindex then R[n] else offset_addr;
             data = MemU_unpriv[address,4];
             if postindex then R[n] = offset_addr;
             R[t] = data;');
INSERT INTO "instructions" VALUES('ARM','LSLS','Logical Shift Left, setting flags (immediate) shifts a register value left by an immediate number of bits, shifting in       (F7.1.98)
zeros, and writes the result to the destination register.

If the destination register is not the PC, this instruction updates the condition flags based on the result.

The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
deprecates any use of these encodings. However, when the destination register is the PC:

.      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

.      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from AArch32
       state on page G1-3845.

.      The instruction is UNDEFINED in Hyp mode.

.      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.

This instruction is an alias of the MOV, MOVS (register) instruction. This means that:

.      The encodings in this description are named to match the encodings of MOV, MOVS (register).

.      The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.


A1


  31        28 27 26 25 24 23 22 21 20 19 18 17 16 15             12 11            7 6 5 4 3             0
     !=1111     0 0 0 1 1 0 1 1 (0) (0) (0) (0)              Rd           !=00000     0 0 0        Rm
      cond                              S                                   imm5      type


MOVS, shift or rotate by value variant

LSLS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

is equivalent to

MOVS{<c>}{<q>} <Rd>, <Rm>, LSL #<imm>

and is always the preferred disassembly.


T2


  15 14 13 12 11 10              6 5        3 2       0
   0 0 0 0 0           !=00000         Rn         Rd
              op        imm5


T2 variant

LSLS{<q>} {<Rd>,} <Rm>, #<imm>// Outside IT block

is equivalent to

MOVS{<q>} <Rd>, <Rm>, LSL #<imm>

and is the preferred disassembly when !InITBlock().
        T3


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                  12 11           8 7 6 5 4 3                0
           1 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 (0) imm3                             Rd       imm2 0 0           Rm
                                              S                                                  type


        MOVS, shift or rotate by value variant

        LSLS.W {<Rd>,} <Rm>, #<imm>// Outside IT block, and <Rd>, <Rm>, <imm> can be represented in T2

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, LSL #<imm>

        and is always the preferred disassembly.

        LSLS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, LSL #<imm>

        and is always the preferred disassembly.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
                        deprecates using the PC as the destination register, but if the PC is used, the instruction performs an
                        exception return, that restores PSTATE from SPSR_<current_mode>.

                        For encoding T2 and T3: is the general-purpose destination register, encoded in the "Rd" field.

        <Rm>            For encoding A1: is the general-purpose source register, encoded in the "Rm" field. The PC can be
                        used.

                        For encoding T2 and T3: is the general-purpose source register, encoded in the "Rm" field.

        <imm>           For encoding A1 and T2: is the shift amount, in the range 1 to 31, encoded in the "imm5" field.

                        For encoding T3: is the shift amount, in the range 1 to 31, encoded in the "imm3:imm2" field.


        Operation for all encodings

        The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','LSRS','Logical Shift Right, setting flags (immediate) shifts a register value right by an immediate number of bits, shifting       (F7.1.102)
in zeros, and writes the result to the destination register.

If the destination register is not the PC, this instruction updates the condition flags based on the result.

The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
deprecates any use of these encodings. However, when the destination register is the PC:

.      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

.      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from AArch32
       state on page G1-3845.

.      The instruction is UNDEFINED in Hyp mode.

.      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.

This instruction is an alias of the MOV, MOVS (register) instruction. This means that:

.      The encodings in this description are named to match the encodings of MOV, MOVS (register).

.      The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.


A1


  31        28 27 26 25 24 23 22 21 20 19 18 17 16 15             12 11            7 6 5 4 3             0
     !=1111     0 0 0 1 1 0 1 1 (0) (0) (0) (0)              Rd             imm5      0 1 0        Rm
      cond                              S                                             type


MOVS, shift or rotate by value variant

LSRS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

is equivalent to

MOVS{<c>}{<q>} <Rd>, <Rm>, LSR #<imm>

and is always the preferred disassembly.


T2


  15 14 13 12 11 10               6 5       3 2       0
   0 0 0 0 1            imm5           Rn         Rd
              op


T2 variant

LSRS{<q>} {<Rd>,} <Rm>, #<imm>// Outside IT block

is equivalent to

MOVS{<q>} <Rd>, <Rm>, LSR #<imm>

and is the preferred disassembly when !InITBlock().
        T3


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                  12 11           8 7 6 5 4 3                0
           1 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 (0) imm3                             Rd       imm2 0 1           Rm
                                              S                                                  type


        MOVS, shift or rotate by value variant

        LSRS.W {<Rd>,} <Rm>, #<imm>// Outside IT block, and <Rd>, <Rm>, <imm> can be represented in T2

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, LSR #<imm>

        and is always the preferred disassembly.

        LSRS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, LSR #<imm>

        and is always the preferred disassembly.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
                        deprecates using the PC as the destination register, but if the PC is used, the instruction performs an
                        exception return, that restores PSTATE from SPSR_<current_mode>.

                        For encoding T2 and T3: is the general-purpose destination register, encoded in the "Rd" field.

        <Rm>            For encoding A1: is the general-purpose source register, encoded in the "Rm" field. The PC can be
                        used.

                        For encoding T2 and T3: is the general-purpose source register, encoded in the "Rm" field.

        <imm>           For encoding A1 and T2: is the shift amount, in the range 1 to 32, encoded in the "imm5" field as
                        <imm> modulo 32.

                        For encoding T3: is the shift amount, in the range 1 to 32, encoded in the "imm3:imm2" field as
                        <imm> modulo 32.


        Operation for all encodings

        The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','MCR','Move to Coprocessor from general-purpose register passes the value of a general-purpose register to a conceptual       (F7.1.104)
coprocessor.

This is a generic coprocessor instruction. The coproc field identifies the target conceptual coprocessor. This must be
one of CP10, CP11, CP14, or CP15, and for these CP values, this manual defines the opc1, opc2, CRn, and CRd field
values that are valid MCR and MCR2 instructions. Other encodings are UNDEFINED. For more information see
Conceptual coprocessor support on page E1-2414 and General behavior of System registers on page G4-4172.

In an implementation that includes EL2, MCR accesses to system control registers can be trapped to Hyp mode,
meaning that an attempt to execute an MCR instruction in a Non-secure mode other than Hyp mode, that would be
permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see EL2
configurable controls on page G1-3909.

Because of the range of possible traps to Hyp mode, the MCR pseudocode does not show these possible traps.


A1


  31        28 27 26 25 24 23      21 20 19        16 15        12 11          8 7       5 4 3          0
     !=1111     1 1 1 0       opc1     0     CRn            Rt         !=101x       opc2    1    CRm
      cond                                                              coproc


A1 variant

MCR{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}


Decode for this encoding

 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 t = UInt(Rt);    cp = UInt(coproc);
 if t == 15   then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


A2


  31        28 27 26 25 24 23      21 20 19        16 15        12 11          8 7       5 4 3          0
   1 1 1 1 1 1 1 0            opc1     0     CRn            Rt         !=101x       opc2    1    CRm
      cond                                                              coproc


A2 variant

MCR2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}


Decode for this encoding

 if coproc == ''101x'' then UNDEFINED;
 t = UInt(Rt);    cp = UInt(coproc);
 if t == 15   then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


T1


  15 14 13 12 11 10 9 8 7          5 4 3           0 15         12 11          8 7       5 4 3          0
   1 1 1 0 1 1 1 0            opc1     0     CRn            Rt         !=101x       opc2    1    CRm
                                                                        coproc


T1 variant

MCR{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}
        Decode for this encoding

         if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
         t = UInt(Rt);   cp = UInt(coproc);
         if t == 15   then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        T2


          15 14 13 12 11 10 9 8 7          5 4 3            0 15       12 11         8 7       5 4 3          0
           1 1 1 1 1 1 1 0            opc1    0      CRn           Rt        !=101x       opc2    1    CRm
                                                                             coproc


        T2 variant

        MCR2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}


        Decode for this encoding

         if coproc == ''101x'' then UNDEFINED;
         t = UInt(Rt);   cp = UInt(coproc);
         if t == 15   then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.

        Advanced SIMD and floating-point: 8, 16, and 32-bit transfers accessing the SIMD and floating-point register file
        on page F5-2606.


        Assembler symbols

        <c>            For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

                       For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <coproc>       Is the name of the coprocessor, encoded in the "coproc" field. The valid coprocessor names are p10,
                       p11, p14, and p15.

        <opc1>         Is a coprocessor-specific opcode in the range 0 to 7, encoded in the "opc1" field.

        <Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

        <CRn>          Is the first coprocessor register, encoded in the "CRn" field.

        <CRm>          Is the second coprocessor register, encoded in the "CRm" field.

        <opc2>         Is a coprocessor-specific opcode in the range 0 to 7, defaulting to 0 and encoded in the "opc2" field.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             Coproc_CheckInstr(cp, ThisInstr());
             Coproc_SendOneWord(R[t], cp, ThisInstr());');
INSERT INTO "instructions" VALUES('ARM','MCR2','-R:MCR');
INSERT INTO "instructions" VALUES('ARM','MCRR','Move to Coprocessor from two general-purpose registers passes the values of two general-purpose registers to a       (F7.1.105)
conceptual coprocessor.

This is a generic coprocessor instruction. The coproc field identifies the target conceptual coprocessor. This must be
one of CP10, CP11, CP14, or CP15, and for these CP values, this manual defines the opc1, and CRm field values that
are valid MCRR and MCRR2 instructions. Other encodings are UNDEFINED. For more information see Conceptual
coprocessor support on page E1-2414 and General behavior of System registers on page G4-4172.

In an implementation that includes EL2, MCRR accesses to system control registers can be trapped to Hyp mode,
meaning that an attempt to execute an MCRR instruction in a Non-secure mode other than Hyp mode, that would be
permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see EL2
configurable controls on page G1-3909.

Because of the range of possible traps to Hyp mode, the MCRR pseudocode does not show these possible traps.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15         12 11          8 7          4 3         0
     !=1111     1 1 0 0 0 1 0 0              Rt2            Rt         !=101x        opc1        CRm
      cond                                                              coproc


A1 variant

MCRR{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


Decode for this encoding

 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 t = UInt(Rt);    t2 = UInt(Rt2);   cp = UInt(coproc);
 if t == 15 || t2 == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13


A2


  31        28 27 26 25 24 23 22 21 20 19         16 15         12 11          8 7          4 3         0
   1 1 1 1 1 1 0 0 0 1 0 0                   Rt2            Rt         !=101x        opc1        CRm
      cond                                                              coproc


A2 variant

MCRR2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


Decode for this encoding

 if coproc == ''101x'' then UNDEFINED;
 t = UInt(Rt);    t2 = UInt(Rt2);   cp = UInt(coproc);
 if t == 15 || t2 == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11          8 7          4 3         0
   1 1 1 0 1 1 0 0 0 1 0 0                   Rt2            Rt         !=101x        opc1        CRm
                                                                        coproc
        T1 variant

        MCRR{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


        Decode for this encoding

         if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
         t = UInt(Rt);   t2 = UInt(Rt2);     cp = UInt(coproc);
         if t == 15 || t2 == 15 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13


        T2


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11        8 7          4 3          0
           1 1 1 1 1 1 0 0 0 1 0 0                    Rt2           Rt         !=101x        opc1         CRm
                                                                               coproc


        T2 variant

        MCRR2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


        Decode for this encoding

         if coproc == ''101x'' then UNDEFINED;
         t = UInt(Rt);   t2 = UInt(Rt2);     cp = UInt(coproc);
         if t == 15 || t2 == 15 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.

        Advanced SIMD and floating-point: 64-bit transfers accessing the SIMD and floating-point register file on
        page F5-2607.


        Assembler symbols

        <c>             For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

                        For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <coproc>        Is the name of the coprocessor, encoded in the "coproc" field. The valid coprocessor names are p10,
                        p11, p14, and p15.

        <opc1>          Is a coprocessor-specific opcode in the range 0 to 15, encoded in the "opc1" field.

        <Rt>            Is the first general-purpose register to be transferred, encoded in the "Rt" field.

        <Rt2>           Is the second general-purpose register to be transferred, encoded in the "Rt2" field.

        <CRm>           Is a coprocessor register, encoded in the "CRm" field.

        The relative significance of <Rt2> and <Rt> is IMPLEMENTATION DEFINED for IMPLEMENTATION DEFINED uses of the
        MCRR and MRRC instructions. For the architected uses, as described in this manual, <Rt2> transfers bits[63:32] of the
        selected coprocessor register, while <Rt> transfers bits[31:0].
Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    Coproc_CheckInstr(cp, ThisInstr());
    Coproc_SendTwoWords(R[t2], R[t], cp, ThisInstr());');
INSERT INTO "instructions" VALUES('ARM','MCRR2','-R:MCRR');
INSERT INTO "instructions" VALUES('ARM','MLAS','        Multiply Accumulate multiplies two register values, and adds a third register value. The least significant 32 bits of       (F7.1.106)
        the result are written to the destination register. These 32 bits do not depend on whether the source register values
        are considered to be signed values or unsigned values.

        In an A32 instruction, the condition flags can optionally be updated based on the result. Use of this option adversely
        affects performance on many implementations.


        A1


          31        28 27 26 25 24 23 22 21 20 19            16 15        12 11       8 7 6 5 4 3                0
             !=1111     0 0 0 0 0 0 1 S                Rd           Ra           Rm      1 0 0 1          Rn
              cond


        Flag setting variant

        Applies when S = 1.

        MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Not flag setting variant

        Applies when S = 0.

        MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);    a = UInt(Ra);   setflags = (S == ''1'');
         if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15         12 11       8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 0 0 0 0                     Rn         !=1111         Rd      0 0 0 0          Rm
                                                                    Ra


        T1 variant

        MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for this encoding

         if Ra == ''1111'' then SEE MUL;
         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);    a = UInt(Ra);   setflags = FALSE;
         if d == 15 || n == 15 || m      == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.
<Rn>          Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.

<Ra>          Is the third general-purpose source register holding the addend, encoded in the "Ra" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    operand1 = SInt(R[n]);     // operand1 = UInt(R[n]) produces the same final results
    operand2 = SInt(R[m]);     // operand2 = UInt(R[m]) produces the same final results
    addend    = SInt(R[a]);    // addend    = UInt(R[a]) produces the same final results
    result = operand1 * operand2 + addend;
    R[d] = result<31:0>;
    if setflags then
        PSTATE.N = result<31>;
        PSTATE.Z = IsZeroBit(result<31:0>);
        // PSTATE.C, PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','MOVS','        Move (immediate) writes an immediate value to the destination register.       (F7.1.108)

        If the destination register is not the PC, the MOVS variant of the instruction updates the condition flags based on
        the result.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The MOV variant of the instruction is an interworking branch, see Pseudocode description of operations on
               the AArch32 general-purpose registers and the PC on page E1-2378.

        .      The MOVS variant of the instruction performs an exception return without the use of the stack. In this case:

               --      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

               --      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from
                      AArch32 state on page G1-3845.

               --      The instruction is UNDEFINED in Hyp mode.

               --      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.


        A1


          31        28 27 26 25 24 23 22 21 20 19 18 17 16 15          12 11                                   0
             !=1111     0 0 1 1 1 0 1 S (0) (0) (0) (0)            Rd                     imm12
              cond


        MOV variant

        Applies when S = 0.

        MOV{<c>}{<q>} <Rd>, #<const>


        MOVS variant

        Applies when S = 1.

        MOVS{<c>}{<q>} <Rd>, #<const>


        Decode for all variants of this encoding

         d = UInt(Rd);    setflags = (S == ''1'');      (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C);


        A2


          31        28 27 26 25 24 23 22 21 20 19          16 15       12 11                                   0
             !=1111     0 0 1 1 0 0 0 0               imm4         Rd                     imm12
              cond


        A2 variant

        MOV{<c>}{<q>} <Rd>, #<imm16>// <imm16> can not be represented in A1
        MOVW{<c>}{<q>} <Rd>, #<imm16>// <imm16> can be represented in A1


        Decode for this encoding

         d = UInt(Rd);    setflags = FALSE;     imm32 = ZeroExtend(imm4:imm12, 32);
         if d == 15 then UNPREDICTABLE;
T1


  15 14 13 12 11 10    8 7                    0
  0 0 1 0 0        Rd             imm8




T1 variant

MOV<c>{<q>} <Rd>, #<imm8>// Inside IT block
MOVS{<q>} <Rd>, #<imm8>// Outside IT block


Decode for this encoding

 d = UInt(Rd);  setflags = !InITBlock();  imm32 = ZeroExtend(imm8, 32);     carry = PSTATE.C;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14              12 11        8 7                      0
  1 1 1 1 0 i 0 0 0 1 0 S 1 1 1 1 0                   imm3         Rd              imm8




MOV variant

Applies when S = 0.

MOV<c>.W <Rd>, #<const>// Inside IT block, and <Rd>, <const> can be represented in T1
MOV{<c>}{<q>} <Rd>, #<const>


MOVS variant

Applies when S = 1.

MOVS.W <Rd>, #<const>// Outside IT block, and <Rd>, <const> can be represented in T1
MOVS{<c>}{<q>} <Rd>, #<const>


Decode for all variants of this encoding

 d = UInt(Rd);  setflags = (S == ''1'');  (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C);
 if d == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


T3


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15 14      12 11        8 7                      0
  1 1 1 1 0 i 1 0 0 1 0 0               imm4      0   imm3         Rd              imm8




T3 variant

MOV{<c>}{<q>} <Rd>, #<imm16>// <imm16> cannot be represented in T1 or T2
MOVW{<c>}{<q>} <Rd>, #<imm16>// <imm16> can be represented in T1 or T2


Decode for this encoding

 d = UInt(Rd);  setflags = FALSE;  imm32 = ZeroExtend(imm4:i:imm3:imm8, 32);
 if d == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rd>           For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
                       deprecates using the PC as the destination register, but if the PC is used:

                       .      For the MOV variant, the instruction is a branch to the address calculated by the operation.
                              This is an interworking branch, see Pseudocode description of operations on the AArch32
                              general-purpose registers and the PC on page E1-2378.

                       .      For the MOVS variant, the instruction performs an exception return, that restores PSTATE
                              from SPSR_<current_mode>.

                       For encoding A2, T1, T2 and T3: is the general-purpose destination register, encoded in the "Rd"
                       field.

        <imm8>         Is a 8-bit unsigned immediate, in the range 0 to 255, encoded in the "imm8" field.

        <imm16>        For encoding A2: is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the
                       "imm4:imm12" field.

                       For encoding T3: is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the
                       "imm4:i:imm3:imm8" field.

        <const>        For encoding A1: an immediate value. See Modified immediate constants in A32 instructions on
                       page F4-2559 for the range of values.

                       For encoding T2: an immediate value. See Modified immediate constants in T32 instructions on
                       page F3-2530 for the range of values.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             result = imm32;
             if d == 15 then            // Can only occur for encoding A1
                 if setflags then
                      ALUExceptionReturn(result);
                 else
                      ALUWritePC(result);
             else
                 R[d] = result;
                 if setflags then
                      PSTATE.N = result<31>;
                      PSTATE.Z = IsZeroBit(result);
                      PSTATE.C = carry;
                      // PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','MOVT','Move Top writes an immediate value to the top halfword of the destination register. It does not affect the contents       (F7.1.111)
of the bottom halfword.


A1


  31        28 27 26 25 24 23 22 21 20 19       16 15         12 11                                  0
     !=1111    0 0 1 1 0 1 0 0            imm4           Rd                     imm12
      cond


A1 variant

MOVT{<c>}{<q>} <Rd>, #<imm16>


Decode for this encoding

 d = UInt(Rd);   imm16 = imm4:imm12;
 if d == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15 14      12 11         8 7                      0
   1 1 1 1 0 i 1 0 1 1 0 0                imm4      0    imm3         Rd               imm8




T1 variant

MOVT{<c>}{<q>} <Rd>, #<imm16>


Decode for this encoding

 d = UInt(Rd);   imm16 = imm4:i:imm3:imm8;
 if d == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<imm16>        For encoding A1: is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the
               "imm4:imm12" field.

               For encoding T1: is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the
               "imm4:i:imm3:imm8" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             R[d]<31:16> = imm16;
             // R[d]<15:0> unchanged');
INSERT INTO "instructions" VALUES('ARM','MRC','Move to general-purpose register from Coprocessor causes a conceptual coprocessor to transfer a value to a       (F7.1.112)
general-purpose register or to the condition flags.

This is a generic coprocessor instruction. The coproc field identifies the target conceptual coprocessor. This must be
one of CP10, CP11, CP14, or CP15, and for these CP values, this manual defines the opc1, opc2, CRn, and CRd field
values that are valid MRC and MRC2 instructions. Other encodings are UNDEFINED. For more information see
Conceptual coprocessor support on page E1-2414 and General behavior of System registers on page G4-4172.

In an implementation that includes EL2, MRC accesses to system control registers can be trapped to Hyp mode,
meaning that an attempt to execute an MRC instruction in a Non-secure mode other than Hyp mode, that would be
permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see EL2
configurable controls on page G1-3909.

Because of the range of possible traps to Hyp mode, the MRC pseudocode does not show these possible traps.


A1


  31        28 27 26 25 24 23      21 20 19        16 15        12 11          8 7       5 4 3          0
     !=1111     1 1 1 0       opc1     1     CRn            Rt         !=101x       opc2    1    CRm
      cond                                                              coproc


A1 variant

MRC{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}


Decode for this encoding

 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 t = UInt(Rt);    cp = UInt(coproc);
 // ARMv8-A removes UNPREDICTABLE for R13


A2


  31        28 27 26 25 24 23      21 20 19        16 15        12 11          8 7       5 4 3          0
   1 1 1 1 1 1 1 0            opc1     1     CRn            Rt         !=101x       opc2    1    CRm
      cond                                                              coproc


A2 variant

MRC2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}


Decode for this encoding

 if coproc == ''101x'' then UNDEFINED;
 t = UInt(Rt);    cp = UInt(coproc);
 // ARMv8-A removes UNPREDICTABLE for R13


T1


  15 14 13 12 11 10 9 8 7          5 4 3           0 15         12 11          8 7       5 4 3          0
   1 1 1 0 1 1 1 0            opc1     1     CRn            Rt         !=101x       opc2    1    CRm
                                                                        coproc


T1 variant

MRC{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}
        Decode for this encoding

         if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
         t = UInt(Rt);  cp = UInt(coproc);
         // ARMv8-A removes UNPREDICTABLE for R13


        T2


          15 14 13 12 11 10 9 8 7          5 4 3            0 15        12 11         8 7       5 4 3            0
           1 1 1 1 1 1 1 0            opc1    1      CRn           Rt          !=101x     opc2     1     CRm
                                                                               coproc


        T2 variant

        MRC2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <CRn>, <CRm>{, {#}<opc2>}


        Decode for this encoding

         if coproc == ''101x'' then UNDEFINED;
         t = UInt(Rt);  cp = UInt(coproc);
         // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.

        Advanced SIMD and floating-point: 8, 16, and 32-bit transfers accessing the SIMD and floating-point register file
        on page F5-2606.


        Assembler symbols

        <c>            For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

                       For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <coproc>       Is the name of the coprocessor, encoded in the "coproc" field. The valid coprocessor names are p10,
                       p11, p14, and p15.

        <opc1>         Is a coprocessor-specific opcode in the range 0 to 7, encoded in the "opc1" field.

        <Rt>           Is the general-purpose register to be transferred or APSR_nzcv (encoded as 0b1111), encoded in the
                       "Rt" field. If APSR_nzcv is used, bits [31:28] of the transferred value are written to the PSTATE
                       condition flags.

        <CRn>          Is the first coprocessor register, encoded in the "CRn" field.

        <CRm>          Is the second coprocessor register, encoded in the "CRm" field.

        <opc2>         Is a coprocessor-specific opcode in the range 0 to 7, defaulting to 0 and encoded in the "opc2" field.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             Coproc_CheckInstr(cp, ThisInstr());
             value = Coproc_GetOneWord(cp, ThisInstr());
             if t != 15 then
                 R[t] = value;
             elsif Coproc_CanWriteAPSR(cp, ThisInstr()) then
                 PSTATE.<N,Z,C,V> = value<31:28>;
      // value<27:0> are not used.
   else
      PSTATE.<N,Z,C,V> = bits(4) UNKNOWN;');
INSERT INTO "instructions" VALUES('ARM','MRC2','-R:MRC');
INSERT INTO "instructions" VALUES('ARM','MRRC','        Move to two general-purpose registers from Coprocessor causes a conceptual coprocessor to transfer values to two       (F7.1.113)
        general-purpose registers.

        This is a generic coprocessor instruction. The coproc field identifies the target conceptual coprocessor. This must be
        one of CP10, CP11, CP14, or CP15, and for these CP values, this manual defines the opc1, and CRm field values that
        are valid MRRC and MRRC2 instructions. Other encodings are UNDEFINED. For more information see Conceptual
        coprocessor support on page E1-2414 and General behavior of System registers on page G4-4172.

        In an implementation that includes EL2, MRRC accesses to system control registers can be trapped to Hyp mode,
        meaning that an attempt to execute an MRRC instruction in a Non-secure mode other than Hyp mode, that would be
        permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see EL2
        configurable controls on page G1-3909.

        Because of the range of possible traps to Hyp mode, the MRRC pseudocode does not show these possible traps.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15         12 11          8 7          4 3         0
             !=1111     1 1 0 0 0 1 0 1              Rt2            Rt         !=101x        opc1        CRm
              cond                                                              coproc


        A1 variant

        MRRC{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


        Decode for this encoding

         if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
         t = UInt(Rt);    t2 = UInt(Rt2);   cp = UInt(coproc);
         if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        A2


          31        28 27 26 25 24 23 22 21 20 19         16 15         12 11          8 7          4 3         0
           1 1 1 1 1 1 0 0 0 1 0 1                   Rt2            Rt         !=101x        opc1        CRm
              cond                                                              coproc


        A2 variant

        MRRC2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


        Decode for this encoding

         if coproc == ''101x'' then UNDEFINED;
         t = UInt(Rt);    t2 = UInt(Rt2);   cp = UInt(coproc);
         if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11          8 7          4 3         0
           1 1 1 0 1 1 0 0 0 1 0 1                   Rt2            Rt         !=101x        opc1        CRm
                                                                                coproc
T1 variant

MRRC{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


Decode for this encoding

 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 t = UInt(Rt);   t2 = UInt(Rt2);     cp = UInt(coproc);
 if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11        8 7          4 3          0
   1 1 1 1 1 1 0 0 0 1 0 1                    Rt2           Rt         !=101x        opc1         CRm
                                                                       coproc


T2 variant

MRRC2{<c>}{<q>} <coproc>, {#}<opc1>, <Rt>, <Rt2>, <CRm>


Decode for this encoding

 if coproc == ''101x'' then UNDEFINED;
 t = UInt(Rt);   t2 = UInt(Rt2);     cp = UInt(coproc);
 if t == 15 || t2 == 15 || t == t2 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

Advanced SIMD and floating-point: 64-bit transfers accessing the SIMD and floating-point register file on
page F5-2607.


Assembler symbols

<c>             For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

                For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

<q>             See Standard assembler syntax fields on page F2-2506.

<coproc>        Is the name of the coprocessor, encoded in the "coproc" field. The valid coprocessor names are p10,
                p11, p14, and p15.

<opc1>          Is a coprocessor-specific opcode in the range 0 to 15, encoded in the "opc1" field.

<Rt>            Is the first general-purpose register to be transferred, encoded in the "Rt" field.

<Rt2>           Is the second general-purpose register to be transferred, encoded in the "Rt2" field.

<CRm>           Is a coprocessor register, encoded in the "CRm" field.

The relative significance of <Rt2> and {syntax{<Rt>} is IMPLEMENTATION DEFINED for IMPLEMENTATION DEFINED
uses of the MCRR and MRRC instructions. For the architected uses, as described in this manual, <Rt2> transfers
bits[63:32] of the selected coprocessor register, while <Rt> transfers bits[31:0].


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     Coproc_CheckInstr(cp, ThisInstr());
     (R[t2], R[t]) = Coproc_GetTwoWords(cp, ThisInstr());');
INSERT INTO "instructions" VALUES('ARM','MRRC2','-R:MRRC');
INSERT INTO "instructions" VALUES('ARM','MULS','        Multiply multiplies two register values. The least significant 32 bits of the result are written to the destination       (F7.1.119)
        register. These 32 bits do not depend on whether the source register values are considered to be signed values or
        unsigned values.

        Optionally, it can update the condition flags based on the result. In the T32 instruction set, this option is limited to
        only a few forms of the instruction. Use of this option adversely affects performance on many implementations.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11           8 7 6 5 4 3                0
             !=1111     0 0 0 0 0 0 0 S               Rd     (0) (0) (0) (0)    Rm       1 0 0 1            Rn
              cond


        Flag setting variant

        Applies when S = 1.

        MULS{<c>}{<q>} <Rd>, <Rn>{, <Rm>}


        Not flag setting variant

        Applies when S = 0.

        MUL{<c>}{<q>} <Rd>, <Rn>{, <Rm>}


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);   m = UInt(Rm);   setflags = (S == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5             3 2      0
           0 1 0 0 0 0 1 1 0 1               Rn       Rdm




        T1 variant

        MUL<c>{<q>} <Rdm>, <Rn>{, <Rdm>}// Inside IT block
        MULS{<q>} <Rdm>, <Rn>{, <Rdm>}// Outside IT block


        Decode for this encoding

         d = UInt(Rdm);    n = UInt(Rn);   m = UInt(Rdm);    setflags = !InITBlock();


        T2


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11           8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 0 0 0 0                    Rn      1 1 1 1           Rd       0 0 0 0           Rm




        T2 variant

        MUL<c>.W <Rd>, <Rn>{, <Rm>}// Inside IT block, and <Rd>, <Rn>, <Rm> can be represented in T1
        MUL{<c>}{<q>} <Rd>, <Rn>{, <Rm>}
Decode for this encoding

 d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);  setflags = FALSE;
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rdm>          Is the second general-purpose source register holding the multiplier and the destination register,
               encoded in the "Rdm" field.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field. If
               omitted, <Rd> is used.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand1 = SInt(R[n]);     // operand1 = UInt(R[n]) produces the same final results
     operand2 = SInt(R[m]);     // operand2 = UInt(R[m]) produces the same final results
     result = operand1 * operand2;
     R[d] = result<31:0>;
     if setflags then
         PSTATE.N = result<31>;
         PSTATE.Z = IsZeroBit(result<31:0>);
         // PSTATE.C, PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','MVNS','        Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register.       (F7.1.120)

        If the destination register is not the PC, the MVNS variant of the instruction updates the condition flags based on
        the result.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The MVN variant of the instruction is an interworking branch, see Pseudocode description of operations on
               the AArch32 general-purpose registers and the PC on page E1-2378.

        .      The MVNS variant of the instruction performs an exception return without the use of the stack. In this case:

               --      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

               --      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from
                      AArch32 state on page G1-3845.

               --      The instruction is UNDEFINED in Hyp mode.

               --      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.


        A1


          31        28 27 26 25 24 23 22 21 20 19 18 17 16 15          12 11                                   0
             !=1111     0 0 1 1 1 1 1 S (0) (0) (0) (0)            Rd                     imm12
              cond


        MVN variant

        Applies when S = 0.

        MVN{<c>}{<q>} <Rd>, #<const>


        MVNS variant

        Applies when S = 1.

        MVNS{<c>}{<q>} <Rd>, #<const>


        Decode for all variants of this encoding

         d = UInt(Rd);    setflags = (S == ''1'');
         (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C);


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                  12 11         8 7                       0
           1 1 1 1 0        i  0 0 0 1 1 S 1 1 1 1 0                imm3        Rd               imm8




        MVN variant

        Applies when S = 0.

        MVN{<c>}{<q>} <Rd>, #<const>


        MVNS variant

        Applies when S = 1.

        MVNS{<c>}{<q>} <Rd>, #<const>
Decode for all variants of this encoding

 d = UInt(Rd);   setflags = (S == ''1'');
 (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C);
 if d == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
               deprecates using the PC as the destination register, but if the PC is used:

               .     For the MVN variant, the instruction is a branch to the address calculated by the operation.
                     This is an interworking branch, see Pseudocode description of operations on the AArch32
                     general-purpose registers and the PC on page E1-2378.

               .     For the MVNS variant, the instruction performs an exception return, that restores PSTATE
                     from SPSR_<current_mode>.

               For encoding T1: is the general-purpose destination register, encoded in the "Rd" field.

<const>        For encoding A1: an immediate value. See Modified immediate constants in A32 instructions on
               page F4-2559 for the range of values.

               For encoding T1: an immediate value. See Modified immediate constants in T32 instructions on
               page F3-2530 for the range of values.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     result = NOT(imm32);
     if d == 15 then           // Can only occur for A32 encoding
         if setflags then
              ALUExceptionReturn(result);
         else
              ALUWritePC(result);
     else
         R[d] = result;
         if setflags then
              PSTATE.N = result<31>;
              PSTATE.Z = IsZeroBit(result);
              PSTATE.C = carry;
              // PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','ORNS','Bitwise OR NOT (immediate) performs a bitwise (inclusive) OR of a register value and the complement of an       (F7.1.124)
immediate value, and writes the result to the destination register. It can optionally update the condition flags based
on the result.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14      12 11          8 7                      0
  1 1 1 1 0 i 0 0 0 1 1 S                  !=1111      0   imm3          Rd                imm8
                                             Rn


Flag setting variant

Applies when S = 1.

ORNS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


Not flag setting variant

Applies when S = 0.

ORN{<c>}{<q>} {<Rd>,} <Rn>, #<const>


Decode for all variants of this encoding

 if Rn == ''1111'' then SEE MVN (immediate);
 d = UInt(Rd);  n = UInt(Rn);    setflags = (S == ''1'');
 (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C);
 if d == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field. If omitted, this register is the
               same as <Rn>.

<Rn>           Is the general-purpose source register, encoded in the "Rn" field.

<const>        An immediate value. See Modified immediate constants in T32 instructions on page F3-2530 for the
               range of values.


Operation

 if ConditionPassed() then
     EncodingSpecificOperations();
     result = R[n] OR NOT(imm32);
     R[d] = result;
     if setflags then
         PSTATE.N = result<31>;
         PSTATE.Z = IsZeroBit(result);
         PSTATE.C = carry;
         // PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','ORRS','        Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and writes       (F7.1.126)
        the result to the destination register.

        If the destination register is not the PC, the ORRS variant of the instruction updates the condition flags based on the
        result.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The ORR variant of the instruction is an interworking branch, see Pseudocode description of operations on
               the AArch32 general-purpose registers and the PC on page E1-2378.

        .      The ORRS variant of the instruction performs an exception return without the use of the stack. In this case:

               --       The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

               --       The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from
                       AArch32 state on page G1-3845.

               --       The instruction is UNDEFINED in Hyp mode.

               --       The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.


        A1


           31       28 27 26 25 24 23 22 21 20 19            16 15       12 11                                   0
             !=1111     0 0 1 1 1 0 0 S                 Rn          Rd                      imm12
               cond


        ORR variant

        Applies when S = 0.

        ORR{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        ORRS variant

        Applies when S = 1.

        ORRS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        Decode for all variants of this encoding

         d = UInt(Rd);     n = UInt(Rn);     setflags = (S == ''1'');
         (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14     12 11         8 7                       0
           1 1 1 1 0 i 0 0 0 1 0 S                     !=1111    0   imm3        Rd                 imm8
                                                        Rn


        ORR variant

        Applies when S = 0.

        ORR{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        ORRS variant

        Applies when S = 1.
ORRS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


Decode for all variants of this encoding

 if Rn == ''1111'' then SEE MOV (immediate);
 d = UInt(Rd);   n = UInt(Rn);     setflags = (S == ''1'');
 (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C);
 if d == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. If omitted,
               this register is the same as <Rn>. ARM deprecates using the PC as the destination register, but if the
               PC is used:

               .      For the ORR variant, the instruction is a branch to the address calculated by the operation.
                      This is an interworking branch, see Pseudocode description of operations on the AArch32
                      general-purpose registers and the PC on page E1-2378.

               .      For the ORRS variant, the instruction performs an exception return, that restores PSTATE
                      from SPSR_<current_mode>.

               For encoding T1: is the general-purpose destination register, encoded in the "Rd" field. If omitted,
               this register is the same as <Rn>.

<Rn>           For encoding A1: is the general-purpose source register, encoded in the "Rn" field. The PC can be
               used.

               For encoding T1: is the general-purpose source register, encoded in the "Rn" field.

<const>        For encoding A1: an immediate value. See Modified immediate constants in A32 instructions on
               page F4-2559 for the range of values.

               For encoding T1: an immediate value. See Modified immediate constants in T32 instructions on
               page F3-2530 for the range of values.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     result = R[n] OR imm32;
     if d == 15 then              // Can only occur for A32 encoding
         if setflags then
              ALUExceptionReturn(result);
         else
              ALUWritePC(result);
     else
         R[d] = result;
         if setflags then
              PSTATE.N = result<31>;
              PSTATE.Z = IsZeroBit(result);
              PSTATE.C = carry;
              // PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','PKHBT','        Pack Halfword combines one halfword of its first operand with the other halfword of its shifted second operand.       (F7.1.129)


        A1


          31       28 27 26 25 24 23 22 21 20 19         16 15       12 11           7 6 5 4 3              0
             !=1111   0 1 1 0 1 0 0 0                 Rn         Rd          imm5      tb 0 1         Rm
              cond


        PKHBT variant

        Applies when tb = 0.

        PKHBT{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, LSL #<imm>}


        PKHTB variant

        Applies when tb = 1.

        PKHTB{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ASR #<imm>}


        Decode for all variants of this encoding

         d = UInt(Rd);  n = UInt(Rn);    m = UInt(Rm);   tbform = (tb == ''1'');
         (shift_t, shift_n) = DecodeImmShift(tb:''0'', imm5);
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                0 15 14     12 11       8 7 6 5 4 3                0
           1 1 1 0 1 0 1 0 1 1 0 0                    Rn     (0)  imm3      Rd      imm2 tb 0         Rm
                                              S                                               T


        PKHBT variant

        Applies when tb = 0.

        PKHBT{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, LSL #<imm>}// tbform == FALSE


        PKHTB variant

        Applies when tb = 1.

        PKHTB{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ASR #<imm>}// tbform == TRUE


        Decode for all variants of this encoding

         if S == ''1'' || T == ''1'' then UNDEFINED;
         d = UInt(Rd);  n = UInt(Rn);    m = UInt(Rm);   tbform = (tb == ''1'');
         (shift_t, shift_n) = DecodeImmShift(tb:''0'', imm3:imm2);
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>          Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register, encoded in the "Rm" field.

<imm>         For encoding A1: the shift to apply to the value read from <Rm>, encoded in imm5. Is one of:

              omitted      No shift, encoded as 0b00000.

              1-31         Left shift by specified number of bits, encoded as a binary number.

              For encoding A1: the shift to apply to the value read from <Rm>, encoded in imm5. Is one of:

              omitted      Instruction is a pseudo-instruction and is assembled as though PKHBT{<c>}{<q>} <Rd>,
                           <Rm>, <Rn> had been written.

              1-32         Arithmetic right shift by specified number of bits. A shift by 32 bits is encoded as
                           0b00000. Other shift amounts are encoded as binary numbers.

                        Note
              An assembler can permit <imm> = 0 to mean the same thing as omitting the shift, but this is not
              standard UAL and must not be used for disassembly.


              For encoding T1: the shift to apply to the value read from <Rm>, encoded in imm3:imm2. For PKHBT,
              it is one of:

              omitted      No shift, encoded as 0b00000.

              1-31         Left shift by specified number of bits, encoded as a binary number.

               For PKHTB, it is one of:

              omitted      Instruction is a pseudo-instruction and is assembled as though PKHBT{<c>}{<q>} <Rd>,
                           <Rm>, <Rn> had been written.

              1-32         Arithmetic right shift by specified number of bits. A shift by 32 bits is encoded as
                           0b00000. Other shift amounts are encoded as binary numbers.

                        Note
              An assembler can permit <imm> = 0 to mean the same thing as omitting the shift, but this is not
              standard UAL and must not be used for disassembly.



Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    operand2 = Shift(R[m], shift_t, shift_n, PSTATE.C);        // PSTATE.C ignored
    R[d]<15:0>   = if tbform then operand2<15:0> else R[n]<15:0>;
    R[d]<31:16> = if tbform then R[n]<31:16>         else operand2<31:16>;');
INSERT INTO "instructions" VALUES('ARM','PKHTB','-R:PKHBT');
INSERT INTO "instructions" VALUES('ARM','PLD','        Preload Data (immediate) signals the memory system that data memory accesses from a specified address are likely       (F7.1.130)
        in the near future. The memory system can respond by taking actions that are expected to speed up the memory
        accesses when they do occur, such as preloading the cache line containing the specified address into the data cache.

        The PLD instruction signals that the likely memory access is a read, and the PLDW instruction signals that it is a write.

        The effect of a PLD or PLDW instruction is IMPLEMENTATION DEFINED. For more information, see Preloading caches
        on page E2-2425.


        A1


          31 30 29 28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11                                    0
           1 1 1 1 0 1 0 1 U R 0 1                   !=1111   (1) (1) (1) (1)              imm12
                                                      Rn


        Preload read variant

        Applies when R = 1.

        PLD{<c>}{<q>} [<Rn> {, #{+/-}<imm>}]


        Preload write variant

        Applies when R = 0.

        PLDW{<c>}{<q>} [<Rn> {, #{+/-}<imm>}]


        Decode for all variants of this encoding

         if Rn == ''1111'' then SEE PLD (literal);
         n = UInt(Rn);    imm32 = ZeroExtend(imm12, 32);     add = (U == ''1'');     is_pldw = (R == ''0'');


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11                                     0
           1 1 1 1 1 0 0 0 1 0 W 1                   !=1111    1 1 1 1                     imm12
                                                      Rn


        Preload read variant

        Applies when W = 0.

        PLD{<c>}{<q>} [<Rn> {, #{+}<imm>}]


        Preload write variant

        Applies when W = 1.

        PLDW{<c>}{<q>} [<Rn> {, #{+}<imm>}]


        Decode for all variants of this encoding

         if Rn == ''1111'' then SEE PLD (literal);
         n = UInt(Rn);    imm32 = ZeroExtend(imm12, 32);     add = TRUE;     is_pldw = (W == ''1'');
T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11 10 9 8 7                            0
  1 1 1 1 1 0 0 0 0 0 W 1                  !=1111     1 1 1 1 1 1 0 0                    imm8
                                             Rn


Preload read variant

Applies when W = 0.

PLD{<c>}{<q>} [<Rn> {, #-<imm>}]


Preload write variant

Applies when W = 1.

PLDW{<c>}{<q>} [<Rn> {, #-<imm>}]


Decode for all variants of this encoding

 if Rn == ''1111'' then SEE PLD (literal);
 n = UInt(Rn);  imm32 = ZeroExtend(imm8, 32);       add = FALSE;   is_pldw = (W == ''1'');


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            For encoding A1: see Standard assembler syntax fields on page F2-2506. Must be AL or omitted.

               For encoding T1 and T2: see Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field. If the PC is used, see PLD (literal).

+/-            Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
               encoded in the "U" field. It can have the following values:

               -           when U = 0

               +           when U = 1

+              Specifies the offset is added to the base register.

<imm>          For encoding A1: is the optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
               defaulting to 0 and encoded in the "imm12" field.

               For encoding T1: is an optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
               defaulting to 0 and encoded in the "imm12" field.

               For encoding T2: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
               defaulting to 0 and encoded in the "imm8" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = if add then (R[n] + imm32) else (R[n] - imm32);
     if is_pldw then
         Hint_PreloadDataForWrite(address);
     else
         Hint_PreloadData(address);');
INSERT INTO "instructions" VALUES('ARM','PLDW','-R:PLD');
INSERT INTO "instructions" VALUES('ARM','PLI','        Preload Instruction signals the memory system that instruction memory accesses from a specified address are likely       (F7.1.133)
        in the near future. The memory system can respond by taking actions that are expected to speed up the memory
        accesses when they do occur, such as pre-loading the cache line containing the specified address into the instruction
        cache.

        The effect of a PLI instruction is IMPLEMENTATION DEFINED. For more information, see Preloading caches on
        page E2-2425.


        A1


          31 30 29 28 27 26 25 24 23 22 21 20 19          16 15 14 13 12 11                                    0
           1 1 1 1 0 1 0 0 U 1 0 1                    Rn      (1) (1) (1) (1)            imm12




        A1 variant

        PLI{<c>}{<q>} [<Rn> {, #{+/-}<imm>}]
        PLI{<c>}{<q>} <label>// Normal form
        PLI{<c>}{<q>} [PC, #{+/-}<imm>]// Alternative form


        Decode for this encoding

         n = UInt(Rn);    imm32 = ZeroExtend(imm12, 32);     add = (U == ''1'');


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11                                     0
           1 1 1 1 1 0 0 1 1 0 0 1                  !=1111     1 1 1 1                   imm12
                                                      Rn


        T1 variant

        PLI{<c>}{<q>} [<Rn> {, #{+}<imm>}]


        Decode for this encoding

         if Rn == ''1111'' then SEE encoding T3;
         n = UInt(Rn);    imm32 = ZeroExtend(imm12, 32);     add = TRUE;


        T2


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11 10 9 8 7                            0
           1 1 1 1 1 0 0 1 0 0 0 1                  !=1111     1 1 1 1 1 1 0 0                   imm8
                                                      Rn


        T2 variant

        PLI{<c>}{<q>} [<Rn> {, #-<imm>}]


        Decode for this encoding

         if Rn == ''1111'' then SEE encoding T3;
         n = UInt(Rn);    imm32 = ZeroExtend(imm8, 32);    add = FALSE;
T3


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11                                                     0
   1 1 1 1 1 0 0 1 U 0 0 1 1 1 1 1 1 1 1 1                                            imm12




T3 variant

PLI{<c>}{<q>} <label>// Preferred syntax
PLI{<c>}{<q>} [PC, #{+/-}<imm>]// Alternative syntax


Decode for this encoding

 n = 15;   imm32 = ZeroExtend(imm12, 32);       add = (U == ''1'');


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>              For encoding A1: see Standard assembler syntax fields on page F2-2506. Must be AL or omitted.

                 For encoding T1, T2 and T3: see Standard assembler syntax fields on page F2-2506.

<q>              See Standard assembler syntax fields on page F2-2506.

<label>          The label of the instruction that is likely to be accessed in the near future. The assembler calculates
                 the required value of the offset from the Align(PC, 4) value of the instruction to this label. The offset
                 must be in the range 4095 to 4095. If the offset is zero or positive, imm32 is equal to the offset and
                 add == TRUE. If the offset is negative, imm32 is equal to minus the offset and add == FALSE.

<Rn>             Is the general-purpose base register, encoded in the "Rn" field.

+/-              Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
                 encoded in the "U" field. It can have the following values:

                 -            when U = 0

                 +            when U = 1

+                Specifies the offset is added to the base register.

<imm>            For encoding A1: is the optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
                 defaulting to 0 and encoded in the "imm12" field.

                 For encoding T1: is an optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
                 defaulting to 0 and encoded in the "imm12" field.

                 For encoding T2: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                 defaulting to 0 and encoded in the "imm8" field.

                 For encoding T3: is a 12-bit unsigned immediate byte offset, in the range 0 to 4095, encoded in the
                 "imm12" field.

For the literal forms of the instruction, encoding T3 is used, or Rn is encoded as 0b1111 in encoding A1, to indicate
that the PC is the base register.

The alternative literal syntax permits the addition or subtraction of the offset and the immediate offset to be specified
separately, including permitting a subtraction of 0 that cannot be specified using the normal syntax. For more
information, see Use of labels in UAL instruction syntax on page F1-2469.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             base = if n == 15 then Align(PC,4) else R[n];
             address = if add then (base + imm32) else (base - imm32);
             Hint_PreloadInstr(address);');
INSERT INTO "instructions" VALUES('ARM','POP','Pop Multiple Registers from Stack loads multiple general-purpose registers from the stack, loading from       (F7.1.135)
consecutive memory locations starting at the address in SP, and updates SP to point just above the loaded data.

The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
page F2-2514.

The registers loaded can include the PC, causing a branch to a loaded address. This is an interworking branch, see
Pseudocode description of operations on the AArch32 general-purpose registers and the PC on page E1-2378.


T1


  15 14 13 12 11 10 9 8 7                               0
  1 0 1 1 1 1 0 P                   register_list




T1 variant

POP{<c>}{<q>} <registers>// Preferred syntax
LDM{<c>}{<q>} SP!, <registers>// Alternate syntax


Decode for this encoding

 registers = P:''0000000'':register_list;           UnalignedAllowed = FALSE;
 if BitCount(registers) < 1 then UNPREDICTABLE;
 if registers<15> == ''1'' && InITBlock() && !LastInITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly POP (T32) on page J1-5351 and POP
(A32) on page J1-5352.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<registers>     Is a list of one or more registers to be loaded, separated by commas and surrounded by { and }. The
                registers in the list must be in the range R0-R7, encoded in the "register_list" field, and can
                optionally include the PC. If the PC is in the list, the "P" field is set to 1, otherwise this field defaults
                to 0. If the PC is in the list, the instruction must be either outside any IT block, or the last instruction
                in an IT block.


Operation

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = SP;
     for i = 0 to 14
         if registers<i> == ''1'' then
              R[i] = if UnalignedAllowed then MemU[address,4] else MemA[address,4];
              address = address + 4;
     if registers<15> == ''1'' then
         if UnalignedAllowed then
              if address<1:0> == ''00'' then
                   LoadWritePC(MemU[address,4]);
              else
                         UNPREDICTABLE;
                 else
                     LoadWritePC(MemA[address,4]);
             if registers<13> == ''0'' then SP = SP + 4*BitCount(registers);
             if registers<13> == ''1'' then SP = bits(32) UNKNOWN;');
INSERT INTO "instructions" VALUES('ARM','PUSH','Push Multiple Registers to Stack stores multiple general-purpose registers to the stack, storing to consecutive       (F7.1.138)
memory locations ending just below the address in SP, and updates SP to point to the start of the stored data.

The lowest-numbered register is stored to the lowest memory address, through to the highest-numbered register to
the highest memory address. See also Encoding of lists of general-purpose registers and the PC on page F2-2514.


T1


  15 14 13 12 11 10 9 8 7                           0
  1 0 1 1 0 1 0 M                  register_list




T1 variant

PUSH{<c>}{<q>} <registers>// Preferred syntax
STMDB{<c>}{<q>} SP!, <registers>// Alternate syntax


Decode for this encoding

 registers = ''0'':M:''000000'':register_list;       UnalignedAllowed = FALSE;
 if BitCount(registers) < 1 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly PUSH on page J1-5353.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<registers>    Is a list of one or more registers to be stored, separated by commas and surrounded by { and }. The
               registers in the list must be in the range R0-R7, encoded in the "register_list" field, and can
               optionally include the LR. If the LR is in the list, the "M" field is set to 1, otherwise this field defaults
               to 0.


Operation

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = SP - 4*BitCount(registers);
     for i = 0 to 14
         if registers<i> == ''1'' then
              if i == 13 && i != LowestSetBit(registers) then           // Only possible for encoding A1
                  MemA[address,4] = bits(32) UNKNOWN;
              else
                  if UnalignedAllowed then
                       MemU[address,4] = R[i];
                  else
                       MemA[address,4] = R[i];
              address = address + 4;
     if registers<15> == ''1'' then      // Only possible for encoding A1 or A2
         if UnalignedAllowed then
              MemU[address,4] = PCStoreValue();
         else
              MemA[address,4] = PCStoreValue();
     SP = SP - 4*BitCount(registers);');
INSERT INTO "instructions" VALUES('ARM','QADD','Saturating Add adds two register values, saturates the result to the 32-bit signed integer range -231 to (231 - 1), and       (F7.1.141)
writes the result to the destination register. If saturation occurs, it sets PSTATE.Q to 1.


A1


  31        28 27 26 25 24 23 22 21 20 19             16 15       12 11 10 9 8 7 6 5 4 3                  0
     !=1111     0 0 0 1 0 0 0 0                 Rn            Rd       (0) (0) (0) (0) 0 1 0 1      Rm
      cond


A1 variant

QADD{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                     0 15 14 13 12 11              8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 0 0 0                       Rn        1 1 1 1           Rd         1 0 0 0      Rm




T1 variant

QADD{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rm>            Is the first general-purpose source register, encoded in the "Rm" field.

<Rn>            Is the second general-purpose source register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     (R[d], sat) = SignedSatQ(SInt(R[m]) + SInt(R[n]), 32);
     if sat then
         PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','QADD16','     Saturating Add 16 performs two 16-bit integer additions, saturates the results to the 16-bit signed integer range -215       (F7.1.142)
     <= x <= 215 - 1, and writes the results to the destination register.


     A1


       31       28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                 0
          !=1111    0 1 1 0 0 0 1 0                 Rn           Rd      (1) (1) (1) (1) 0 0 0 1       Rm
           cond


     A1 variant

     QADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11             8 7 6 5 4 3            0
        1 1 1 1 1 0 1 0 1 0 0 1                     Rn       1 1 1 1          Rd        0 0 0 1        Rm




     T1 variant

     QADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>            See Standard assembler syntax fields on page F2-2506.

     <q>            See Standard assembler syntax fields on page F2-2506.

     <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum1 = SInt(R[n]<15:0>) + SInt(R[m]<15:0>);
sum2 = SInt(R[n]<31:16>) + SInt(R[m]<31:16>);
R[d]<15:0>  = SignedSat(sum1, 16);
R[d]<31:16> = SignedSat(sum2, 16);');
INSERT INTO "instructions" VALUES('ARM','QADD8','     Saturating Add 8 performs four 8-bit integer additions, saturates the results to the 8-bit signed integer range -27 <=       (F7.1.143)
     x <= 27 - 1, and writes the results to the destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
          !=1111    0 1 1 0 0 0 1 0                 Rn           Rd     (1) (1) (1) (1) 1 0 0 1         Rm
           cond


     A1 variant

     QADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11           8 7 6 5 4 3             0
        1 1 1 1 1 0 1 0 1 0 0 0                     Rn       1 1 1 1         Rd        0 0 0 1          Rm




     T1 variant

     QADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum1 = SInt(R[n]<7:0>) + SInt(R[m]<7:0>);
          sum2 = SInt(R[n]<15:8>) + SInt(R[m]<15:8>);
          sum3 = SInt(R[n]<23:16>) + SInt(R[m]<23:16>);
sum4 = SInt(R[n]<31:24>) + SInt(R[m]<31:24>);
R[d]<7:0>   = SignedSat(sum1, 8);
R[d]<15:8>  = SignedSat(sum2, 8);
R[d]<23:16> = SignedSat(sum3, 8);
R[d]<31:24> = SignedSat(sum4, 8);');
INSERT INTO "instructions" VALUES('ARM','QASX','     Saturating Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one       (F7.1.144)
     16-bit integer addition and one 16-bit subtraction, saturates the results to the 16-bit signed integer range -215 <= x
     <= 215 - 1, and writes the results to the destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                   0
          !=1111     0 1 1 0 0 0 1 0                Rn           Rd     (1) (1) (1) (1) 0 0 1 1         Rm
           cond


     A1 variant

     QASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11            8 7 6 5 4 3              0
        1 1 1 1 1 0 1 0 1 0 1 0                     Rn       1 1 1 1         Rd        0 0 0 1          Rm




     T1 variant

     QASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          diff = SInt(R[n]<15:0>) - SInt(R[m]<31:16>);
sum  = SInt(R[n]<31:16>) + SInt(R[m]<15:0>);
R[d]<15:0>  = SignedSat(diff, 16);
R[d]<31:16> = SignedSat(sum, 16);');
INSERT INTO "instructions" VALUES('ARM','QDADD','     Saturating Double and Add adds a doubled register value to another register value, and writes the result to the       (F7.1.145)
     destination register. Both the doubling and the addition have their results saturated to the 32-bit signed integer range
     -231 <= x <= 231 - 1. If saturation occurs in either operation, it sets PSTATE.Q to 1.


     A1


       31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                  0
          !=1111     0 0 0 1 0 1 0 0               Rn            Rd       (0) (0) (0) (0) 0 1 0 1        Rm
           cond


     A1 variant

     QDADD{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3             0
        1 1 1 1 1 0 1 0 1 0 0 0                    Rn       1 1 1 1            Rd         1 0 0 1        Rm




     T1 variant

     QDADD{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rm>            Is the first general-purpose source register, encoded in the "Rm" field.

     <Rn>            Is the second general-purpose source register, encoded in the "Rn" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          (doubled, sat1) = SignedSatQ(2 * SInt(R[n]), 32);
(R[d], sat2)  = SignedSatQ(SInt(R[m]) + SInt(doubled), 32);
if sat1 || sat2 then
   PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','QDSUB','     Saturating Double and Subtract subtracts a doubled register value from another register value, and writes the result       (F7.1.146)
     to the destination register. Both the doubling and the subtraction have their results saturated to the 32-bit signed
     integer range -231 <= x <= 231 - 1. If saturation occurs in either operation, it sets PSTATE.Q to 1.


     A1


       31        28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                  0
          !=1111     0 0 0 1 0 1 1 0                Rn          Rd       (0) (0) (0) (0) 0 1 0 1        Rm
           cond


     A1 variant

     QDSUB{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11             8 7 6 5 4 3            0
        1 1 1 1 1 0 1 0 1 0 0 0                     Rn      1 1 1 1           Rd         1 0 1 1        Rm




     T1 variant

     QDSUB{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rm>            Is the first general-purpose source register, encoded in the "Rm" field.

     <Rn>            Is the second general-purpose source register, encoded in the "Rn" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          (doubled, sat1) = SignedSatQ(2 * SInt(R[n]), 32);
(R[d], sat2)  = SignedSatQ(SInt(R[m]) - SInt(doubled), 32);
if sat1 || sat2 then
   PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','QSAX','     Saturating Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one       (F7.1.147)
     16-bit integer subtraction and one 16-bit addition, saturates the results to the 16-bit signed integer range -215 <= x
     <= 215 - 1, and writes the results to the destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                   0
          !=1111     0 1 1 0 0 0 1 0                Rn           Rd     (1) (1) (1) (1) 0 1 0 1         Rm
           cond


     A1 variant

     QSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11            8 7 6 5 4 3              0
        1 1 1 1 1 0 1 0 1 1 1 0                     Rn       1 1 1 1         Rd        0 0 0 1          Rm




     T1 variant

     QSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum   = SInt(R[n]<15:0>) + SInt(R[m]<31:16>);
diff = SInt(R[n]<31:16>) - SInt(R[m]<15:0>);
R[d]<15:0>  = SignedSat(sum, 16);
R[d]<31:16> = SignedSat(diff, 16);');
INSERT INTO "instructions" VALUES('ARM','QSUB','        Saturating Subtract subtracts one register value from another register value, saturates the result to the 32-bit signed       (F7.1.148)
        integer range -231 <= x <= 231 - 1, and writes the result to the destination register. If saturation occurs, it sets
        PSTATE.Q to 1.


        A1


          31       28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                   0
             !=1111    0 0 0 1 0 0 1 0                Rn           Rd      (0) (0) (0) (0) 0 1 0 1          Rm
              cond


        A1 variant

        QSUB{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


        Decode for this encoding

         d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3               0
           1 1 1 1 1 0 1 0 1 0 0 0                    Rn      1 1 1 1            Rd        1 0 1 0          Rm




        T1 variant

        QSUB{<c>}{<q>} {<Rd>,} <Rm>, <Rn>


        Decode for this encoding

         d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

        <Rm>           Is the first general-purpose source register, encoded in the "Rm" field.

        <Rn>           Is the second general-purpose source register, encoded in the "Rn" field.
Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    (R[d], sat) = SignedSatQ(SInt(R[m]) - SInt(R[n]), 32);
    if sat then
        PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','QSUB16','     Saturating Subtract 16 performs two 16-bit integer subtractions, saturates the results to the 16-bit signed integer       (F7.1.149)
     range -215 <= x <= 215 - 1, and writes the results to the destination register.


     A1


       31       28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                  0
          !=1111   0 1 1 0 0 0 1 0                 Rn           Rd       (1) (1) (1) (1) 0 1 1 1      Rm
           cond


     A1 variant

     QSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11             8 7 6 5 4 3            0
        1 1 1 1 1 0 1 0 1 1 0 1                    Rn       1 1 1 1           Rd        0 0 0 1       Rm




     T1 variant

     QSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>            See Standard assembler syntax fields on page F2-2506.

     <q>            See Standard assembler syntax fields on page F2-2506.

     <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          diff1 = SInt(R[n]<15:0>) - SInt(R[m]<15:0>);
diff2 = SInt(R[n]<31:16>) - SInt(R[m]<31:16>);
R[d]<15:0>  = SignedSat(diff1, 16);
R[d]<31:16> = SignedSat(diff2, 16);');
INSERT INTO "instructions" VALUES('ARM','QSUB8','     Saturating Subtract 8 performs four 8-bit integer subtractions, saturates the results to the 8-bit signed integer range       (F7.1.150)
     -27 <= x <= 27 - 1, and writes the results to the destination register.


     A1


       31       28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                  0
          !=1111    0 1 1 0 0 0 1 0                 Rn           Rd      (1) (1) (1) (1) 1 1 1 1         Rm
           cond


     A1 variant

     QSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11             8 7 6 5 4 3             0
        1 1 1 1 1 0 1 0 1 1 0 0                     Rn       1 1 1 1          Rd        0 0 0 1          Rm




     T1 variant

     QSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>            See Standard assembler syntax fields on page F2-2506.

     <q>            See Standard assembler syntax fields on page F2-2506.

     <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          diff1 = SInt(R[n]<7:0>) - SInt(R[m]<7:0>);
          diff2 = SInt(R[n]<15:8>) - SInt(R[m]<15:8>);
          diff3 = SInt(R[n]<23:16>) - SInt(R[m]<23:16>);
diff4 = SInt(R[n]<31:24>) - SInt(R[m]<31:24>);
R[d]<7:0>   = SignedSat(diff1, 8);
R[d]<15:8>  = SignedSat(diff2, 8);
R[d]<23:16> = SignedSat(diff3, 8);
R[d]<31:24> = SignedSat(diff4, 8);');
INSERT INTO "instructions" VALUES('ARM','REVSH','        Byte-Reverse Signed Halfword reverses the byte order in the lower 16-bit halfword of a 32-bit register, and       (F7.1.154)
        sign-extends the result to 32 bits.


        A1


          31       28 27 26 25 24 23 22 21 20 19 18 17 16 15        12 11 10 9 8 7 6 5 4 3                 0
             !=1111    0 1 1 0 1 1 1 1 (1) (1) (1) (1)           Rd     (1) (1) (1) (1) 1 0 1 1      Rn
              cond


        A1 variant

        REVSH{<c>}{<q>} <Rd>, <Rm>


        Decode for this encoding

         d = UInt(Rd);   m = UInt(Rm);
         if d == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5            3 2     0
           1 0 1 1 1 0 1 0 1 1               Rs        Rd




        T1 variant

        REVSH{<c>}{<q>} <Rd>, <Rm>


        Decode for this encoding

         d = UInt(Rd);   m = UInt(Rm);


        T2


          15 14 13 12 11 10 9 8 7 6 5 4 3                0 15 14 13 12 11            8 7 6 5 4 3           0
           1 1 1 1 1 0 1 0 1 0 0 1                   Rm       1 1 1 1        Rd         1 0 1 1      Rm




        T2 variant

        REVSH{<c>}.W <Rd>, <Rm>// <Rd>, <Rm> can be represented in T1
        REVSH{<c>}{<q>} <Rd>, <Rm>


        Decode for this encoding

         if !Consistent(Rm) then UNPREDICTABLE;
         d = UInt(Rd);   m = UInt(Rm);
         if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly REVSH on page J1-5355.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rm>          For encoding A1 and T1: is the general-purpose source register, encoded in the "Rm" field.

              For encoding T2: is the general-purpose source register, encoded in the "Rm" field. Its number must
              be encoded twice.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    bits(32) result;
    result<31:8>   = SignExtend(R[m]<7:0>, 24);
    result<7:0>    = R[m]<15:8>;
    R[d] = result;');
INSERT INTO "instructions" VALUES('ARM','RFE','        Return From Exception loads two consecutive memory locations using an address in a base register:       (F7.1.155)

        .      The word loaded from the lower address is treated as an instruction address. The PE branches to it.

        .      The word loaded from the higher address is used to restore PSTATE. This word must be in the format of an
               SPSR.

        An address adjusted by the size of the data loaded can optionally be written back to the base register.

        The PE checks the value of the word loaded from the higher address for an illegal return event. See Illegal return
        events from AArch32 state on page G1-3845.

        RFE is UNDEFINED in Hyp mode and CONSTRAINED UNPREDICTABLE in User mode.


        A1


          31 30 29 28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
           1 1 1 1 1 0 0 P U 0 W 1                    Rn     (0) (0) (0) (0) (1) (0) (1) (0) (0) (0) (0) (0) (0) (0) (0) (0)




        Decrement After variant

        Applies when P = 0 && U = 0.

        RFEDA{<c>}{<q>} <Rn>{!}


        Decrement Before variant

        Applies when P = 1 && U = 0.

        RFEDB{<c>}{<q>} <Rn>{!}


        Increment After variant

        Applies when P = 0 && U = 1.

        RFE{IA}{<c>}{<q>} <Rn>{!}


        Increment Before variant

        Applies when P = 1 && U = 1.

        RFEIB{<c>}{<q>} <Rn>{!}


        Decode for all variants of this encoding

         n = UInt(Rn);
         wback = (W == ''1'');   increment = (U == ''1'');     wordhigher = (P == U);
         if n == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
           1 1 1 0 1 0 0 0 0 0 W 1                    Rn     (1) (1) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0)




        T1 variant

        RFEDB{<c>}{<q>} <Rn>{!}// Outside or last in IT block
Decode for this encoding

 n = UInt(Rn);    wback = (W == ''1'');   increment = FALSE;       wordhigher = FALSE;
 if n == 15 then UNPREDICTABLE;
 if InITBlock() && !LastInITBlock() then UNPREDICTABLE;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  1 1 1 0 1 0 0 1 1 0 W 1                    Rn       (1) (1) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0) (0)




T2 variant

RFE{IA}{<c>}{<q>} <Rn>{!}// Outside or last in IT block


Decode for this encoding

 n = UInt(Rn);    wback = (W == ''1'');   increment = TRUE;      wordhigher = FALSE;
 if n == 15 then UNPREDICTABLE;
 if InITBlock() && !LastInITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly RFE on page J1-5381.


Assembler symbols

IA              For encoding A1: is an optional suffix to indicate the Increment After variant.

                For encoding T2: is an optional suffix for the Increment After form.

<c>             For encoding A1: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

                For encoding T1 and T2: see Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.

!               The address adjusted by the size of the data loaded is written back to the base register. If specified,
                it is encoded in the "W" field as 1, otherwise this field defaults to 0.

RFEFA, RFEEA, RFEFD, and RFEED are pseudo-instructions for RFEDA, RFEDB, RFEIA, and RFEIB respectively, referring to
their use for popping data from Full Ascending, Empty Ascending, Full Descending, and Empty Descending stacks.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      if PSTATE.EL == EL2 then
          UNDEFINED;
      elsif PSTATE.EL == EL0 then
          UNPREDICTABLE;                             // UNDEFINED or NOP
      else
          address = if increment then R[n] else R[n]-8;
          if wordhigher then address = address+4;
          new_pc_value = MemA[address,4];
          spsr = MemA[address+4,4];
          if wback then R[n] = if increment then R[n]+8 else R[n]-8;
          AArch32.ExceptionReturn(new_pc_value, spsr);');
INSERT INTO "instructions" VALUES('ARM','RFEDA','-R:RFE');
INSERT INTO "instructions" VALUES('ARM','RFEDB','-R:RFE');
INSERT INTO "instructions" VALUES('ARM','RFEIA','-R:RFE');
INSERT INTO "instructions" VALUES('ARM','RFEIB','-R:RFE');
INSERT INTO "instructions" VALUES('ARM','RORS','        Rotate Right, setting flags (immediate) provides the value of the contents of a register rotated by a constant value.       (F7.1.158)
        The bits that are rotated off the right end are inserted into the vacated bit positions on the left.

        If the destination register is not the PC, this instruction updates the condition flags based on the result.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

        .      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from AArch32
               state on page G1-3845.

        .      The instruction is UNDEFINED in Hyp mode.

        .      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.

        This instruction is an alias of the MOV, MOVS (register) instruction. This means that:

        .      The encodings in this description are named to match the encodings of MOV, MOVS (register).

        .      The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.


        A1


          31        28 27 26 25 24 23 22 21 20 19 18 17 16 15             12 11             7 6 5 4 3            0
             !=1111     0 0 0 1 1 0 1 1 (0) (0) (0) (0)              Rd          !=00000      1 1 0         Rm
              cond                              S                                 imm5        type


        MOVS, shift or rotate by value variant

        RORS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, ROR #<imm>

        and is always the preferred disassembly.


        T3


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                     12 11        8 7 6 5 4 3               0
           1 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 (0)                       imm3         Rd       imm2 1 1         Rm
                                                S                                                type


        MOVS, shift or rotate by value variant

        Applies when !(imm3 == 000 && imm2 == 00).

        RORS{<c>}{<q>} {<Rd>,} <Rm>, #<imm>

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, ROR #<imm>

        and is always the preferred disassembly.


        Assembler symbols

        <c>              See Standard assembler syntax fields on page F2-2506.
<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
               deprecates using the PC as the destination register, but if the PC is used, the instruction performs an
               exception return, that restores PSTATE from SPSR_<current_mode>.

               For encoding T3: is the general-purpose destination register, encoded in the "Rd" field.

<Rm>           For encoding A1: is the general-purpose source register, encoded in the "Rm" field. The PC can be
               used.

               For encoding T3: is the general-purpose source register, encoded in the "Rm" field.

<imm>          For encoding A1: is the shift amount, in the range 1 to 31, encoded in the "imm5" field.

               For encoding T3: is the shift amount, in the range 1 to 31, encoded in the "imm3:imm2" field.


Operation for all encodings

The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','RRX','        Rotate Right with Extend provides the value of the contents of a register shifted right by one place, with the Carry       (F7.1.160)
        flag shifted into bit[31].

        This instruction is an alias of the MOV, MOVS (register) instruction. This means that:

        .      The encodings in this description are named to match the encodings of MOV, MOVS (register).

        .      The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.


        A1


          31        28 27 26 25 24 23 22 21 20 19 18 17 16 15          12 11              7 6 5 4 3              0
             !=1111     0 0 0 1 1 0 1 0 (0) (0) (0) (0)           Rd        0 0 0 0 0 1 1 0                Rm
              cond                            S                                 imm5         type


        MOV, rotate right with extend variant

        RRX{<c>}{<q>} {<Rd>,} <Rm>

        is equivalent to

        MOV{<c>}{<q>} <Rd>, <Rm>, RRX

        and is always the preferred disassembly.


        T3


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                  12 11          8 7 6 5 4 3                0
           1 1 1 0 1 0 1 0 0 1 0 0 1 1 1 1 (0) 0 0 0                            Rd        0 0 1 1          Rm
                                              S                    imm3                  imm2 type


        MOV, rotate right with extend variant

        RRX{<c>}{<q>} {<Rd>,} <Rm>

        is equivalent to

        MOV{<c>}{<q>} <Rd>, <Rm>, RRX

        and is always the preferred disassembly.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
                        deprecates using the PC as the destination register, but if the PC is used, the instruction is a branch
                        to the address calculated by the operation. This is an interworking branch, see Pseudocode
                        description of operations on the AArch32 general-purpose registers and the PC on page E1-2378.

                        For encoding T3: is the general-purpose destination register, encoded in the "Rd" field.

        <Rm>            For encoding A1: is the general-purpose source register, encoded in the "Rm" field. The PC can be
                        used.

                        For encoding T3: is the general-purpose source register, encoded in the "Rm" field.
Operation for all encodings

The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','RRXS','        Rotate Right with Extend, setting flags provides the value of the contents of a register shifted right by one place,       (F7.1.161)
        with the Carry flag shifted into bit[31].

        If the destination register is not the PC, this instruction updates the condition flags based on the result, and bit[0] is
        shifted into the Carry flag.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

        .      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from AArch32
               state on page G1-3845.

        .      The instruction is UNDEFINED in Hyp mode.

        .      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.

        This instruction is an alias of the MOV, MOVS (register) instruction. This means that:

        .      The encodings in this description are named to match the encodings of MOV, MOVS (register).

        .      The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.


        A1


          31        28 27 26 25 24 23 22 21 20 19 18 17 16 15             12 11             7 6 5 4 3             0
             !=1111     0 0 0 1 1 0 1 1 (0) (0) (0) (0)              Rd       0 0 0 0 0 1 1 0               Rm
              cond                              S                                 imm5         type


        MOVS, rotate right with extend variant

        RRXS{<c>}{<q>} {<Rd>,} <Rm>

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, RRX

        and is always the preferred disassembly.


        T3


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14                     12 11         8 7 6 5 4 3                0
           1 1 1 0 1 0 1 0 0 1 0 1 1 1 1 1 (0) 0 0 0                              Rd        0 0 1 1         Rm
                                                S                     imm3                 imm2 type


        MOVS, rotate right with extend variant

        RRXS{<c>}{<q>} {<Rd>,} <Rm>

        is equivalent to

        MOVS{<c>}{<q>} <Rd>, <Rm>, RRX

        and is always the preferred disassembly.


        Assembler symbols

        <c>              See Standard assembler syntax fields on page F2-2506.
<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. ARM
               deprecates using the PC as the destination register, but if the PC is used, the instruction performs an
               exception return, that restores PSTATE from SPSR_<current_mode>.

               For encoding T3: is the general-purpose destination register, encoded in the "Rd" field.

<Rm>           For encoding A1: is the general-purpose source register, encoded in the "Rm" field. The PC can be
               used.

               For encoding T3: is the general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

The description of MOV, MOVS (register) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','RSB','        Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to the       (F7.1.162)
        destination register.

        If the destination register is not the PC, the RSBS variant of the instruction updates the condition flags based on the
        result.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The RSB variant of the instruction is an interworking branch, see Pseudocode description of operations on
               the AArch32 general-purpose registers and the PC on page E1-2378.

        .      The RSBS variant of the instruction performs an exception return without the use of the stack. In this case:

               --      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

               --      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from
                      AArch32 state on page G1-3845.

               --      The instruction is UNDEFINED in Hyp mode.

               --      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15        12 11                                   0
             !=1111     0 0 1 0 0 1 1 S                 Rn          Rd                      imm12
              cond


        RSB variant

        Applies when S = 0.

        RSB{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        RSBS variant

        Applies when S = 1.

        RSBS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);      setflags = (S == ''1'');   imm32 = A32ExpandImm(imm12);


        T1


          15 14 13 12 11 10 9 8 7 6 5               3 2     0
           0 1 0 0 0 0 1 0 0 1                  Rn       Rd




        T1 variant

        RSB<c>{<q>} {<Rd>, }<Rn>, #0// Inside IT block
        RSBS{<q>} {<Rd>, }<Rn>, #0// Outside IT block


        Decode for this encoding

         d = UInt(Rd);    n = UInt(Rn);      setflags = !InITBlock();    imm32 = Zeros(32); // immediate = #0
T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14    12 11          8 7                      0
  1 1 1 1 0 i 0 1 1 1 0 S                     Rn       0   imm3         Rd              imm8




RSB variant

Applies when S = 0.

RSB<c>.W {<Rd>,} <Rn>, #0// Inside IT block
RSB{<c>}{<q>} {<Rd>,} <Rn>, #<const>


RSBS variant

Applies when S = 1.

RSBS.W {<Rd>,} <Rn>, #0// Outside IT block
RSBS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


Decode for all variants of this encoding

 d = UInt(Rd);  n = UInt(Rn);      setflags = (S == ''1'');   imm32 = T32ExpandImm(i:imm3:imm8);
 if d == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           For encoding A1: is the general-purpose destination register, encoded in the "Rd" field. If omitted,
               this register is the same as <Rn>. ARM deprecates using the PC as the destination register, but if the
               PC is used:

               .      For the RSB variant, the instruction is a branch to the address calculated by the operation.
                      This is an interworking branch, see Pseudocode description of operations on the AArch32
                      general-purpose registers and the PC on page E1-2378.

               .      For the RSBS variant, the instruction performs an exception return, that restores PSTATE
                      from SPSR_<current_mode>.

               For encoding T1 and T2: is the general-purpose destination register, encoded in the "Rd" field. If
               omitted, this register is the same as <Rn>.

<Rn>           For encoding A1: is the general-purpose source register, encoded in the "Rn" field. The PC can be
               used.

               For encoding T1 and T2: is the general-purpose source register, encoded in the "Rn" field.

<const>        For encoding A1: an immediate value. See Modified immediate constants in A32 instructions on
               page F4-2559 for the range of values.

               For encoding T2: an immediate value. See Modified immediate constants in T32 instructions on
               page F3-2530 for the range of values.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             (result, nzcv) = AddWithCarry(NOT(R[n]), imm32, ''1'');
             if d == 15 then            // Can only occur for A32 encoding
                 if setflags then
                     ALUExceptionReturn(result);
                 else
                     ALUWritePC(result);
             else
                 R[d] = result;
                 if setflags then
                     PSTATE.<N,Z,C,V> = nzcv;');
INSERT INTO "instructions" VALUES('ARM','RSBS','-R:RSB');
INSERT INTO "instructions" VALUES('ARM','RSC','        Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from an       (F7.1.165)
        immediate value, and writes the result to the destination register.

        If the destination register is not the PC, the RSCS variant of the instruction updates the condition flags based on the
        result.

        The field descriptions for <Rd> identify the encodings where the PC is permitted as the destination register. ARM
        deprecates any use of these encodings. However, when the destination register is the PC:

        .      The RSC variant of the instruction is an interworking branch, see Pseudocode description of operations on
               the AArch32 general-purpose registers and the PC on page E1-2378.

        .      The RSCS variant of the instruction performs an exception return without the use of the stack. In this case:

               --      The PE branches to the address written to the PC, and restores PSTATE from SPSR_<current_mode>.

               --      The PE checks SPSR_<current_mode> for an illegal return event. See Illegal return events from
                      AArch32 state on page G1-3845.

               --      The instruction is UNDEFINED in Hyp mode.

               --      The instruction is CONSTRAINED UNPREDICTABLE in User mode and System mode.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15        12 11                                    0
             !=1111     0 0 1 0 1 1 1 S                 Rn          Rd                      imm12
              cond


        RSC variant

        Applies when S = 0.

        RSC{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        RSCS variant

        Applies when S = 1.

        RSCS{<c>}{<q>} {<Rd>,} <Rn>, #<const>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);      setflags = (S == ''1'');   imm32 = A32ExpandImm(imm12);


        Assembler symbols

        <c>              See Standard assembler syntax fields on page F2-2506.

        <q>              See Standard assembler syntax fields on page F2-2506.

        <Rd>             Is the general-purpose destination register, encoded in the "Rd" field. If omitted, this register is the
                         same as <Rn>. ARM deprecates using the PC as the destination register, but if the PC is used:

                         .      For the RSC variant, the instruction is a branch to the address calculated by the operation.
                                This is an interworking branch, see Pseudocode description of operations on the AArch32
                                general-purpose registers and the PC on page E1-2378.

                         .      For the RSCS variant, the instruction performs an exception return, that restores PSTATE
                                from SPSR_<current_mode>.

        <Rn>             Is the general-purpose source register, encoded in the "Rn" field. The PC can be used.
<const>       An immediate value. See Modified immediate constants in A32 instructions on page F4-2559 for the
              range of values.


Operation

 if ConditionPassed() then
    EncodingSpecificOperations();
    (result, nzcv) = AddWithCarry(NOT(R[n]), imm32, PSTATE.C);
    if d == 15 then
        if setflags then
            ALUExceptionReturn(result);
        else
            ALUWritePC(result);
    else
        R[d] = result;
        if setflags then
            PSTATE.<N,Z,C,V> = nzcv;');
INSERT INTO "instructions" VALUES('ARM','RSCS','-R:RSC');
INSERT INTO "instructions" VALUES('ARM','SADD16','     Signed Add 16 performs two 16-bit signed integer additions, and writes the results to the destination register. It sets       (F7.1.168)
     PSTATE.GE according to the results of the additions.


     A1


       31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                  0
          !=1111   0 1 1 0 0 0 0 1                 Rn          Rd      (1) (1) (1) (1) 0 0 0 1       Rm
           cond


     A1 variant

     SADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3             0
        1 1 1 1 1 0 1 0 1 0 0 1                    Rn      1 1 1 1          Rd        0 0 0 0        Rm




     T1 variant

     SADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>            See Standard assembler syntax fields on page F2-2506.

     <q>            See Standard assembler syntax fields on page F2-2506.

     <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum1 = SInt(R[n]<15:0>) + SInt(R[m]<15:0>);
          sum2 = SInt(R[n]<31:16>) + SInt(R[m]<31:16>);
          R[d]<15:0>   = sum1<15:0>;
R[d]<31:16> = sum2<15:0>;
PSTATE.GE<1:0> = if sum1 >= 0 then ''11'' else ''00'';
PSTATE.GE<3:2> = if sum2 >= 0 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','SADD8','     Signed Add 8 performs four 8-bit signed integer additions, and writes the results to the destination register. It sets       (F7.1.169)
     PSTATE.GE according to the results of the additions.


     A1


       31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                 0
          !=1111   0 1 1 0 0 0 0 1                 Rn          Rd      (1) (1) (1) (1) 1 0 0 1       Rm
           cond


     A1 variant

     SADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3            0
        1 1 1 1 1 0 1 0 1 0 0 0                    Rn      1 1 1 1          Rd        0 0 0 0        Rm




     T1 variant

     SADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>            See Standard assembler syntax fields on page F2-2506.

     <q>            See Standard assembler syntax fields on page F2-2506.

     <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum1 = SInt(R[n]<7:0>) + SInt(R[m]<7:0>);
          sum2 = SInt(R[n]<15:8>) + SInt(R[m]<15:8>);
          sum3 = SInt(R[n]<23:16>) + SInt(R[m]<23:16>);
sum4 = SInt(R[n]<31:24>) + SInt(R[m]<31:24>);
R[d]<7:0>   = sum1<7:0>;
R[d]<15:8>  = sum2<7:0>;
R[d]<23:16> = sum3<7:0>;
R[d]<31:24> = sum4<7:0>;
PSTATE.GE<0>  = if sum1 >= 0 then ''1'' else ''0'';
PSTATE.GE<1>  = if sum2 >= 0 then ''1'' else ''0'';
PSTATE.GE<2>  = if sum3 >= 0 then ''1'' else ''0'';
PSTATE.GE<3>  = if sum4 >= 0 then ''1'' else ''0'';');
INSERT INTO "instructions" VALUES('ARM','SASX','     Signed Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one 16-bit       (F7.1.170)
     integer addition and one 16-bit subtraction, and writes the results to the destination register. It sets PSTATE.GE
     according to the results.


     A1


       31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                     0
          !=1111    0 1 1 0 0 0 0 1                Rn          Rd       (1) (1) (1) (1) 0 0 1 1          Rm
           cond


     A1 variant

     SASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11              8 7 6 5 4 3               0
        1 1 1 1 1 0 1 0 1 0 1 0                    Rn      1 1 1 1           Rd        0 0 0 0           Rm




     T1 variant

     SASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          diff = SInt(R[n]<15:0>) - SInt(R[m]<31:16>);
          sum  = SInt(R[n]<31:16>) + SInt(R[m]<15:0>);
R[d]<15:0>  = diff<15:0>;
R[d]<31:16> = sum<15:0>;
PSTATE.GE<1:0> = if diff >= 0 then ''11'' else ''00'';
PSTATE.GE<3:2> = if sum  >= 0 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','SEL','Select Bytes selects each byte of its result from either its first operand or its second operand, according to the values       (F7.1.176)
of the PSTATE.GE flags.


A1


  31       28 27 26 25 24 23 22 21 20 19             16 15          12 11 10 9 8 7 6 5 4 3                0
     !=1111    0 1 1 0 1 0 0 0                  Rn            Rd       (1) (1) (1) (1) 1 0 1 1       Rm
      cond


A1 variant

SEL{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11               8 7 6 5 4 3           0
   1 1 1 1 1 0 1 0 1 0 1 0                      Rn       1 1 1 1            Rd         1 0 0 0       Rm




T1 variant

SEL{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     R[d]<7:0>     = if PSTATE.GE<0> == ''1'' then R[n]<7:0>           else R[m]<7:0>;
             R[d]<15:8>  = if PSTATE.GE<1> == ''1'' then R[n]<15:8>    else R[m]<15:8>;
             R[d]<23:16> = if PSTATE.GE<2> == ''1'' then R[n]<23:16> else R[m]<23:16>;
             R[d]<31:24> = if PSTATE.GE<3> == ''1'' then R[n]<31:24> else R[m]<31:24>;');
INSERT INTO "instructions" VALUES('ARM','SETEND','Set Endianness writes a new value to PSTATE.E.       (F7.1.177)


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 (0) (0) (0) (0) (0) (0) E (0) 0 0 0 0 (0) (0) (0) (0)




A1 variant

SETEND{<q>} <endian_specifier>// Cannot be conditional


Decode for this encoding

 set_bigend = (E == ''1'');


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  1 0 1 1 0 1 1 0 0 1 0 (1) E (0) (0) (0)




T1 variant

SETEND{<q>} <endian_specifier>// Not permitted in IT block


Decode for this encoding

 set_bigend = (E == ''1'');
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<q>            See Standard assembler syntax fields on page F2-2506.

<endian_specifier>

               Is the endianness to be selected, and the value to be set in PSTATE.E, encoded in the "E" field. It
               can have the following values:

               LE          when E = 0

               BE          when E = 1


Operation for all encodings

 EncodingSpecificOperations();
 AArch32.CheckSETENDEnabled();
 PSTATE.E = if set_bigend then ''1'' else ''0'';');
INSERT INTO "instructions" VALUES('ARM','SHADD16','     Signed Halving Add 16 performs two signed 16-bit integer additions, halves the results, and writes the results to the       (F7.1.180)
     destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3               0
          !=1111    0 1 1 0 0 0 1 1                Rn           Rd      (1) (1) (1) (1) 0 0 0 1     Rm
           cond


     A1 variant

     SHADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3          0
        1 1 1 1 1 0 1 0 1 0 0 1                    Rn       1 1 1 1          Rd        0 0 1 0      Rm




     T1 variant

     SHADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum1 = SInt(R[n]<15:0>) + SInt(R[m]<15:0>);
sum2 = SInt(R[n]<31:16>) + SInt(R[m]<31:16>);
R[d]<15:0>  = sum1<16:1>;
R[d]<31:16> = sum2<16:1>;');
INSERT INTO "instructions" VALUES('ARM','SHADD8','     Signed Halving Add 8 performs four signed 8-bit integer additions, halves the results, and writes the results to the       (F7.1.181)
     destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3               0
          !=1111    0 1 1 0 0 0 1 1                Rn           Rd      (1) (1) (1) (1) 1 0 0 1     Rm
           cond


     A1 variant

     SHADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3          0
        1 1 1 1 1 0 1 0 1 0 0 0                    Rn       1 1 1 1          Rd        0 0 1 0      Rm




     T1 variant

     SHADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum1 = SInt(R[n]<7:0>) + SInt(R[m]<7:0>);
          sum2 = SInt(R[n]<15:8>) + SInt(R[m]<15:8>);
          sum3 = SInt(R[n]<23:16>) + SInt(R[m]<23:16>);
sum4 = SInt(R[n]<31:24>) + SInt(R[m]<31:24>);
R[d]<7:0>   = sum1<8:1>;
R[d]<15:8>  = sum2<8:1>;
R[d]<23:16> = sum3<8:1>;
R[d]<31:24> = sum4<8:1>;');
INSERT INTO "instructions" VALUES('ARM','SHASX','     Signed Halving Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one       (F7.1.182)
     signed 16-bit integer addition and one signed 16-bit subtraction, halves the results, and writes the results to the
     destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                 0
          !=1111    0 1 1 0 0 0 1 1                Rn           Rd      (1) (1) (1) (1) 0 0 1 1       Rm
           cond


     A1 variant

     SHASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3            0
        1 1 1 1 1 0 1 0 1 0 1 0                    Rn       1 1 1 1          Rd        0 0 1 0        Rm




     T1 variant

     SHASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          diff = SInt(R[n]<15:0>) - SInt(R[m]<31:16>);
sum  = SInt(R[n]<31:16>) + SInt(R[m]<15:0>);
R[d]<15:0>  = diff<16:1>;
R[d]<31:16> = sum<16:1>;');
INSERT INTO "instructions" VALUES('ARM','SHSAX','     Signed Halving Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one       (F7.1.183)
     signed 16-bit integer subtraction and one signed 16-bit addition, halves the results, and writes the results to the
     destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                 0
          !=1111    0 1 1 0 0 0 1 1                Rn           Rd      (1) (1) (1) (1) 0 1 0 1       Rm
           cond


     A1 variant

     SHSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3            0
        1 1 1 1 1 0 1 0 1 1 1 0                    Rn       1 1 1 1          Rd        0 0 1 0        Rm




     T1 variant

     SHSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          sum  = SInt(R[n]<15:0>) + SInt(R[m]<31:16>);
diff = SInt(R[n]<31:16>) - SInt(R[m]<15:0>);
R[d]<15:0>  = sum<16:1>;
R[d]<31:16> = diff<16:1>;');
INSERT INTO "instructions" VALUES('ARM','SHSUB16','     Signed Halving Subtract 16 performs two signed 16-bit integer subtractions, halves the results, and writes the results       (F7.1.184)
     to the destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
          !=1111     0 1 1 0 0 0 1 1               Rn           Rd      (1) (1) (1) (1) 0 1 1 1       Rm
           cond


     A1 variant

     SHSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3           0
        1 1 1 1 1 0 1 0 1 1 0 1                    Rn       1 1 1 1          Rd        0 0 1 0        Rm




     T1 variant

     SHSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          diff1 = SInt(R[n]<15:0>) - SInt(R[m]<15:0>);
diff2 = SInt(R[n]<31:16>) - SInt(R[m]<31:16>);
R[d]<15:0>  = diff1<16:1>;
R[d]<31:16> = diff2<16:1>;');
INSERT INTO "instructions" VALUES('ARM','SHSUB8','     Signed Halving Subtract 8 performs four signed 8-bit integer subtractions, halves the results, and writes the results       (F7.1.185)
     to the destination register.


     A1


       31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
          !=1111     0 1 1 0 0 0 1 1               Rn           Rd      (1) (1) (1) (1) 1 1 1 1      Rm
           cond


     A1 variant

     SHSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


     T1


       15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3           0
        1 1 1 1 1 0 1 0 1 1 0 0                    Rn       1 1 1 1          Rd        0 0 1 0       Rm




     T1 variant

     SHSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


     Decode for this encoding

      d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
      if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

     <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

     <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


     Operation for all encodings

      if ConditionPassed() then
          EncodingSpecificOperations();
          diff1 = SInt(R[n]<7:0>) - SInt(R[m]<7:0>);
          diff2 = SInt(R[n]<15:8>) - SInt(R[m]<15:8>);
          diff3 = SInt(R[n]<23:16>) - SInt(R[m]<23:16>);
diff4 = SInt(R[n]<31:24>) - SInt(R[m]<31:24>);
R[d]<7:0>   = diff1<8:1>;
R[d]<15:8>  = diff2<8:1>;
R[d]<23:16> = diff3<8:1>;
R[d]<31:24> = diff4<8:1>;');
INSERT INTO "instructions" VALUES('ARM','SMLABB','        Signed Multiply Accumulate (halfwords) performs a signed multiply accumulate operation. The multiply acts on       (F7.1.187)
        two signed 16-bit quantities, taken from either the bottom or the top half of their respective source registers. The
        other halves of these source registers are ignored. The 32-bit product is added to a 32-bit accumulate value and the
        result is written to the destination register.

        If overflow occurs during the addition of the accumulate value, the instruction sets PSTATE.Q to 1. It is not possible
        for overflow to occur during the multiplication.


        A1


           31       28 27 26 25 24 23 22 21 20 19          16 15        12 11         8 7 6 5 4 3               0
             !=1111     0 0 0 1 0 0 0 0               Rd           Ra           Rm       1 M N 0         Rn
              cond


        SMLABB variant

        Applies when M = 0 && N = 0.

        SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLABT variant

        Applies when M = 1 && N = 0.

        SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLATB variant

        Applies when M = 0 && N = 1.

        SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLATT variant

        Applies when M = 1 && N = 1.

        SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         d = UInt(Rd);     n = UInt(Rn);    m = UInt(Rm);   a = UInt(Ra);
         n_high = (N == ''1'');      m_high = (M == ''1'');
         if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11         8 7 6 5 4 3               0
           1 1 1 1 1 0 1 1 0 0 0 1                    Rn         !=1111         Rd       0 0 N M         Rm
                                                                   Ra


        SMLABB variant

        Applies when N = 0 && M = 0.

        SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLABT variant

        Applies when N = 0 && M = 1.
SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


SMLATB variant

Applies when N = 1 && M = 0.

SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


SMLATT variant

Applies when N = 1 && M = 1.

SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


Decode for all variants of this encoding

 if Ra == ''1111'' then SEE SMULBB, SMULBT, SMULTB, SMULTT;
 d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);  a = UInt(Ra);
 n_high = (N == ''1'');    m_high = (M == ''1'');
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register holding the multiplicand in the bottom or top half
               (selected by <x>), encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register holding the multiplier in the bottom or top half
               (selected by <y>), encoded in the "Rm" field.

<Ra>           Is the third general-purpose source register holding the addend, encoded in the "Ra" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand1 = if n_high then R[n]<31:16> else R[n]<15:0>;
     operand2 = if m_high then R[m]<31:16> else R[m]<15:0>;
     result = SInt(operand1) * SInt(operand2) + SInt(R[a]);
     R[d] = result<31:0>;
     if result != SInt(result<31:0>) then     // Signed overflow
         PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','SMLABT','-R:SMLABB');
INSERT INTO "instructions" VALUES('ARM','SMLATB','-R:SMLABB');
INSERT INTO "instructions" VALUES('ARM','SMLATT','-R:SMLABB');
INSERT INTO "instructions" VALUES('ARM','SMLAD','        Signed Multiply Accumulate Dual performs two signed 16 x 16-bit multiplications. It adds the products to a 32-bit       (F7.1.188)
        accumulate operand.

        Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This
        produces top x bottom and bottom x top multiplication.

        This instruction sets PSTATE.Q to 1 if the accumulate operation overflows. Overflow cannot occur during the
        multiplications.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15        12 11       8 7 6 5 4 3               0
             !=1111     0 1 1 1 0 0 0 0               Rd        !=1111        Rm       0 0 M 1         Rn
              cond                                                Ra


        SMLAD variant

        Applies when M = 0.

        SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLADX variant

        Applies when M = 1.

        SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         if Ra == ''1111'' then SEE SMUAD;
         d = UInt(Rd);    n = UInt(Rn);   m = UInt(Rm);   a = UInt(Ra);
         m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11       8 7 6 5 4 3               0
           1 1 1 1 1 0 1 1 0 0 1 0                    Rn        !=1111        Rd       0 0 0 M         Rm
                                                                  Ra


        SMLAD variant

        Applies when M = 0.

        SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLADX variant

        Applies when M = 1.

        SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         if Ra == ''1111'' then SEE SMUAD;
         d = UInt(Rd);    n = UInt(Rn);   m = UInt(Rm);   a = UInt(Ra);
         m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.

<Ra>           Is the third general-purpose source register holding the addend, encoded in the "Ra" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand2 = if m_swap then ROR(R[m],16) else R[m];
     product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
     product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
     result = product1 + product2 + SInt(R[a]);
     R[d] = result<31:0>;
     if result != SInt(result<31:0>) then     // Signed overflow
         PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','SMLADX','-R:SMLAD');
INSERT INTO "instructions" VALUES('ARM','SMLALS','        Signed Multiply Accumulate Long multiplies two signed 32-bit values to produce a 64-bit value, and accumulates       (F7.1.189)
        this with a 64-bit value.

        In A32 instructions, the condition flags can optionally be updated based on the result. Use of this option adversely
        affects performance on many implementations.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15       12 11         8 7 6 5 4 3                0
             !=1111    0 0 0 0 1 1 1 S               RdHi        RdLo         Rm       1 0 0 1           Rn
              cond


        Flag setting variant

        Applies when S = 1.

        SMLALS{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Not flag setting variant

        Applies when S = 0.

        SMLAL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for all variants of this encoding

         dLo = UInt(RdLo);    dHi = UInt(RdHi);     n = UInt(Rn);  m = UInt(Rm);   setflags = (S == ''1'');
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         if dHi == dLo then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11         8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 1 1 0 0                    Rn         RdLo        RdHi      0 0 0 0          Rm




        T1 variant

        SMLAL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for this encoding

         dLo = UInt(RdLo);    dHi = UInt(RdHi);     n = UInt(Rn);  m = UInt(Rm);   setflags = FALSE;
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13
         if dHi == dLo then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly SMLAL on page J1-5357.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.
<RdLo>        Is the general-purpose source register holding the lower 32 bits of the addend, and the destination
              register for the lower 32 bits of the result, encoded in the "RdLo" field.

<RdHi>        Is the general-purpose source register holding the upper 32 bits of the addend, and the destination
              register for the upper 32 bits of the result, encoded in the "RdHi" field.

<Rn>          Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    result = SInt(R[n]) * SInt(R[m]) + SInt(R[dHi]:R[dLo]);
    R[dHi] = result<63:32>;
    R[dLo] = result<31:0>;
    if setflags then
        PSTATE.N = result<63>;
        PSTATE.Z = IsZeroBit(result<63:0>);
        // PSTATE.C, PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','SMLALBB','        Signed Multiply Accumulate Long (halfwords) multiplies two signed 16-bit values to produce a 32-bit value, and       (F7.1.190)
        accumulates this with a 64-bit value. The multiply acts on two signed 16-bit quantities, taken from either the bottom
        or the top half of their respective source registers. The other halves of these source registers are ignored. The 32-bit
        product is sign-extended and accumulated with a 64-bit accumulate value.

        Overflow is possible during this instruction, but only as a result of the 64-bit addition. This overflow is not detected
        if it occurs. Instead, the result wraps around modulo 264.


        A1


           31        28 27 26 25 24 23 22 21 20 19           16 15        12 11         8 7 6 5 4 3               0
              !=1111     0 0 0 1 0 1 0 0              RdHi          RdLo          Rm       1 M N 0           Rn
               cond


        SMLALBB variant

        Applies when M = 0 && N = 0.

        SMLALBB{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        SMLALBT variant

        Applies when M = 1 && N = 0.

        SMLALBT{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        SMLALTB variant

        Applies when M = 0 && N = 1.

        SMLALTB{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        SMLALTT variant

        Applies when M = 1 && N = 1.

        SMLALTT{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for all variants of this encoding

         dLo = UInt(RdLo);      dHi = UInt(RdHi);    n = UInt(Rn);    m = UInt(Rm);
         n_high = (N == ''1'');      m_high = (M == ''1'');
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         if dHi == dLo then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15        12 11         8 7 6 5 4 3               0
           1 1 1 1 1 0 1 1 1 1 0 0                     Rn           RdLo         RdHi      1 0 N M           Rm




        SMLALBB variant

        Applies when N = 0 && M = 0.

        SMLALBB{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>
SMLALBT variant

Applies when N = 0 && M = 1.

SMLALBT{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


SMLALTB variant

Applies when N = 1 && M = 0.

SMLALTB{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


SMLALTT variant

Applies when N = 1 && M = 1.

SMLALTT{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Decode for all variants of this encoding

 dLo = UInt(RdLo);   dHi = UInt(RdHi);    n = UInt(Rn);      m = UInt(Rm);
 n_high = (N == ''1'');    m_high = (M == ''1'');
 if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13
 if dHi == dLo then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly SMLALBB, SMLALBT, SMLALTB,
SMLALTT on page J1-5357.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<RdLo>         Is the general-purpose source register holding the lower 32 bits of the addend, and the destination
               register for the lower 32 bits of the result, encoded in the "RdLo" field.

<RdHi>         Is the general-purpose source register holding the upper 32 bits of the addend, and the destination
               register for the upper 32 bits of the result, encoded in the "RdHi" field.

<Rn>           For encoding A1: is the first general-purpose source register holding the multiplicand in the bottom
               or top half (selected by <x>), encoded in the "Rn" field.

               For encoding T1: is the first general-purpose source register holding the multiplicand in the bottom
               or top half (selected by <x>), encoded in the "Rn" field.

<Rm>           For encoding A1: is the second general-purpose source register holding the multiplier in the bottom
               or top half (selected by <y>), encoded in the "Rm" field.

               For encoding T1: is the second general-purpose source register holding the multiplier in the bottom
               or top half (selected by <x>), encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand1 = if n_high then R[n]<31:16> else R[n]<15:0>;
     operand2 = if m_high then R[m]<31:16> else R[m]<15:0>;
     result = SInt(operand1) * SInt(operand2) + SInt(R[dHi]:R[dLo]);
     R[dHi] = result<63:32>;
     R[dLo] = result<31:0>;');
INSERT INTO "instructions" VALUES('ARM','SMLALBT','-R:SMLALBB');
INSERT INTO "instructions" VALUES('ARM','SMLALTB','-R:SMLALBB');
INSERT INTO "instructions" VALUES('ARM','SMLALTT','-R:SMLALBB');
INSERT INTO "instructions" VALUES('ARM','SMLALD','        Signed Multiply Accumulate Long Dual performs two signed 16 x 16-bit multiplications. It adds the products to a       (F7.1.191)
        64-bit accumulate operand.

        Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This
        produces top x bottom and bottom x top multiplication.

        Overflow is possible during this instruction, but only as a result of the 64-bit addition. This overflow is not detected
        if it occurs. Instead, the result wraps around modulo 264.


        A1


           31        28 27 26 25 24 23 22 21 20 19         16 15         12 11          8 7 6 5 4 3               0
              !=1111     0 1 1 1 0 1 0 0             RdHi         RdLo            Rm       0 0 M 1          Rn
               cond


        SMLALD variant

        Applies when M = 0.

        SMLALD{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        SMLALDX variant

        Applies when M = 1.

        SMLALDX{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for all variants of this encoding

         dLo = UInt(RdLo);      dHi = UInt(RdHi);   n = UInt(Rn);    m = UInt(Rm);     m_swap = (M == ''1'');
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         if dHi == dLo then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15          12 11          8 7 6 5 4 3               0
           1 1 1 1 1 0 1 1 1 1 0 0                     Rn         RdLo           RdHi      1 1 0 M          Rm




        SMLALD variant

        Applies when M = 0.

        SMLALD{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        SMLALDX variant

        Applies when M = 1.

        SMLALDX{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for all variants of this encoding

         dLo = UInt(RdLo);      dHi = UInt(RdHi);   n = UInt(Rn);    m = UInt(Rm);     m_swap = (M == ''1'');
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13
         if dHi == dLo then UNPREDICTABLE;
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly SMLALD on page J1-5358.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<RdLo>         Is the general-purpose source register holding the lower 32 bits of the addend, and the destination
               register for the lower 32 bits of the result, encoded in the "RdLo" field.

<RdHi>         Is the general-purpose source register holding the upper 32 bits of the addend, and the destination
               register for the upper 32 bits of the result, encoded in the "RdHi" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand2 = if m_swap then ROR(R[m],16) else R[m];
     product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
     product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
     result = product1 + product2 + SInt(R[dHi]:R[dLo]);
     R[dHi] = result<63:32>;
     R[dLo] = result<31:0>;');
INSERT INTO "instructions" VALUES('ARM','SMLALDX','-R:SMLALD');
INSERT INTO "instructions" VALUES('ARM','SMLAWB','        Signed Multiply Accumulate (word by halfword) performs a signed multiply accumulate operation. The multiply       (F7.1.192)
        acts on a signed 32-bit quantity and a signed 16-bit quantity. The signed 16-bit quantity is taken from either the
        bottom or the top half of its source register. The other half of the second source register is ignored. The top 32 bits
        of the 48-bit product are added to a 32-bit accumulate value and the result is written to the destination register. The
        bottom 16 bits of the 48-bit product are ignored.

        If overflow occurs during the addition of the accumulate value, the instruction sets PSTATE.Q to 1. No overflow
        can occur during the multiplication.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15         12 11       8 7 6 5 4 3                0
             !=1111     0 0 0 1 0 0 1 0                Rd           Ra           Rm      1 M 0 0           Rn
              cond


        SMLAWB variant

        Applies when M = 0.

        SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLAWT variant

        Applies when M = 1.

        SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);    a = UInt(Ra);     m_high = (M == ''1'');
         if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15          12 11       8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 0 0 1 1                     Rn         !=1111         Rd      0 0 0 M           Rm
                                                                    Ra


        SMLAWB variant

        Applies when M = 0.

        SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLAWT variant

        Applies when M = 1.

        SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         if Ra == ''1111'' then SEE SMULWB, SMULWT;
         d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);    a = UInt(Ra);     m_high = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register holding the multiplier in the bottom or top half
               (selected by <y>), encoded in the "Rm" field.

<Ra>           Is the third general-purpose source register holding the addend, encoded in the "Ra" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand2 = if m_high then R[m]<31:16> else R[m]<15:0>;
     result = SInt(R[n]) * SInt(operand2) + (SInt(R[a]) << 16);
     R[d] = result<47:16>;
     if (result >> 16) != SInt(R[d]) then     // Signed overflow
         PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','SMLAWT','-R:SMLAWB');
INSERT INTO "instructions" VALUES('ARM','SMLSD','        Signed Multiply Subtract Dual performs two signed 16 x 16-bit multiplications. It adds the difference of the       (F7.1.193)
        products to a 32-bit accumulate operand.

        Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This
        produces top x bottom and bottom x top multiplication.

        This instruction sets PSTATE.Q to 1 if the accumulate operation overflows. Overflow cannot occur during the
        multiplications or subtraction.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15        12 11       8 7 6 5 4 3               0
             !=1111     0 1 1 1 0 0 0 0               Rd        !=1111        Rm       0 1 M 1         Rn
              cond                                                Ra


        SMLSD variant

        Applies when M = 0.

        SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLSDX variant

        Applies when M = 1.

        SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         if Ra == ''1111'' then SEE SMUSD;
         d = UInt(Rd);    n = UInt(Rn);   m = UInt(Rm);   a = UInt(Ra);    m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11       8 7 6 5 4 3               0
           1 1 1 1 1 0 1 1 0 1 0 0                    Rn        !=1111        Rd       0 0 0 M         Rm
                                                                  Ra


        SMLSD variant

        Applies when M = 0.

        SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMLSDX variant

        Applies when M = 1.

        SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         if Ra == ''1111'' then SEE SMUSD;
         d = UInt(Rd);    n = UInt(Rn);   m = UInt(Rm);   a = UInt(Ra);    m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.

<Ra>           Is the third general-purpose source register holding the addend, encoded in the "Ra" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand2 = if m_swap then ROR(R[m],16) else R[m];
     product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
     product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
     result = product1 - product2 + SInt(R[a]);
     R[d] = result<31:0>;
     if result != SInt(result<31:0>) then     // Signed overflow
         PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','SMLSDX','-R:SMLSD');
INSERT INTO "instructions" VALUES('ARM','SMLSLD','        Signed Multiply Subtract Long Dual performs two signed 16 x 16-bit multiplications. It adds the difference of the       (F7.1.194)
        products to a 64-bit accumulate operand.

        Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This
        produces top x bottom and bottom x top multiplication.

        Overflow is possible during this instruction, but only as a result of the 64-bit addition. This overflow is not detected
        if it occurs. Instead, the result wraps around modulo 264.


        A1


           31        28 27 26 25 24 23 22 21 20 19         16 15         12 11          8 7 6 5 4 3               0
              !=1111     0 1 1 1 0 1 0 0             RdHi         RdLo            Rm       0 1 M 1          Rn
               cond


        SMLSLD variant

        Applies when M = 0.

        SMLSLD{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        SMLSLDX variant

        Applies when M = 1.

        SMLSLDX{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for all variants of this encoding

         dLo = UInt(RdLo);      dHi = UInt(RdHi);   n = UInt(Rn);    m = UInt(Rm);     m_swap = (M == ''1'');
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         if dHi == dLo then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15          12 11          8 7 6 5 4 3               0
           1 1 1 1 1 0 1 1 1 1 0 1                     Rn         RdLo           RdHi      1 1 0 M          Rm




        SMLSLD variant

        Applies when M = 0.

        SMLSLD{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        SMLSLDX variant

        Applies when M = 1.

        SMLSLDX{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for all variants of this encoding

         dLo = UInt(RdLo);      dHi = UInt(RdHi);   n = UInt(Rn);    m = UInt(Rm);     m_swap = (M == ''1'');
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         // ARMv8-A removes UPREDICTABLE for R13
         if dHi == dLo then UNPREDICTABLE;
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly SMLSLD on page J1-5358.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<RdLo>         Is the general-purpose source register holding the lower 32 bits of the addend, and the destination
               register for the lower 32 bits of the result, encoded in the "RdLo" field.

<RdHi>         Is the general-purpose source register holding the upper 32 bits of the addend, and the destination
               register for the upper 32 bits of the result, encoded in the "RdHi" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand2 = if m_swap then ROR(R[m],16) else R[m];
     product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
     product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
     result = product1 - product2 + SInt(R[dHi]:R[dLo]);
     R[dHi] = result<63:32>;
     R[dLo] = result<31:0>;');
INSERT INTO "instructions" VALUES('ARM','SMLSLDX','-R:SMLSLD');
INSERT INTO "instructions" VALUES('ARM','SMMLA','        Signed Most Significant Word Multiply Accumulate multiplies two signed 32-bit values, extracts the most       (F7.1.195)
        significant 32 bits of the result, and adds an accumulate value.

        Optionally, the instruction can specify that the result is rounded instead of being truncated. In this case, the constant
        0x80000000 is added to the product before the high word is extracted.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15         12 11        8 7 6 5 4 3                0
             !=1111     0 1 1 1 0 1 0 1                Rd           !=1111       Rm       0 0 R 1            Rn
              cond                                                   Ra


        SMMLA variant

        Applies when R = 0.

        SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMMLAR variant

        Applies when R = 1.

        SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         if Ra == ''1111'' then SEE SMMUL;
         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);   a = UInt(Ra);     round = (R == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15          12 11        8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 0 1 0 1                     Rn           !=1111       Rd       0 0 0 R           Rm
                                                                     Ra


        SMMLA variant

        Applies when R = 0.

        SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMMLAR variant

        Applies when R = 1.

        SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         if Ra == ''1111'' then SEE SMMUL;
         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);   a = UInt(Ra);     round = (R == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>          Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.

<Ra>          Is the third general-purpose source register holding the addend, encoded in the "Ra" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    result = (SInt(R[a]) << 32) + SInt(R[n]) * SInt(R[m]);
    if round then result = result + 0x80000000;
    R[d] = result<63:32>;');
INSERT INTO "instructions" VALUES('ARM','SMMLAR','-R:SMMLA');
INSERT INTO "instructions" VALUES('ARM','SMMLS','        Signed Most Significant Word Multiply Subtract multiplies two signed 32-bit values, subtracts the result from a       (F7.1.196)
        32-bit accumulate value that is shifted left by 32 bits, and extracts the most significant 32 bits of the result of that
        subtraction.

        Optionally, the instruction can specify that the result of the instruction is rounded instead of being truncated. In this
        case, the constant 0x80000000 is added to the result of the subtraction before the high word is extracted.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15         12 11          8 7 6 5 4 3              0
             !=1111     0 1 1 1 0 1 0 1                Rd            Ra           Rm       1 1 R 1          Rn
              cond


        SMMLS variant

        Applies when R = 0.

        SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMMLSR variant

        Applies when R = 1.

        SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);   m = UInt(Rm);     a = UInt(Ra);     round = (R == ''1'');
         if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15          12 11          8 7 6 5 4 3              0
           1 1 1 1 1 0 1 1 0 1 1 0                     Rn            Ra            Rd      0 0 0 R          Rm




        SMMLS variant

        Applies when R = 0.

        SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        SMMLSR variant

        Applies when R = 1.

        SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);   m = UInt(Rm);     a = UInt(Ra);     round = (R == ''1'');
         if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>          Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.

<Ra>          Is the third general-purpose source register holding the addend, encoded in the "Ra" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    result = (SInt(R[a]) << 32) - SInt(R[n]) * SInt(R[m]);
    if round then result = result + 0x80000000;
    R[d] = result<63:32>;');
INSERT INTO "instructions" VALUES('ARM','SMMLSR','-R:SMMLS');
INSERT INTO "instructions" VALUES('ARM','SMMUL','        Signed Most Significant Word Multiply multiplies two signed 32-bit values, extracts the most significant 32 bits of       (F7.1.197)
        the result, and writes those bits to the destination register.

        Optionally, the instruction can specify that the result is rounded instead of being truncated. In this case, the constant
        0x80000000 is added to the product before the high word is extracted.


        A1


          31         28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11         8 7 6 5 4 3                0
             !=1111     0 1 1 1 0 1 0 1                Rd        1 1 1 1         Rm       0 0 R 1            Rn
              cond


        SMMUL variant

        Applies when R = 0.

        SMMUL{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMMULR variant

        Applies when R = 1.

        SMMULR{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);     round = (R == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11          8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 0 1 0 1                     Rn        1 1 1 1         Rd       0 0 0 R           Rm




        SMMUL variant

        Applies when R = 0.

        SMMUL{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMMULR variant

        Applies when R = 1.

        SMMULR{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);     round = (R == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>          Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    result = SInt(R[n]) * SInt(R[m]);
    if round then result = result + 0x80000000;
    R[d] = result<63:32>;');
INSERT INTO "instructions" VALUES('ARM','SMMULR','-R:SMMUL');
INSERT INTO "instructions" VALUES('ARM','SMUAD','        Signed Dual Multiply Add performs two signed 16 x 16-bit multiplications. It adds the products together, and writes       (F7.1.198)
        the result to the destination register.

        Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This
        produces top x bottom and bottom x top multiplication.

        This instruction sets PSTATE.Q to 1 if the addition overflows. The multiplications cannot overflow.


        A1


          31        28 27 26 25 24 23 22 21 20 19          16 15 14 13 12 11       8 7 6 5 4 3               0
             !=1111     0 1 1 1 0 0 0 0               Rd        1 1 1 1       Rm       0 0 M 1         Rn
              cond


        SMUAD variant

        Applies when M = 0.

        SMUAD{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMUADX variant

        Applies when M = 1.

        SMUADX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);  m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11        8 7 6 5 4 3               0
           1 1 1 1 1 0 1 1 0 0 1 0                    Rn        1 1 1 1       Rd       0 0 0 M         Rm




        SMUAD variant

        Applies when M = 0.

        SMUAD{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMUADX variant

        Applies when M = 1.

        SMUADX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);  m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>          Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    operand2 = if m_swap then ROR(R[m],16) else R[m];
    product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
    product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
    result = product1 + product2;
    R[d] = result<31:0>;
    if result != SInt(result<31:0>) then     // Signed overflow
        PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','SMUADX','-R:SMUAD');
INSERT INTO "instructions" VALUES('ARM','SMULBB','        Signed Multiply (halfwords) multiplies two signed 16-bit quantities, taken from either the bottom or the top half of       (F7.1.199)
        their respective source registers. The other halves of these source registers are ignored. The 32-bit product is written
        to the destination register. No overflow is possible during this instruction.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11           8 7 6 5 4 3              0
             !=1111     0 0 0 1 0 1 1 0               Rd        (0) (0) (0) (0)  Rm        1 M N 0         Rn
              cond


        SMULBB variant

        Applies when M = 0 && N = 0.

        SMULBB{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMULBT variant

        Applies when M = 1 && N = 0.

        SMULBT{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMULTB variant

        Applies when M = 0 && N = 1.

        SMULTB{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMULTT variant

        Applies when M = 1 && N = 1.

        SMULTT{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
         n_high = (N == ''1'');     m_high = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11            8 7 6 5 4 3              0
           1 1 1 1 1 0 1 1 0 0 0 1                    Rn         1 1 1 1         Rd        0 0 N M         Rm




        SMULBB variant

        Applies when N = 0 && M = 0.

        SMULBB{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMULBT variant

        Applies when N = 0 && M = 1.

        SMULBT{<c>}{<q>} {<Rd>,} <Rn>, <Rm>
SMULTB variant

Applies when N = 1 && M = 0.

SMULTB{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


SMULTT variant

Applies when N = 1 && M = 1.

SMULTT{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for all variants of this encoding

 d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
 n_high = (N == ''1'');    m_high = (M == ''1'');
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register holding the multiplicand in the bottom or top half
               (selected by <x>), encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register holding the multiplier in the bottom or top half
               (selected by <y>), encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     operand1 = if n_high then R[n]<31:16> else R[n]<15:0>;
     operand2 = if m_high then R[m]<31:16> else R[m]<15:0>;
     result = SInt(operand1) * SInt(operand2);
     R[d] = result<31:0>;
     // Signed overflow cannot occur');
INSERT INTO "instructions" VALUES('ARM','SMULBT','-R:SMULBB');
INSERT INTO "instructions" VALUES('ARM','SMULTB','-R:SMULBB');
INSERT INTO "instructions" VALUES('ARM','SMULTT','-R:SMULBB');
INSERT INTO "instructions" VALUES('ARM','SMULLS','        Signed Multiply Long multiplies two 32-bit signed values to produce a 64-bit result.       (F7.1.200)

        In A32 instructions, the condition flags can optionally be updated based on the result. Use of this option adversely
        affects performance on many implementations.


        A1


          31        28 27 26 25 24 23 22 21 20 19         16 15       12 11         8 7 6 5 4 3                0
             !=1111    0 0 0 0 1 1 0 S               RdHi        RdLo         Rm       1 0 0 1           Rn
              cond


        Flag setting variant

        Applies when S = 1.

        SMULLS{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Not flag setting variant

        Applies when S = 0.

        SMULL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for all variants of this encoding

         dLo = UInt(RdLo);    dHi = UInt(RdHi);     n = UInt(Rn);  m = UInt(Rm);  setflags = (S == ''1'');
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         if dHi == dLo then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11         8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 1 0 0 0                    Rn         RdLo        RdHi      0 0 0 0          Rm




        T1 variant

        SMULL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


        Decode for this encoding

         dLo = UInt(RdLo);    dHi = UInt(RdHi);     n = UInt(Rn);  m = UInt(Rm);  setflags = FALSE;
         if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13
         if dHi == dLo then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly SMULL on page J1-5357.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.
<RdLo>        Is the general-purpose destination register for the lower 32 bits of the result, encoded in the "RdLo"
              field.

<RdHi>        Is the general-purpose destination register for the upper 32 bits of the result, encoded in the "RdHi"
              field.

<Rn>          Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    result = SInt(R[n]) * SInt(R[m]);
    R[dHi] = result<63:32>;
    R[dLo] = result<31:0>;
    if setflags then
        PSTATE.N = result<63>;
        PSTATE.Z = IsZeroBit(result<63:0>);
        // PSTATE.C, PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','SMULWB','        Signed Multiply (word by halfword) multiplies a signed 32-bit quantity and a signed 16-bit quantity. The signed       (F7.1.201)
        16-bit quantity is taken from either the bottom or the top half of its source register. The other half of the second
        source register is ignored. The top 32 bits of the 48-bit product are written to the destination register. The bottom
        16 bits of the 48-bit product are ignored. No overflow is possible during this instruction.


        A1


          31        28 27 26 25 24 23 22 21 20 19          16 15 14 13 12 11           8 7 6 5 4 3               0
             !=1111     0 0 0 1 0 0 1 0               Rd      (0) (0) (0) (0)   Rm        1 M 1 0          Rn
              cond


        SMULWB variant

        Applies when M = 0.

        SMULWB{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMULWT variant

        Applies when M = 1.

        SMULWT{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);   m_high = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11           8 7 6 5 4 3                0
           1 1 1 1 1 0 1 1 0 0 1 1                    Rn       1 1 1 1           Rd       0 0 0 M          Rm




        SMULWB variant

        Applies when M = 0.

        SMULWB{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMULWT variant

        Applies when M = 1.

        SMULWT{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);   m_high = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>          Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register holding the multiplier in the bottom or top half
              (selected by <y>), encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    operand2 = if m_high then R[m]<31:16> else R[m]<15:0>;
    product = SInt(R[n]) * SInt(operand2);
    R[d] = product<47:16>;
    // Signed overflow cannot occur');
INSERT INTO "instructions" VALUES('ARM','SMULWT','-R:SMULWB');
INSERT INTO "instructions" VALUES('ARM','SMUSD','        Signed Multiply Subtract Dual performs two signed 16 x 16-bit multiplications. It subtracts one of the products from       (F7.1.202)
        the other, and writes the result to the destination register.

        Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This
        produces top x bottom and bottom x top multiplication.

        Overflow cannot occur.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11      8 7 6 5 4 3                 0
             !=1111     0 1 1 1 0 0 0 0                Rd       1 1 1 1        Rm      0 1 M 1          Rn
              cond


        SMUSD variant

        Applies when M = 0.

        SMUSD{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMUSDX variant

        Applies when M = 1.

        SMUSDX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);    m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11      8 7 6 5 4 3                 0
           1 1 1 1 1 0 1 1 0 1 0 0                     Rn       1 1 1 1        Rd      0 0 0 M          Rm




        SMUSD variant

        Applies when M = 0.

        SMUSD{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        SMUSDX variant

        Applies when M = 1.

        SMUSDX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


        Decode for all variants of this encoding

         d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);    m_swap = (M == ''1'');
         if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rd>          Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>          Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>          Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    operand2 = if m_swap then ROR(R[m],16) else R[m];
    product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
    product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
    result = product1 - product2;
    R[d] = result<31:0>;
    // Signed overflow cannot occur');
INSERT INTO "instructions" VALUES('ARM','SMUSDX','-R:SMUSD');
INSERT INTO "instructions" VALUES('ARM','SRS','        Store Return State stores the LR_<current_mode> and SPSR_<current_mode> to the stack of a specified mode. For       (F7.1.203)
        information about memory accesses see Memory accesses on page F2-2513.

        SRS is UNDEFINED in Hyp mode.

        SRS is UNPREDICTABLE if it is executed in User or System mode, or if the specified mode is any of the following:

        .      Not implemented.

        .      A mode that Table G1-2 on page G1-3806 does not show.

        .      Not accessible from the context that the SRS instruction is executed in, as follows:

               --      A mode that is at a higher Exception level.

               --      When executing in Non-secure state, Monitor mode.

        SRS is trapped to EL3 if all of the following are true:

        .      It is executed at Secure PL1.

        .      The specified mode is monitor mode.

        .      EL3 is using AArch64.

        See Traps to EL3 of Secure monitor functionality from Secure EL1 using AArch32 on page D1-1586.


        A1


          31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4                     0
           1 1 1 1 1 0 0 P U 1 W 0 (1) (1) (0) (1) (0) (0) (0) (0) (0) (1) (0) (1) (0) (0) (0)      mode




        Decrement After variant

        Applies when P = 0 && U = 0.

        SRSDA{<c>}{<q>} SP{!}, #<mode>


        Decrement Before variant

        Applies when P = 1 && U = 0.

        SRSDB{<c>}{<q>} SP{!}, #<mode>


        Increment After variant

        Applies when P = 0 && U = 1.

        SRS{IA}{<c>}{<q>} SP{!}, #<mode>


        Increment Before variant

        Applies when P = 1 && U = 1.

        SRSIB{<c>}{<q>} SP{!}, #<mode>


        Decode for all variants of this encoding

         wback = (W == ''1'');     increment = (U == ''1'');     wordhigher = (P == U);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 7 6 5 4                                  0
  1 1 1 0 1 0 0 0 0 0 W 0 (1) (1) (0) (1) (1) (1) (0) (0) (0) (0) (0) (0) (0) (0) (0)         mode




T1 variant

SRSDB{<c>}{<q>} SP{!}, #<mode>


Decode for this encoding

 wback = (W == ''1'');     increment = FALSE;   wordhigher = FALSE;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 7 6 5 4                                  0
  1 1 1 0 1 0 0 1 1 0 W 0 (1) (1) (0) (1) (1) (1) (0) (0) (0) (0) (0) (0) (0) (0) (0)         mode




T2 variant

SRS{IA}{<c>}{<q>} SP{!}, #<mode>


Decode for this encoding

 wback = (W == ''1'');     increment = TRUE;   wordhigher = FALSE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly SRS (T32) on page J1-5381 and SRS
(A32) on page J1-5382.


Assembler symbols

IA              For encoding A1: is an optional suffix to indicate the Increment After variant.

                For encoding T2: is an optional suffix for the Increment After form.

<c>             For encoding A1: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

                For encoding T1 and T2: see Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

!               The address adjusted by the size of the data loaded is written back to the base register. If specified,
                it is encoded in the "W" field as 1, otherwise this field defaults to 0.

<mode>          Is the number of the mode whose Banked SP is used as the base register, encoded in the "mode"
                field. For details of PE modes and their numbers see AArch32 PE mode descriptions on
                page G1-3806.

SRSFA, SRSEA, SRSFD, and SRSED are pseudo-instructions for SRSIB, SRSIA, SRSDB, and SRSDA respectively, referring to
their use for pushing data onto Full Ascending, Empty Ascending, Full Descending, and Empty Descending stacks.
        Operation for all encodings

         if CurrentInstrSet() == InstrSet_A32 then
             if ConditionPassed() then
                 EncodingSpecificOperations();
                 if PSTATE.EL == EL2 then              // UNDEFINED at EL2
                     UNDEFINED;

                 // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these
                 // to be security holes
                 if PSTATE.M IN {M32_User,M32_System} then
                     UNPREDICTABLE;
                 elsif mode == M32_Hyp then            // Check for attempt to access Hyp mode SP
                     UNPREDICTABLE;
                 elsif mode == M32_Monitor then        // Check for attempt to access Monitor mode SP
                     if !HaveEL(EL3) || !IsSecure()      then
                         UNPREDICTABLE;
                     elsif !ELUsingAArch32(EL3) then
                         AArch64.MonitorModeTrap();

                 base = Rmode[13,mode];
                 address = if increment then base else base-8;
                 if wordhigher then address = address+4;
                 MemA[address,4]     = LR;
                 MemA[address+4,4] = SPSR[];
                 if wback then Rmode[13,mode] = if increment then base+8 else base-8;
         else
             if ConditionPassed() then
                 EncodingSpecificOperations();
                 if PSTATE.EL == EL2 then              // UNDEFINED at EL2
                     UNDEFINED;

                 // Check for UNPREDICTABLE cases. The definition of UNPREDICTABLE does not permit these
                 // to be security holes
                 if PSTATE.M IN {M32_User,M32_System} then
                     UNPREDICTABLE;
                 elsif mode == M32_Hyp then            // Check for attempt to access Hyp mode SP
                     UNPREDICTABLE;
                 elsif mode == M32_Monitor then        // Check for attempt to access Monitor mode SP
                     if !HaveEL(EL3) || !IsSecure()      then
                         UNPREDICTABLE;
                     elsif !ELUsingAArch32(EL3) then
                         AArch64.MonitorModeTrap();

                 base = Rmode[13,mode];
                 address = if increment then base else base-8;
                 if wordhigher then address = address+4;
                 MemA[address,4]     = LR;
                 MemA[address+4,4] = SPSR[];
                 if wback then Rmode[13,mode] = if increment then base+8 else base-8;');
INSERT INTO "instructions" VALUES('ARM','SRSDA','-R:SRS');
INSERT INTO "instructions" VALUES('ARM','SRSDB','-R:SRS');
INSERT INTO "instructions" VALUES('ARM','SRSIA','-R:SRS');
INSERT INTO "instructions" VALUES('ARM','SRSIB','-R:SRS');
INSERT INTO "instructions" VALUES('ARM','SSAT','Signed Saturate saturates an optionally-shifted signed value to a selectable signed range.       (F7.1.204)

This instruction sets PSTATE.Q to 1 if the operation saturates.


A1


  31       28 27 26 25 24 23 22 21 20             16 15       12 11             7 6 5 4 3            0
     !=1111    0 1 1 0 1 0 1            sat_imm          Rd             imm5      sh 0 1       Rn
      cond


Arithmetic shift right variant

Applies when sh = 1.

SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount>


Logical shift left variant

Applies when sh = 0.

SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount>}


Decode for all variants of this encoding

 d = UInt(Rd);   n = UInt(Rn);   saturate_to = UInt(sat_imm)+1;
 (shift_t, shift_n) = DecodeImmShift(sh:''0'', imm5);
 if d == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14    12 11          8 7 6 5 4                0
  1 1 1 1 0 (0) 1 1 0 0 sh 0                 Rn      0    imm3         Rd      imm2 (0)    sat_imm




Arithmetic shift right variant

Applies when sh = 1 && !(imm3 == 000 && imm2 == 00).

SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount>


Logical shift left variant

Applies when sh = 0.

SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount>}


Decode for all variants of this encoding

 if sh == ''1'' && (imm3:imm2) == ''00000'' then SEE SSAT16;
 d = UInt(Rd);   n = UInt(Rn);   saturate_to = UInt(sat_imm)+1;
 (shift_t, shift_n) = DecodeImmShift(sh:''0'', imm3:imm2);
 if d == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.
        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

        <imm>          Is the bit position for saturation, in the range 1 to 32, encoded in the "sat_imm" field as <imm>-1.

        <Rn>           Is the general-purpose source register, encoded in the "Rn" field.

        <amount>       For encoding A1: is the optional shift amount, in the range 0 to 31, defaulting to 0 and encoded in
                       the "imm5" field.

                       For encoding A1: is the shift amount, in the range 1 to 32 encoded in the "imm5" field as <amount>
                       modulo 32.

                       For encoding T1: is the optional shift amount, in the range 0 to 31, defaulting to 0 and encoded in
                       the "imm3:imm2" field.

                       For encoding T1: is the shift amount, in the range 1 to 31 encoded in the "imm3:imm2" field as
                       <amount>.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             operand = Shift(R[n], shift_t, shift_n, PSTATE.C);         // PSTATE.C ignored
             (result, sat) = SignedSatQ(SInt(operand), saturate_to);
             R[d] = SignExtend(result, 32);
             if sat then
                 PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','SSAT16','Signed Saturate 16 saturates two signed 16-bit values to a selected signed range.       (F7.1.205)

This instruction sets PSTATE.Q to 1 if the operation saturates.


A1


  31       28 27 26 25 24 23 22 21 20 19             16 15       12 11 10 9 8 7 6 5 4 3                 0
     !=1111    0 1 1 0 1 0 1 0              sat_imm          Rd      (1) (1) (1) (1) 0 0 1 1       Rn
      cond


A1 variant

SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     saturate_to = UInt(sat_imm)+1;
 if d == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 0 (0) 1 1 0 0 1 0                    Rn        0 0 0 0          Rd         0 0 (0) (0) sat_imm




T1 variant

SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     saturate_to = UInt(sat_imm)+1;
 if d == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<imm>           Is the bit position for saturation, in the range 1 to 16, encoded in the "sat_imm" field as <imm>-1.

<Rn>            Is the general-purpose source register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     (result1, sat1) = SignedSatQ(SInt(R[n]<15:0>), saturate_to);
     (result2, sat2) = SignedSatQ(SInt(R[n]<31:16>), saturate_to);
             R[d]<15:0> = SignExtend(result1, 16);
             R[d]<31:16> = SignExtend(result2, 16);
             if sat1 || sat2 then
                 PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','SSAX','Signed Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one 16-bit       (F7.1.206)
integer subtraction and one 16-bit addition, and writes the results to the destination register. It sets PSTATE.GE
according to the results.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                    0
     !=1111    0 1 1 0 0 0 0 1                Rn           Rd      (1) (1) (1) (1) 0 1 0 1          Rm
      cond


A1 variant

SSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3               0
   1 1 1 1 1 0 1 0 1 1 1 0                    Rn       1 1 1 1          Rd        0 0 0 0           Rm




T1 variant

SSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum  = SInt(R[n]<15:0>) + SInt(R[m]<31:16>);
     diff = SInt(R[n]<31:16>) - SInt(R[m]<15:0>);
             R[d]<15:0>  = sum<15:0>;
             R[d]<31:16> = diff<15:0>;
             PSTATE.GE<1:0> = if sum    >= 0 then ''11'' else ''00'';
             PSTATE.GE<3:2> = if diff >= 0 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','SSUB16','Signed Subtract 16 performs two 16-bit signed integer subtractions, and writes the results to the destination register.       (F7.1.207)
It sets PSTATE.GE according to the results of the subtractions.


A1


   31       28 27 26 25 24 23 22 21 20 19        16 15         12 11 10 9 8 7 6 5 4 3                   0
      !=1111   0 1 1 0 0 0 0 1               Rn           Rd      (1) (1) (1) (1) 0 1 1 1         Rm
       cond


A1 variant

SSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


   15 14 13 12 11 10 9 8 7 6 5 4 3                0 15 14 13 12 11             8 7 6 5 4 3              0
   1 1 1 1 1 0 1 0 1 1 0 1                   Rn       1 1 1 1          Rd        0 0 0 0          Rm




T1 variant

SSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      diff1 = SInt(R[n]<15:0>) - SInt(R[m]<15:0>);
      diff2 = SInt(R[n]<31:16>) - SInt(R[m]<31:16>);
      R[d]<15:0>  = diff1<15:0>;
             R[d]<31:16> = diff2<15:0>;
             PSTATE.GE<1:0> = if diff1 >= 0 then ''11'' else ''00'';
             PSTATE.GE<3:2> = if diff2 >= 0 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','SSUB8','Signed Subtract 8 performs four 8-bit signed integer subtractions, and writes the results to the destination register.       (F7.1.208)
It sets PSTATE.GE according to the results of the subtractions.


A1


   31       28 27 26 25 24 23 22 21 20 19        16 15         12 11 10 9 8 7 6 5 4 3                  0
      !=1111   0 1 1 0 0 0 0 1               Rn           Rd      (1) (1) (1) (1) 1 1 1 1        Rm
       cond


A1 variant

SSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


   15 14 13 12 11 10 9 8 7 6 5 4 3                0 15 14 13 12 11             8 7 6 5 4 3             0
   1 1 1 1 1 0 1 0 1 1 0 0                   Rn       1 1 1 1          Rd        0 0 0 0         Rm




T1 variant

SSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      diff1 = SInt(R[n]<7:0>) - SInt(R[m]<7:0>);
      diff2 = SInt(R[n]<15:8>) - SInt(R[m]<15:8>);
      diff3 = SInt(R[n]<23:16>) - SInt(R[m]<23:16>);
             diff4 = SInt(R[n]<31:24>) - SInt(R[m]<31:24>);
             R[d]<7:0>   = diff1<7:0>;
             R[d]<15:8>  = diff2<7:0>;
             R[d]<23:16> = diff3<7:0>;
             R[d]<31:24> = diff4<7:0>;
             PSTATE.GE<0>   = if diff1 >= 0 then ''1'' else ''0'';
             PSTATE.GE<1>   = if diff2 >= 0 then ''1'' else ''0'';
             PSTATE.GE<2>   = if diff3 >= 0 then ''1'' else ''0'';
             PSTATE.GE<3>   = if diff4 >= 0 then ''1'' else ''0'';');
INSERT INTO "instructions" VALUES('ARM','STC','Store Coprocessor stores data from a conceptual coprocessor to a sequence of consecutive memory addresses.       (F7.1.209)

This is a generic coprocessor instruction. The coproc field identifies the target conceptual coprocessor. This must be
one of CP10, CP11, CP14, or CP15, and for these CP values, this manual defines the imm8, CRd, and D field values
that are valid STC and STC2 instructions. Other encodings are UNDEFINED. For more information see Conceptual
coprocessor support on page E1-2414 and General behavior of System registers on page G4-4172.

In an implementation that includes EL2, the permitted STC access to a system control register can be trapped to Hyp
mode, meaning that an attempt to execute an STC instruction in a Non-secure mode other than Hyp mode, that would
be permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see
Trapping general CP14 accesses to debug registers on page G1-3923.

For simplicity, the STC pseudocode does not show this possible trap to Hyp mode.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15        12 11          8 7                      0
     !=1111     1 1 0 P U D W 0               Rn          CRd          !=101x              imm8
      cond                                                              coproc


Offset variant

Applies when P = 1 && W = 0.

STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


Post-indexed variant

Applies when P = 0 && W = 1.

STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


Pre-indexed variant

Applies when P = 1 && W = 1.

STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


Unindexed variant

Applies when P = 0 && U = 1 && W = 0.

STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>


Decode for all variants of this encoding

 if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
 if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MCRR, MCRR2;
 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 n = UInt(Rn);    cp = UInt(coproc);
 imm32 = ZeroExtend(imm8:''00'', 32);       index = (P == ''1'');    add = (U == ''1'');     wback = (W == ''1'');
 if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;


A2


  31        28 27 26 25 24 23 22 21 20 19          16 15        12 11          8 7                      0
   1 1 1 1 1 1 0 P U D W 0                    Rn          CRd          !=101x              imm8
      cond                                                              coproc
        Offset variant

        Applies when P = 1 && W = 0.

        STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


        Post-indexed variant

        Applies when P = 0 && W = 1.

        STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


        Pre-indexed variant

        Applies when P = 1 && W = 1.

        STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


        Unindexed variant

        Applies when P = 0 && U = 1 && W = 0.

        STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>


        Decode for all variants of this encoding

         if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
         if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MCRR, MCRR2;
         if coproc == ''101x'' then UNDEFINED;
         n = UInt(Rn);  cp = UInt(coproc);
         imm32 = ZeroExtend(imm8:''00'', 32);      index = (P == ''1'');add = (U == ''1'');wback = (W == ''1'');
         if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15      12 11       8 7                  0
           1 1 1 0 1 1 0 P U D W 0                    Rn         CRd     !=101x         imm8
                                                                         coproc


        Offset variant

        Applies when P = 1 && W = 0.

        STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


        Post-indexed variant

        Applies when P = 0 && W = 1.

        STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


        Pre-indexed variant

        Applies when P = 1 && W = 1.

        STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


        Unindexed variant

        Applies when P = 0 && U = 1 && W = 0.

        STC{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>
Decode for all variants of this encoding

 if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
 if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MCRR, MCRR2;
 if coproc == ''101x'' then SEE "Advanced SIMD and Floating-point";
 n = UInt(Rn);  cp = UInt(coproc);
 imm32 = ZeroExtend(imm8:''00'', 32);      index = (P == ''1'');   add = (U == ''1'');    wback = (W == ''1'');
 if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11         8 7                       0
  1 1 1 1 1 1 0 P U D W 0                    Rn          CRd         !=101x              imm8
                                                                     coproc


Offset variant

Applies when P = 1 && W = 0.

STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>{, #{+/-}<imm>}]


Post-indexed variant

Applies when P = 0 && W = 1.

STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], #{+/-}<imm>


Pre-indexed variant

Applies when P = 1 && W = 1.

STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>, #{+/-}<imm>]!


Unindexed variant

Applies when P = 0 && U = 1 && W = 0.

STC2{L}{<c>}{<q>} <coproc>, <CRd>, [<Rn>], <option>


Decode for all variants of this encoding

 if P == ''0'' && U == ''0'' && D == ''0'' && W == ''0'' then UNDEFINED;
 if P == ''0'' && U == ''0'' && D == ''1'' && W == ''0'' then SEE MCRR, MCRR2;
 if coproc == ''101x'' then UNDEFINED;
 n = UInt(Rn);  cp = UInt(coproc);
 imm32 = ZeroExtend(imm8:''00'', 32);      index = (P == ''1'');   add = (U == ''1'');    wback = (W == ''1'');
 if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly STC, STC2 on page J1-5359.

Advanced SIMD and floating-point: Advanced SIMD and floating-point register load/store instructions on
page F5-2602.


Assembler symbols

L              If specified, selects the D == 1 form of the encoding. If omitted, selects the D == 0 form.

<c>            For encoding A1, T1 and T2: see Standard assembler syntax fields on page F2-2506.

               For encoding A2: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.
        <q>            See Standard assembler syntax fields on page F2-2506.

        <coproc>       Is the name of the coprocessor, encoded in the "coproc" field. The valid coprocessor names are p10,
                       p11, p14, and p15.

        <CRd>          Is the coprocessor register to be transferred, encoded in the "CRd" field.

        <Rn>           For encoding A1, A2: is the general-purpose base register, encoded in the "Rn" field. The PC can
                       be used, but this is deprecated.

                       For encoding A1, A2, T1, T2: is the general-purpose base register, encoded in the "Rn" field.

        <option>       Is a coprocessor option, in the range 0 to 255 enclosed in { }, encoded in the "imm8" field.

        +/-            Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
                       encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <imm>          Is the immediate offset used for forming the address, a multiple of 4 in the range 0-1020, defaulting
                       to 0 and encoded in the "imm8" field, as <imm>/4.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             Coproc_CheckInstr(cp, ThisInstr());
             offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
             address = if index then offset_addr else R[n];
             repeat
                 MemA[address,4] = Coproc_GetWordToStore(cp, ThisInstr());
                 address = address + 4;
             until Coproc_DoneStoring(cp, ThisInstr());
             if wback then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','STC2','-R:STC');
INSERT INTO "instructions" VALUES('ARM','STL','Store-Release Word stores a word from a register to memory. The instruction also has memory ordering semantics       (F7.1.210)
as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19           16 15 14 13 12 11 10 9 8 7 6 5 4 3                     0
     !=1111    0 0 0 1 1 0 0 0               Rn       (1) (1) (1) (1) (1) (1) 0 0 1 0 0 1          Rt
      cond


A1 variant

STL{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15           12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 0                   Rn            Rt         (1) (1) (1) (1) 1 0 1 0 (1) (1) (1) (1)




T1 variant

STL{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n];
     MemO[address, 4] = R[t];');
INSERT INTO "instructions" VALUES('ARM','STLB','Store-Release Byte stores a byte from a register to memory. The instruction also has memory ordering semantics as       (F7.1.211)
described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15 14 13 12 11 10 9 8 7 6 5 4 3                     0
     !=1111    0 0 0 1 1 1 0 0                Rn     (1) (1) (1) (1) (1) (1) 0 0 1 0 0 1          Rt
      cond


A1 variant

STLB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 0                    Rn          Rt         (1) (1) (1) (1) 1 0 0 0 (1) (1) (1) (1)




T1 variant

STLB{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n];
     MemO[address, 1] = R[t]<7:0>;');
INSERT INTO "instructions" VALUES('ARM','STLEX','Store-Release Exclusive Word stores a word from a register to memory if the executing PE has exclusive access to       (F7.1.212)
the memory at that address, and returns a status value of 0 if the store was successful, or of 1 if no store was
performed.

The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                   0
     !=1111    0 0 0 1 1 0 0 0               Rn           Rd       (1) (1) 1 0 1 0 0 1             Rt
      cond


A1 variant

STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    n = UInt(Rn);
 if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 0 1 0 0 0 1 1 0 0                   Rn           Rt       (1) (1) (1) (1) 1 1 1 0         Rd




T1 variant

STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    n = UInt(Rn);
 if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the destination general-purpose register into which the status result of the store exclusive is
               written, encoded in the "Rd" field. The value returned is:

               0           If the operation updates memory.

               1           If the operation fails to update memory.
        <Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>            Is the general-purpose base register, encoded in the "Rn" field.

        Aborts and alignment

        If a synchronous Data Abort exception is generated by the execution of this instruction:

        .      Memory is not updated.

        .      <Rd> is not updated.

        A non word-aligned memory address causes an Alignment fault Data Abort exception to be generated, subject to
        the following rules:

        .      If AArch32.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

        .      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

        If AArch32.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
        synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


        Operation for all encodings

         if ConditionPassed() then
              EncodingSpecificOperations();
              address = R[n];
              if AArch32.ExclusiveMonitorsPass(address,4) then
                  MemO[address, 4] = R[t];
                  R[d] = ZeroExtend(''0'');
              else
                  R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STLEXB','Store-Release Exclusive Byte stores a byte from a register to memory if the executing PE has exclusive access to       (F7.1.213)
the memory at that address, and returns a status value of 0 if the store was successful, or of 1 if no store was
performed.

The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                   0
     !=1111    0 0 0 1 1 1 0 0               Rn           Rd       (1) (1) 1 0 1 0 0 1             Rt
      cond


A1 variant

STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    n = UInt(Rn);
 if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 0 1 0 0 0 1 1 0 0                   Rn           Rt       (1) (1) (1) (1) 1 1 0 0         Rd




T1 variant

STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    n = UInt(Rn);
 if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the destination general-purpose register into which the status result of the store exclusive is
               written, encoded in the "Rd" field. The value returned is:

               0           If the operation updates memory.

               1           If the operation fails to update memory.
        <Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>            Is the general-purpose base register, encoded in the "Rn" field.


        Aborts

        If a synchronous Data Abort exception is generated by the execution of this instruction:

        .      Memory is not updated.

        .      <Rd> is not updated.

        If ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a synchronous Data
        Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


        Operation for all encodings

         if ConditionPassed() then
              EncodingSpecificOperations();
              address = R[n];
              if AArch32.ExclusiveMonitorsPass(address,1) then
                  MemO[address, 1] = R[t]<7:0>;
                  R[d] = ZeroExtend(''0'');
              else
                  R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STLEXD','Store-Release Exclusive Doubleword stores a doubleword from two registers to memory if the executing PE has       (F7.1.214)
exclusive access to the memory at that address, and returns a status value of 0 if the store was successful, or of 1 if
no store was performed.

The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
     !=1111    0 0 0 1 1 0 1 0               Rn           Rd       (1) (1) 1 0 1 0 0 1            Rt
      cond


A1 variant

STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    t2 = t+1;  n = UInt(Rn);
 if d == 15 || Rt<0> == ''1'' || t2 == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t || d == t2 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11         8 7 6 5 4 3               0
   1 1 1 0 1 0 0 0 1 1 0 0                   Rn           Rt            Rt2     1 1 1 1           Rd




T1 variant

STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    t2 = UInt(Rt2);    n = UInt(Rn);
 if d == 15 || t == 15 || t2 == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t || d == t2 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly STLEXD on page J1-5376.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the destination general-purpose register into which the status result of the store exclusive is
               written, encoded in the "Rd" field. The value returned is:

               0           If the operation updates memory.

               1           If the operation fails to update memory.
        <Rt>            For encoding A1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
                        <Rt> must be even-numbered and not R14.

                        For encoding T1: is the first general-purpose register to be transferred, encoded in the "Rt" field.

        <Rt2>           For encoding A1: is the second general-purpose register to be transferred. <Rt2> must be <R(t+1)>.

                        For encoding T1: is the second general-purpose register to be transferred, encoded in the "Rt2" field.

        <Rn>            Is the general-purpose base register, encoded in the "Rn" field.


        Aborts and alignment

        If a synchronous Data Abort exception is generated by the execution of this instruction:

        .      Memory is not updated.

        .      <Rd> is not updated.

        A non word-aligned memory address causes an Alignment fault Data Abort exception to be generated, subject to
        the following rules:

        .      If AArch32.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

        .      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

        If AArch32.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
        synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


        Operation for all encodings

         if ConditionPassed() then
              EncodingSpecificOperations();
              address = R[n];
              // Create doubleword to store such that R[t] will be stored at address and R[t2] at address+4.
              value = if BigEndian() then R[t]:R[t2] else R[t2]:R[t];
              if AArch32.ExclusiveMonitorsPass(address, 8) then
                  MemO[address, 8] = value;
                  R[d] = ZeroExtend(''0'');
              else
                  R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STLEXH','Store-Release Exclusive Halfword stores a halfword from a register to memory if the executing PE has exclusive       (F7.1.215)
access to the memory at that address, and returns a status value of 0 if the store was successful, or of 1 if no store
was performed.

The instruction also has memory ordering semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3                   0
     !=1111    0 0 0 1 1 1 1 0               Rn           Rd       (1) (1) 1 0 1 0 0 1            Rt
      cond


A1 variant

STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    n = UInt(Rn);
 if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 0 1 0 0 0 1 1 0 0                   Rn           Rt       (1) (1) (1) (1) 1 1 0 1        Rd




T1 variant

STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


Decode for this encoding

 d = UInt(Rd);   t = UInt(Rt);    n = UInt(Rn);
 if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
 if d == n || d == t then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the destination general-purpose register into which the status result of the store exclusive is
               written, encoded in the "Rd" field. The value returned is:

               0           If the operation updates memory.

               1           If the operation fails to update memory.
        <Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>            Is the general-purpose base register, encoded in the "Rn" field.


        Aborts and alignment

        If a synchronous Data Abort exception is generated by the execution of this instruction:

        .      Memory is not updated

        .      <Rd> is not updated.

        A non word-aligned memory address causes an Alignment fault Data Abort exception to be generated, subject to
        the following rules:

        .      If AArch32.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

        .      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

        If AArch32.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
        synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


        Operation for all encodings

         if ConditionPassed() then
              EncodingSpecificOperations();
              address = R[n];
              if AArch32.ExclusiveMonitorsPass(address,2) then
                  MemO[address, 2] = R[t]<15:0>;
                  R[d] = ZeroExtend(''0'');
              else
                  R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STLH','Store-Release Halfword stores a halfword from a register to memory. The instruction also has memory ordering       (F7.1.216)
semantics as described in Load-Acquire, Store-Release on page B2-88.

For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
information about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15 14 13 12 11 10 9 8 7 6 5 4 3                     0
     !=1111   0 0 0 1 1 1 1 0               Rn       (1) (1) (1) (1) (1) (1) 0 0 1 0 0 1          Rt
      cond


A1 variant

STLH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15           12 11 10 9 8 7 6 5 4 3 2 1 0
   1 1 1 0 1 0 0 0 1 1 0 0                  Rn            Rt         (1) (1) (1) (1) 1 0 0 1 (1) (1) (1) (1)




T1 variant

STLH{<c>}{<q>} <Rt>, [<Rn>]


Decode for this encoding

 t = UInt(Rt); n = UInt(Rn);
 if t == 15 || n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n];
     MemO[address, 2] = R[t]<15:0>;');
INSERT INTO "instructions" VALUES('ARM','STM','        Store Multiple (Increment After, Empty Ascending) stores multiple registers to consecutive memory locations using       (F7.1.217)
        an address from a base register. The consecutive memory locations start at this address, and the address just above
        the last of those locations can optionally be written back to the base register.

        The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
        from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
        page F2-2514.

        For details of related system instructions see STM (User registers).


        A1


          31         28 27 26 25 24 23 22 21 20 19         16 15                                             0
             !=1111     1 0 0 0 1 0 W 0               Rn                          register_list
              cond


        A1 variant

        STM{IA}{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
        STMEA{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Empty Ascending stack


        Decode for this encoding

         n = UInt(Rn);     registers = register_list;    wback = (W == ''1'');
         if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10       8 7                       0
           1 1 0 0 0          Rn           register_list




        T1 variant

        STM{IA}{<c>}{<q>} <Rn>!, <registers>// Preferred syntax
        STMEA{<c>}{<q>} <Rn>!, <registers>// Alternate syntax, Empty Ascending stack


        Decode for this encoding

         n = UInt(Rn);     registers = ''00000000'':register_list;     wback = TRUE;
         if BitCount(registers) < 1 then UNPREDICTABLE;


        T2


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12                                    0
           1 1 1 0 1 0 0 0 1 0 W 0                    Rn      (0) M (0)                 register_list




        T2 variant

        STM{IA}{<c>}.W <Rn>{!}, <registers>// Preferred syntax, if <Rn>, ''!'' and <registers> can be represented
        in T1
        STMEA{<c>}.W <Rn>{!}, <registers>// Alternate syntax, Empty Ascending stack, if <Rn>, ''!'' and <registers>
        can be represented in T1
        STM{IA}{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
        STMEA{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Empty Ascending stack
Decode for this encoding

 n = UInt(Rn);   registers = ''0'':M:''0'':register_list;        wback = (W == ''1'');
 if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
 if wback && registers<n> == ''1'' then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly STM (STMIA, STMEA) on
page J1-5359.


Assembler symbols

IA             Is an optional suffix for the Increment After form.

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rn>           Is the general-purpose base register, encoded in the "Rn" field.

!              The address adjusted by the size of the data loaded is written back to the base register. If specified,
               it is encoded in the "W" field as 1, otherwise this field defaults to 0.

<registers>    For encoding A1: is a list of one or more registers to be stored, separated by commas and surrounded
               by { and }. The PC can be in the list. However, ARM deprecates the use of instructions that include
               the PC in the list. If base register writeback is specified, and the base register is not the
               lowest-numbered register in the list, such an instruction stores an UNKNOWN value for the base
               register.

               For encoding T1: is a list of one or more registers to be stored, separated by commas and surrounded
               by { and }. The registers in the list must be in the range R0-R7, encoded in the "register_list" field.
               If the base register is not the lowest-numbered register in the list, such an instruction stores an
               UNKNOWN value for the base register.

               For encoding T2: is a list of one or more registers to be stored, separated by commas and surrounded
               by { and }. The registers in the list must be in the range R0-R12, encoded in the "register_list" field,
               and can optionally contain the LR. If the LR is in the list, the "M" field is set to 1, otherwise it
               defaults to 0.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     address = R[n];
     for i = 0 to 14
         if registers<i> == ''1'' then
              if i == n && wback && i != LowestSetBit(registers) then
                  MemA[address,4] = bits(32) UNKNOWN;        // Only possible for encodings T1 and A1
              else
                  MemA[address,4] = R[i];
              address = address + 4;
     if registers<15> == ''1'' then      // Only possible for encoding A1
         MemA[address,4] = PCStoreValue();
     if wback then R[n] = R[n] + 4*BitCount(registers);');
INSERT INTO "instructions" VALUES('ARM','STMIA','-R:STM');
INSERT INTO "instructions" VALUES('ARM','STMEA','-R:STM');
INSERT INTO "instructions" VALUES('ARM','STMDA','     Store Multiple Decrement After (Empty Descending) stores multiple registers to consecutive memory locations       (F7.1.219)
     using an address from a base register. The consecutive memory locations end at this address, and the address just
     below the lowest of those locations can optionally be written back to the base register.

     The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
     from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
     page F2-2514.

     For details of related system instructions see STM (User registers).


     A1


       31        28 27 26 25 24 23 22 21 20 19            16 15                                                0
          !=1111     1 0 0 0 0 0 W 0                Rn                            register_list
           cond


     A1 variant

     STMDA{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
     STMED{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Empty Descending stack


     Decode for this encoding

      n = UInt(Rn);    registers = register_list;       wback = (W == ''1'');
      if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors, and particularly STMDA (STMED) on page J1-5360.


     Assembler symbols

     <c>             See Standard assembler syntax fields on page F2-2506.

     <q>             See Standard assembler syntax fields on page F2-2506.

     <Rn>            Is the general-purpose base register, encoded in the "Rn" field.

     !               The address adjusted by the size of the data loaded is written back to the base register. If specified,
                     it is encoded in the "W" field as 1, otherwise this field defaults to 0.

     <registers>     Is a list of one or more registers to be stored, separated by commas and surrounded by { and }. The
                     PC can be in the list. However, ARM deprecates the use of instructions that include the PC in the
                     list. If base register writeback is specified, and the base register is not the lowest-numbered register
                     in the list, such an instruction stores an UNKNOWN value for the base register.


     Operation

      if ConditionPassed() then
          EncodingSpecificOperations();
          address = R[n] - 4*BitCount(registers) + 4;
          for i = 0 to 14
               if registers<i> == ''1'' then
                    if i == n && wback && i != LowestSetBit(registers) then
                        MemA[address,4] = bits(32) UNKNOWN;
                    else
                        MemA[address,4] = R[i];
                    address = address + 4;
if registers<15> == ''1'' then
   MemA[address,4] = PCStoreValue();
if wback then R[n] = R[n] - 4*BitCount(registers);');
INSERT INTO "instructions" VALUES('ARM','STMED','-R:STMDA');
INSERT INTO "instructions" VALUES('ARM','STMDB','        Store Multiple Decrement Before (Full Descending) stores multiple registers to consecutive memory locations       (F7.1.220)
        using an address from a base register. The consecutive memory locations end just below this address, and the
        address of the first of those locations can optionally be written back to the base register.

        The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
        from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
        page F2-2514.

        For details of related system instructions see STM (User registers).

        This instruction is used by the alias PUSH (multiple registers). See the Alias conditions on page F7-3099 table for
        details of when each alias is preferred.


        A1


          31        28 27 26 25 24 23 22 21 20 19          16 15                                             0
             !=1111     1 0 0 1 0 0 W 0               Rn                           register_list
              cond


        A1 variant

        STMDB{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
        STMFD{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Full Descending stack


        Decode for this encoding

         n = UInt(Rn);    registers = register_list;     wback = (W == ''1'');
         if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12                                    0
           1 1 1 0 1 0 0 1 0 0 W 0                    Rn       (0) M (0)               register_list




        T1 variant

        STMDB{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
        STMFD{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Full Descending stack


        Decode for this encoding

         n = UInt(Rn);    registers = ''0'':M:''0'':register_list;      wback = (W == ''1'');
         if n == 15 || BitCount(registers) < 2 then UNPREDICTABLE;
         if wback && registers<n> == ''1'' then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STMDB (STMFD) on page J1-5361.
Alias conditions


              Alias                           is preferred when

              PUSH (multiple registers)       W == ''1'' && Rn == ''1101'' && BitCount(register_list) > 1



Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rn>          Is the general-purpose base register, encoded in the "Rn" field.

!             The address adjusted by the size of the data loaded is written back to the base register. If specified,
              it is encoded in the "W" field as 1, otherwise this field defaults to 0.

<registers>   For encoding A1: is a list of one or more registers to be stored, separated by commas and surrounded
              by { and }. The PC can be in the list. However, ARM deprecates the use of instructions that include
              the PC in the list. If base register writeback is specified, and the base register is not the
              lowest-numbered register in the list, such an instruction stores an UNKNOWN value for the base
              register.

              For encoding T1: is a list of one or more registers to be stored, separated by commas and surrounded
              by { and }. The registers in the list must be in the range R0-R12, encoded in the "register_list" field,
              and can optionally contain the LR. If the LR is in the list, the "M" field is set to 1, otherwise it
              defaults to 0.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    address = R[n] - 4*BitCount(registers);
    for i = 0 to 14
        if registers<i> == ''1'' then
            if i == n && wback && i != LowestSetBit(registers) then
                 MemA[address,4] = bits(32) UNKNOWN;        // Only possible for encoding A1
            else
                 MemA[address,4] = R[i];
            address = address + 4;
    if registers<15> == ''1'' then      // Only possible for encoding A1
        MemA[address,4] = PCStoreValue();
    if wback then R[n] = R[n] - 4*BitCount(registers);');
INSERT INTO "instructions" VALUES('ARM','STMFD','-R:STMDB');
INSERT INTO "instructions" VALUES('ARM','STMIB','     Store Multiple Increment Before (Full Ascending) stores multiple registers to consecutive memory locations using       (F7.1.221)
     an address from a base register. The consecutive memory locations start just above this address, and the address of
     the last of those locations can optionally be written back to the base register.

     The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register
     from the highest memory address. See also Encoding of lists of general-purpose registers and the PC on
     page F2-2514.

     For details of related system instructions see STM (User registers).


     A1


       31         28 27 26 25 24 23 22 21 20 19            16 15                                                0
          !=1111     1 0 0 1 1 0 W 0                 Rn                            register_list
           cond


     A1 variant

     STMIB{<c>}{<q>} <Rn>{!}, <registers>// Preferred syntax
     STMFA{<c>}{<q>} <Rn>{!}, <registers>// Alternate syntax, Full Ascending stack


     Decode for this encoding

      n = UInt(Rn);     registers = register_list;       wback = (W == ''1'');
      if n == 15 || BitCount(registers) < 1 then UNPREDICTABLE;


     Notes for all encodings

     For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
     Architectural Constraints on UNPREDICTABLE behaviors, and particularly STMIB (STMFA) on page J1-5361.


     Assembler symbols

     <c>              See Standard assembler syntax fields on page F2-2506.

     <q>              See Standard assembler syntax fields on page F2-2506.

     <Rn>             Is the general-purpose base register, encoded in the "Rn" field.

     !                The address adjusted by the size of the data loaded is written back to the base register. If specified,
                      it is encoded in the "W" field as 1, otherwise this field defaults to 0.

     <registers>      Is a list of one or more registers to be stored, separated by commas and surrounded by { and }. The
                      PC can be in the list. However, ARM deprecates the use of instructions that include the PC in the
                      list. If base register writeback is specified, and the base register is not the lowest-numbered register
                      in the list, such an instruction stores an UNKNOWN value for the base register.


     Operation

      if ConditionPassed() then
          EncodingSpecificOperations();
          address = R[n] + 4;
          for i = 0 to 14
               if registers<i> == ''1'' then
                    if i == n && wback && i != LowestSetBit(registers) then
                         MemA[address,4] = bits(32) UNKNOWN;
                    else
                         MemA[address,4] = R[i];
                    address = address + 4;
if registers<15> == ''1'' then
   MemA[address,4] = PCStoreValue();
if wback then R[n] = R[n] + 4*BitCount(registers);');
INSERT INTO "instructions" VALUES('ARM','STMFA','-R:STMIB');
INSERT INTO "instructions" VALUES('ARM','STRBT','Store Register Byte Unprivileged stores a byte from a register to memory. For information about memory accesses       (F7.1.226)
see Memory accesses on page F2-2513.

The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
actually running in User mode.

STRBT is UNPREDICTABLE in Hyp mode.

The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
base register value and an immediate offset, and leaves the base register unchanged.

The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
memory access, and calculates a new address from a base register value and an offset and writes it back to the base
register. The offset can be an immediate value or an optionally-shifted register value.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15        12 11                                 0
     !=1111     0 1 0 0 U 1 1 0              Rn           Rt                      imm12
      cond


A1 variant

STRBT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   postindex = TRUE;   add = (U == ''1'');
 register_form = FALSE;     imm32 = ZeroExtend(imm12, 32);
 if t == 15 || n == 15 || n == t then UNPREDICTABLE;


A2


  31        28 27 26 25 24 23 22 21 20 19         16 15        12 11            7 6 5 4 3            0
     !=1111     0 1 1 0 U 1 1 0              Rn           Rt            imm5       type 0      Rm
      cond


A2 variant

STRBT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   m = UInt(Rm);   postindex = TRUE;     add = (U == ''1'');
 register_form = TRUE;     (shift_t, shift_n) = DecodeImmShift(type, imm5);
 if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7                        0
  1 1 1 1 1 0 0 0 0 0 0 0                  !=1111         Rt      1 1 1 0               imm8
                                             Rn


T1 variant

STRBT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
        Decode for this encoding

         if Rn == ''1111'' then UNDEFINED;
         t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;   add = TRUE;
         register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STRBT on page J1-5367.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rt>           For encoding A1: is the general-purpose register to be transferred, encoded in the "Rt" field. The PC
                       can be used, but this is deprecated.

                       For encoding A2 and T1: is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>           For encoding A1: is the general-purpose base register, encoded in the "Rn" field. The SP can be
                       used.

                       For encoding A2 and T1: is the general-purpose base register, encoded in the "Rn" field.

        +/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
                       + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

                       For encoding A2: specifies the index register is added to or subtracted from the base register,
                       defaulting to + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <Rm>           Is the general-purpose index register, encoded in the "Rm" field.

        <shift>        The shift to apply to the value read from <Rm>. If absent, no shift is applied. Otherwise, see Shifts
                       applied to a register on page F2-2510.

        +              Specifies the offset is added to the base register.

        <imm>          For encoding A1: is the optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
                       defaulting to 0 and encoded in the "imm12" field.

                       For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm8" field.


        Operation for all encodings

         if ConditionPassed() then
             if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
             EncodingSpecificOperations();
             offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32;
             offset_addr = if add then (R[n] + offset) else (R[n] - offset);
             address = if postindex then R[n] else offset_addr;
             MemU_unpriv[address,1] = R[t]<7:0>;
             if postindex then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','STRD','Store Register Dual (immediate) calculates an address from a base register value and an immediate offset, and stores       (F7.1.227)
two words from two registers to memory. It can use offset, post-indexed, or pre-indexed addressing. For information
about memory accesses see Memory accesses on page F2-2513.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15         12 11         8 7 6 5 4 3             0
    !=1111     0 0 0 P U 1 W 0              Rn             Rt        imm4H      1 1 1 1       imm4L
      cond


Offset variant

Applies when P = 1 && W = 0.

STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn> {, #{+/-}<imm>}]


Post-indexed variant

Applies when P = 0 && W = 0.

STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm>


Pre-indexed variant

Applies when P = 1 && W = 1.

STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<imm>]!


Decode for all variants of this encoding

 if Rt<0> == ''1'' then UNPREDICTABLE;
 t = UInt(Rt);  t2 = t+1;   n = UInt(Rn);    imm32 = ZeroExtend(imm4H:imm4L, 32);
 index = (P == ''1'');   add = (U == ''1'');    wback = (P == ''0'') || (W == ''1'');
 if P == ''0'' && W == ''1'' then UNPREDICTABLE;
 if wback && (n == 15 || n == t || n == t2) then UNPREDICTABLE;
 if t2 == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15          12 11         8 7                     0
  1 1 1 0 1 0 0 P U 1 W 0                 !=1111           Rt          Rt2               imm8
                                            Rn


Offset variant

Applies when P = 1 && W = 0.

STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn> {, #{+/-}<imm>}]


Post-indexed variant

Applies when P = 0 && W = 1.

STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm>


Pre-indexed variant

Applies when P = 1 && W = 1.

STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<imm>]!
        Decode for all variants of this encoding

         if P == ''0'' && W == ''0'' then SEE "Related encodings";
         t = UInt(Rt);   t2 = UInt(Rt2);    n = UInt(Rn);   imm32 = ZeroExtend(imm8:''00'', 32);
         index = (P == ''1'');   add = (U == ''1'');     wback = (W == ''1'');
         if wback && (n == t || n == t2) then UNPREDICTABLE;
         if n == 15 || t == 15 || t2 == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STRD (immediate) on page J1-5372.

        Related encodings: Load/Store dual, Load/Store-Exclusive, Load-Acquire/Store-Release, table branch on
        page F3-2536.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rt>           For encoding A1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
                       This register must be even-numbered and not R14.

                       For encoding T1: is the first general-purpose register to be transferred, encoded in the "Rt" field.

        <Rt2>          For encoding A1: is the second general-purpose register to be transferred. This register must be
                       <R(t+1)>.

                       For encoding T1: is the second general-purpose register to be transferred, encoded in the "Rt2" field.

        <Rn>           For encoding A1: is the general-purpose base register, encoded in the "Rn" field. The PC can be
                       used, but this is deprecated.

                       For the offset, post-indexed or pre-indexed variant: is the general-purpose base register, encoded in
                       the "Rn" field.

        +/-            Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
                       encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <imm>          For encoding A1: is the optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm4H:imm4L" field.

                       For the post-indexed or pre-indexed variant: is the unsigned immediate byte offset, a multiple of 4,
                       in the range 0 to 1020, encoded in the "imm8" field as <imm>/4.

                       For the post-indexed or pre-indexed variant: is the 8-bit unsigned immediate byte offset, in the range
                       0 to 255, encoded in the "imm4H:imm4L" field.

                       For encoding T1: is the optional unsigned immediate byte offset, a multiple of 4, in the range 0 to
                       1020, defaulting to 0 and encoded in the "imm8" field as <imm>/4.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             offset_addr = if add then (R[n] + imm32) else (R[n] - imm32);
             address = if index then offset_addr else R[n];
             if address == Align(address, 8) then
                 bits(64) data;
                 if BigEndian() then
                      data<63:32> = R[t];
                      data<31:0> = R[t2];
      else
          data<31:0> = R[t];
          data<63:32> = R[t2];
      MemA[address,8] = data;
   else
      MemA[address,4] = R[t];
      MemA[address+4,4] = R[t2];
   if wback then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','STREX','        Store Register Exclusive calculates an address from a base register value and an immediate offset, stores a word       (F7.1.229)
        from a register to the calculated address if the PE has exclusive access to the memory at that address, and returns a
        status value of 0 if the store was successful, or of 1 if no store was performed.

        For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
        information about memory accesses see Memory accesses on page F2-2513.


        A1


          31       28 27 26 25 24 23 22 21 20 19             16 15        12 11 10 9 8 7 6 5 4 3                0
             !=1111     0 0 0 1 1 0 0 0                Rn            Rd     (1) (1) 1 1 1 0 0 1            Rt
              cond


        A1 variant

        STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn> {, {#}<imm>}]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);    n = UInt(Rn);     imm32 = Zeros(32); // Zero offset
         if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
         if d == n || d == t then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15         12 11       8 7                       0
           1 1 1 0 1 0 0 0 0 1 0 0                     Rn            Rt          Rd               imm8




        T1 variant

        STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn> {, #<imm>}]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);    n = UInt(Rn);     imm32 = ZeroExtend(imm8:''00'', 32);
         if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
         if d == n || d == t then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STREX on page J1-5374.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            Is the destination general-purpose register into which the status result of the store exclusive is
                        written, encoded in the "Rd" field. The value returned is:

                        0            If the operation updates memory.

                        1            If the operation fails to update memory.

        <Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.
<Rn>            Is the general-purpose base register, encoded in the "Rn" field.

<imm>           For encoding A1: the immediate offset added to the value of <Rn> to calculate the address. <imm> can
                only be 0 or omitted.

                For encoding T1: the immediate offset added to the value of <Rn> to calculate the address. <imm> can
                be omitted, meaning an offset of 0. Values are multiples of 4 in the range 0-1020.

Aborts and alignment

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Rd> is not updated.

A non word-aligned memory address causes an Alignment fault Data Abort exception to be generated, subject to
the following rules:

.      If AArch32.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

.      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

If AArch32.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      address = R[n] + imm32;
      if AArch32.ExclusiveMonitorsPass(address,4) then
          MemA[address,4] = R[t];
          R[d] = ZeroExtend(''0'');
      else
          R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STREXB','        Store Register Exclusive Byte derives an address from a base register value, stores a byte from a register to the       (F7.1.230)
        derived address if the executing PE has exclusive access to the memory at that address, and returns a status value
        of 0 if the store was successful, or of 1 if no store was performed.

        For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
        information about memory accesses see Memory accesses on page F2-2513.


        A1


          31         28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
             !=1111      0 0 0 1 1 1 0 0                Rn          Rd      (1) (1) 1 1 1 0 0 1             Rt
              cond


        A1 variant

        STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);     n = UInt(Rn);
         if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
         if d == n || d == t then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                     0 15       12 11 10 9 8 7 6 5 4 3                  0
           1 1 1 0 1 0 0 0 1 1 0 0                      Rn          Rt      (1) (1) (1) (1) 0 1 0 0        Rd




        T1 variant

        STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);     n = UInt(Rn);
         if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
         if d == n || d == t then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STREXB on page J1-5374.


        Assembler symbols

        <c>              See Standard assembler syntax fields on page F2-2506.

        <q>              See Standard assembler syntax fields on page F2-2506.

        <Rd>             Is the destination general-purpose register into which the status result of the store exclusive is
                         written, encoded in the "Rd" field. The value returned is:

                         0           If the operation updates memory.

                         1           If the operation fails to update memory.

        <Rt>             Is the general-purpose register to be transferred, encoded in the "Rt" field.
<Rn>            Is the general-purpose base register, encoded in the "Rn" field.

Aborts

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Rd> is not updated.

If AArch32.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      address = R[n];
      if AArch32.ExclusiveMonitorsPass(address,1) then
         MemA[address,1] = R[t]<7:0>;
         R[d] = ZeroExtend(''0'');
      else
         R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STREXD','        Store Register Exclusive Doubleword derives an address from a base register value, stores a 64-bit doubleword from       (F7.1.231)
        two registers to the derived address if the executing PE has exclusive access to the memory at that address, and
        returns a status value of 0 if the store was successful, or of 1 if no store was performed.

        For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
        information about memory accesses see Memory accesses on page F2-2513.


        A1


          31        28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                 0
             !=1111     0 0 0 1 1 0 1 0                Rn           Rd       (1) (1) 1 1 1 0 0 1            Rt
              cond


        A1 variant

        STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);     t2 = t+1;  n = UInt(Rn);
         if d == 15 || Rt<0> == ''1'' || t2 == 15 || n == 15 then UNPREDICTABLE;
         if d == n || d == t || d == t2 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15         12 11        8 7 6 5 4 3               0
           1 1 1 0 1 0 0 0 1 1 0 0                     Rn           Rt            Rt2     0 1 1 1          Rd




        T1 variant

        STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);     t2 = UInt(Rt2);    n = UInt(Rn);
         if d == 15 || t == 15 || t2 == 15 || n == 15 then UNPREDICTABLE;
         // ARMv8-A removes UNPREDICTABLE for R13
         if d == n || d == t || d == t2 then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STREXD on page J1-5374.


        Assembler symbols

        <c>              See Standard assembler syntax fields on page F2-2506.

        <q>              See Standard assembler syntax fields on page F2-2506.

        <Rd>             Is the destination general-purpose register into which the status result of the store exclusive is
                         written, encoded in the "Rd" field. The value returned is:

                         0           If the operation updates memory.

                         1           If the operation fails to update memory.

                         <Rd> must not be the same as <Rn>, <Rt>, or <Rt2>.
<Rt>            For encoding A1: is the first general-purpose register to be transferred, encoded in the "Rt" field.
                <Rt> must be even-numbered and not R14.

                For encoding T1: is the first general-purpose register to be transferred, encoded in the "Rt" field.

<Rt2>           For encoding A1: is the second general-purpose register to be transferred. <Rt2> must be <R(t+1)>.

                For encoding T1: is the second general-purpose register to be transferred, encoded in the "Rt2" field.

<Rn>            Is the general-purpose base register, encoded in the "Rn" field.

Aborts and alignment

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Rd> is not updated.

A non doubleword-aligned memory address causes an Alignment fault Data Abort exception to be generated,
subject to the following rules:

.      If AArch32.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

.      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

If AArch32.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      address = R[n];
      // Create doubleword to store such that R[t] will be stored at address and R[t2] at address+4.
      value = if BigEndian() then R[t]:R[t2] else R[t2]:R[t];
      if AArch32.ExclusiveMonitorsPass(address,8) then
          MemA[address,8] = value;    R[d] = ZeroExtend(''0'');
      else
          R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STREXH','        Store Register Exclusive Halfword derives an address from a base register value, stores a halfword from a register       (F7.1.232)
        to the derived address if the executing PE has exclusive access to the memory at that address, and returns a status
        value of 0 if the store was successful, or of 1 if no store was performed.

        For more information about support for shared memory see Synchronization and semaphores on page E2-2456. For
        information about memory accesses see Memory accesses on page F2-2513.


        A1


          31        28 27 26 25 24 23 22 21 20 19            16 15       12 11 10 9 8 7 6 5 4 3                 0
             !=1111     0 0 0 1 1 1 1 0                Rn           Rd      (1) (1) 1 1 1 0 0 1            Rt
              cond


        A1 variant

        STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);    n = UInt(Rn);
         if d == 15 || t == 15 || n == 15 then UNPREDICTABLE;
         if d == n || d == t then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15        12 11 10 9 8 7 6 5 4 3                 0
           1 1 1 0 1 0 0 0 1 1 0 0                     Rn           Rt      (1) (1) (1) (1) 0 1 0 1       Rd




        T1 variant

        STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>]


        Decode for this encoding

         d = UInt(Rd);    t = UInt(Rt);    n = UInt(Rn);
         if d == 15 || t == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
         if d == n || d == t then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STREXH on page J1-5375.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            Is the destination general-purpose register into which the status result of the store exclusive is
                        written, encoded in the "Rd" field. The value returned is:

                        0            If the operation updates memory.

                        1            If the operation fails to update memory.

        <Rt>            Is the general-purpose register to be transferred, encoded in the "Rt" field.
<Rn>            Is the general-purpose base register, encoded in the "Rn" field.


Aborts and alignment

If a synchronous Data Abort exception is generated by the execution of this instruction:

.      Memory is not updated.

.      <Rd> is not updated.

A non halfword-aligned memory address causes an Alignment fault Data Abort exception to be generated, subject
to the following rules:

.      If AArch32.ExclusiveMonitorsPass() returns TRUE, the exception is generated.

.      Otherwise, it is IMPLEMENTATION DEFINED whether the exception is generated.

If AArch32.ExclusiveMonitorsPass() returns FALSE and the memory address, if accessed, would generate a
synchronous Data Abort exception, it is IMPLEMENTATION DEFINED whether the exception is generated.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      address = R[n];
      if AArch32.ExclusiveMonitorsPass(address,2) then
           MemA[address,2] = R[t]<15:0>;
           R[d] = ZeroExtend(''0'');
      else
           R[d] = ZeroExtend(''1'');');
INSERT INTO "instructions" VALUES('ARM','STRHT','Store Register Halfword Unprivileged stores a halfword from a register to memory. For information about memory       (F7.1.235)
accesses see Memory accesses on page F2-2513.

The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
actually running in User mode.

STRHT is UNPREDICTABLE in Hyp mode.

The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
base register value and an immediate offset, and leaves the base register unchanged.

The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
memory access, and calculates a new address from a base register value and an offset and writes it back to the base
register. The offset can be an immediate value or a register value.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15        12 11          8 7 6 5 4 3            0
     !=1111     0 0 0 0 U 1 1 0              Rn           Rt         imm4H       1 0 1 1      imm4L
      cond


A1 variant

STRHT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   postindex = TRUE;   add = (U == ''1'');
 register_form = FALSE;     imm32 = ZeroExtend(imm4H:imm4L, 32);
 if t == 15 || n == 15 || n == t then UNPREDICTABLE;


A2


  31        28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3                0
     !=1111     0 0 0 0 U 0 1 0              Rn           Rt      (0) (0) (0) (0) 1 0 1 1      Rm
      cond


A2 variant

STRHT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   m = UInt(Rm);   postindex = TRUE;     add = (U == ''1'');
 register_form = TRUE;
 if t == 15 || n == 15 || n == t || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7                        0
  1 1 1 1 1 0 0 0 0 0 1 0                  !=1111         Rt       1 1 1 0              imm8
                                             Rn


T1 variant

STRHT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
        Decode for this encoding

         if Rn == ''1111'' then UNDEFINED;
         t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;    add = TRUE;
         register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STRHT on page J1-5370.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rt>           Is the general-purpose register to be transferred, encoded in the "Rt" field.

        <Rn>           Is the general-purpose base register, encoded in the "Rn" field.

        +/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
                       + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

                       For encoding A2: specifies the index register is added to or subtracted from the base register,
                       defaulting to + if omitted and encoded in the "U" field. It can have the following values:

                       -            when U = 0

                       +            when U = 1

        <Rm>           Is the general-purpose index register, encoded in the "Rm" field.

        +              Specifies the offset is added to the base register.

        <imm>          For encoding A1: is the optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm4H:imm4L" field.

                       For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm8" field.


        Operation for all encodings

         if ConditionPassed() then
             if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
             EncodingSpecificOperations();
             offset = if register_form then R[m] else imm32;
             offset_addr = if add then (R[n] + offset) else (R[n] - offset);
             address = if postindex then R[n] else offset_addr;
             MemU_unpriv[address,2] = R[t]<15:0>;
             if postindex then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','STRT','Store Register Unprivileged stores a word from a register to memory. For information about memory accesses see       (F7.1.236)
Memory accesses on page F2-2513.

The memory access is restricted as if the PE were running in User mode. This makes no difference if the PE is
actually running in User mode.

STRT is UNPREDICTABLE in Hyp mode.

The T32 instruction uses an offset addressing mode, that calculates the address used for the memory access from a
base register value and an immediate offset, and leaves the base register unchanged.

The A32 instruction uses a post-indexed addressing mode, that uses a base register value as the address for the
memory access, and calculates a new address from a base register value and an offset and writes it back to the base
register. The offset can be an immediate value or an optionally-shifted register value.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15       12 11                                  0
     !=1111     0 1 0 0 U 0 1 0              Rn           Rt                      imm12
      cond


A1 variant

STRT{<c>}{<q>} <Rt>, [<Rn>] {, #{+/-}<imm>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   postindex = TRUE;   add = (U == ''1'');
 register_form = FALSE;     imm32 = ZeroExtend(imm12, 32);
 if n == 15 || n == t then UNPREDICTABLE;


A2


  31        28 27 26 25 24 23 22 21 20 19         16 15       12 11             7 6 5 4 3            0
     !=1111     0 1 1 0 U 0 1 0              Rn           Rt            imm5       type 0      Rm
      cond


A2 variant

STRT{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>}


Decode for this encoding

 t = UInt(Rt);    n = UInt(Rn);   m = UInt(Rm);   postindex = TRUE;     add = (U == ''1'');
 register_form = TRUE;     (shift_t, shift_n) = DecodeImmShift(type, imm5);
 if n == 15 || n == t || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15        12 11 10 9 8 7                         0
  1 1 1 1 1 0 0 0 0 1 0 0                  !=1111         Rt      1 1 1 0               imm8
                                             Rn


T1 variant

STRT{<c>}{<q>} <Rt>, [<Rn> {, #{+}<imm>}]
        Decode for this encoding

         if Rn == ''1111'' then UNDEFINED;
         t = UInt(Rt);  n = UInt(Rn);     postindex = FALSE;    add = TRUE;
         register_form = FALSE;   imm32 = ZeroExtend(imm8, 32);
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly STRT on page J1-5371.


        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rt>           For the offset variant: is the general-purpose register to be transferred, encoded in the "Rt" field.

                       For the post-indexed variant: is the general-purpose register to be transferred, encoded in the "Rt"
                       field. The PC can be used, but this is deprecated.

        <Rn>           For encoding A1: is the general-purpose base register, encoded in the "Rn" field. The SP can be
                       used.

                       For encoding A2 and T1: is the general-purpose base register, encoded in the "Rn" field.

        +/-            For encoding A1: specifies the offset is added to or subtracted from the base register, defaulting to
                       + if omitted and encoded in the "U" field. It can have the following values:
                       -            when U = 0
                       +            when U = 1

                       For encoding A2: specifies the index register is added to or subtracted from the base register,
                       defaulting to + if omitted and encoded in the "U" field. It can have the following values:
                       -            when U = 0
                       +            when U = 1

        <Rm>           Is the general-purpose index register, encoded in the "Rm" field.

        <shift>        The shift to apply to the value read from <Rm>. If absent, no shift is applied. Otherwise, see Shifts
                       applied to a register on page F2-2510.

        +              Specifies the offset is added to the base register.

        <imm>          For encoding A1: is the optional 12-bit unsigned immediate byte offset, in the range 0 to 4095,
                       defaulting to 0 and encoded in the "imm12" field.

                       For encoding T1: is an optional 8-bit unsigned immediate byte offset, in the range 0 to 255,
                       defaulting to 0 and encoded in the "imm8" field.


        Operation for all encodings

         if ConditionPassed() then
             if PSTATE.EL == EL2 then UNPREDICTABLE;                      // Hyp mode
             EncodingSpecificOperations();
             offset = if register_form then Shift(R[m], shift_t, shift_n, PSTATE.C) else imm32;
             offset_addr = if add then (R[n] + offset) else (R[n] - offset);
             address = if postindex then R[n] else offset_addr;
             if t == 15 then   // Only possible for encodings A1 and A2
                 data = PCStoreValue();
             else
                 data = R[t];
             MemU_unpriv[address,4] = data;
             if postindex then R[n] = offset_addr;');
INSERT INTO "instructions" VALUES('ARM','SXTAB','        Signed Extend and Add Byte extracts an 8-bit value from a register, sign-extends it to 32 bits, adds the result to the       (F7.1.244)
        value in another register, and writes the final result to the destination register. The instruction can specify a rotation
        by 0, 8, 16, or 24 bits before extracting the 8-bit value.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15          12 11 10 9 8 7 6 5 4 3                  0
             !=1111     0 1 1 0 1 0 1 0              !=1111           Rd      rotate (0) (0) 0 1 1 1         Rm
              cond                                     Rn


        A1 variant

        SXTAB{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


        Decode for this encoding

         if Rn == ''1111'' then SEE SXTB;
         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);     rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3              0
           1 1 1 1 1 0 1 0 0 1 0 0                   !=1111       1 1 1 1          Rd        1 (0) rotate    Rm
                                                       Rn


        T1 variant

        SXTAB{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


        Decode for this encoding

         if Rn == ''1111'' then SEE SXTB;
         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);     rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

        <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

        <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.

        <amount>        Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                        (omitted)    when rotate = 00

                        8            when rotate = 01
              16         when rotate = 10

              24         when rotate = 11


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    rotated = ROR(R[m], rotation);
    R[d] = R[n] + SignExtend(rotated<7:0>, 32);');
INSERT INTO "instructions" VALUES('ARM','SXTAB16','        Signed Extend and Add Byte 16 extracts two 8-bit values from a register, sign-extends them to 16 bits each, adds       (F7.1.245)
        the results to two 16-bit values from another register, and writes the final results to the destination register. The
        instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit values.


        A1


          31         28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                   0
             !=1111     0 1 1 0 1 0 0 0              !=1111         Rd      rotate (0) (0) 0 1 1 1          Rm
              cond                                    Rn


        A1 variant

        SXTAB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


        Decode for this encoding

         if Rn == ''1111'' then SEE SXTB16;
         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11            8 7 6 5 4 3               0
           1 1 1 1 1 0 1 0 0 0 1 0                   !=1111     1 1 1 1          Rd       1 (0) rotate      Rm
                                                      Rn


        T1 variant

        SXTAB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


        Decode for this encoding

         if Rn == ''1111'' then SEE SXTB16;
         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

        <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

        <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.

        <amount>        Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                        (omitted)    when rotate = 00

                        8            when rotate = 01
              16         when rotate = 10

              24         when rotate = 11


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    rotated = ROR(R[m], rotation);
    R[d]<15:0>  = R[n]<15:0> + SignExtend(rotated<7:0>, 16);
    R[d]<31:16> = R[n]<31:16> + SignExtend(rotated<23:16>, 16);');
INSERT INTO "instructions" VALUES('ARM','SXTAH','        Signed Extend and Add Halfword extracts a 16-bit value from a register, sign-extends it to 32 bits, adds the result       (F7.1.246)
        to a value from another register, and writes the final result to the destination register. The instruction can specify a
        rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.


        A1


          31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                  0
             !=1111     0 1 1 0 1 0 1 1              !=1111         Rd       rotate (0) (0) 0 1 1 1         Rm
              cond                                     Rn


        A1 variant

        SXTAH{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


        Decode for this encoding

         if Rn == ''1111'' then SEE SXTH;
         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11            8 7 6 5 4 3              0
           1 1 1 1 1 0 1 0 0 0 0 0                   !=1111     1 1 1 1           Rd       1 (0) rotate     Rm
                                                       Rn


        T1 variant

        SXTAH{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


        Decode for this encoding

         if Rn == ''1111'' then SEE SXTH;
         d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>             See Standard assembler syntax fields on page F2-2506.

        <q>             See Standard assembler syntax fields on page F2-2506.

        <Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

        <Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

        <Rm>            Is the second general-purpose source register, encoded in the "Rm" field.

        <amount>        Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                        (omitted)    when rotate = 00

                        8            when rotate = 01
              16         when rotate = 10

              24         when rotate = 11


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    rotated = ROR(R[m], rotation);
    R[d] = R[n] + SignExtend(rotated<15:0>, 32);');
INSERT INTO "instructions" VALUES('ARM','SXTB16','        Signed Extend Byte 16 extracts two 8-bit values from a register, sign-extends them to 16 bits each, and writes the       (F7.1.248)
        results to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the
        8-bit values.


        A1


          31         28 27 26 25 24 23 22 21 20 19 18 17 16 15           12 11 10 9 8 7 6 5 4 3                    0
             !=1111     0 1 1 0 1 0 0 0 1 1 1 1                     Rd       rotate (0) (0) 0 1 1 1          Rm
              cond


        A1 variant

        SXTB16{<c>}{<q>} {<Rd>,} <Rm> {, ROR #<amount>}


        Decode for this encoding

         d = UInt(Rd);    m = UInt(Rm);      rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE;


        T1


          15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11                           8 7 6 5 4 3               0
           1 1 1 1 1 0 1 0 0 0 1 0 1 1 1 1 1 1 1 1                                Rd       1 (0) rotate      Rm




        T1 variant

        SXTB16{<c>}{<q>} {<Rd>,} <Rm> {, ROR #<amount>}


        Decode for this encoding

         d = UInt(Rd);    m = UInt(Rm);      rotation = UInt(rotate:''000'');
         if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>              See Standard assembler syntax fields on page F2-2506.

        <q>              See Standard assembler syntax fields on page F2-2506.

        <Rd>             Is the general-purpose destination register, encoded in the "Rd" field.

        <Rm>             Is the general-purpose source register, encoded in the "Rm" field.

        <amount>         Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                         (omitted)    when rotate = 00

                         8            when rotate = 01

                         16           when rotate = 10

                         24           when rotate = 11
Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    rotated = ROR(R[m], rotation);
    R[d]<15:0>  = SignExtend(rotated<7:0>, 16);
    R[d]<31:16> = SignExtend(rotated<23:16>, 16);');
INSERT INTO "instructions" VALUES('ARM','TBB','Table Branch Byte or Halfword causes a PC-relative forward branch using a table of single byte or halfword offsets.       (F7.1.250)
A base register provides a pointer to the table, and a second register supplies an index into the table. The branch
length is twice the value returned from the table.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11 10 9 8 7 6 5 4 3                     0
   1 1 1 0 1 0 0 0 1 1 0 1                    Rn      (1) (1) (1) (1) (0) (0) (0) (0) 0 0 0 H      Rm




Byte variant

Applies when H = 0.

TBB{<c>}{<q>} [<Rn>, <Rm>]// Outside or last in IT block


Halfword variant

Applies when H = 1.

TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1]// Outside or last in IT block


Decode for all variants of this encoding

 n = UInt(Rn);    m = UInt(Rm);   is_tbh = (H == ''1'');
 if m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
 if InITBlock() && !LastInITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rn>            Is the general-purpose base register holding the address of the table of branch lengths, encoded in
                the "Rn" field. The PC can be used. If it is, the table immediately follows this instruction.

<Rm>            For the byte variant: is the general-purpose index register, encoded in the "Rm" field. This register
                contains an integer pointing to a single byte in the table. The offset in the table is the value of the
                index.

                For the halfword variant: is the general-purpose index register, encoded in the "Rm" field. This
                register contains an integer pointing to a halfword in the table. The offset in the table is twice the
                value of the index.


Operation

 if ConditionPassed() then
     EncodingSpecificOperations();
     if is_tbh then
          halfwords = UInt(MemU[R[n]+LSL(R[m],1), 2]);
     else
          halfwords = UInt(MemU[R[n]+R[m], 1]);
     BranchWritePC(PC + 2*halfwords);');
INSERT INTO "instructions" VALUES('ARM','TBH','-R:TBB');
INSERT INTO "instructions" VALUES('ARM','TEQ','Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an immediate       (F7.1.251)
value. It updates the condition flags based on the result, and discards the result.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15 14 13 12 11                                  0
     !=1111    0 0 1 1 0 0 1 1               Rn       (0) (0) (0) (0)              imm12
      cond


A1 variant

TEQ{<c>}{<q>} <Rn>, #<const>


Decode for this encoding

 n = UInt(Rn);
 (imm32, carry) = A32ExpandImm_C(imm12, PSTATE.C);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14        12 11 10 9 8 7                      0
  1 1 1 1 0        i  0 0 1 0 0 1            Rn        0    imm3     1 1 1 1            imm8




T1 variant

TEQ{<c>}{<q>} <Rn>, #<const>


Decode for this encoding

 n = UInt(Rn);
 (imm32, carry) = T32ExpandImm_C(i:imm3:imm8, PSTATE.C);
 if n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rn>            For encoding A1: is the general-purpose source register, encoded in the "Rn" field. The PC can be
                used.

                For encoding T1: is the general-purpose source register, encoded in the "Rn" field.

<const>         For encoding A1: an immediate value. See Modified immediate constants in A32 instructions on
                page F4-2559 for the range of values.

                For encoding T1: an immediate value. See Modified immediate constants in T32 instructions on
                page F3-2530 for the range of values.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             result = R[n] EOR imm32;
             PSTATE.N = result<31>;
             PSTATE.Z = IsZeroBit(result);
             PSTATE.C = carry;
             // PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','UADD16','Unsigned Add 16 performs two 16-bit unsigned integer additions, and writes the results to the destination register.       (F7.1.257)
It sets PSTATE.GE according to the results of the additions.


A1


   31       28 27 26 25 24 23 22 21 20 19        16 15         12 11 10 9 8 7 6 5 4 3                0
      !=1111   0 1 1 0 0 1 0 1               Rn           Rd      (1) (1) (1) (1) 0 0 0 1      Rm
       cond


A1 variant

UADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


   15 14 13 12 11 10 9 8 7 6 5 4 3                0 15 14 13 12 11             8 7 6 5 4 3            0
   1 1 1 1 1 0 1 0 1 0 0 1                   Rn       1 1 1 1          Rd        0 1 0 0       Rm




T1 variant

UADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
      EncodingSpecificOperations();
      sum1 = UInt(R[n]<15:0>) + UInt(R[m]<15:0>);
      sum2 = UInt(R[n]<31:16>) + UInt(R[m]<31:16>);
      R[d]<15:0>  = sum1<15:0>;
             R[d]<31:16> = sum2<15:0>;
             PSTATE.GE<1:0> = if sum1 >= 0x10000 then ''11'' else ''00'';
             PSTATE.GE<3:2> = if sum2 >= 0x10000 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','UADD8','Unsigned Add 8 performs four unsigned 8-bit integer additions, and writes the results to the destination register. It       (F7.1.258)
sets PSTATE.GE according to the results of the additions.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                 0
     !=1111   0 1 1 0 0 1 0 1                Rn           Rd      (1) (1) (1) (1) 1 0 0 1      Rm
      cond


A1 variant

UADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3            0
   1 1 1 1 1 0 1 0 1 0 0 0                   Rn       1 1 1 1          Rd        0 1 0 0       Rm




T1 variant

UADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);  n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m     == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum1 = UInt(R[n]<7:0>) + UInt(R[m]<7:0>);
     sum2 = UInt(R[n]<15:8>) + UInt(R[m]<15:8>);
     sum3 = UInt(R[n]<23:16>) + UInt(R[m]<23:16>);
             sum4 = UInt(R[n]<31:24>) + UInt(R[m]<31:24>);
             R[d]<7:0>   = sum1<7:0>;
             R[d]<15:8>  = sum2<7:0>;
             R[d]<23:16> = sum3<7:0>;
             R[d]<31:24> = sum4<7:0>;
             PSTATE.GE<0>   = if sum1 >= 0x100 then ''1'' else ''0'';
             PSTATE.GE<1>   = if sum2 >= 0x100 then ''1'' else ''0'';
             PSTATE.GE<2>   = if sum3 >= 0x100 then ''1'' else ''0'';
             PSTATE.GE<3>   = if sum4 >= 0x100 then ''1'' else ''0'';');
INSERT INTO "instructions" VALUES('ARM','UASX','Unsigned Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one       (F7.1.259)
unsigned 16-bit integer addition and one unsigned 16-bit subtraction, and writes the results to the destination
register. It sets PSTATE.GE according to the results.


A1


  31         28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111       0 1 1 0 0 1 0 1               Rn           Rd      (1) (1) (1) (1) 0 0 1 1      Rm
      cond


A1 variant

UASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 0 1 0                       Rn       1 1 1 1          Rd        0 1 0 0       Rm




T1 variant

UASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>               See Standard assembler syntax fields on page F2-2506.

<q>               See Standard assembler syntax fields on page F2-2506.

<Rd>              Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>              Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>              Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff = UInt(R[n]<15:0>) - UInt(R[m]<31:16>);
     sum     = UInt(R[n]<31:16>) + UInt(R[m]<15:0>);
             R[d]<15:0>  = diff<15:0>;
             R[d]<31:16> = sum<15:0>;
             PSTATE.GE<1:0> = if diff >= 0 then ''11'' else ''00'';
             PSTATE.GE<3:2> = if sum    >= 0x10000 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','UDF','Permanently Undefined generates an Undefined Instruction exception.       (F7.1.261)

The encodings for UDF used in this section are defined as permanently UNDEFINED in the ARMv8-A architecture.
However:

.     With the T32 instruction set, ARM deprecates using the UDF instruction in an IT block.

.     In the A32 instruction set, UDF is not conditional.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19                                     8 7 6 5 4 3              0
  1 1 1 0 0 1 1 1 1 1 1 1                                imm12                  1 1 1 1        imm4




A1 variant

UDF{<c>}{<q>} {#}<imm>


Decode for this encoding

 imm32 = ZeroExtend(imm12:imm4, 32);
 // imm32 is for assembly and disassembly only, and is ignored by hardware.


T1


  15 14 13 12 11 10 9 8 7                          0
  1 1 0 1 1 1 1 0                    imm8




T1 variant

UDF{<c>}{<q>} {#}<imm>


Decode for this encoding

 imm32 = ZeroExtend(imm8, 32);
 // imm32 is for assembly and disassembly only, and is ignored by hardware.


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11                                   0
  1 1 1 1 0 1 1 1 1 1 1 1                   imm4      1 0 1 0                     imm12




T2 variant

UDF{<c>}.W {#}<imm>// <imm> can be represented in T1
UDF{<c>}{<q>} {#}<imm>


Decode for this encoding

 imm32 = ZeroExtend(imm4:imm12, 32);
 // imm32 is for assembly and disassembly only, and is ignored by hardware.
        Assembler symbols

        <c>            For encoding A1: see Standard assembler syntax fields on page F2-2506. <c> must be AL or omitted.

                       For encoding T1 and T2: see Standard assembler syntax fields on page F2-2506. ARM deprecates
                       using any <c> value other than AL.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <imm>          For encoding A1: is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the
                       "imm12:imm4" field. The PE ignores the value of this constant.

                       For encoding T1: is a 8-bit unsigned immediate, in the range 0 to 255, encoded in the "imm8" field.
                       The PE ignores the value of this constant.

                       For encoding T2: is a 16-bit unsigned immediate, in the range 0 to 65535, encoded in the
                       "imm4:imm12" field. The PE ignores the value of this constant.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             UNDEFINED;');
INSERT INTO "instructions" VALUES('ARM','UHADD16','Unsigned Halving Add 16 performs two unsigned 16-bit integer additions, halves the results, and writes the results       (F7.1.263)
to the destination register.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111     0 1 1 0 0 1 1 1               Rn           Rd      (1) (1) (1) (1) 0 0 0 1      Rm
      cond


A1 variant

UHADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3            0
   1 1 1 1 1 0 1 0 1 0 0 1                    Rn       1 1 1 1          Rd        0 1 1 0       Rm




T1 variant

UHADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum1 = UInt(R[n]<15:0>) + UInt(R[m]<15:0>);
             sum2 = UInt(R[n]<31:16>) + UInt(R[m]<31:16>);
             R[d]<15:0>  = sum1<16:1>;
             R[d]<31:16> = sum2<16:1>;');
INSERT INTO "instructions" VALUES('ARM','UHADD8','Unsigned Halving Add 8 performs four unsigned 8-bit integer additions, halves the results, and writes the results to       (F7.1.264)
the destination register.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111     0 1 1 0 0 1 1 1               Rn           Rd      (1) (1) (1) (1) 1 0 0 1      Rm
      cond


A1 variant

UHADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 0 0 0                     Rn       1 1 1 1          Rd        0 1 1 0       Rm




T1 variant

UHADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum1 = UInt(R[n]<7:0>) + UInt(R[m]<7:0>);
     sum2 = UInt(R[n]<15:8>) + UInt(R[m]<15:8>);
     sum3 = UInt(R[n]<23:16>) + UInt(R[m]<23:16>);
             sum4 = UInt(R[n]<31:24>) + UInt(R[m]<31:24>);
             R[d]<7:0>   = sum1<8:1>;
             R[d]<15:8>  = sum2<8:1>;
             R[d]<23:16> = sum3<8:1>;
             R[d]<31:24> = sum4<8:1>;');
INSERT INTO "instructions" VALUES('ARM','UHASX','Unsigned Halving Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs       (F7.1.265)
one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, halves the results, and writes the results
to the destination register.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111     0 1 1 0 0 1 1 1               Rn           Rd      (1) (1) (1) (1) 0 0 1 1      Rm
      cond


A1 variant

UHASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3            0
   1 1 1 1 1 0 1 0 1 0 1 0                    Rn       1 1 1 1          Rd        0 1 1 0       Rm




T1 variant

UHASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff = UInt(R[n]<15:0>) - UInt(R[m]<31:16>);
             sum  = UInt(R[n]<31:16>) + UInt(R[m]<15:0>);
             R[d]<15:0>  = diff<16:1>;
             R[d]<31:16> = sum<16:1>;');
INSERT INTO "instructions" VALUES('ARM','UHSAX','Unsigned Halving Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs       (F7.1.266)
one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, halves the results, and writes the results
to the destination register.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111     0 1 1 0 0 1 1 1               Rn           Rd      (1) (1) (1) (1) 0 1 0 1      Rm
      cond


A1 variant

UHSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3            0
   1 1 1 1 1 0 1 0 1 1 1 0                    Rn       1 1 1 1          Rd        0 1 1 0       Rm




T1 variant

UHSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum   = UInt(R[n]<15:0>) + UInt(R[m]<31:16>);
             diff = UInt(R[n]<31:16>) - UInt(R[m]<15:0>);
             R[d]<15:0>  = sum<16:1>;
             R[d]<31:16> = diff<16:1>;');
INSERT INTO "instructions" VALUES('ARM','UHSUB16','Unsigned Halving Subtract 16 performs two unsigned 16-bit integer subtractions, halves the results, and writes the       (F7.1.267)
results to the destination register.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111     0 1 1 0 0 1 1 1                Rn           Rd      (1) (1) (1) (1) 0 1 1 1      Rm
      cond


A1 variant

UHSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 1 0 1                      Rn       1 1 1 1          Rd        0 1 1 0       Rm




T1 variant

UHSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>              See Standard assembler syntax fields on page F2-2506.

<q>              See Standard assembler syntax fields on page F2-2506.

<Rd>             Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>             Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>             Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff1 = UInt(R[n]<15:0>) - UInt(R[m]<15:0>);
             diff2 = UInt(R[n]<31:16>) - UInt(R[m]<31:16>);
             R[d]<15:0>  = diff1<16:1>;
             R[d]<31:16> = diff2<16:1>;');
INSERT INTO "instructions" VALUES('ARM','UHSUB8','Unsigned Halving Subtract 8 performs four unsigned 8-bit integer subtractions, halves the results, and writes the       (F7.1.268)
results to the destination register.


A1


  31        28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111     0 1 1 0 0 1 1 1                Rn           Rd      (1) (1) (1) (1) 1 1 1 1      Rm
      cond


A1 variant

UHSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 1 0 0                      Rn       1 1 1 1          Rd        0 1 1 0       Rm




T1 variant

UHSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);    n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>              See Standard assembler syntax fields on page F2-2506.

<q>              See Standard assembler syntax fields on page F2-2506.

<Rd>             Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>             Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>             Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff1 = UInt(R[n]<7:0>) - UInt(R[m]<7:0>);
     diff2 = UInt(R[n]<15:8>) - UInt(R[m]<15:8>);
     diff3 = UInt(R[n]<23:16>) - UInt(R[m]<23:16>);
             diff4 = UInt(R[n]<31:24>) - UInt(R[m]<31:24>);
             R[d]<7:0>   = diff1<8:1>;
             R[d]<15:8>  = diff2<8:1>;
             R[d]<23:16> = diff3<8:1>;
             R[d]<31:24> = diff4<8:1>;');
INSERT INTO "instructions" VALUES('ARM','UMAAL','Unsigned Multiply Accumulate Accumulate Long multiplies two unsigned 32-bit values to produce a 64-bit value,       (F7.1.269)
adds two unsigned 32-bit values, and writes the 64-bit result to two registers.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15         12 11         8 7 6 5 4 3              0
     !=1111   0 0 0 0 0 1 0 0               RdHi         RdLo           Rm      1 0 0 1         Rn
      cond


A1 variant

UMAAL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Decode for this encoding

 dLo = UInt(RdLo);   dHi = UInt(RdHi);     n = UInt(Rn);   m = UInt(Rm);
 if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 if dHi == dLo then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11         8 7 6 5 4 3               0
  1 1 1 1 1 0 1 1 1 1 1 0                    Rn          RdLo          RdHi     0 1 1 0         Rm




T1 variant

UMAAL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Decode for this encoding

 dLo = UInt(RdLo);   dHi = UInt(RdHi);     n = UInt(Rn);   m = UInt(Rm);
 if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13
 if dHi == dLo then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly UMAAL on page J1-5358.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<RdLo>         Is the general-purpose source register holding the first addend and the destination register for the
               lower 32 bits of the result, encoded in the "RdLo" field.

<RdHi>         Is the general-purpose source register holding the second addend and the destination register for the
               upper 32 bits of the result, encoded in the "RdHi" field.

<Rn>           Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             result = UInt(R[n]) * UInt(R[m]) + UInt(R[dHi]) + UInt(R[dLo]);
             R[dHi] = result<63:32>;
             R[dLo] = result<31:0>;');
INSERT INTO "instructions" VALUES('ARM','UMLALS','Unsigned Multiply Accumulate Long multiplies two unsigned 32-bit values to produce a 64-bit value, and       (F7.1.270)
accumulates this with a 64-bit value.

In A32 instructions, the condition flags can optionally be updated based on the result. Use of this option adversely
affects performance on many implementations.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15       12 11          8 7 6 5 4 3               0
     !=1111    0 0 0 0 1 0 1 S              RdHi         RdLo           Rm      1 0 0 1          Rn
      cond


Flag setting variant

Applies when S = 1.

UMLALS{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Not flag setting variant

Applies when S = 0.

UMLAL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Decode for all variants of this encoding

 dLo = UInt(RdLo);    dHi = UInt(RdHi);    n = UInt(Rn);   m = UInt(Rm);     setflags = (S == ''1'');
 if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 if dHi == dLo then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11          8 7 6 5 4 3               0
   1 1 1 1 1 0 1 1 1 1 1 0                   Rn          RdLo          RdHi     0 0 0 0         Rm




T1 variant

UMLAL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Decode for this encoding

 dLo = UInt(RdLo);    dHi = UInt(RdHi);    n = UInt(Rn);   m = UInt(Rm);     setflags = FALSE;
 if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13
 if dHi == dLo then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly UMLAL on page J1-5359.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.
        <RdLo>         Is the general-purpose source register holding the lower 32 bits of the addend, and the destination
                       register for the lower 32 bits of the result, encoded in the "RdLo" field.

        <RdHi>         Is the general-purpose source register holding the upper 32 bits of the addend, and the destination
                       register for the upper 32 bits of the result, encoded in the "RdHi" field.

        <Rn>           Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

        <Rm>           Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             result = UInt(R[n]) * UInt(R[m]) + UInt(R[dHi]:R[dLo]);
             R[dHi] = result<63:32>;
             R[dLo] = result<31:0>;
             if setflags then
                 PSTATE.N = result<63>;
                 PSTATE.Z = IsZeroBit(result<63:0>);
                 // PSTATE.C, PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','UMULLS','Unsigned Multiply Long multiplies two 32-bit unsigned values to produce a 64-bit result.       (F7.1.271)

In A32 instructions, the condition flags can optionally be updated based on the result. Use of this option adversely
affects performance on many implementations.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15       12 11          8 7 6 5 4 3               0
     !=1111    0 0 0 0 1 0 0 S              RdHi         RdLo           Rm      1 0 0 1          Rn
      cond


Flag setting variant

Applies when S = 1.

UMULLS{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Not flag setting variant

Applies when S = 0.

UMULL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Decode for all variants of this encoding

 dLo = UInt(RdLo);    dHi = UInt(RdHi);    n = UInt(Rn);   m = UInt(Rm);     setflags = (S == ''1'');
 if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 if dHi == dLo then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11          8 7 6 5 4 3               0
   1 1 1 1 1 0 1 1 1 0 1 0                   Rn          RdLo          RdHi     0 0 0 0         Rm




T1 variant

UMULL{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm>


Decode for this encoding

 dLo = UInt(RdLo);    dHi = UInt(RdHi);    n = UInt(Rn);   m = UInt(Rm);     setflags = FALSE;
 if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE;
 // ARMv8-A removes UNPREDICTABLE for R13
 if dHi == dLo then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly UMULL on page J1-5358.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.
        <RdLo>         Is the general-purpose destination register for the lower 32 bits of the result, encoded in the "RdLo"
                       field.

        <RdHi>         Is the general-purpose destination register for the upper 32 bits of the result, encoded in the "RdHi"
                       field.

        <Rn>           Is the first general-purpose source register holding the multiplicand, encoded in the "Rn" field.

        <Rm>           Is the second general-purpose source register holding the multiplier, encoded in the "Rm" field.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             result = UInt(R[n]) * UInt(R[m]);
             R[dHi] = result<63:32>;
             R[dLo] = result<31:0>;
             if setflags then
                 PSTATE.N = result<63>;
                 PSTATE.Z = IsZeroBit(result<63:0>);
                 // PSTATE.C, PSTATE.V unchanged');
INSERT INTO "instructions" VALUES('ARM','UQADD16','Unsigned Saturating Add 16 performs two unsigned 16-bit integer additions, saturates the results to the 16-bit       (F7.1.272)
unsigned integer range 0 <= x <= 216 - 1, and writes the results to the destination register.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111   0 1 1 0 0 1 1 0                Rn           Rd      (1) (1) (1) (1) 0 0 0 1      Rm
      cond


A1 variant

UQADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 0 0 1                    Rn       1 1 1 1           Rd       0 1 0 1       Rm




T1 variant

UQADD16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum1 = UInt(R[n]<15:0>) + UInt(R[m]<15:0>);
             sum2 = UInt(R[n]<31:16>) + UInt(R[m]<31:16>);
             R[d]<15:0>  = UnsignedSat(sum1, 16);
             R[d]<31:16> = UnsignedSat(sum2, 16);');
INSERT INTO "instructions" VALUES('ARM','UQADD8','Unsigned Saturating Add 8 performs four unsigned 8-bit integer additions, saturates the results to the 8-bit unsigned       (F7.1.273)
integer range 0 <= x <= 28 - 1, and writes the results to the destination register.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                 0
     !=1111    0 1 1 0 0 1 1 0                Rn           Rd      (1) (1) (1) (1) 1 0 0 1       Rm
      cond


A1 variant

UQADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11             8 7 6 5 4 3            0
   1 1 1 1 1 0 1 0 1 0 0 0                    Rn       1 1 1 1          Rd        0 1 0 1        Rm




T1 variant

UQADD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum1 = UInt(R[n]<7:0>) + UInt(R[m]<7:0>);
     sum2 = UInt(R[n]<15:8>) + UInt(R[m]<15:8>);
     sum3 = UInt(R[n]<23:16>) + UInt(R[m]<23:16>);
             sum4 = UInt(R[n]<31:24>) + UInt(R[m]<31:24>);
             R[d]<7:0>   = UnsignedSat(sum1, 8);
             R[d]<15:8>  = UnsignedSat(sum2, 8);
             R[d]<23:16> = UnsignedSat(sum3, 8);
             R[d]<31:24> = UnsignedSat(sum4, 8);');
INSERT INTO "instructions" VALUES('ARM','UQASX','Unsigned Saturating Add and Subtract with Exchange exchanges the two halfwords of the second operand,       (F7.1.274)
performs one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, saturates the results to the 16-bit
unsigned integer range 0 <= x <= 216 - 1, and writes the results to the destination register.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                  0
     !=1111   0 1 1 0 0 1 1 0                Rn           Rd      (1) (1) (1) (1) 0 0 1 1       Rm
      cond


A1 variant

UQASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3             0
  1 1 1 1 1 0 1 0 1 0 1 0                    Rn       1 1 1 1           Rd       0 1 0 1        Rm




T1 variant

UQASX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff = UInt(R[n]<15:0>) - UInt(R[m]<31:16>);
             sum  = UInt(R[n]<31:16>) + UInt(R[m]<15:0>);
             R[d]<15:0>  = UnsignedSat(diff, 16);
             R[d]<31:16> = UnsignedSat(sum, 16);');
INSERT INTO "instructions" VALUES('ARM','UQSAX','Unsigned Saturating Subtract and Add with Exchange exchanges the two halfwords of the second operand,       (F7.1.275)
performs one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturates the results to the 16-bit
unsigned integer range 0 <= x <= 216 - 1, and writes the results to the destination register.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                  0
     !=1111   0 1 1 0 0 1 1 0                Rn           Rd      (1) (1) (1) (1) 0 1 0 1       Rm
      cond


A1 variant

UQSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3             0
  1 1 1 1 1 0 1 0 1 1 1 0                    Rn       1 1 1 1           Rd       0 1 0 1        Rm




T1 variant

UQSAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum  = UInt(R[n]<15:0>) + UInt(R[m]<31:16>);
             diff = UInt(R[n]<31:16>) - UInt(R[m]<15:0>);
             R[d]<15:0>  = UnsignedSat(sum, 16);
             R[d]<31:16> = UnsignedSat(diff, 16);');
INSERT INTO "instructions" VALUES('ARM','UQSUB16','Unsigned Saturating Subtract 16 performs two unsigned 16-bit integer subtractions, saturates the results to the       (F7.1.276)
16-bit unsigned integer range 0 <= x <= 216 - 1, and writes the results to the destination register.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                0
     !=1111   0 1 1 0 0 1 1 0                Rn           Rd      (1) (1) (1) (1) 0 1 1 1         Rm
      cond


A1 variant

UQSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 1 0 1                    Rn       1 1 1 1          Rd        0 1 0 1          Rm




T1 variant

UQSUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff1 = UInt(R[n]<15:0>) - UInt(R[m]<15:0>);
             diff2 = UInt(R[n]<31:16>) - UInt(R[m]<31:16>);
             R[d]<15:0>  = UnsignedSat(diff1, 16);
             R[d]<31:16> = UnsignedSat(diff2, 16);');
INSERT INTO "instructions" VALUES('ARM','UQSUB8','Unsigned Saturating Subtract 8 performs four unsigned 8-bit integer subtractions, saturates the results to the 8-bit       (F7.1.277)
unsigned integer range 0 <= x <= 28 - 1, and writes the results to the destination register.


A1


  31       28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111   0 1 1 0 0 1 1 0                Rn           Rd      (1) (1) (1) (1) 1 1 1 1      Rm
      cond


A1 variant

UQSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 1 0 0                    Rn       1 1 1 1          Rd        0 1 0 1       Rm




T1 variant

UQSUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff1 = UInt(R[n]<7:0>) - UInt(R[m]<7:0>);
     diff2 = UInt(R[n]<15:8>) - UInt(R[m]<15:8>);
     diff3 = UInt(R[n]<23:16>) - UInt(R[m]<23:16>);
             diff4 = UInt(R[n]<31:24>) - UInt(R[m]<31:24>);
             R[d]<7:0>   = UnsignedSat(diff1, 8);
             R[d]<15:8>  = UnsignedSat(diff2, 8);
             R[d]<23:16> = UnsignedSat(diff3, 8);
             R[d]<31:24> = UnsignedSat(diff4, 8);');
INSERT INTO "instructions" VALUES('ARM','USAD8','Unsigned Sum of Absolute Differences performs four unsigned 8-bit subtractions, and adds the absolute values of       (F7.1.278)
the differences together.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15 14 13 12 11           8 7 6 5 4 3             0
     !=1111     0 1 1 1 1 0 0 0               Rd       1 1 1 1          Rm      0 0 0 1         Rn
      cond


A1 variant

USAD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15 14 13 12 11           8 7 6 5 4 3              0
  1 1 1 1 1 0 1 1 0 1 1 1                     Rn       1 1 1 1          Rd      0 0 0 0         Rm




T1 variant

USAD8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     absdiff1 = Abs(UInt(R[n]<7:0>)       - UInt(R[m]<7:0>));
     absdiff2 = Abs(UInt(R[n]<15:8>)      - UInt(R[m]<15:8>));
     absdiff3 = Abs(UInt(R[n]<23:16>) - UInt(R[m]<23:16>));
             absdiff4 = Abs(UInt(R[n]<31:24>) - UInt(R[m]<31:24>));
             result = absdiff1 + absdiff2 + absdiff3 + absdiff4;
             R[d] = result<31:0>;');
INSERT INTO "instructions" VALUES('ARM','USADA8','Unsigned Sum of Absolute Differences and Accumulate performs four unsigned 8-bit subtractions, and adds the       (F7.1.279)
absolute values of the differences to a 32-bit accumulate operand.


A1


  31       28 27 26 25 24 23 22 21 20 19          16 15        12 11          8 7 6 5 4 3              0
     !=1111    0 1 1 1 1 0 0 0                Rd        !=1111           Rm      0 0 0 1         Rn
      cond                                                Ra


A1 variant

USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


Decode for this encoding

 if Ra == ''1111'' then SEE USAD8;
 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);    a = UInt(Ra);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11          8 7 6 5 4 3               0
  1 1 1 1 1 0 1 1 0 1 1 1                     Rn        !=1111           Rd      0 0 0 0         Rm
                                                          Ra


T1 variant

USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra>


Decode for this encoding

 if Ra == ''1111'' then SEE USAD8;
 d = UInt(Rd);   n = UInt(Rn);    m = UInt(Rm);    a = UInt(Ra);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

<Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>           Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>           Is the second general-purpose source register, encoded in the "Rm" field.

<Ra>           Is the third general-purpose source register holding the addend, encoded in the "Ra" field.
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             absdiff1 = Abs(UInt(R[n]<7:0>)       - UInt(R[m]<7:0>));
             absdiff2 = Abs(UInt(R[n]<15:8>)      - UInt(R[m]<15:8>));
             absdiff3 = Abs(UInt(R[n]<23:16>) - UInt(R[m]<23:16>));
             absdiff4 = Abs(UInt(R[n]<31:24>) - UInt(R[m]<31:24>));
             result = UInt(R[a]) + absdiff1 + absdiff2 + absdiff3 + absdiff4;
             R[d] = result<31:0>;');
INSERT INTO "instructions" VALUES('ARM','USAT','Unsigned Saturate saturates an optionally-shifted signed value to a selected unsigned range.       (F7.1.280)

This instruction sets PSTATE.Q to 1 if the operation saturates.


A1


  31       28 27 26 25 24 23 22 21 20            16 15        12 11            7 6 5 4 3             0
     !=1111    0 1 1 0 1 1 1            sat_imm          Rd             imm5     sh 0 1        Rn
      cond


Arithmetic shift right variant

Applies when sh = 1.

USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount>


Logical shift left variant

Applies when sh = 0.

USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount>}


Decode for all variants of this encoding

 d = UInt(Rd);   n = UInt(Rn);  saturate_to = UInt(sat_imm);
 (shift_t, shift_n) = DecodeImmShift(sh:''0'', imm5);
 if d == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15 14     12 11         8 7 6 5 4                 0
  1 1 1 1 0 (0) 1 1 1 0 sh 0                Rn       0   imm3          Rd     imm2 (0)     sat_imm




Arithmetic shift right variant

Applies when sh = 1 && !(imm3 == 000 && imm2 == 00).

USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount>


Logical shift left variant

Applies when sh = 0.

USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount>}


Decode for all variants of this encoding

 if sh == ''1'' && (imm3:imm2) == ''00000'' then SEE USAT16;
 d = UInt(Rd);   n = UInt(Rn);  saturate_to = UInt(sat_imm);
 (shift_t, shift_n) = DecodeImmShift(sh:''0'', imm3:imm2);
 if d == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.
        Assembler symbols

        <c>            See Standard assembler syntax fields on page F2-2506.

        <q>            See Standard assembler syntax fields on page F2-2506.

        <Rd>           Is the general-purpose destination register, encoded in the "Rd" field.

        <imm>          Is the bit position for saturation, in the range 0 to 31, encoded in the "sat_imm" field.

        <Rn>           Is the general-purpose source register, encoded in the "Rn" field.

        <amount>       For encoding A1: is the optional shift amount, in the range 0 to 31, defaulting to 0 and encoded in
                       the "imm5" field.

                       For encoding A1: is the shift amount, in the range 1 to 32 encoded in the "imm5" field as <amount>
                       modulo 32.

                       For encoding T1: is the optional shift amount, in the range 0 to 31, defaulting to 0 and encoded in
                       the "imm3:imm2" field.

                       For encoding T1: is the shift amount, in the range 1 to 31 encoded in the "imm3:imm2" field as
                       <amount>.


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             operand = Shift(R[n], shift_t, shift_n, PSTATE.C);         // PSTATE.C ignored
             (result, sat) = UnsignedSatQ(SInt(operand), saturate_to);
             R[d] = ZeroExtend(result, 32);
             if sat then
                 PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','USAT16','Unsigned Saturate 16 saturates two signed 16-bit values to a selected unsigned range.       (F7.1.281)

This instruction sets PSTATE.Q to 1 if the operation saturates.


A1


  31       28 27 26 25 24 23 22 21 20 19             16 15       12 11 10 9 8 7 6 5 4 3                 0
     !=1111    0 1 1 0 1 1 1 0              sat_imm          Rd      (1) (1) (1) (1) 0 0 1 1       Rn
      cond


A1 variant

USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     saturate_to = UInt(sat_imm);
 if d == 15 || n == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 0 (0) 1 1 1 0 1 0                    Rn        0 0 0 0          Rd         0 0 (0) (0) sat_imm




T1 variant

USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn>


Decode for this encoding

 d = UInt(Rd);   n = UInt(Rn);     saturate_to = UInt(sat_imm);
 if d == 15 || n == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<imm>           Is the bit position for saturation, in the range 0 to 15, encoded in the "sat_imm" field.

<Rn>            Is the general-purpose source register, encoded in the "Rn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     (result1, sat1) = UnsignedSatQ(SInt(R[n]<15:0>), saturate_to);
     (result2, sat2) = UnsignedSatQ(SInt(R[n]<31:16>), saturate_to);
             R[d]<15:0> = ZeroExtend(result1, 16);
             R[d]<31:16> = ZeroExtend(result2, 16);
             if sat1 || sat2 then
                 PSTATE.Q = ''1'';');
INSERT INTO "instructions" VALUES('ARM','USAX','Unsigned Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one       (F7.1.282)
unsigned 16-bit integer subtraction and one unsigned 16-bit addition, and writes the results to the destination
register. It sets PSTATE.GE according to the results.


A1


  31         28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111       0 1 1 0 0 1 0 1               Rn           Rd      (1) (1) (1) (1) 0 1 0 1      Rm
      cond


A1 variant

USAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 1 1 0                       Rn       1 1 1 1          Rd        0 1 0 0       Rm




T1 variant

USAX{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>               See Standard assembler syntax fields on page F2-2506.

<q>               See Standard assembler syntax fields on page F2-2506.

<Rd>              Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>              Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>              Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     sum     = UInt(R[n]<15:0>) + UInt(R[m]<31:16>);
     diff = UInt(R[n]<31:16>) - UInt(R[m]<15:0>);
             R[d]<15:0>  = sum<15:0>;
             R[d]<31:16> = diff<15:0>;
             PSTATE.GE<1:0> = if sum    >= 0x10000 then ''11'' else ''00'';
             PSTATE.GE<3:2> = if diff >= 0 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','USUB16','Unsigned Subtract 16 performs two 16-bit unsigned integer subtractions, and writes the results to the destination       (F7.1.283)
register. It sets PSTATE.GE according to the results of the subtractions.


A1


  31         28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111       0 1 1 0 0 1 0 1               Rn           Rd      (1) (1) (1) (1) 0 1 1 1      Rm
      cond


A1 variant

USUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 1 0 1                       Rn       1 1 1 1          Rd        0 1 0 0       Rm




T1 variant

USUB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>               See Standard assembler syntax fields on page F2-2506.

<q>               See Standard assembler syntax fields on page F2-2506.

<Rd>              Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>              Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>              Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff1 = UInt(R[n]<15:0>) - UInt(R[m]<15:0>);
     diff2 = UInt(R[n]<31:16>) - UInt(R[m]<31:16>);
     R[d]<15:0>      = diff1<15:0>;
             R[d]<31:16> = diff2<15:0>;
             PSTATE.GE<1:0> = if diff1 >= 0 then ''11'' else ''00'';
             PSTATE.GE<3:2> = if diff2 >= 0 then ''11'' else ''00'';');
INSERT INTO "instructions" VALUES('ARM','USUB8','Unsigned Subtract 8 performs four 8-bit unsigned integer subtractions, and writes the results to the destination       (F7.1.284)
register. It sets PSTATE.GE according to the results of the subtractions.


A1


  31         28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                0
     !=1111       0 1 1 0 0 1 0 1               Rn           Rd      (1) (1) (1) (1) 1 1 1 1      Rm
      cond


A1 variant

USUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11             8 7 6 5 4 3            0
  1 1 1 1 1 0 1 0 1 1 0 0                       Rn       1 1 1 1          Rd        0 1 0 0       Rm




T1 variant

USUB8{<c>}{<q>} {<Rd>,} <Rn>, <Rm>


Decode for this encoding

 d = UInt(Rd);     n = UInt(Rn);     m = UInt(Rm);
 if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>               See Standard assembler syntax fields on page F2-2506.

<q>               See Standard assembler syntax fields on page F2-2506.

<Rd>              Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>              Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>              Is the second general-purpose source register, encoded in the "Rm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();
     diff1 = UInt(R[n]<7:0>) - UInt(R[m]<7:0>);
     diff2 = UInt(R[n]<15:8>) - UInt(R[m]<15:8>);
     diff3 = UInt(R[n]<23:16>) - UInt(R[m]<23:16>);
             diff4 = UInt(R[n]<31:24>) - UInt(R[m]<31:24>);
             R[d]<7:0>   = diff1<7:0>;
             R[d]<15:8>  = diff2<7:0>;
             R[d]<23:16> = diff3<7:0>;
             R[d]<31:24> = diff4<7:0>;
             PSTATE.GE<0>   = if diff1 >= 0 then ''1'' else ''0'';
             PSTATE.GE<1>   = if diff2 >= 0 then ''1'' else ''0'';
             PSTATE.GE<2>   = if diff3 >= 0 then ''1'' else ''0'';
             PSTATE.GE<3>   = if diff4 >= 0 then ''1'' else ''0'';');
INSERT INTO "instructions" VALUES('ARM','UXTAB','Unsigned Extend and Add Byte extracts an 8-bit value from a register, zero-extends it to 32 bits, adds the result to       (F7.1.285)
the value in another register, and writes the final result to the destination register. The instruction can specify a
rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value.


A1


  31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                  0
     !=1111     0 1 1 0 1 1 1 0              !=1111          Rd      rotate (0) (0) 0 1 1 1          Rm
      cond                                     Rn


A1 variant

UXTAB{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


Decode for this encoding

 if Rn == ''1111'' then SEE UXTB;
 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11            8 7 6 5 4 3              0
   1 1 1 1 1 0 1 0 0 1 0 1                   !=1111     1 1 1 1            Rd       1 (0) rotate     Rm
                                               Rn


T1 variant

UXTAB{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


Decode for this encoding

 if Rn == ''1111'' then SEE UXTB;
 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.

<amount>        Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                (omitted)    when rotate = 00

                8            when rotate = 01
                       16           when rotate = 10

                       24           when rotate = 11


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             rotated = ROR(R[m], rotation);
             R[d] = R[n] + ZeroExtend(rotated<7:0>, 32);');
INSERT INTO "instructions" VALUES('ARM','UXTAB16','Unsigned Extend and Add Byte 16 extracts two 8-bit values from a register, zero-extends them to 16 bits each, adds       (F7.1.286)
the results to two 16-bit values from another register, and writes the final results to the destination register. The
instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit values.


A1


  31         28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                   0
     !=1111     0 1 1 0 1 1 0 0              !=1111         Rd      rotate (0) (0) 0 1 1 1          Rm
      cond                                    Rn


A1 variant

UXTAB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


Decode for this encoding

 if Rn == ''1111'' then SEE UXTB16;
 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15 14 13 12 11            8 7 6 5 4 3               0
  1 1 1 1 1 0 1 0 0 0 1 1                    !=1111     1 1 1 1          Rd       1 (0) rotate      Rm
                                              Rn


T1 variant

UXTAB16{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


Decode for this encoding

 if Rn == ''1111'' then SEE UXTB16;
 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.

<amount>        Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                (omitted)    when rotate = 00

                8            when rotate = 01
                       16           when rotate = 10

                       24           when rotate = 11


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             rotated = ROR(R[m], rotation);
             R[d]<15:0>  = R[n]<15:0> + ZeroExtend(rotated<7:0>, 16);
             R[d]<31:16> = R[n]<31:16> + ZeroExtend(rotated<23:16>, 16);');
INSERT INTO "instructions" VALUES('ARM','UXTAH','Unsigned Extend and Add Halfword extracts a 16-bit value from a register, zero-extends it to 32 bits, adds the result       (F7.1.287)
to a value from another register, and writes the final result to the destination register. The instruction can specify a
rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value.


A1


  31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                  0
     !=1111     0 1 1 0 1 1 1 1              !=1111         Rd       rotate (0) (0) 0 1 1 1         Rm
      cond                                     Rn


A1 variant

UXTAH{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


Decode for this encoding

 if Rn == ''1111'' then SEE UXTH;
 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15 14 13 12 11            8 7 6 5 4 3              0
   1 1 1 1 1 0 1 0 0 0 0 1                   !=1111     1 1 1 1           Rd       1 (0) rotate     Rm
                                               Rn


T1 variant

UXTAH{<c>}{<q>} {<Rd>,} <Rn>, <Rm> {, ROR #<amount>}


Decode for this encoding

 if Rn == ''1111'' then SEE UXTH;
 d = UInt(Rd);    n = UInt(Rn);    m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506.

<q>             See Standard assembler syntax fields on page F2-2506.

<Rd>            Is the general-purpose destination register, encoded in the "Rd" field.

<Rn>            Is the first general-purpose source register, encoded in the "Rn" field.

<Rm>            Is the second general-purpose source register, encoded in the "Rm" field.

<amount>        Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                (omitted)    when rotate = 00

                8            when rotate = 01
                       16           when rotate = 10

                       24           when rotate = 11


        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             rotated = ROR(R[m], rotation);
             R[d] = R[n] + ZeroExtend(rotated<15:0>, 32);');
INSERT INTO "instructions" VALUES('ARM','UXTB16','Unsigned Extend Byte 16 extracts two 8-bit values from a register, zero-extends them to 16 bits each, and writes       (F7.1.289)
the results to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting
the 8-bit values.


A1


  31         28 27 26 25 24 23 22 21 20 19 18 17 16 15           12 11 10 9 8 7 6 5 4 3                    0
     !=1111      0 1 1 0 1 1 0 0 1 1 1 1                     Rd       rotate (0) (0) 0 1 1 1         Rm
      cond


A1 variant

UXTB16{<c>}{<q>} {<Rd>,} <Rm> {, ROR #<amount>}


Decode for this encoding

 d = UInt(Rd);     m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15 14 13 12 11                            8 7 6 5 4 3              0
  1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1                                  Rd       1 (0) rotate     Rm




T1 variant

UXTB16{<c>}{<q>} {<Rd>,} <Rm> {, ROR #<amount>}


Decode for this encoding

 d = UInt(Rd);     m = UInt(Rm);    rotation = UInt(rotate:''000'');
 if d == 15 || m == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>              See Standard assembler syntax fields on page F2-2506.

<q>              See Standard assembler syntax fields on page F2-2506.

<Rd>             Is the general-purpose destination register, encoded in the "Rd" field.

<Rm>             For encoding A1: is the general-purpose source register, encoded in the "Rm" field.

                 For encoding T1: is the second general-purpose source register, encoded in the "Rm" field.

<amount>         Is the rotate amount, encoded in the "rotate" field. It can have the following values:

                 (omitted)    when rotate = 00

                 8            when rotate = 01

                 16           when rotate = 10

                 24           when rotate = 11
        Operation for all encodings

         if ConditionPassed() then
             EncodingSpecificOperations();
             rotated = ROR(R[m], rotation);
             R[d]<15:0>  = ZeroExtend(rotated<7:0>, 16);
             R[d]<31:16> = ZeroExtend(rotated<23:16>, 16);');
INSERT INTO "instructions" VALUES('ARM','FLDMDBX','        FLDMDBX loads multiple registers from consecutive locations in the Advanced SIMD and floating-point register       (F8.1.5)
        file using an address from a general-purpose register. ARM deprecates use of FLDMDBX, except for disassembly
        purposes, and reassembly of disassembled code.

        This instruction is an alias of the VLDM, VLDMDB, VLDMIA instruction. This means that:

        .       The encodings in this description are named to match the encodings of VLDM, VLDMDB, VLDMIA.

        .       The description of VLDM, VLDMDB, VLDMIA gives the operational pseudocode for this instruction.


        A1


           31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7                         0
              !=1111     1 1 0 1 0 D 1 1                Rn           Vd         1 0 1 1               imm8
               cond                 P U       W


        Decrement Before variant

        FLDMDBX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VLDMDB{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15         12 11 10 9 8 7                         0
            1 1 1 0 1 1 0 1 0 D 1 1                     Rn           Vd         1 0 1 1               imm8
                                    P U       W


        Decrement Before variant

        FLDMDBX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VLDMDB{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <Rn>              For encoding A1: is the general-purpose base register, encoded in the "Rn" field. If writeback is not
                          specified, the PC can be used.

                          For encoding T1: is the general-purpose base register, encoded in the "Rn" field.

        !                 Specifies base register writeback. Encoded in the "W" field as 1 if present, otherwise 0.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list plus
                          one. The list must contain at least one register, all registers must be in the range D0-D15, and must
                          not contain more than 16 registers.
Operation for all encodings

The description of VLDM, VLDMDB, VLDMIA gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','FLDMIAX','        FLDMIAX loads multiple registers from consecutive locations in the Advanced SIMD and floating-point register       (F8.1.6)
        file using an address from a general-purpose register. ARM deprecates use of FLDMIAX, except for disassembly
        purposes, and reassembly of disassembled code.

        This instruction is an alias of the VLDM, VLDMDB, VLDMIA instruction. This means that:

        .       The encodings in this description are named to match the encodings of VLDM, VLDMDB, VLDMIA.

        .       The description of VLDM, VLDMDB, VLDMIA gives the operational pseudocode for this instruction.


        A1


           31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7                         0
              !=1111     1 1 0 0 1 D W 1                Rn           Vd         1 0 1 1               imm8
               cond                 P U


        Increment After variant

        FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VLDM{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15         12 11 10 9 8 7                         0
            1 1 1 0 1 1 0 0 1 D W 1                     Rn           Vd         1 0 1 1               imm8
                                    P U


        Increment After variant

        FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VLDM{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <Rn>              For encoding A1: is the general-purpose base register, encoded in the "Rn" field. If writeback is not
                          specified, the PC can be used.

                          For encoding T1: is the general-purpose base register, encoded in the "Rn" field.

        !                 Specifies base register writeback. Encoded in the "W" field as 1 if present, otherwise 0.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list plus
                          one. The list must contain at least one register, all registers must be in the range D0-D15, and must
                          not contain more than 16 registers.
Operation for all encodings

The description of VLDM, VLDMDB, VLDMIA gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','FSTMDBX','        FSTMDBX stores multiple registers from the Advanced SIMD and floating-point register file to consecutive       (F8.1.7)
        memory locations using an address from a general-purpose register. ARM deprecates use of FSTMDBX, except for
        disassembly purposes, and reassembly of disassembled code.

        This instruction is an alias of the VSTM, VSTMDB, VSTMIA instruction. This means that:

        .       The encodings in this description are named to match the encodings of VSTM, VSTMDB, VSTMIA.

        .       The description of VSTM, VSTMDB, VSTMIA gives the operational pseudocode for this instruction.


        A1


           31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7                         0
              !=1111     1 1 0 1 0 D 1 0                Rn           Vd         1 0 1 1               imm8
               cond                 P U       W


        Decrement Before variant

        FSTMDBX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VSTMDB{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15         12 11 10 9 8 7                         0
            1 1 1 0 1 1 0 1 0 D 1 0                     Rn           Vd         1 0 1 1               imm8
                                    P U       W


        Decrement Before variant

        FSTMDBX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VSTMDB{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <Rn>              For encoding A1: is the general-purpose base register, encoded in the "Rn" field. If writeback is not
                          specified, the PC can be used.

                          For encoding T1: is the general-purpose base register, encoded in the "Rn" field.

        !                 Specifies base register writeback. Encoded in the "W" field as 1 if present, otherwise 0.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list plus
                          one. The list must contain at least one register, all registers must be in the range D0-D15, and must
                          not contain more than 16 registers.
Operation for all encodings

The description of VSTM, VSTMDB, VSTMIA gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','FSTMIAX','        FSTMIAX stores multiple registers from the Advanced SIMD and floating-point register file to consecutive       (F8.1.8)
        memory locations using an address from a general-purpose register. ARM deprecates use of FSTMIAX, except for
        disassembly purposes, and reassembly of disassembled code.

        This instruction is an alias of the VSTM, VSTMDB, VSTMIA instruction. This means that:

        .       The encodings in this description are named to match the encodings of VSTM, VSTMDB, VSTMIA.

        .       The description of VSTM, VSTMDB, VSTMIA gives the operational pseudocode for this instruction.


        A1


           31        28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7                         0
              !=1111     1 1 0 0 1 D W 0                Rn           Vd         1 0 1 1               imm8
               cond                 P U


        Increment After variant

        FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VSTM{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15         12 11 10 9 8 7                         0
            1 1 1 0 1 1 0 0 1 D W 0                     Rn           Vd         1 0 1 1               imm8
                                    P U


        Increment After variant

        FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist>

        is equivalent to

        VSTM{<c>}{<q>} <Rn>{!}, <dreglist>

        and is the preferred disassembly when imm8<0> == ''1''.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <Rn>              For encoding A1: is the general-purpose base register, encoded in the "Rn" field. If writeback is not
                          specified, the PC can be used.

                          For encoding T1: is the general-purpose base register, encoded in the "Rn" field.

        !                 Specifies base register writeback. Encoded in the "W" field as 1 if present, otherwise 0.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list plus
                          one. The list must contain at least one register, all registers must be in the range D0-D15, and must
                          not contain more than 16 registers.
Operation for all encodings

The description of VSTM, VSTMDB, VSTMIA gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VABA','Vector Absolute Difference and Accumulate subtracts the elements of one vector from the corresponding elements       (F8.1.19)
of another vector, and accumulates the absolute values of the results into the elements of the destination vector.

Operand and result elements are all integers of the same length.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction that is not also available as a
floating-point instruction, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 U 0 D size                  Vn            Vd       0 1 1 1 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');     long_destination = FALSE;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 U 1 1 1 1 0 D size                  Vn            Vd       0 1 1 1 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm>
        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         unsigned = (U == ''1'');       long_destination = FALSE;
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VABA or VABAL instruction must be
                          unconditional. ARM strongly recommends that a T32 VABA or VABAL instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "U:size" field. It can have the
                          following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

                          It is RESERVED when:

                          .      U = 0, size = 11.

                          .      U = 1, size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        op1 = Elem[Din[n+r],e,esize];
                        op2 = Elem[Din[m+r],e,esize];
                        absdiff = Abs(Int(op1,unsigned) - Int(op2,unsigned));
                        if long_destination then
                             Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + absdiff;
                        else
                             Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + absdiff;');
INSERT INTO "instructions" VALUES('ARM','VABAL','Vector Absolute Difference and Accumulate Long subtracts the elements of one vector from the corresponding       (F8.1.20)
elements of another vector, and accumulates the absolute values of the results into the elements of the destination
vector.

Operand elements are all integers of the same length, and the result elements are double the length of the operands.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction that is not also available as a
floating-point instruction, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 U 1 D !=11                  Vn            Vd       0 1 0 1 N 0 M 0              Vm
                                   size


A1 variant

VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' then UNDEFINED;
 unsigned = (U == ''1'');     long_destination = TRUE;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = 1;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 U 1 1 1 1 1 D !=11                  Vn            Vd       0 1 0 1 N 0 M 0              Vm
                                   size


T1 variant

VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' then UNDEFINED;
 unsigned = (U == ''1'');     long_destination = TRUE;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = 1;


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.
        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VABA or VABAL instruction must be
                          unconditional. ARM strongly recommends that a T32 VABA or VABAL instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "U:size" field. It can have the
                          following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        op1 = Elem[Din[n+r],e,esize];
                        op2 = Elem[Din[m+r],e,esize];
                        absdiff = Abs(Int(op1,unsigned) - Int(op2,unsigned));
                        if long_destination then
                             Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + absdiff;
                        else
                             Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + absdiff;');
INSERT INTO "instructions" VALUES('ARM','VABD','Vector Absolute Difference (floating-point) subtracts the elements of one vector from the corresponding elements       (F8.1.21)
of another vector, and places the absolute values of the results in the elements of the destination vector.

Operand and result elements are all single-precision floating-point numbers.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 1 0 D 1 sz                   Vn           Vd        1 1 0 1 N Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VABD{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VABD{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 esize = 32;    elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 1 1 1 1 0 D 1 sz                   Vn           Vd        1 1 0 1 N Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VABD{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VABD{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>
        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);      n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VABD instruction must be
                          unconditional. ARM strongly recommends that a T32 VABD instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        op1 = Elem[D[n+r],e,esize];      op2 = Elem[D[m+r],e,esize];
                        Elem[D[d+r],e,esize] = FPAbs(FPSub(op1,op2,StandardFPSCRValue()));');
INSERT INTO "instructions" VALUES('ARM','VABDL','Vector Absolute Difference Long (integer) subtracts the elements of one vector from the corresponding elements       (F8.1.23)
of another vector, and places the absolute values of the results in the elements of the destination vector.

Operand elements are all integers of the same length, and the result elements are double the length of the operands.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction that is not also available as a
floating-point instruction, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 U 1 D !=11                  Vn            Vd        0 1 1 1 N 0 M 0              Vm
                                   size


A1 variant

VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' then UNDEFINED;
 unsigned = (U == ''1'');     long_destination = TRUE;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = 1;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 U 1 1 1 1 1 D !=11                  Vn            Vd        0 1 1 1 N 0 M 0              Vm
                                   size


T1 variant

VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' then UNDEFINED;
 unsigned = (U == ''1'');     long_destination = TRUE;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = 1;


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VABD or VABDL instruction must be
                unconditional. ARM strongly recommends that a T32 VABD or VABDL instruction is unconditional, see
                Conditional execution on page F2-2507.
        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "U:size" field. It can have the
                          following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        op1 = Elem[Din[n+r],e,esize];
                        op2 = Elem[Din[m+r],e,esize];
                        absdiff = Abs(Int(op1,unsigned) - Int(op2,unsigned));
                        if long_destination then
                             Elem[Q[d>>1],e,2*esize] = absdiff<2*esize-1:0>;
                        else
                             Elem[D[d+r],e,esize] = absdiff<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VABS','Vector Absolute takes the absolute value of each element in a vector, and places the results in a second vector. The       (F8.1.24)
floating-point version only clears the sign bit.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                  0
   1 1 1 1 0 0 1 1 1 D 1 1 size 0 1                       Vd         0 F 1 1 0 Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VABS{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VABS{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 advsimd = TRUE;    floating_point = (F == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


A2


  31        28 27 26 25 24 23 22 21 20 19 18 17 16 15          12 11 10 9 8 7 6 5 4 3                  0
     !=1111    1 1 1 0 1 D 1 1 0 0 0 0                    Vd         1 0 1 sz 1 1 M 0             Vm
      cond


Single-precision scalar variant

Applies when sz = 0.

VABS{<c>}{<q>}.F32 <Sd>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VABS{<c>}{<q>}.F64 <Dd>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;    dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3          0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 1                      Vd       0 F 1 1 0 Q M 0        Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VABS{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VABS{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         advsimd = TRUE;     floating_point = (F == ''1'');
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3          0
            1 1 1 0 1 1 1 0 1 D 1 1 0 0 0 0                       Vd       1 0 1 sz 1 1 M 0       Vm




        Single-precision scalar variant

        Applies when sz = 0.

        VABS{<c>}{<q>}.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VABS{<c>}{<q>}.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE;     dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 Advanced SIMD VABS instruction
                          must be unconditional. ARM strongly recommends that a T32 Advanced SIMD VABS instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.
<dt>          Is the data type for the elements of the vectors, encoded in the "F:size" field. It can have the
              following values:

              S8           when F = 0, size = 00

              S16          when F = 0, size = 01

              S32          when F = 0, size = 10

              F32          when F = 1, size = 10

              It is RESERVED when:

              .      F = 0, size = 11.

              .      F = 1, size = 0x.

              .      F = 1, size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

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

<Sm>          Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();      CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
    if advsimd then   // Advanced SIMD instruction
        for r = 0 to regs-1
            for e = 0 to elements-1
                 if floating_point then
                     Elem[D[d+r],e,esize] = FPAbs(Elem[D[m+r],e,esize]);
                 else
                     result = Abs(SInt(Elem[D[m+r],e,esize]));
                     Elem[D[d+r],e,esize] = result<esize-1:0>;
    else              // VFP instruction
        if dp_operation then
            D[d] = FPAbs(D[m]);
        else
            S[d] = FPAbs(S[m]);');
INSERT INTO "instructions" VALUES('ARM','VACGE','        Vector Absolute Compare Greater Than or Equal takes the absolute value of each element in a vector, and compares       (F8.1.25)
        it with the absolute value of the corresponding element of a second vector. If the first is greater than or equal to the
        second, the corresponding element in the destination vector is set to all ones. Otherwise, it is set to all zeros.

        The operands and result can be quadword or doubleword vectors. They must all be the same size.

        The operand vector elements must be 32-bit floating-point numbers.

        The result vector elements are 32-bit fields.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction that is not also available as a
        floating-point instruction, see Conditional execution on page F2-2507.

        This instruction is used by the alias VACLE. See the Alias conditions on page F8-3305 table for details of when
        each alias is preferred.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 1 0 0 1 1 0 D 0 0                  Vn            Vd      1 1 1 0 N Q M 1                  Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACGE{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VACGE{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         or_equal = (op == ''0'');     esize = 32;   elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 1 1 1 1 1 0 D 0 0                  Vn            Vd      1 1 1 0 N Q M 1                  Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACGE{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.
VACGE{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 or_equal = (op == ''0'');   esize = 32;   elements = 2;
 d = UInt(D:Vd);  n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Alias conditions


                   Alias                     is preferred when

                   VACLE                     Never



Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VACGE, VACGT, VACLE, or VACLT
              instruction must be unconditional. ARM strongly recommends that a T32 VACGE, VACGT, VACLE, or
              VACLT instruction is unconditional, see Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();    CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             op1 = FPAbs(Elem[D[n+r],e,esize]);     op2 = FPAbs(Elem[D[m+r],e,esize]);
             if or_equal then
                 test_passed = FPCompareGE(op1, op2, StandardFPSCRValue());
             else
                 test_passed = FPCompareGT(op1, op2, StandardFPSCRValue());
             Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VACLE','        Vector Absolute Compare Less Than or Equal takes the absolute value of each element in a vector, and compares       (F8.1.26)
        it with the absolute value of the corresponding element of a second vector. If the first is less than or equal to the
        second, the corresponding element in the destination vector is set to all ones. Otherwise, it is set to all zeros

        This instruction is an alias of the VACGE instruction. This means that:

        .       The encodings in this description are named to match the encodings of VACGE.

        .       The description of VACGE gives the operational pseudocode for this instruction.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19         16 15       12 11 10 9 8 7 6 5 4 3                     0
            1 1 1 1 0 0 1 1 0 D 0 0                   Vn          Vd       1 1 1 0 N Q M 1                 Vm
                                            op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACLE{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>

        is equivalent to

        VACGE{<c>}{<q>}.F32 <Dd>, <Dm>, <Dn>

        and is never the preferred disassembly.

        128-bit SIMD vector variant

        Applies when Q = 1.

        VACLE{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>

        is equivalent to

        VACGE{<c>}{<q>}.F32 <Qd>, <Qm>, <Qn>

        and is never the preferred disassembly.


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15       12 11 10 9 8 7 6 5 4 3                     0
            1 1 1 1 1 1 1 1 0 D 0 0                   Vn          Vd       1 1 1 0 N Q M 1                 Vm
                                            op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACLE{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>

        is equivalent to

        VACGE{<c>}{<q>}.F32 <Dd>, <Dm>, <Dn>

        and is never the preferred disassembly.

        128-bit SIMD vector variant

        Applies when Q = 1.
VACLE{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>

is equivalent to

VACGE{<c>}{<q>}.F32 <Qd>, <Qm>, <Qn>

and is never the preferred disassembly.


Assembler symbols

<Dm>            Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.

<Dn>            Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Qm>            Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                <Qm>*2.

<Qn>            Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VACGE, VACGT, VACLE, or VACLT
                instruction must be unconditional. ARM strongly recommends that a T32 VACGE, VACGT, VACLE, or
                VACLT instruction is unconditional, see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<Qd>            Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

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


Operation for all encodings

The description of VACGE gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VACGT','        Vector Absolute Compare Greater Than takes the absolute value of each element in a vector, and compares it with       (F8.1.27)
        the absolute value of the corresponding element of a second vector. If the first is greater than the second, the
        corresponding element in the destination vector is set to all ones. Otherwise, it is set to all zeros.

        The operands and result can be quadword or doubleword vectors. They must all be the same size.

        The operand vector elements must be 32-bit floating-point numbers.

        The result vector elements are 32-bit fields.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction that is not also available as a
        floating-point instruction, see Conditional execution on page F2-2507.

        This instruction is used by the alias VACLT. See the Alias conditions on page F8-3309 table for details of when
        each alias is preferred.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 1 0 D 1 0                  Vn            Vd       1 1 1 0 N Q M 1                 Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACGT{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VACGT{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         or_equal = (op == ''0'');     esize = 32;   elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 1 1 1 1 0 D 1 0                  Vn            Vd       1 1 1 0 N Q M 1                 Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACGT{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.
VACGT{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 or_equal = (op == ''0'');   esize = 32;   elements = 2;
 d = UInt(D:Vd);  n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Alias conditions


                   Alias                     is preferred when

                   VACLT                     Never



Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VACGE, VACGT, VACLE, or VACLT
              instruction must be unconditional. ARM strongly recommends that a T32 VACGE, VACGT, VACLE, or
              VACLT instruction is unconditional, see Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();    CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             op1 = FPAbs(Elem[D[n+r],e,esize]);     op2 = FPAbs(Elem[D[m+r],e,esize]);
             if or_equal then
                 test_passed = FPCompareGE(op1, op2, StandardFPSCRValue());
             else
                 test_passed = FPCompareGT(op1, op2, StandardFPSCRValue());
             Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VACLT','        Vector Absolute Compare Less Than takes the absolute value of each element in a vector, and compares it with the       (F8.1.28)
        absolute value of the corresponding element of a second vector. If the first is less than the second, the corresponding
        element in the destination vector is set to all ones. Otherwise, it is set to all zeros

        This instruction is an alias of the VACGT instruction. This means that:

        .       The encodings in this description are named to match the encodings of VACGT.

        .       The description of VACGT gives the operational pseudocode for this instruction.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 0 0 1 1 0 D 1 0                    Vn          Vd         1 1 1 0 N Q M 1              Vm
                                            op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACLT{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>

        is equivalent to

        VACGT{<c>}{<q>}.F32 <Dd>, <Dm>, <Dn>

        and is never the preferred disassembly.

        128-bit SIMD vector variant

        Applies when Q = 1.

        VACLT{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>

        is equivalent to

        VACGT{<c>}{<q>}.F32 <Qd>, <Qm>, <Qn>

        and is never the preferred disassembly.


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 1 1 1 1 0 D 1 0                    Vn          Vd         1 1 1 0 N Q M 1              Vm
                                            op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VACLT{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>

        is equivalent to

        VACGT{<c>}{<q>}.F32 <Dd>, <Dm>, <Dn>

        and is never the preferred disassembly.

        128-bit SIMD vector variant

        Applies when Q = 1.
VACLT{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>

is equivalent to

VACGT{<c>}{<q>}.F32 <Qd>, <Qm>, <Qn>

and is never the preferred disassembly.


Assembler symbols

<Dm>            Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.

<Dn>            Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Qm>            Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                <Qm>*2.

<Qn>            Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VACGE, VACGT, VACLE, or VACLT
                instruction must be unconditional. ARM strongly recommends that a T32 VACGE, VACGT, VACLE, or
                VACLT instruction is unconditional, see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<Qd>            Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

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


Operation for all encodings

The description of VACGT gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VADD','        Vector Add (floating-point) adds corresponding elements in two vectors, and places the results in the destination       (F8.1.29)
        vector.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 0 0 D 0 sz                  Vn          Vd       1 1 0 1 N Q M 0            Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VADD{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VADD{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         advsimd = TRUE;     esize = 32;  elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        A2


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3               0
              !=1111     1 1 1 0 0 D 1 1              Vn          Vd       1 0 1 sz N 0 M 0           Vm
               cond


        Single-precision scalar variant

        Applies when sz = 0.

        VADD{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VADD{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE;     dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3              0 15        12 11 10 9 8 7 6 5 4 3                  0
  1 1 1 0 1 1 1 1 0 D 0 sz                Vn          Vd         1 1 0 1 N Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VADD{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VADD{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 advsimd = TRUE;  esize = 32;  elements = 2;
 d = UInt(D:Vd);  n = UInt(N:Vn);   m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3              0 15        12 11 10 9 8 7 6 5 4 3                  0
  1 1 1 0 1 1 1 0 0 D 1 1                 Vn          Vd         1 0 1 sz N 0 M 0             Vm




Single-precision scalar variant

Applies when sz = 0.

VADD{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VADD{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;  dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


Assembler symbols

<c>           For encoding A1, A2 and T1: see Standard assembler syntax fields on page F2-2506. An A32
              Advanced SIMD VADD instruction must be unconditional. ARM strongly recommends that a T32
              Advanced SIMD VADD instruction is unconditional, see Conditional execution on page F2-2507

              For encoding T2: see Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Sd>          Is the 32-bit name of the SIMD&FP destination register, encoded in the "Vd:D" field.
        <Sn>              Is the 32-bit name of the first SIMD&FP source register, encoded in the "Vn:N" field.

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
               if advsimd then    // Advanced SIMD instruction
                   for r = 0 to regs-1
                        for e = 0 to elements-1
                             Elem[D[d+r],e,esize] = FPAdd(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize],
                                                             StandardFPSCRValue());
               else               // VFP instruction
                   if dp_operation then
                        D[d] = FPAdd(D[n], D[m], FPSCR);
                   else
                        S[d] = FPAdd(S[n], S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VADDHN','Vector Add and Narrow, returning High Half adds corresponding elements in two quadword vectors, and places the       (F8.1.31)
most significant half of each result in a doubleword vector. The results are truncated. For rounded results, see
VRADDHN.

The operand elements can be 16-bit, 32-bit, or 64-bit integers. There is no distinction between signed and unsigned
integers.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                0
   1 1 1 1 0 0 1 0 1 D !=11                   Vn           Vd       0 1 0 0 N 0 M 0              Vm
                                   size


A1 variant

VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);     m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                0
   1 1 1 0 1 1 1 1 1 D !=11                   Vn           Vd       0 1 0 0 N 0 M 0              Vm
                                   size


T1 variant

VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);     m = UInt(M:Vm);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VADDHN instruction must be
                unconditional.ARM strongly recommends that a T32 VADDHN instruction is unconditional, see
                Conditional execution on page F2-2507.
        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "size" field. It can have the
                          following values:

                          I16          when size = 00

                          I32          when size = 01

                          I64          when size = 10

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

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for e = 0 to elements-1
                   result = Elem[Qin[n>>1],e,2*esize] + Elem[Qin[m>>1],e,2*esize];
                   Elem[D[d],e,esize] = result<2*esize-1:esize>;');
INSERT INTO "instructions" VALUES('ARM','VADDL','Vector Add Long adds corresponding elements in two doubleword vectors, and places the results in a quadword       (F8.1.32)
vector. Before adding, it sign-extends or zero-extends the elements of both operands.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 U 1 D !=11                   Vn           Vd       0 0 0 0 N 0 M 0              Vm
                                   size                                        op


A1 variant

VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vaddw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 U 1 1 1 1 1 D !=11                   Vn           Vd       0 0 0 0 N 0 M 0              Vm
                                   size                                        op


T1 variant

VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vaddw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VADDL or VADDW instruction must be
                unconditional. ARM strongly recommends that a T32 VADDL or VADDW instruction is unconditional,
                see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.
        <dt>              Is the data type for the elements of the second operand vector, encoded in the "U:size" field. It can
                          have the following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for e = 0 to elements-1
                   if is_vaddw then
                        op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned);
                   else
                        op1 = Int(Elem[Din[n],e,esize], unsigned);
                   result = op1 + Int(Elem[Din[m],e,esize],unsigned);
                   Elem[Q[d>>1],e,2*esize] = result<2*esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VADDW','Vector Add Wide adds corresponding elements in one quadword and one doubleword vector, and places the results       (F8.1.33)
in a quadword vector. Before adding, it sign-extends or zero-extends the elements of the doubleword operand.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 U 1 D !=11                   Vn           Vd       0 0 0 1 N 0 M 0              Vm
                                   size                                        op


A1 variant

VADDW{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vaddw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 U 1 1 1 1 1 D !=11                   Vn           Vd       0 0 0 1 N 0 M 0              Vm
                                   size                                        op


T1 variant

VADDW{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vaddw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VADDL or VADDW instruction must be
                unconditional. ARM strongly recommends that a T32 VADDL or VADDW instruction is unconditional,
                see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.
        <dt>              Is the data type for the elements of the second operand vector, encoded in the "U:size" field. It can
                          have the following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for e = 0 to elements-1
                   if is_vaddw then
                        op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned);
                   else
                        op1 = Int(Elem[Din[n],e,esize], unsigned);
                   result = op1 + Int(Elem[Din[m],e,esize],unsigned);
                   Elem[Q[d>>1],e,2*esize] = result<2*esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VAND','Vector Bitwise AND (immediate) performs a bitwise AND between a register value and an immediate value, and       (F8.1.34)
returns the result into the destination vector

This instruction is an alias of the VBIC (immediate) instruction. This means that:

.      The encodings in this description are named to match the encodings of VBIC (immediate).

.      The description of VBIC (immediate) gives the operational pseudocode for this instruction.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19 18        16 15      12 11            8 7 6 5 4 3            0
   1 1 1 1 0 0 1 i 1 D 0 0 0                  imm3         Vd         cmode       0 Q 1 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VAND{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>

is equivalent to

VBIC{<c>}{<q>}.<dt> <Dd>, #~<imm>

and is never the preferred disassembly.

128-bit SIMD vector variant

Applies when Q = 1.

VAND{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>

is equivalent to

VBIC{<c>}{<q>}.<dt> <Qd>, #~<imm>

and is never the preferred disassembly.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2                0 15       12 11            8 7 6 5 4 3            0
   1 1 1 i 1 1 1 1 1 D 0 0 0                  imm3         Vd         cmode       0 Q 1 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VAND{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>

is equivalent to

VBIC{<c>}{<q>}.<dt> <Dd>, #~<imm>

and is never the preferred disassembly.

128-bit SIMD vector variant

Applies when Q = 1.

VAND{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>
        is equivalent to

        VBIC{<c>}{<q>}.<dt> <Qd>, #~<imm>

        and is never the preferred disassembly.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VORR instruction must be
                          unconditional. ARM strongly recommends that a T32 VORR instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              The data type used for <imm>. It can be either I16 or I32. I8, I64, and F32 are also permitted, but the
                          resulting syntax is a pseudo-instruction.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

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

        <imm>             Is a constant of the type specified by <dt> that is replicated to fill the destination register. For details
                          of the range of constants available and the encoding of <dt> and <imm>, see One register and a
                          modified immediate value on page F5-2596.


        Operation for all encodings

        The description of VBIC (immediate) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VBIC','Vector Bitwise Bit Clear (immediate) performs a bitwise AND between a register value and the complement of an       (F8.1.36)
immediate value, and returns the result into the destination vector.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.

This instruction is used by the alias VAND (immediate). See the Alias conditions on page F8-3328 table for details
of when each alias is preferred.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19 18        16 15       12 11           8 7 6 5 4 3            0
   1 1 1 1 0 0 1 i 1 D 0 0 0                  imm3         Vd         cmode       0 Q 1 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VBIC{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>


128-bit SIMD vector variant

Applies when Q = 1.

VBIC{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>


Decode for all variants of this encoding

 if cmode<0> == ''0'' || cmode<3:2> == ''11'' then SEE "Related encodings";
 if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
 imm64 = AdvSIMDExpandImm(''1'', cmode, i:imm3:imm4);
 d = UInt(D:Vd);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2                 0 15       12 11           8 7 6 5 4 3            0
   1 1 1 i 1 1 1 1 1 D 0 0 0                  imm3         Vd         cmode       0 Q 1 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VBIC{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>


128-bit SIMD vector variant

Applies when Q = 1.

VBIC{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>
        Decode for all variants of this encoding

         if cmode<0> == ''0'' || cmode<3:2> == ''11'' then SEE "Related encodings";
         if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
         imm64 = AdvSIMDExpandImm(''1'', cmode, i:imm3:imm4);
         d = UInt(D:Vd);      regs = if Q == ''0'' then 1 else 2;


        Notes for all encodings

        Related encodings: One register and a modified immediate value on page F5-2596.


        Alias conditions


                               Alias                     is preferred when

                               VAND (immediate)          Never



        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VBIC instruction must be
                          unconditional. ARM strongly recommends that a T32 VBIC instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              The data type used for <imm>. It can be either I16 or I32. I8, I64, and F32 are also permitted, but the
                          resulting syntax is a pseudo-instruction.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

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

        <imm>             Is a constant of the type specified by <dt> that is replicated to fill the destination register. For details
                          of the range of constants available and the encoding of <dt> and <imm>, see One register and a
                          modified immediate value on page F5-2596.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   D[d+r] = D[d+r] AND NOT(imm64);');
INSERT INTO "instructions" VALUES('ARM','VBIF','Vector Bitwise Insert if False inserts each bit from the first source register into the destination register if the       (F8.1.38)
corresponding bit of the second source register is 0, otherwise leaves the bit in the destination register unchanged.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 0 0 1 1 0 D 1 1                    Vn            Vd       0 0 0 1 N Q M 1                Vm
                                    op


64-bit SIMD vector variant

Applies when Q = 0.

VBIF{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VBIF{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if op == ''00'' then SEE VEOR;
 if op == ''01'' then operation = VBitOps_VBSL;
 if op == ''10'' then operation = VBitOps_VBIT;
 if op == ''11'' then operation = VBitOps_VBIF;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 1 1 1 1 0 D 1 1                    Vn            Vd       0 0 0 1 N Q M 1                Vm
                                    op


64-bit SIMD vector variant

Applies when Q = 0.

VBIF{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VBIF{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if op == ''00'' then SEE VEOR;
 if op == ''01'' then operation = VBitOps_VBSL;
         if op == ''10'' then operation = VBitOps_VBIT;
         if op == ''11'' then operation = VBitOps_VBIF;
         d = UInt(D:Vd);      n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VBIF, VBIT, or VBSL instruction must
                          be unconditional. ARM strongly recommends that a T32 VBIF, VBIT, or VBSL instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              An optional data type. It is ignored by assemblers, and does not affect the encoding.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         enumeration VBitOps {VBitOps_VBIF, VBitOps_VBIT, VBitOps_VBSL};

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   case operation of
                        when VBitOps_VBIF    D[d+r] = (D[d+r] AND D[m+r]) OR (D[n+r] AND NOT(D[m+r]));
                        when VBitOps_VBIT    D[d+r] = (D[n+r] AND D[m+r]) OR (D[d+r] AND NOT(D[m+r]));
                        when VBitOps_VBSL    D[d+r] = (D[n+r] AND D[d+r]) OR (D[m+r] AND NOT(D[d+r]));');
INSERT INTO "instructions" VALUES('ARM','VBIT','Vector Bitwise Insert if True inserts each bit from the first source register into the destination register if the       (F8.1.39)
corresponding bit of the second source register is 1, otherwise leaves the bit in the destination register unchanged.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 0 0 1 1 0 D 1 0                    Vn           Vd       0 0 0 1 N Q M 1                Vm




64-bit SIMD vector variant

Applies when Q = 0.

VBIT{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VBIT{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if op == ''00'' then SEE VEOR;
 if op == ''01'' then operation = VBitOps_VBSL;
 if op == ''10'' then operation = VBitOps_VBIT;
 if op == ''11'' then operation = VBitOps_VBIF;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 1 1 1 1 0 D 1 0                    Vn           Vd       0 0 0 1 N Q M 1                Vm




64-bit SIMD vector variant

Applies when Q = 0.

VBIT{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VBIT{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if op == ''00'' then SEE VEOR;
 if op == ''01'' then operation = VBitOps_VBSL;
         if op == ''10'' then operation = VBitOps_VBIT;
         if op == ''11'' then operation = VBitOps_VBIF;
         d = UInt(D:Vd);      n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VBIF, VBIT, or VBSL instruction must
                          be unconditional. ARM strongly recommends that a T32 VBIF, VBIT, or VBSL instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              An optional data type. It is ignored by assemblers, and does not affect the encoding.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         enumeration VBitOps {VBitOps_VBIF, VBitOps_VBIT, VBitOps_VBSL};

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   case operation of
                        when VBitOps_VBIF    D[d+r] = (D[d+r] AND D[m+r]) OR (D[n+r] AND NOT(D[m+r]));
                        when VBitOps_VBIT    D[d+r] = (D[n+r] AND D[m+r]) OR (D[d+r] AND NOT(D[m+r]));
                        when VBitOps_VBSL    D[d+r] = (D[n+r] AND D[d+r]) OR (D[m+r] AND NOT(D[d+r]));');
INSERT INTO "instructions" VALUES('ARM','VBSL','Vector Bitwise Select sets each bit in the destination to the corresponding bit from the first source operand when       (F8.1.40)
the original destination bit was 1, otherwise from the second source operand.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 1 0 D 0 1                    Vn           Vd       0 0 0 1 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VBSL{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VBSL{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if op == ''00'' then SEE VEOR;
 if op == ''01'' then operation = VBitOps_VBSL;
 if op == ''10'' then operation = VBitOps_VBIT;
 if op == ''11'' then operation = VBitOps_VBIF;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 1 1 1 1 0 D 0 1                    Vn           Vd       0 0 0 1 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VBSL{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VBSL{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if op == ''00'' then SEE VEOR;
 if op == ''01'' then operation = VBitOps_VBSL;
         if op == ''10'' then operation = VBitOps_VBIT;
         if op == ''11'' then operation = VBitOps_VBIF;
         d = UInt(D:Vd);      n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VBIF, VBIT, or VBSL instruction must
                          be unconditional. ARM strongly recommends that a T32 VBIF, VBIT, or VBSL instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              An optional data type. It is ignored by assemblers, and does not affect the encoding.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         enumeration VBitOps {VBitOps_VBIF, VBitOps_VBIT, VBitOps_VBSL};

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   case operation of
                        when VBitOps_VBIF    D[d+r] = (D[d+r] AND D[m+r]) OR (D[n+r] AND NOT(D[m+r]));
                        when VBitOps_VBIT    D[d+r] = (D[n+r] AND D[m+r]) OR (D[d+r] AND NOT(D[m+r]));
                        when VBitOps_VBSL    D[d+r] = (D[n+r] AND D[d+r]) OR (D[m+r] AND NOT(D[d+r]));');
INSERT INTO "instructions" VALUES('ARM','VCEQ','Vector Compare Equal to Zero takes each element in a vector, and compares it with zero. If it is equal to zero, the       (F8.1.41)
corresponding element in the destination vector is set to all ones. Otherwise, it is set to all zeros.

The operand vector elements can be any one of:

.      8-bit, 16-bit, or 32-bit integers. There is no distinction between signed and unsigned integers.

.      32-bit floating-point numbers.

The result vector elements are fields the same size as the operand vector elements.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                0
   1 1 1 1 0 0 1 1 1 D 1 1 size 0 1                          Vd       0 F 0 1 0 Q M 0               Vm




64-bit SIMD vector variant

Applies when Q = 0.

VCEQ{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


128-bit SIMD vector variant

Applies when Q = 1.

VCEQ{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


Decode for all variants of this encoding

 if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 floating_point = (F == ''1'');
 esize = 8 << UInt(size);       elements = 64 DIV esize;
 d = UInt(D:Vd);     m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                        12 11 10 9 8 7 6 5 4 3                0
   1 1 1 1 1 1 1 1 1 D 1 1 size 0 1                          Vd       0 F 0 1 0 Q M 0               Vm




64-bit SIMD vector variant

Applies when Q = 0.

VCEQ{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


128-bit SIMD vector variant

Applies when Q = 1.
        VCEQ{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


        Decode for all variants of this encoding

         if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         floating_point = (F == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VCEQ instruction must be
                          unconditional. ARM strongly recommends that a T32 VCEQ instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "F:size" field. It can have the
                          following values:

                          I8           when F = 0, size = 00

                          I16          when F = 0, size = 01

                          I32          when F = 0, size = 10

                          F32          when F = 1, size = 10

                          It is RESERVED when:

                          .      F = 0, size = 11.

                          .      F = 1, size = 0x.

                          .      F = 1, size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        if floating_point then
                             bits(esize) zero = FPZero(''0'');
                             test_passed = FPCompareEQ(Elem[D[m+r],e,esize], zero, StandardFPSCRValue());
                        else
                             test_passed = (Elem[D[m+r],e,esize] == Zeros(esize));
                        Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VCGE','        Vector Compare Greater Than or Equal to Zero takes each element in a vector, and compares it with zero. If it is       (F8.1.43)
        greater than or equal to zero, the corresponding element in the destination vector is set to all ones. Otherwise, it is
        set to all zeros.

        The operand vector elements can be any one of:

        .       8-bit, 16-bit, or 32-bit signed integers.

        .       32-bit floating-point numbers.

        The result vector elements are fields the same size as the operand vector elements.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                   0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 1                       Vd      0 F 0 0 1 Q M 0                Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCGE{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCGE{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


        Decode for all variants of this encoding

         if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         floating_point = (F == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 1                       Vd      0 F 0 0 1 Q M 0                Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCGE{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


        128-bit SIMD vector variant

        Applies when Q = 1.
VCGE{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


Decode for all variants of this encoding

 if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 floating_point = (F == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VCGE instruction must be
              unconditional. ARM strongly recommends that a T32 VCGE instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "F:size" field. It can have the
              following values:

              S8           when F = 0, size = 00

              S16          when F = 0, size = 01

              S32          when F = 0, size = 10

              F32          when F = 1, size = 10

              It is RESERVED when:

              .      F = 0, size = 11.

              .      F = 1, size = 0x.

              .      F = 1, size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             if floating_point then
                 bits(esize) zero = FPZero(''0'');
                 test_passed = FPCompareGE(Elem[D[m+r],e,esize], zero, StandardFPSCRValue());
             else
                 test_passed = (SInt(Elem[D[m+r],e,esize]) >= 0);
             Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VCGT','        Vector Compare Greater Than Zero takes each element in a vector, and compares it with zero. If it is greater than       (F8.1.45)
        zero, the corresponding element in the destination vector is set to all ones. Otherwise, it is set to all zeros.

        The operand vector elements can be any one of:

        .       8-bit, 16-bit, or 32-bit signed integers.

        .       32-bit floating-point numbers.

        The result vector elements are fields the same size as the operand vector elements.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                     0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 1                       Vd       0 F 0 0 0 Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCGT{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCGT{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


        Decode for all variants of this encoding

         if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         floating_point = (F == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                     0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 1                       Vd       0 F 0 0 0 Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCGT{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


        128-bit SIMD vector variant

        Applies when Q = 1.
VCGT{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


Decode for all variants of this encoding

 if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 floating_point = (F == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VCGT instruction must be
              unconditional. ARM strongly recommends that a T32 VCGT instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "F:size" field. It can have the
              following values:

              S8           when F = 0, size = 00

              S16          when F = 0, size = 01

              S32          when F = 0, size = 10

              F32          when F = 1, size = 10

              It is RESERVED when:

              .      F = 0, size = 11.

              .      F = 1, size = 0x.

              .      F = 1, size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             if floating_point then
                 bits(esize) zero = FPZero(''0'');
                 test_passed = FPCompareGT(Elem[D[m+r],e,esize], zero, StandardFPSCRValue());
             else
                 test_passed = (SInt(Elem[D[m+r],e,esize]) > 0);
             Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VCLE','        Vector Compare Less Than or Equal to Zero takes each element in a vector, and compares it with zero. If it is less       (F8.1.47)
        than or equal to zero, the corresponding element in the destination vector is set to all ones. Otherwise, it is set to all
        zeros.

        The operand vector elements can be any one of:

        .       8-bit, 16-bit, or 32-bit signed integers.

        .       32-bit floating-point numbers.

        The result vector elements are fields the same size as the operand vector elements.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                   0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 1                       Vd      0 F 0 1 1 Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCLE{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCLE{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


        Decode for all variants of this encoding

         if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         floating_point = (F == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 1                       Vd      0 F 0 1 1 Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCLE{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


        128-bit SIMD vector variant

        Applies when Q = 1.
VCLE{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


Decode for all variants of this encoding

 if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 floating_point = (F == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VCLE instruction must be
              unconditional. ARM strongly recommends that a T32 VCLE instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "F:size" field. It can have the
              following values:

              S8           when F = 0, size = 00

              S16          when F = 0, size = 01

              S32          when F = 0, size = 10

              F32          when F = 1, size = 10

              It is RESERVED when:

              .      F = 0, size = 11.

              .      F = 1, size = 0x.

              .      F = 1, size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             if floating_point then
                 bits(esize) zero = FPZero(''0'');
                 test_passed = FPCompareGE(zero, Elem[D[m+r],e,esize], StandardFPSCRValue());
             else
                 test_passed = (SInt(Elem[D[m+r],e,esize]) <= 0);
             Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VCLS','Vector Count Leading Sign Bits counts the number of consecutive bits following the topmost bit, that are the same       (F8.1.49)
as the topmost bit, in each element in a vector, and places the results in a second vector. The count does not include
the topmost bit itself.

The operand vector elements can be any one of 8-bit, 16-bit, or 32-bit signed integers.

The result vector elements are the same data type as the operand vector elements.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                 0
   1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                        Vd        0 1 0 0 0 Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VCLS{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VCLS{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                        Vd        0 1 0 0 0 Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VCLS{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VCLS{<c>}{<q>}.<dt> <Qd>, <Qm>
        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VCLS instruction must be
                          unconditional. ARM strongly recommends that a T32 VCLS instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "size" field. It can have the
                          following values:

                          S8           when size = 00

                          S16          when size = 01

                          S32          when size = 10

                          It is RESERVED when size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        Elem[D[d+r],e,esize] = CountLeadingSignBits(Elem[D[m+r],e,esize])<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VCLT','Vector Compare Less Than Zero takes each element in a vector, and compares it with zero. If it is less than zero,       (F8.1.50)
the corresponding element in the destination vector is set to all ones. Otherwise, it is set to all zeros.

The operand vector elements can be any one of:

.      8-bit, 16-bit, or 32-bit signed integers.

.      32-bit floating-point numbers.

The result vector elements are fields the same size as the operand vector elements.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                    0
   1 1 1 1 0 0 1 1 1 D 1 1 size 0 1                        Vd         0 F 1 0 0 Q M 0               Vm




64-bit SIMD vector variant

Applies when Q = 0.

VCLT{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


128-bit SIMD vector variant

Applies when Q = 1.

VCLT{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


Decode for all variants of this encoding

 if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 floating_point = (F == ''1'');
 esize = 8 << UInt(size);      elements = 64 DIV esize;
 d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                      12 11 10 9 8 7 6 5 4 3                    0
   1 1 1 1 1 1 1 1 1 D 1 1 size 0 1                        Vd         0 F 1 0 0 Q M 0               Vm




64-bit SIMD vector variant

Applies when Q = 0.

VCLT{<c>}{<q>}.<dt> {<Dd>,} <Dm>, #0


128-bit SIMD vector variant

Applies when Q = 1.
        VCLT{<c>}{<q>}.<dt> {<Qd>,} <Qm>, #0


        Decode for all variants of this encoding

         if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         floating_point = (F == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VCLT instruction must be
                          unconditional. ARM strongly recommends that a T32 VCLT instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "F:size" field. It can have the
                          following values:

                          S8           when F = 0, size = 00

                          S16          when F = 0, size = 01

                          S32          when F = 0, size = 10

                          F32          when F = 1, size = 10

                          It is RESERVED when:

                          .      F = 0, size = 11.

                          .      F = 1, size = 0x.

                          .      F = 1, size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        if floating_point then
                             bits(esize) zero = FPZero(''0'');
                             test_passed = FPCompareGT(zero, Elem[D[m+r],e,esize], StandardFPSCRValue());
                        else
                             test_passed = (SInt(Elem[D[m+r],e,esize]) < 0);
                        Elem[D[d+r],e,esize] = if test_passed then Ones(esize) else Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VCLZ','        Vector Count Leading Zeros counts the number of consecutive zeros, starting from the most significant bit, in each       (F8.1.52)
        element in a vector, and places the results in a second vector.

        The operand vector elements can be any one of 8-bit, 16-bit, or 32-bit integers. There is no distinction between
        signed and unsigned integers.

        The result vector elements are the same data type as the operand vector elements.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                 0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                       Vd      0 1 0 0 1 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                       Vd      0 1 0 0 1 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm>
Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VCLZ instruction must be
              unconditional. ARM strongly recommends that a T32 VCLZ instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "size" field. It can have the
              following values:

              I8           when size = 00

              I16          when size = 01

              I32          when size = 10

              It is RESERVED when size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             Elem[D[d+r],e,esize] = CountLeadingZeroBits(Elem[D[m+r],e,esize])<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VCMP','        Vector Compare compares two floating-point registers, or one floating-point register and zero. It writes the result       (F8.1.53)
        to the FPSCR flags. These are normally transferred to the PSTATE.{N, Z, C, V} Condition flags by a subsequent
        VMRS instruction.

        It raises an Invalid Operation exception only if either operand is a signaling NaN.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19 18 17 16 15         12 11 10 9 8 7 6 5 4 3               0
              !=1111     1 1 1 0 1 D 1 1 0 1 0 0                   Vd       1 0 1 sz 0 1 M 0           Vm
               cond                                                                     E


        Single-precision scalar variant

        Applies when sz = 0.

        VCMP{<c>}{<q>}.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VCMP{<c>}{<q>}.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         dp_operation = (sz == ''1'');     quiet_nan_exc = (E == ''1'');     with_zero = FALSE;
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        A2


           31        28 27 26 25 24 23 22 21 20 19 18 17 16 15         12 11 10 9 8 7 6 5 4 3 2 1 0
              !=1111     1 1 1 0 1 D 1 1 0 1 0 1                   Vd       1 0 1 sz 0 1 (0) 0 (0) (0) (0) (0)
               cond                                                                     E


        Single-precision scalar variant

        Applies when sz = 0.

        VCMP{<c>}{<q>}.F32 <Sd>, #0.0


        Double-precision scalar variant

        Applies when sz = 1.

        VCMP{<c>}{<q>}.F64 <Dd>, #0.0


        Decode for all variants of this encoding

         dp_operation = (sz == ''1'');     quiet_nan_exc = (E == ''1'');     with_zero = TRUE;
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                  12 11 10 9 8 7 6 5 4 3                  0
  1 1 1 0 1 1 1 0 1 D 1 1 0 1 0 0                      Vd         1 0 1 sz 0 1 M 0             Vm
                                                                                E


Single-precision scalar variant

Applies when sz = 0.

VCMP{<c>}{<q>}.F32 <Sd>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VCMP{<c>}{<q>}.F64 <Dd>, <Dm>


Decode for all variants of this encoding

 dp_operation = (sz == ''1'');   quiet_nan_exc = (E == ''1'');     with_zero = FALSE;
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                  12 11 10 9 8 7 6 5 4 3 2 1 0
  1 1 1 0 1 1 1 0 1 D 1 1 0 1 0 1                      Vd         1 0 1 sz 0 1 (0) 0 (0) (0) (0) (0)
                                                                                E


Single-precision scalar variant

Applies when sz = 0.

VCMP{<c>}{<q>}.F32 <Sd>, #0.0


Double-precision scalar variant

Applies when sz = 1.

VCMP{<c>}{<q>}.F64 <Dd>, #0.0


Decode for all variants of this encoding

 dp_operation = (sz == ''1'');   quiet_nan_exc = (E == ''1'');     with_zero = TRUE;
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

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

<Sm>           Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.
        <Dd>              Is the 64-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field.

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        NaNs

        The IEEE 754 standard specifies that the result of a comparison is precisely one of <, ==, > or unordered. If either
        or both of the operands are NaNs, they are unordered, and all three of (Operand1 < Operand2), (Operand1 ==
        Operand2) and (Operand1 > Operand2) are false. This results in the FPSCR flags being set as N=0, Z=0, C=1 and
        V=1.

        VCMPE raises an Invalid Operation exception if either operand is any type of NaN, and is suitable for testing for <,
        <=, >, >=, and other predicates that raise an exception when the operands are unordered.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();     CheckVFPEnabled(TRUE);
               if dp_operation then
                   bits(64) op64 = if with_zero then FPZero(''0'') else D[m];
                   FPSCR.<N,Z,C,V> = FPCompare(D[d], op64, quiet_nan_exc, FPSCR);
               else
                   bits(32) op32 = if with_zero then FPZero(''0'') else S[m];
                   FPSCR.<N,Z,C,V> = FPCompare(S[d], op32, quiet_nan_exc, FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VCMPE','Vector Compare, raising Invalid Operation on NaN compares two floating-point registers, or one floating-point       (F8.1.54)
register and zero. It writes the result to the FPSCR flags. These are normally transferred to the PSTATE.{N, Z, C,
V} Condition flags by a subsequent VMRS instruction.

It raises an Invalid Operation exception if either operand is any type of NaN, or if either operand is a signaling NaN.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


   31        28 27 26 25 24 23 22 21 20 19 18 17 16 15          12 11 10 9 8 7 6 5 4 3                    0
      !=1111    1 1 1 0 1 D 1 1 0 1 0 0                     Vd        1 0 1 sz 1 1 M 0             Vm
       cond                                                                         E


Single-precision scalar variant

Applies when sz = 0.

VCMPE{<c>}{<q>}.F32 <Sd>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VCMPE{<c>}{<q>}.F64 <Dd>, <Dm>


Decode for all variants of this encoding

 dp_operation = (sz == ''1'');      quiet_nan_exc = (E == ''1'');      with_zero = FALSE;
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


A2


   31        28 27 26 25 24 23 22 21 20 19 18 17 16 15          12 11 10 9 8 7 6 5 4 3 2 1 0
      !=1111    1 1 1 0 1 D 1 1 0 1 0 1                     Vd        1 0 1 sz 1 1 (0) 0 (0) (0) (0) (0)
       cond                                                                         E


Single-precision scalar variant

Applies when sz = 0.

VCMPE{<c>}{<q>}.F32 <Sd>, #0.0


Double-precision scalar variant

Applies when sz = 1.

VCMPE{<c>}{<q>}.F64 <Dd>, #0.0


Decode for all variants of this encoding

 dp_operation = (sz == ''1'');      quiet_nan_exc = (E == ''1'');      with_zero = TRUE;
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3               0
            1 1 1 0 1 1 1 0 1 D 1 1 0 1 0 0                       Vd        1 0 1 sz 1 1 M 0          Vm
                                                                                      E


        Single-precision scalar variant

        Applies when sz = 0.

        VCMPE{<c>}{<q>}.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VCMPE{<c>}{<q>}.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         dp_operation = (sz == ''1'');      quiet_nan_exc = (E == ''1'');    with_zero = FALSE;
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3 2 1 0
            1 1 1 0 1 1 1 0 1 D 1 1 0 1 0 1                       Vd        1 0 1 sz 1 1 (0) 0 (0) (0) (0) (0)
                                                                                      E


        Single-precision scalar variant

        Applies when sz = 0.

        VCMPE{<c>}{<q>}.F32 <Sd>, #0.0


        Double-precision scalar variant

        Applies when sz = 1.

        VCMPE{<c>}{<q>}.F64 <Dd>, #0.0


        Decode for all variants of this encoding

         dp_operation = (sz == ''1'');      quiet_nan_exc = (E == ''1'');    with_zero = TRUE;
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

        <Sm>              Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.
<Dd>            Is the 64-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field.

<Dm>            Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


NaNs

The IEEE 754 standard specifies that the result of a comparison is precisely one of <, ==, > or unordered. If either
or both of the operands are NaNs, they are unordered, and all three of (Operand1 < Operand2), (Operand1 ==
Operand2) and (Operand1 > Operand2) are false. This results in the FPSCR flags being set as N=0, Z=0, C=1 and
V=1.

VCMPE raises an Invalid Operation exception if either operand is any type of NaN, and is suitable for testing for <,
<=, >, >=, and other predicates that raise an exception when the operands are unordered.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();      CheckVFPEnabled(TRUE);
     if dp_operation then
          bits(64) op64 = if with_zero then FPZero(''0'') else D[m];
          FPSCR.<N,Z,C,V> = FPCompare(D[d], op64, quiet_nan_exc, FPSCR);
     else
          bits(32) op32 = if with_zero then FPZero(''0'') else S[m];
          FPSCR.<N,Z,C,V> = FPCompare(S[d], op32, quiet_nan_exc, FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VCNT','        Vector Count Set Bits counts the number of bits that are one in each element in a vector, and places the results in a       (F8.1.55)
        second vector.

        The operand vector elements must be 8-bit fields.

        The result vector elements are 8-bit integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                 0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                       Vd      0 1 0 1 0 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCNT{<c>}{<q>}.8 <Dd>, <Dm>// Encoded as Q = 0


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCNT{<c>}{<q>}.8 <Qd>, <Qm>// Encoded as Q = 1


        Decode for all variants of this encoding

         if size != ''00'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8;     elements = 8;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                       Vd      0 1 0 1 0 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VCNT{<c>}{<q>}.8 <Dd>, <Dm>// Encoded as Q = 0


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCNT{<c>}{<q>}.8 <Qd>, <Qm>// Encoded as Q = 1
Decode for all variants of this encoding

 if size != ''00'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8; elements = 8;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VCNT instruction must be
              unconditional. ARM strongly recommends that a T32 VCNT instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();   CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             Elem[D[d+r],e,esize] = BitCount(Elem[D[m+r],e,esize])<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VCVT','        Convert between double-precision and single-precision does one of the following:       (F8.1.56)

        .       Converts the value in a double-precision register to single-precision and writes the result to a single-precision
                register.

        .       Converts the value in a single-precision register to double-precision and writes the result to a
                double-precision register.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19 18 17 16 15            12 11 10 9 8 7 6 5 4 3                   0
              !=1111     1 1 1 0 1 D 1 1 0 1 1 1                     Vd      1 0 1 sz 1 1 M 0                Vm
               cond


        Encoding

        Applies when sz = 0.

        VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm>


        Encoding

        Applies when sz = 1.

        VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm>


        Decode for all variants of this encoding

         double_to_single = (sz == ''1'');
         d = if double_to_single then UInt(Vd:D) else UInt(D:Vd);
         m = if double_to_single then UInt(M:Vm) else UInt(Vm:M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                       12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 0 1 1 1 0 1 D 1 1 0 1 1 1                          Vd      1 0 1 sz 1 1 M 0                Vm




        Encoding

        Applies when sz = 0.

        VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm>


        Encoding

        Applies when sz = 1.

        VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm>


        Decode for all variants of this encoding

         double_to_single = (sz == ''1'');
         d = if double_to_single then UInt(Vd:D) else UInt(D:Vd);
         m = if double_to_single then UInt(M:Vm) else UInt(Vm:M);
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

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

<Sm>          Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();    CheckVFPEnabled(TRUE);
    if double_to_single then
        S[d] = FPConvert(D[m], FPSCR);
    else
        D[d] = FPConvert(S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VCVTA','Vector Convert floating-point to integer with Round to Nearest with Ties to Away converts each element in a vector       (F8.1.63)
from floating-point to integer using the Round to Nearest with Ties to Away rounding mode, and places the results
in a second vector.

The operand vector elements must be 32-bit floating-point numbers.

The result vector elements are 32-bit integers. Signed and unsigned integers are distinct.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


  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 3                 0
   1 1 1 1 0 0 1 1 1 D 1 1 size 1 1                       Vd        0 0 0 0 op Q M 0             Vm
                                                                            RM


64-bit SIMD vector variant

Applies when Q = 0.

VCVTA{<q>}.<dt>.F32 <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VCVTA{<q>}.<dt>.F32 <Qd>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size != ''10'' then UNDEFINED;
 rounding = FPDecodeRM(RM);     unsigned = (op == ''1'');
 esize = 32;   elements = 2;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 1 1 1 1 1 D 1 1 size 1 1                       Vd        0 0 0 0 op Q M 0             Vm
                                                                            RM


64-bit SIMD vector variant

Applies when Q = 0.

VCVTA{<q>}.<dt>.F32 <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VCVTA{<q>}.<dt>.F32 <Qd>, <Qm>
        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPDecodeRM(RM);       unsigned = (op == ''1'');
         esize = 32;     elements = 2;
         d = UInt(D:Vd);      m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        Assembler symbols

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              For encoding A1: is the data type for the elements of the destination, encoded in the "op" field. It
                          can have the following values:

                          S32         when op = 0

                          U32         when op = 1

                          For encoding T1: is the data type for the elements of the destination, encoded in the "op" field. It
                          can have the following values:

                          S32         when op = 0

                          U32         when op = 1

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         EncodingSpecificOperations(); CheckAdvSIMDEnabled();
         bits(esize) result;
         for r = 0 to regs-1
               for e = 0 to elements-1
                   Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned,
                                                        StandardFPSCRValue(), rounding);');
INSERT INTO "instructions" VALUES('ARM','VCVTB','Convert to or from a half-precision value in the bottom half of a single-precision register does one of the following:       (F8.1.65)

.     Converts the half-precision value in the bottom half of a single-precision register to single-precision and
      writes the result to a single-precision register.

.     Converts the half-precision value in the bottom half of a single-precision register to double-precision and
      writes the result to a double-precision register.

.     Converts the single-precision value in a single-precision register to half-precision and writes the result into
      the bottom half of a single-precision register, preserving the other half of the destination register.

.     Converts the double-precision value in a double-precision register to half-precision and writes the result into
      the bottom half of a single-precision register, preserving the other half of the destination register.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


  31       28 27 26 25 24 23 22 21 20 19 18 17 16 15            12 11 10 9 8 7 6 5 4 3                  0
    !=1111     1 1 1 0 1 D 1 1 0 0 1 op                   Vd         1 0 1 sz 0 1 M 0             Vm
     cond                                                                          T


Encoding

Applies when op = 0 && sz = 0.

VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm>


Encoding

Applies when op = 0 && sz = 1.

VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm>


Encoding

Applies when op = 1 && sz = 0.

VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm>


Encoding

Applies when op = 1 && sz = 1.

VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm>


Decode for all variants of this encoding

 uses_double = (sz == ''1''); convert_from_half = (op == ''0'');
 lowbit = (if T == ''1'' then 16 else 0);
 if uses_double then
    if convert_from_half then
         d = UInt(D:Vd); m = UInt(Vm:M);
    else
         d = UInt(Vd:D); m = UInt(M:Vm);
 else
    d = UInt(Vd:D); m = UInt(Vm:M);
        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3               0
            1 1 1 0 1 1 1 0 1 D 1 1 0 0 1 op                      Vd        1 0 1 sz 0 1 M 0          Vm
                                                                                      T


        Encoding

        Applies when op = 0 && sz = 0.

        VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm>


        Encoding

        Applies when op = 0 && sz = 1.

        VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm>


        Encoding

        Applies when op = 1 && sz = 0.

        VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm>


        Encoding

        Applies when op = 1 && sz = 1.

        VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm>


        Decode for all variants of this encoding

         uses_double = (sz == ''1''); convert_from_half = (op == ''0'');
         lowbit = (if T == ''1'' then 16 else 0);
         if uses_double then
               if convert_from_half then
                   d = UInt(D:Vd); m = UInt(Vm:M);
               else
                   d = UInt(Vd:D); m = UInt(M:Vm);
         else
               d = UInt(Vd:D); m = UInt(Vm:M);


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

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

        <Sm>              Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations(); CheckVFPEnabled(TRUE);
               bits(16) hp;
               if convert_from_half then
                   hp = S[m]<lowbit+15:lowbit>;
                   if uses_double then
         D[d] = FPConvert(hp, FPSCR);
      else
         S[d] = FPConvert(hp, FPSCR);
   else
      if uses_double then
         hp = FPConvert(D[m], FPSCR);
      else
         hp = FPConvert(S[m], FPSCR);
      S[d]<lowbit+15:lowbit> = hp;');
INSERT INTO "instructions" VALUES('ARM','VCVTM','        Vector Convert floating-point to integer with Round towards -Infinity converts each element in a vector from       (F8.1.66)
        floating-point to integer using the Round towards -Infinity rounding mode, and places the results in a second vector.

        The operand vector elements must be 32-bit floating-point numbers.

        The result vector elements are 32-bit integers. Signed and unsigned integers are distinct.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           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 3                  0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 1                      Vd       0 0 1 1 op Q M 0             Vm
                                                                                 RM


        64-bit SIMD vector variant

        Applies when Q = 0.

        VCVTM{<q>}.<dt>.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCVTM{<q>}.<dt>.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPDecodeRM(RM);      unsigned = (op == ''1'');
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 1                      Vd       0 0 1 1 op Q M 0             Vm
                                                                                 RM


        64-bit SIMD vector variant

        Applies when Q = 0.

        VCVTM{<q>}.<dt>.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCVTM{<q>}.<dt>.F32 <Qd>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size != ''10'' then UNDEFINED;
 rounding = FPDecodeRM(RM);   unsigned = (op == ''1'');
 esize = 32;  elements = 2;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          For encoding A1: is the data type for the elements of the destination, encoded in the "op" field. It
              can have the following values:

              S32         when op = 0

              U32         when op = 1

              For encoding T1: is the data type for the elements of the destination, encoded in the "op" field. It
              can have the following values:

              S32         when op = 0

              U32         when op = 1

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 bits(esize) result;
 for r = 0 to regs-1
     for e = 0 to elements-1
         Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned,
                                            StandardFPSCRValue(), rounding);');
INSERT INTO "instructions" VALUES('ARM','VCVTN','        Vector Convert floating-point to integer with Round to Nearest converts each element in a vector from       (F8.1.68)
        floating-point to integer using the Round to Nearest rounding mode, and places the results in a second vector.

        The operand vector elements must be 32-bit floating-point numbers.

        The result vector elements are 32-bit integers. Signed and unsigned integers are distinct.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           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 3               0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 1                      Vd       0 0 0 1 op Q M 0            Vm
                                                                                 RM


        64-bit SIMD vector variant

        Applies when Q = 0.

        VCVTN{<q>}.<dt>.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCVTN{<q>}.<dt>.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPDecodeRM(RM);      unsigned = (op == ''1'');
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 1                      Vd       0 0 0 1 op Q M 0            Vm
                                                                                 RM


        64-bit SIMD vector variant

        Applies when Q = 0.

        VCVTN{<q>}.<dt>.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCVTN{<q>}.<dt>.F32 <Qd>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size != ''10'' then UNDEFINED;
 rounding = FPDecodeRM(RM);   unsigned = (op == ''1'');
 esize = 32;  elements = 2;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          For encoding A1: is the data type for the elements of the destination, encoded in the "op" field. It
              can have the following values:

              S32         when op = 0

              U32         when op = 1

              For encoding T1: is the data type for the elements of the destination, encoded in the "op" field. It
              can have the following values:

              S32         when op = 0

              U32         when op = 1

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 bits(esize) result;
 for r = 0 to regs-1
     for e = 0 to elements-1
         Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned,
                                            StandardFPSCRValue(), rounding);');
INSERT INTO "instructions" VALUES('ARM','VCVTP','        Vector Convert floating-point to integer with Round towards +Infinity converts each element in a vector from       (F8.1.70)
        floating-point to integer using the Round towards +Infinity rounding mode, and places the results in a second vector.

        The operand vector elements must be 32-bit floating-point numbers.

        The result vector elements are 32-bit integers. Signed and unsigned integers are distinct.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           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 3                  0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 1                      Vd       0 0 1 0 op Q M 0             Vm
                                                                                 RM


        64-bit SIMD vector variant

        Applies when Q = 0.

        VCVTP{<q>}.<dt>.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCVTP{<q>}.<dt>.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPDecodeRM(RM);      unsigned = (op == ''1'');
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 1                      Vd       0 0 1 0 op Q M 0             Vm
                                                                                 RM


        64-bit SIMD vector variant

        Applies when Q = 0.

        VCVTP{<q>}.<dt>.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VCVTP{<q>}.<dt>.F32 <Qd>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size != ''10'' then UNDEFINED;
 rounding = FPDecodeRM(RM);   unsigned = (op == ''1'');
 esize = 32;  elements = 2;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          For encoding A1: is the data type for the elements of the destination, encoded in the "op" field. It
              can have the following values:

              S32         when op = 0

              U32         when op = 1

              For encoding T1: is the data type for the elements of the destination, encoded in the "op" field. It
              can have the following values:

              S32         when op = 0

              U32         when op = 1

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 bits(esize) result;
 for r = 0 to regs-1
     for e = 0 to elements-1
         Elem[D[d+r],e,esize] = FPToFixed(Elem[D[m+r],e,esize], 0, unsigned,
                                            StandardFPSCRValue(), rounding);');
INSERT INTO "instructions" VALUES('ARM','VCVTR','        Convert floating-point to integer converts a value in a register from floating-point to a 32-bit integer, using the       (F8.1.72)
        rounding mode specified by the FPSCR and places the result in a second register.

        VCVT (between floating-point and fixed-point, floating-point) describes conversions between floating-point and
        16-bit integers.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19 18     16 15         12 11 10 9 8 7 6 5 4 3                  0
              !=1111     1 1 1 0 1 D 1 1 1 1 0 x                  Vd        1 0 1 sz 0 1 M 0              Vm
               cond                                  opc2                               op


        Single-precision scalar variant

        Applies when opc2 = 100 && sz = 0.

        VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm>


        Single-precision scalar variant

        Applies when opc2 = 101 && sz = 0.

        VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when opc2 = 100 && sz = 1.

        VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm>


        Double-precision scalar variant

        Applies when opc2 = 101 && sz = 1.

        VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm>


        Decode for all variants of this encoding

         if opc2 != ''000'' && opc2 != ''10x'' then SEE "Related encodings";
         to_integer = (opc2<2> == ''1'');     dp_operation = (sz == ''1'');
         if to_integer then
               unsigned = (opc2<0> == ''0'');
               rounding = if op == ''1'' then FPRounding_ZERO else FPRoundingMode(FPSCR);
               d = UInt(Vd:D);  m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
         else
               unsigned = (op == ''0'');
               rounding = FPRoundingMode(FPSCR);
               m = UInt(Vm:M);  d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2               0 15         12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 0 1 1 1 0 1 D 1 1 1 1 0 x                       Vd        1 0 1 sz 0 1 M 0              Vm
                                                     opc2                               op
Single-precision scalar variant

Applies when opc2 = 100 && sz = 0.

VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm>


Single-precision scalar variant

Applies when opc2 = 101 && sz = 0.

VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm>


Double-precision scalar variant

Applies when opc2 = 100 && sz = 1.

VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm>


Double-precision scalar variant

Applies when opc2 = 101 && sz = 1.

VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm>


Decode for all variants of this encoding

 if opc2 != ''000'' && opc2 != ''10x'' then SEE "Related encodings";
 to_integer = (opc2<2> == ''1'');   dp_operation = (sz == ''1'');
 if to_integer then
     unsigned = (opc2<0> == ''0'');
     rounding = if op == ''1'' then FPRounding_ZERO else FPRoundingMode(FPSCR);
     d = UInt(Vd:D);  m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
 else
     unsigned = (op == ''0'');
     rounding = FPRoundingMode(FPSCR);
     m = UInt(Vm:M);  d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);


Notes for all encodings

Related encodings: Floating-point data-processing instructions on page F5-2599.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

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

<Sm>          Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();   CheckVFPEnabled(TRUE);
     if to_integer then
         if dp_operation then
            S[d] = FPToFixed(D[m], 0, unsigned, FPSCR, rounding);
         else
            S[d] = FPToFixed(S[m], 0, unsigned, FPSCR, rounding);
     else
         if dp_operation then
                        D[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding);
                   else
                        S[d] = FixedToFP(S[m], 0, unsigned, FPSCR, rounding);');
INSERT INTO "instructions" VALUES('ARM','VCVTT','Convert to or from a half-precision value in the top half of a single-precision register does one of the following:       (F8.1.73)

.     Converts the half-precision value in the top half of a single-precision register to single-precision and writes
      the result to a single-precision register.

.     Converts the half-precision value in the top half of a single-precision register to double-precision and writes
      the result to a double-precision register.

.     Converts the single-precision value in a single-precision register to half-precision and writes the result into
      the top half of a single-precision register, preserving the other half of the destination register.

.     Converts the double-precision value in a double-precision register to half-precision and writes the result into
      the top half of a single-precision register, preserving the other half of the destination register.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


  31       28 27 26 25 24 23 22 21 20 19 18 17 16 15            12 11 10 9 8 7 6 5 4 3                   0
    !=1111     1 1 1 0 1 D 1 1 0 0 1 op                    Vd        1 0 1 sz 1 1 M 0              Vm
     cond                                                                          T


Encoding

Applies when op = 0 && sz = 0.

VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm>


Encoding

Applies when op = 0 && sz = 1.

VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm>


Encoding

Applies when op = 1 && sz = 0.

VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm>


Encoding

Applies when op = 1 && sz = 1.

VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm>


Decode for all variants of this encoding

 uses_double = (sz == ''1''); convert_from_half = (op == ''0'');
 lowbit = (if T == ''1'' then 16 else 0);
 if uses_double then
    if convert_from_half then
         d = UInt(D:Vd); m = UInt(Vm:M);
    else
         d = UInt(Vd:D); m = UInt(M:Vm);
 else
    d = UInt(Vd:D); m = UInt(Vm:M);
        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3               0
            1 1 1 0 1 1 1 0 1 D 1 1 0 0 1 op                      Vd        1 0 1 sz 1 1 M 0          Vm
                                                                                      T


        Encoding

        Applies when op = 0 && sz = 0.

        VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm>


        Encoding

        Applies when op = 0 && sz = 1.

        VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm>


        Encoding

        Applies when op = 1 && sz = 0.

        VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm>


        Encoding

        Applies when op = 1 && sz = 1.

        VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm>


        Decode for all variants of this encoding

         uses_double = (sz == ''1''); convert_from_half = (op == ''0'');
         lowbit = (if T == ''1'' then 16 else 0);
         if uses_double then
               if convert_from_half then
                   d = UInt(D:Vd); m = UInt(Vm:M);
               else
                   d = UInt(Vd:D); m = UInt(M:Vm);
         else
               d = UInt(Vd:D); m = UInt(Vm:M);


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

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

        <Sm>              Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations(); CheckVFPEnabled(TRUE);
               bits(16) hp;
               if convert_from_half then
                   hp = S[m]<lowbit+15:lowbit>;
                   if uses_double then
         D[d] = FPConvert(hp, FPSCR);
      else
         S[d] = FPConvert(hp, FPSCR);
   else
      if uses_double then
         hp = FPConvert(D[m], FPSCR);
      else
         hp = FPConvert(S[m], FPSCR);
      S[d]<lowbit+15:lowbit> = hp;');
INSERT INTO "instructions" VALUES('ARM','VDIV','        Divide divides one floating-point value by another floating-point value and writes the result to a third floating-point       (F8.1.74)
        register.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                    0
              !=1111     1 1 1 0 1 D 0 0             Vn           Vd       1 0 1 sz N 0 M 0               Vm
               cond


        Single-precision scalar variant

        Applies when sz = 0.

        VDIV{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VDIV{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                0 15         12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 0 1 1 1 0 1 D 0 0                  Vn           Vd       1 0 1 sz N 0 M 0               Vm




        Single-precision scalar variant

        Applies when sz = 0.

        VDIV{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VDIV{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

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

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

<Sm>          Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();    CheckVFPEnabled(TRUE);
    if dp_operation then
        D[d] = FPDiv(D[n], D[m], FPSCR);
    else
        S[d] = FPDiv(S[n], S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VDUP','        Duplicate general-purpose register to vector duplicates an element from a general-purpose register into every       (F8.1.75)
        element of the destination vector.

        The destination vector elements can be 8-bit, 16-bit, or 32-bit fields. The source element is the least significant 8,
        16, or 32 bits of the general-purpose register. There is no distinction between data types.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31        28 27 26 25 24 23 22 21 20 19         16 15         12 11 10 9 8 7 6 5 4 3 2 1 0
              !=1111     1 1 1 0 1 B Q 0              Vd            Rt       1 0 1 1 D 0 E 1 (0) (0) (0) (0)
               cond


        A1 variant

        VDUP{<c>}{<q>}.<size> <Qd>, <Rt>// Encoded as Q = 1
        VDUP{<c>}{<q>}.<size> <Dd>, <Rt>// Encoded as Q = 0


        Decode for this encoding

         if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
         d = UInt(D:Vd);     t = UInt(Rt);   regs = if Q == ''0'' then 1 else 2;
         case B:E of
               when ''00''   esize = 32;   elements = 2;
               when ''01''   esize = 16;   elements = 4;
               when ''10''   esize = 8;    elements = 8;
               when ''11''   UNDEFINED;
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
            1 1 1 0 1 1 1 0 1 B Q 0                   Vd            Rt       1 0 1 1 D 0 E 1 (0) (0) (0) (0)




        T1 variant

        VDUP{<c>}{<q>}.<size> <Qd>, <Rt>// Encoded as Q = 1
        VDUP{<c>}{<q>}.<size> <Dd>, <Rt>// Encoded as Q = 0


        Decode for this encoding

         if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
         d = UInt(D:Vd);     t = UInt(Rt);   regs = if Q == ''0'' then 1 else 2;
         case B:E of
               when ''00''   esize = 32;   elements = 2;
               when ''01''   esize = 16;   elements = 4;
               when ''10''   esize = 8;    elements = 8;
               when ''11''   UNDEFINED;
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. ARM strongly recommends that any VDUP
               instruction is unconditional, see Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<size>         The data size for the elements of the destination vector. It must be one of:

               8           Encoded as [b, e] = 0b10.

               16          Encoded as [b, e] = 0b01.

               32          Encoded as [b, e] = 0b00.

<Qd>           The destination vector for a quadword operation.

<Dd>           The destination vector for a doubleword operation.

<Rt>           The ARM source register.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     scalar = R[t]<esize-1:0>;
     for r = 0 to regs-1
         for e = 0 to elements-1
              Elem[D[d+r],e,esize] = scalar;');
INSERT INTO "instructions" VALUES('ARM','VEOR','        Vector Bitwise Exclusive OR performs a bitwise Exclusive OR operation between two registers, and places the       (F8.1.77)
        result in the destination register. The operand and result registers can be quadword or doubleword. They must all be
        the same size.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3              0
            1 1 1 1 0 0 1 1 0 D 0 0                    Vn            Vd       0 0 0 1 N Q M 1           Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VEOR{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VEOR{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         d = UInt(D:Vd);     n = UInt(N:Vn);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3              0
            1 1 1 1 1 1 1 1 0 D 0 0                    Vn            Vd       0 0 0 1 N Q M 1           Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VEOR{<c>}{<q>}{.<dt>} {<Dd>,} <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VEOR{<c>}{<q>}{.<dt>} {<Qd>,} <Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         d = UInt(D:Vd);     n = UInt(N:Vn);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VEOR instruction must be
              unconditional. ARM strongly recommends that a T32 VEOR instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          An optional data type. It is ignored by assemblers, and does not affect the encoding.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();     CheckAdvSIMDEnabled();
    for r = 0 to regs-1
        D[d+r] = D[n+r] EOR D[m+r];');
INSERT INTO "instructions" VALUES('ARM','VEXT','        Vector Extract extracts elements from the bottom end of the second operand vector and the top end of the first,       (F8.1.78)
        concatenates them and places the result in the destination vector.

        The elements of the vectors are treated as being 8-bit fields. There is no distinction between data types.

        The following figure shows an example of the operation of VEXT doubleword operation for imm = 3.
                                                                     7 6 5 4 3 2 1 0                7 6 5 4 3 2 1 0
                                                                Vm                              Vn




                                                                                                Vd

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.

        This instruction is used by the alias VEXT (multibyte elements). See the Alias conditions on page F8-3427 table for
        details of when each alias is preferred.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11         8 7 6 5 4 3              0
            1 1 1 1 0 0 1 0 1 D 1 1                   Vn           Vd          imm4      N Q M 0         Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VEXT{<c>}{<q>}.8 {<Dd>,} <Dn>, <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VEXT{<c>}{<q>}.8 {<Qd>,} <Qn>, <Qm>, #<imm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if Q == ''0'' && imm4<3> == ''1'' then UNDEFINED;
         quadword_operation = (Q == ''1'');      position = 8 * UInt(imm4);
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11         8 7 6 5 4 3              0
            1 1 1 0 1 1 1 1 1 D 1 1                   Vn           Vd          imm4      N Q M 0         Vm
64-bit SIMD vector variant

Applies when Q = 0.

VEXT{<c>}{<q>}.8 {<Dd>,} <Dn>, <Dm>, #<imm>


128-bit SIMD vector variant

Applies when Q = 1.

VEXT{<c>}{<q>}.8 {<Qd>,} <Qn>, <Qm>, #<imm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if Q == ''0'' && imm4<3> == ''1'' then UNDEFINED;
 quadword_operation = (Q == ''1'');   position = 8 * UInt(imm4);
 d = UInt(D:Vd);  n = UInt(N:Vn);   m = UInt(M:Vm);


Alias conditions


            Alias                            is preferred when

            VEXT (multibyte elements)        Never



Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VEXT instruction must be
              unconditional. ARM strongly recommends that a T32 VEXT instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         For the 64-bit SIMD vector variant: is the location of the extracted result in the concatenation of the
              operands, as a number of bytes from the least significant end, in the range 0 to 7, encoded in the
              "imm4" field.

              For the 128-bit SIMD vector variant: is the location of the extracted result in the concatenation of
              the operands, as a number of bytes from the least significant end, in the range 0 to 15, encoded in
              the "imm4" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();   CheckAdvSIMDEnabled();
     if quadword_operation then
         Q[d>>1] = (Q[m>>1]:Q[n>>1])<position+127:position>;
     else
         D[d] = (D[m]:D[n])<position+63:position>;');
INSERT INTO "instructions" VALUES('ARM','VFMA','        Vector Fused Multiply Accumulate multiplies corresponding elements of two vectors, and accumulates the results       (F8.1.80)
        into the elements of the destination vector. The instruction does not round the result of the multiply before the
        accumulation.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 0 0 D 0 0                   Vn           Vd      1 1 0 0 N Q M 1               Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         advsimd = TRUE; op1_neg = (op == ''1''); esize = 32; elements = 2;
         d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm);
         regs = if Q == ''0'' then 1 else 2;


        A2


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                  0
              !=1111     1 1 1 0 1 D 1 0              Vn           Vd      1 0 1 sz N 0 M 0              Vm
               cond                                                                        op


        Single-precision scalar variant

        Applies when sz = 0.

        VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>
Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE; dp_operation = (sz == ''1''); op1_neg = (op == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 0 1 1 1 1 0 D 0 0                Vn          Vd         1 1 0 0 N Q M 1             Vm
                               op sz


64-bit SIMD vector variant

Applies when Q = 0.

VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 advsimd = TRUE; op1_neg = (op == ''1''); esize = 32; elements = 2;
 d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm);
 regs = if Q == ''0'' then 1 else 2;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 0 1 1 1 0 1 D 1 0                Vn          Vd         1 0 1 sz N 0 M 0            Vm
                                                                                op


Single-precision scalar variant

Applies when sz = 0.

VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE; dp_operation = (sz == ''1''); op1_neg = (op == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
        Assembler symbols

        <c>               For encoding A1, A2 and T1: see Standard assembler syntax fields on page F2-2506. An A32
                          Advanced SIMD VFMA or VMFS instruction must be unconditional. ARM strongly recommends that a
                          T32 Advanced SIMD VFMA or VMFS instruction is unconditional, see Conditional execution on
                          page F2-2507.

                          For encoding T2: see Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
               if advsimd then // Advanced SIMD instruction
                   for r = 0 to regs-1
                        for e = 0 to elements-1
                             bits(esize) op1 = Elem[D[n+r],e,esize];
                             if op1_neg then op1 = FPNeg(op1);
                             Elem[D[d+r],e,esize] = FPMulAdd(Elem[D[d+r],e,esize],
                                                      op1, Elem[D[m+r],e,esize], StandardFPSCRValue());

               else // VFP instruction
                   if dp_operation then
                        op64 = if op1_neg then FPNeg(D[n]) else D[n];
                        D[d] = FPMulAdd(D[d], op64, D[m], FPSCR);
                   else
                        op32 = if op1_neg then FPNeg(S[n]) else S[n];
                        S[d] = FPMulAdd(S[d], op32, S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VFMS','Vector Fused Multiply Subtract negates the elements of one vector and multiplies them with the corresponding       (F8.1.81)
elements of another vector, adds the products to the corresponding elements of the destination vector, and places the
results in the destination vector. The instruction does not round the result of the multiply before the addition.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19            16 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 0 0 D 1 0                     Vn           Vd        1 1 0 0 N Q M 1              Vm
                                   op sz


64-bit SIMD vector variant

Applies when Q = 0.

VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 advsimd = TRUE; op1_neg = (op == ''1''); esize = 32; elements = 2;
 d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm);
 regs = if Q == ''0'' then 1 else 2;


A2


  31        28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
     !=1111     1 1 1 0 1 D 1 0                Vn           Vd        1 0 1 sz N 1 M 0             Vm
      cond                                                                             op


Single-precision scalar variant

Applies when sz = 0.

VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>
        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE; dp_operation = (sz == ''1''); op1_neg = (op == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3              0 15          12 11 10 9 8 7 6 5 4 3   0
            1 1 1 0 1 1 1 1 0 D 1 0                  Vn         Vd         1 1 0 0 N Q M 1   Vm
                                         op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         advsimd = TRUE; op1_neg = (op == ''1''); esize = 32; elements = 2;
         d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm);
         regs = if Q == ''0'' then 1 else 2;


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3              0 15          12 11 10 9 8 7 6 5 4 3   0
            1 1 1 0 1 1 1 0 1 D 1 0                  Vn         Vd         1 0 1 sz N 1 M 0  Vm
                                                                                     op


        Single-precision scalar variant

        Applies when sz = 0.

        VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE; dp_operation = (sz == ''1''); op1_neg = (op == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
Assembler symbols

<c>           For encoding A1, A2 and T1: see Standard assembler syntax fields on page F2-2506. An A32
              Advanced SIMD VFMA or VMFS instruction must be unconditional. ARM strongly recommends that a
              T32 Advanced SIMD VFMA or VMFS instruction is unconditional, see Conditional execution on
              page F2-2507.

              For encoding T2: see Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

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

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

<Sm>          Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();     CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
    if advsimd then // Advanced SIMD instruction
        for r = 0 to regs-1
            for e = 0 to elements-1
                 bits(esize) op1 = Elem[D[n+r],e,esize];
                 if op1_neg then op1 = FPNeg(op1);
                 Elem[D[d+r],e,esize] = FPMulAdd(Elem[D[d+r],e,esize],
                                          op1, Elem[D[m+r],e,esize], StandardFPSCRValue());

    else // VFP instruction
        if dp_operation then
            op64 = if op1_neg then FPNeg(D[n]) else D[n];
            D[d] = FPMulAdd(D[d], op64, D[m], FPSCR);
        else
            op32 = if op1_neg then FPNeg(S[n]) else S[n];
            S[d] = FPMulAdd(S[d], op32, S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VFNMA','        Vector Fused Negate Multiply Accumulate negates one floating-point register value and multiplies it by another       (F8.1.82)
        floating-point register value, adds the negation of the floating-point value in the destination register to the product,
        and writes the result back to the destination register. The instruction does not round the result of the multiply before
        the addition.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                  0
              !=1111     1 1 1 0 1 D 0 1               Vn            Vd       1 0 1 sz N 1 M 0              Vm
               cond                                                                          op


        Single-precision scalar variant

        Applies when sz = 0.

        VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         op1_neg = (op == ''1'');
         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 0 1 1 1 0 1 D 0 1                    Vn            Vd       1 0 1 sz N 1 M 0              Vm
                                                                                             op


        Single-precision scalar variant

        Applies when sz = 0.

        VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         op1_neg = (op == ''1'');
         dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

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

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

<Sm>          Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations(); CheckVFPEnabled(TRUE);
     if dp_operation then
        op64 = if op1_neg then FPNeg(D[n]) else D[n];
        D[d] = FPMulAdd(FPNeg(D[d]), op64, D[m], FPSCR);
     else
        op32 = if op1_neg then FPNeg(S[n]) else S[n];
        S[d] = FPMulAdd(FPNeg(S[d]), op32, S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VFNMS','        Vector Fused Negate Multiply Subtract multiplies together two floating-point register values, adds the negation of       (F8.1.83)
        the floating-point value in the destination register to the product, and writes the result back to the destination
        register. The instruction does not round the result of the multiply before the addition.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3                   0
              !=1111     1 1 1 0 1 D 0 1              Vn            Vd       1 0 1 sz N 0 M 0               Vm
               cond                                                                          op


        Single-precision scalar variant

        Applies when sz = 0.

        VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         op1_neg = (op == ''1'');
         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 0 1 1 1 0 1 D 0 1                   Vn            Vd       1 0 1 sz N 0 M 0               Vm
                                                                                             op


        Single-precision scalar variant

        Applies when sz = 0.

        VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         op1_neg = (op == ''1'');
         dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

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

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

<Sm>          Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations(); CheckVFPEnabled(TRUE);
     if dp_operation then
        op64 = if op1_neg then FPNeg(D[n]) else D[n];
        D[d] = FPMulAdd(FPNeg(D[d]), op64, D[m], FPSCR);
     else
        op32 = if op1_neg then FPNeg(S[n]) else S[n];
        S[d] = FPMulAdd(FPNeg(S[d]), op32, S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VHADD','        Vector Halving Add adds corresponding elements in two vectors of integers, shifts each result right one bit, and       (F8.1.84)
        places the final results in the destination vector. The results of the halving operations are truncated. For rounded
        results, see VRHADD.

        The operand and result elements are all the same type, and can be any one of:

        .       8-bit, 16-bit, or 32-bit signed integers.

        .       8-bit, 16-bit, or 32-bit unsigned integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15         12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 1 0 0 1 U 0 D size                    Vn          Vd        0 0 0 0 N Q M 0              Vm
                                                                                    op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VHADD{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VHADD{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size == ''11'' then UNDEFINED;
         add = (op == ''0'');       unsigned = (U == ''1'');
         esize = 8 << UInt(size);        elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);    m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 U 1 1 1 1 0 D size                    Vn          Vd        0 0 0 0 N Q M 0              Vm
                                                                                    op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VHADD{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VHADD{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size == ''11'' then UNDEFINED;
 add = (op == ''0'');  unsigned = (U == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VHADD or VHSUB instruction must be
              unconditional. ARM strongly recommends that a T32 VHADD or VHSUB instruction is unconditional,
              see Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "U:size" field. It can have the
              following values:

              S8           when U = 0, size = 00

              S16          when U = 0, size = 01

              S32          when U = 0, size = 10

              U8           when U = 1, size = 00

              U16          when U = 1, size = 01

              U32          when U = 1, size = 10

              It is RESERVED when:

              .      U = 0, size = 11.

              .      U = 1, size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             op1 = Int(Elem[D[n+r],e,esize], unsigned);
             op2 = Int(Elem[D[m+r],e,esize], unsigned);
             result = if add then op1+op2 else op1-op2;
             Elem[D[d+r],e,esize] = result<esize:1>;');
INSERT INTO "instructions" VALUES('ARM','VHSUB','        Vector Halving Subtract subtracts the elements of the second operand from the corresponding elements of the first       (F8.1.85)
        operand, shifts each result right one bit, and places the final results in the destination vector. The results of the
        halving operations are truncated. There is no rounding version.

        The operand and result elements are all the same type, and can be any one of:

        .       8-bit, 16-bit, or 32-bit signed integers.

        .       8-bit, 16-bit, or 32-bit unsigned integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 0 0 1 U 0 D size                    Vn          Vd        0 0 1 0 N Q M 0               Vm
                                                                                    op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VHSUB{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VHSUB{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size == ''11'' then UNDEFINED;
         add = (op == ''0'');       unsigned = (U == ''1'');
         esize = 8 << UInt(size);        elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);    m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15         12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 U 1 1 1 1 0 D size                    Vn          Vd        0 0 1 0 N Q M 0               Vm
                                                                                    op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VHSUB{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VHSUB{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size == ''11'' then UNDEFINED;
 add = (op == ''0'');  unsigned = (U == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VHADD or VHSUB instruction must be
              unconditional. ARM strongly recommends that a T32 VHADD or VHSUB instruction is unconditional,
              see Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "U:size" field. It can have the
              following values:

              S8           when U = 0, size = 00

              S16          when U = 0, size = 01

              S32          when U = 0, size = 10

              U8           when U = 1, size = 00

              U16          when U = 1, size = 01

              U32          when U = 1, size = 10

              It is RESERVED when:

              .      U = 0, size = 11.

              .      U = 1, size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             op1 = Int(Elem[D[n+r],e,esize], unsigned);
             op2 = Int(Elem[D[m+r],e,esize], unsigned);
             result = if add then op1+op2 else op1-op2;
             Elem[D[d+r],e,esize] = result<esize:1>;');
INSERT INTO "instructions" VALUES('ARM','VLD1','        Load single 1-element structure to one lane of one register loads one element from memory into one element of a       (F8.1.86)
        register. Elements of the register that are not loaded are unchanged. For details of the addressing mode see Advanced
        SIMD addressing mode on page F5-2605.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19            16 15       12 11 10 9 8 7              4 3         0
            1 1 1 1 0 1 0 0 1 D 1 0                      Rn          Vd      !=11 0 0 index_align           Rm
                                                                             size


        Offset variant

        Applies when Rm = 1111.

        VLD1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


        Post-indexed variant

        Applies when Rm = 1101.

        VLD1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VLD1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then SEE VLD1 (single element to all lanes);
         case size of
               when ''00''
                   if index_align<0> != ''0'' then UNDEFINED;
                   ebytes = 1;   index = UInt(index_align<3:1>);       alignment = 1;
               when ''01''
                   if index_align<1> != ''0'' then UNDEFINED;
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   alignment = if index_align<0> == ''0'' then 1 else 2;
               when ''10''
                   if index_align<2> != ''0'' then UNDEFINED;
                   if index_align<1:0> != ''00'' && index_align<1:0> != ''11'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   alignment = if index_align<1:0> == ''00'' then 1 else 4;
         d = UInt(D:Vd);     n = UInt(Rn);    m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7              4 3         0
            1 1 1 1 1 0 0 1 1 D 1 0                      Rn          Vd      !=11 0 0 index_align           Rm
                                                                             size
Offset variant

Applies when Rm = 1111.

VLD1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


Post-indexed variant

Applies when Rm = 1101.

VLD1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


Post-indexed variant

Applies when Rm != 11x1.

VLD1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then SEE VLD1 (single element to all lanes);
 case size of
     when ''00''
         if index_align<0> != ''0'' then UNDEFINED;
         ebytes = 1;   index = UInt(index_align<3:1>);     alignment = 1;
     when ''01''
         if index_align<1> != ''0'' then UNDEFINED;
         ebytes = 2;   index = UInt(index_align<3:2>);
         alignment = if index_align<0> == ''0'' then 1 else 2;
     when ''10''
         if index_align<2> != ''0'' then UNDEFINED;
         if index_align<1:0> != ''00'' && index_align<1:0> != ''11'' then UNDEFINED;
         ebytes = 4;   index = UInt(index_align<3>);
         alignment = if index_align<1:0> == ''00'' then 1 else 4;
 d = UInt(D:Vd);  n = UInt(Rn);    m = UInt(Rm);
 wback = (m != 15);   register_index = (m != 15 && m != 13);
 if n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 VLD1 instruction must be
               unconditional. ARM strongly recommends that a T32 VLD1 instruction is unconditional, see
               Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<size>         The data size. It must be one of:

               8           Encoded as size = 0b00.

               16          Encoded as size = 0b01.

               32          Encoded as size = 0b10.

<list>         The register containing the element to load. It must be {<Dd[x]>}. The register <Dd> is encoded in
               D:Vd.

<Rn>           Contains the base address for the access.

<align>        The alignment. It can be one of:

               16          2-byte alignment, available only if <size> is 16.
                          32           4-byte alignment, available only if <size> is 32.

                          omitted      Standard alignment, see Unaligned data access on page E2-2427.

                          : is the preferred separator before the <align> value, but the alignment can be specified as @<align>,
                          see Advanced SIMD addressing mode on page F5-2605.

        <Rm>              Contains an address offset applied after the access.

        For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

        Table F8-1 shows the encoding of index and alignment for the different <size> values.

                                                                          Table F8-1 Encoding of index and alignment

                                              <size> == 8              <size> == 16                 <size> == 32

                         Index                index_align[3:1] = x     index_align[3:2] = x         index_align[3] = x

                         <align> omitted      index_align[0] = 0       index_align[1:0] = ''00''      index_align[2:0] = ''000''

                         <align> == 16        -                        index_align[1:0] = ''01''      -

                         <align> == 32        -                        -                            index_align[2:0] = ''011''



        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               address = R[n];     if (address MOD alignment) != 0 then GenerateAlignmentException();
               if wback then
                   if register_index then
                        R[n] = R[n] + R[m];
                   else
                        R[n] = R[n] + ebytes;
               Elem[D[d],index] = MemU[address,ebytes];');
INSERT INTO "instructions" VALUES('ARM','VLD2','Load single 2-element structure to one lane of two registers loads one 2-element structure from memory into       (F8.1.89)
corresponding elements of two registers. Elements of the registers that are not loaded are unchanged. For details of
the addressing mode see Advanced SIMD addressing mode on page F5-2605.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7               4 3       0
   1 1 1 1 0 1 0 0 1 D 1 0                    Rn           Vd       !=11 0 1 index_align         Rm
                                                                    size


Offset variant

Applies when Rm = 1111.

VLD2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


Post-indexed variant

Applies when Rm = 1101.

VLD2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


Post-indexed variant

Applies when Rm != 11x1.

VLD2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then SEE VLD2 (single 2-element structure to all lanes);
 case size of
      when ''00''
           ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
           alignment = if index_align<0> == ''0'' then 1 else 2;
      when ''01''
           ebytes = 2;   index = UInt(index_align<3:2>);
           inc = if index_align<1> == ''0'' then 1 else 2;
           alignment = if index_align<0> == ''0'' then 1 else 4;
      when ''10''
           if index_align<1> != ''0'' then UNDEFINED;
           ebytes = 4;   index = UInt(index_align<3>);
           inc = if index_align<2> == ''0'' then 1 else 2;
           alignment = if index_align<0> == ''0'' then 1 else 8;
 d = UInt(D:Vd);    d2 = d + inc;    n = UInt(Rn);   m = UInt(Rm);
 wback = (m != 15);     register_index = (m != 15 && m != 13);
 if n == 15 || d2 > 31 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7               4 3       0
   1 1 1 1 1 0 0 1 1 D 1 0                    Rn           Vd       !=11 0 1 index_align         Rm
                                                                    size
        Offset variant

        Applies when Rm = 1111.

        VLD2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


        Post-indexed variant

        Applies when Rm = 1101.

        VLD2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VLD2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then SEE VLD2 (single 2-element structure to all lanes);
         case size of
               when ''00''
                   ebytes = 1;   index = UInt(index_align<3:1>);      inc = 1;
                   alignment = if index_align<0> == ''0'' then 1 else 2;
               when ''01''
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   inc = if index_align<1> == ''0'' then 1 else 2;
                   alignment = if index_align<0> == ''0'' then 1 else 4;
               when ''10''
                   if index_align<1> != ''0'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   inc = if index_align<2> == ''0'' then 1 else 2;
                   alignment = if index_align<0> == ''0'' then 1 else 8;
         d = UInt(D:Vd);     d2 = d + inc;    n = UInt(Rn);   m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 || d2 > 31 then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VLD2 (single 2-element structure to
        one lane) on page J1-5385.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VLD2 instruction must be
                          unconditional. ARM strongly recommends that a T32 VLD2 instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <size>            The data size. It must be one of:

                          8          Encoded as size = 0b00.

                          16         Encoded as size = 0b01.

                          32         Encoded as size = 0b10.

        <list>            The registers containing the structure. Encoded with D:Vd = <Dd>. It must be one of:

                          {<Dd[x]>, <Dd+1[x]>}
                                     Single-spaced registers, see Table F8-2 on page F8-3455.

                          {<Dd[x]>, <Dd+2[x]>}
                                     Double-spaced registers, see Table F8-2 on page F8-3455.
              This is not available if <size> == 8.

<Rn>          Contains the base address for the access.

<align>       The alignment. It can be one of:

              16            2-byte alignment, available only if <size> is 8.

              32            4-byte alignment, available only if <size> is 16.

              64            8-byte alignment, available only if <size> is 32.

              omitted       Standard alignment, see Unaligned data access on page E2-2427.

               : is the preferred separator before the <align> value, but the alignment can be specified as @<align>,
              see Advanced SIMD addressing mode on page F5-2605.

<Rm>          Contains an address offset applied after the access.

For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

                                         Table F8-2 Encoding of index, alignment, and register spacing

                                       <size> == 8              <size> == 16               <size> == 32

                  Index                index_align[3:1] = x     index_align[3:2] = x       index_align[3] = x

                  Single-spacing       -                        index_align[1] = 0         index_align[2] = 0

                  Double-spacing       -                        index_align[1] = 1         index_align[2] = 1

                  <align> omitted      index_align[0] = 0       index_align[0] = 0         index_align[1:0] = ''00''

                  <align> == 16        index_align[0] = 1       -                          -

                  <align> == 32        -                        index_align[0] = 1         -

                  <align> == 64        -                        -                          index_align[1:0] = ''01''



Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();      CheckAdvSIMDEnabled();
    address = R[n];     if (address MOD alignment) != 0 then GenerateAlignmentException();
    if wback then
        if register_index then
             R[n] = R[n] + R[m];
        else
             R[n] = R[n] + 2*ebytes;
    Elem[D[d], index] = MemU[address,ebytes];
    Elem[D[d2],index] = MemU[address+ebytes,ebytes];');
INSERT INTO "instructions" VALUES('ARM','VLD3','        Load single 3-element structure to one lane of three registers loads one 3-element structure from memory into       (F8.1.92)
        corresponding elements of three registers. Elements of the registers that are not loaded are unchanged. For details
        of the addressing mode see Advanced SIMD addressing mode on page F5-2605.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7           4 3         0
            1 1 1 1 0 1 0 0 1 D 1 0                   Rn           Vd      !=11 1 0 index_align         Rm
                                                                           size


        Offset variant

        Applies when Rm = 1111.

        VLD3{<c>}{<q>}.<size> <list>, [<Rn>]


        Post-indexed variant

        Applies when Rm = 1101.

        VLD3{<c>}{<q>}.<size> <list>, [<Rn>]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VLD3{<c>}{<q>}.<size> <list>, [<Rn>], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then SEE VLD3 (single 3-element structure to all lanes);
         case size of
               when ''00''
                   if index_align<0> != ''0'' then UNDEFINED;
                   ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
               when ''01''
                   if index_align<0> != ''0'' then UNDEFINED;
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   inc = if index_align<1> == ''0'' then 1 else 2;
               when ''10''
                   if index_align<1:0> != ''00'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   inc = if index_align<2> == ''0'' then 1 else 2;
         d = UInt(D:Vd);     d2 = d + inc;   d3 = d2 + inc;   n = UInt(Rn);   m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 || d3 > 31 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7           4 3         0
            1 1 1 1 1 0 0 1 1 D 1 0                   Rn           Vd      !=11 1 0 index_align         Rm
                                                                           size
Offset variant

Applies when Rm = 1111.

VLD3{<c>}{<q>}.<size> <list>, [<Rn>]


Post-indexed variant

Applies when Rm = 1101.

VLD3{<c>}{<q>}.<size> <list>, [<Rn>]!


Post-indexed variant

Applies when Rm != 11x1.

VLD3{<c>}{<q>}.<size> <list>, [<Rn>], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then SEE VLD3 (single 3-element structure to all lanes);
 case size of
     when ''00''
         if index_align<0> != ''0'' then UNDEFINED;
         ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
     when ''01''
         if index_align<0> != ''0'' then UNDEFINED;
         ebytes = 2;   index = UInt(index_align<3:2>);
         inc = if index_align<1> == ''0'' then 1 else 2;
     when ''10''
         if index_align<1:0> != ''00'' then UNDEFINED;
         ebytes = 4;   index = UInt(index_align<3>);
         inc = if index_align<2> == ''0'' then 1 else 2;
 d = UInt(D:Vd);  d2 = d + inc;    d3 = d2 + inc;    n = UInt(Rn);     m = UInt(Rm);
 wback = (m != 15);   register_index = (m != 15 && m != 13);
 if n == 15 || d3 > 31 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly VLD3 (single 3-element structure to
one lane) on page J1-5386.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 VLD3 instruction must be
               unconditional. ARM strongly recommends that a T32 VLD3 instruction is unconditional, see
               Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<size>         The data size. It must be one of:

               8           Encoded as size = 0b00.

               16          Encoded as size = 0b01.

               32          Encoded as size = 0b10.

<list>         The registers containing the structure. Encoded with D:Vd = <Dd>. It must be one of:

               {<Dd[x]>, <Dd+1[x]>, <Dd+2[x]>}
                           Single-spaced registers, see Table F8-3 on page F8-3464.

               {<Dd[x]>, <Dd+2[x]>, <Dd+4[x]>}
                           Double-spaced registers, see Table F8-3 on page F8-3464.

               This is not available if <size> == 8.
        <Rn>              Contains the base address for the access.

        <Rm>              Contains an address offset applied after the access.

        For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

                                                                 Table F8-3 Encoding of index and register spacing

                                            <size> == 8               <size> == 16            <size> == 32

                         Index              index_align[3:1] = x      index_align[3:2] = x    index_align[3] = x

                         Single-spacing     index_align[0] = 0        index_align[1:0] = ''00'' index_align[2:0] = ''000''

                         Double-spacing     -                         index_align[1:0] = ''10'' index_align[2:0] = ''100''



        Alignment

        Standard alignment rules apply, see Alignment support on page B2-75.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();    CheckAdvSIMDEnabled();
               address = R[n];
               if wback then
                   if register_index then
                        R[n] = R[n] + R[m];
                   else
                        R[n] = R[n] + 3*ebytes;
               Elem[D[d], index] = MemU[address,ebytes];
               Elem[D[d2],index] = MemU[address+ebytes,ebytes];
               Elem[D[d3],index] = MemU[address+2*ebytes,ebytes];');
INSERT INTO "instructions" VALUES('ARM','VLD4','Load single 4-element structure to one lane of four registers loads one 4-element structure from memory into       (F8.1.95)
corresponding elements of four registers. Elements of the registers that are not loaded are unchanged. For details of
the addressing mode see Advanced SIMD addressing mode on page F5-2605.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7               4 3         0
   1 1 1 1 0 1 0 0 1 D 1 0                    Rn           Vd       !=11 1 1 index_align          Rm
                                                                    size


Offset variant

Applies when Rm = 1111.

VLD4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


Post-indexed variant

Applies when Rm = 1101.

VLD4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


Post-indexed variant

Applies when Rm != 11x1.

VLD4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then SEE VLD4 (single 4-element structure to all lanes);
 case size of
      when ''00''
           ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
           alignment = if index_align<0> == ''0'' then 1 else 4;
      when ''01''
           ebytes = 2;   index = UInt(index_align<3:2>);
           inc = if index_align<1> == ''0'' then 1 else 2;
           alignment = if index_align<0> == ''0'' then 1 else 8;
      when ''10''
           if index_align<1:0> == ''11'' then UNDEFINED;
           ebytes = 4;   index = UInt(index_align<3>);
           inc = if index_align<2> == ''0'' then 1 else 2;
           alignment = if index_align<1:0> == ''00'' then 1 else 4 << UInt(index_align<1:0>);
 d = UInt(D:Vd);    d2 = d + inc;    d3 = d2 + inc;   d4 = d3 + inc;      n = UInt(Rn);    m = UInt(Rm);
 wback = (m != 15);     register_index = (m != 15 && m != 13);
 if n == 15 || d4 > 31 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7               4 3         0
   1 1 1 1 1 0 0 1 1 D 1 0                    Rn           Vd       !=11 1 1 index_align          Rm
                                                                    size
        Offset variant

        Applies when Rm = 1111.

        VLD4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


        Post-indexed variant

        Applies when Rm = 1101.

        VLD4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VLD4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then SEE VLD4 (single 4-element structure to all lanes);
         case size of
               when ''00''
                   ebytes = 1;   index = UInt(index_align<3:1>);      inc = 1;
                   alignment = if index_align<0> == ''0'' then 1 else 4;
               when ''01''
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   inc = if index_align<1> == ''0'' then 1 else 2;
                   alignment = if index_align<0> == ''0'' then 1 else 8;
               when ''10''
                   if index_align<1:0> == ''11'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   inc = if index_align<2> == ''0'' then 1 else 2;
                   alignment = if index_align<1:0> == ''00'' then 1 else 4 << UInt(index_align<1:0>);
         d = UInt(D:Vd);     d2 = d + inc;    d3 = d2 + inc;    d4 = d3 + inc; n = UInt(Rn);   m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 || d4 > 31 then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VLD4 (single 4-element structure to
        one lane) on page J1-5387.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VLD4 instruction must be
                          unconditional. ARM strongly recommends that a T32 VLD4 instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <size>            The data size. It must be one of:

                          8          Encoded as size = 0b00.

                          16         Encoded as size = 0b01.

                          32         Encoded as size = 0b10.

        <list>            The registers containing the structure. Encoded with D:Vd = <Dd>. It must be one of:

                          {<Dd[x]>, <Dd+1[x]>, <Dd+2[x]>, <Dd+3[x]>}
                                     Single-spaced registers, see Table F8-4 on page F8-3473.

                          {<Dd[x]>, <Dd+2[x]>, <Dd+4[x]>, <Dd+6[x]>}
                                     Double-spaced registers, see Table F8-4 on page F8-3473.
               Not available if <size> == 8.

<Rn>          The base address for the access.

<align>       The alignment. It can be:

              32            4-byte alignment, available only if <size> is 8.

              64            8-byte alignment, available only if <size> is 16 or 32.

              128           16-byte alignment, available only if <size> is 32.

              omitted       Standard alignment, see Unaligned data access on page E2-2427.

               : is the preferred separator before the <align> value, but the alignment can be specified as @<align>,
              see Advanced SIMD addressing mode on page F5-2605.

<Rm>          Contains an address offset applied after the access.

For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

                                         Table F8-4 Encoding of index, alignment, and register spacing

                                       <size> == 8              <size> == 16               <size> == 32

                  Index                index_align[3:1] = x     index_align[3:2] = x       index_align[3] = x

                  Single-spacing       -                        index_align[1] = 0         index_align[2] = 0

                  Double-spacing       -                        index_align[1] = 1         index_align[2] = 1

                  <align> omitted      index_align[0] = 0       index_align[0] = 0         index_align[1:0] = ''00''

                  <align> == 32        index_align[0] = 1       -                          -

                  <align> == 64        -                        index_align[0] = 1         index_align[1:0] = ''01''

                  <align> == 128       -                        -                          index_align[1:0] = ''10''



Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();      CheckAdvSIMDEnabled();
    address = R[n];     if (address MOD alignment) != 0 then GenerateAlignmentException();
    if wback then
        if register_index then
             R[n] = R[n] + R[m];
        else
             R[n] = R[n] + 4*ebytes;
    Elem[D[d], index] = MemU[address,ebytes];
    Elem[D[d2],index] = MemU[address+ebytes,ebytes];
    Elem[D[d3],index] = MemU[address+2*ebytes,ebytes];
    Elem[D[d4],index] = MemU[address+3*ebytes,ebytes];');
INSERT INTO "instructions" VALUES('ARM','VLDM','        Load Multiple SIMD&FP registers loads multiple registers from consecutive locations in the Advanced SIMD and       (F8.1.98)
        floating-point register file using an address from a general-purpose register.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        This instruction is used by the aliases FLDMDBX, FLDMIAX, and VPOP. See the Alias conditions on
        page F8-3482 table for details of when each alias is preferred.


        A1


           31        28 27 26 25 24 23 22 21 20 19         16 15       12 11 10 9 8 7                       0
              !=1111     1 1 0 P U D W 1               Rn          Vd      1 0 1 1              imm8
               cond


        Decrement Before variant

        Applies when P = 1 && U = 0 && W = 1.

        VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist>


        Increment After variant

        Applies when P = 0 && U = 1.

        VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>
        VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>


        Decode for all variants of this encoding

         if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
         if P == ''1'' && W == ''0'' then SEE VLDR;
         if P == U && W == ''1'' then UNDEFINED;
         // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
         single_regs = FALSE;      add = (U == ''1'');    wback = (W == ''1'');
         d = UInt(D:Vd);     n = UInt(Rn);    imm32 = ZeroExtend(imm8:''00'', 32);
         regs = UInt(imm8) DIV 2;      // If UInt(imm8) is odd, see "FLDMX".
         if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
         if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
         if imm8<0> == ''1'' && (d+regs) > 16 then UNPREDICTABLE;


        A2


           31        28 27 26 25 24 23 22 21 20 19         16 15       12 11 10 9 8 7                       0
              !=1111     1 1 0 P U D W 1               Rn          Vd      1 0 1 0              imm8
               cond


        Decrement Before variant

        Applies when P = 1 && U = 0 && W = 1.

        VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist>


        Increment After variant

        Applies when P = 0 && U = 1.

        VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
        VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
Decode for all variants of this encoding

 if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
 if P == ''1'' && W == ''0'' then SEE VLDR;
 if P == U && W == ''1'' then UNDEFINED;
 // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
 single_regs = TRUE;  add = (U == ''1'');  wback = (W == ''1'');     d = UInt(Vd:D);    n = UInt(Rn);
 imm32 = ZeroExtend(imm8:''00'', 32);  regs = UInt(imm8);
 if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
 if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7                        0
  1 1 1 0 1 1 0 P U D W 1                Rn          Vd         1 0 1 1               imm8




Decrement Before variant

Applies when P = 1 && U = 0 && W = 1.

VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist>


Increment After variant

Applies when P = 0 && U = 1.

VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>
VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>


Decode for all variants of this encoding

 if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
 if P == ''1'' && W == ''0'' then SEE VLDR;
 if P == U && W == ''1'' then UNDEFINED;
 // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
 single_regs = FALSE;  add = (U == ''1'');  wback = (W == ''1'');
 d = UInt(D:Vd);  n = UInt(Rn);  imm32 = ZeroExtend(imm8:''00'', 32);
 regs = UInt(imm8) DIV 2;  // If UInt(imm8) is odd, see "FLDMX".
 if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
 if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
 if imm8<0> == ''1'' && (d+regs) > 16 then UNPREDICTABLE;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7                        0
  1 1 1 0 1 1 0 P U D W 1                Rn          Vd         1 0 1 0               imm8




Decrement Before variant

Applies when P = 1 && U = 0 && W = 1.

VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist>


Increment After variant

Applies when P = 0 && U = 1.

VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
VLDMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
        Decode for all variants of this encoding

         if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
         if P == ''1'' && W == ''0'' then SEE VLDR;
         if P == U && W == ''1'' then UNDEFINED;
         // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
         single_regs = TRUE;       add = (U == ''1'');     wback = (W == ''1'');      d = UInt(Vd:D);     n = UInt(Rn);
         imm32 = ZeroExtend(imm8:''00'', 32);          regs = UInt(imm8);
         if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
         if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VLDM on page J1-5388.

        Related encodings: 64-bit transfers accessing the SIMD and floating-point register file on page F5-2607.


        Alias conditions


                               Alias                     is preferred when

                               FLDMDBX                   P == ''1'' && U == ''0'' && imm8<0> == ''1''

                               FLDMIAX                   P == ''0'' && U == ''1'' && imm8<0> == ''1''

                               VPOP                      P == ''0'' && U == ''1'' && W == ''1'' && Rn == ''1101''



        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <size>            An optional data size specifier. If present, it must be equal to the size in bits, 32 or 64, of the registers
                          being transferred.

        <Rn>              For encoding A1 and A2: is the general-purpose base register, encoded in the "Rn" field. If
                          writeback is not specified, the PC can be used.

                          For encoding T1 and T2: is the general-purpose base register, encoded in the "Rn" field.

        !                 Specifies base register writeback. Encoded in the "W" field as 1 if present, otherwise 0.

        <sreglist>        Is the list of consecutively numbered 32-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "Vd:D", and "imm8" is set to the number of registers in the list. The list must
                          contain at least one register.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list. The
                          list must contain at least one register, and must not contain more than 16 registers.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();        CheckVFPEnabled(TRUE);
               address = if add then R[n] else R[n]-imm32;
               if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
               for r = 0 to regs-1
                   if single_regs then
                        S[d+r] = MemA[address,4];       address = address+4;
                   else
   word1 = MemA[address,4];  word2 = MemA[address+4,4];      address = address+8;
   // Combine the word-aligned words in the correct order for current endianness.
   D[d+r] = if BigEndian() then word1:word2 else word2:word1;');
INSERT INTO "instructions" VALUES('ARM','VLDMDB','-R:VLDM');
INSERT INTO "instructions" VALUES('ARM','VLDMIA','-R:VLDM');
INSERT INTO "instructions" VALUES('ARM','VLDR','        Load SIMD&FP register loads a single register from the Advanced SIMD and floating-point register file, using an       (F8.1.99)
        address from a general-purpose register, with an optional offset.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7                       0
              !=1111     1 1 0 1 U D 0 1             Rn           Vd       1 0 1 1             imm8
               cond


        Literal variant

        Applies when Rn = 1111.

        VLDR{<c>}{<q>}{.64} <Dd>, <label>
        VLDR{<c>}{<q>}{.64} <Dd>, [PC, #{+/-}<imm>]


        Offset variant

        Applies when Rn != 1111.

        VLDR{<c>}{<q>}{.64} <Dd>, [<Rn> {, #{+/-}<imm>}]


        Decode for all variants of this encoding

         single_reg = FALSE;     add = (U == ''1'');   imm32 = ZeroExtend(imm8:''00'', 32);
         d = UInt(D:Vd);     n = UInt(Rn);


        A2


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7                       0
              !=1111     1 1 0 1 U D 0 1             Rn           Vd       1 0 1 0             imm8
               cond


        Literal variant

        Applies when Rn = 1111.

        VLDR{<c>}{<q>}{.32} <Sd>, <label>
        VLDR{<c>}{<q>}{.32} <Sd>, [PC, #{+/-}<imm>]


        Offset variant

        Applies when Rn != 1111.

        VLDR{<c>}{<q>}{.32} <Sd>, [<Rn> {, #{+/-}<imm>}]


        Decode for all variants of this encoding

         single_reg = TRUE;     add = (U == ''1'');   imm32 = ZeroExtend(imm8:''00'', 32);
         d = UInt(Vd:D);     n = UInt(Rn);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15        12 11 10 9 8 7                         0
  1 1 1 0 1 1 0 1 U D 0 1                  Rn           Vd        1 0 1 1                imm8




Literal variant

Applies when Rn = 1111.

VLDR{<c>}{<q>}{.64} <Dd>, <label>
VLDR{<c>}{<q>}{.64} <Dd>, [PC, #{+/-}<imm>]


Offset variant

Applies when Rn != 1111.

VLDR{<c>}{<q>}{.64} <Dd>, [<Rn> {, #{+/-}<imm>}]


Decode for all variants of this encoding

 single_reg = FALSE;  add = (U == ''1'');    imm32 = ZeroExtend(imm8:''00'', 32);
 d = UInt(D:Vd);  n = UInt(Rn);


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15        12 11 10 9 8 7                         0
  1 1 1 0 1 1 0 1 U D 0 1                  Rn           Vd        1 0 1 0                imm8




Literal variant

Applies when Rn = 1111.

VLDR{<c>}{<q>}{.32} <Sd>, <label>
VLDR{<c>}{<q>}{.32} <Sd>, [PC, #{+/-}<imm>]


Offset variant

Applies when Rn != 1111.

VLDR{<c>}{<q>}{.32} <Sd>, [<Rn> {, #{+/-}<imm>}]


Decode for all variants of this encoding

 single_reg = TRUE;  add = (U == ''1'');    imm32 = ZeroExtend(imm8:''00'', 32);
 d = UInt(Vd:D);  n = UInt(Rn);


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

.64           Optional data size specifiers.

<Dd>          The destination register for a doubleword load.

.32           Optional data size specifiers.

<Sd>          The destination register for a singleword load.
        <label>           The label of the literal data item to be loaded. The assembler calculates the required value of the
                          offset from the Align(PC, 4) value of the instruction to this label. Permitted values are multiples of
                          4 in the range -1020 to 1020. If the offset is zero or positive, imm32 is equal to the offset and add ==
                          TRUE. If the offset is negative, imm32 is equal to minus the offset and add == FALSE.

        <Rn>              Is the general-purpose base register, encoded in the "Rn" field.

        +/-               Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
                          encoded in the "U" field. It can have the following values:

                          -            when U = 0

                          +            when U = 1

        <imm>             The immediate offset used for forming the address. For the immediate forms of the syntax, <imm>
                          can be omitted, in which case the #0 form of the instruction is assembled. Permitted values are
                          multiples of 4 in the range 0 to 1020.

        For the literal forms of the instruction, the base register is encoded as 0b1111 to indicate that the PC is the base
        register.

        The alternative syntax permits the addition or subtraction of the offset and the immediate offset to be specified
        separately, including permitting a subtraction of 0 that cannot be specified using the normal syntax. For more
        information, see Use of labels in UAL instruction syntax on page F1-2469.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckVFPEnabled(TRUE);
               base = if n == 15 then Align(PC,4) else R[n];
               address = if add then (base + imm32) else (base - imm32);
               if single_reg then
                   S[d] = MemA[address,4];
               else
                   word1 = MemA[address,4];       word2 = MemA[address+4,4];
                   // Combine the word-aligned words in the correct order for current endianness.
                   D[d] = if BigEndian() then word1:word2 else word2:word1;');
INSERT INTO "instructions" VALUES('ARM','VMAX','Vector Maximum compares corresponding elements in two vectors, and copies the larger of each pair into the       (F8.1.100)
corresponding element in the destination vector.

The operand vector elements are 32-bit floating-point numbers.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 0 0 D 0 0                    Vn           Vd       1 1 1 1 N Q M 0              Vm
                                   op sz


64-bit SIMD vector variant

Applies when Q = 0.

VMAX{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VMAX{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 maximum = (op == ''0'');      esize = 32;  elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 0 1 1 1 1 0 D 0 0                    Vn           Vd       1 1 1 1 N Q M 0              Vm
                                   op sz


64-bit SIMD vector variant

Applies when Q = 0.

VMAX{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VMAX{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>
        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         maximum = (op == ''0'');      esize = 32;    elements = 2;
         d = UInt(D:Vd);      n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VMAX or VMIN instruction must be
                          unconditional. ARM strongly recommends that a T32 VMAX or VMIN instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Floating-point maximum and minimum

        .       max(+0.0, -0.0) = +0.0

        .       If any input is a NaN, the corresponding result element is the default NaN.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        op1 = Elem[D[n+r],e,esize];      op2 = Elem[D[m+r],e,esize];
                        if maximum then
                             Elem[D[d+r],e,esize] = FPMax(op1, op2, StandardFPSCRValue());
                        else
                             Elem[D[d+r],e,esize] = FPMin(op1, op2, StandardFPSCRValue());');
INSERT INTO "instructions" VALUES('ARM','VMAXNM','This instruction determines the floating-point maximum number.       (F8.1.102)

It handles NaNs in consistence with the IEEE754-2008 specification. It returns the numerical operand when one
operand is numerical and the other is a quiet NaN, but otherwise the result is identical to floating-point VMAX.

This instruction is not conditional.


A1


   31 30 29 28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 0 0 1 1 0 D 0 0                   Vn          Vd         1 1 1 1 N Q M 1               Vm
                                  op sz


64-bit SIMD vector variant

Applies when Q = 0.

VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 maximum = (op == ''0'');
 advsimd = TRUE; esize = 32; elements = 2;
 d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


A2


   31 30 29 28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 1 1 1 0 1 D 0 0                   Vn          Vd         1 0 1 sz N 0 M 0              Vm
                                                                                     op


Single-precision scalar variant

Applies when sz = 0.

VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

 advsimd = FALSE;
 maximum = (op == ''0''); dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
 if InITBlock() then UNPREDICTABLE;
        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3              0 15          12 11 10 9 8 7 6 5 4 3          0
            1 1 1 1 1 1 1 1 0 D 0 0                  Vn         Vd         1 1 1 1 N Q M 1       Vm
                                         op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm>// Not permitted in IT block


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm>// Not permitted in IT block


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         maximum = (op == ''0'');
         advsimd = TRUE; esize = 32; elements = 2;
         d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3              0 15          12 11 10 9 8 7 6 5 4 3          0
            1 1 1 1 1 1 1 0 1 D 0 0                  Vn         Vd         1 0 1 sz N 0 M 0      Vm
                                                                                     op


        Single-precision scalar variant

        Applies when sz = 0.

        VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm>// Not permitted in IT block


        Double-precision scalar variant

        Applies when sz = 1.

        VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm>// Not permitted in IT block


        Decode for all variants of this encoding

         advsimd = FALSE;
         maximum = (op == ''0''); dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
         if InITBlock() then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors.
Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

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

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

<Sm>          Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations();   CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
 if advsimd then              // Advanced SIMD instruction
    for r = 0 to regs-1
        for e = 0 to elements-1
            op1 = Elem[D[n+r], e, esize]; op2 = Elem[D[m+r], e, esize];
            if maximum then
                 Elem[D[d+r], e, esize] = FPMaxNum(op1, op2, StandardFPSCRValue());
            else
                 Elem[D[d+r], e, esize] = FPMinNum(op1, op2, StandardFPSCRValue());
 else                         // VFP instruction
    if dp_operation then
        if maximum then
            D[d] = FPMaxNum(D[n], D[m], FPSCR);
        else
            D[d] = FPMinNum(D[n], D[m], FPSCR);
    else
        if maximum then
            S[d] = FPMaxNum(S[n], S[m], FPSCR);
        else
            S[d] = FPMinNum(S[n], S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VMIN','        Vector Minimum compares corresponding elements in two vectors, and copies the smaller of each pair into the       (F8.1.103)
        corresponding element in the destination vector.

        The operand vector elements are 32-bit floating-point numbers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 0 0 D 1 0                   Vn           Vd      1 1 1 1 N Q M 0             Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VMIN{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMIN{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         maximum = (op == ''0'');      esize = 32;  elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7 6 5 4 3               0
            1 1 1 0 1 1 1 1 0 D 1 0                   Vn           Vd      1 1 1 1 N Q M 0             Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VMIN{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMIN{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 maximum = (op == ''0'');   esize = 32;    elements = 2;
 d = UInt(D:Vd);   n = UInt(N:Vn);    m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 VMAX or VMIN instruction must be
               unconditional. ARM strongly recommends that a T32 VMAX or VMIN instruction is unconditional, see
               Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<Qd>           Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>           Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>           Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
               <Qm>*2.

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

<Dn>           Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Floating-point minimum

.     min(+0.0, -0.0) = -0.0

.     If any input is a NaN, the corresponding result element is the default NaN.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
              op1 = Elem[D[n+r],e,esize];     op2 = Elem[D[m+r],e,esize];
              if maximum then
                  Elem[D[d+r],e,esize] = FPMax(op1, op2, StandardFPSCRValue());
              else
                  Elem[D[d+r],e,esize] = FPMin(op1, op2, StandardFPSCRValue());');
INSERT INTO "instructions" VALUES('ARM','VMINNM','        This instruction determines the floating point minimum number.       (F8.1.105)

        It handles NaNs in consistence with the IEEE754-2008 specification. It returns the numerical operand when one
        operand is numerical and the other is a quiet NaN, but otherwise the result is identical to floating-point VMIN.

        This instruction is not conditional.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 0 0 1 1 0 D 1 0                  Vn          Vd        1 1 1 1 N Q M 1                Vm
                                          op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         maximum = (op == ''0'');
         advsimd = TRUE; esize = 32; elements = 2;
         d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        A2


           31 30 29 28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 1 1 1 0 1 D 0 0                  Vn          Vd        1 0 1 sz N 1 M 0               Vm
                                                                                          op


        Single-precision scalar variant

        Applies when sz = 0.

        VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm>


        Decode for all variants of this encoding

         advsimd = FALSE;
         maximum = (op == ''0''); dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
         if InITBlock() then UNPREDICTABLE;
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15          12 11 10 9 8 7 6 5 4 3                0
  1 1 1 1 1 1 1 1 0 D 1 0                Vn           Vd         1 1 1 1 N Q M 1             Vm
                               op sz


64-bit SIMD vector variant

Applies when Q = 0.

VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm>// Not permitted in IT block


128-bit SIMD vector variant

Applies when Q = 1.

VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm>// Not permitted in IT block


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 maximum = (op == ''0'');
 advsimd = TRUE; esize = 32; elements = 2;
 d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15          12 11 10 9 8 7 6 5 4 3                0
  1 1 1 1 1 1 1 0 1 D 0 0                Vn           Vd         1 0 1 sz N 1 M 0            Vm
                                                                                 op


Single-precision scalar variant

Applies when sz = 0.

VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm>// Not permitted in IT block


Double-precision scalar variant

Applies when sz = 1.

VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm>// Not permitted in IT block


Decode for all variants of this encoding

 advsimd = FALSE;
 maximum = (op == ''0''); dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.
        Assembler symbols

        <q>               See Standard assembler syntax fields on page F2-2506.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         EncodingSpecificOperations();       CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
         if advsimd then                  // Advanced SIMD instruction
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        op1 = Elem[D[n+r], e, esize]; op2 = Elem[D[m+r], e, esize];
                        if maximum then
                             Elem[D[d+r], e, esize] = FPMaxNum(op1, op2, StandardFPSCRValue());
                        else
                             Elem[D[d+r], e, esize] = FPMinNum(op1, op2, StandardFPSCRValue());
         else                             // VFP instruction
               if dp_operation then
                   if maximum then
                        D[d] = FPMaxNum(D[n], D[m], FPSCR);
                   else
                        D[d] = FPMinNum(D[n], D[m], FPSCR);
               else
                   if maximum then
                        S[d] = FPMaxNum(S[n], S[m], FPSCR);
                   else
                        S[d] = FPMinNum(S[n], S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VMLA','Vector Multiply Accumulate multiplies corresponding elements in two vectors, and accumulates the results into the       (F8.1.106)
elements of the destination vector.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 0 0 D 0 0                    Vn          Vd        1 1 0 1 N Q M 1              Vm
                                   op sz


64-bit SIMD vector variant

Applies when Q = 0.

VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>// Encoding T1/A1, encoded as Q = 0, sz = 0


128-bit SIMD vector variant

Applies when Q = 1.

VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>// Encoding T1/A1, encoded as Q = 1, sz = 0


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 advsimd = TRUE;    add = (op == ''0'');    esize = 32;  elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


A2


  31        28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3                 0
     !=1111    1 1 1 0 0 D 0 0                Vn          Vd        1 0 1 sz N 0 M 0             Vm
      cond                                                                           op


Single-precision scalar variant

Applies when sz = 0.

VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;    dp_operation = (sz == ''1'');    add = (op == ''0'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15        12 11 10 9 8 7 6 5 4 3              0
            1 1 1 0 1 1 1 1 0 D 0 0                  Vn           Vd       1 1 0 1 N Q M 1           Vm
                                          op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>// Encoding T1/A1, encoded as Q = 0, sz = 0


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>// Encoding T1/A1, encoded as Q = 1, sz = 0


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         advsimd = TRUE;     add = (op == ''0'');   esize = 32;   elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15        12 11 10 9 8 7 6 5 4 3              0
            1 1 1 0 1 1 1 0 0 D 0 0                  Vn           Vd       1 0 1 sz N 0 M 0          Vm




        Single-precision scalar variant

        Applies when sz = 0.

        VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE;     dp_operation = (sz == ''1'');   add = (op == ''0'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        Assembler symbols

        <c>               For encoding A1, A2 and T1: see Standard assembler syntax fields on page F2-2506. An A32
                          Advanced SIMD VMLA or VMLS instruction must be unconditional. ARM strongly recommends that a
                          T32 Advanced SIMD VMLA or VMLS instruction is unconditional, see Conditional execution on
                          page F2-2507.

                          For encoding T2: see Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.
<Sd>          Is the 32-bit name of the SIMD&FP destination register, encoded in the "Vd:D" field.

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

<Sm>          Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();     CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
    if advsimd then   // Advanced SIMD instruction
        for r = 0 to regs-1
            for e = 0 to elements-1
                 product = FPMul(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], StandardFPSCRValue());
                 addend = if add then product else FPNeg(product);
                 Elem[D[d+r],e,esize] = FPAdd(Elem[D[d+r],e,esize], addend, StandardFPSCRValue());
    else              // VFP instruction
        if dp_operation then
            addend64 = if add then FPMul(D[n], D[m], FPSCR) else FPNeg(FPMul(D[n], D[m], FPSCR));
            D[d] = FPAdd(D[d], addend64, FPSCR);
        else
            addend32 = if add then FPMul(S[n], S[m], FPSCR) else FPNeg(FPMul(S[n], S[m], FPSCR));
            S[d] = FPAdd(S[d], addend32, FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VMLAL','        Vector Multiply Accumulate Long multiplies corresponding elements in two vectors, and add the products to the       (F8.1.109)
        corresponding element of the destination vector. The destination vector element is twice as long as the elements that
        are multiplied.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19             16 15       12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 1 0 0 1 U 1 D !=11                    Vn            Vd       1 0 0 0 N 0 M 0              Vm
                                              size                                   op


        A1 variant

        VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm>// Encoding T2/A2


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if Vd<0> == ''1'' then UNDEFINED;
         add = (op == ''0'');      long_destination = TRUE;      unsigned = (U == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);    m = UInt(M:Vm);     regs = 1;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                     0 15       12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 U 1 1 1 1 1 D !=11                    Vn            Vd       1 0 0 0 N 0 M 0              Vm
                                              size                                   op


        T1 variant

        VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm>// Encoding T2/A2


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if Vd<0> == ''1'' then UNDEFINED;
         add = (op == ''0'');      long_destination = TRUE;      unsigned = (U == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);    m = UInt(M:Vm);     regs = 1;


        Notes for all encodings

        Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 Advanced SIMD VMLA, VMLAL, VMLS,
                          or VMLSL instruction must be unconditional. ARM strongly recommends that a T32 Advanced SIMD
                          VMLA, VMLAL, VMLS, or VMLSL instruction is unconditional, see Conditional execution on page F2-2507.
<q>           See Standard assembler syntax fields on page F2-2506.

<type>        The data type for the elements of the operands. It must be one of:

              S           Optional in encoding T1/A1. Encoded as U = 0 in encoding T2/A2.

              U           Optional in encoding T1/A1. Encoded as U = 1 in encoding T2/A2.

              I           Available only in encoding T1/A1.

<size>        The data size for the elements of the operands. It must be one of:

              8           Encoded as size = 0b00.

              16          Encoded as size = 0b01.

              32          Encoded as size = 0b10.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();     CheckAdvSIMDEnabled();
    for r = 0 to regs-1
        for e = 0 to elements-1
            product = Int(Elem[Din[n+r],e,esize],unsigned) * Int(Elem[Din[m+r],e,esize],unsigned);
            addend = if add then product else -product;
            if long_destination then
                 Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend;
            else
                 Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend;');
INSERT INTO "instructions" VALUES('ARM','VMLS','        Vector Multiply Subtract multiplies corresponding elements in two vectors, subtracts the products from       (F8.1.111)
        corresponding elements of the destination vector, and places the results in the destination vector.

                  Note
        ARM recommends that software does not use the VMLS instruction in the Round towards Plus Infinity and Round
        towards Minus Infinity rounding modes, because the rounding of the product and of the sum can change the result
        of the instruction in opposite directions, defeating the purpose of these rounding modes.


        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3              0
            1 1 1 1 0 0 1 0 0 D 1 0                   Vn           Vd       1 1 0 1 N Q M 1             Vm
                                           op sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>// Encoding T1/A1, encoded as Q = 0, sz = 0


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>// Encoding T1/A1, encoded as Q = 1, sz = 0


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         advsimd = TRUE;     add = (op == ''0'');    esize = 32;   elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        A2


           31        28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3              0
              !=1111     1 1 1 0 0 D 0 0              Vn           Vd       1 0 1 sz N 1 M 0            Vm
               cond                                                                        op


        Single-precision scalar variant

        Applies when sz = 0.

        VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>
Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;  dp_operation = (sz == ''1'');  add = (op == ''0'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 0 1 1 1 1 0 D 1 0                Vn          Vd         1 1 0 1 N Q M 1             Vm
                               op sz


64-bit SIMD vector variant

Applies when Q = 0.

VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm>// Encoding T1/A1, encoded as Q = 0, sz = 0


128-bit SIMD vector variant

Applies when Q = 1.

VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm>// Encoding T1/A1, encoded as Q = 1, sz = 0


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 advsimd = TRUE;  add = (op == ''0'');  esize = 32;  elements = 2;
 d = UInt(D:Vd);  n = UInt(N:Vn);  m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 0 1 1 1 0 0 D 0 0                Vn          Vd         1 0 1 sz N 1 M 0            Vm




Single-precision scalar variant

Applies when sz = 0.

VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;  dp_operation = (sz == ''1'');  add = (op == ''0'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
        Assembler symbols

        <c>               For encoding A1, A2 and T1: see Standard assembler syntax fields on page F2-2506. An A32
                          Advanced SIMD VMLA or VMLS instruction must be unconditional. ARM strongly recommends that a
                          T32 Advanced SIMD VMLA or VMLS instruction is unconditional, see Conditional execution on
                          page F2-2507.

                          For encoding T2: see Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
               if advsimd then    // Advanced SIMD instruction
                   for r = 0 to regs-1
                        for e = 0 to elements-1
                             product = FPMul(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], StandardFPSCRValue());
                             addend = if add then product else FPNeg(product);
                             Elem[D[d+r],e,esize] = FPAdd(Elem[D[d+r],e,esize], addend, StandardFPSCRValue());
               else               // VFP instruction
                   if dp_operation then
                        addend64 = if add then FPMul(D[n], D[m], FPSCR) else FPNeg(FPMul(D[n], D[m], FPSCR));
                        D[d] = FPAdd(D[d], addend64, FPSCR);
                   else
                        addend32 = if add then FPMul(S[n], S[m], FPSCR) else FPNeg(FPMul(S[n], S[m], FPSCR));
                        S[d] = FPAdd(S[d], addend32, FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VMLSL','Vector Multiply Subtract Long multiplies corresponding elements in two vectors, and subtract the products from       (F8.1.114)
the corresponding elements of the destination vector. The destination vector element is twice as long as the elements
that are multiplied.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19            16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 U 1 D !=11                   Vn            Vd       1 0 1 0 N 0 M 0              Vm
                                    size                                    op


A1 variant

VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm>// Encoding T2/A2


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' then UNDEFINED;
 add = (op == ''0'');     long_destination = TRUE;     unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);     regs = 1;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 U 1 1 1 1 1 D !=11                   Vn            Vd       1 0 1 0 N 0 M 0              Vm
                                    size                                    op


T1 variant

VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm>// Encoding T2/A2


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' then UNDEFINED;
 add = (op == ''0'');     long_destination = TRUE;     unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);     regs = 1;


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 Advanced SIMD VMLA, VMLAL, VMLS,
                or VMLSL instruction must be unconditional. ARM strongly recommends that a T32 Advanced SIMD
                VMLA, VMLAL, VMLS, or VMLSL instruction is unconditional, see Conditional execution on page F2-2507.
        <q>               See Standard assembler syntax fields on page F2-2506.

        <type>            The data type for the elements of the operands. It must be one of:

                          S           Optional in encoding T1/A1. Encoded as U = 0 in encoding T2/A2.

                          U           Optional in encoding T1/A1. Encoded as U = 1 in encoding T2/A2.

                          I           Available only in encoding T1/A1.

        <size>            The data size for the elements of the operands. It must be one of:

                          8           Encoded as size = 0b00.

                          16          Encoded as size = 0b01.

                          32          Encoded as size = 0b10.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        product = Int(Elem[Din[n+r],e,esize],unsigned) * Int(Elem[Din[m+r],e,esize],unsigned);
                        addend = if add then product else -product;
                        if long_destination then
                             Elem[Q[d>>1],e,2*esize] = Elem[Qin[d>>1],e,2*esize] + addend;
                        else
                             Elem[D[d+r],e,esize] = Elem[Din[d+r],e,esize] + addend;');
INSERT INTO "instructions" VALUES('ARM','VMOV','Copy two general-purpose registers to or from a SIMD&FP register copies two words from two general-purpose       (F8.1.116)
registers into a doubleword register in the Advanced SIMD and floating-point register file, or from a doubleword
register in the Advanced SIMD and floating-point register file to two general-purpose registers.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


  31         28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                0
     !=1111      1 1 0 0 0 1 0 op            Rt2          Rt       1 0 1 1 0 0 M 1              Vm
      cond


Encoding

Applies when op = 1.

VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm>


Encoding

Applies when op = 0.

VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2>


Decode for all variants of this encoding

 to_arm_registers = (op == ''1'');      t = UInt(Rt);   t2 = UInt(Rt2);     m = UInt(M:Vm);
 if t == 15 || t2 == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
 if to_arm_registers && t == t2 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 0 1 1 0 0 0 1 0 op                   Rt2          Rt       1 0 1 1 0 0 M 1              Vm




Encoding

Applies when op = 1.

VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm>


Encoding

Applies when op = 0.

VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2>


Decode for all variants of this encoding

 to_arm_registers = (op == ''1'');      t = UInt(Rt);   t2 = UInt(Rt2);     m = UInt(M:Vm);
 if t == 15 || t2 == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13
 if to_arm_registers && t == t2 then UNPREDICTABLE;
        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VMOV (between two general-purpose
        registers and a doubleword floating-point register) on page J1-5390.


        Assembler symbols

        <Dm>              Is the 64-bit name of the SIMD&FP register to be transferred, encoded in the "M:Vm" field.

        <Rt2>             Is the first general-purpose register that <Dm>[63:32] will be transferred to or from, encoded in the
                          "Rt" field.

        <Rt>              Is the first general-purpose register that <Dm>[31:0] will be transferred to or from, encoded in the "Rt"
                          field.

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckVFPEnabled(TRUE);
               if to_arm_registers then
                   R[t] = D[m]<31:0>;
                   R[t2] = D[m]<63:32>;
               else
                   D[m]<31:0> = R[t];
                   D[m]<63:32> = R[t2];');
INSERT INTO "instructions" VALUES('ARM','VMOVL','        Vector Move Long takes each element in a doubleword vector, sign or zero-extends them to twice their original       (F8.1.124)
        length, and places the results in a quadword vector.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21      19 18 17 16 15        12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 U 1 D              !=000   0 0 0         Vd      1 0 1 0 0 0 M 1             Vm
                                            imm3H


        A1 variant

        VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm>


        Decode for this encoding

         if imm3 == ''000'' then SEE "Related encodings";
         if imm3 != ''001'' && imm3 != ''010'' && imm3 != ''100'' then SEE VSHLL;
         if Vd<0> == ''1'' then UNDEFINED;
         esize = 8 * UInt(imm3);
         unsigned = (U == ''1'');      elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5            3 2 1 0 15           12 11 10 9 8 7 6 5 4 3               0
            1 1 1 U 1 1 1 1 1 D              !=000   0 0 0         Vd      1 0 1 0 0 0 M 1             Vm
                                            imm3H


        T1 variant

        VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm>


        Decode for this encoding

         if imm3 == ''000'' then SEE "Related encodings";
         if imm3 != ''001'' && imm3 != ''010'' && imm3 != ''100'' then SEE VSHLL;
         if Vd<0> == ''1'' then UNDEFINED;
         esize = 8 * UInt(imm3);
         unsigned = (U == ''1'');      elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);


        Notes for all encodings

        Related encodings: One register and a modified immediate value on page F5-2596.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VMOVL instruction must be
                          unconditional. ARM strongly recommends that a T32 VMOVL instruction is unconditional, see
                          Conditional execution on page F2-2507.
<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          The data type for the elements of the operand. It must be one of:

              S8          Encoded as U = 0, imm3 = 0b001.

              S16         Encoded as U = 0, imm3 = 0b010.

              S32         Encoded as U = 0, imm3 = 0b100.

              U8          Encoded as U = 1, imm3 = 0b001.

              U16         Encoded as U = 1, imm3 = 0b010.

              U32         Encoded as U = 1, imm3 = 0b100.



<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();    CheckAdvSIMDEnabled();
    for e = 0 to elements-1
        result = Int(Elem[Din[m],e,esize], unsigned);
        Elem[Q[d>>1],e,2*esize] = result<2*esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VMOVN','        Vector Move and Narrow copies the least significant half of each element of a quadword vector into the       (F8.1.125)
        corresponding elements of a doubleword vector.

        The operand vector elements can be any one of 16-bit, 32-bit, or 64-bit integers. There is no distinction between
        signed and unsigned integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.

        This instruction is used by the aliases VRSHRN (zero) and VSHRN (zero). See the Alias conditions on
        page F8-3543 table for details of when each alias is preferred.


        A1


           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 3                 0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                       Vd      0 0 1 0 0 0 M 0              Vm




        A1 variant

        VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>


        Decode for this encoding

         if size == ''11'' then UNDEFINED;
         if Vm<0> == ''1'' then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                       Vd      0 0 1 0 0 0 M 0              Vm




        T1 variant

        VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>


        Decode for this encoding

         if size == ''11'' then UNDEFINED;
         if Vm<0> == ''1'' then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);
Alias conditions


                    Alias                    is preferred when

                    VRSHRN (zero)            Never

                    VSHRN (zero)             Never



Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VMOVN instruction must be
              unconditional. ARM strongly recommends that a T32 VMOVN instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operand, encoded in the "size" field. It can have the following
              values:

              I16          when size = 00

              I32          when size = 01

              I64          when size = 10

              It is RESERVED when size = 11.

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

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();      CheckAdvSIMDEnabled();
    for e = 0 to elements-1
        Elem[D[d],e,esize] = Elem[Qin[m>>1],e,2*esize]<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VMRS','        Move SIMD&FP Special register to general-purpose register moves the value of an Advanced SIMD and       (F8.1.126)
        floating-point System register to a general-purpose register. When the specified System register is the FPSCR, a
        form of the instruction transfers the FPSCR.{N, Z, C, V} condition flags to the The Application Program Status
        Register, APSR on page E1-2382.{N, Z, C, V} condition flags.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        When these settings permit the execution of floating-point and Advanced SIMD instructions, if the specified
        floating-point System register is not the FPSCR, the instruction is UNDEFINED if executed in User mode.

        In an implementation that includes EL2, when HCR.TID0 is set to 1, any VMRS access to FPSID from a Non-secure
        EL1 mode that would be permitted if HCR.TID0 was set to 0 generates a Hyp Trap exception. For more information,
        see ID group 0, Primary device identification registers on page G1-3917.

        For simplicity, the VMRS pseudocode does not show the possible trap to Hyp mode.


        A1


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3 2 1 0
              !=1111     1 1 1 0 1 1 1 1             reg          Rt       1 0 1 0 (0) (0) (0) 1 (0) (0) (0) (0)
               cond


        A1 variant

        VMRS{<c>}{<q>} <Rt>, <spec_reg>


        Decode for this encoding

         t = UInt(Rt);
         if !(reg IN {''000x'', ''0101'', ''011x'', ''1000''}) then UNPREDICTABLE;
         if t == 15 && reg != ''0001'' then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
            1 1 1 0 1 1 1 0 1 1 1 1                  reg          Rt       1 0 1 0 0 (0) (0) 1 (0) (0) (0) (0)




        T1 variant

        VMRS{<c>}{<q>} <Rt>, <spec_reg>


        Decode for this encoding

         t = UInt(Rt);
         if !(reg IN {''000x'', ''0101'', ''011x'', ''1000''}) then UNPREDICTABLE;
         if t == 15 && reg != ''0001'' then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VMRS on page J1-5390.
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Rt>          Is the general-purpose destination register, encoded in the "Rt" field. Is one of:

              R0-R14      General-purpose register.

              APSR_nzcv   If <spec_reg> is FPSCR, encoded as 0b1111. This instruction transfers the FPSCR.{N, Z,
                          C, V} condition flags to the APSR.{N, Z, C, V} condition flags.

<spec_reg>    Is the source Advanced SIMD and floating-point System register, encoded in the "reg" field. It can
              have the following values:

              FPSID       when reg = 0000

              FPSCR       when reg = 0001

              MVFR2       when reg = 0101

              MVFR1       when reg = 0110

              MVFR0       when reg = 0111

              FPEXC       when reg = 1000

              It is RESERVED when:

              .      reg = 001x.

              .      reg = 0100.

              .      reg = 1001.

              .      reg = 101x.

              .      reg = 11xx.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    if reg == ''0001'' then                    // FPSCR
        CheckVFPEnabled(TRUE);
        if t == 15 then
            PSTATE.<N,Z,C,V> = FPSR.<N,Z,C,V>;
        else
            R[t] = FPSCR;
    elsif PSTATE.EL == EL0 then
        UNDEFINED;                           // Non-FPSCR registers accessible only at PL1 or above
    else
        CheckVFPEnabled(FALSE);              // Non-FPSCR registers are not affected by FPEXC.EN
        case reg of
            // Pseudocode does not consider possible HCR.TIDn Hyp Traps of Non-secure register reads
            when ''0000''   R[t] = FPSID;
            when ''0101''   R[t] = MVFR2;
            when ''0110''   R[t] = MVFR1;
            when ''0111''   R[t] = MVFR0;
            when ''1000''   R[t] = FPEXC;
            otherwise     Unreachable();     // Dealt with above or in encoding-specific pseudocode');
INSERT INTO "instructions" VALUES('ARM','VMSR','        Move general-purpose register to SIMD&FP Special register moves the value of a general-purpose register to a       (F8.1.127)
        floating-point System register.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        When these settings permit the execution of floating-point and Advanced SIMD instructions:

        .       If the specified floating-point System register is not the FPSCR, the instruction is UNDEFINED if executed in
                User mode.

        .       If the specified floating-point System register is the FPEXC and the instruction is executed in a mode other
                than User mode the instruction is ignored.


        A1


           31        28 27 26 25 24 23 22 21 20 19          16 15         12 11 10 9 8 7 6 5 4 3 2 1 0
              !=1111     1 1 1 0 1 1 1 0              reg            Rt      1 0 1 0 (0) (0) (0) 1 (0) (0) (0) (0)
               cond


        A1 variant

        VMSR{<c>}{<q>} <spec_reg>, <Rt>


        Decode for this encoding

         t = UInt(Rt);
         if reg != ''000x'' && reg != ''1000'' then UNPREDICTABLE;
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3 2 1 0
            1 1 1 0 1 1 1 0 1 1 1 0                   reg            Rt      1 0 1 0 0 (0) (0) 1 (0) (0) (0) (0)




        T1 variant

        VMSR{<c>}{<q>} <spec_reg>, <Rt>


        Decode for this encoding

         t = UInt(Rt);
         if reg != ''000x'' && reg != ''1000'' then UNPREDICTABLE;
         if t == 15 then UNPREDICTABLE; // ARMv8-A removes UNPREDICTABLE for R13


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VMSR on page J1-5390.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.
<spec_reg>    Is the destination Advanced SIMD and floating-point System register, encoded in the "reg" field. It
              can have the following values:

              FPSID       when reg = 0000

              FPSCR       when reg = 0001

              FPEXC       when reg = 1000

              It is RESERVED when:

              .      reg = 001x.

              .      reg = 01xx.

              .      reg = 1001.

              .      reg = 101x.

              .      reg = 11xx.

<Rt>          Is the general-purpose source register, encoded in the "Rt" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();
    if reg == ''0001'' then                   // FPSCR
        CheckVFPEnabled(TRUE);
        FPSCR = R[t];
    elsif PSTATE.EL == EL0 then
        UNDEFINED;                          // Non-FPSCR registers accessible only at PL1 or above
    else
        CheckVFPEnabled(FALSE);             // Non-FPSCR registers are not affected by FPEXC.EN
        case reg of
            when ''0000''                     // VMSR access to FPSID is ignored
            when ''1000''    FPEXC = R[t];
            otherwise      Unreachable();   // Dealt with above or in encoding-specific pseudocode');
INSERT INTO "instructions" VALUES('ARM','VMUL','        Vector Multiply multiplies corresponding elements in two vectors, and places the results in the destination vector.       (F8.1.128)

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 0 0 1 1 0 D 0 0                   Vn          Vd       1 1 0 1 N Q M 1            Vm
                                              sz


        64-bit SIMD vector variant

        Applies when Q = 0.

        VMUL{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMUL{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         advsimd = TRUE;     esize = 32;  elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        A2


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7 6 5 4 3                0
              !=1111     1 1 1 0 0 D 1 0              Vn          Vd       1 0 1 sz N 0 M 0           Vm
               cond


        Single-precision scalar variant

        Applies when sz = 0.

        VMUL{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VMUL{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE;     dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3              0 15        12 11 10 9 8 7 6 5 4 3                  0
  1 1 1 1 1 1 1 1 0 D 0 sz                Vn          Vd         1 1 0 1 N Q M 1              Vm




64-bit SIMD vector variant

Applies when sz = 0 && Q = 0.

VMUL{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VMUL{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 advsimd = TRUE;  esize = 32;  elements = 2;
 d = UInt(D:Vd);  n = UInt(N:Vn);   m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3              0 15        12 11 10 9 8 7 6 5 4 3                  0
  1 1 1 0 1 1 1 0 0 D 1 0                 Vn          Vd         1 0 1 sz N 0 M 0             Vm




Single-precision scalar variant

Applies when sz = 0.

VMUL{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VMUL{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;  dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


Assembler symbols

<c>           For encoding A1, A2 and T1: see Standard assembler syntax fields on page F2-2506. An A32
              Advanced SIMD VMUL instruction must be unconditional. ARM strongly recommends that a T32
              Advanced SIMD VMUL instruction is unconditional, see Conditional execution on page F2-2507.

              For encoding T2: see Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

<Sd>          Is the 32-bit name of the SIMD&FP destination register, encoded in the "Vd:D" field.
        <Sn>              Is the 32-bit name of the first SIMD&FP source register, encoded in the "Vn:N" field.

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
               if advsimd then    // Advanced SIMD instruction
                   for r = 0 to regs-1
                        for e = 0 to elements-1
                             Elem[D[d+r],e,esize] = FPMul(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize],
        StandardFPSCRValue());
               else               // VFP instruction
                   if dp_operation then
                        D[d] = FPMul(D[n], D[m], FPSCR);
                   else
                        S[d] = FPMul(S[n], S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VMULL','        Vector Multiply Long multiplies corresponding elements in two vectors. The destination vector elements are twice       (F8.1.131)
        as long as the elements that are multiplied.

        For information about multiplying polynomials see Polynomial arithmetic over {0, 1} on page A1-45.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 U 1 D !=11                  Vn           Vd      1 1 op 0 N 0 M 0            Vm
                                           size


        A1 variant

        VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         unsigned = (U == ''1''); polynomial = (op == ''1''); long_destination = TRUE;
         esize = 8 << UInt(size); elements = 64 DIV esize;
         if polynomial then
               if U == ''1'' || size == ''01'' then UNDEFINED;
               if size == ''10'' then      // .p64
                   if !HaveCryptoExt() then UNDEFINED;
                   if InITBlock() then UNPREDICTABLE;
                   esize = 64; elements = 1;
         if Vd<0> == ''1'' then UNDEFINED;
         d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7 6 5 4 3               0
            1 1 1 U 1 1 1 1 1 D !=11                  Vn           Vd      1 1 op 0 N 0 M 0            Vm
                                           size


        T1 variant

        VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         unsigned = (U == ''1''); polynomial = (op == ''1''); long_destination = TRUE;
         esize = 8 << UInt(size); elements = 64 DIV esize;
         if polynomial then
               if U == ''1'' || size == ''01'' then UNDEFINED;
               if size == ''10'' then      // .p64
                   if !HaveCryptoExt() then UNDEFINED;
                   if InITBlock() then UNPREDICTABLE;
                   esize = 64; elements = 1;
         if Vd<0> == ''1'' then UNDEFINED;
         d = UInt(D:Vd); n = UInt(N:Vn); m = UInt(M:Vm); regs = 1;
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 Advanced SIMD VMUL or VMULL
               instruction must be unconditional. ARM strongly recommends that a T32 Advanced SIMD VMUL or
               VMULL instruction is unconditional, see Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<dt>           Is the data type for the elements of the operands, encoded in the "op:U:size" field. It can have the
               following values:

               S8           when op = 0, U = 0, size = 00

               S16          when op = 0, U = 0, size = 01

               S32          when op = 0, U = 0, size = 10

               U8           when op = 0, U = 1, size = 00

               U16          when op = 0, U = 1, size = 01

               U32          when op = 0, U = 1, size = 10

               P8           when op = 1, U = 0, size = 00

               P64          when op = 1, U = 0, size = 10

               It is RESERVED when:

               .      op = 0, U = 0, size = 11.

               .      op = 0, U = 1, size = 11.

               .      op = 1, U = 0, size = 01.

               .      op = 1, U = 0, size = 11.

               .      op = 1, U = 1, size = xx.

<Qd>           Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Dn>           Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>           Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();      CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
              op1 = Elem[Din[n+r],e,esize];     op1val = Int(op1, unsigned);
              op2 = Elem[Din[m+r],e,esize];     op2val = Int(op2, unsigned);
              if polynomial then
                  product = PolynomialMult(op1,op2);
              else
                  product = (op1val*op2val)<2*esize-1:0>;
              if long_destination then
                  Elem[Q[d>>1],e,2*esize] = product;
              else
                  Elem[D[d+r],e,esize] = product<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VMVN','        Vector Bitwise NOT (immediate) places the bitwise inverse of an immediate integer constant into every element of       (F8.1.133)
        the destination register.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19 18       16 15       12 11       8 7 6 5 4 3              0
            1 1 1 1 0 0 1 i 1 D 0 0 0                 imm3         Vd        cmode    0 Q 1 1         imm4




        64-bit SIMD vector variant

        Applies when Q = 0.

        VMVN{<c>}{<q>}.<dt> <Dd>, #<imm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMVN{<c>}{<q>}.<dt> <Qd>, #<imm>


        Decode for all variants of this encoding

         if (cmode<0> == ''1'' && cmode<3:2> != ''11'') || cmode<3:1> == ''111'' then SEE "Related encodings";
         if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
         imm64 = AdvSIMDExpandImm(''1'', cmode, i:imm3:imm4);
         d = UInt(D:Vd);     regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2                0 15       12 11       8 7 6 5 4 3              0
            1 1 1 i 1 1 1 1 1 D 0 0 0                 imm3         Vd        cmode    0 Q 1 1         imm4




        64-bit SIMD vector variant

        Applies when Q = 0.

        VMVN{<c>}{<q>}.<dt> <Dd>, #<imm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VMVN{<c>}{<q>}.<dt> <Qd>, #<imm>


        Decode for all variants of this encoding

         if (cmode<0> == ''1'' && cmode<3:2> != ''11'') || cmode<3:1> == ''111'' then SEE "Related encodings";
         if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
         imm64 = AdvSIMDExpandImm(''1'', cmode, i:imm3:imm4);
         d = UInt(D:Vd);     regs = if Q == ''0'' then 1 else 2;
Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VMVN instruction must be
              unconditional. ARM strongly recommends that a T32 VMVN instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          The data type. It must be either I16 or I32.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

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

<imm>         Is a constant of the type specified by <dt> that is replicated to fill the destination register. For details
              of the range of constants available and the encoding of <dt> and <imm>, see One register and a
              modified immediate value on page F5-2596.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();    CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         D[d+r] = NOT(imm64);');
INSERT INTO "instructions" VALUES('ARM','VNEG','        Vector Negate negates each element in a vector, and places the results in a second vector. The floating-point version       (F8.1.135)
        only inverts the sign bit.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                  0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 1                      Vd       0 F 1 1 1 Q M 0               Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VNEG{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VNEG{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         advsimd = TRUE;     floating_point = (F == ''1'');
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


        A2


           31        28 27 26 25 24 23 22 21 20 19 18 17 16 15         12 11 10 9 8 7 6 5 4 3                  0
              !=1111     1 1 1 0 1 D 1 1 0 0 0 1                  Vd       1 0 1 sz 0 1 M 0              Vm
               cond


        Single-precision scalar variant

        Applies when sz = 0.

        VNEG{<c>}{<q>}.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VNEG{<c>}{<q>}.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE;     dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                 12 11 10 9 8 7 6 5 4 3                 0
  1 1 1 1 1 1 1 1 1 D 1 1 size 0 1                    Vd        0 F 1 1 1 Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VNEG{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VNEG{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' || (F == ''1'' && size != ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 advsimd = TRUE;  floating_point = (F == ''1'');
 esize = 8 << UInt(size);  elements = 64 DIV esize;
 d = UInt(D:Vd);  m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                 12 11 10 9 8 7 6 5 4 3                 0
  1 1 1 0 1 1 1 0 1 D 1 1 0 0 0 1                     Vd        1 0 1 sz 0 1 M 0             Vm




Single-precision scalar variant

Applies when sz = 0.

VNEG{<c>}{<q>}.F32 <Sd>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VNEG{<c>}{<q>}.F64 <Dd>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;  dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 Advanced SIMD VNEG instruction
              must be unconditional. ARM strongly recommends that a T32 Advanced SIMD VNEG instruction is
              unconditional, see Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.
        <dt>              Is the data type for the elements of the vectors, encoded in the "F:size" field. It can have the
                          following values:

                          S8           when F = 0, size = 00

                          S16          when F = 0, size = 01

                          S32          when F = 0, size = 10

                          F32          when F = 1, size = 10

                          It is RESERVED when:

                          .      F = 0, size = 11.

                          .      F = 1, size = 0x.

                          .      F = 1, size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

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

        <Sm>              Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
               if advsimd then    // Advanced SIMD instruction
                   for r = 0 to regs-1
                        for e = 0 to elements-1
                             if floating_point then
                                 Elem[D[d+r],e,esize] = FPNeg(Elem[D[m+r],e,esize]);
                             else
                                 result = -SInt(Elem[D[m+r],e,esize]);
                                 Elem[D[d+r],e,esize] = result<esize-1:0>;
               else               // VFP instruction
                   if dp_operation then
                        D[d] = FPNeg(D[m]);
                   else
                        S[d] = FPNeg(S[m]);');
INSERT INTO "instructions" VALUES('ARM','VNMLA','Vector Negate Multiply Accumulate multiplies together two floating-point register values, adds the negation of the       (F8.1.136)
floating-point value in the destination register to the negation of the product, and writes the result back to the
destination register.

         Note
ARM recommends that software does not use the VNMLA instruction in the Round towards Plus Infinity and Round
towards Minus Infinity rounding modes, because the rounding of the product and of the sum can change the result
of the instruction in opposite directions, defeating the purpose of these rounding modes.


Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


  31        28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                  0
     !=1111     1 1 1 0 0 D 0 1               Vn           Vd        1 0 1 sz N 1 M 0              Vm
      cond                                                                            op


Single-precision scalar variant

Applies when sz = 0.

VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 type = if op == ''1'' then VFPNegMul_VNMLA else VFPNegMul_VNMLS;
 dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15        12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 0 1 1 1 0 0 D 0 1                    Vn           Vd        1 0 1 sz N 1 M 0              Vm
                                                                                      op


Single-precision scalar variant

Applies when sz = 0.

VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>
        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         type = if op == ''1'' then VFPNegMul_VNMLA else VFPNegMul_VNMLS;
         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         enumeration VFPNegMul {VFPNegMul_VNMLA, VFPNegMul_VNMLS, VFPNegMul_VNMUL};

         if ConditionPassed() then
               EncodingSpecificOperations();     CheckVFPEnabled(TRUE);
               if dp_operation then
                   product64 = FPMul(D[n], D[m], FPSCR);
                   case type of
                        when VFPNegMul_VNMLA    D[d] = FPAdd(FPNeg(D[d]), FPNeg(product64), FPSCR);
                        when VFPNegMul_VNMLS    D[d] = FPAdd(FPNeg(D[d]), product64, FPSCR);
                        when VFPNegMul_VNMUL    D[d] = FPNeg(product64);
               else
                   product32 = FPMul(S[n], S[m], FPSCR);
                   case type of
                        when VFPNegMul_VNMLA    S[d] = FPAdd(FPNeg(S[d]), FPNeg(product32), FPSCR);
                        when VFPNegMul_VNMLS    S[d] = FPAdd(FPNeg(S[d]), product32, FPSCR);
                        when VFPNegMul_VNMUL    S[d] = FPNeg(product32);');
INSERT INTO "instructions" VALUES('ARM','VNMLS','Vector Negate Multiply Subtract multiplies together two floating-point register values, adds the negation of the       (F8.1.137)
floating-point value in the destination register to the product, and writes the result back to the destination register.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


  31       28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                  0
     !=1111    1 1 1 0 0 D 0 1                Vn            Vd       1 0 1 sz N 0 M 0              Vm
      cond                                                                            op


Single-precision scalar variant

Applies when sz = 0.

VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 type = if op == ''1'' then VFPNegMul_VNMLA else VFPNegMul_VNMLS;
 dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15        12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 0 1 1 1 0 0 D 0 1                    Vn            Vd       1 0 1 sz N 0 M 0              Vm
                                                                                      op


Single-precision scalar variant

Applies when sz = 0.

VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 type = if op == ''1'' then VFPNegMul_VNMLA else VFPNegMul_VNMLS;
 dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         enumeration VFPNegMul {VFPNegMul_VNMLA, VFPNegMul_VNMLS, VFPNegMul_VNMUL};

         if ConditionPassed() then
               EncodingSpecificOperations();     CheckVFPEnabled(TRUE);
               if dp_operation then
                   product64 = FPMul(D[n], D[m], FPSCR);
                   case type of
                        when VFPNegMul_VNMLA    D[d] = FPAdd(FPNeg(D[d]), FPNeg(product64), FPSCR);
                        when VFPNegMul_VNMLS    D[d] = FPAdd(FPNeg(D[d]), product64, FPSCR);
                        when VFPNegMul_VNMUL    D[d] = FPNeg(product64);
               else
                   product32 = FPMul(S[n], S[m], FPSCR);
                   case type of
                        when VFPNegMul_VNMLA    S[d] = FPAdd(FPNeg(S[d]), FPNeg(product32), FPSCR);
                        when VFPNegMul_VNMLS    S[d] = FPAdd(FPNeg(S[d]), product32, FPSCR);
                        when VFPNegMul_VNMUL    S[d] = FPNeg(product32);');
INSERT INTO "instructions" VALUES('ARM','VNMUL','Vector Negate Multiply multiplies together two floating-point register values, and writes the negation of the result       (F8.1.138)
to the destination register.

Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3                0
     !=1111     1 1 1 0 0 D 1 0              Vn           Vd       1 0 1 sz N 1 M 0             Vm
      cond


Single-precision scalar variant

Applies when sz = 0.

VNMUL{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VNMUL{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 type = VFPNegMul_VNMUL;
 dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15         12 11 10 9 8 7 6 5 4 3                0
   1 1 1 0 1 1 1 0 0 D 1 0                   Vn           Vd       1 0 1 sz N 1 M 0             Vm




Single-precision scalar variant

Applies when sz = 0.

VNMUL{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VNMUL{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 type = VFPNegMul_VNMUL;
 dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         enumeration VFPNegMul {VFPNegMul_VNMLA, VFPNegMul_VNMLS, VFPNegMul_VNMUL};

         if ConditionPassed() then
               EncodingSpecificOperations();     CheckVFPEnabled(TRUE);
               if dp_operation then
                   product64 = FPMul(D[n], D[m], FPSCR);
                   case type of
                        when VFPNegMul_VNMLA    D[d] = FPAdd(FPNeg(D[d]), FPNeg(product64), FPSCR);
                        when VFPNegMul_VNMLS    D[d] = FPAdd(FPNeg(D[d]), product64, FPSCR);
                        when VFPNegMul_VNMUL    D[d] = FPNeg(product64);
               else
                   product32 = FPMul(S[n], S[m], FPSCR);
                   case type of
                        when VFPNegMul_VNMLA    S[d] = FPAdd(FPNeg(S[d]), FPNeg(product32), FPSCR);
                        when VFPNegMul_VNMLS    S[d] = FPAdd(FPNeg(S[d]), product32, FPSCR);
                        when VFPNegMul_VNMUL    S[d] = FPNeg(product32);');
INSERT INTO "instructions" VALUES('ARM','VORN','Vector Bitwise OR NOT (immediate) performs a bitwise OR between a register value and the complement of an       (F8.1.139)
immediate value, and returns the result into the destination vector

This instruction is an alias of the VORR (immediate) instruction. This means that:

.      The encodings in this description are named to match the encodings of VORR (immediate).

.      The description of VORR (immediate) gives the operational pseudocode for this instruction.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19 18       16 15        12 11           8 7 6 5 4 3            0
   1 1 1 1 0 0 1 i 1 D 0 0 0                  imm3        Vd          cmode       0 Q 0 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VORN{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>

is equivalent to

VORR{<c>}{<q>}.<dt> <Dd>, #~<imm>

and is never the preferred disassembly.

128-bit SIMD vector variant

Applies when Q = 1.

VORN{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>

is equivalent to

VORR{<c>}{<q>}.<dt> <Qd>, #~<imm>

and is never the preferred disassembly.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2                0 15        12 11           8 7 6 5 4 3            0
   1 1 1 i 1 1 1 1 1 D 0 0 0                  imm3        Vd          cmode       0 Q 0 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VORN{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>

is equivalent to

VORR{<c>}{<q>}.<dt> <Dd>, #~<imm>

and is never the preferred disassembly.

128-bit SIMD vector variant

Applies when Q = 1.

VORN{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>
        is equivalent to

        VORR{<c>}{<q>}.<dt> <Qd>, #~<imm>

        and is never the preferred disassembly.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VORR instruction must be
                          unconditional. ARM strongly recommends that a T32 VORR instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              The data type used for <imm>. It can be either I16 or I32. I8, I64, and F32 are also permitted, but the
                          resulting syntax is a pseudo-instruction.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

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

        <imm>             Is a constant of the type specified by <dt> that is replicated to fill the destination register. For details
                          of the range of constants available and the encoding of <dt> and <imm>, see One register and a
                          modified immediate value on page F5-2596.


        Operation for all encodings

        The description of VORR (immediate) gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VORR','Vector Bitwise OR (immediate) performs a bitwise OR between a register value and an immediate value, and       (F8.1.141)
returns the result into the destination vector.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.

This instruction is used by the alias VORN (immediate). See the Alias conditions on page F8-3578 table for details
of when each alias is preferred.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19 18        16 15       12 11            8 7 6 5 4 3            0
   1 1 1 1 0 0 1 i 1 D 0 0 0                   imm3        Vd          cmode       0 Q 0 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VORR{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>


128-bit SIMD vector variant

Applies when Q = 1.

VORR{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>


Decode for all variants of this encoding

 if cmode<0> == ''0'' || cmode<3:2> == ''11'' then SEE VMOV (immediate);
 if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
 imm64 = AdvSIMDExpandImm(''0'', cmode, i:imm3:imm4);
 d = UInt(D:Vd);     regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2                 0 15       12 11            8 7 6 5 4 3            0
   1 1 1 i 1 1 1 1 1 D 0 0 0                   imm3        Vd          cmode       0 Q 0 1       imm4




64-bit SIMD vector variant

Applies when Q = 0.

VORR{<c>}{<q>}.<dt> {<Dd>,} <Dd>, #<imm>


128-bit SIMD vector variant

Applies when Q = 1.

VORR{<c>}{<q>}.<dt> {<Qd>,} <Qd>, #<imm>
        Decode for all variants of this encoding

         if cmode<0> == ''0'' || cmode<3:2> == ''11'' then SEE VMOV (immediate);
         if Q == ''1'' && Vd<0> == ''1'' then UNDEFINED;
         imm64 = AdvSIMDExpandImm(''0'', cmode, i:imm3:imm4);
         d = UInt(D:Vd);      regs = if Q == ''0'' then 1 else 2;


        Notes for all encodings

        Related encodings: One register and a modified immediate value on page F5-2596.


        Alias conditions


                               Alias                     is preferred when

                               VORN (immediate)          Never



        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VORR instruction must be
                          unconditional. ARM strongly recommends that a T32 VORR instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              The data type used for <imm>. It can be either I16 or I32. I8, I64, and F32 are also permitted, but the
                          resulting syntax is a pseudo-instruction.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

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

        <imm>             Is a constant of the type specified by <dt> that is replicated to fill the destination register. For details
                          of the range of constants available and the encoding of <dt> and <imm>, see One register and a
                          modified immediate value on page F5-2596.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   D[d+r] = D[d+r] OR imm64;');
INSERT INTO "instructions" VALUES('ARM','VPADAL','Vector Pairwise Add and Accumulate Long adds adjacent pairs of elements of a vector, and accumulates the results       (F8.1.143)
into the elements of the destination vector.

The vectors can be doubleword or quadword. The operand elements can be 8-bit, 16-bit, or 32-bit integers. The
result elements are twice the length of the operand elements.

The following figure shows an example of the operation of VPADAL doubleword operation for data type S16.

                                                                                 Dm




                                                                                            +             +




                                                                                 Dd

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                 0
   1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                        Vd       0 1 1 0 op Q M 0             Vm




64-bit SIMD vector variant

Applies when Q = 0.

VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 unsigned = (op == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                        Vd       0 1 1 0 op Q M 0             Vm
        64-bit SIMD vector variant

        Applies when Q = 0.

        VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         unsigned = (op == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VPADAL instruction must be
                          unconditional. ARM strongly recommends that a T32 VPADAL instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the vectors, encoded in the "op:size" field. It can have the
                          following values:

                          S8           when op = 0, size = 00

                          S16          when op = 0, size = 01

                          S32          when op = 0, size = 10

                          U8           when op = 1, size = 00

                          U16          when op = 1, size = 01

                          U32          when op = 1, size = 10

                          It is RESERVED when:

                          .      op = 0, size = 11.

                          .      op = 1, size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               h = elements DIV 2;

               for r = 0 to regs-1
                   for e = 0 to h-1
                        op1 = Elem[D[m+r],2*e,esize];      op2 = Elem[D[m+r],2*e+1,esize];
                        result = Int(op1, unsigned) + Int(op2, unsigned);
                        Elem[D[d+r],e,2*esize] = Elem[D[d+r],e,2*esize] + result;');
INSERT INTO "instructions" VALUES('ARM','VPADD','Vector Pairwise Add (floating-point) adds adjacent pairs of elements of two vectors, and places the results in the       (F8.1.144)
destination vector.

The operands and result are doubleword vectors.

The operand and result elements are 32-bit floating-point numbers.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 1 0 D 0 sz                   Vn           Vd        1 1 0 1 N Q M 0              Vm




A1 variant

VPADD{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


Decode for this encoding

 if sz == ''1'' || Q == ''1'' then UNDEFINED;
 esize = 32;    elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 1 1 1 1 0 D 0 sz                   Vn           Vd        1 1 0 1 N Q M 0              Vm




T1 variant

VPADD{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


Decode for this encoding

 if sz == ''1'' || Q == ''1'' then UNDEFINED;
 esize = 32;    elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VPADD instruction must be
                unconditional. ARM strongly recommends that a T32 VPADD instruction is unconditional, see
                Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

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

<Dn>            Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>            Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.
        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();   CheckAdvSIMDEnabled();
               bits(64) dest;
               h = elements DIV 2;

               for e = 0 to h-1
                   Elem[dest,e,esize]   = FPAdd(Elem[D[n],2*e,esize], Elem[D[n],2*e+1,esize],
        StandardFPSCRValue());
                   Elem[dest,e+h,esize] = FPAdd(Elem[D[m],2*e,esize], Elem[D[m],2*e+1,esize],
        StandardFPSCRValue());

               D[d] = dest;');
INSERT INTO "instructions" VALUES('ARM','VPADDL','Vector Pairwise Add Long adds adjacent pairs of elements of two vectors, and places the results in the destination       (F8.1.146)
vector.

The vectors can be doubleword or quadword. The operand elements can be 8-bit, 16-bit, or 32-bit integers. The
result elements are twice the length of the operand elements.

The following figure shows an example of the operation of VPADDL doubleword operation for data type S16.

                                                                                  Dm




                                                                                             +             +




                                                                                  Dd

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                 0
   1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                        Vd       0 0 1 0 op Q M 0             Vm




64-bit SIMD vector variant

Applies when Q = 0.

VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 unsigned = (op == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                        Vd       0 0 1 0 op Q M 0             Vm
        64-bit SIMD vector variant

        Applies when Q = 0.

        VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         unsigned = (op == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VPADDL instruction must be
                          unconditional. ARM strongly recommends that a T32 VPADDL instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the vectors, encoded in the "op:size" field. It can have the
                          following values:

                          S8           when op = 0, size = 00

                          S16          when op = 0, size = 01

                          S32          when op = 0, size = 10

                          U8           when op = 1, size = 00

                          U16          when op = 1, size = 01

                          U32          when op = 1, size = 10

                          It is RESERVED when:

                          .      op = 0, size = 11.

                          .      op = 1, size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               h = elements DIV 2;

               for r = 0 to regs-1
                   for e = 0 to h-1
                        op1 = Elem[D[m+r],2*e,esize];      op2 = Elem[D[m+r],2*e+1,esize];
                        result = Int(op1, unsigned) + Int(op2, unsigned);
                        Elem[D[d+r],e,2*esize] = result<2*esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VPMAX','Vector Pairwise Maximum compares adjacent pairs of elements in two doubleword vectors, and copies the larger       (F8.1.147)
of each pair into the corresponding element in the destination doubleword vector.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 1 0 D 0 0                    Vn           Vd        1 1 1 1 N 0 M 0              Vm
                                   op sz                                              Q


A1 variant

VPMAX{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


Decode for this encoding

 if sz == ''1'' || Q == ''1'' then UNDEFINED;
 maximum = (op == ''0'');      esize = 32;  elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 1 1 1 1 0 D 0 0                    Vn           Vd        1 1 1 1 N 0 M 0              Vm
                                   op sz                                              Q


T1 variant

VPMAX{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


Decode for this encoding

 if sz == ''1'' || Q == ''1'' then UNDEFINED;
 maximum = (op == ''0'');      esize = 32;  elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VPMAX or VPMIN instruction must be
                unconditional. ARM strongly recommends that a T32 VPMAX or VPMIN instruction is unconditional,
                see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

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

<Dn>            Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>            Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.
        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();   CheckAdvSIMDEnabled();
               bits(64) dest;
               h = elements DIV 2;

               for e = 0 to h-1
                   op1 = Elem[D[n],2*e,esize];   op2 = Elem[D[n],2*e+1,esize];
                   Elem[dest,e,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else
        FPMin(op1,op2,StandardFPSCRValue());
                   op1 = Elem[D[m],2*e,esize];   op2 = Elem[D[m],2*e+1,esize];
                   Elem[dest,e+h,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else
        FPMin(op1,op2,StandardFPSCRValue());

               D[d] = dest;');
INSERT INTO "instructions" VALUES('ARM','VPMIN','Vector Pairwise Minimum compares adjacent pairs of elements in two doubleword vectors, and copies the smaller       (F8.1.149)
of each pair into the corresponding element in the destination doubleword vector.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 1 0 D 1 0                    Vn           Vd        1 1 1 1 N 0 M 0              Vm
                                   op sz                                              Q


A1 variant

VPMIN{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


Decode for this encoding

 if sz == ''1'' || Q == ''1'' then UNDEFINED;
 maximum = (op == ''0'');      esize = 32;  elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 1 1 1 1 0 D 1 0                    Vn           Vd        1 1 1 1 N 0 M 0              Vm
                                   op sz                                              Q


T1 variant

VPMIN{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


Decode for this encoding

 if sz == ''1'' || Q == ''1'' then UNDEFINED;
 maximum = (op == ''0'');      esize = 32;  elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VPMAX or VPMIN instruction must be
                unconditional. ARM strongly recommends that a T32 VPMAX or VPMIN instruction is unconditional,
                see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

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

<Dn>            Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>            Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.
        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();   CheckAdvSIMDEnabled();
               bits(64) dest;
               h = elements DIV 2;

               for e = 0 to h-1
                   op1 = Elem[D[n],2*e,esize];   op2 = Elem[D[n],2*e+1,esize];
                   Elem[dest,e,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else
        FPMin(op1,op2,StandardFPSCRValue());
                   op1 = Elem[D[m],2*e,esize];   op2 = Elem[D[m],2*e+1,esize];
                   Elem[dest,e+h,esize] = if maximum then FPMax(op1,op2,StandardFPSCRValue()) else
        FPMin(op1,op2,StandardFPSCRValue());

               D[d] = dest;');
INSERT INTO "instructions" VALUES('ARM','VPOP','Pop SIMD&FP registers from Stack loads multiple consecutive Advanced SIMD and floating-point register file       (F8.1.151)
registers from the stack

This instruction is an alias of the VLDM, VLDMDB, VLDMIA instruction. This means that:

.      The encodings in this description are named to match the encodings of VLDM, VLDMDB, VLDMIA.

.      The description of VLDM, VLDMDB, VLDMIA gives the operational pseudocode for this instruction.


A1


  31        28 27 26 25 24 23 22 21 20 19         16 15      12 11 10 9 8 7                          0
     !=1111     1 1 0 0 1 D 1 1 1 1 0 1                   Vd       1 0 1 1                imm8
      cond                P U       W        Rn


Increment After variant

VPOP{<c>}{<q>}{.<size>} <dreglist>

is equivalent to

VLDM{<c>}{<q>}{.<size>} SP!, <dreglist>

and is always the preferred disassembly.


A2


  31        28 27 26 25 24 23 22 21 20 19         16 15      12 11 10 9 8 7                          0
     !=1111     1 1 0 0 1 D 1 1 1 1 0 1                   Vd       1 0 1 0                imm8
      cond                P U       W        Rn


Increment After variant

VPOP{<c>}{<q>}{.<size>} <sreglist>

is equivalent to

VLDM{<c>}{<q>}{.<size>} SP!, <sreglist>

and is always the preferred disassembly.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                 0 15       12 11 10 9 8 7                          0
   1 1 1 0 1 1 0 0 1 D 1 1 1 1 0 1                        Vd       1 0 1 1                imm8
                          P U       W        Rn


Increment After variant

VPOP{<c>}{<q>}{.<size>} <dreglist>

is equivalent to

VLDM{<c>}{<q>}{.<size>} SP!, <dreglist>

and is always the preferred disassembly.
        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3                     0 15         12 11 10 9 8 7                              0
            1 1 1 0 1 1 0 0 1 D 1 1 1 1 0 1                            Vd       1 0 1 0                 imm8
                                    P U       W         Rn


        Increment After variant

        VPOP{<c>}{<q>}{.<size>} <sreglist>

        is equivalent to

        VLDM{<c>}{<q>}{.<size>} SP!, <sreglist>

        and is always the preferred disassembly.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <size>            An optional data size specifier. If present, it must be equal to the size in bits, 32 or 64, of the registers
                          being transferred.

        <sreglist>        Is the list of consecutively numbered 32-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "Vd:D", and "imm8" is set to the number of registers in the list. The list must
                          contain at least one register.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list. The
                          list must contain at least one register, and must not contain more than 16 registers.


        Operation for all encodings

        The description of VLDM, VLDMDB, VLDMIA gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VPUSH','Push SIMD&FP registers to Stack stores multiple consecutive registers from the Advanced SIMD and       (F8.1.152)
floating-point register file to the stack

This instruction is an alias of the VSTM, VSTMDB, VSTMIA instruction. This means that:

.      The encodings in this description are named to match the encodings of VSTM, VSTMDB, VSTMIA.

.      The description of VSTM, VSTMDB, VSTMIA gives the operational pseudocode for this instruction.


A1


  31       28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7                          0
     !=1111     1 1 0 1 0 D 1 0 1 1 0 1                    Vd       1 0 1 1                imm8
      cond                 P U       W        Rn


Decrement Before variant

VPUSH{<c>}{<q>}{.<size>} <dreglist>

is equivalent to

VSTMDB{<c>}{<q>}{.<size>} SP!, <dreglist>

and is always the preferred disassembly.


A2


  31       28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7                          0
     !=1111     1 1 0 1 0 D 1 0 1 1 0 1                    Vd       1 0 1 0                imm8
      cond                 P U       W        Rn


Decrement Before variant

VPUSH{<c>}{<q>}{.<size>} <sreglist>

is equivalent to

VSTMDB{<c>}{<q>}{.<size>} SP!, <sreglist>

and is always the preferred disassembly.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7                          0
   1 1 1 0 1 1 0 1 0 D 1 0 1 1 0 1                         Vd       1 0 1 1                imm8
                           P U       W        Rn


Decrement Before variant

VPUSH{<c>}{<q>}{.<size>} <dreglist>

is equivalent to

VSTMDB{<c>}{<q>}{.<size>} SP!, <dreglist>

and is always the preferred disassembly.
        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3                     0 15         12 11 10 9 8 7                              0
            1 1 1 0 1 1 0 1 0 D 1 0 1 1 0 1                            Vd       1 0 1 0                 imm8
                                    P U       W         Rn


        Decrement Before variant

        VPUSH{<c>}{<q>}{.<size>} <sreglist>

        is equivalent to

        VSTMDB{<c>}{<q>}{.<size>} SP!, <sreglist>

        and is always the preferred disassembly.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <size>            An optional data size specifier. If present, it must be equal to the size in bits, 32 or 64, of the registers
                          being transferred.

        <sreglist>        Is the list of consecutively numbered 32-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "Vd:D", and "imm8" is set to the number of registers in the list. The list must
                          contain at least one register.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list. The
                          list must contain at least one register, and must not contain more than 16 registers.


        Operation for all encodings

        The description of VSTM, VSTMDB, VSTMIA gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VQABS','Vector Saturating Absolute takes the absolute value of each element in a vector, and places the results in the       (F8.1.153)
destination vector.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                  0
   1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                        Vd        0 1 1 1 0 Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQABS{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VQABS{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                        Vd        0 1 1 1 0 Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQABS{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VQABS{<c>}{<q>}.<dt> <Qd>, <Qm>
        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQABS instruction must be
                          unconditional. ARM strongly recommends that a T32 VQABS instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the vectors, encoded in the "size" field. It can have the following
                          values:

                          S8           when size = 00

                          S16          when size = 01

                          S32          when size = 10

                          It is RESERVED when size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        result = Abs(SInt(Elem[D[m+r],e,esize]));
                        (Elem[D[d+r],e,esize], sat) = SignedSatQ(result, esize);
                        if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQADD','Vector Saturating Add adds the values of corresponding elements of two vectors, and places the results in the       (F8.1.154)
destination vector.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19            16 15      12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 U 0 D size                   Vn           Vd        0 0 0 0 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQADD{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VQADD{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 U 1 1 1 1 0 D size                   Vn           Vd        0 0 0 0 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQADD{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VQADD{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Qm>
        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         unsigned = (U == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQADD instruction must be
                          unconditional. ARM strongly recommends that a T32 VQADD instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the vectors, encoded in the "U:size" field. It can have the
                          following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          S64          when U = 0, size = 11

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

                          U64          when U = 1, size = 11

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        sum = Int(Elem[D[n+r],e,esize], unsigned) + Int(Elem[D[m+r],e,esize], unsigned);
                        (Elem[D[d+r],e,esize], sat) = SatQ(sum, esize, unsigned);
                        if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQDMLAL','Vector Saturating Doubling Multiply Accumulate Long multiplies corresponding elements in two doubleword       (F8.1.155)
vectors, doubles the products, and accumulates the results into the elements of a quadword vector.

The second operand can be a scalar instead of a vector. For more information about scalars see Advanced SIMD
scalars on page F5-2586.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19            16 15      12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 0 1 D !=11                   Vn           Vd        1 0 0 1 N 0 M 0              Vm
                                    size                                    op


A1 variant

VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
 add = (op == ''0'');
 scalar_form = FALSE;     d = UInt(D:Vd);    n = UInt(N:Vn);   m = UInt(M:Vm);
 esize = 8 << UInt(size);     elements = 64 DIV esize;


A2


  31 30 29 28 27 26 25 24 23 22 21 20 19            16 15      12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 0 1 D !=11                   Vn           Vd        0 0 1 1 N 1 M 0              Vm
                                    size                                op


A2 variant

VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>]


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
 add = (op == ''0'');
 scalar_form = TRUE;     d = UInt(D:Vd);    n = UInt(N:Vn);
 if size == ''01'' then esize = 16;      elements = 4;    m = UInt(Vm<2:0>);      index = UInt(M:Vm<3>);
 if size == ''10'' then esize = 32;      elements = 2;    m = UInt(Vm);      index = UInt(M);
        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 0 1 1 1 1 1 D !=11                    Vn           Vd      1 0 0 1 N 0 M 0                 Vm
                                              size                                    op


        T1 variant

        VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
         add = (op == ''0'');
         scalar_form = FALSE;      d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);
         esize = 8 << UInt(size);       elements = 64 DIV esize;


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 0 1 1 1 1 1 D !=11                    Vn           Vd      0 0 1 1 N 1 M 0                 Vm
                                              size                             op


        T2 variant

        VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>]


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
         add = (op == ''0'');
         scalar_form = TRUE;      d = UInt(D:Vd);     n = UInt(N:Vn);
         if size == ''01'' then esize = 16;        elements = 4;   m = UInt(Vm<2:0>);   index = UInt(M:Vm<3>);
         if size == ''10'' then esize = 32;        elements = 2;   m = UInt(Vm);   index = UInt(M);


        Notes for all encodings

        Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQDMLAL or VQDMLSL instruction must
                          be unconditional. ARM strongly recommends that a T32 VQDMLAL or VQDMLSL instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "size" field. It can have the
                          following values:

                          S16          when size = 01

                          S32          when size = 10

                          It is RESERVED when:

                          .      size = 00.

                          .      size = 11.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.
<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          For encoding A1 and T1: is the 64-bit name of the second SIMD&FP source register, encoded in
              the "M:Vm" field.

              For encoding A2 and T2: is the 64-bit name of the second SIMD&FP source register, encoded in
              the "Vm<2:0>" field when <dt> is S16, otherwise the "Vm" field.

<index>       Is the element index in the range 0 to 3, encoded in the "M:Vm<3>" field when <dt> is S16,
              otherwise in range 0 to 1, encoded in the "M" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();    CheckAdvSIMDEnabled();
    if scalar_form then op2 = SInt(Elem[Din[m],index,esize]);
    for e = 0 to elements-1
        if !scalar_form then op2 = SInt(Elem[Din[m],e,esize]);
        op1 = SInt(Elem[Din[n],e,esize]);
        // The following only saturates if both op1 and op2 equal -(2^(esize-1))
        (product, sat1) = SignedSatQ(2*op1*op2, 2*esize);
        if add then
            result = SInt(Elem[Qin[d>>1],e,2*esize]) + SInt(product);
        else
            result = SInt(Elem[Qin[d>>1],e,2*esize]) - SInt(product);
        (Elem[Q[d>>1],e,2*esize], sat2) = SignedSatQ(result, 2*esize);
        if sat1 || sat2 then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQDMLSL','        Vector Saturating Doubling Multiply Subtract Long multiplies corresponding elements in two doubleword vectors,       (F8.1.156)
        subtracts double the products from corresponding elements of a quadword vector, and places the results in the same
        quadword vector.

        The second operand can be a scalar instead of a vector. For more information about scalars see Advanced SIMD
        scalars on page F5-2586.

        If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
        occurs. For details see Pseudocode description of saturation on page E1-2375.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 0 1 D !=11                  Vn           Vd      1 0 1 1 N 0 M 0             Vm
                                            size                                 op


        A1 variant

        VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
         add = (op == ''0'');
         scalar_form = FALSE;     d = UInt(D:Vd);    n = UInt(N:Vn);   m = UInt(M:Vm);
         esize = 8 << UInt(size);     elements = 64 DIV esize;


        A2


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 0 1 D !=11                  Vn           Vd      0 1 1 1 N 1 M 0             Vm
                                            size                              op


        A2 variant

        VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>]


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
         add = (op == ''0'');
         scalar_form = TRUE;     d = UInt(D:Vd);    n = UInt(N:Vn);
         if size == ''01'' then esize = 16;      elements = 4;    m = UInt(Vm<2:0>);   index = UInt(M:Vm<3>);
         if size == ''10'' then esize = 32;      elements = 2;    m = UInt(Vm);   index = UInt(M);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15        12 11 10 9 8 7 6 5 4 3                   0
  1 1 1 0 1 1 1 1 1 D !=11                  Vn           Vd       1 0 1 1 N 0 M 0                Vm
                                  size                                       op


T1 variant

VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
 add = (op == ''0'');
 scalar_form = FALSE;  d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);
 esize = 8 << UInt(size);   elements = 64 DIV esize;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15        12 11 10 9 8 7 6 5 4 3                   0
  1 1 1 0 1 1 1 1 1 D !=11                  Vn           Vd       0 1 1 1 N 1 M 0                Vm
                                  size                               op


T2 variant

VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>]


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
 add = (op == ''0'');
 scalar_form = TRUE;  d = UInt(D:Vd);     n = UInt(N:Vn);
 if size == ''01'' then esize = 16;    elements = 4;   m = UInt(Vm<2:0>);      index = UInt(M:Vm<3>);
 if size == ''10'' then esize = 32;    elements = 2;   m = UInt(Vm);      index = UInt(M);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VQDMLAL or VQDMLSL instruction must
              be unconditional. ARM strongly recommends that a T32 VQDMLAL or VQDMLSL instruction is
              unconditional, see Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "size" field. It can have the
              following values:

              S16          when size = 01

              S32          when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.
        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              For encoding A1 and T1: is the 64-bit name of the second SIMD&FP source register, encoded in
                          the "M:Vm" field.

                          For encoding A2 and T2: is the 64-bit name of the second SIMD&FP source register, encoded in
                          the "Vm<2:0>" field when <dt> is S16, otherwise the "Vm" field.

        <index>           Is the element index in the range 0 to 3, encoded in the "M:Vm<3>" field when <dt> is S16,
                          otherwise in range 0 to 1, encoded in the "M" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();     CheckAdvSIMDEnabled();
               if scalar_form then op2 = SInt(Elem[Din[m],index,esize]);
               for e = 0 to elements-1
                   if !scalar_form then op2 = SInt(Elem[Din[m],e,esize]);
                   op1 = SInt(Elem[Din[n],e,esize]);
                   // The following only saturates if both op1 and op2 equal -(2^(esize-1))
                   (product, sat1) = SignedSatQ(2*op1*op2, 2*esize);
                   if add then
                        result = SInt(Elem[Qin[d>>1],e,2*esize]) + SInt(product);
                   else
                        result = SInt(Elem[Qin[d>>1],e,2*esize]) - SInt(product);
                   (Elem[Q[d>>1],e,2*esize], sat2) = SignedSatQ(result, 2*esize);
                   if sat1 || sat2 then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQDMULH','Vector Saturating Doubling Multiply Returning High Half multiplies corresponding elements in two vectors,       (F8.1.157)
doubles the results, and places the most significant half of the final results in the destination vector. The results are
truncated, for rounded results see VQRDMULH.

The second operand can be a scalar instead of a vector. For more information about scalars see Advanced SIMD
scalars on page F5-2586.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 0 0 1 0 0 D size                   Vn           Vd        1 0 1 1 N Q M 0                Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQDMULH{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VQDMULH{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size == ''00'' || size == ''11'' then UNDEFINED;
 scalar_form = FALSE;     esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


A2


  31 30 29 28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 0 0 1 Q 1 D !=11                   Vn           Vd        1 1 0 0 N 1 M 0                Vm
                                    size


64-bit SIMD vector variant

Applies when Q = 0.

VQDMULH{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm[x]>


128-bit SIMD vector variant

Applies when Q = 1.

VQDMULH{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm[x]>
        Decode for all variants of this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
         scalar_form = TRUE;     d = UInt(D:Vd);  n = UInt(N:Vn);    regs = if Q == ''0'' then 1 else 2;
         if size == ''01'' then esize = 16;     elements = 4;   m = UInt(Vm<2:0>);    index = UInt(M:Vm<3>);
         if size == ''10'' then esize = 32;     elements = 2;   m = UInt(Vm);    index = UInt(M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3               0 15         12 11 10 9 8 7 6 5 4 3              0
            1 1 1 0 1 1 1 1 0 D size                 Vn         Vd         1 0 1 1 N Q M 0           Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VQDMULH{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VQDMULH{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size == ''00'' || size == ''11'' then UNDEFINED;
         scalar_form = FALSE;     esize = 8 << UInt(size);   elements = 64 DIV esize;
         d = UInt(D:Vd);     n = UInt(N:Vn);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3               0 15         12 11 10 9 8 7 6 5 4 3              0
            1 1 1 Q 1 1 1 1 1 D !=11                 Vn         Vd         1 1 0 0 N 1 M 0           Vm
                                          size


        64-bit SIMD vector variant

        Applies when Q = 0.

        VQDMULH{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm[x]>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VQDMULH{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm[x]>


        Decode for all variants of this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
         scalar_form = TRUE;     d = UInt(D:Vd);  n = UInt(N:Vn);    regs = if Q == ''0'' then 1 else 2;
         if size == ''01'' then esize = 16;     elements = 4;   m = UInt(Vm<2:0>);    index = UInt(M:Vm<3>);
         if size == ''10'' then esize = 32;     elements = 2;   m = UInt(Vm);    index = UInt(M);
Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VQDMULH instruction must be
              unconditional. ARM strongly recommends that a T32 VQDMULH instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "size" field. It can have the
              following values:

              S16          when size = 01

              S32          when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<Qd>          For encoding A1 and T1: is the 128-bit name of the SIMD&FP destination register, encoded in the
              "D:Vd" field, as <Qd>*2.

              For encoding A2 and T2: is the 128-bit name of the SIMD&FP destination register, encoded in the
              "D:Vd" field as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm[x]>       The scalar for either a quadword or a doubleword scalar operation. If <dt> is S16, Dm is restricted to
              D0-D7. If <dt> is S32, Dm is restricted to D0-D15.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     if scalar_form then op2 = SInt(Elem[D[m],index,esize]);
     for r = 0 to regs-1
         for e = 0 to elements-1
             if !scalar_form then op2 = SInt(Elem[D[m+r],e,esize]);
             op1 = SInt(Elem[D[n+r],e,esize]);
             // The following only saturates if both op1 and op2 equal -(2^(esize-1))
             (result, sat) = SignedSatQ((2*op1*op2) >> esize, esize);
             Elem[D[d+r],e,esize] = result;
             if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQDMULL','        Vector Saturating Doubling Multiply Long multiplies corresponding elements in two doubleword vectors, doubles       (F8.1.158)
        the products, and places the results in a quadword vector.

        The second operand can be a scalar instead of a vector. For more information about scalars see Advanced SIMD
        scalars on page F5-2586.

        If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
        occurs. For details see Pseudocode description of saturation on page E1-2375.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 0 1 D !=11                  Vn           Vd      1 1 0 1 N 0 M 0             Vm
                                            size


        A1 variant

        VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
         scalar_form = FALSE;     d = UInt(D:Vd);    n = UInt(N:Vn);   m = UInt(M:Vm);
         esize = 8 << UInt(size);     elements = 64 DIV esize;


        A2


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 0 1 D !=11                  Vn           Vd      1 0 1 1 N 1 M 0             Vm
                                            size


        A2 variant

        VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]>// Encoding T2/A2


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
         scalar_form = TRUE;     d = UInt(D:Vd);    n = UInt(N:Vn);
         if size == ''01'' then esize = 16;      elements = 4;    m = UInt(Vm<2:0>);   index = UInt(M:Vm<3>);
         if size == ''10'' then esize = 32;      elements = 2;    m = UInt(Vm);   index = UInt(M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 0 1 1 1 1 1 D !=11                  Vn           Vd      1 1 0 1 N 0 M 0             Vm
                                            size
T1 variant

VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
 scalar_form = FALSE;  d = UInt(D:Vd);     n = UInt(N:Vn);       m = UInt(M:Vm);
 esize = 8 << UInt(size);   elements = 64 DIV esize;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15          12 11 10 9 8 7 6 5 4 3                     0
  1 1 1 0 1 1 1 1 1 D !=11                   Vn             Vd        1 0 1 1 N 1 M 0                Vm
                                  size


T2 variant

VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]>// Encoding T2/A2


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' || Vd<0> == ''1'' then UNDEFINED;
 scalar_form = TRUE;  d = UInt(D:Vd);     n = UInt(N:Vn);
 if size == ''01'' then esize = 16;     elements = 4;    m = UInt(Vm<2:0>);        index = UInt(M:Vm<3>);
 if size == ''10'' then esize = 32;     elements = 2;    m = UInt(Vm);       index = UInt(M);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VQDMULL instruction must be
              unconditional. ARM strongly recommends that a T32 VQDMULL instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "size" field. It can have the
              following values:

              S16          when size = 01

              S32          when size = 10

              It is RESERVED when:

              .      size = 00.

              .      size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm[x]>       The scalar for a scalar operation. If <dt> is S16, Dm is restricted to D0-D7. If <dt> is S32, Dm is restricted
              to D0-D15.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.
        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();   CheckAdvSIMDEnabled();
               if scalar_form then op2 = SInt(Elem[Din[m],index,esize]);
               for e = 0 to elements-1
                   if !scalar_form then op2 = SInt(Elem[Din[m],e,esize]);
                   op1 = SInt(Elem[Din[n],e,esize]);
                   // The following only saturates if both op1 and op2 equal -(2^(esize-1))
                   (product, sat) = SignedSatQ(2*op1*op2, 2*esize);
                   Elem[Q[d>>1],e,2*esize] = product;
                   if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQMOVN','Vector Saturating Move and Narrow copies each element of the operand vector to the corresponding element of the       (F8.1.159)
destination vector.

The operand is a quadword vector. The elements can be any one of:

.      16-bit, 32-bit, or 64-bit signed integers.

.      16-bit, 32-bit, or 64-bit unsigned integers.

The result is a doubleword vector. The elements are half the length of the operand vector elements. If the operand
is unsigned, the results are unsigned. If the operand is signed, the results can be signed or unsigned.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.

This instruction is used by the aliases VQRSHRN (zero), VQRSHRUN (zero), VQSHRN (zero), and VQSHRUN
(zero). See the Alias conditions on page F8-3618 table for details of when each alias is preferred.


A1


  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 3                0
   1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                         Vd       0 0 1 0        op   M 0      Vm




Signed result variant

Applies when op = 1x.

VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>


Unsigned result variant

Applies when op = 01.

VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm>


Decode for all variants of this encoding

 if op == ''00'' then SEE VMOVN;
 if size == ''11'' || Vm<0> == ''1'' then UNDEFINED;
 src_unsigned = (op == ''11'');       dest_unsigned = (op<0> == ''1'');
 esize = 8 << UInt(size);      elements = 64 DIV esize;
 d = UInt(D:Vd);     m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                       12 11 10 9 8 7 6 5 4 3                0
   1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                         Vd       0 0 1 0        op   M 0      Vm




Signed result variant

Applies when op = 1x.
        VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>


        Unsigned result variant

        Applies when op = 01.

        VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm>


        Decode for all variants of this encoding

         if op == ''00'' then SEE VMOVN;
         if size == ''11'' || Vm<0> == ''1'' then UNDEFINED;
         src_unsigned = (op == ''11'');        dest_unsigned = (op<0> == ''1'');
         esize = 8 << UInt(size);        elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);


        Alias conditions


                                Alias                    is preferred when

                                VQRSHRN (zero)           Never

                                VQRSHRUN (zero)          Never

                                VQSHRN (zero)            Never

                                VQSHRUN (zero)           Never



        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQMOVN or VQMOVUN instruction must
                          be unconditional. ARM strongly recommends that a T32 VQMOVN or VQMOVUN instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              For the signed result variant: is the data type for the elements of the operand, encoded in the
                          "op:size" field. It can have the following values:

                          S16          when op = 10, size = 00

                          S32          when op = 10, size = 01

                          S64          when op = 10, size = 10

                          U8           when op = 11, size = 00

                          U32          when op = 11, size = 01

                          U64          when op = 11, size = 10

                          It is RESERVED when:

                          .      op = 0x, size = xx.

                          .      op = 10, size = 11.

                          .      op = 11, size = 11.

                          For the unsigned result variant: is the data type for the elements of the operand, encoded in the "size"
                          field. It can have the following values:

                          S16          when size = 00

                          S32          when size = 01

                          S64          when size = 10

                          It is RESERVED when size = 11.

        <Dd>              Is the 64-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field.
<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();    CheckAdvSIMDEnabled();
    for e = 0 to elements-1
        operand = Int(Elem[Qin[m>>1],e,2*esize], src_unsigned);
        (Elem[D[d],e,esize], sat) = SatQ(operand, esize, dest_unsigned);
        if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQMOVUN','-R:VQMOVN');
INSERT INTO "instructions" VALUES('ARM','VQNEG','        Vector Saturating Negate negates each element in a vector, and places the results in the destination vector.       (F8.1.160)

        If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
        occurs. For details see Pseudocode description of saturation on page E1-2375.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                  0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                       Vd      0 1 1 1 1 Q M 0             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                       Vd      0 1 1 1 1 Q M 0             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm>
Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VQNEG instruction must be
              unconditional. ARM strongly recommends that a T32 VQNEG instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the vectors, encoded in the "size" field. It can have the following
              values:

              S8           when size = 00

              S16          when size = 01

              S32          when size = 10

              It is RESERVED when size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             result = -SInt(Elem[D[m+r],e,esize]);
             (Elem[D[d+r],e,esize], sat) = SignedSatQ(result, esize);
             if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQRDMULH','        Vector Saturating Rounding Doubling Multiply Returning High Half multiplies corresponding elements in two       (F8.1.161)
        vectors, doubles the results, and places the most significant half of the final results in the destination vector. The
        results are rounded. For truncated results see VQDMULH.

        The second operand can be a scalar instead of a vector. For more information about scalars see Advanced SIMD
        scalars on page F5-2586.

        If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
        occurs. For details see Pseudocode description of saturation on page E1-2375.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7 6 5 4 3                     0
            1 1 1 1 0 0 1 1 0 D size                  Vn           Vd       1 0 1 1 N Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VQRDMULH{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VQRDMULH{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size == ''00'' || size == ''11'' then UNDEFINED;
         scalar_form = FALSE;     esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        A2


           31 30 29 28 27 26 25 24 23 22 21 20 19           16 15      12 11 10 9 8 7 6 5 4 3                     0
            1 1 1 1 0 0 1 Q 1 D !=11                  Vn           Vd       1 1 0 1 N 1 M 0                 Vm
                                            size


        64-bit SIMD vector variant

        Applies when Q = 0.

        VQRDMULH{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm[x]>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VQRDMULH{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm[x]>
Decode for all variants of this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
 scalar_form = TRUE;  d = UInt(D:Vd);  n = UInt(N:Vn);    regs = if Q == ''0'' then 1 else 2;
 if size == ''01'' then esize = 16;  elements = 4;   m = UInt(Vm<2:0>);     index = UInt(M:Vm<3>);
 if size == ''10'' then esize = 32;  elements = 2;   m = UInt(Vm);     index = UInt(M);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 1 1 1 1 1 0 D size               Vn          Vd         1 0 1 1 N Q M 0             Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQRDMULH{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VQRDMULH{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size == ''00'' || size == ''11'' then UNDEFINED;
 scalar_form = FALSE;  esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  n = UInt(N:Vn);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 Q 1 1 1 1 1 D !=11               Vn          Vd         1 1 0 1 N 1 M 0             Vm
                               size


64-bit SIMD vector variant

Applies when Q = 0.

VQRDMULH{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm[x]>


128-bit SIMD vector variant

Applies when Q = 1.

VQRDMULH{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm[x]>


Decode for all variants of this encoding

 if size == ''11'' then SEE "Related encodings";
 if size == ''00'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
 scalar_form = TRUE;  d = UInt(D:Vd);  n = UInt(N:Vn);    regs = if Q == ''0'' then 1 else 2;
 if size == ''01'' then esize = 16;  elements = 4;   m = UInt(Vm<2:0>);     index = UInt(M:Vm<3>);
 if size == ''10'' then esize = 32;  elements = 2;   m = UInt(Vm);     index = UInt(M);
        Notes for all encodings

        Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQRDMULH instruction must be
                          unconditional. ARM strongly recommends that a T32 VQRDMULH instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "size" field. It can have the
                          following values:

                          S16          when size = 01

                          S32          when size = 10

                          It is RESERVED when:

                          .      size = 00.

                          .      size = 11.

        <Qd>              For encoding A1 and T1: is the 128-bit name of the SIMD&FP destination register, encoded in the
                          "D:Vd" field, as <Qd>*2.

                          For encoding A2 and T2: is the 128-bit name of the SIMD&FP destination register, encoded in the
                          "D:Vd" field as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm[x]>           The scalar for either a quadword or a doubleword scalar operation. If <dt> is S16, Dm is restricted to
                          D0-D7. If <dt> is S32, Dm is restricted to D0-D15.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               round_const = 1 << (esize-1);
               if scalar_form then op2 = SInt(Elem[D[m],index,esize]);
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        op1 = SInt(Elem[D[n+r],e,esize]);
                        if !scalar_form then op2 = SInt(Elem[D[m+r],e,esize]);
                        (result, sat) = SignedSatQ((2*op1*op2 + round_const) >> esize, esize);
                        Elem[D[d+r],e,esize] = result;
                        if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQRSHL','Vector Saturating Rounding Shift Left takes each element in a vector, shifts them by a value from the least       (F8.1.162)
significant byte of the corresponding element of a second vector, and places the results in the destination vector. If
the shift value is positive, the operation is a left shift. Otherwise, it is a right shift.

For truncated results see VQSHL (register).

The first operand and result elements are the same data type, and can be any one of:

.      8-bit, 16-bit, 32-bit, or 64-bit signed integers.

.      8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

The second operand is a signed integer of the same size.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19              16 15        12 11 10 9 8 7 6 5 4 3                0
   1 1 1 1 0 0 1 U 0 D size                     Vn            Vd       0 1 0 1 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQRSHL{<c>}{<q>}.<dt> {<Dd>,} <Dm>, <Dn>


128-bit SIMD vector variant

Applies when Q = 1.

VQRSHL{<c>}{<q>}.<dt> {<Qd>,} <Qm>, <Qn>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);      elements = 64 DIV esize;
 d = UInt(D:Vd);     m = UInt(M:Vm);     n = UInt(N:Vn);      regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                     0 15         12 11 10 9 8 7 6 5 4 3                0
   1 1 1 U 1 1 1 1 0 D size                     Vn            Vd       0 1 0 1 N Q M 1              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VQRSHL{<c>}{<q>}.<dt> {<Dd>,} <Dm>, <Dn>
        128-bit SIMD vector variant

        Applies when Q = 1.

        VQRSHL{<c>}{<q>}.<dt> {<Qd>,} <Qm>, <Qn>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
         unsigned = (U == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);    n = UInt(N:Vn);    regs = if Q == ''0'' then 1 else 2;


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQRSHL instruction must be
                          unconditional. ARM strongly recommends that a T32 VQRSHL instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the vectors, encoded in the "U:size" field. It can have the
                          following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          S64          when U = 0, size = 11

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

                          U64          when U = 1, size = 11

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

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

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        shift = SInt(Elem[D[n+r],e,esize]<7:0>);
                        round_const = 1 << (-1-shift); // 0 for left shift, 2^(n-1) for right shift
                        operand = Int(Elem[D[m+r],e,esize], unsigned);
                        (result, sat) = SatQ((operand + round_const) << shift, esize, unsigned);
                        Elem[D[d+r],e,esize] = result;
                        if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQRSHRN','Vector Saturating Rounding Shift Right, Narrow takes each element in a quadword vector of integers, right shifts       (F8.1.163)
them by an immediate value, and places the signed rounded results in a doubleword vector

This instruction is an alias of the VQMOVN, VQMOVUN instruction. This means that:

.      The encodings in this description are named to match the encodings of VQMOVN, VQMOVUN.

.      The description of VQMOVN, VQMOVUN gives the operational pseudocode for this instruction.


A1


  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 3                   0
   1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd       0 0 1 0 1 x M 0              Vm
                                                                                   op


Signed result variant

VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0

is equivalent to

VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>

and is never the preferred disassembly.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                        Vd       0 0 1 0 1 x M 0              Vm
                                                                                   op


Signed result variant

VQRSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0

is equivalent to

VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>

and is never the preferred disassembly.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VQMOVN or VQMOVUN instruction must
                be unconditional. ARM strongly recommends that a T32 VQMOVN or VQMOVUN instruction is
                unconditional, see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<dt>            Is the data type for the elements of the operand, encoded in the "op:size" field. It can have the
                following values:

                S16          when op = 10, size = 00

                S32          when op = 10, size = 01

                S64          when op = 10, size = 10

                U8           when op = 11, size = 00

                U32          when op = 11, size = 01
                          U64         when op = 11, size = 10

                          It is RESERVED when:

                          .      op = 0x, size = xx.

                          .      op = 10, size = 11.

                          .      op = 11, size = 11.

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

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.


        Operation for all encodings

        The description of VQMOVN, VQMOVUN gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VQRSHRUN','Vector Saturating Rounding Shift Right, Narrow takes each element in a quadword vector of integers, right shifts       (F8.1.164)
them by an immediate value, and places the rounded results in a doubleword vector.

For truncated results, see VQSHL (register).

The operand elements must all be the same size, and can be any one of:

.      16-bit, 32-bit, or 64-bit signed integers.

.      16-bit, 32-bit, or 64-bit unsigned integers.

The result elements are half the width of the operand elements. If the operand elements are signed, the results can
be either signed or unsigned. If the operand elements are unsigned, the result elements must also be unsigned.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21                  16 15      12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 U 1 D                    imm6             Vd        1 0 0 op 0 1 M 1             Vm




Signed result variant

Applies when !(imm6 == 000xxx) && op = 1.

VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


Unsigned result variant

Applies when U = 1 && !(imm6 == 000xxx) && op = 0.

VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


Decode for all variants of this encoding

 if imm6 == ''000xxx'' then SEE "Related encodings";
 if U == ''0'' && op == ''0'' then SEE VRSHRN;
 if Vm<0> == ''1'' then UNDEFINED;
 case imm6 of
      when "001xxx"    esize = 8;    elements = 8;   shift_amount = 16 - UInt(imm6);
      when "01xxxx"    esize = 16;    elements = 4;   shift_amount = 32 - UInt(imm6);
      when "1xxxxx"    esize = 32;    elements = 2;   shift_amount = 64 - UInt(imm6);
 src_unsigned = (U == ''1'' && op == ''1'');       dest_unsigned = (U == ''1'');
 d = UInt(D:Vd);     m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5                       0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 U 1 1 1 1 1 D                    imm6             Vd        1 0 0 op 0 1 M 1             Vm
        Signed result variant

        Applies when !(imm6 == 000xxx) && op = 1.

        VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


        Unsigned result variant

        Applies when U = 1 && !(imm6 == 000xxx) && op = 0.

        VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


        Decode for all variants of this encoding

         if imm6 == ''000xxx'' then SEE "Related encodings";
         if U == ''0'' && op == ''0'' then SEE VRSHRN;
         if Vm<0> == ''1'' then UNDEFINED;
         case imm6 of
               when "001xxx"    esize = 8;    elements = 8;    shift_amount = 16 - UInt(imm6);
               when "01xxxx"    esize = 16;     elements = 4;   shift_amount = 32 - UInt(imm6);
               when "1xxxxx"    esize = 32;     elements = 2;   shift_amount = 64 - UInt(imm6);
         src_unsigned = (U == ''1'' && op == ''1'');         dest_unsigned = (U == ''1'');
         d = UInt(D:Vd);      m = UInt(M:Vm);


        Notes for all encodings

        Related encodings: One register and a modified immediate value on page F5-2596.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQRSHRN or VQRSHRUN instruction
                          must be unconditional. ARM strongly recommends that a T32 VQRSHRN or VQRSHRUN instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <type>            For the signed result variant: is the data type for the elements of the vectors, encoded in the "U"
                          field. It can have the following values:

                          S            when U = 0

                          U            when U = 1

                          For the unsigned result variant: is the data type for the elements of the vectors, encoded in the "U"
                          field. It can have the following values:

                          S            when U = 1

        <size>            Is the data size for the elements of the vectors, encoded in the "imm6<5:3>" field. It can have the
                          following values:

                          16           when imm6<5:3> = 001

                          32           when imm6<5:3> = 01x

                          64           when imm6<5:3> = 1xx

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

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

        <imm>             Is an immediate value, in the range 1 to <size>/2, encoded in the "imm6" field as <size>/2 - <imm>.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               round_const = 1 << (shift_amount - 1);
   for e = 0 to elements-1
       operand = Int(Elem[Qin[m>>1],e,2*esize], src_unsigned);
       (result, sat) = SatQ((operand + round_const) >> shift_amount, esize, dest_unsigned);
       Elem[D[d],e,esize] = result;
       if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQSHL','        Vector Saturating Shift Left (immediate) takes each element in a vector of integers, left shifts them by an immediate       (F8.1.166)
        value, and places the results in a second vector.

        The operand elements must all be the same size, and can be any one of:

        .       8-bit, 16-bit, 32-bit, or 64-bit signed integers.

        .       8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

        The result elements are the same size as the operand elements. If the operand elements are signed, the results can
        be either signed or unsigned. If the operand elements are unsigned, the result elements must also be unsigned.

        If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
        occurs. For details see Pseudocode description of saturation on page E1-2375.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                  16 15       12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 U 1 D                     imm6            Vd      0 1 1 op L Q M 1               Vm




        VQSHL, double, signed-result variant

        Applies when !(imm6 == 000xxx && L == 0) && op = 1 && Q = 0.

        VQSHL{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        VQSHL, quad, signed-result variant

        Applies when !(imm6 == 000xxx && L == 0) && op = 1 && Q = 1.

        VQSHL{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


        VQSHLU, double, unsigned-result variant

        Applies when U = 1 && !(imm6 == 000xxx && L == 0) && op = 0 && Q = 0.

        VQSHLU{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        VQSHLU, quad, unsigned-result variant

        Applies when U = 1 && !(imm6 == 000xxx && L == 0) && op = 0 && Q = 1.

        VQSHLU{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
         if U == ''0'' && op == ''0'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;    elements = 8;    shift_amount = UInt(imm6) - 8;
               when "001xxxx"    esize = 16;     elements = 4;   shift_amount = UInt(imm6) - 16;
               when "01xxxxx"    esize = 32;     elements = 2;   shift_amount = UInt(imm6) - 32;
     when "1xxxxxx"  esize = 64;    elements = 1;    shift_amount = UInt(imm6);
 src_unsigned = (U == ''1'' && op == ''1'');    dest_unsigned = (U == ''1'');
 d = UInt(D:Vd);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5                    0 15         12 11 10 9 8 7 6 5 4 3                  0
  1 1 1 U 1 1 1 1 1 D                   imm6             Vd       0 1 1 op L Q M 1              Vm




VQSHL, double, signed-result variant

Applies when !(imm6 == 000xxx && L == 0) && op = 1 && Q = 0.

VQSHL{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


VQSHL, quad, signed-result variant

Applies when !(imm6 == 000xxx && L == 0) && op = 1 && Q = 1.

VQSHL{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


VQSHLU, double, unsigned-result variant

Applies when U = 1 && !(imm6 == 000xxx && L == 0) && op = 0 && Q = 0.

VQSHLU{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


VQSHLU, quad, unsigned-result variant

Applies when U = 1 && !(imm6 == 000xxx && L == 0) && op = 0 && Q = 1.

VQSHLU{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


Decode for all variants of this encoding

 if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
 if U == ''0'' && op == ''0'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
     when "0001xxx"  esize = 8;    elements = 8;    shift_amount = UInt(imm6) - 8;
     when "001xxxx"  esize = 16;    elements = 4;    shift_amount = UInt(imm6) - 16;
     when "01xxxxx"  esize = 32;    elements = 2;    shift_amount = UInt(imm6) - 32;
     when "1xxxxxx"  esize = 64;    elements = 1;    shift_amount = UInt(imm6);
 src_unsigned = (U == ''1'' && op == ''1'');    dest_unsigned = (U == ''1'');
 d = UInt(D:Vd);  m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VQSHL or VQSHLU instruction must be
              unconditional. ARM strongly recommends that a T32 VQSHL or VQSHLU instruction is unconditional,
              see Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<type>        Is the data type for the elements of the vectors, encoded in the "U" field. It can have the following
              values:

              S            when U = 0
                          U            when U = 1

        <size>            Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
                          following values:

                          8            when L = 0, imm6<5:3> = 001

                          16           when L = 0, imm6<5:3> = 01x

                          32           when L = 0, imm6<5:3> = 1xx

                          64           when L = 1, imm6<5:3> = xxx

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

        <imm>             Is an immediate value, in the range 0 to <size>-1, encoded in the "imm6" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        operand = Int(Elem[D[m+r],e,esize], src_unsigned);
                        (result, sat) = SatQ(operand << shift_amount, esize, dest_unsigned);
                        Elem[D[d+r],e,esize] = result;
                        if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQSHLU','-R:VQSHL');
INSERT INTO "instructions" VALUES('ARM','VQSHRN','Vector Saturating Shift Right, Narrow takes each element in a quadword vector of integers, right shifts them by an       (F8.1.168)
immediate value, and places the signed truncated results in a doubleword vector

This instruction is an alias of the VQMOVN, VQMOVUN instruction. This means that:

.      The encodings in this description are named to match the encodings of VQMOVN, VQMOVUN.

.      The description of VQMOVN, VQMOVUN gives the operational pseudocode for this instruction.


A1


  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 3                   0
   1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd       0 0 1 0 1 x M 0              Vm
                                                                                   op


Signed result variant

VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0

is equivalent to

VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>

and is never the preferred disassembly.


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                        Vd       0 0 1 0 1 x M 0              Vm
                                                                                   op


Signed result variant

VQSHRN{<c>}{<q>}.<dt> <Dd>, <Qm>, #0

is equivalent to

VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm>

and is never the preferred disassembly.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VQMOVN or VQMOVUN instruction must
                be unconditional. ARM strongly recommends that a T32 VQMOVN or VQMOVUN instruction is
                unconditional, see Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<dt>            Is the data type for the elements of the operand, encoded in the "op:size" field. It can have the
                following values:

                S16          when op = 10, size = 00

                S32          when op = 10, size = 01

                S64          when op = 10, size = 10

                U8           when op = 11, size = 00

                U32          when op = 11, size = 01
                          U64         when op = 11, size = 10

                          It is RESERVED when:

                          .      op = 0x, size = xx.

                          .      op = 10, size = 11.

                          .      op = 11, size = 11.

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

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.


        Operation for all encodings

        The description of VQMOVN, VQMOVUN gives the operational pseudocode for this instruction.');
INSERT INTO "instructions" VALUES('ARM','VQSHRUN','Vector Saturating Shift Right, Narrow takes each element in a quadword vector of integers, right shifts them by an       (F8.1.169)
immediate value, and places the truncated results in a doubleword vector.

For rounded results, see VQRSHRN, VQRSHRUN.

The operand elements must all be the same size, and can be any one of:

.      16-bit, 32-bit, or 64-bit signed integers.

.      16-bit, 32-bit, or 64-bit unsigned integers.

The result elements are half the width of the operand elements. If the operand elements are signed, the results can
be either signed or unsigned. If the operand elements are unsigned, the result elements must also be unsigned.

If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
occurs. For details see Pseudocode description of saturation on page E1-2375.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21                  16 15      12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 U 1 D                    imm6             Vd        1 0 0 op 0 0 M 1             Vm




Signed result variant

Applies when !(imm6 == 000xxx) && op = 1.

VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


Unsigned result variant

Applies when U = 1 && !(imm6 == 000xxx) && op = 0.

VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


Decode for all variants of this encoding

 if imm6 == ''000xxx'' then SEE "Related encodings";
 if U == ''0'' && op == ''0'' then SEE VSHRN;
 if Vm<0> == ''1'' then UNDEFINED;
 case imm6 of
      when "001xxx"    esize = 8;    elements = 8;   shift_amount = 16 - UInt(imm6);
      when "01xxxx"    esize = 16;    elements = 4;   shift_amount = 32 - UInt(imm6);
      when "1xxxxx"    esize = 32;    elements = 2;   shift_amount = 64 - UInt(imm6);
 src_unsigned = (U == ''1'' && op == ''1'');       dest_unsigned = (U == ''1'');
 d = UInt(D:Vd);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5                       0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 U 1 1 1 1 1 D                    imm6             Vd        1 0 0 op 0 0 M 1             Vm
        Signed result variant

        Applies when !(imm6 == 000xxx) && op = 1.

        VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


        Unsigned result variant

        Applies when U = 1 && !(imm6 == 000xxx) && op = 0.

        VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm>


        Decode for all variants of this encoding

         if imm6 == ''000xxx'' then SEE "Related encodings";
         if U == ''0'' && op == ''0'' then SEE VSHRN;
         if Vm<0> == ''1'' then UNDEFINED;
         case imm6 of
               when "001xxx"    esize = 8;    elements = 8;    shift_amount = 16 - UInt(imm6);
               when "01xxxx"    esize = 16;     elements = 4;   shift_amount = 32 - UInt(imm6);
               when "1xxxxx"    esize = 32;     elements = 2;   shift_amount = 64 - UInt(imm6);
         src_unsigned = (U == ''1'' && op == ''1'');         dest_unsigned = (U == ''1'');
         d = UInt(D:Vd);      m = UInt(M:Vm);


        Notes for all encodings

        Related encodings: One register and a modified immediate value on page F5-2596.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VQSHRN or VQSHRUN instruction must
                          be unconditional. ARM strongly recommends that a T32 VQSHRN or VQSHRUN instruction is
                          unconditional, see Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <type>            For the signed result variant: is the data type for the elements of the vectors, encoded in the "U"
                          field. It can have the following values:

                          S            when U = 0

                          U            when U = 1

                          For the unsigned result variant: is the data type for the elements of the vectors, encoded in the "U"
                          field. It can have the following values:

                          S            when U = 1

        <size>            Is the data size for the elements of the vectors, encoded in the "imm6<5:3>" field. It can have the
                          following values:

                          16           when imm6<5:3> = 001

                          32           when imm6<5:3> = 01x

                          64           when imm6<5:3> = 1xx

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

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

        <imm>             Is an immediate value, in the range 1 to <size>/2, encoded in the "imm6" field as <size>/2 - <imm>.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for e = 0 to elements-1
   operand = Int(Elem[Qin[m>>1],e,2*esize], src_unsigned);
   (result, sat) = SatQ(operand >> shift_amount, esize, dest_unsigned);
   Elem[D[d],e,esize] = result;
   if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VQSUB','        Vector Saturating Subtract subtracts the elements of the second operand vector from the corresponding elements of       (F8.1.171)
        the first operand vector, and places the results in the destination vector. Signed and unsigned operations are distinct.

        The operand and result elements must all be the same type, and can be any one of:

        .       8-bit, 16-bit, 32-bit, or 64-bit signed integers.

        .       8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

        If any of the results overflow, they are saturated. The cumulative saturation bit, FPSCR.QC, is set if saturation
        occurs. For details see Pseudocode description of saturation on page E1-2375.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 0 0 1 U 0 D size                     Vn          Vd       0 0 1 0 N Q M 1             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VQSUB{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VQSUB{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         unsigned = (U == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                    0 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 U 1 1 1 1 0 D size                     Vn          Vd       0 0 1 0 N Q M 1             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VQSUB{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.
VQSUB{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VQSUB instruction must be
              unconditional. ARM strongly recommends that a T32 VQSUB instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the vectors, encoded in the "U:size" field. It can have the
              following values:

              S8           when U = 0, size = 00

              S16          when U = 0, size = 01

              S32          when U = 0, size = 10

              S64          when U = 0, size = 11

              U8           when U = 1, size = 00

              U16          when U = 1, size = 01

              U32          when U = 1, size = 10

              U64          when U = 1, size = 11

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             diff = Int(Elem[D[n+r],e,esize], unsigned) - Int(Elem[D[m+r],e,esize], unsigned);
             (Elem[D[d+r],e,esize], sat) = SatQ(diff, esize, unsigned);
             if sat then FPSR.QC = ''1'';');
INSERT INTO "instructions" VALUES('ARM','VRADDHN','        Vector Rounding Add and Narrow, returning High Half adds corresponding elements in two quadword vectors, and       (F8.1.172)
        places the most significant half of each result in a doubleword vector. The results are rounded. For truncated results,
        see VADDHN.

        The operand elements can be 16-bit, 32-bit, or 64-bit integers. There is no distinction between signed and unsigned
        integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19            16 15      12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 1 1 D !=11                   Vn          Vd       0 1 0 0 N 0 M 0               Vm
                                            size


        A1 variant

        VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 1 1 1 1 1 D !=11                   Vn          Vd       0 1 0 0 N 0 M 0               Vm
                                            size


        T1 variant

        VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);


        Notes for all encodings

        Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VRADDHN instruction must be
                          unconditional. ARM strongly recommends that a T32 VRADDHN instruction is unconditional, see
                          Conditional execution on page F2-2507.
<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "size" field. It can have the
              following values:

              I16          when size = 00

              I32          when size = 01

              I64          when size = 10

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

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();      CheckAdvSIMDEnabled();
    round_const = 1 << (esize-1);
    for e = 0 to elements-1
        result = Elem[Qin[n>>1],e,2*esize] + Elem[Qin[m>>1],e,2*esize] + round_const;
        Elem[D[d],e,esize] = result<2*esize-1:esize>;');
INSERT INTO "instructions" VALUES('ARM','VRECPE','        Vector Reciprocal Estimate finds an approximate reciprocal of each element in the operand vector, and places the       (F8.1.173)
        results in the destination vector.

        The operand and result elements are the same type, and can be 32-bit floating-point numbers, or 32-bit unsigned
        integers.

        For details of the operation performed by this instruction see Floating-point reciprocal square root estimate and
        step on page E1-2408.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                 0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 1                       Vd      0 1 0 F 0 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         floating_point = (F == ''1'');     esize = 32;   elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                 0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 1                       Vd      0 1 0 F 0 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size != ''10'' then UNDEFINED;
 floating_point = (F == ''1'');      esize = 32;   elements = 2;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VRECPE instruction must be
                unconditional. ARM strongly recommends that a T32 VRECPE instruction is unconditional, see
                Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<dt>            Is the data type for the elements of the vectors, encoded in the "F:size" field. It can have the
                following values:

                S32          when F = 0, size = 10

                F32          when F = 1, size = 10

                It is RESERVED when:

                .      F = 0, size = 0x.

                .      F = 0, size = 11.

                .      F = 1, size = 0x.

                .      F = 1, size = 11.

<Qd>            Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>            Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>            Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Newton-Raphson iteration

For details of the operation performed and how it can be used in a Newton-Raphson iteration to calculate the
reciprocal of a number, see Floating-point reciprocal estimate and step on page E1-2405.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();       CheckAdvSIMDEnabled();
     for r = 0 to regs-1
          for e = 0 to elements-1
               if floating_point then
                   Elem[D[d+r],e,32] = FPRecipEstimate(Elem[D[m+r],e,32], StandardFPSCRValue());
               else
                   Elem[D[d+r],e,32] = UnsignedRecipEstimate(Elem[D[m+r],e,32]);');
INSERT INTO "instructions" VALUES('ARM','VRECPS','        Vector Reciprocal Step multiplies the elements of one vector by the corresponding elements of another vector,       (F8.1.174)
        subtracts each of the products from 2.0, and places the results into the elements of the destination vector.

        The operand and result elements are 32-bit floating-point numbers.

        For details of the operation performed by this instruction see Floating-point reciprocal estimate and step on
        page E1-2405.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 0 0 1 0 0 D 0 sz                  Vn           Vd      1 1 1 1 N Q M 1                Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRECPS{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRECPS{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 0 1 1 1 1 0 D 0 sz                  Vn           Vd      1 1 1 1 N Q M 1                Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRECPS{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRECPS{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 esize = 32;    elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VRECPS instruction must be
                unconditional. ARM strongly recommends that a T32 VRECPS instruction is unconditional, see
                Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<Qd>            Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>            Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>            Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dn>            Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>            Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Newton-Raphson iteration

For details of the operation performed and how it can be used in a Newton-Raphson iteration to calculate the
reciprocal of a number, see Floating-point reciprocal estimate and step on page E1-2405.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();      CheckAdvSIMDEnabled();
     for r = 0 to regs-1
          for e = 0 to elements-1
               Elem[D[d+r],e,32] = FPRecipStep(Elem[D[n+r],e,32], Elem[D[m+r],e,32]);');
INSERT INTO "instructions" VALUES('ARM','VREV16','        Vector Reverse in halfwords reverses the order of 8-bit elements in each halfword of the vector, and places the result       (F8.1.175)
        in the corresponding destination vector.

        There is no distinction between data types, other than size.

        The following figure shows an example of the operation of VREV16 doubleword operation.

                                                                                       VREV16.8, doubleword
                                                                                       Dm




                                                                                       Dd

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                  0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                       Vd      0 0 0 1 0 Q M 0               Vm
                                                                                     op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VREV16{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VREV16{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if UInt(op)+UInt(size) >= 3 then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         groupsize = (1 << (3-UInt(op)-UInt(size))); // elements per reversing group: 2, 4 or 8
         reverse_mask = (groupsize-1)<esize-1:0>;        // EORing mask used for index calculations
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                       Vd      0 0 0 1 0 Q M 0               Vm
                                                                                     op
64-bit SIMD vector variant

Applies when Q = 0.

VREV16{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VREV16{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if UInt(op)+UInt(size) >= 3 then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 groupsize = (1 << (3-UInt(op)-UInt(size))); // elements per reversing group: 2, 4 or 8
 reverse_mask = (groupsize-1)<esize-1:0>;        // EORing mask used for index calculations
 d = UInt(D:Vd);  m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VREV instruction must be
              unconditional. ARM strongly recommends that a T32 VREV instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operand, encoded in the "size" field. It can have the following
              values:

              8            when size = 00

              It is RESERVED when:

              .      size = 01.

              .      size = 1x.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     bits(64) dest;

     for r = 0 to regs-1
         for e = 0 to elements-1
             // Calculate destination element index by bitwise EOR on source element index:
             e_bits = e<esize-1:0>;      d_bits = e_bits EOR reverse_mask;      d = UInt(d_bits);
             Elem[dest,d,esize] = Elem[D[m+r],e,esize];
         D[d+r] = dest;');
INSERT INTO "instructions" VALUES('ARM','VREV32','        Vector Reverse in words reverses the order of 8-bit or 16-bit elements in each word of the vector, and places the       (F8.1.176)
        result in the corresponding destination vector.

        There is no distinction between data types, other than size.

        The following figure shows an example of the operation of VREV32 doubleword operations.

             VREV32.8, doubleword                       VREV32.16, doubleword
             Dm                                         Dm




              Dd                                        Dd

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                       Vd      0 0 0 0 1 Q M 0             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VREV32{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VREV32{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if UInt(op)+UInt(size) >= 3 then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         groupsize = (1 << (3-UInt(op)-UInt(size))); // elements per reversing group: 2, 4 or 8
         reverse_mask = (groupsize-1)<esize-1:0>;        // EORing mask used for index calculations
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                       Vd      0 0 0 0 1 Q M 0             Vm
64-bit SIMD vector variant

Applies when Q = 0.

VREV32{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VREV32{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if UInt(op)+UInt(size) >= 3 then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 groupsize = (1 << (3-UInt(op)-UInt(size))); // elements per reversing group: 2, 4 or 8
 reverse_mask = (groupsize-1)<esize-1:0>;        // EORing mask used for index calculations
 d = UInt(D:Vd);  m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VREV instruction must be
              unconditional. ARM strongly recommends that a T32 VREV instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operand, encoded in the "size" field. It can have the following
              values:

              8            when size = 00

              16           when size = 01

              It is RESERVED when size = 1x.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     bits(64) dest;

     for r = 0 to regs-1
         for e = 0 to elements-1
             // Calculate destination element index by bitwise EOR on source element index:
             e_bits = e<esize-1:0>;      d_bits = e_bits EOR reverse_mask;      d = UInt(d_bits);
             Elem[dest,d,esize] = Elem[D[m+r],e,esize];
         D[d+r] = dest;');
INSERT INTO "instructions" VALUES('ARM','VREV64','        Vector Reverse in doublewords reverses the order of 8-bit, 16-bit, or 32-bit elements in each doubleword of the       (F8.1.177)
        vector, and places the result in the corresponding destination vector.

        There is no distinction between data types, other than size.

        The following figure shows an example of the operation of VREV64 doubleword operations.

             VREV64.8, doubleword                       VREV64.32, quadword
             Dm                                         Qm




              Dd                                        Qm

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3               0
            1 1 1 1 0 0 1 1 1 D 1 1 size 0 0                       Vd      0 0 0 0 0 Q M 0             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VREV64{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VREV64{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if UInt(op)+UInt(size) >= 3 then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);      elements = 64 DIV esize;
         groupsize = (1 << (3-UInt(op)-UInt(size))); // elements per reversing group: 2, 4 or 8
         reverse_mask = (groupsize-1)<esize-1:0>;         // EORing mask used for index calculations
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 1 1 1 1 1 D 1 1 size 0 0                       Vd      0 0 0 0 0 Q M 0             Vm
64-bit SIMD vector variant

Applies when Q = 0.

VREV64{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VREV64{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if UInt(op)+UInt(size) >= 3 then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 groupsize = (1 << (3-UInt(op)-UInt(size))); // elements per reversing group: 2, 4 or 8
 reverse_mask = (groupsize-1)<esize-1:0>;        // EORing mask used for index calculations
 d = UInt(D:Vd);  m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VREV instruction must be
              unconditional. ARM strongly recommends that a T32 VREV instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operand, 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.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     bits(64) dest;

     for r = 0 to regs-1
         for e = 0 to elements-1
             // Calculate destination element index by bitwise EOR on source element index:
             e_bits = e<esize-1:0>;      d_bits = e_bits EOR reverse_mask;      d = UInt(d_bits);
             Elem[dest,d,esize] = Elem[D[m+r],e,esize];
         D[d+r] = dest;');
INSERT INTO "instructions" VALUES('ARM','VRHADD','        Vector Rounding Halving Add adds corresponding elements in two vectors of integers, shifts each result right one       (F8.1.178)
        bit, and places the final results in the destination vector.

        The operand and result elements are all the same type, and can be any one of:

        .       8-bit, 16-bit, or 32-bit signed integers.

        .       8-bit, 16-bit, or 32-bit unsigned integers.

        The results of the halving operations are rounded. For truncated results, see VHADD.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19            16 15       12 11 10 9 8 7 6 5 4 3             0
            1 1 1 1 0 0 1 U 0 D size                    Vn          Vd      0 0 0 1 N Q M 0            Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRHADD{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRHADD{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size == ''11'' then UNDEFINED;
         unsigned = (U == ''1'');
         esize = 8 << UInt(size);        elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3             0
            1 1 1 U 1 1 1 1 0 D size                    Vn          Vd      0 0 0 1 N Q M 0            Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRHADD{<c>}{<q>}.<dt> {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.
VRHADD{<c>}{<q>}.<dt> {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size == ''11'' then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VRHADD instruction must be
              unconditional. ARM strongly recommends that a T32 VRHADD instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "U:size" field. It can have the
              following values:

              S8           when U = 0, size = 00

              S16          when U = 0, size = 01

              S32          when U = 0, size = 10

              U8           when U = 1, size = 00

              U16          when U = 1, size = 01

              U32          when U = 1, size = 10

              It is RESERVED when:

              .      U = 0, size = 11.

              .      U = 1, size = 11.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             op1 = Int(Elem[D[n+r],e,esize], unsigned);
             op2 = Int(Elem[D[m+r],e,esize], unsigned);
             result = op1 + op2 + 1;
             Elem[D[d+r],e,esize] = result<esize:1>;');
INSERT INTO "instructions" VALUES('ARM','VRINTA','        Vector Round floating-point to integer towards Nearest with Ties to Away rounds a vector of floating-point values       (F8.1.179)
        to integral floating-point values of the same size using the Round to Nearest with Ties to Away rounding mode. A
        zero input gives a zero result with the same sign, an infinite input gives an infinite result with the same sign, and a
        NaN is propagated as for normal arithmetic.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15            12 11 10 9       7 6 5 4 3              0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                       Vd        0 1 0 1 0 Q M 0                Vm
                                                                                      op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTA{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTA{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));       exact = FALSE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                      12 11 10 9       7 6 5 4 3              0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                       Vd        0 1 0 1 0 Q M 0                Vm
                                                                                      op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTA{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTA{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));       exact = FALSE;
 esize = 32;  elements = 2;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

Related encodings: Two registers, miscellaneous on page F5-2594.


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 for r = 0 to regs-1
     for e = 0 to elements-1
         op1 = Elem[D[m+r],e,esize];
         result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact);
         Elem[D[d+r],e,esize] = result;');
INSERT INTO "instructions" VALUES('ARM','VRINTM','        Vector Round floating-point to integer towards -Infinity rounds a vector of floating-point values to integral       (F8.1.181)
        floating-point values of the same size, using the Round towards -Infinity rounding mode. A zero input gives a zero
        result with the same sign, an infinite input gives an infinite result with the same sign, and a NaN is propagated as
        for normal arithmetic.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15            12 11 10 9       7 6 5 4 3             0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd        0 1 1 0 1 Q M 0             Vm
                                                                                       op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTM{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTM{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));       exact = FALSE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                      12 11 10 9       7 6 5 4 3             0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                        Vd        0 1 1 0 1 Q M 0             Vm
                                                                                       op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTM{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTM{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));       exact = FALSE;
 esize = 32;  elements = 2;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

Related encodings: Two registers, miscellaneous on page F5-2594.


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 for r = 0 to regs-1
     for e = 0 to elements-1
         op1 = Elem[D[m+r],e,esize];
         result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact);
         Elem[D[d+r],e,esize] = result;');
INSERT INTO "instructions" VALUES('ARM','VRINTN','        Vector Round floating-point to integer to Nearest rounds a vector of floating-point values to integral floating-point       (F8.1.183)
        values of the same size using the Round to Nearest rounding mode. A zero input gives a zero result with the same
        sign, an infinite input gives an infinite result with the same sign, and a NaN is propagated as for normal arithmetic.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15             12 11 10 9      7 6 5 4 3            0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd        0 1 0 0 0 Q M 0             Vm
                                                                                     op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTN{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTN{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));        exact = FALSE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                       12 11 10 9      7 6 5 4 3            0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                        Vd        0 1 0 0 0 Q M 0             Vm
                                                                                     op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTN{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTN{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));        exact = FALSE;
 esize = 32;  elements = 2;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

Related encodings: Two registers, miscellaneous on page F5-2594.


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 for r = 0 to regs-1
     for e = 0 to elements-1
         op1 = Elem[D[m+r],e,esize];
         result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact);
         Elem[D[d+r],e,esize] = result;');
INSERT INTO "instructions" VALUES('ARM','VRINTP','        Vector Round floating-point to integer towards +Infinity rounds a vector of floating-point values to integral       (F8.1.185)
        floating-point values of the same size using the Round towards +Infinity rounding mode. A zero input gives a zero
        result with the same sign, an infinite input gives an infinite result with the same sign, and a NaN is propagated as
        for normal arithmetic.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15            12 11 10 9       7 6 5 4 3             0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd        0 1 1 1 1 Q M 0             Vm
                                                                                       op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTP{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTP{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));       exact = FALSE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                      12 11 10 9       7 6 5 4 3             0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                        Vd        0 1 1 1 1 Q M 0             Vm
                                                                                       op


        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTP{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTP{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if op<2> != op<0> then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         // Rounding encoded differently from other VCVT and VRINT instructions
         rounding = FPDecodeRM(op<2>:NOT(op<1>));       exact = FALSE;
 esize = 32;  elements = 2;
 d = UInt(D:Vd);  m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
 if InITBlock() then UNPREDICTABLE;


Notes for all encodings

Related encodings: Two registers, miscellaneous on page F5-2594.


Assembler symbols

<q>           See Standard assembler syntax fields on page F2-2506.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 for r = 0 to regs-1
     for e = 0 to elements-1
         op1 = Elem[D[m+r],e,esize];
         result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact);
         Elem[D[d+r],e,esize] = result;');
INSERT INTO "instructions" VALUES('ARM','VRINTR','        Round floating-point to integer rounds a floating-point value to an integral floating-point value of the same size       (F8.1.187)
        using the rounding mode specified in the FPSCR. A zero input gives a zero result with the same sign, an infinite
        input gives an infinite result with the same sign, and a NaN is propagated as for normal arithmetic.


        A1


           31        28 27 26 25 24 23 22 21 20 19 18 17 16 15         12 11 10 9 8 7 6 5 4 3                  0
              !=1111     1 1 1 0 1 D 1 1 0 1 1 0                  Vd       1 0 1 sz 0 1 M 0             Vm
               cond                                                                    op


        Single-precision scalar variant

        Applies when sz = 0.

        VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         rounding = if op == ''1'' then FPRounding_ZERO else FPRoundingMode(FPSCR);
         dp_operation = (sz == ''1'');      exact = FALSE;
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                  0
            1 1 1 0 1 1 1 0 1 D 1 1 0 1 1 0                       Vd       1 0 1 sz 0 1 M 0             Vm
                                                                                       op


        Single-precision scalar variant

        Applies when sz = 0.

        VRINTR{<c>}{<q>}.F32.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VRINTR{<c>}{<q>}.F64.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         rounding = if op == ''1'' then FPRounding_ZERO else FPRoundingMode(FPSCR);
         dp_operation = (sz == ''1'');      exact = FALSE;
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.
<Sd>          Is the 32-bit name of the SIMD&FP destination register, encoded in the "Vd:D" field.

<Sm>          Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations(); CheckVFPEnabled(TRUE);
    if dp_operation then
        D[d] = FPRoundInt(D[m], FPSCR, rounding, exact);
    else
        S[d] = FPRoundInt(S[m], FPSCR, rounding, exact);');
INSERT INTO "instructions" VALUES('ARM','VRINTX','        Vector round floating-point to integer inexact rounds a vector of floating-point values to integral floating-point       (F8.1.188)
        values of the same size, using the Round to Nearest rounding mode, and raises the Inexact exception when the result
        value is not numerically equal to the input value. A zero input gives a zero result with the same sign, an infinite input
        gives an infinite result with the same sign, and a NaN is propagated as for normal arithmetic.


        A1


           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 3                   0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd      0 1 0 0 1 Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTX{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTX{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPRounding_TIEEVEN;      exact = TRUE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                      12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                        Vd      0 1 0 0 1 Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTX{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTX{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPRounding_TIEEVEN;      exact = TRUE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<q>            See Standard assembler syntax fields on page F2-2506.

<Qd>           Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>           Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>           Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 for r = 0 to regs-1
     for e = 0 to elements-1
         op1 = Elem[D[m+r],e,esize];
         result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact);
         Elem[D[d+r],e,esize] = result;');
INSERT INTO "instructions" VALUES('ARM','VRINTZ','        Vector round floating-point to integer towards Zero rounds a vector of floating-point values to integral       (F8.1.190)
        floating-point values of the same size, using the Round towards Zero rounding mode. A zero input gives a zero result
        with the same sign, an infinite input gives an infinite result with the same sign, and a NaN is propagated as for
        normal arithmetic.


        A1


           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 3               0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                       Vd        0 1 0 1 1 Q M 0             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTZ{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTZ{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPRounding_ZERO;     exact = FALSE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                      12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                       Vd        0 1 0 1 1 Q M 0             Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRINTZ{<q>}.F32.F32 <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRINTZ{<q>}.F32.F32 <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         rounding = FPRounding_ZERO;     exact = FALSE;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
         if InITBlock() then UNPREDICTABLE;
Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<q>            See Standard assembler syntax fields on page F2-2506.

<Qd>           Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>           Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>           Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 EncodingSpecificOperations(); CheckAdvSIMDEnabled();
 for r = 0 to regs-1
     for e = 0 to elements-1
         op1 = Elem[D[m+r],e,esize];
         result = FPRoundInt(op1, StandardFPSCRValue(), rounding, exact);
         Elem[D[d+r],e,esize] = result;');
INSERT INTO "instructions" VALUES('ARM','VRSHL','        Vector Rounding Shift Left takes each element in a vector, shifts them by a value from the least significant byte of       (F8.1.192)
        the corresponding element of a second vector, and places the results in the destination vector. If the shift value is
        positive, the operation is a left shift. If the shift value is negative, it is a rounding right shift. For a truncating shift,
        see VSHL.

        The first operand and result elements are the same data type, and can be any one of:

        .       8-bit, 16-bit, 32-bit, or 64-bit signed integers.

        .       8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

        The second operand is always a signed integer of the same size.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19              16 15         12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 1 0 0 1 U 0 D size                      Vn            Vd       0 1 0 1 N Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRSHL{<c>}{<q>}.<dt> {<Dd>,} <Dm>, <Dn>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRSHL{<c>}{<q>}.<dt> {<Qd>,} <Qm>, <Qn>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
         unsigned = (U == ''1'');
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);     n = UInt(N:Vn);      regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                      0 15         12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 U 1 1 1 1 0 D size                      Vn            Vd       0 1 0 1 N Q M 0                 Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRSHL{<c>}{<q>}.<dt> {<Dd>,} <Dm>, <Dn>


        128-bit SIMD vector variant

        Applies when Q = 1.
VRSHL{<c>}{<q>}.<dt> {<Qd>,} <Qm>, <Qn>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'' || Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  m = UInt(M:Vm);    n = UInt(N:Vn);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VRSHL instruction must be
              unconditional. ARM strongly recommends that a T32 VRSHL instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the vectors, encoded in the "U:size" field. It can have the
              following values:

              S8           when U = 0, size = 00

              S16          when U = 0, size = 01

              S32          when U = 0, size = 10

              S64          when U = 0, size = 11

              U8           when U = 1, size = 00

              U16          when U = 1, size = 01

              U32          when U = 1, size = 10

              U64          when U = 1, size = 11

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

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

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             shift = SInt(Elem[D[n+r],e,esize]<7:0>);
             round_const = 1 << (-shift-1); // 0 for left shift, 2^(n-1) for right shift
             result = (Int(Elem[D[m+r],e,esize], unsigned) + round_const) << shift;
             Elem[D[d+r],e,esize] = result<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VRSHR','        Vector Rounding Shift Right takes each element in a vector, right shifts them by an immediate value, and places the       (F8.1.193)
        rounded results in the destination vector. For truncated results, see VSHR.

        The operand and result elements must be the same size, and can be any one of:

        .       8-bit, 16-bit, 32-bit, or 64-bit signed integers.

        .       8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                  16 15       12 11 10 9 8 7 6 5 4 3              0
            1 1 1 1 0 0 1 U 1 D                     imm6            Vd      0 0 1 0 L Q M 1            Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VRSHR{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VRSHR{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;    elements = 8;    shift_amount = 16 - UInt(imm6);
               when "001xxxx"    esize = 16;     elements = 4;   shift_amount = 32 - UInt(imm6);
               when "01xxxxx"    esize = 32;     elements = 2;   shift_amount = 64 - UInt(imm6);
               when "1xxxxxx"    esize = 64;     elements = 1;   shift_amount = 64 - UInt(imm6);
         unsigned = (U == ''1'');       d = UInt(D:Vd);    m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5                        0 15       12 11 10 9 8 7 6 5 4 3              0
            1 1 1 U 1 1 1 1 1 D                     imm6            Vd      0 0 1 0 L Q M 1            Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VRSHR{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.
VRSHR{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


Decode for all variants of this encoding

 if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
     when "0001xxx"  esize = 8;     elements = 8;   shift_amount = 16 - UInt(imm6);
     when "001xxxx"  esize = 16;     elements = 4;    shift_amount = 32 - UInt(imm6);
     when "01xxxxx"  esize = 32;     elements = 2;    shift_amount = 64 - UInt(imm6);
     when "1xxxxxx"  esize = 64;     elements = 1;    shift_amount = 64 - UInt(imm6);
 unsigned = (U == ''1'');   d = UInt(D:Vd);    m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VRSHR instruction must be
              unconditional. ARM strongly recommends that a T32 VRSHR instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<type>        Is the data type for the elements of the vectors, encoded in the "U" field. It can have the following
              values:

              S            when U = 0

              U            when U = 1

<size>        Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
              following values:

              8            when L = 0, imm6<5:3> = 001

              16           when L = 0, imm6<5:3> = 01x

              32           when L = 0, imm6<5:3> = 1xx

              64           when L = 1, imm6<5:3> = xxx

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         Is an immediate value, in the range 1 to <size>, encoded in the "imm6" field as <size> - <imm>.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     round_const = 1 << (shift_amount - 1);
     for r = 0 to regs-1
         for e = 0 to elements-1
             result = (Int(Elem[D[m+r],e,esize], unsigned) + round_const) >> shift_amount;
             Elem[D[d+r],e,esize] = result<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VRSHRN','        Vector Rounding Shift Right and Narrow takes each element in a vector, right shifts them by an immediate value,       (F8.1.195)
        and places the rounded results in the destination vector. For truncated results, see VSHRN.

        The operand elements can be 16-bit, 32-bit, or 64-bit integers. There is no distinction between signed and unsigned
        integers. The destination elements are half the size of the source elements.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                16 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 0 0 1 0 1 D                  imm6              Vd       1 0 0 0 0 1 M 1              Vm




        A1 variant

        Applies when imm6 != 000xxx.

        VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm>


        Decode for this encoding

         if imm6 == ''000xxx'' then SEE "Related encodings";
         if Vm<0> == ''1'' then UNDEFINED;
         case imm6 of
               when "001xxx"   esize = 8;  elements = 8;    shift_amount = 16 - UInt(imm6);
               when "01xxxx"   esize = 16;   elements = 4;   shift_amount = 32 - UInt(imm6);
               when "1xxxxx"   esize = 32;   elements = 2;   shift_amount = 64 - UInt(imm6);
         d = UInt(D:Vd);     m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5                      0 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 0 1 1 1 1 1 D                  imm6              Vd       1 0 0 0 0 1 M 1              Vm




        T1 variant

        Applies when imm6 != 000xxx.

        VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm>


        Decode for this encoding

         if imm6 == ''000xxx'' then SEE "Related encodings";
         if Vm<0> == ''1'' then UNDEFINED;
         case imm6 of
               when "001xxx"   esize = 8;  elements = 8;    shift_amount = 16 - UInt(imm6);
               when "01xxxx"   esize = 16;   elements = 4;   shift_amount = 32 - UInt(imm6);
               when "1xxxxx"   esize = 32;   elements = 2;   shift_amount = 64 - UInt(imm6);
         d = UInt(D:Vd);     m = UInt(M:Vm);
Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VRSHRN instruction must be
              unconditional. ARM strongly recommends that a T32 VRSHRN instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<size>        Is the data size for the elements of the vectors, encoded in the "imm6<5:3>" field. It can have the
              following values:

              16          when imm6<5:3> = 001

              32          when imm6<5:3> = 01x

              64          when imm6<5:3> = 1xx

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

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

<imm>         Is an immediate value, in the range 1 to <size>/2, encoded in the "imm6" field as <size>/2 - <imm>.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     round_const = 1 << (shift_amount-1);
     for e = 0 to elements-1
         result = LSR(Elem[Qin[m>>1],e,2*esize] + round_const, shift_amount);
         Elem[D[d],e,esize] = result<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VRSQRTE','        Vector Reciprocal Square Root Estimate finds an approximate reciprocal square root of each element in a vector,       (F8.1.197)
        and places the results in a second vector.

        The operand and result elements are the same type, and can be 32-bit floating-point numbers, or 32-bit unsigned
        integers.

        For details of the operation performed by this instruction see Floating-point reciprocal estimate and step on
        page E1-2405.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 1                       Vd      0 1 0 F 1 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size != ''10'' then UNDEFINED;
         floating_point = (F == ''1'');     esize = 32;   elements = 2;
         d = UInt(D:Vd);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 1                       Vd      0 1 0 F 1 Q M 0              Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size != ''10'' then UNDEFINED;
 floating_point = (F == ''1'');      esize = 32;   elements = 2;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VRSQRTE instruction must be
                unconditional. ARM strongly recommends that a T32 VRSQRTE instruction is unconditional, see
                Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<dt>            Is the data type for the elements of the vectors, encoded in the "F:size" field. It can have the
                following values:

                S32          when F = 0, size = 10

                F32          when F = 1, size = 10

                It is RESERVED when:

                .      F = 0, size = 0x.

                .      F = 0, size = 11.

                .      F = 1, size = 0x.

                .      F = 1, size = 11.

<Qd>            Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>            Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>            Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Newton-Raphson iteration

For details of the operation performed and how it can be used in a Newton-Raphson iteration to calculate the
reciprocal of the square root of a number, see Floating-point reciprocal estimate and step on page E1-2405.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();       CheckAdvSIMDEnabled();
     for r = 0 to regs-1
          for e = 0 to elements-1
               if floating_point then
                   Elem[D[d+r],e,32] = FPRSqrtEstimate(Elem[D[m+r],e,32], StandardFPSCRValue());
               else
                   Elem[D[d+r],e,32] = UnsignedRSqrtEstimate(Elem[D[m+r],e,32]);');
INSERT INTO "instructions" VALUES('ARM','VRSQRTS','        Vector Reciprocal Square Root Step multiplies the elements of one vector by the corresponding elements of another       (F8.1.198)
        vector, subtracts each of the products from 3.0, divides these results by 2.0, and places the results into the elements
        of the destination vector.

        The operand and result elements are 32-bit floating-point numbers.

        For details of the operation performed by this instruction see Floating-point reciprocal estimate and step on
        page E1-2405.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 1 0 0 1 0 0 D 1 sz                  Vn           Vd       1 1 1 1 N Q M 1                Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRSQRTS{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRSQRTS{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         esize = 32;     elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 0 1 1 1 1 0 D 1 sz                  Vn           Vd       1 1 1 1 N Q M 1                Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VRSQRTS{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VRSQRTS{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 esize = 32;    elements = 2;
 d = UInt(D:Vd);    n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VRSQRTS instruction must be
                unconditional. ARM strongly recommends that a T32 VRSQRTS instruction is unconditional, see
                Conditional execution on page F2-2507.

<q>             See Standard assembler syntax fields on page F2-2506.

<Qd>            Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>            Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>            Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dn>            Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>            Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Newton-Raphson iteration

For details of the operation performed and how it can be used in a Newton-Raphson iteration to calculate the
reciprocal of the square root of a number, see Floating-point reciprocal estimate and step on page E1-2405.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();      CheckAdvSIMDEnabled();
     for r = 0 to regs-1
          for e = 0 to elements-1
               Elem[D[d+r],e,32] = FPRSqrtStep(Elem[D[n+r],e,32], Elem[D[m+r],e,32]);');
INSERT INTO "instructions" VALUES('ARM','VRSRA','        Vector Rounding Shift Right and Accumulate takes each element in a vector, right shifts them by an immediate       (F8.1.199)
        value, and accumulates the rounded results into the destination vector. For truncated results, see VSRA.

        The operand and result elements must all be the same type, and can be any one of:

        .       8-bit, 16-bit, 32-bit, or 64-bit signed integers.

        .       8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                  16 15       12 11 10 9 8 7 6 5 4 3              0
            1 1 1 1 0 0 1 U 1 D                     imm6            Vd      0 0 1 1 L Q M 1              Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VRSRA{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VRSRA{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;    elements = 8;    shift_amount = 16 - UInt(imm6);
               when "001xxxx"    esize = 16;     elements = 4;   shift_amount = 32 - UInt(imm6);
               when "01xxxxx"    esize = 32;     elements = 2;   shift_amount = 64 - UInt(imm6);
               when "1xxxxxx"    esize = 64;     elements = 1;   shift_amount = 64 - UInt(imm6);
         unsigned = (U == ''1'');       d = UInt(D:Vd);    m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5                        0 15       12 11 10 9 8 7 6 5 4 3              0
            1 1 1 U 1 1 1 1 1 D                     imm6            Vd      0 0 1 1 L Q M 1              Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VRSRA{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.
VRSRA{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


Decode for all variants of this encoding

 if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
     when "0001xxx"  esize = 8;     elements = 8;   shift_amount = 16 - UInt(imm6);
     when "001xxxx"  esize = 16;     elements = 4;    shift_amount = 32 - UInt(imm6);
     when "01xxxxx"  esize = 32;     elements = 2;    shift_amount = 64 - UInt(imm6);
     when "1xxxxxx"  esize = 64;     elements = 1;    shift_amount = 64 - UInt(imm6);
 unsigned = (U == ''1'');   d = UInt(D:Vd);    m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VRSRA instruction must be
              unconditional. ARM strongly recommends that a T32 VRSRA instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<type>        Is the data type for the elements of the vectors, encoded in the "U" field. It can have the following
              values:

              S            when U = 0

              U            when U = 1

<size>        Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
              following values:

              8            when L = 0, imm6<5:3> = 001

              16           when L = 0, imm6<5:3> = 01x

              32           when L = 0, imm6<5:3> = 1xx

              64           when L = 1, imm6<5:3> = xxx

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         Is an immediate value, in the range 1 to <size>, encoded in the "imm6" field as <size> - <imm>.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     round_const = 1 << (shift_amount - 1);
     for r = 0 to regs-1
         for e = 0 to elements-1
             result = (Int(Elem[D[m+r],e,esize], unsigned) + round_const) >> shift_amount;
             Elem[D[d+r],e,esize] = Elem[D[d+r],e,esize] + result;');
INSERT INTO "instructions" VALUES('ARM','VRSUBHN','        Vector Rounding Subtract and Narrow, returning High Half subtracts the elements of one quadword vector from the       (F8.1.200)
        corresponding elements of another quadword vector, takes the most significant half of each result, and places the
        final results in a doubleword vector. The results are rounded. For truncated results, see VSUBHN.

        The operand elements can be 16-bit, 32-bit, or 64-bit integers. There is no distinction between signed and unsigned
        integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 0 0 1 1 1 D !=11                  Vn           Vd      0 1 1 0 N 0 M 0               Vm
                                           size


        A1 variant

        VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 1 1 1 1 1 D !=11                  Vn           Vd      0 1 1 0 N 0 M 0               Vm
                                           size


        T1 variant

        VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


        Decode for this encoding

         if size == ''11'' then SEE "Related encodings";
         if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);


        Notes for all encodings

        Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VRSUBHN instruction must be
                          unconditional. ARM strongly recommends that a T32 VRSUBHN instruction is unconditional, see
                          Conditional execution on page F2-2507.
<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          Is the data type for the elements of the operands, encoded in the "size" field. It can have the
              following values:

              I16          when size = 00

              I32          when size = 01

              I64          when size = 10

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

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();      CheckAdvSIMDEnabled();
    round_const = 1 << (esize-1);
    for e = 0 to elements-1
        result = Elem[Qin[n>>1],e,2*esize] - Elem[Qin[m>>1],e,2*esize] + round_const;
        Elem[D[d],e,esize] = result<2*esize-1:esize>;');
INSERT INTO "instructions" VALUES('ARM','VSELEQ','        Floating-point conditional select allows the destination register to take the value in either one or the other source       (F8.1.201)
        register according to the condition codes in the The Application Program Status Register, APSR on page E1-2382.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19         16 15        12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 1 1 1 1 0 0 D             cc        Vn          Vd        1 0 1 sz N 0 M 0              Vm




        VSELEQ, doubleprec variant

        Applies when cc = 00 && sz = 1.

        VSELEQ.F64 <Dd>, <Dn>, <Dm>// Cannot be conditional


        VSELEQ, singleprec variant

        Applies when cc = 00 && sz = 0.

        VSELEQ.F32 <Sd>, <Sn>, <Sm>// Cannot be conditional


        VSELGE, doubleprec variant

        Applies when cc = 10 && sz = 1.

        VSELGE.F64 <Dd>, <Dn>, <Dm>// Cannot be conditional


        VSELGE, singleprec variant

        Applies when cc = 10 && sz = 0.

        VSELGE.F32 <Sd>, <Sn>, <Sm>// Cannot be conditional


        VSELGT, doubleprec variant

        Applies when cc = 11 && sz = 1.

        VSELGT.F64 <Dd>, <Dn>, <Dm>// Cannot be conditional


        VSELGT, singleprec variant

        Applies when cc = 11 && sz = 0.

        VSELGT.F32 <Sd>, <Sn>, <Sm>// Cannot be conditional


        VSELVS, doubleprec variant

        Applies when cc = 01 && sz = 1.

        VSELVS.F64 <Dd>, <Dn>, <Dm>// Cannot be conditional


        VSELVS, singleprec variant

        Applies when cc = 01 && sz = 0.

        VSELVS.F32 <Sd>, <Sn>, <Sm>// Cannot be conditional


        Decode for all variants of this encoding

         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
 cond = cc:(cc<1> EOR cc<0>):''0'';
 if InITBlock() then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7 6 5 4 3                0
  1 1 1 1 1 1 1 0 0 D           cc       Vn          Vd         1 0 1 sz N 0 M 0            Vm




VSELEQ, doubleprec variant

Applies when cc = 00 && sz = 1.

VSELEQ.F64 <Dd>, <Dn>, <Dm>// Not permitted in IT block


VSELEQ, singleprec variant

Applies when cc = 00 && sz = 0.

VSELEQ.F32 <Sd>, <Sn>, <Sm>// Not permitted in IT block


VSELGE, doubleprec variant

Applies when cc = 10 && sz = 1.

VSELGE.F64 <Dd>, <Dn>, <Dm>// Not permitted in IT block


VSELGE, singleprec variant

Applies when cc = 10 && sz = 0.

VSELGE.F32 <Sd>, <Sn>, <Sm>// Not permitted in IT block


VSELGT, doubleprec variant

Applies when cc = 11 && sz = 1.

VSELGT.F64 <Dd>, <Dn>, <Dm>// Not permitted in IT block


VSELGT, singleprec variant

Applies when cc = 11 && sz = 0.

VSELGT.F32 <Sd>, <Sn>, <Sm>// Not permitted in IT block


VSELVS, doubleprec variant

Applies when cc = 01 && sz = 1.

VSELVS.F64 <Dd>, <Dn>, <Dm>// Not permitted in IT block


VSELVS, singleprec variant

Applies when cc = 01 && sz = 0.

VSELVS.F32 <Sd>, <Sn>, <Sm>// Not permitted in IT block


Decode for all variants of this encoding

 dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
         cond = cc:(cc<1> EOR cc<0>):''0'';
         if InITBlock() then UNPREDICTABLE;


        Assembler symbols

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.


        Operation for all encodings

         EncodingSpecificOperations(); CheckVFPEnabled(TRUE);
         if dp_operation then
               D[d] = if ConditionHolds(cond) then D[n] else D[m];
         else
               S[d] = if ConditionHolds(cond) then S[n] else S[m];');
INSERT INTO "instructions" VALUES('ARM','VSELGE','-R:VSELEQ');
INSERT INTO "instructions" VALUES('ARM','VSELGT','-R:VSELEQ');
INSERT INTO "instructions" VALUES('ARM','VSELVS','-R:VSELEQ');
INSERT INTO "instructions" VALUES('ARM','VSHL','Vector Shift Left (immediate) takes each element in a vector of integers, left shifts them by an immediate value, and       (F8.1.202)
places the results in the destination vector.

Bits shifted out of the left of each element are lost.

The elements must all be the same size, and can be 8-bit, 16-bit, 32-bit, or 64-bit integers. There is no distinction
between signed and unsigned integers.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21                  16 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 0 1 D                    imm6             Vd        0 1 0 1 L Q M 1              Vm




64-bit SIMD vector variant

Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

VSHL{<c>}{<q>}.I<size> {<Dd>,} <Dm>, #<imm>


128-bit SIMD vector variant

Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

VSHL{<c>}{<q>}.I<size> {<Qd>,} <Qm>, #<imm>


Decode for all variants of this encoding

 if L:imm6 == ''0000xxx'' then SEE "Related encodings";
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
      when "0001xxx"    esize = 8;    elements = 8;   shift_amount = UInt(imm6) - 8;
      when "001xxxx"    esize = 16;    elements = 4;    shift_amount = UInt(imm6) - 16;
      when "01xxxxx"    esize = 32;    elements = 2;    shift_amount = UInt(imm6) - 32;
      when "1xxxxxx"    esize = 64;    elements = 1;    shift_amount = UInt(imm6);
 d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5                        0 15       12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 0 1 1 1 1 1 D                    imm6             Vd        0 1 0 1 L Q M 1              Vm




64-bit SIMD vector variant

Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

VSHL{<c>}{<q>}.I<size> {<Dd>,} <Dm>, #<imm>


128-bit SIMD vector variant

Applies when !(imm6 == 000xxx && L == 0) && Q = 1.
        VSHL{<c>}{<q>}.I<size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if L:imm6 == ''0000xxx'' then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;     elements = 8;   shift_amount = UInt(imm6) - 8;
               when "001xxxx"    esize = 16;     elements = 4;    shift_amount = UInt(imm6) - 16;
               when "01xxxxx"    esize = 32;     elements = 2;    shift_amount = UInt(imm6) - 32;
               when "1xxxxxx"    esize = 64;     elements = 1;    shift_amount = UInt(imm6);
         d = UInt(D:Vd);      m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


        Notes for all encodings

        Related encodings: One register and a modified immediate value on page F5-2596.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VSHL instruction must be
                          unconditional. ARM strongly recommends that a T32 VSHL instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <size>            Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
                          following values:

                          8            when L = 0, imm6<5:3> = 001

                          16           when L = 0, imm6<5:3> = 01x

                          32           when L = 0, imm6<5:3> = 1xx

                          64           when L = 1, imm6<5:3> = xxx

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

        <imm>             Is an immediate value, in the range 0 to <size>-1, encoded in the "imm6" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   for e = 0 to elements-1
                        Elem[D[d+r],e,esize] = LSL(Elem[D[m+r],e,esize], shift_amount);');
INSERT INTO "instructions" VALUES('ARM','VSHLL','Vector Shift Left Long takes each element in a doubleword vector, left shifts them by an immediate value, and       (F8.1.204)
places the results in a quadword vector.

The operand elements can be:

.      8-bit, 16-bit, or 32-bit signed integers.

.      8-bit, 16-bit, or 32-bit unsigned integers.

.      8-bit, 16-bit, or 32-bit untyped integers, maximum shift only.

The result elements are twice the length of the operand elements.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21                 16 15        12 11 10 9 8 7 6 5 4 3                  0
   1 1 1 1 0 0 1 U 1 D                     imm6            Vd         1 0 1 0 0 0 M 1              Vm




A1 variant

Applies when imm6 != 000xxx.

VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm>


Decode for this encoding

 if imm6 == ''000xxx'' then SEE "Related encodings";
 if Vd<0> == ''1'' then UNDEFINED;
 case imm6 of
      when "001xxx"    esize = 8;    elements = 8;   shift_amount = UInt(imm6) - 8;
      when "01xxxx"    esize = 16;    elements = 4;   shift_amount = UInt(imm6) - 16;
      when "1xxxxx"    esize = 32;    elements = 2;   shift_amount = UInt(imm6) - 32;
 if shift_amount == 0 then SEE VMOVL;
 unsigned = (U == ''1'');      d = UInt(D:Vd);    m = UInt(M:Vm);


A2


  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 3                  0
   1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd         0 0 1 1 0 0 M 0              Vm




A2 variant

VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm>


Decode for this encoding

 if size == ''11'' || Vd<0> == ''1'' then UNDEFINED;
 esize = 8 << UInt(size);       elements = 64 DIV esize;   shift_amount = esize;
 unsigned = FALSE;     // Or TRUE without change of functionality
 d = UInt(D:Vd);     m = UInt(M:Vm);
        T1


           15 14 13 12 11 10 9 8 7 6 5                      0 15        12 11 10 9 8 7 6 5 4 3             0
            1 1 1 U 1 1 1 1 1 D                   imm6             Vd       1 0 1 0 0 0 M 1           Vm




        T1 variant

        Applies when imm6 != 000xxx.

        VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm>


        Decode for this encoding

         if imm6 == ''000xxx'' then SEE "Related encodings";
         if Vd<0> == ''1'' then UNDEFINED;
         case imm6 of
               when "001xxx"   esize = 8;    elements = 8;   shift_amount = UInt(imm6) - 8;
               when "01xxxx"   esize = 16;    elements = 4;   shift_amount = UInt(imm6) - 16;
               when "1xxxxx"   esize = 32;    elements = 2;   shift_amount = UInt(imm6) - 32;
         if shift_amount == 0 then SEE VMOVL;
         unsigned = (U == ''1'');     d = UInt(D:Vd);    m = UInt(M:Vm);


        T2


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3             0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                       Vd       0 0 1 1 0 0 M 0           Vm




        T2 variant

        VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm>


        Decode for this encoding

         if size == ''11'' || Vd<0> == ''1'' then UNDEFINED;
         esize = 8 << UInt(size);     elements = 64 DIV esize;     shift_amount = esize;
         unsigned = FALSE;     // Or TRUE without change of functionality
         d = UInt(D:Vd);     m = UInt(M:Vm);


        Notes for all encodings

        Related encodings: One register and a modified immediate value on page F5-2596.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VSHLL instruction must be
                          unconditional. ARM strongly recommends that a T32 VSHLL instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <type>            The data type for the elements of the operand. It must be one of:

                          S          Signed. In encoding T1/A1, encoded as U = 0.

                          U          Unsigned. In encoding T1/A1, encoded as U = 1.

                          I          Untyped integer, Available only in encoding T2/A2.
<size>        The data size for the elements of the operand. The following table shows the permitted values and
              their encodings:


                                          <size>      Encoding T1/A1                       Encoding T2/A2

                                          8           Encoded as imm6<5:3> = 0b001         Encoded as size = 0b00

                                          16          Encoded as imm6<5:4> = 0b01          Encoded as size = 0b01

                                          32          Encoded as imm6<5> = 1               Encoded as size = 0b10


<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         The immediate value. <imm> must lie in the range 1 to <size>, and:

              .      If <size> == <imm>, the encoding is T2/A2.

              .      Otherwise, the encoding is T1/A1, and:

                     --      If <size> == 8, <imm> is encoded in imm6<2:0>.

                     --      If <size> == 16, <imm> is encoded in imm6<3:0>.

                     --      If <size> == 32, <imm> is encoded in imm6<4:0>.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();     CheckAdvSIMDEnabled();
    for e = 0 to elements-1
        result = Int(Elem[Din[m],e,esize], unsigned) << shift_amount;
        Elem[Q[d>>1],e,2*esize] = result<2*esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VSHR','        Vector Shift Right takes each element in a vector, right shifts them by an immediate value, and places the truncated       (F8.1.205)
        results in the destination vector. For rounded results, see VRSHR.

        The operand and result elements must be the same size, and can be any one of:

        .       8-bit, 16-bit, 32-bit, or 64-bit signed integers.

        .       8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                  16 15       12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 U 1 D                     imm6            Vd      0 0 0 0 L Q M 1             Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSHR{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VSHR{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;    elements = 8;    shift_amount = 16 - UInt(imm6);
               when "001xxxx"    esize = 16;     elements = 4;   shift_amount = 32 - UInt(imm6);
               when "01xxxxx"    esize = 32;     elements = 2;   shift_amount = 64 - UInt(imm6);
               when "1xxxxxx"    esize = 64;     elements = 1;   shift_amount = 64 - UInt(imm6);
         unsigned = (U == ''1'');       d = UInt(D:Vd);    m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5                        0 15       12 11 10 9 8 7 6 5 4 3               0
            1 1 1 U 1 1 1 1 1 D                     imm6            Vd      0 0 0 0 L Q M 1             Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSHR{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.
VSHR{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


Decode for all variants of this encoding

 if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
     when "0001xxx"  esize = 8;     elements = 8;   shift_amount = 16 - UInt(imm6);
     when "001xxxx"  esize = 16;     elements = 4;    shift_amount = 32 - UInt(imm6);
     when "01xxxxx"  esize = 32;     elements = 2;    shift_amount = 64 - UInt(imm6);
     when "1xxxxxx"  esize = 64;     elements = 1;    shift_amount = 64 - UInt(imm6);
 unsigned = (U == ''1'');   d = UInt(D:Vd);    m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VSHR instruction must be
              unconditional. ARM strongly recommends that a T32 VSHR instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<type>        Is the data type for the elements of the vectors, encoded in the "U" field. It can have the following
              values:

              S            when U = 0

              U            when U = 1

<size>        Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
              following values:

              8            when L = 0, imm6<5:3> = 001

              16           when L = 0, imm6<5:3> = 01x

              32           when L = 0, imm6<5:3> = 1xx

              64           when L = 1, imm6<5:3> = xxx

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         Is an immediate value, in the range 1 to <size>, encoded in the "imm6" field as <size> - <imm>.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             result = Int(Elem[D[m+r],e,esize], unsigned) >> shift_amount;
             Elem[D[d+r],e,esize] = result<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VSHRN','        Vector Shift Right Narrow takes each element in a vector, right shifts them by an immediate value, and places the       (F8.1.207)
        truncated results in the destination vector. For rounded results, see VRSHRN.

        The operand elements can be 16-bit, 32-bit, or 64-bit integers. There is no distinction between signed and unsigned
        integers. The destination elements are half the size of the source elements.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                16 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 1 0 0 1 0 1 D                  imm6              Vd       1 0 0 0 0 0 M 1              Vm




        A1 variant

        Applies when imm6 != 000xxx.

        VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm>


        Decode for this encoding

         if imm6 == ''000xxx'' then SEE "Related encodings";
         if Vm<0> == ''1'' then UNDEFINED;
         case imm6 of
               when "001xxx"   esize = 8;   elements = 8;   shift_amount = 16 - UInt(imm6);
               when "01xxxx"   esize = 16;   elements = 4;   shift_amount = 32 - UInt(imm6);
               when "1xxxxx"   esize = 32;   elements = 2;   shift_amount = 64 - UInt(imm6);
         d = UInt(D:Vd);     m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5                      0 15        12 11 10 9 8 7 6 5 4 3                0
            1 1 1 0 1 1 1 1 1 D                  imm6              Vd       1 0 0 0 0 0 M 1              Vm




        T1 variant

        Applies when imm6 != 000xxx.

        VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm>


        Decode for this encoding

         if imm6 == ''000xxx'' then SEE "Related encodings";
         if Vm<0> == ''1'' then UNDEFINED;
         case imm6 of
               when "001xxx"   esize = 8;   elements = 8;   shift_amount = 16 - UInt(imm6);
               when "01xxxx"   esize = 16;   elements = 4;   shift_amount = 32 - UInt(imm6);
               when "1xxxxx"   esize = 32;   elements = 2;   shift_amount = 64 - UInt(imm6);
         d = UInt(D:Vd);     m = UInt(M:Vm);
Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VSHRN instruction must be
              unconditional. ARM strongly recommends that a T32 VSHRN instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<size>        Is the data size for the elements of the vectors, encoded in the "imm6<5:3>" field. It can have the
              following values:

              16          when imm6<5:3> = 001

              32          when imm6<5:3> = 01x

              64          when imm6<5:3> = 1xx

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

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

<imm>         Is an immediate value, in the range 1 to <size>/2, encoded in the "imm6" field as <size>/2 - <imm>.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for e = 0 to elements-1
         result = LSR(Elem[Qin[m>>1],e,2*esize], shift_amount);
         Elem[D[d],e,esize] = result<esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VSLI','        Vector Shift Left and Insert takes each element in the operand vector, left shifts them by an immediate value, and       (F8.1.209)
        inserts the results in the destination vector. Bits shifted out of the left of each element are lost.

        The elements must all be the same size, and can be 8-bit, 16-bit, 32-bit, or 64-bit. There is no distinction between
        data types.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                  16 15         12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 1 1 D                    imm6              Vd        0 1 0 1 L Q M 1               Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSLI{<c>}{<q>}.<size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VSLI{<c>}{<q>}.<size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;   elements = 8;     shift_amount = UInt(imm6) - 8;
               when "001xxxx"    esize = 16;   elements = 4;     shift_amount = UInt(imm6) - 16;
               when "01xxxxx"    esize = 32;   elements = 2;     shift_amount = UInt(imm6) - 32;
               when "1xxxxxx"    esize = 64;   elements = 1;     shift_amount = UInt(imm6);
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5                        0 15         12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 1 1 1 1 1 D                    imm6              Vd        0 1 0 1 L Q M 1               Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSLI{<c>}{<q>}.<size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VSLI{<c>}{<q>}.<size> {<Qd>,} <Qm>, #<imm>
Decode for all variants of this encoding

 if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
     when "0001xxx"  esize = 8;     elements = 8;   shift_amount = UInt(imm6) - 8;
     when "001xxxx"  esize = 16;     elements = 4;    shift_amount = UInt(imm6) - 16;
     when "01xxxxx"  esize = 32;     elements = 2;    shift_amount = UInt(imm6) - 32;
     when "1xxxxxx"  esize = 64;     elements = 1;    shift_amount = UInt(imm6);
 d = UInt(D:Vd);  m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VSLI instruction must be
              unconditional. ARM strongly recommends that a T32 VSLI instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<size>        Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
              following values:

              8            when L = 0, imm6<5:3> = 001

              16           when L = 0, imm6<5:3> = 01x

              32           when L = 0, imm6<5:3> = 1xx

              64           when L = 1, imm6<5:3> = xxx

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         Is an immediate value, in the range 0 to <size>-1, encoded in the "imm6" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     mask = LSL(Ones(esize), shift_amount);
     for r = 0 to regs-1
         for e = 0 to elements-1
             shifted_op = LSL(Elem[D[m+r],e,esize], shift_amount);
             Elem[D[d+r],e,esize] = (Elem[D[d+r],e,esize] AND NOT(mask)) OR shifted_op;');
INSERT INTO "instructions" VALUES('ARM','VSQRT','        Square Root calculates the square root of the value in a floating-point register and writes the result to another       (F8.1.210)
        floating-point register.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19 18 17 16 15         12 11 10 9 8 7 6 5 4 3                   0
              !=1111     1 1 1 0 1 D 1 1 0 0 0 1                  Vd       1 0 1 sz 1 1 M 0              Vm
               cond


        Single-precision scalar variant

        Applies when sz = 0.

        VSQRT{<c>}{<q>}.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VSQRT{<c>}{<q>}.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                   0
            1 1 1 0 1 1 1 0 1 D 1 1 0 0 0 1                       Vd       1 0 1 sz 1 1 M 0              Vm




        Single-precision scalar variant

        Applies when sz = 0.

        VSQRT{<c>}{<q>}.F32 <Sd>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VSQRT{<c>}{<q>}.F64 <Dd>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506.

<q>           See Standard assembler syntax fields on page F2-2506.

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

<Sm>          Is the 32-bit name of the SIMD&FP source register, encoded in the "Vm:M" field.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
    EncodingSpecificOperations();    CheckVFPEnabled(TRUE);
    if dp_operation then
        D[d] = FPSqrt(D[m], StandardFPSCRValue());
    else
        S[d] = FPSqrt(S[m], StandardFPSCRValue());');
INSERT INTO "instructions" VALUES('ARM','VSRA','        Vector Shift Right and Accumulate takes each element in a vector, right shifts them by an immediate value, and       (F8.1.211)
        accumulates the truncated results into the destination vector. For rounded results, see VRSRA.

        The operand and result elements must all be the same type, and can be any one of:

        .       8-bit, 16-bit, 32-bit, or 64-bit signed integers.

        .       8-bit, 16-bit, 32-bit, or 64-bit unsigned integers.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                  16 15       12 11 10 9 8 7 6 5 4 3             0
            1 1 1 1 0 0 1 U 1 D                     imm6            Vd      0 0 0 1 L Q M 1            Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSRA{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VSRA{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;    elements = 8;    shift_amount = 16 - UInt(imm6);
               when "001xxxx"    esize = 16;     elements = 4;   shift_amount = 32 - UInt(imm6);
               when "01xxxxx"    esize = 32;     elements = 2;   shift_amount = 64 - UInt(imm6);
               when "1xxxxxx"    esize = 64;     elements = 1;   shift_amount = 64 - UInt(imm6);
         unsigned = (U == ''1'');       d = UInt(D:Vd);    m = UInt(M:Vm);  regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5                        0 15       12 11 10 9 8 7 6 5 4 3             0
            1 1 1 U 1 1 1 1 1 D                     imm6            Vd      0 0 0 1 L Q M 1            Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSRA{<c>}{<q>}.<type><size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.
VSRA{<c>}{<q>}.<type><size> {<Qd>,} <Qm>, #<imm>


Decode for all variants of this encoding

 if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
     when "0001xxx"  esize = 8;     elements = 8;   shift_amount = 16 - UInt(imm6);
     when "001xxxx"  esize = 16;     elements = 4;    shift_amount = 32 - UInt(imm6);
     when "01xxxxx"  esize = 32;     elements = 2;    shift_amount = 64 - UInt(imm6);
     when "1xxxxxx"  esize = 64;     elements = 1;    shift_amount = 64 - UInt(imm6);
 unsigned = (U == ''1'');   d = UInt(D:Vd);    m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VSRA instruction must be
              unconditional. ARM strongly recommends that a T32 VSRA instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<type>        Is the data type for the elements of the vectors, encoded in the "U" field. It can have the following
              values:

              S            when U = 0

              U            when U = 1

<size>        Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
              following values:

              8            when L = 0, imm6<5:3> = 001

              16           when L = 0, imm6<5:3> = 01x

              32           when L = 0, imm6<5:3> = 1xx

              64           when L = 1, imm6<5:3> = xxx

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         Is an immediate value, in the range 1 to <size>, encoded in the "imm6" field as <size> - <imm>.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             result = Int(Elem[D[m+r],e,esize], unsigned) >> shift_amount;
             Elem[D[d+r],e,esize] = Elem[D[d+r],e,esize] + result;');
INSERT INTO "instructions" VALUES('ARM','VSRI','        Vector Shift Right and Insert takes each element in the operand vector, right shifts them by an immediate value, and       (F8.1.212)
        inserts the results in the destination vector. Bits shifted out of the right of each element are lost.

        The elements must all be the same size, and can be 8-bit, 16-bit, 32-bit, or 64-bit. There is no distinction between
        data types.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21                  16 15         12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 1 1 D                    imm6              Vd        0 1 0 0 L Q M 1               Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSRI{<c>}{<q>}.<size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VSRI{<c>}{<q>}.<size> {<Qd>,} <Qm>, #<imm>


        Decode for all variants of this encoding

         if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         case L:imm6 of
               when "0001xxx"    esize = 8;   elements = 8;     shift_amount = 16 - UInt(imm6);
               when "001xxxx"    esize = 16;   elements = 4;     shift_amount = 32 - UInt(imm6);
               when "01xxxxx"    esize = 32;   elements = 2;     shift_amount = 64 - UInt(imm6);
               when "1xxxxxx"    esize = 64;   elements = 1;     shift_amount = 64 - UInt(imm6);
         d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5                        0 15         12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 1 1 1 1 1 D                    imm6              Vd        0 1 0 0 L Q M 1               Vm




        64-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 0.

        VSRI{<c>}{<q>}.<size> {<Dd>,} <Dm>, #<imm>


        128-bit SIMD vector variant

        Applies when !(imm6 == 000xxx && L == 0) && Q = 1.

        VSRI{<c>}{<q>}.<size> {<Qd>,} <Qm>, #<imm>
Decode for all variants of this encoding

 if (L:imm6) == ''0000xxx'' then SEE "Related encodings";
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 case L:imm6 of
     when "0001xxx"  esize = 8;     elements = 8;   shift_amount = 16 - UInt(imm6);
     when "001xxxx"  esize = 16;     elements = 4;    shift_amount = 32 - UInt(imm6);
     when "01xxxxx"  esize = 32;     elements = 2;    shift_amount = 64 - UInt(imm6);
     when "1xxxxxx"  esize = 64;     elements = 1;    shift_amount = 64 - UInt(imm6);
 d = UInt(D:Vd);  m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


Notes for all encodings

Related encodings: One register and a modified immediate value on page F5-2596.


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VSRI instruction must be
              unconditional. ARM strongly recommends that a T32 VSRI instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<size>        Is the data size for the elements of the vectors, encoded in the "L:imm6<5:3>" field. It can have the
              following values:

              8            when L = 0, imm6<5:3> = 001

              16           when L = 0, imm6<5:3> = 01x

              32           when L = 0, imm6<5:3> = 1xx

              64           when L = 1, imm6<5:3> = xxx

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.

<imm>         Is an immediate value, in the range 1 to <size>, encoded in the "imm6" field as <size> - <imm>.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     mask = LSR(Ones(esize), shift_amount);
     for r = 0 to regs-1
         for e = 0 to elements-1
             shifted_op = LSR(Elem[D[m+r],e,esize], shift_amount);
             Elem[D[d+r],e,esize] = (Elem[D[d+r],e,esize] AND NOT(mask)) OR shifted_op;');
INSERT INTO "instructions" VALUES('ARM','VST1','        Store single element from one lane of one register stores one element to memory from one element of a register. For       (F8.1.213)
        details of the addressing mode see Advanced SIMD addressing mode on page F5-2605.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7          4 3         0
            1 1 1 1 0 1 0 0 1 D 0 0                   Rn           Vd      !=11 0 0 index_align        Rm
                                                                           size


        Offset variant

        Applies when Rm = 1111.

        VST1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


        Post-indexed variant

        Applies when Rm = 1101.

        VST1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VST1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         case size of
               when ''00''
                   if index_align<0> != ''0'' then UNDEFINED;
                   ebytes = 1;   index = UInt(index_align<3:1>);     alignment = 1;
               when ''01''
                   if index_align<1> != ''0'' then UNDEFINED;
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   alignment = if index_align<0> == ''0'' then 1 else 2;
               when ''10''
                   if index_align<2> != ''0'' then UNDEFINED;
                   if index_align<1:0> != ''00'' && index_align<1:0> != ''11'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   alignment = if index_align<1:0> == ''00'' then 1 else 4;
         d = UInt(D:Vd);     n = UInt(Rn);   m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7          4 3         0
            1 1 1 1 1 0 0 1 1 D 0 0                   Rn           Vd      !=11 0 0 index_align        Rm
                                                                           size
Offset variant

Applies when Rm = 1111.

VST1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


Post-indexed variant

Applies when Rm = 1101.

VST1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


Post-indexed variant

Applies when Rm != 11x1.

VST1{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 case size of
     when ''00''
         if index_align<0> != ''0'' then UNDEFINED;
         ebytes = 1;   index = UInt(index_align<3:1>);     alignment = 1;
     when ''01''
         if index_align<1> != ''0'' then UNDEFINED;
         ebytes = 2;   index = UInt(index_align<3:2>);
         alignment = if index_align<0> == ''0'' then 1 else 2;
     when ''10''
         if index_align<2> != ''0'' then UNDEFINED;
         if index_align<1:0> != ''00'' && index_align<1:0> != ''11'' then UNDEFINED;
         ebytes = 4;   index = UInt(index_align<3>);
         alignment = if index_align<1:0> == ''00'' then 1 else 4;
 d = UInt(D:Vd);  n = UInt(Rn);    m = UInt(Rm);
 wback = (m != 15);   register_index = (m != 15 && m != 13);
 if n == 15 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 VST1 instruction must be
               unconditional. ARM strongly recommends that a T32 VST1 instruction is unconditional, see
               Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<size>         The data size. It must be one of:

               8           Encoded as size = 0b00.

               16          Encoded as size = 0b01.

               32          Encoded as size = 0b10.

<list>         The register containing the element to store. It must be {<Dd[x]>}. The register <Dd> is encoded in
               D:Vd.

<Rn>           Contains the base address for the access.

<align>        The alignment. It can be one of:

               16          2-byte alignment, available only if <size> is 16.
                          32           4-byte alignment, available only if <size> is 32.

                          omitted      Standard alignment, see Unaligned data access on page E2-2427.

                          : is the preferred separator before the <align> value, but the alignment can be specified as @<align>,
                          see Advanced SIMD addressing mode on page F5-2605.

        <Rm>              Contains an address offset applied after the access.

        For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

        Table F8-5 shows the encoding of index and alignment for different <size> values.

                                                                          Table F8-5 Encoding of index and alignment

                                              <size> == 8              <size> == 16                 <size> == 32

                         Index                index_align[3:1] = x     index_align[3:2] = x         index_align[3] = x

                         <align> omitted      index_align[0] = 0       index_align[1:0] = ''00''      index_align[2:0] = ''000''

                         <align> == 16        -                        index_align[1:0] = ''01''      -

                         <align> == 32        -                        -                            index_align[2:0] = ''011''



        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDEnabled();
               address = R[n];     if (address MOD alignment) != 0 then GenerateAlignmentException();
               if wback then
                   if register_index then
                        R[n] = R[n] + R[m];
                   else
                        R[n] = R[n] + ebytes;
               MemU[address,ebytes] = Elem[D[d],index];');
INSERT INTO "instructions" VALUES('ARM','VST2','        Store single 2-element structure from one lane of two registers stores one 2-element structure to memory from       (F8.1.215)
        corresponding elements of two registers. For details of the addressing mode see Advanced SIMD addressing mode
        on page F5-2605.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7           4 3         0
            1 1 1 1 0 1 0 0 1 D 0 0                   Rn           Vd      !=11 0 1 index_align         Rm
                                                                           size


        Offset variant

        Applies when Rm = 1111.

        VST2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


        Post-indexed variant

        Applies when Rm = 1101.

        VST2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VST2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         case size of
               when ''00''
                   ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
                   alignment = if index_align<0> == ''0'' then 1 else 2;
               when ''01''
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   inc = if index_align<1> == ''0'' then 1 else 2;
                   alignment = if index_align<0> == ''0'' then 1 else 4;
               when ''10''
                   if index_align<1> != ''0'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   inc = if index_align<2> == ''0'' then 1 else 2;
                   alignment = if index_align<0> == ''0'' then 1 else 8;
         d = UInt(D:Vd);     d2 = d + inc;   n = UInt(Rn);   m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 || d2 > 31 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7           4 3         0
            1 1 1 1 1 0 0 1 1 D 0 0                   Rn           Vd      !=11 0 1 index_align         Rm
                                                                           size
Offset variant

Applies when Rm = 1111.

VST2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


Post-indexed variant

Applies when Rm = 1101.

VST2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


Post-indexed variant

Applies when Rm != 11x1.

VST2{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 case size of
     when ''00''
         ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
         alignment = if index_align<0> == ''0'' then 1 else 2;
     when ''01''
         ebytes = 2;   index = UInt(index_align<3:2>);
         inc = if index_align<1> == ''0'' then 1 else 2;
         alignment = if index_align<0> == ''0'' then 1 else 4;
     when ''10''
         if index_align<1> != ''0'' then UNDEFINED;
         ebytes = 4;   index = UInt(index_align<3>);
         inc = if index_align<2> == ''0'' then 1 else 2;
         alignment = if index_align<0> == ''0'' then 1 else 8;
 d = UInt(D:Vd);  d2 = d + inc;    n = UInt(Rn);   m = UInt(Rm);
 wback = (m != 15);   register_index = (m != 15 && m != 13);
 if n == 15 || d2 > 31 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly VST2 (single 2-element structure from
one lane) on page J1-5391.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 VST2 instruction must be
               unconditional. ARM strongly recommends that a T32 VST2 instruction is unconditional, see
               Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<size>         The data size. It must be one of:

               8           Encoded as size = 0b00.

               16          Encoded as size = 0b01.

               32          Encoded as size = 0b10.

<list>         The registers containing the structure. Encoded with D:Vd = <Dd>. It must be one of:

               {<Dd[x]>, <Dd+1[x]>}
                           Single-spaced registers, see Table F8-6 on page F8-3740.

               {<Dd[x]>, <Dd+2[x]>}
                           Double-spaced registers, see Table F8-6 on page F8-3740.
                          This is not available if <size> == 8.

        <Rn>              Contains the base address for the access.

        <align>           The alignment. It can be one of:

                          16           2-byte alignment, available only if <size> is 8.

                          32           4-byte alignment, available only if <size> is 16.

                          64           8-byte alignment, available only if <size> is 32.

                          omitted      Standard alignment, see Unaligned data access on page E2-2427.

                          : is the preferred separator before the <align> value, but the alignment can be specified as @<align>,
                          see Advanced SIMD addressing mode on page F5-2605.

        <Rm>              Contains an address offset applied after the access.

        For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

                                                    Table F8-6 Encoding of index, alignment, and register spacing

                                                  <size> == 8              <size> == 16              <size> == 32

                             Index                index_align[3:1] = x     index_align[3:2] = x      index_align[3] = x

                             Single-spacing       -                        index_align[1] = 0        index_align[2] = 0

                             Double-spacing       -                        index_align[1] = 1        index_align[2] = 1

                             <align> omitted      index_align[0] = 0       index_align[0] = 0        index_align[1:0] = ''00''

                             <align> == 16        index_align[0] = 1       -                         -

                             <align> == 32        -                        index_align[0] = 1        -

                             <align> == 64        -                        -                         index_align[1:0] = ''01''



        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               address = R[n];     if (address MOD alignment) != 0 then GenerateAlignmentException();
               if wback then
                   if register_index then
                        R[n] = R[n] + R[m];
                   else
                        R[n] = R[n] + 2*ebytes;
               MemU[address,          ebytes] = Elem[D[d], index];
               MemU[address+ebytes,ebytes] = Elem[D[d2],index];');
INSERT INTO "instructions" VALUES('ARM','VST3','        Store single 3-element structure from one lane of three registers stores one 3-element structure to memory from       (F8.1.217)
        corresponding elements of three registers. For details of the addressing mode see Advanced SIMD addressing mode
        on page F5-2605.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15        12 11 10 9 8 7           4 3         0
            1 1 1 1 0 1 0 0 1 D 0 0                   Rn           Vd       !=11 1 0 index_align        Rm
                                                                            size


        Offset variant

        Applies when Rm = 1111.

        VST3{<c>}{<q>}.<size> <list>, [<Rn>]


        Post-indexed variant

        Applies when Rm = 1101.

        VST3{<c>}{<q>}.<size> <list>, [<Rn>]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VST3{<c>}{<q>}.<size> <list>, [<Rn>], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         case size of
               when ''00''
                   if index_align<0> != ''0'' then UNDEFINED;
                   ebytes = 1;   index = UInt(index_align<3:1>);      inc = 1;
               when ''01''
                   if index_align<0> != ''0'' then UNDEFINED;
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   inc = if index_align<1> == ''0'' then 1 else 2;
               when ''10''
                   if index_align<1:0> != ''00'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   inc = if index_align<2> == ''0'' then 1 else 2;
         d = UInt(D:Vd);     d2 = d + inc;   d3 = d2 + inc;   n = UInt(Rn);    m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 || d3 > 31 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7           4 3         0
            1 1 1 1 1 0 0 1 1 D 0 0                   Rn           Vd       !=11 1 0 index_align        Rm
                                                                            size
Offset variant

Applies when Rm = 1111.

VST3{<c>}{<q>}.<size> <list>, [<Rn>]


Post-indexed variant

Applies when Rm = 1101.

VST3{<c>}{<q>}.<size> <list>, [<Rn>]!


Post-indexed variant

Applies when Rm != 11x1.

VST3{<c>}{<q>}.<size> <list>, [<Rn>], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 case size of
     when ''00''
         if index_align<0> != ''0'' then UNDEFINED;
         ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
     when ''01''
         if index_align<0> != ''0'' then UNDEFINED;
         ebytes = 2;   index = UInt(index_align<3:2>);
         inc = if index_align<1> == ''0'' then 1 else 2;
     when ''10''
         if index_align<1:0> != ''00'' then UNDEFINED;
         ebytes = 4;   index = UInt(index_align<3>);
         inc = if index_align<2> == ''0'' then 1 else 2;
 d = UInt(D:Vd);  d2 = d + inc;    d3 = d2 + inc;    n = UInt(Rn);     m = UInt(Rm);
 wback = (m != 15);   register_index = (m != 15 && m != 13);
 if n == 15 || d3 > 31 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly VST3 (single 3-element structure from
one lane) on page J1-5392.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 VST3 instruction must be
               unconditional. ARM strongly recommends that a T32 VST3 instruction is unconditional, see
               Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<size>         The data size. It must be one of:

               8           Encoded as size = 0b00.

               16          Encoded as size = 0b01.

               32          Encoded as size = 0b10.

<list>         The registers containing the structure. Encoded with D:Vd = <Dd>. It must be one of:

               {<Dd[x]>, <Dd+1[x]>, <Dd+2[x]>}
                           Single-spaced registers, see Table F8-7 on page F8-3746.

               {<Dd[x]>, <Dd+2[x]>, <Dd+4[x]>}
                           Double-spaced registers, see Table F8-7 on page F8-3746.

               This is not available if <size> == 8.
        <Rn>              Contains the base address for the access.

        <Rm>              Contains an address offset applied after the access.

        For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

                                                                 Table F8-7 Encoding of index and register spacing

                                            <size> == 8               <size> == 16            <size> == 32

                         Index              index_align[3:1] = x      index_align[3:2] = x    index_align[3] = x

                         Single-spacing     index_align[0] = 0        index_align[1:0] = ''00'' index_align[2:0] = ''000''

                         Double-spacing     -                         index_align[1:0] = ''10'' index_align[2:0] = ''100''



        Alignment

        Standard alignment rules apply, see Alignment support on page B2-75.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();    CheckAdvSIMDEnabled();
               address = R[n];
               if wback then
                   if register_index then
                        R[n] = R[n] + R[m];
                   else
                        R[n] = R[n] + 3*ebytes;
               MemU[address,           ebytes] = Elem[D[d], index];
               MemU[address+ebytes,    ebytes] = Elem[D[d2],index];
               MemU[address+2*ebytes,ebytes] = Elem[D[d3],index];');
INSERT INTO "instructions" VALUES('ARM','VST4','        Store single 4-element structure from one lane of four registers stores one 4-element structure to memory from       (F8.1.219)
        corresponding elements of four registers. For details of the addressing mode see Advanced SIMD addressing mode
        on page F5-2605.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7            4 3         0
            1 1 1 1 0 1 0 0 1 D 0 0                   Rn           Vd      !=11 1 1 index_align         Rm
                                                                           size


        Offset variant

        Applies when Rm = 1111.

        VST4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


        Post-indexed variant

        Applies when Rm = 1101.

        VST4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


        Post-indexed variant

        Applies when Rm != 11x1.

        VST4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         case size of
               when ''00''
                   ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
                   alignment = if index_align<0> == ''0'' then 1 else 4;
               when ''01''
                   ebytes = 2;   index = UInt(index_align<3:2>);
                   inc = if index_align<1> == ''0'' then 1 else 2;
                   alignment = if index_align<0> == ''0'' then 1 else 8;
               when ''10''
                   if index_align<1:0> == ''11'' then UNDEFINED;
                   ebytes = 4;   index = UInt(index_align<3>);
                   inc = if index_align<2> == ''0'' then 1 else 2;
                   alignment = if index_align<1:0> == ''00'' then 1 else 4 << UInt(index_align<1:0>);
         d = UInt(D:Vd);     d2 = d + inc;   d3 = d2 + inc;   d4 = d3 + inc;    n = UInt(Rn);  m = UInt(Rm);
         wback = (m != 15);     register_index = (m != 15 && m != 13);
         if n == 15 || d4 > 31 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15       12 11 10 9 8 7            4 3         0
            1 1 1 1 1 0 0 1 1 D 0 0                   Rn           Vd      !=11 1 1 index_align         Rm
                                                                           size
Offset variant

Applies when Rm = 1111.

VST4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]


Post-indexed variant

Applies when Rm = 1101.

VST4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}]!


Post-indexed variant

Applies when Rm != 11x1.

VST4{<c>}{<q>}.<size> <list>, [<Rn>{:<align>}], <Rm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 case size of
     when ''00''
         ebytes = 1;   index = UInt(index_align<3:1>);     inc = 1;
         alignment = if index_align<0> == ''0'' then 1 else 4;
     when ''01''
         ebytes = 2;   index = UInt(index_align<3:2>);
         inc = if index_align<1> == ''0'' then 1 else 2;
         alignment = if index_align<0> == ''0'' then 1 else 8;
     when ''10''
         if index_align<1:0> == ''11'' then UNDEFINED;
         ebytes = 4;   index = UInt(index_align<3>);
         inc = if index_align<2> == ''0'' then 1 else 2;
         alignment = if index_align<1:0> == ''00'' then 1 else 4 << UInt(index_align<1:0>);
 d = UInt(D:Vd);  d2 = d + inc;    d3 = d2 + inc;    d4 = d3 + inc;      n = UInt(Rn);    m = UInt(Rm);
 wback = (m != 15);   register_index = (m != 15 && m != 13);
 if n == 15 || d4 > 31 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors, and particularly VST4 (single 4-element structure from
one lane) on page J1-5393.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506. An A32 VST4 instruction must be
               unconditional. ARM strongly recommends that a T32 VST4 instruction is unconditional, see
               Conditional execution on page F2-2507.

<q>            See Standard assembler syntax fields on page F2-2506.

<size>         The data size. It must be one of:

               8           Encoded as size = 0b00.

               16          Encoded as size = 0b01.

               32          Encoded as size = 0b10.

<list>         The registers containing the structure. Encoded with D:Vd = <Dd>. It must be one of:

               {<Dd[x]>, <Dd+1[x]>, <Dd+2[x]>, <Dd+3[x]>}
                           Single-spaced registers, see Table F8-8 on page F8-3752.

               {<Dd[x]>, <Dd+2[x]>, <Dd+4[x]>, <Dd+6[x]>}
                           Double-spaced registers, see Table F8-8 on page F8-3752.
                          This is not available if <size> == 8.

        <Rn>              The base address for the access.

        <align>           The alignment. It can be:

                          32           4-byte alignment, available only if <size> is 8.

                          64           8-byte alignment, available only if <size> is 16 or 32.

                          128          16-byte alignment, available only if <size> is 32.

                          omitted      Standard alignment, see Unaligned data access on page E2-2427.

                          : is the preferred separator before the <align> value, but the alignment can be specified as @<align>,
                          see Advanced SIMD addressing mode on page F5-2605.

        <Rm>              Contains an address offset applied after the access.

        For more information about <Rn>, !, and <Rm>, see Advanced SIMD addressing mode on page F5-2605.

                                                    Table F8-8 Encoding of index, alignment, and register spacing

                                                  <size> == 8              <size> == 16              <size> == 32

                             Index                index_align[3:1] = x     index_align[3:2] = x      index_align[3] = x

                             Single-spacing       -                        index_align[1] = 0        index_align[2] = 0

                             Double-spacing       -                        index_align[1] = 1        index_align[2] = 1

                             <align> omitted      index_align[0] = 0       index_align[0] = 0        index_align[1:0] = ''00''

                             <align> == 32        index_align[0] = 1       -                         -

                             <align> == 64        -                        index_align[0] = 1        index_align[1:0] = ''01''

                             <align> == 128       -                        -                         index_align[1:0] = ''10''



        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               address = R[n];     if (address MOD alignment) != 0 then GenerateAlignmentException();
               if wback then
                   if register_index then
                        R[n] = R[n] + R[m];
                   else
                        R[n] = R[n] + 4*ebytes;
               MemU[address,            ebytes] = Elem[D[d], index];
               MemU[address+ebytes,     ebytes] = Elem[D[d2],index];
               MemU[address+2*ebytes,ebytes] = Elem[D[d3],index];
               MemU[address+3*ebytes,ebytes] = Elem[D[d4],index];');
INSERT INTO "instructions" VALUES('ARM','VSTM','        Store multiple SIMD&FP registers stores multiple registers from the Advanced SIMD and floating-point register       (F8.1.221)
        file to consecutive memory locations using an address from a general-purpose register.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        This instruction is used by the aliases FSTMDBX, FSTMIAX, and VPUSH. See the Alias conditions on
        page F8-3758 table for details of when each alias is preferred.


        A1


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7                       0
              !=1111     1 1 0 P U D W 0             Rn           Vd       1 0 1 1             imm8
               cond


        Decrement Before variant

        Applies when P = 1 && U = 0 && W = 1.

        VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist>


        Increment After variant

        Applies when P = 0 && U = 1.

        VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>
        VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>


        Decode for all variants of this encoding

         if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
         if P == ''1'' && W == ''0'' then SEE VSTR;
         if P == U && W == ''1'' then UNDEFINED;
         // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
         single_regs = FALSE;     add = (U == ''1'');   wback = (W == ''1'');
         d = UInt(D:Vd);     n = UInt(Rn);   imm32 = ZeroExtend(imm8:''00'', 32);
         regs = UInt(imm8) DIV 2;     // If UInt(imm8) is odd, see "FSTMX".
         if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
         if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
         if imm8<0> == ''1'' && (d+regs) > 16 then UNPREDICTABLE;


        A2


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7                       0
              !=1111     1 1 0 P U D W 0             Rn           Vd       1 0 1 0             imm8
               cond


        Decrement Before variant

        Applies when P = 1 && U = 0 && W = 1.

        VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist>


        Increment After variant

        Applies when P = 0 && U = 1.

        VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
        VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
Decode for all variants of this encoding

 if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
 if P == ''1'' && W == ''0'' then SEE VSTR;
 if P == U && W == ''1'' then UNDEFINED;
 // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
 single_regs = TRUE;  add = (U == ''1'');  wback = (W == ''1'');     d = UInt(Vd:D);    n = UInt(Rn);
 imm32 = ZeroExtend(imm8:''00'', 32);  regs = UInt(imm8);
 if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
 if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7                        0
  1 1 1 0 1 1 0 P U D W 0                Rn          Vd         1 0 1 1               imm8




Decrement Before variant

Applies when P = 1 && U = 0 && W = 1.

VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist>


Increment After variant

Applies when P = 0 && U = 1.

VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>
VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist>


Decode for all variants of this encoding

 if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
 if P == ''1'' && W == ''0'' then SEE VSTR;
 if P == U && W == ''1'' then UNDEFINED;
 // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
 single_regs = FALSE;  add = (U == ''1'');  wback = (W == ''1'');
 d = UInt(D:Vd);  n = UInt(Rn);  imm32 = ZeroExtend(imm8:''00'', 32);
 regs = UInt(imm8) DIV 2;  // If UInt(imm8) is odd, see "FSTMX".
 if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
 if regs == 0 || regs > 16 || (d+regs) > 32 then UNPREDICTABLE;
 if imm8<0> == ''1'' && (d+regs) > 16 then UNPREDICTABLE;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3             0 15         12 11 10 9 8 7                        0
  1 1 1 0 1 1 0 P U D W 0                Rn          Vd         1 0 1 0               imm8




Decrement Before variant

Applies when P = 1 && U = 0 && W = 1.

VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist>


Increment After variant

Applies when P = 0 && U = 1.

VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
VSTMIA{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist>
        Decode for all variants of this encoding

         if P == ''0'' && U == ''0'' && W == ''0'' then SEE "Related encodings";
         if P == ''1'' && W == ''0'' then SEE VSTR;
         if P == U && W == ''1'' then UNDEFINED;
         // Remaining combinations are PUW = 010 (IA without !), 011 (IA with !), 101 (DB with !)
         single_regs = TRUE;       add = (U == ''1'');     wback = (W == ''1'');      d = UInt(Vd:D);     n = UInt(Rn);
         imm32 = ZeroExtend(imm8:''00'', 32);          regs = UInt(imm8);
         if n == 15 && (wback || CurrentInstrSet() != InstrSet_A32) then UNPREDICTABLE;
         if regs == 0 || (d+regs) > 32 then UNPREDICTABLE;


        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VSTM on page J1-5393.

        Related encodings: 64-bit transfers accessing the SIMD and floating-point register file on page F5-2607.


        Alias conditions


                               Alias                     is preferred when

                               FSTMDBX                   P == ''1'' && U == ''0'' && imm8<0> == ''1''

                               FSTMIAX                   P == ''0'' && U == ''1'' && imm8<0> == ''1''

                               VPUSH                     P == ''1'' && U == ''0'' && W == ''1'' && Rn == ''1101''



        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <size>            An optional data size specifier. If present, it must be equal to the size in bits, 32 or 64, of the registers
                          being transferred.

        <Rn>              For encoding A1 and A2: is the general-purpose base register, encoded in the "Rn" field. If
                          writeback is not specified, the PC can be used. However, ARM deprecates use of the PC.

                          For encoding T1 and T2: is the general-purpose base register, encoded in the "Rn" field.

        !                 Specifies base register writeback. Encoded in the "W" field as 1 if present, otherwise 0.

        <sreglist>        Is the list of consecutively numbered 32-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "Vd:D", and "imm8" is set to the number of registers in the list. The list must
                          contain at least one register.

        <dreglist>        Is the list of consecutively numbered 64-bit SIMD&FP registers to be transferred. The first register
                          in the list is encoded in "D:Vd", and "imm8" is set to twice the number of registers in the list. The
                          list must contain at least one register, and must not contain more than 16 registers.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();        CheckVFPEnabled(TRUE);
               address = if add then R[n] else R[n]-imm32;
               if wback then R[n] = if add then R[n]+imm32 else R[n]-imm32;
               for r = 0 to regs-1
                   if single_regs then
                        MemA[address,4] = S[d+r];       address = address+4;
                   else
                        // Store as two word-aligned words in the correct order for current endianness.
   MemA[address,4] = if BigEndian() then D[d+r]<63:32> else D[d+r]<31:0>;
   MemA[address+4,4] = if BigEndian() then D[d+r]<31:0> else D[d+r]<63:32>;
   address = address+8;');
INSERT INTO "instructions" VALUES('ARM','VSTMDB','-R:VSTM');
INSERT INTO "instructions" VALUES('ARM','VSTMIA','-R:VSTM');
INSERT INTO "instructions" VALUES('ARM','VSTR','        Store SIMD&FP register stores a single register from the Advanced SIMD and floating-point register file to       (F8.1.222)
        memory, using an address from a general-purpose register, with an optional offset.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.


        A1


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7                       0
              !=1111     1 1 0 1 U D 0 0             Rn           Vd       1 0 1 1             imm8
               cond


        A1 variant

        VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}]


        Decode for this encoding

         single_reg = FALSE;     add = (U == ''1'');   imm32 = ZeroExtend(imm8:''00'', 32);
         d = UInt(D:Vd);     n = UInt(Rn);
         if n == 15 && CurrentInstrSet() != InstrSet_A32 then UNPREDICTABLE;


        A2


           31        28 27 26 25 24 23 22 21 20 19        16 15        12 11 10 9 8 7                       0
              !=1111     1 1 0 1 U D 0 0             Rn           Vd       1 0 1 0             imm8
               cond


        A2 variant

        VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}]


        Decode for this encoding

         single_reg = TRUE;     add = (U == ''1'');   imm32 = ZeroExtend(imm8:''00'', 32);
         d = UInt(Vd:D);     n = UInt(Rn);
         if n == 15 && CurrentInstrSet() != InstrSet_A32 then UNPREDICTABLE;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                0 15         12 11 10 9 8 7                       0
            1 1 1 0 1 1 0 1 U D 0 0                  Rn           Vd       1 0 1 1             imm8




        T1 variant

        VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}]


        Decode for this encoding

         single_reg = FALSE;     add = (U == ''1'');   imm32 = ZeroExtend(imm8:''00'', 32);
         d = UInt(D:Vd);     n = UInt(Rn);
         if n == 15 && CurrentInstrSet() != InstrSet_A32 then UNPREDICTABLE;
T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                  0 15        12 11 10 9 8 7                           0
  1 1 1 0 1 1 0 1 U D 0 0                    Rn           Vd        1 0 1 0                imm8




T2 variant

VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}]


Decode for this encoding

 single_reg = TRUE;   add = (U == ''1'');    imm32 = ZeroExtend(imm8:''00'', 32);
 d = UInt(Vd:D);  n = UInt(Rn);
 if n == 15 && CurrentInstrSet() != InstrSet_A32 then UNPREDICTABLE;


Notes for all encodings

For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
Architectural Constraints on UNPREDICTABLE behaviors.


Assembler symbols

<c>            See Standard assembler syntax fields on page F2-2506.

<q>            See Standard assembler syntax fields on page F2-2506.

.64            Optional data size specifiers.

<Dd>           The source register for a doubleword store.

.32            Optional data size specifiers.

<Sd>           The source register for a singleword store.

<Rn>           For encoding A1 and A2: is the general-purpose base register, encoded in the "Rn" field. The PC
               can be used, but this is deprecated.

               For encoding T1 and T2: is the general-purpose base register, encoded in the "Rn" field.

+/-            Specifies the offset is added to or subtracted from the base register, defaulting to + if omitted and
               encoded in the "U" field. It can have the following values:

               -           when U = 0

               +           when U = 1

<imm>          The immediate offset used for forming the address. Values are multiples of 4 in the range 0-1020.
               <imm> can be omitted, meaning an offset of +0.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckVFPEnabled(TRUE);
     address = if add then (R[n] + imm32) else (R[n] - imm32);
     if single_reg then
         MemA[address,4] = S[d];
     else
         // Store as two word-aligned words in the correct order for current endianness.
         MemA[address,4] = if BigEndian() then D[d]<63:32> else D[d]<31:0>;
         MemA[address+4,4] = if BigEndian() then D[d]<31:0> else D[d]<63:32>;');
INSERT INTO "instructions" VALUES('ARM','VSUB','        Vector Subtract (floating-point) subtracts the elements of one vector from the corresponding elements of another       (F8.1.223)
        vector, and places the results in the destination vector.

        Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the security state and mode in
        which the instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp
        mode. For more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19          16 15       12 11 10 9 8 7 6 5 4 3               0
            1 1 1 1 0 0 1 0 0 D 1 sz                   Vn         Vd       1 1 0 1 N Q M 0            Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VSUB{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VSUB{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if sz == ''1'' then UNDEFINED;
         advsimd = TRUE;     esize = 32;   elements = 2;
         d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


        A2


           31        28 27 26 25 24 23 22 21 20 19         16 15       12 11 10 9 8 7 6 5 4 3               0
              !=1111     1 1 1 0 0 D 1 1               Vn         Vd       1 0 1 sz N 1 M 0           Vm
               cond


        Single-precision scalar variant

        Applies when sz = 0.

        VSUB{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


        Double-precision scalar variant

        Applies when sz = 1.

        VSUB{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


        Decode for all variants of this encoding

         if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
         advsimd = FALSE;     dp_operation = (sz == ''1'');
         d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
         n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
         m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);
T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15        12 11 10 9 8 7 6 5 4 3                 0
  1 1 1 0 1 1 1 1 0 D 1 sz                 Vn           Vd        1 1 0 1 N Q M 0              Vm




64-bit SIMD vector variant

Applies when Q = 0.

VSUB{<c>}{<q>}.F32 {<Dd>, }<Dn>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VSUB{<c>}{<q>}.F32 {<Qd>, }<Qn>, <Qm>


Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if sz == ''1'' then UNDEFINED;
 advsimd = TRUE;  esize = 32;   elements = 2;
 d = UInt(D:Vd);  n = UInt(N:Vn);   m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T2


  15 14 13 12 11 10 9 8 7 6 5 4 3                0 15        12 11 10 9 8 7 6 5 4 3                 0
  1 1 1 0 1 1 1 0 0 D 1 1                  Vn           Vd        1 0 1 sz N 1 M 0             Vm




Single-precision scalar variant

Applies when sz = 0.

VSUB{<c>}{<q>}.F32 {<Sd>,} <Sn>, <Sm>


Double-precision scalar variant

Applies when sz = 1.

VSUB{<c>}{<q>}.F64 {<Dd>,} <Dn>, <Dm>


Decode for all variants of this encoding

 if FPSCR.Len != ''000'' || FPSCR.Stride != ''00'' then UNDEFINED;
 advsimd = FALSE;  dp_operation = (sz == ''1'');
 d = if dp_operation then UInt(D:Vd) else UInt(Vd:D);
 n = if dp_operation then UInt(N:Vn) else UInt(Vn:N);
 m = if dp_operation then UInt(M:Vm) else UInt(Vm:M);


Assembler symbols

<c>           For encoding A1 and T1: see Standard assembler syntax fields on page F2-2506. An A32 Advanced
              SIMD VSUB instruction must be unconditional. ARM strongly recommends that a T32 Advanced
              SIMD VSUB instruction is unconditional, see Conditional execution on page F2-2507.

              For encoding A2: see Standard assembler syntax fields on page F2-2506. An A32 Advanced SIMD
              VADD instruction must be unconditional. ARM strongly recommends that a T32 Advanced SIMD
              VADD instruction is unconditional, see Conditional execution on page F2-2507

              For encoding T2: see Standard assembler syntax fields on page F2-2506.
        <q>               See Standard assembler syntax fields on page F2-2506.

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

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

        <Sm>              Is the 32-bit name of the second SIMD&FP source register, encoded in the "Vm:M" field.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.

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

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();      CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
               if advsimd then    // Advanced SIMD instruction
                   for r = 0 to regs-1
                        for e = 0 to elements-1
                             Elem[D[d+r],e,esize] = FPSub(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize],
        StandardFPSCRValue());
               else               // VFP instruction
                   if dp_operation then
                        D[d] = FPSub(D[n], D[m], FPSCR);
                   else
                        S[d] = FPSub(S[n], S[m], FPSCR);');
INSERT INTO "instructions" VALUES('ARM','VSUBHN','Vector Subtract and Narrow, returning High Half subtracts the elements of one quadword vector from the       (F8.1.225)
corresponding elements of another quadword vector, takes the most significant half of each result, and places the
final results in a doubleword vector. The results are truncated. For rounded results, see VRSUBHN.

There is no distinction between signed and unsigned integers.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15        12 11 10 9 8 7 6 5 4 3                0
   1 1 1 1 0 0 1 0 1 D !=11                   Vn           Vd       0 1 1 0 N 0 M 0              Vm
                                   size


A1 variant

VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15        12 11 10 9 8 7 6 5 4 3                0
   1 1 1 0 1 1 1 1 1 D !=11                   Vn           Vd       0 1 1 0 N 0 M 0              Vm
                                   size


T1 variant

VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vn<0> == ''1'' || Vm<0> == ''1'' then UNDEFINED;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);     n = UInt(N:Vn);   m = UInt(M:Vm);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>              See Standard assembler syntax fields on page F2-2506. An A32 VSUBHN instruction must be
                 unconditional. ARM strongly recommends that a T32 VSUBHN instruction is unconditional, see
                 Conditional execution on page F2-2507.
        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the operands, encoded in the "size" field. It can have the
                          following values:

                          I16          when size = 00

                          I32          when size = 01

                          I64          when size = 10

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

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Qm>              Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
                          <Qm>*2.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for e = 0 to elements-1
                   result = Elem[Qin[n>>1],e,2*esize] - Elem[Qin[m>>1],e,2*esize];
                   Elem[D[d],e,esize] = result<2*esize-1:esize>;');
INSERT INTO "instructions" VALUES('ARM','VSUBL','Vector Subtract Long subtracts the elements of one doubleword vector from the corresponding elements of another       (F8.1.226)
doubleword vector, and places the results in a quadword vector. Before subtracting, it sign-extends or zero-extends
the elements of both operands.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 U 1 D !=11                   Vn           Vd       0 0 1 0 N 0 M 0              Vm
                                   size                                        op


A1 variant

VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vsubw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 U 1 1 1 1 1 D !=11                   Vn           Vd       0 0 1 0 N 0 M 0              Vm
                                   size                                        op


T1 variant

VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vsubw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VSUBL or VSUBW instruction must be
                unconditional. ARM strongly recommends that a T32 VSUBL or VSUBW instruction is unconditional,
                see Conditional execution on page F2-2507.
        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the second operand vector, encoded in the "U:size" field. It can
                          have the following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Dn>              Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for e = 0 to elements-1
                   if is_vsubw then
                        op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned);
                   else
                        op1 = Int(Elem[Din[n],e,esize], unsigned);
                   result = op1 - Int(Elem[Din[m],e,esize], unsigned);
                   Elem[Q[d>>1],e,2*esize] = result<2*esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VSUBW','Vector Subtract Wide subtracts the elements of a doubleword vector from the corresponding elements of a       (F8.1.227)
quadword vector, and places the results in another quadword vector. Before subtracting, it sign-extends or
zero-extends the elements of the doubleword operand.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 U 1 D !=11                   Vn           Vd       0 0 1 1 N 0 M 0              Vm
                                   size                                        op


A1 variant

VSUBW{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vsubw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 U 1 1 1 1 1 D !=11                   Vn           Vd       0 0 1 1 N 0 M 0              Vm
                                   size                                        op


T1 variant

VSUBW{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Dm>


Decode for this encoding

 if size == ''11'' then SEE "Related encodings";
 if Vd<0> == ''1'' || (op == ''1'' && Vn<0> == ''1'') then UNDEFINED;
 unsigned = (U == ''1'');
 esize = 8 << UInt(size);     elements = 64 DIV esize;     is_vsubw = (op == ''1'');
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);


Notes for all encodings

Related encodings: Advanced SIMD data-processing instructions on page F5-2587.


Assembler symbols

<c>             See Standard assembler syntax fields on page F2-2506. An A32 VSUBL or VSUBW instruction must be
                unconditional. ARM strongly recommends that a T32 VSUBL or VSUBW instruction is unconditional,
                see Conditional execution on page F2-2507.
        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the second operand vector, encoded in the "U:size" field. It can
                          have the following values:

                          S8           when U = 0, size = 00

                          S16          when U = 0, size = 01

                          S32          when U = 0, size = 10

                          U8           when U = 1, size = 00

                          U16          when U = 1, size = 01

                          U32          when U = 1, size = 10

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qn>              Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

        <Dm>              Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               for e = 0 to elements-1
                   if is_vsubw then
                        op1 = Int(Elem[Qin[n>>1],e,2*esize], unsigned);
                   else
                        op1 = Int(Elem[Din[n],e,esize], unsigned);
                   result = op1 - Int(Elem[Din[m],e,esize], unsigned);
                   Elem[Q[d>>1],e,2*esize] = result<2*esize-1:0>;');
INSERT INTO "instructions" VALUES('ARM','VSWP','Vector Swap exchanges the contents of two vectors. The vectors can be either doubleword or quadword. There is       (F8.1.228)
no distinction between data types.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  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 3                 0
   1 1 1 1 0 0 1 1 1 D 1 1 0 0 1 0                         Vd       0 0 0 0 0 Q M 0              Vm
                                          size


64-bit SIMD vector variant

Applies when Q = 0.

VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm>


Decode for all variants of this encoding

 if size != ''00'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 1 1 1 1 1 D 1 1 0 0 1 0                         Vd       0 0 0 0 0 Q M 0              Vm
                                          size


64-bit SIMD vector variant

Applies when Q = 0.

VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm>


Decode for all variants of this encoding

 if size != ''00'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 d = UInt(D:Vd);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;
        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VSWP instruction must be
                          unconditional. ARM strongly recommends that a T32 VSWP instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              An optional data type. It is ignored by assemblers, and does not affect the encoding.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();     CheckAdvSIMDEnabled();
               for r = 0 to regs-1
                   if d == m then
                        D[d+r] = bits(64) UNKNOWN;
                   else
                        D[d+r] = Din[m+r];
                        D[m+r] = Din[d+r];');
INSERT INTO "instructions" VALUES('ARM','VTBL','Vector Table Lookup uses byte indexes in a control vector to look up byte values in a table and generate a new       (F8.1.229)
vector. Indexes out of range return 0.

Vector Table Extension works in the same way, except that indexes out of range leave the destination element
unchanged.

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.


A1


  31 30 29 28 27 26 25 24 23 22 21 20 19           16 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 0 0 1 1 1 D 1 1                    Vn           Vd       1 0      len N op M 0        Vm




VTBL variant

Applies when op = 0.

VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm>


VTBX variant

Applies when op = 1.

VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm>


Decode for all variants of this encoding

 is_vtbl = (op == ''0'');      length = UInt(len)+1;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);
 if n+length > 32 then UNPREDICTABLE;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15       12 11 10 9 8 7 6 5 4 3                 0
   1 1 1 1 1 1 1 1 1 D 1 1                    Vn           Vd       1 0      len N op M 0        Vm




VTBL variant

Applies when op = 0.

VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm>


VTBX variant

Applies when op = 1.

VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm>


Decode for all variants of this encoding

 is_vtbl = (op == ''0'');      length = UInt(len)+1;
 d = UInt(D:Vd);    n = UInt(N:Vn);    m = UInt(M:Vm);
 if n+length > 32 then UNPREDICTABLE;
        Notes for all encodings

        For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Appendix J1
        Architectural Constraints on UNPREDICTABLE behaviors, and particularly VTBL, VTBX on page J1-5395.


        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VTBL or VTBX instruction must be
                          unconditional. ARM strongly recommends that a T32 VTBL or VTBX instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

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

        <list>            The vectors containing the table. It must be one of:

                          {<Dn>}      Encoded as len = 0b00.

                          {<Dn>, <Dn+1>}
                                      Encoded as len = 0b01.

                          {<Dn>, <Dn+1>, <Dn+2>}
                                      Encoded as len = 0b10.

                          {<Dn>, <Dn+1>, <Dn+2>, <Dn+3>}
                                      Encoded as len = 0b11.

        <Dm>              Is the 64-bit name of the SIMD&FP source register holding the indices, encoded in the "M:Vm"
                          field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();     CheckAdvSIMDEnabled();

               // Create 256-bit = 32-byte table variable, with zeros in entries that will not be used.
               table3 = if length == 4 then D[n+3] else Zeros(64);
               table2 = if length >= 3 then D[n+2] else Zeros(64);
               table1 = if length >= 2 then D[n+1] else Zeros(64);
               table = table3 : table2 : table1 : D[n];

               for i = 0 to 7
                   index = UInt(Elem[D[m],i,8]);
                   if index < 8*length then
                        Elem[D[d],i,8] = Elem[table,index,8];
                   else
                        if is_vtbl then
                             Elem[D[d],i,8] = Zeros(8);
                        // else Elem[D[d],i,8] unchanged');
INSERT INTO "instructions" VALUES('ARM','VTBX','-R:VTBL');
INSERT INTO "instructions" VALUES('ARM','VTRN','Vector Transpose treats the elements of its operand vectors as elements of 2 x 2 matrices, and transposes the       (F8.1.230)
matrices.

The elements of the vectors can be 8-bit, 16-bit, or 32-bit. There is no distinction between data types.

The following figure shows an example of the operation of VTRN doubleword operations.

VTRN.32                                  VTRN.16                                  VTRN.8
            1               0                                             0123                                    01234567
Dd                                       Dd                                       Dd




Dm                                       Dm                                       Dm

Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
as a floating-point instruction encoding, see Conditional execution on page F2-2507.

This instruction is used by the aliases VUZP (alias) and VZIP (alias). See the Alias conditions on page F8-3778 table
for details of when each alias is preferred.


A1


  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 3                   0
   1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                        Vd       0 0 0 0 1 Q M 0                Vm




64-bit SIMD vector variant

Applies when Q = 0.

VTRN{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VTRN{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 esize = 8 << UInt(size);     elements = 64 DIV esize;
 d = UInt(D:Vd);     m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


T1


  15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                     12 11 10 9 8 7 6 5 4 3                   0
   1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                        Vd       0 0 0 0 1 Q M 0                Vm
        64-bit SIMD vector variant

        Applies when Q = 0.

        VTRN{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VTRN{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         esize = 8 << UInt(size);       elements = 64 DIV esize;
         d = UInt(D:Vd);      m = UInt(M:Vm);     regs = if Q == ''0'' then 1 else 2;


        Alias conditions


                                Alias                   is preferred when

                                VUZP (alias)            Never

                                VZIP (alias)            Never



        Assembler symbols

        <c>               See Standard assembler syntax fields on page F2-2506. An A32 VTRN instruction must be
                          unconditional. ARM strongly recommends that a T32 VTRN instruction is unconditional, see
                          Conditional execution on page F2-2507.

        <q>               See Standard assembler syntax fields on page F2-2506.

        <dt>              Is the data type for the elements of the vectors, 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.

        <Qd>              Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

        <Qm>              Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

        <Dm>              Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


        Operation for all encodings

         if ConditionPassed() then
               EncodingSpecificOperations();       CheckAdvSIMDEnabled();
               h = elements DIV 2;

               for r = 0 to regs-1
                   if d == m then
                        D[d+r] = bits(64) UNKNOWN;
                   else
   for e = 0 to h-1
       Elem[D[d+r],2*e+1,esize] = Elem[Din[m+r],2*e,esize];
       Elem[D[m+r],2*e,esize] = Elem[Din[d+r],2*e+1,esize];');
INSERT INTO "instructions" VALUES('ARM','VTST','        Vector Test Bits takes each element in a vector, and bitwise ANDs it with the corresponding element of a second       (F8.1.231)
        vector. If the result is not zero, the corresponding element in the destination vector is set to all ones. Otherwise, it is
        set to all zeros.

        The operand vector elements can be any one of:

        .       8-bit, 16-bit, or 32-bit fields.

        The result vector elements are fields the same size as the operand vector elements.

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           31 30 29 28 27 26 25 24 23 22 21 20 19            16 15        12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 1 0 0 1 0 0 D size                    Vn           Vd      1 0 0 0 N Q M 1                  Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VTST{<c>}{<q>}.<dt> {<Dd>,} <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VTST{<c>}{<q>}.<dt> {<Qd>,} <Qn>, <Qm>


        Decode for all variants of this encoding

         if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         if size == ''11'' then UNDEFINED;
         esize = 8 << UInt(size);        elements = 64 DIV esize;
         d = UInt(D:Vd);      n = UInt(N:Vn);     m = UInt(M:Vm);   regs = if Q == ''0'' then 1 else 2;


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3                   0 15         12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 0 1 1 1 1 0 D size                    Vn           Vd      1 0 0 0 N Q M 1                  Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VTST{<c>}{<q>}.<size> {<Dd>,} <Dn>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VTST{<c>}{<q>}.<size> {<Qd>,} <Qn>, <Qm>
Decode for all variants of this encoding

 if Q == ''1'' && (Vd<0> == ''1'' || Vn<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 if size == ''11'' then UNDEFINED;
 esize = 8 << UInt(size);   elements = 64 DIV esize;
 d = UInt(D:Vd);  n = UInt(N:Vn);    m = UInt(M:Vm);    regs = if Q == ''0'' then 1 else 2;


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VTST instruction must be
              unconditional. ARM strongly recommends that a T32 VTST instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<size>        The data size for the elements of the operands. It must be one of:

              8            Encoded as size = 0b00.

              16           Encoded as size = 0b01.

              32           Encoded as size = 0b10.

<dt>          Is the data type for the elements of the operands, 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.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field, as <Qd>*2.

<Qn>          Is the 128-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field as <Qn>*2.

<Qm>          Is the 128-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field as
              <Qm>*2.

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

<Dn>          Is the 64-bit name of the first SIMD&FP source register, encoded in the "N:Vn" field.

<Dm>          Is the 64-bit name of the second SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();     CheckAdvSIMDEnabled();
     for r = 0 to regs-1
         for e = 0 to elements-1
             if !IsZero(Elem[D[n+r],e,esize] AND Elem[D[m+r],e,esize]) then
                 Elem[D[d+r],e,esize] = Ones(esize);
             else
                 Elem[D[d+r],e,esize] = Zeros(esize);');
INSERT INTO "instructions" VALUES('ARM','VUZP','        Vector Unzip de-interleaves the elements of two vectors.       (F8.1.232)

        The elements of the vectors can be 8-bit, 16-bit, or 32-bit. There is no distinction between data types.

        The following figure shows an example of the operation of VUZP doubleword operation for data type 8.
                 VUZP.8, doubleword
                                Register state before operation                      Register state after operation
                 Dd      A7   A6     A5    A4    A3     A2    A1     A0    B6     B4     B2    B0     A6    A4     A2  A0
                 Dm      B7   B6     B5    B4    B3     B2    B1     B0    B7     B5     B3    B1     A7    A5     A3  A1

        The following figure shows an example of the operation of VUZP quadword operation for data type 32.
                 VUZP.32, quadword
                                Register state before operation                      Register state after operation
                 Qd        A3           A2          A1           A0            B2           B0            A2         A0
                 Qm        B3           B2          B1           B0            B3           B1            A3         A1

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                    0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                       Vd       0 0 0 1 0 Q M 0               Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VUZP{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VUZP{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' || (Q == ''0'' && size == ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         quadword_operation = (Q == ''1'');      esize = 8 << UInt(size);
         d = UInt(D:Vd);     m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                       Vd       0 0 0 1 0 Q M 0               Vm




        64-bit SIMD vector variant

        Applies when Q = 0.
VUZP{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VUZP{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' || (Q == ''0'' && size == ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 quadword_operation = (Q == ''1'');    esize = 8 << UInt(size);
 d = UInt(D:Vd);  m = UInt(M:Vm);


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VUZP instruction must be
              unconditional. ARM strongly recommends that a T32 VUZP instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          For the 64-bit SIMD vector variant: is the data type for the elements of the vectors, encoded in the
              "size" field. It can have the following values:
              8            when size = 00
              16           when size = 01

              It is RESERVED when size = 1x.

              For the 128-bit SIMD vector variant: is the data type for the elements of the vectors, 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.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();    CheckAdvSIMDEnabled();
     if quadword_operation then
         if d == m then
             Q[d>>1] = bits(128) UNKNOWN;      Q[m>>1] = bits(128) UNKNOWN;
         else
             zipped_q = Q[m>>1]:Q[d>>1];
             for e = 0 to (128 DIV esize) - 1
                 Elem[Q[d>>1],e,esize] = Elem[zipped_q,2*e,esize];
                 Elem[Q[m>>1],e,esize] = Elem[zipped_q,2*e+1,esize];
     else
         if d == m then
             D[d] = bits(64) UNKNOWN;     D[m] = bits(64) UNKNOWN;
         else
             zipped_d = D[m]:D[d];
                        for e = 0 to (64 DIV esize) - 1
                            Elem[D[d],e,esize] = Elem[zipped_d,2*e,esize];
                            Elem[D[m],e,esize] = Elem[zipped_d,2*e+1,esize];');
INSERT INTO "instructions" VALUES('ARM','VZIP','        Vector Zip interleaves the elements of two vectors.       (F8.1.234)

        The elements of the vectors can be 8-bit, 16-bit, or 32-bit. There is no distinction between data types.

        The following figure shows an example of the operation of VZIP doubleword operation for data type 8.
                 VZIP.8, doubleword
                                Register state before operation                      Register state after operation
                 Dd      A7   A6     A5    A4    A3     A2    A1     A0    B3     A3     B2    A2     B1    A1     B0  A0
                 Dm      B7   B6     B5    B4    B3     B2    B1     B0    B7     A7     B6    A6     B5    A5     B4  A4

        The following figure shows an example of the operation of VZIP quadword operation for data type 32.
                 VZIP.32, quadword
                                Register state before operation                      Register state after operation
                 Qd        A3           A2          A1           A0            B1           A1            B0         A0
                 Qm        B3           B2          B1           B0            B3           A3            B2         A2

        Depending on settings in the CPACR, NSACR, and HCPTR registers, and the security state and mode in which the
        instruction is executed, an attempt to execute the instruction might be UNDEFINED, or trapped to Hyp mode. For
        more information see Enabling Advanced SIMD and floating-point support on page G1-3896.

        ARM deprecates the conditional execution of any Advanced SIMD instruction encoding that is not also available
        as a floating-point instruction encoding, see Conditional execution on page F2-2507.


        A1


           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 3                    0
            1 1 1 1 0 0 1 1 1 D 1 1 size 1 0                       Vd       0 0 0 1 1 Q M 0               Vm




        64-bit SIMD vector variant

        Applies when Q = 0.

        VZIP{<c>}{<q>}.<dt> <Dd>, <Dm>


        128-bit SIMD vector variant

        Applies when Q = 1.

        VZIP{<c>}{<q>}.<dt> <Qd>, <Qm>


        Decode for all variants of this encoding

         if size == ''11'' || (Q == ''0'' && size == ''10'') then UNDEFINED;
         if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
         quadword_operation = (Q == ''1'');      esize = 8 << UInt(size);
         d = UInt(D:Vd);     m = UInt(M:Vm);


        T1


           15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 15                    12 11 10 9 8 7 6 5 4 3                    0
            1 1 1 1 1 1 1 1 1 D 1 1 size 1 0                       Vd       0 0 0 1 1 Q M 0               Vm




        64-bit SIMD vector variant

        Applies when Q = 0.
VZIP{<c>}{<q>}.<dt> <Dd>, <Dm>


128-bit SIMD vector variant

Applies when Q = 1.

VZIP{<c>}{<q>}.<dt> <Qd>, <Qm>


Decode for all variants of this encoding

 if size == ''11'' || (Q == ''0'' && size == ''10'') then UNDEFINED;
 if Q == ''1'' && (Vd<0> == ''1'' || Vm<0> == ''1'') then UNDEFINED;
 quadword_operation = (Q == ''1'');    esize = 8 << UInt(size);
 d = UInt(D:Vd);  m = UInt(M:Vm);


Assembler symbols

<c>           See Standard assembler syntax fields on page F2-2506. An A32 VZIP instruction must be
              unconditional. ARM strongly recommends that a T32 VZIP instruction is unconditional, see
              Conditional execution on page F2-2507.

<q>           See Standard assembler syntax fields on page F2-2506.

<dt>          For the 64-bit SIMD vector variant: is the data type for the elements of the vectors, encoded in the
              "size" field. It can have the following values:
              8            when size = 00
              16           when size = 01

              It is RESERVED when size = 1x.

              For the 128-bit SIMD vector variant: is the data type for the elements of the vectors, 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.

<Qd>          Is the 128-bit name of the SIMD&FP destination register, encoded in the "D:Vd" field as <Qd>*2.

<Qm>          Is the 128-bit name of the SIMD&FP source register, encoded in the "M:Vm" field as <Qm>*2.

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

<Dm>          Is the 64-bit name of the SIMD&FP source register, encoded in the "M:Vm" field.


Operation for all encodings

 if ConditionPassed() then
     EncodingSpecificOperations();    CheckAdvSIMDEnabled();
     if quadword_operation then
         if d == m then
             Q[d>>1] = bits(128) UNKNOWN;      Q[m>>1] = bits(128) UNKNOWN;
         else
             bits(256) zipped_q;
             for e = 0 to (128 DIV esize) - 1
                 Elem[zipped_q,2*e,esize] = Elem[Q[d>>1],e,esize];
                 Elem[zipped_q,2*e+1,esize] = Elem[Q[m>>1],e,esize];
             Q[d>>1] = zipped_q<127:0>;      Q[m>>1] = zipped_q<255:128>;
     else
         if d == m then
             D[d] = bits(64) UNKNOWN;     D[m] = bits(64) UNKNOWN;
         else
             bits(128) zipped_d;
             for e = 0 to (64 DIV esize) - 1
                            Elem[zipped_d,2*e,esize] = Elem[D[d],e,esize];
                            Elem[zipped_d,2*e+1,esize] = Elem[D[m],e,esize];
                        D[d] = zipped_d<63:0>;  D[m] = zipped_d<127:64>;');
COMMIT;
