# instructions

platform: ARM
mnem: STLRH
description:
      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);


platform: ARM
mnem: STLXP
description:
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);


platform: ARM
mnem: STLXR
description:
       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);


platform: ARM
mnem: STLXRB
description:
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);


platform: ARM
mnem: STLXRH
description:
       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);


platform: ARM
mnem: STNP
description:
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;


platform: ARM
mnem: STP
description:
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;


platform: ARM
mnem: STR
description:
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;


platform: ARM
mnem: STRB
description:
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;


platform: ARM
mnem: STRH
description:
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;


platform: ARM
mnem: STTR
description:
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;


platform: ARM
mnem: STTRB
description:
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;


platform: ARM
mnem: STTRH
description:
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;


platform: ARM
mnem: STUR
description:
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;


platform: ARM
mnem: STURB
description:
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;


platform: ARM
mnem: STURH
description:
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;


platform: ARM
mnem: STXP
description:
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);


platform: ARM
mnem: STXR
description:
       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);


platform: ARM
mnem: STXRB
description:
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);


platform: ARM
mnem: STXRH
description:
       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);


platform: ARM
mnem: SUB
description:
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;


platform: ARM
mnem: SUBS
description:
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;


platform: ARM
mnem: SVC
description:
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);


platform: ARM
mnem: SXTB
description:
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.


platform: ARM
mnem: SXTH
description:
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.


platform: ARM
mnem: SXTW
description:
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.


platform: ARM
mnem: SYS
description:
       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]);


platform: ARM
mnem: SYSL
description:
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]);


platform: ARM
mnem: TBNZ
description:
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);


platform: ARM
mnem: TBZ
description:
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);


platform: ARM
mnem: TLBI
description:
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.


platform: ARM
mnem: TST
description:
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.


platform: ARM
mnem: UBFIZ
description:
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.


platform: ARM
mnem: UBFM
description:
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);


platform: ARM
mnem: UBFX
description:
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.


platform: ARM
mnem: UDIV
description:
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>;


platform: ARM
mnem: UMADDL
description:
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>;


platform: ARM
mnem: UMNEGL
description:
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.


platform: ARM
mnem: UMSUBL
description:
      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>;


platform: ARM
mnem: UMULH
description:
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>;


platform: ARM
mnem: UMULL
description:
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.


platform: ARM
mnem: UXTB
description:
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.


platform: ARM
mnem: UXTH
description:
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.


platform: ARM
mnem: WFE
description:
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.


platform: ARM
mnem: WFI
description:
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.


platform: ARM
mnem: YIELD
description:
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.


platform: ARM
mnem: ABS
description:
       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;


platform: ARM
mnem: ADDHN
description:
       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;


platform: ARM
mnem: ADDP
description:
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);


platform: ARM
mnem: ADDV
description:
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);


platform: ARM
mnem: AESD
description:
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;


platform: ARM
mnem: AESE
description:
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;


platform: ARM
mnem: AESIMC
description:
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;


platform: ARM
mnem: AESMC
description:
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;


platform: ARM
mnem: BIF
description:
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);


platform: ARM
mnem: BIT
description:
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);


platform: ARM
mnem: BSL
description:
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);


platform: ARM
mnem: CMEQ
description:
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;


platform: ARM
mnem: CMGE
description:
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;


platform: ARM
mnem: CMGT
description:
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;


platform: ARM
mnem: CMHI
description:
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;


platform: ARM
mnem: CMHS
description:
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;


platform: ARM
mnem: CMLE
description:
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;


platform: ARM
mnem: CMLT
description:
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;


platform: ARM
mnem: CMTST
description:
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;


platform: ARM
mnem: CNT
description:
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;


platform: ARM
mnem: DUP
description:
       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;


platform: ARM
mnem: EXT
description:
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>;


platform: ARM
mnem: FABD
description:
       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;


platform: ARM
mnem: FABS
description:
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;


platform: ARM
mnem: FACGE
description:
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;


platform: ARM
mnem: FACGT
description:
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;


platform: ARM
mnem: FADD
description:
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;


platform: ARM
mnem: FADDP
description:
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);


platform: ARM
mnem: FCCMP
description:
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;


platform: ARM
mnem: FCCMPE
description:
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;


platform: ARM
mnem: FCMEQ
description:
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;


platform: ARM
mnem: FCMGE
description:
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;


platform: ARM
mnem: FCMGT
description:
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;


platform: ARM
mnem: FCMLE
description:
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;


platform: ARM
mnem: FCMLT
description:
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;


platform: ARM
mnem: FCMP
description:
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);


platform: ARM
mnem: FCMPE
description:
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);


platform: ARM
mnem: FCSEL
description:
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;


platform: ARM
mnem: FCVT
description:
       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;


platform: ARM
mnem: FCVTAS
description:
       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;


platform: ARM
mnem: FCVTAU
description:
       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;


platform: ARM
mnem: FCVTL
description:
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;


platform: ARM
mnem: FCVTMS
description:
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;


platform: ARM
mnem: FCVTMU
description:
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;


platform: ARM
mnem: FCVTN
description:
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;


platform: ARM
mnem: FCVTNS
description:
       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;


platform: ARM
mnem: FCVTNU
description:
       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;


platform: ARM
mnem: FCVTPS
description:
       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;


platform: ARM
mnem: FCVTPU
description:
       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;


platform: ARM
mnem: FCVTXN
description:
       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;


platform: ARM
mnem: FCVTZS
description:
       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;


platform: ARM
mnem: FCVTZU
description:
       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;


platform: ARM
mnem: FDIV
description:
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;


platform: ARM
mnem: FMADD
description:
       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;


platform: ARM
mnem: FMAX
description:
      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;


platform: ARM
mnem: FMAXNM
description:
      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;


platform: ARM
mnem: FMAXNMP
description:
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);


platform: ARM
mnem: FMAXNMV
description:
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);


platform: ARM
mnem: FMAXP
description:
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);


platform: ARM
mnem: FMAXV
description:
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);


platform: ARM
mnem: FMIN
description:
      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;


platform: ARM
mnem: FMINNM
description:
      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;


platform: ARM
mnem: FMINNMP
description:
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);


platform: ARM
mnem: FMINNMV
description:
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);


platform: ARM
mnem: FMINP
description:
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);


platform: ARM
mnem: FMINV
description:
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);


platform: ARM
mnem: FMLA
description:
       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;


platform: ARM
mnem: FMLS
description:
       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;


platform: ARM
mnem: FMOV
description:
       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;


platform: ARM
mnem: FMSUB
description:
       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;


platform: ARM
mnem: FMUL
description:
       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;


platform: ARM
mnem: FMULX
description:
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;


platform: ARM
mnem: FNEG
description:
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;


platform: ARM
mnem: FNMADD
description:
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;


platform: ARM
mnem: FNMSUB
description:
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;


platform: ARM
mnem: FNMUL
description:
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;


platform: ARM
mnem: FRECPE
description:
       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;


platform: ARM
mnem: FRECPS
description:
       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;


platform: ARM
mnem: FRECPX
description:
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;


platform: ARM
mnem: FRINTA
description:
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;


platform: ARM
mnem: FRINTI
description:
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;


platform: ARM
mnem: FRINTM
description:
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;


platform: ARM
mnem: FRINTN
description:
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;


platform: ARM
mnem: FRINTP
description:
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;


platform: ARM
mnem: FRINTX
description:
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;


platform: ARM
mnem: FRINTZ
description:
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;


platform: ARM
mnem: FRSQRTE
description:
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;


platform: ARM
mnem: FRSQRTS
description:
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;


platform: ARM
mnem: FSQRT
description:
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;


platform: ARM
mnem: FSUB
description:
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;


platform: ARM
mnem: INS
description:
       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;


