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