Home | History | Annotate | Download | only in a64
      1 // Copyright 2013, ARM Limited
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #ifndef VIXL_A64_CONSTANTS_A64_H_
     28 #define VIXL_A64_CONSTANTS_A64_H_
     29 
     30 namespace vixl {
     31 
     32 const unsigned kNumberOfRegisters = 32;
     33 const unsigned kNumberOfFPRegisters = 32;
     34 // Callee saved registers are x21-x30(lr).
     35 const int kNumberOfCalleeSavedRegisters = 10;
     36 const int kFirstCalleeSavedRegisterIndex = 21;
     37 // Callee saved FP registers are d8-d15.
     38 const int kNumberOfCalleeSavedFPRegisters = 8;
     39 const int kFirstCalleeSavedFPRegisterIndex = 8;
     40 
     41 #define REGISTER_CODE_LIST(R)                                                  \
     42 R(0)  R(1)  R(2)  R(3)  R(4)  R(5)  R(6)  R(7)                                 \
     43 R(8)  R(9)  R(10) R(11) R(12) R(13) R(14) R(15)                                \
     44 R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23)                                \
     45 R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
     46 
     47 #define INSTRUCTION_FIELDS_LIST(V_)                                            \
     48 /* Register fields */                                                          \
     49 V_(Rd, 4, 0, Bits)                        /* Destination register.     */      \
     50 V_(Rn, 9, 5, Bits)                        /* First source register.    */      \
     51 V_(Rm, 20, 16, Bits)                      /* Second source register.   */      \
     52 V_(Ra, 14, 10, Bits)                      /* Third source register.    */      \
     53 V_(Rt, 4, 0, Bits)                        /* Load dest / store source. */      \
     54 V_(Rt2, 14, 10, Bits)                     /* Load second dest /        */      \
     55                                          /* store second source.      */       \
     56 V_(PrefetchMode, 4, 0, Bits)                                                   \
     57                                                                                \
     58 /* Common bits */                                                              \
     59 V_(SixtyFourBits, 31, 31, Bits)                                                \
     60 V_(FlagsUpdate, 29, 29, Bits)                                                  \
     61                                                                                \
     62 /* PC relative addressing */                                                   \
     63 V_(ImmPCRelHi, 23, 5, SignedBits)                                              \
     64 V_(ImmPCRelLo, 30, 29, Bits)                                                   \
     65                                                                                \
     66 /* Add/subtract/logical shift register */                                      \
     67 V_(ShiftDP, 23, 22, Bits)                                                      \
     68 V_(ImmDPShift, 15, 10, Bits)                                                   \
     69                                                                                \
     70 /* Add/subtract immediate */                                                   \
     71 V_(ImmAddSub, 21, 10, Bits)                                                    \
     72 V_(ShiftAddSub, 23, 22, Bits)                                                  \
     73                                                                                \
     74 /* Add/substract extend */                                                     \
     75 V_(ImmExtendShift, 12, 10, Bits)                                               \
     76 V_(ExtendMode, 15, 13, Bits)                                                   \
     77                                                                                \
     78 /* Move wide */                                                                \
     79 V_(ImmMoveWide, 20, 5, Bits)                                                   \
     80 V_(ShiftMoveWide, 22, 21, Bits)                                                \
     81                                                                                \
     82 /* Logical immediate, bitfield and extract */                                  \
     83 V_(BitN, 22, 22, Bits)                                                         \
     84 V_(ImmRotate, 21, 16, Bits)                                                    \
     85 V_(ImmSetBits, 15, 10, Bits)                                                   \
     86 V_(ImmR, 21, 16, Bits)                                                         \
     87 V_(ImmS, 15, 10, Bits)                                                         \
     88                                                                                \
     89 /* Test and branch immediate */                                                \
     90 V_(ImmTestBranch, 18, 5, SignedBits)                                           \
     91 V_(ImmTestBranchBit40, 23, 19, Bits)                                           \
     92 V_(ImmTestBranchBit5, 31, 31, Bits)                                            \
     93                                                                                \
     94 /* Conditionals */                                                             \
     95 V_(Condition, 15, 12, Bits)                                                    \
     96 V_(ConditionBranch, 3, 0, Bits)                                                \
     97 V_(Nzcv, 3, 0, Bits)                                                           \
     98 V_(ImmCondCmp, 20, 16, Bits)                                                   \
     99 V_(ImmCondBranch, 23, 5, SignedBits)                                           \
    100                                                                                \
    101 /* Floating point */                                                           \
    102 V_(FPType, 23, 22, Bits)                                                       \
    103 V_(ImmFP, 20, 13, Bits)                                                        \
    104 V_(FPScale, 15, 10, Bits)                                                      \
    105                                                                                \
    106 /* Load Store */                                                               \
    107 V_(ImmLS, 20, 12, SignedBits)                                                  \
    108 V_(ImmLSUnsigned, 21, 10, Bits)                                                \
    109 V_(ImmLSPair, 21, 15, SignedBits)                                              \
    110 V_(SizeLS, 31, 30, Bits)                                                       \
    111 V_(ImmShiftLS, 12, 12, Bits)                                                   \
    112                                                                                \
    113 /* Other immediates */                                                         \
    114 V_(ImmUncondBranch, 25, 0, SignedBits)                                         \
    115 V_(ImmCmpBranch, 23, 5, SignedBits)                                            \
    116 V_(ImmLLiteral, 23, 5, SignedBits)                                             \
    117 V_(ImmException, 20, 5, Bits)                                                  \
    118 V_(ImmHint, 11, 5, Bits)                                                       \
    119 V_(ImmBarrierDomain, 11, 10, Bits)                                             \
    120 V_(ImmBarrierType, 9, 8, Bits)                                                 \
    121                                                                                \
    122 /* System (MRS, MSR) */                                                        \
    123 V_(ImmSystemRegister, 19, 5, Bits)                                             \
    124 V_(SysO0, 19, 19, Bits)                                                        \
    125 V_(SysOp1, 18, 16, Bits)                                                       \
    126 V_(SysOp2, 7, 5, Bits)                                                         \
    127 V_(CRn, 15, 12, Bits)                                                          \
    128 V_(CRm, 11, 8, Bits)                                                           \
    129 
    130 
    131 #define SYSTEM_REGISTER_FIELDS_LIST(V_, M_)                                    \
    132 /* NZCV */                                                                     \
    133 V_(Flags, 31, 28, Bits)                                                        \
    134 V_(N, 31, 31, Bits)                                                            \
    135 V_(Z, 30, 30, Bits)                                                            \
    136 V_(C, 29, 29, Bits)                                                            \
    137 V_(V, 28, 28, Bits)                                                            \
    138 M_(NZCV, Flags_mask)                                                           \
    139                                                                                \
    140 /* FPCR */                                                                     \
    141 V_(AHP, 26, 26, Bits)                                                          \
    142 V_(DN, 25, 25, Bits)                                                           \
    143 V_(FZ, 24, 24, Bits)                                                           \
    144 V_(RMode, 23, 22, Bits)                                                        \
    145 M_(FPCR, AHP_mask | DN_mask | FZ_mask | RMode_mask)
    146 
    147 
    148 // Fields offsets.
    149 #define DECLARE_FIELDS_OFFSETS(Name, HighBit, LowBit, X)                       \
    150 const int Name##_offset = LowBit;                                              \
    151 const int Name##_width = HighBit - LowBit + 1;                                 \
    152 const uint32_t Name##_mask = ((1 << Name##_width) - 1) << LowBit;
    153 #define NOTHING(A, B)
    154 INSTRUCTION_FIELDS_LIST(DECLARE_FIELDS_OFFSETS)
    155 SYSTEM_REGISTER_FIELDS_LIST(DECLARE_FIELDS_OFFSETS, NOTHING)
    156 #undef NOTHING
    157 #undef DECLARE_FIELDS_BITS
    158 
    159 // ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST), formed
    160 // from ImmPCRelLo and ImmPCRelHi.
    161 const int ImmPCRel_mask = ImmPCRelLo_mask | ImmPCRelHi_mask;
    162 
    163 // Condition codes.
    164 enum Condition {
    165   eq = 0,
    166   ne = 1,
    167   hs = 2,
    168   lo = 3,
    169   mi = 4,
    170   pl = 5,
    171   vs = 6,
    172   vc = 7,
    173   hi = 8,
    174   ls = 9,
    175   ge = 10,
    176   lt = 11,
    177   gt = 12,
    178   le = 13,
    179   al = 14,
    180   nv = 15  // Behaves as always/al.
    181 };
    182 
    183 inline Condition InvertCondition(Condition cond) {
    184   // Conditions al and nv behave identically, as "always true". They can't be
    185   // inverted, because there is no "always false" condition.
    186   VIXL_ASSERT((cond != al) && (cond != nv));
    187   return static_cast<Condition>(cond ^ 1);
    188 }
    189 
    190 enum FlagsUpdate {
    191   SetFlags   = 1,
    192   LeaveFlags = 0
    193 };
    194 
    195 enum StatusFlags {
    196   NoFlag    = 0,
    197 
    198   // Derive the flag combinations from the system register bit descriptions.
    199   NFlag     = N_mask,
    200   ZFlag     = Z_mask,
    201   CFlag     = C_mask,
    202   VFlag     = V_mask,
    203   NZFlag    = NFlag | ZFlag,
    204   NCFlag    = NFlag | CFlag,
    205   NVFlag    = NFlag | VFlag,
    206   ZCFlag    = ZFlag | CFlag,
    207   ZVFlag    = ZFlag | VFlag,
    208   CVFlag    = CFlag | VFlag,
    209   NZCFlag   = NFlag | ZFlag | CFlag,
    210   NZVFlag   = NFlag | ZFlag | VFlag,
    211   NCVFlag   = NFlag | CFlag | VFlag,
    212   ZCVFlag   = ZFlag | CFlag | VFlag,
    213   NZCVFlag  = NFlag | ZFlag | CFlag | VFlag,
    214 
    215   // Floating-point comparison results.
    216   FPEqualFlag       = ZCFlag,
    217   FPLessThanFlag    = NFlag,
    218   FPGreaterThanFlag = CFlag,
    219   FPUnorderedFlag   = CVFlag
    220 };
    221 
    222 enum Shift {
    223   NO_SHIFT = -1,
    224   LSL = 0x0,
    225   LSR = 0x1,
    226   ASR = 0x2,
    227   ROR = 0x3
    228 };
    229 
    230 enum Extend {
    231   NO_EXTEND = -1,
    232   UXTB      = 0,
    233   UXTH      = 1,
    234   UXTW      = 2,
    235   UXTX      = 3,
    236   SXTB      = 4,
    237   SXTH      = 5,
    238   SXTW      = 6,
    239   SXTX      = 7
    240 };
    241 
    242 enum SystemHint {
    243   NOP   = 0,
    244   YIELD = 1,
    245   WFE   = 2,
    246   WFI   = 3,
    247   SEV   = 4,
    248   SEVL  = 5
    249 };
    250 
    251 enum BarrierDomain {
    252   OuterShareable = 0,
    253   NonShareable   = 1,
    254   InnerShareable = 2,
    255   FullSystem     = 3
    256 };
    257 
    258 enum BarrierType {
    259   BarrierOther  = 0,
    260   BarrierReads  = 1,
    261   BarrierWrites = 2,
    262   BarrierAll    = 3
    263 };
    264 
    265 // System/special register names.
    266 // This information is not encoded as one field but as the concatenation of
    267 // multiple fields (Op0<0>, Op1, Crn, Crm, Op2).
    268 enum SystemRegister {
    269   NZCV = ((0x1 << SysO0_offset) |
    270           (0x3 << SysOp1_offset) |
    271           (0x4 << CRn_offset) |
    272           (0x2 << CRm_offset) |
    273           (0x0 << SysOp2_offset)) >> ImmSystemRegister_offset,
    274   FPCR = ((0x1 << SysO0_offset) |
    275           (0x3 << SysOp1_offset) |
    276           (0x4 << CRn_offset) |
    277           (0x4 << CRm_offset) |
    278           (0x0 << SysOp2_offset)) >> ImmSystemRegister_offset
    279 };
    280 
    281 // Instruction enumerations.
    282 //
    283 // These are the masks that define a class of instructions, and the list of
    284 // instructions within each class. Each enumeration has a Fixed, FMask and
    285 // Mask value.
    286 //
    287 // Fixed: The fixed bits in this instruction class.
    288 // FMask: The mask used to extract the fixed bits in the class.
    289 // Mask:  The mask used to identify the instructions within a class.
    290 //
    291 // The enumerations can be used like this:
    292 //
    293 // VIXL_ASSERT(instr->Mask(PCRelAddressingFMask) == PCRelAddressingFixed);
    294 // switch(instr->Mask(PCRelAddressingMask)) {
    295 //   case ADR:  Format("adr 'Xd, 'AddrPCRelByte"); break;
    296 //   case ADRP: Format("adrp 'Xd, 'AddrPCRelPage"); break;
    297 //   default:   printf("Unknown instruction\n");
    298 // }
    299 
    300 
    301 // Generic fields.
    302 enum GenericInstrField {
    303   SixtyFourBits        = 0x80000000,
    304   ThirtyTwoBits        = 0x00000000,
    305   FP32                 = 0x00000000,
    306   FP64                 = 0x00400000
    307 };
    308 
    309 // PC relative addressing.
    310 enum PCRelAddressingOp {
    311   PCRelAddressingFixed = 0x10000000,
    312   PCRelAddressingFMask = 0x1F000000,
    313   PCRelAddressingMask  = 0x9F000000,
    314   ADR                  = PCRelAddressingFixed | 0x00000000,
    315   ADRP                 = PCRelAddressingFixed | 0x80000000
    316 };
    317 
    318 // Add/sub (immediate, shifted and extended.)
    319 const int kSFOffset = 31;
    320 enum AddSubOp {
    321   AddSubOpMask      = 0x60000000,
    322   AddSubSetFlagsBit = 0x20000000,
    323   ADD               = 0x00000000,
    324   ADDS              = ADD | AddSubSetFlagsBit,
    325   SUB               = 0x40000000,
    326   SUBS              = SUB | AddSubSetFlagsBit
    327 };
    328 
    329 #define ADD_SUB_OP_LIST(V)  \
    330   V(ADD),                   \
    331   V(ADDS),                  \
    332   V(SUB),                   \
    333   V(SUBS)
    334 
    335 enum AddSubImmediateOp {
    336   AddSubImmediateFixed = 0x11000000,
    337   AddSubImmediateFMask = 0x1F000000,
    338   AddSubImmediateMask  = 0xFF000000,
    339   #define ADD_SUB_IMMEDIATE(A)           \
    340   A##_w_imm = AddSubImmediateFixed | A,  \
    341   A##_x_imm = AddSubImmediateFixed | A | SixtyFourBits
    342   ADD_SUB_OP_LIST(ADD_SUB_IMMEDIATE)
    343   #undef ADD_SUB_IMMEDIATE
    344 };
    345 
    346 enum AddSubShiftedOp {
    347   AddSubShiftedFixed   = 0x0B000000,
    348   AddSubShiftedFMask   = 0x1F200000,
    349   AddSubShiftedMask    = 0xFF200000,
    350   #define ADD_SUB_SHIFTED(A)             \
    351   A##_w_shift = AddSubShiftedFixed | A,  \
    352   A##_x_shift = AddSubShiftedFixed | A | SixtyFourBits
    353   ADD_SUB_OP_LIST(ADD_SUB_SHIFTED)
    354   #undef ADD_SUB_SHIFTED
    355 };
    356 
    357 enum AddSubExtendedOp {
    358   AddSubExtendedFixed  = 0x0B200000,
    359   AddSubExtendedFMask  = 0x1F200000,
    360   AddSubExtendedMask   = 0xFFE00000,
    361   #define ADD_SUB_EXTENDED(A)           \
    362   A##_w_ext = AddSubExtendedFixed | A,  \
    363   A##_x_ext = AddSubExtendedFixed | A | SixtyFourBits
    364   ADD_SUB_OP_LIST(ADD_SUB_EXTENDED)
    365   #undef ADD_SUB_EXTENDED
    366 };
    367 
    368 // Add/sub with carry.
    369 enum AddSubWithCarryOp {
    370   AddSubWithCarryFixed = 0x1A000000,
    371   AddSubWithCarryFMask = 0x1FE00000,
    372   AddSubWithCarryMask  = 0xFFE0FC00,
    373   ADC_w                = AddSubWithCarryFixed | ADD,
    374   ADC_x                = AddSubWithCarryFixed | ADD | SixtyFourBits,
    375   ADC                  = ADC_w,
    376   ADCS_w               = AddSubWithCarryFixed | ADDS,
    377   ADCS_x               = AddSubWithCarryFixed | ADDS | SixtyFourBits,
    378   SBC_w                = AddSubWithCarryFixed | SUB,
    379   SBC_x                = AddSubWithCarryFixed | SUB | SixtyFourBits,
    380   SBC                  = SBC_w,
    381   SBCS_w               = AddSubWithCarryFixed | SUBS,
    382   SBCS_x               = AddSubWithCarryFixed | SUBS | SixtyFourBits
    383 };
    384 
    385 
    386 // Logical (immediate and shifted register).
    387 enum LogicalOp {
    388   LogicalOpMask = 0x60200000,
    389   NOT   = 0x00200000,
    390   AND   = 0x00000000,
    391   BIC   = AND | NOT,
    392   ORR   = 0x20000000,
    393   ORN   = ORR | NOT,
    394   EOR   = 0x40000000,
    395   EON   = EOR | NOT,
    396   ANDS  = 0x60000000,
    397   BICS  = ANDS | NOT
    398 };
    399 
    400 // Logical immediate.
    401 enum LogicalImmediateOp {
    402   LogicalImmediateFixed = 0x12000000,
    403   LogicalImmediateFMask = 0x1F800000,
    404   LogicalImmediateMask  = 0xFF800000,
    405   AND_w_imm   = LogicalImmediateFixed | AND,
    406   AND_x_imm   = LogicalImmediateFixed | AND | SixtyFourBits,
    407   ORR_w_imm   = LogicalImmediateFixed | ORR,
    408   ORR_x_imm   = LogicalImmediateFixed | ORR | SixtyFourBits,
    409   EOR_w_imm   = LogicalImmediateFixed | EOR,
    410   EOR_x_imm   = LogicalImmediateFixed | EOR | SixtyFourBits,
    411   ANDS_w_imm  = LogicalImmediateFixed | ANDS,
    412   ANDS_x_imm  = LogicalImmediateFixed | ANDS | SixtyFourBits
    413 };
    414 
    415 // Logical shifted register.
    416 enum LogicalShiftedOp {
    417   LogicalShiftedFixed = 0x0A000000,
    418   LogicalShiftedFMask = 0x1F000000,
    419   LogicalShiftedMask  = 0xFF200000,
    420   AND_w               = LogicalShiftedFixed | AND,
    421   AND_x               = LogicalShiftedFixed | AND | SixtyFourBits,
    422   AND_shift           = AND_w,
    423   BIC_w               = LogicalShiftedFixed | BIC,
    424   BIC_x               = LogicalShiftedFixed | BIC | SixtyFourBits,
    425   BIC_shift           = BIC_w,
    426   ORR_w               = LogicalShiftedFixed | ORR,
    427   ORR_x               = LogicalShiftedFixed | ORR | SixtyFourBits,
    428   ORR_shift           = ORR_w,
    429   ORN_w               = LogicalShiftedFixed | ORN,
    430   ORN_x               = LogicalShiftedFixed | ORN | SixtyFourBits,
    431   ORN_shift           = ORN_w,
    432   EOR_w               = LogicalShiftedFixed | EOR,
    433   EOR_x               = LogicalShiftedFixed | EOR | SixtyFourBits,
    434   EOR_shift           = EOR_w,
    435   EON_w               = LogicalShiftedFixed | EON,
    436   EON_x               = LogicalShiftedFixed | EON | SixtyFourBits,
    437   EON_shift           = EON_w,
    438   ANDS_w              = LogicalShiftedFixed | ANDS,
    439   ANDS_x              = LogicalShiftedFixed | ANDS | SixtyFourBits,
    440   ANDS_shift          = ANDS_w,
    441   BICS_w              = LogicalShiftedFixed | BICS,
    442   BICS_x              = LogicalShiftedFixed | BICS | SixtyFourBits,
    443   BICS_shift          = BICS_w
    444 };
    445 
    446 // Move wide immediate.
    447 enum MoveWideImmediateOp {
    448   MoveWideImmediateFixed = 0x12800000,
    449   MoveWideImmediateFMask = 0x1F800000,
    450   MoveWideImmediateMask  = 0xFF800000,
    451   MOVN                   = 0x00000000,
    452   MOVZ                   = 0x40000000,
    453   MOVK                   = 0x60000000,
    454   MOVN_w                 = MoveWideImmediateFixed | MOVN,
    455   MOVN_x                 = MoveWideImmediateFixed | MOVN | SixtyFourBits,
    456   MOVZ_w                 = MoveWideImmediateFixed | MOVZ,
    457   MOVZ_x                 = MoveWideImmediateFixed | MOVZ | SixtyFourBits,
    458   MOVK_w                 = MoveWideImmediateFixed | MOVK,
    459   MOVK_x                 = MoveWideImmediateFixed | MOVK | SixtyFourBits
    460 };
    461 
    462 // Bitfield.
    463 const int kBitfieldNOffset = 22;
    464 enum BitfieldOp {
    465   BitfieldFixed = 0x13000000,
    466   BitfieldFMask = 0x1F800000,
    467   BitfieldMask  = 0xFF800000,
    468   SBFM_w        = BitfieldFixed | 0x00000000,
    469   SBFM_x        = BitfieldFixed | 0x80000000,
    470   SBFM          = SBFM_w,
    471   BFM_w         = BitfieldFixed | 0x20000000,
    472   BFM_x         = BitfieldFixed | 0xA0000000,
    473   BFM           = BFM_w,
    474   UBFM_w        = BitfieldFixed | 0x40000000,
    475   UBFM_x        = BitfieldFixed | 0xC0000000,
    476   UBFM          = UBFM_w
    477   // Bitfield N field.
    478 };
    479 
    480 // Extract.
    481 enum ExtractOp {
    482   ExtractFixed = 0x13800000,
    483   ExtractFMask = 0x1F800000,
    484   ExtractMask  = 0xFFA00000,
    485   EXTR_w       = ExtractFixed | 0x00000000,
    486   EXTR_x       = ExtractFixed | 0x80000000,
    487   EXTR         = EXTR_w
    488 };
    489 
    490 // Unconditional branch.
    491 enum UnconditionalBranchOp {
    492   UnconditionalBranchFixed = 0x14000000,
    493   UnconditionalBranchFMask = 0x7C000000,
    494   UnconditionalBranchMask  = 0xFC000000,
    495   B                        = UnconditionalBranchFixed | 0x00000000,
    496   BL                       = UnconditionalBranchFixed | 0x80000000
    497 };
    498 
    499 // Unconditional branch to register.
    500 enum UnconditionalBranchToRegisterOp {
    501   UnconditionalBranchToRegisterFixed = 0xD6000000,
    502   UnconditionalBranchToRegisterFMask = 0xFE000000,
    503   UnconditionalBranchToRegisterMask  = 0xFFFFFC1F,
    504   BR      = UnconditionalBranchToRegisterFixed | 0x001F0000,
    505   BLR     = UnconditionalBranchToRegisterFixed | 0x003F0000,
    506   RET     = UnconditionalBranchToRegisterFixed | 0x005F0000
    507 };
    508 
    509 // Compare and branch.
    510 enum CompareBranchOp {
    511   CompareBranchFixed = 0x34000000,
    512   CompareBranchFMask = 0x7E000000,
    513   CompareBranchMask  = 0xFF000000,
    514   CBZ_w              = CompareBranchFixed | 0x00000000,
    515   CBZ_x              = CompareBranchFixed | 0x80000000,
    516   CBZ                = CBZ_w,
    517   CBNZ_w             = CompareBranchFixed | 0x01000000,
    518   CBNZ_x             = CompareBranchFixed | 0x81000000,
    519   CBNZ               = CBNZ_w
    520 };
    521 
    522 // Test and branch.
    523 enum TestBranchOp {
    524   TestBranchFixed = 0x36000000,
    525   TestBranchFMask = 0x7E000000,
    526   TestBranchMask  = 0x7F000000,
    527   TBZ             = TestBranchFixed | 0x00000000,
    528   TBNZ            = TestBranchFixed | 0x01000000
    529 };
    530 
    531 // Conditional branch.
    532 enum ConditionalBranchOp {
    533   ConditionalBranchFixed = 0x54000000,
    534   ConditionalBranchFMask = 0xFE000000,
    535   ConditionalBranchMask  = 0xFF000010,
    536   B_cond                 = ConditionalBranchFixed | 0x00000000
    537 };
    538 
    539 // System.
    540 // System instruction encoding is complicated because some instructions use op
    541 // and CR fields to encode parameters. To handle this cleanly, the system
    542 // instructions are split into more than one enum.
    543 
    544 enum SystemOp {
    545   SystemFixed = 0xD5000000,
    546   SystemFMask = 0xFFC00000
    547 };
    548 
    549 enum SystemSysRegOp {
    550   SystemSysRegFixed = 0xD5100000,
    551   SystemSysRegFMask = 0xFFD00000,
    552   SystemSysRegMask  = 0xFFF00000,
    553   MRS               = SystemSysRegFixed | 0x00200000,
    554   MSR               = SystemSysRegFixed | 0x00000000
    555 };
    556 
    557 enum SystemHintOp {
    558   SystemHintFixed = 0xD503201F,
    559   SystemHintFMask = 0xFFFFF01F,
    560   SystemHintMask  = 0xFFFFF01F,
    561   HINT            = SystemHintFixed | 0x00000000
    562 };
    563 
    564 // Exception.
    565 enum ExceptionOp {
    566   ExceptionFixed = 0xD4000000,
    567   ExceptionFMask = 0xFF000000,
    568   ExceptionMask  = 0xFFE0001F,
    569   HLT            = ExceptionFixed | 0x00400000,
    570   BRK            = ExceptionFixed | 0x00200000,
    571   SVC            = ExceptionFixed | 0x00000001,
    572   HVC            = ExceptionFixed | 0x00000002,
    573   SMC            = ExceptionFixed | 0x00000003,
    574   DCPS1          = ExceptionFixed | 0x00A00001,
    575   DCPS2          = ExceptionFixed | 0x00A00002,
    576   DCPS3          = ExceptionFixed | 0x00A00003
    577 };
    578 
    579 enum MemBarrierOp {
    580   MemBarrierFixed = 0xD503309F,
    581   MemBarrierFMask = 0xFFFFF09F,
    582   MemBarrierMask  = 0xFFFFF0FF,
    583   DSB             = MemBarrierFixed | 0x00000000,
    584   DMB             = MemBarrierFixed | 0x00000020,
    585   ISB             = MemBarrierFixed | 0x00000040
    586 };
    587 
    588 // Any load or store.
    589 enum LoadStoreAnyOp {
    590   LoadStoreAnyFMask = 0x0a000000,
    591   LoadStoreAnyFixed = 0x08000000
    592 };
    593 
    594 #define LOAD_STORE_PAIR_OP_LIST(V)  \
    595   V(STP, w,   0x00000000),          \
    596   V(LDP, w,   0x00400000),          \
    597   V(LDPSW, x, 0x40400000),          \
    598   V(STP, x,   0x80000000),          \
    599   V(LDP, x,   0x80400000),          \
    600   V(STP, s,   0x04000000),          \
    601   V(LDP, s,   0x04400000),          \
    602   V(STP, d,   0x44000000),          \
    603   V(LDP, d,   0x44400000)
    604 
    605 // Load/store pair (post, pre and offset.)
    606 enum LoadStorePairOp {
    607   LoadStorePairMask = 0xC4400000,
    608   LoadStorePairLBit = 1 << 22,
    609   #define LOAD_STORE_PAIR(A, B, C) \
    610   A##_##B = C
    611   LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR)
    612   #undef LOAD_STORE_PAIR
    613 };
    614 
    615 enum LoadStorePairPostIndexOp {
    616   LoadStorePairPostIndexFixed = 0x28800000,
    617   LoadStorePairPostIndexFMask = 0x3B800000,
    618   LoadStorePairPostIndexMask  = 0xFFC00000,
    619   #define LOAD_STORE_PAIR_POST_INDEX(A, B, C)  \
    620   A##_##B##_post = LoadStorePairPostIndexFixed | A##_##B
    621   LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_POST_INDEX)
    622   #undef LOAD_STORE_PAIR_POST_INDEX
    623 };
    624 
    625 enum LoadStorePairPreIndexOp {
    626   LoadStorePairPreIndexFixed = 0x29800000,
    627   LoadStorePairPreIndexFMask = 0x3B800000,
    628   LoadStorePairPreIndexMask  = 0xFFC00000,
    629   #define LOAD_STORE_PAIR_PRE_INDEX(A, B, C)  \
    630   A##_##B##_pre = LoadStorePairPreIndexFixed | A##_##B
    631   LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_PRE_INDEX)
    632   #undef LOAD_STORE_PAIR_PRE_INDEX
    633 };
    634 
    635 enum LoadStorePairOffsetOp {
    636   LoadStorePairOffsetFixed = 0x29000000,
    637   LoadStorePairOffsetFMask = 0x3B800000,
    638   LoadStorePairOffsetMask  = 0xFFC00000,
    639   #define LOAD_STORE_PAIR_OFFSET(A, B, C)  \
    640   A##_##B##_off = LoadStorePairOffsetFixed | A##_##B
    641   LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_OFFSET)
    642   #undef LOAD_STORE_PAIR_OFFSET
    643 };
    644 
    645 enum LoadStorePairNonTemporalOp {
    646   LoadStorePairNonTemporalFixed = 0x28000000,
    647   LoadStorePairNonTemporalFMask = 0x3B800000,
    648   LoadStorePairNonTemporalMask  = 0xFFC00000,
    649   STNP_w = LoadStorePairNonTemporalFixed | STP_w,
    650   LDNP_w = LoadStorePairNonTemporalFixed | LDP_w,
    651   STNP_x = LoadStorePairNonTemporalFixed | STP_x,
    652   LDNP_x = LoadStorePairNonTemporalFixed | LDP_x,
    653   STNP_s = LoadStorePairNonTemporalFixed | STP_s,
    654   LDNP_s = LoadStorePairNonTemporalFixed | LDP_s,
    655   STNP_d = LoadStorePairNonTemporalFixed | STP_d,
    656   LDNP_d = LoadStorePairNonTemporalFixed | LDP_d
    657 };
    658 
    659 // Load literal.
    660 enum LoadLiteralOp {
    661   LoadLiteralFixed = 0x18000000,
    662   LoadLiteralFMask = 0x3B000000,
    663   LoadLiteralMask  = 0xFF000000,
    664   LDR_w_lit        = LoadLiteralFixed | 0x00000000,
    665   LDR_x_lit        = LoadLiteralFixed | 0x40000000,
    666   LDRSW_x_lit      = LoadLiteralFixed | 0x80000000,
    667   PRFM_lit         = LoadLiteralFixed | 0xC0000000,
    668   LDR_s_lit        = LoadLiteralFixed | 0x04000000,
    669   LDR_d_lit        = LoadLiteralFixed | 0x44000000
    670 };
    671 
    672 #define LOAD_STORE_OP_LIST(V)     \
    673   V(ST, RB, w,  0x00000000),  \
    674   V(ST, RH, w,  0x40000000),  \
    675   V(ST, R, w,   0x80000000),  \
    676   V(ST, R, x,   0xC0000000),  \
    677   V(LD, RB, w,  0x00400000),  \
    678   V(LD, RH, w,  0x40400000),  \
    679   V(LD, R, w,   0x80400000),  \
    680   V(LD, R, x,   0xC0400000),  \
    681   V(LD, RSB, x, 0x00800000),  \
    682   V(LD, RSH, x, 0x40800000),  \
    683   V(LD, RSW, x, 0x80800000),  \
    684   V(LD, RSB, w, 0x00C00000),  \
    685   V(LD, RSH, w, 0x40C00000),  \
    686   V(ST, R, s,   0x84000000),  \
    687   V(ST, R, d,   0xC4000000),  \
    688   V(LD, R, s,   0x84400000),  \
    689   V(LD, R, d,   0xC4400000)
    690 
    691 
    692 // Load/store unscaled offset.
    693 enum LoadStoreUnscaledOffsetOp {
    694   LoadStoreUnscaledOffsetFixed = 0x38000000,
    695   LoadStoreUnscaledOffsetFMask = 0x3B200C00,
    696   LoadStoreUnscaledOffsetMask  = 0xFFE00C00,
    697   #define LOAD_STORE_UNSCALED(A, B, C, D)  \
    698   A##U##B##_##C = LoadStoreUnscaledOffsetFixed | D
    699   LOAD_STORE_OP_LIST(LOAD_STORE_UNSCALED)
    700   #undef LOAD_STORE_UNSCALED
    701 };
    702 
    703 // Load/store (post, pre, offset and unsigned.)
    704 enum LoadStoreOp {
    705   LoadStoreOpMask   = 0xC4C00000,
    706   #define LOAD_STORE(A, B, C, D)  \
    707   A##B##_##C = D
    708   LOAD_STORE_OP_LIST(LOAD_STORE),
    709   #undef LOAD_STORE
    710   PRFM = 0xC0800000
    711 };
    712 
    713 // Load/store post index.
    714 enum LoadStorePostIndex {
    715   LoadStorePostIndexFixed = 0x38000400,
    716   LoadStorePostIndexFMask = 0x3B200C00,
    717   LoadStorePostIndexMask  = 0xFFE00C00,
    718   #define LOAD_STORE_POST_INDEX(A, B, C, D)  \
    719   A##B##_##C##_post = LoadStorePostIndexFixed | D
    720   LOAD_STORE_OP_LIST(LOAD_STORE_POST_INDEX)
    721   #undef LOAD_STORE_POST_INDEX
    722 };
    723 
    724 // Load/store pre index.
    725 enum LoadStorePreIndex {
    726   LoadStorePreIndexFixed = 0x38000C00,
    727   LoadStorePreIndexFMask = 0x3B200C00,
    728   LoadStorePreIndexMask  = 0xFFE00C00,
    729   #define LOAD_STORE_PRE_INDEX(A, B, C, D)  \
    730   A##B##_##C##_pre = LoadStorePreIndexFixed | D
    731   LOAD_STORE_OP_LIST(LOAD_STORE_PRE_INDEX)
    732   #undef LOAD_STORE_PRE_INDEX
    733 };
    734 
    735 // Load/store unsigned offset.
    736 enum LoadStoreUnsignedOffset {
    737   LoadStoreUnsignedOffsetFixed = 0x39000000,
    738   LoadStoreUnsignedOffsetFMask = 0x3B000000,
    739   LoadStoreUnsignedOffsetMask  = 0xFFC00000,
    740   PRFM_unsigned                = LoadStoreUnsignedOffsetFixed | PRFM,
    741   #define LOAD_STORE_UNSIGNED_OFFSET(A, B, C, D) \
    742   A##B##_##C##_unsigned = LoadStoreUnsignedOffsetFixed | D
    743   LOAD_STORE_OP_LIST(LOAD_STORE_UNSIGNED_OFFSET)
    744   #undef LOAD_STORE_UNSIGNED_OFFSET
    745 };
    746 
    747 // Load/store register offset.
    748 enum LoadStoreRegisterOffset {
    749   LoadStoreRegisterOffsetFixed = 0x38200800,
    750   LoadStoreRegisterOffsetFMask = 0x3B200C00,
    751   LoadStoreRegisterOffsetMask  = 0xFFE00C00,
    752   PRFM_reg                     = LoadStoreRegisterOffsetFixed | PRFM,
    753   #define LOAD_STORE_REGISTER_OFFSET(A, B, C, D) \
    754   A##B##_##C##_reg = LoadStoreRegisterOffsetFixed | D
    755   LOAD_STORE_OP_LIST(LOAD_STORE_REGISTER_OFFSET)
    756   #undef LOAD_STORE_REGISTER_OFFSET
    757 };
    758 
    759 // Conditional compare.
    760 enum ConditionalCompareOp {
    761   ConditionalCompareMask = 0x60000000,
    762   CCMN                   = 0x20000000,
    763   CCMP                   = 0x60000000
    764 };
    765 
    766 // Conditional compare register.
    767 enum ConditionalCompareRegisterOp {
    768   ConditionalCompareRegisterFixed = 0x1A400000,
    769   ConditionalCompareRegisterFMask = 0x1FE00800,
    770   ConditionalCompareRegisterMask  = 0xFFE00C10,
    771   CCMN_w = ConditionalCompareRegisterFixed | CCMN,
    772   CCMN_x = ConditionalCompareRegisterFixed | SixtyFourBits | CCMN,
    773   CCMP_w = ConditionalCompareRegisterFixed | CCMP,
    774   CCMP_x = ConditionalCompareRegisterFixed | SixtyFourBits | CCMP
    775 };
    776 
    777 // Conditional compare immediate.
    778 enum ConditionalCompareImmediateOp {
    779   ConditionalCompareImmediateFixed = 0x1A400800,
    780   ConditionalCompareImmediateFMask = 0x1FE00800,
    781   ConditionalCompareImmediateMask  = 0xFFE00C10,
    782   CCMN_w_imm = ConditionalCompareImmediateFixed | CCMN,
    783   CCMN_x_imm = ConditionalCompareImmediateFixed | SixtyFourBits | CCMN,
    784   CCMP_w_imm = ConditionalCompareImmediateFixed | CCMP,
    785   CCMP_x_imm = ConditionalCompareImmediateFixed | SixtyFourBits | CCMP
    786 };
    787 
    788 // Conditional select.
    789 enum ConditionalSelectOp {
    790   ConditionalSelectFixed = 0x1A800000,
    791   ConditionalSelectFMask = 0x1FE00000,
    792   ConditionalSelectMask  = 0xFFE00C00,
    793   CSEL_w                 = ConditionalSelectFixed | 0x00000000,
    794   CSEL_x                 = ConditionalSelectFixed | 0x80000000,
    795   CSEL                   = CSEL_w,
    796   CSINC_w                = ConditionalSelectFixed | 0x00000400,
    797   CSINC_x                = ConditionalSelectFixed | 0x80000400,
    798   CSINC                  = CSINC_w,
    799   CSINV_w                = ConditionalSelectFixed | 0x40000000,
    800   CSINV_x                = ConditionalSelectFixed | 0xC0000000,
    801   CSINV                  = CSINV_w,
    802   CSNEG_w                = ConditionalSelectFixed | 0x40000400,
    803   CSNEG_x                = ConditionalSelectFixed | 0xC0000400,
    804   CSNEG                  = CSNEG_w
    805 };
    806 
    807 // Data processing 1 source.
    808 enum DataProcessing1SourceOp {
    809   DataProcessing1SourceFixed = 0x5AC00000,
    810   DataProcessing1SourceFMask = 0x5FE00000,
    811   DataProcessing1SourceMask  = 0xFFFFFC00,
    812   RBIT    = DataProcessing1SourceFixed | 0x00000000,
    813   RBIT_w  = RBIT,
    814   RBIT_x  = RBIT | SixtyFourBits,
    815   REV16   = DataProcessing1SourceFixed | 0x00000400,
    816   REV16_w = REV16,
    817   REV16_x = REV16 | SixtyFourBits,
    818   REV     = DataProcessing1SourceFixed | 0x00000800,
    819   REV_w   = REV,
    820   REV32_x = REV | SixtyFourBits,
    821   REV_x   = DataProcessing1SourceFixed | SixtyFourBits | 0x00000C00,
    822   CLZ     = DataProcessing1SourceFixed | 0x00001000,
    823   CLZ_w   = CLZ,
    824   CLZ_x   = CLZ | SixtyFourBits,
    825   CLS     = DataProcessing1SourceFixed | 0x00001400,
    826   CLS_w   = CLS,
    827   CLS_x   = CLS | SixtyFourBits
    828 };
    829 
    830 // Data processing 2 source.
    831 enum DataProcessing2SourceOp {
    832   DataProcessing2SourceFixed = 0x1AC00000,
    833   DataProcessing2SourceFMask = 0x5FE00000,
    834   DataProcessing2SourceMask  = 0xFFE0FC00,
    835   UDIV_w  = DataProcessing2SourceFixed | 0x00000800,
    836   UDIV_x  = DataProcessing2SourceFixed | 0x80000800,
    837   UDIV    = UDIV_w,
    838   SDIV_w  = DataProcessing2SourceFixed | 0x00000C00,
    839   SDIV_x  = DataProcessing2SourceFixed | 0x80000C00,
    840   SDIV    = SDIV_w,
    841   LSLV_w  = DataProcessing2SourceFixed | 0x00002000,
    842   LSLV_x  = DataProcessing2SourceFixed | 0x80002000,
    843   LSLV    = LSLV_w,
    844   LSRV_w  = DataProcessing2SourceFixed | 0x00002400,
    845   LSRV_x  = DataProcessing2SourceFixed | 0x80002400,
    846   LSRV    = LSRV_w,
    847   ASRV_w  = DataProcessing2SourceFixed | 0x00002800,
    848   ASRV_x  = DataProcessing2SourceFixed | 0x80002800,
    849   ASRV    = ASRV_w,
    850   RORV_w  = DataProcessing2SourceFixed | 0x00002C00,
    851   RORV_x  = DataProcessing2SourceFixed | 0x80002C00,
    852   RORV    = RORV_w,
    853   CRC32B  = DataProcessing2SourceFixed | 0x00004000,
    854   CRC32H  = DataProcessing2SourceFixed | 0x00004400,
    855   CRC32W  = DataProcessing2SourceFixed | 0x00004800,
    856   CRC32X  = DataProcessing2SourceFixed | SixtyFourBits | 0x00004C00,
    857   CRC32CB = DataProcessing2SourceFixed | 0x00005000,
    858   CRC32CH = DataProcessing2SourceFixed | 0x00005400,
    859   CRC32CW = DataProcessing2SourceFixed | 0x00005800,
    860   CRC32CX = DataProcessing2SourceFixed | SixtyFourBits | 0x00005C00
    861 };
    862 
    863 // Data processing 3 source.
    864 enum DataProcessing3SourceOp {
    865   DataProcessing3SourceFixed = 0x1B000000,
    866   DataProcessing3SourceFMask = 0x1F000000,
    867   DataProcessing3SourceMask  = 0xFFE08000,
    868   MADD_w                     = DataProcessing3SourceFixed | 0x00000000,
    869   MADD_x                     = DataProcessing3SourceFixed | 0x80000000,
    870   MADD                       = MADD_w,
    871   MSUB_w                     = DataProcessing3SourceFixed | 0x00008000,
    872   MSUB_x                     = DataProcessing3SourceFixed | 0x80008000,
    873   MSUB                       = MSUB_w,
    874   SMADDL_x                   = DataProcessing3SourceFixed | 0x80200000,
    875   SMSUBL_x                   = DataProcessing3SourceFixed | 0x80208000,
    876   SMULH_x                    = DataProcessing3SourceFixed | 0x80400000,
    877   UMADDL_x                   = DataProcessing3SourceFixed | 0x80A00000,
    878   UMSUBL_x                   = DataProcessing3SourceFixed | 0x80A08000,
    879   UMULH_x                    = DataProcessing3SourceFixed | 0x80C00000
    880 };
    881 
    882 // Floating point compare.
    883 enum FPCompareOp {
    884   FPCompareFixed = 0x1E202000,
    885   FPCompareFMask = 0x5F203C00,
    886   FPCompareMask  = 0xFFE0FC1F,
    887   FCMP_s         = FPCompareFixed | 0x00000000,
    888   FCMP_d         = FPCompareFixed | FP64 | 0x00000000,
    889   FCMP           = FCMP_s,
    890   FCMP_s_zero    = FPCompareFixed | 0x00000008,
    891   FCMP_d_zero    = FPCompareFixed | FP64 | 0x00000008,
    892   FCMP_zero      = FCMP_s_zero,
    893   FCMPE_s        = FPCompareFixed | 0x00000010,
    894   FCMPE_d        = FPCompareFixed | FP64 | 0x00000010,
    895   FCMPE_s_zero   = FPCompareFixed | 0x00000018,
    896   FCMPE_d_zero   = FPCompareFixed | FP64 | 0x00000018
    897 };
    898 
    899 // Floating point conditional compare.
    900 enum FPConditionalCompareOp {
    901   FPConditionalCompareFixed = 0x1E200400,
    902   FPConditionalCompareFMask = 0x5F200C00,
    903   FPConditionalCompareMask  = 0xFFE00C10,
    904   FCCMP_s                   = FPConditionalCompareFixed | 0x00000000,
    905   FCCMP_d                   = FPConditionalCompareFixed | FP64 | 0x00000000,
    906   FCCMP                     = FCCMP_s,
    907   FCCMPE_s                  = FPConditionalCompareFixed | 0x00000010,
    908   FCCMPE_d                  = FPConditionalCompareFixed | FP64 | 0x00000010,
    909   FCCMPE                    = FCCMPE_s
    910 };
    911 
    912 // Floating point conditional select.
    913 enum FPConditionalSelectOp {
    914   FPConditionalSelectFixed = 0x1E200C00,
    915   FPConditionalSelectFMask = 0x5F200C00,
    916   FPConditionalSelectMask  = 0xFFE00C00,
    917   FCSEL_s                  = FPConditionalSelectFixed | 0x00000000,
    918   FCSEL_d                  = FPConditionalSelectFixed | FP64 | 0x00000000,
    919   FCSEL                    = FCSEL_s
    920 };
    921 
    922 // Floating point immediate.
    923 enum FPImmediateOp {
    924   FPImmediateFixed = 0x1E201000,
    925   FPImmediateFMask = 0x5F201C00,
    926   FPImmediateMask  = 0xFFE01C00,
    927   FMOV_s_imm       = FPImmediateFixed | 0x00000000,
    928   FMOV_d_imm       = FPImmediateFixed | FP64 | 0x00000000
    929 };
    930 
    931 // Floating point data processing 1 source.
    932 enum FPDataProcessing1SourceOp {
    933   FPDataProcessing1SourceFixed = 0x1E204000,
    934   FPDataProcessing1SourceFMask = 0x5F207C00,
    935   FPDataProcessing1SourceMask  = 0xFFFFFC00,
    936   FMOV_s   = FPDataProcessing1SourceFixed | 0x00000000,
    937   FMOV_d   = FPDataProcessing1SourceFixed | FP64 | 0x00000000,
    938   FMOV     = FMOV_s,
    939   FABS_s   = FPDataProcessing1SourceFixed | 0x00008000,
    940   FABS_d   = FPDataProcessing1SourceFixed | FP64 | 0x00008000,
    941   FABS     = FABS_s,
    942   FNEG_s   = FPDataProcessing1SourceFixed | 0x00010000,
    943   FNEG_d   = FPDataProcessing1SourceFixed | FP64 | 0x00010000,
    944   FNEG     = FNEG_s,
    945   FSQRT_s  = FPDataProcessing1SourceFixed | 0x00018000,
    946   FSQRT_d  = FPDataProcessing1SourceFixed | FP64 | 0x00018000,
    947   FSQRT    = FSQRT_s,
    948   FCVT_ds  = FPDataProcessing1SourceFixed | 0x00028000,
    949   FCVT_sd  = FPDataProcessing1SourceFixed | FP64 | 0x00020000,
    950   FRINTN_s = FPDataProcessing1SourceFixed | 0x00040000,
    951   FRINTN_d = FPDataProcessing1SourceFixed | FP64 | 0x00040000,
    952   FRINTN   = FRINTN_s,
    953   FRINTP_s = FPDataProcessing1SourceFixed | 0x00048000,
    954   FRINTP_d = FPDataProcessing1SourceFixed | FP64 | 0x00048000,
    955   FRINTP   = FRINTP_s,
    956   FRINTM_s = FPDataProcessing1SourceFixed | 0x00050000,
    957   FRINTM_d = FPDataProcessing1SourceFixed | FP64 | 0x00050000,
    958   FRINTM   = FRINTM_s,
    959   FRINTZ_s = FPDataProcessing1SourceFixed | 0x00058000,
    960   FRINTZ_d = FPDataProcessing1SourceFixed | FP64 | 0x00058000,
    961   FRINTZ   = FRINTZ_s,
    962   FRINTA_s = FPDataProcessing1SourceFixed | 0x00060000,
    963   FRINTA_d = FPDataProcessing1SourceFixed | FP64 | 0x00060000,
    964   FRINTA   = FRINTA_s,
    965   FRINTX_s = FPDataProcessing1SourceFixed | 0x00070000,
    966   FRINTX_d = FPDataProcessing1SourceFixed | FP64 | 0x00070000,
    967   FRINTX   = FRINTX_s,
    968   FRINTI_s = FPDataProcessing1SourceFixed | 0x00078000,
    969   FRINTI_d = FPDataProcessing1SourceFixed | FP64 | 0x00078000,
    970   FRINTI   = FRINTI_s
    971 };
    972 
    973 // Floating point data processing 2 source.
    974 enum FPDataProcessing2SourceOp {
    975   FPDataProcessing2SourceFixed = 0x1E200800,
    976   FPDataProcessing2SourceFMask = 0x5F200C00,
    977   FPDataProcessing2SourceMask  = 0xFFE0FC00,
    978   FMUL     = FPDataProcessing2SourceFixed | 0x00000000,
    979   FMUL_s   = FMUL,
    980   FMUL_d   = FMUL | FP64,
    981   FDIV     = FPDataProcessing2SourceFixed | 0x00001000,
    982   FDIV_s   = FDIV,
    983   FDIV_d   = FDIV | FP64,
    984   FADD     = FPDataProcessing2SourceFixed | 0x00002000,
    985   FADD_s   = FADD,
    986   FADD_d   = FADD | FP64,
    987   FSUB     = FPDataProcessing2SourceFixed | 0x00003000,
    988   FSUB_s   = FSUB,
    989   FSUB_d   = FSUB | FP64,
    990   FMAX     = FPDataProcessing2SourceFixed | 0x00004000,
    991   FMAX_s   = FMAX,
    992   FMAX_d   = FMAX | FP64,
    993   FMIN     = FPDataProcessing2SourceFixed | 0x00005000,
    994   FMIN_s   = FMIN,
    995   FMIN_d   = FMIN | FP64,
    996   FMAXNM   = FPDataProcessing2SourceFixed | 0x00006000,
    997   FMAXNM_s = FMAXNM,
    998   FMAXNM_d = FMAXNM | FP64,
    999   FMINNM   = FPDataProcessing2SourceFixed | 0x00007000,
   1000   FMINNM_s = FMINNM,
   1001   FMINNM_d = FMINNM | FP64,
   1002   FNMUL    = FPDataProcessing2SourceFixed | 0x00008000,
   1003   FNMUL_s  = FNMUL,
   1004   FNMUL_d  = FNMUL | FP64
   1005 };
   1006 
   1007 // Floating point data processing 3 source.
   1008 enum FPDataProcessing3SourceOp {
   1009   FPDataProcessing3SourceFixed = 0x1F000000,
   1010   FPDataProcessing3SourceFMask = 0x5F000000,
   1011   FPDataProcessing3SourceMask  = 0xFFE08000,
   1012   FMADD_s                      = FPDataProcessing3SourceFixed | 0x00000000,
   1013   FMSUB_s                      = FPDataProcessing3SourceFixed | 0x00008000,
   1014   FNMADD_s                     = FPDataProcessing3SourceFixed | 0x00200000,
   1015   FNMSUB_s                     = FPDataProcessing3SourceFixed | 0x00208000,
   1016   FMADD_d                      = FPDataProcessing3SourceFixed | 0x00400000,
   1017   FMSUB_d                      = FPDataProcessing3SourceFixed | 0x00408000,
   1018   FNMADD_d                     = FPDataProcessing3SourceFixed | 0x00600000,
   1019   FNMSUB_d                     = FPDataProcessing3SourceFixed | 0x00608000
   1020 };
   1021 
   1022 // Conversion between floating point and integer.
   1023 enum FPIntegerConvertOp {
   1024   FPIntegerConvertFixed = 0x1E200000,
   1025   FPIntegerConvertFMask = 0x5F20FC00,
   1026   FPIntegerConvertMask  = 0xFFFFFC00,
   1027   FCVTNS    = FPIntegerConvertFixed | 0x00000000,
   1028   FCVTNS_ws = FCVTNS,
   1029   FCVTNS_xs = FCVTNS | SixtyFourBits,
   1030   FCVTNS_wd = FCVTNS | FP64,
   1031   FCVTNS_xd = FCVTNS | SixtyFourBits | FP64,
   1032   FCVTNU    = FPIntegerConvertFixed | 0x00010000,
   1033   FCVTNU_ws = FCVTNU,
   1034   FCVTNU_xs = FCVTNU | SixtyFourBits,
   1035   FCVTNU_wd = FCVTNU | FP64,
   1036   FCVTNU_xd = FCVTNU | SixtyFourBits | FP64,
   1037   FCVTPS    = FPIntegerConvertFixed | 0x00080000,
   1038   FCVTPS_ws = FCVTPS,
   1039   FCVTPS_xs = FCVTPS | SixtyFourBits,
   1040   FCVTPS_wd = FCVTPS | FP64,
   1041   FCVTPS_xd = FCVTPS | SixtyFourBits | FP64,
   1042   FCVTPU    = FPIntegerConvertFixed | 0x00090000,
   1043   FCVTPU_ws = FCVTPU,
   1044   FCVTPU_xs = FCVTPU | SixtyFourBits,
   1045   FCVTPU_wd = FCVTPU | FP64,
   1046   FCVTPU_xd = FCVTPU | SixtyFourBits | FP64,
   1047   FCVTMS    = FPIntegerConvertFixed | 0x00100000,
   1048   FCVTMS_ws = FCVTMS,
   1049   FCVTMS_xs = FCVTMS | SixtyFourBits,
   1050   FCVTMS_wd = FCVTMS | FP64,
   1051   FCVTMS_xd = FCVTMS | SixtyFourBits | FP64,
   1052   FCVTMU    = FPIntegerConvertFixed | 0x00110000,
   1053   FCVTMU_ws = FCVTMU,
   1054   FCVTMU_xs = FCVTMU | SixtyFourBits,
   1055   FCVTMU_wd = FCVTMU | FP64,
   1056   FCVTMU_xd = FCVTMU | SixtyFourBits | FP64,
   1057   FCVTZS    = FPIntegerConvertFixed | 0x00180000,
   1058   FCVTZS_ws = FCVTZS,
   1059   FCVTZS_xs = FCVTZS | SixtyFourBits,
   1060   FCVTZS_wd = FCVTZS | FP64,
   1061   FCVTZS_xd = FCVTZS | SixtyFourBits | FP64,
   1062   FCVTZU    = FPIntegerConvertFixed | 0x00190000,
   1063   FCVTZU_ws = FCVTZU,
   1064   FCVTZU_xs = FCVTZU | SixtyFourBits,
   1065   FCVTZU_wd = FCVTZU | FP64,
   1066   FCVTZU_xd = FCVTZU | SixtyFourBits | FP64,
   1067   SCVTF     = FPIntegerConvertFixed | 0x00020000,
   1068   SCVTF_sw  = SCVTF,
   1069   SCVTF_sx  = SCVTF | SixtyFourBits,
   1070   SCVTF_dw  = SCVTF | FP64,
   1071   SCVTF_dx  = SCVTF | SixtyFourBits | FP64,
   1072   UCVTF     = FPIntegerConvertFixed | 0x00030000,
   1073   UCVTF_sw  = UCVTF,
   1074   UCVTF_sx  = UCVTF | SixtyFourBits,
   1075   UCVTF_dw  = UCVTF | FP64,
   1076   UCVTF_dx  = UCVTF | SixtyFourBits | FP64,
   1077   FCVTAS    = FPIntegerConvertFixed | 0x00040000,
   1078   FCVTAS_ws = FCVTAS,
   1079   FCVTAS_xs = FCVTAS | SixtyFourBits,
   1080   FCVTAS_wd = FCVTAS | FP64,
   1081   FCVTAS_xd = FCVTAS | SixtyFourBits | FP64,
   1082   FCVTAU    = FPIntegerConvertFixed | 0x00050000,
   1083   FCVTAU_ws = FCVTAU,
   1084   FCVTAU_xs = FCVTAU | SixtyFourBits,
   1085   FCVTAU_wd = FCVTAU | FP64,
   1086   FCVTAU_xd = FCVTAU | SixtyFourBits | FP64,
   1087   FMOV_ws   = FPIntegerConvertFixed | 0x00060000,
   1088   FMOV_sw   = FPIntegerConvertFixed | 0x00070000,
   1089   FMOV_xd   = FMOV_ws | SixtyFourBits | FP64,
   1090   FMOV_dx   = FMOV_sw | SixtyFourBits | FP64
   1091 };
   1092 
   1093 // Conversion between fixed point and floating point.
   1094 enum FPFixedPointConvertOp {
   1095   FPFixedPointConvertFixed = 0x1E000000,
   1096   FPFixedPointConvertFMask = 0x5F200000,
   1097   FPFixedPointConvertMask  = 0xFFFF0000,
   1098   FCVTZS_fixed    = FPFixedPointConvertFixed | 0x00180000,
   1099   FCVTZS_ws_fixed = FCVTZS_fixed,
   1100   FCVTZS_xs_fixed = FCVTZS_fixed | SixtyFourBits,
   1101   FCVTZS_wd_fixed = FCVTZS_fixed | FP64,
   1102   FCVTZS_xd_fixed = FCVTZS_fixed | SixtyFourBits | FP64,
   1103   FCVTZU_fixed    = FPFixedPointConvertFixed | 0x00190000,
   1104   FCVTZU_ws_fixed = FCVTZU_fixed,
   1105   FCVTZU_xs_fixed = FCVTZU_fixed | SixtyFourBits,
   1106   FCVTZU_wd_fixed = FCVTZU_fixed | FP64,
   1107   FCVTZU_xd_fixed = FCVTZU_fixed | SixtyFourBits | FP64,
   1108   SCVTF_fixed     = FPFixedPointConvertFixed | 0x00020000,
   1109   SCVTF_sw_fixed  = SCVTF_fixed,
   1110   SCVTF_sx_fixed  = SCVTF_fixed | SixtyFourBits,
   1111   SCVTF_dw_fixed  = SCVTF_fixed | FP64,
   1112   SCVTF_dx_fixed  = SCVTF_fixed | SixtyFourBits | FP64,
   1113   UCVTF_fixed     = FPFixedPointConvertFixed | 0x00030000,
   1114   UCVTF_sw_fixed  = UCVTF_fixed,
   1115   UCVTF_sx_fixed  = UCVTF_fixed | SixtyFourBits,
   1116   UCVTF_dw_fixed  = UCVTF_fixed | FP64,
   1117   UCVTF_dx_fixed  = UCVTF_fixed | SixtyFourBits | FP64
   1118 };
   1119 
   1120 // Unimplemented and unallocated instructions. These are defined to make fixed
   1121 // bit assertion easier.
   1122 enum UnimplementedOp {
   1123   UnimplementedFixed = 0x00000000,
   1124   UnimplementedFMask = 0x00000000
   1125 };
   1126 
   1127 enum UnallocatedOp {
   1128   UnallocatedFixed = 0x00000000,
   1129   UnallocatedFMask = 0x00000000
   1130 };
   1131 
   1132 }  // namespace vixl
   1133 
   1134 #endif  // VIXL_A64_CONSTANTS_A64_H_
   1135