174f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#ifndef V8_ARM_CONSTANTS_ARM_H_
65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#define V8_ARM_CONSTANTS_ARM_H_
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// ARM EABI is required.
944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#if defined(__arm__) && !defined(__ARM_EABI__)
1044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#error ARM EABI support is required.
11eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif
12eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
13378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgnamespace v8 {
14378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgnamespace internal {
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Constant pool marker.
1772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org// Use UDF, the permanently undefined instruction.
1872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgconst int kConstantPoolMarkerMask = 0xfff000f0;
1972204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgconst int kConstantPoolMarker = 0xe7f000f0;
2072204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgconst int kConstantPoolLengthMaxMask = 0xffff;
2172204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orginline int EncodeConstantPoolLength(int length) {
22e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((length & kConstantPoolLengthMaxMask) == length);
2372204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return ((length & 0xfff0) << 4) | (length & 0xf);
2472204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
2572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orginline int DecodeConstantPoolLength(int instr) {
26e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((instr & kConstantPoolMarkerMask) == kConstantPoolMarker);
2772204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org  return ((instr >> 4) & 0xfff0) | (instr & 0xf);
2872204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.org}
29ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
30c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org// Used in code age prologue - ldr(pc, MemOperand(pc, -4))
31c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.orgconst int kCodeAgeJumpInstruction = 0xe51ff004;
32c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org
33a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// Number of registers in normal ARM mode.
341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kNumRegisters = 16;
35a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
36c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// VFP support.
371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kNumVFPSingleRegisters = 32;
38003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgconst int kNumVFPDoubleRegisters = 32;
391b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kNumVFPRegisters = kNumVFPSingleRegisters + kNumVFPDoubleRegisters;
40c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
41a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// PC is register 15.
421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kPCRegister = 15;
431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kNoRegister = -1;
44a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
45378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// -----------------------------------------------------------------------------
46378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Conditions.
47378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Defines constants and accessor classes to assemble, disassemble and
4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// simulate ARM instructions.
5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
513bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// Section references in the code refer to the "ARM Architecture Reference
523bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
533bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org//
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Constants for specific fields are defined in their respective named enums.
5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// General constants are in an anonymous enum in class Instr.
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
573bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// Values for the condition field as defined in section A3.2
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum Condition {
59378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kNoCondition = -1,
60378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
61378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  eq =  0 << 28,                 // Z set            Equal.
62378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ne =  1 << 28,                 // Z clear          Not equal.
63378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  cs =  2 << 28,                 // C set            Unsigned higher or same.
64378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  cc =  3 << 28,                 // C clear          Unsigned lower.
65378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  mi =  4 << 28,                 // N set            Negative.
66378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  pl =  5 << 28,                 // N clear          Positive or zero.
67378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  vs =  6 << 28,                 // V set            Overflow.
68378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  vc =  7 << 28,                 // V clear          No overflow.
69378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  hi =  8 << 28,                 // C set, Z clear   Unsigned higher.
70378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ls =  9 << 28,                 // C clear or Z set Unsigned lower or same.
71378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ge = 10 << 28,                 // N == V           Greater or equal.
72378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  lt = 11 << 28,                 // N != V           Less than.
73378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  gt = 12 << 28,                 // Z clear, N == V  Greater than.
74378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  le = 13 << 28,                 // Z set or N != V  Less then or equal
75378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  al = 14 << 28,                 //                  Always.
76378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
77378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kSpecialCondition = 15 << 28,  // Special condition (refer to section A3.2.1).
78378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kNumberOfConditions = 16,
79378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
80378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Aliases.
81378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  hs = cs,                       // C set            Unsigned higher or same.
82378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  lo = cc                        // C clear          Unsigned lower.
8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
86378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orginline Condition NegateCondition(Condition cond) {
87e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(cond != al);
88378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  return static_cast<Condition>(cond ^ ne);
89378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
90378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
91378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
921e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org// Commute a condition such that {a cond b == b cond' a}.
9338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orginline Condition CommuteCondition(Condition cond) {
94378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  switch (cond) {
95378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case lo:
96378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return hi;
97378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case hi:
98378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return lo;
99378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case hs:
100378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return ls;
101378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case ls:
102378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return hs;
103378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case lt:
104378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return gt;
105378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case gt:
106378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return lt;
107378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case ge:
108378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return le;
109378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    case le:
110378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return ge;
111378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    default:
112378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return cond;
1133c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
114378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org}
115378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
116378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
117378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// -----------------------------------------------------------------------------
118378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Instructions encoding.
119378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
120378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Instr is merely used by the Assembler to distinguish 32bit integers
121378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// representing instructions from usual 32 bit values.
122378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Instruction objects are pointers to 32bit values, and provide methods to
123378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// access the various ISA fields.
124378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgtypedef int32_t Instr;
125378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
126378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
1273bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
1283bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// as defined in section A3.4
12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum Opcode {
130378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  AND =  0 << 21,  // Logical AND.
131378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  EOR =  1 << 21,  // Logical Exclusive OR.
132378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SUB =  2 << 21,  // Subtract.
133378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  RSB =  3 << 21,  // Reverse Subtract.
134378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ADD =  4 << 21,  // Add.
135378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ADC =  5 << 21,  // Add with Carry.
136378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SBC =  6 << 21,  // Subtract with Carry.
137378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  RSC =  7 << 21,  // Reverse Subtract with Carry.
138378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  TST =  8 << 21,  // Test.
139378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  TEQ =  9 << 21,  // Test Equivalence.
140378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CMP = 10 << 21,  // Compare.
141378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CMN = 11 << 21,  // Compare Negated.
142378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ORR = 12 << 21,  // Logical (inclusive) OR.
143378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  MOV = 13 << 21,  // Move.
144378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  BIC = 14 << 21,  // Bit Clear.
145378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  MVN = 15 << 21   // Move Not.
14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
14743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
149357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org// The bits for bit 7-4 for some type 0 miscellaneous instructions.
150357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.orgenum MiscInstructionsBits74 {
151357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // With bits 22-21 01.
152378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  BX   =  1 << 4,
153378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  BXJ  =  2 << 4,
154378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  BLX  =  3 << 4,
155378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  BKPT =  7 << 4,
1562abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
157357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // With bits 22-21 11.
158378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CLZ  =  1 << 4
159378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
160378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
161378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
162378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Instruction encoding bits and masks.
163378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum {
164378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  H   = 1 << 5,   // Halfword (or byte).
165378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  S6  = 1 << 6,   // Signed (or unsigned).
166378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  L   = 1 << 20,  // Load (or store).
167378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  S   = 1 << 20,  // Set condition code (or leave unchanged).
168378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  W   = 1 << 21,  // Writeback base register (or leave unchanged).
169378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  A   = 1 << 21,  // Accumulate in multiply instruction (or not).
170378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B   = 1 << 22,  // Unsigned byte (or word).
171378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  N   = 1 << 22,  // Long (or short).
172378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  U   = 1 << 23,  // Positive (or negative) offset/index.
173378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  P   = 1 << 24,  // Offset/pre-indexed addressing (or post-indexed addressing).
174378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  I   = 1 << 25,  // Immediate shifter operand (or not).
175378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
176378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B4  = 1 << 4,
177378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B5  = 1 << 5,
178378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B6  = 1 << 6,
179378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B7  = 1 << 7,
180378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B8  = 1 << 8,
181378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B9  = 1 << 9,
182378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B12 = 1 << 12,
183378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B16 = 1 << 16,
184378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B18 = 1 << 18,
185378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B19 = 1 << 19,
186378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B20 = 1 << 20,
187378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B21 = 1 << 21,
188378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B22 = 1 << 22,
189378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B23 = 1 << 23,
190378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B24 = 1 << 24,
191378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B25 = 1 << 25,
192378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B26 = 1 << 26,
193378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B27 = 1 << 27,
194378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  B28 = 1 << 28,
195378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
196378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Instruction bit masks.
197378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kCondMask   = 15 << 28,
198378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kALUMask    = 0x6f << 21,
199378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kRdMask     = 15 << 12,  // In str instruction.
200378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kCoprocessorMask = 15 << 8,
201378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kOpCodeMask = 15 << 21,  // In data-processing instructions.
202378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kImm24Mask  = (1 << 24) - 1,
2034a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  kImm16Mask  = (1 << 16) - 1,
2044a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  kImm8Mask  = (1 << 8) - 1,
2054cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  kOff12Mask  = (1 << 12) - 1,
2064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  kOff8Mask  = (1 << 8) - 1
207378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
208378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
209378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
210378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// -----------------------------------------------------------------------------
211378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Addressing modes and instruction variants.
212378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
213378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Condition code updating mode.
214378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum SBit {
215378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SetCC   = 1 << 20,  // Set condition code.
216378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  LeaveCC = 0 << 20   // Leave condition code unchanged.
217378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
218378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
219378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
220378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Status register selection.
221378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum SRegister {
222378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CPSR = 0 << 22,
223378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SPSR = 1 << 22
2242abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org};
2252abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
2262abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org
2273bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// Shifter types for Data-processing operands as defined in section A5.1.2.
228378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum ShiftOp {
229378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  LSL = 0 << 5,   // Logical shift left.
230378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  LSR = 1 << 5,   // Logical shift right.
231378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ASR = 2 << 5,   // Arithmetic shift right.
232378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ROR = 3 << 5,   // Rotate right.
233378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
234378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // RRX is encoded as ROR with shift_imm == 0.
235378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Use a special code to make the distinction. The RRX ShiftOp is only used
236378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // as an argument, and will never actually be encoded. The Assembler will
237378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // detect it and emit the correct ROR shift operand with shift_imm == 0.
238378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  RRX = -1,
239378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kNumberOfShifts = 4
240378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
241378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
242378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
243378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Status register fields.
244378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum SRegisterField {
245378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CPSR_c = CPSR | 1 << 16,
246378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CPSR_x = CPSR | 1 << 17,
247378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CPSR_s = CPSR | 1 << 18,
248378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  CPSR_f = CPSR | 1 << 19,
249378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SPSR_c = SPSR | 1 << 16,
250378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SPSR_x = SPSR | 1 << 17,
251378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SPSR_s = SPSR | 1 << 18,
252378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  SPSR_f = SPSR | 1 << 19
25343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
25443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
255378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Status register field mask (or'ed SRegisterField enum values).
256378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgtypedef uint32_t SRegisterFieldMask;
257378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
258378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
259378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Memory operand addressing mode.
260378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum AddrMode {
261378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Bit encoding P U W.
262378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  Offset       = (8|4|0) << 21,  // Offset (without writeback to base).
263378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  PreIndex     = (8|4|1) << 21,  // Pre-indexed addressing with writeback.
264378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  PostIndex    = (0|4|0) << 21,  // Post-indexed addressing with writeback.
265378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  NegOffset    = (8|0|0) << 21,  // Negative offset (without writeback to base).
266378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  NegPreIndex  = (8|0|1) << 21,  // Negative pre-indexed with writeback.
267378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  NegPostIndex = (0|0|0) << 21   // Negative post-indexed with writeback.
268378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
269378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
270378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
271378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Load/store multiple addressing mode.
272378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum BlockAddrMode {
273378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Bit encoding P U W .
274378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  da           = (0|0|0) << 21,  // Decrement after.
275378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ia           = (0|4|0) << 21,  // Increment after.
276378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  db           = (8|0|0) << 21,  // Decrement before.
277378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ib           = (8|4|0) << 21,  // Increment before.
278378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  da_w         = (0|0|1) << 21,  // Decrement after with writeback to base.
279378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ia_w         = (0|4|1) << 21,  // Increment after with writeback to base.
280378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  db_w         = (8|0|1) << 21,  // Decrement before with writeback to base.
281378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ib_w         = (8|4|1) << 21,  // Increment before with writeback to base.
282378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
283378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Alias modes for comparison when writeback does not matter.
284378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  da_x         = (0|0|0) << 21,  // Decrement after.
285378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  ia_x         = (0|4|0) << 21,  // Increment after.
286378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  db_x         = (8|0|0) << 21,  // Decrement before.
28774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  ib_x         = (8|4|0) << 21,  // Increment before.
28874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
28974f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  kBlockAddrModeMask = (8|4|1) << 21
290378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
291378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
292378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
293378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Coprocessor load/store operand size.
294378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum LFlag {
295378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  Long  = 1 << 22,  // Long load/store coprocessor.
296378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  Short = 0 << 22   // Short load/store coprocessor.
297378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org};
298378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
299378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
300169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org// NEON data type
301169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgenum NeonDataType {
302169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonS8 = 0x1,   // U = 0, imm3 = 0b001
303169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonS16 = 0x2,  // U = 0, imm3 = 0b010
304169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonS32 = 0x4,  // U = 0, imm3 = 0b100
305169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonU8 = 1 << 24 | 0x1,   // U = 1, imm3 = 0b001
306169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonU16 = 1 << 24 | 0x2,  // U = 1, imm3 = 0b010
307169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonU32 = 1 << 24 | 0x4,   // U = 1, imm3 = 0b100
308169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonDataTypeSizeMask = 0x7,
309169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  NeonDataTypeUMask = 1 << 24
310169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
311169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
312169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgenum NeonListType {
313169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  nlt_1 = 0x7,
314169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  nlt_2 = 0xA,
315169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  nlt_3 = 0x6,
316169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  nlt_4 = 0x2
317169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
318169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
319169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.orgenum NeonSize {
320169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Neon8 = 0x0,
321169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Neon16 = 0x1,
322169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  Neon32 = 0x2,
323a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  Neon64 = 0x3
324169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org};
325169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org
326378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// -----------------------------------------------------------------------------
327378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Supervisor Call (svc) specific support.
32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3293bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// Special Software Interrupt codes when used in the presence of the ARM
3303bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// simulator.
331e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// svc (formerly swi) provides a 24bit immediate value. Use bits 22:0 for
332e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature.
33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenenum SoftwareInterruptCodes {
33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // transition to C code
335378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kCallRtRedirected= 0x10,
33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // break point
337378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kBreakpoint= 0x20,
338e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // stop
339378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  kStopCode = 1 << 23
34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
3411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kStopCodeMask = kStopCode - 1;
3421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kMaxStopCode = kStopCode - 1;
3431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int32_t  kDefaultStopCode = -1;
34443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
346d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org// Type of VFP register. Determines register encoding.
347d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgenum VFPRegPrecision {
348d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  kSinglePrecision = 0,
349d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  kDoublePrecision = 1
350d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org};
351d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
352378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
353378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// VFP FPSCR constants.
35483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgenum VFPConversionMode {
35583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  kFPSCRRounding = 0,
35683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  kDefaultRoundToZero = 1
35783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org};
35883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
3599ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org// This mask does not include the "inexact" or "input denormal" cumulative
3609ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org// exceptions flags, because we usually don't want to check for it.
3611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPExceptionMask = 0xf;
3621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPInvalidOpExceptionBit = 1 << 0;
3631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPOverflowExceptionBit = 1 << 2;
3641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPUnderflowExceptionBit = 1 << 3;
3651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPInexactExceptionBit = 1 << 4;
3661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPFlushToZeroMask = 1 << 24;
367e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgconst uint32_t kVFPDefaultNaNModeControlBit = 1 << 25;
368378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
3691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPNConditionFlagBit = 1 << 31;
3701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPZConditionFlagBit = 1 << 30;
3711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPCConditionFlagBit = 1 << 29;
3721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPVConditionFlagBit = 1 << 28;
373378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
374378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
37501fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org// VFP rounding modes. See ARM DDI 0406B Page A2-29.
37683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgenum VFPRoundingMode {
37783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  RN = 0 << 22,   // Round to Nearest.
37883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  RP = 1 << 22,   // Round towards Plus Infinity.
37983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  RM = 2 << 22,   // Round towards Minus Infinity.
38083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  RZ = 3 << 22,   // Round towards zero.
38183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
38283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // Aliases.
38383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  kRoundToNearest = RN,
38483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  kRoundToPlusInf = RP,
38583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  kRoundToMinusInf = RM,
38683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  kRoundToZero = RZ
38701fe7df37ce9858e3d0069ec6a2d7c667256b95aager@chromium.org};
388d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
3891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst uint32_t kVFPRoundingModeMask = 3 << 22;
39043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3919ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgenum CheckForInexactConversion {
3929ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  kCheckForInexactConversion,
3939ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  kDontCheckForInexactConversion
3949ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org};
3959ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
396378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// -----------------------------------------------------------------------------
397378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Hints.
398378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
399378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Branch hints are not used on the ARM.  They are defined so that they can
400378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// appear in shared function signatures, but will be ignored in ARM
401378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// implementations.
402378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgenum Hint { no_hint };
403378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
404378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Hints are not used on the arm.  Negating is trivial.
405378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orginline Hint NegateHint(Hint ignored) { return no_hint; }
406378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
407378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
408378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// -----------------------------------------------------------------------------
409378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Instruction abstraction.
410378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
411378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// The class Instruction enables access to individual fields defined in the ARM
4123bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// architecture instruction set encoding as described in figure A3-1.
413378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org// Note that the Assembler uses typedef int32_t Instr.
4143bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org//
4153bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// Example: Test whether the instruction at ptr does set the condition code
4163bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// bits.
4173bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org//
4183bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// bool InstructionSetsConditionCodes(byte* ptr) {
419378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org//   Instruction* instr = Instruction::At(ptr);
420378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org//   int type = instr->TypeValue();
4213bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org//   return ((type == 0) || (type == 1)) && instr->HasS();
4223bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org// }
4233bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org//
424378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.orgclass Instruction {
42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  enum {
42743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    kInstrSize = 4,
4288bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    kInstrSizeLog2 = 2,
42943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    kPCReadOffset = 8
43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  };
43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
432378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Helper macro to define static accessors.
433378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // We use the cast to char* trick to bypass the strict anti-aliasing rules.
434378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  #define DECLARE_STATIC_TYPED_ACCESSOR(return_type, Name)                     \
435378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    static inline return_type Name(Instr instr) {                              \
436378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      char* temp = reinterpret_cast<char*>(&instr);                            \
437378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return reinterpret_cast<Instruction*>(temp)->Name();                     \
438378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    }
439378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
440378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  #define DECLARE_STATIC_ACCESSOR(Name) DECLARE_STATIC_TYPED_ACCESSOR(int, Name)
441378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
4423bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  // Get the raw instruction bits.
443378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline Instr InstructionBits() const {
444378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return *reinterpret_cast<const Instr*>(this);
44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4473bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  // Set the raw instruction bits to value.
448378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline void SetInstructionBits(Instr value) {
449378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    *reinterpret_cast<Instr*>(this) = value;
45043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
45143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4523bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  // Read one particular bit out of the instruction bits.
45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline int Bit(int nr) const {
45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return (InstructionBits() >> nr) & 1;
45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
457378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Read a bit field's value out of the instruction bits.
45843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline int Bits(int hi, int lo) const {
45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
46043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
46143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
462378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Read a bit field out of the instruction bits.
463378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int BitField(int hi, int lo) const {
464378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return InstructionBits() & (((2 << (hi - lo)) - 1) << lo);
465378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
466378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
467378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Static support.
468378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
469378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Read one particular bit out of the instruction bits.
470378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  static inline int Bit(Instr instr, int nr) {
471378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return (instr >> nr) & 1;
472378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
473378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
474378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Read the value of a bit field out of the instruction bits.
475378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  static inline int Bits(Instr instr, int hi, int lo) {
476378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return (instr >> lo) & ((2 << (hi - lo)) - 1);
477378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
478378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
479378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
480378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Read a bit field out of the instruction bits.
481378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  static inline int BitField(Instr instr, int hi, int lo) {
482378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return instr & (((2 << (hi - lo)) - 1) << lo);
483378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
484378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Accessors for the different named fields used in the ARM encoding.
4873bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org  // The naming of these accessor corresponds to figure A3-1.
488378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  //
489378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Two kind of accessors are declared:
4902efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // - <Name>Field() will return the raw field, i.e. the field's bits at their
491378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  //   original place in the instruction encoding.
4922efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  //   e.g. if instr is the 'addgt r0, r1, r2' instruction, encoded as
4932efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  //   0xC0810002 ConditionField(instr) will return 0xC0000000.
494378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // - <Name>Value() will return the field value, shifted back to bit 0.
4952efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  //   e.g. if instr is the 'addgt r0, r1, r2' instruction, encoded as
4962efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  //   0xC0810002 ConditionField(instr) will return 0xC.
497378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
498378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
49943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Generally applicable fields
500378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline Condition ConditionValue() const {
50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return static_cast<Condition>(Bits(31, 28));
50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
503378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline Condition ConditionField() const {
504378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return static_cast<Condition>(BitField(31, 28));
505378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
506378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionValue);
507378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionField);
50843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
509378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int TypeValue() const { return Bits(27, 25); }
510169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org  inline int SpecialValue() const { return Bits(27, 23); }
51143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
512378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RnValue() const { return Bits(19, 16); }
513496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  DECLARE_STATIC_ACCESSOR(RnValue);
514378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RdValue() const { return Bits(15, 12); }
515378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  DECLARE_STATIC_ACCESSOR(RdValue);
516378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
517378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int CoprocessorValue() const { return Bits(11, 8); }
518c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Support for VFP.
519c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Vn(19-16) | Vd(15-12) |  Vm(3-0)
520378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VnValue() const { return Bits(19, 16); }
521378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VmValue() const { return Bits(3, 0); }
522378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VdValue() const { return Bits(15, 12); }
523378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int NValue() const { return Bit(7); }
524378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int MValue() const { return Bit(5); }
525378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int DValue() const { return Bit(22); }
526378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RtValue() const { return Bits(15, 12); }
527378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int PValue() const { return Bit(24); }
528378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int UValue() const { return Bit(23); }
529378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int Opc1Value() const { return (Bit(23) << 2) | Bits(21, 20); }
530378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int Opc2Value() const { return Bits(19, 16); }
531378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int Opc3Value() const { return Bits(7, 6); }
532378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int SzValue() const { return Bit(8); }
533378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VLValue() const { return Bit(20); }
534378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VCValue() const { return Bit(8); }
535378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VAValue() const { return Bits(23, 21); }
536378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VBValue() const { return Bits(6, 5); }
537378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VFPNRegValue(VFPRegPrecision pre) {
538378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return VFPGlueRegValue(pre, 16, 7);
539d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
540378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VFPMRegValue(VFPRegPrecision pre) {
541378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return VFPGlueRegValue(pre, 0, 5);
542d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
543378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VFPDRegValue(VFPRegPrecision pre) {
544378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return VFPGlueRegValue(pre, 12, 22);
545d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
546c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fields used in Data processing instructions
548378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int OpcodeValue() const {
54943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return static_cast<Opcode>(Bits(24, 21));
55043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
551378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline Opcode OpcodeField() const {
552378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return static_cast<Opcode>(BitField(24, 21));
553378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
554378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int SValue() const { return Bit(20); }
55543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // with register
556378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RmValue() const { return Bits(3, 0); }
557496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  DECLARE_STATIC_ACCESSOR(RmValue);
558378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int ShiftValue() const { return static_cast<ShiftOp>(Bits(6, 5)); }
559378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline ShiftOp ShiftField() const {
560378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return static_cast<ShiftOp>(BitField(6, 5));
561378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
562378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RegShiftValue() const { return Bit(4); }
563378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RsValue() const { return Bits(11, 8); }
564378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int ShiftAmountValue() const { return Bits(11, 7); }
56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // with immediate
566378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RotateValue() const { return Bits(11, 8); }
567a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DECLARE_STATIC_ACCESSOR(RotateValue);
568378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int Immed8Value() const { return Bits(7, 0); }
569a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DECLARE_STATIC_ACCESSOR(Immed8Value);
570378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int Immed4Value() const { return Bits(19, 16); }
571378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int ImmedMovwMovtValue() const {
572378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org      return Immed4Value() << 12 | Offset12Value(); }
573d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  DECLARE_STATIC_ACCESSOR(ImmedMovwMovtValue);
57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fields used in Load/Store instructions
576378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int PUValue() const { return Bits(24, 23); }
577378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int PUField() const { return BitField(24, 23); }
578378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int  BValue() const { return Bit(22); }
579378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int  WValue() const { return Bit(21); }
580378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int  LValue() const { return Bit(20); }
58143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // with register uses same fields as Data processing instructions above
58243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // with immediate
583378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int Offset12Value() const { return Bits(11, 0); }
58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // multiple
585378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int RlistValue() const { return Bits(15, 0); }
58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // extra loads and stores
587378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int SignValue() const { return Bit(6); }
588378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int HValue() const { return Bit(5); }
589378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int ImmedHValue() const { return Bits(11, 8); }
590378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int ImmedLValue() const { return Bits(3, 0); }
59143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
59243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fields used in Branch instructions
593378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int LinkValue() const { return Bit(24); }
594378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int SImmed24Value() const { return ((InstructionBits() << 8) >> 8); }
59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
59643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Fields used in Software interrupt instructions
597378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline SoftwareInterruptCodes SvcValue() const {
59843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
60043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
60143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Test for special encodings of type 0 instructions (extra loads and stores,
60243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // as well as multiplications).
60343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); }
60443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
605357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // Test for miscellaneous instructions encodings of type 0 instructions.
606357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  inline bool IsMiscType0() const { return (Bit(24) == 1)
607357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org                                           && (Bit(23) == 0)
608357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org                                           && (Bit(20) == 0)
609357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org                                           && ((Bit(7) == 0)); }
610357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
61189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  // Test for a nop instruction, which falls under type 1.
61289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  inline bool IsNopType1() const { return Bits(24, 0) == 0x0120F000; }
61389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
6140a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Test for a stop instruction.
6150a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  inline bool IsStop() const {
616378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return (TypeValue() == 7) && (Bit(24) == 1) && (SvcValue() >= kStopCode);
6170a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
6180a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Special accessors that test for existence of a value.
620378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasS()    const { return SValue() == 1; }
621378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasB()    const { return BValue() == 1; }
622378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasW()    const { return WValue() == 1; }
623378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasL()    const { return LValue() == 1; }
624378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasU()    const { return UValue() == 1; }
625378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasSign() const { return SignValue() == 1; }
626378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasH()    const { return HValue() == 1; }
627378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline bool HasLink() const { return LinkValue() == 1; }
62843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6296a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  // Decoding the double immediate in the vmov instruction.
6306a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org  double DoubleImmedVmov() const;
6316a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org
63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Instructions are read of out a code stream. The only way to get a
63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // reference to an instruction is to convert a pointer. There is no way
634378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // to allocate or create instances of class Instruction.
635378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Use the At(pc) function to create references to Instruction.
636378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  static Instruction* At(byte* pc) {
637378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return reinterpret_cast<Instruction*>(pc);
638378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
639378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
64043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
642d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Join split register codes, depending on single or double precision.
643d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // four_bit is the position of the least-significant bit of the four
644d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // bit specifier. one_bit is the position of the additional single bit
645d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // specifier.
646378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline int VFPGlueRegValue(VFPRegPrecision pre, int four_bit, int one_bit) {
647d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    if (pre == kSinglePrecision) {
648d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org      return (Bits(four_bit + 3, four_bit) << 1) | Bit(one_bit);
649d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    }
650d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org    return (Bit(one_bit) << 4) | Bits(four_bit + 3, four_bit);
651d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  }
652d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
653378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // We need to prevent the creation of instances of class Instruction.
654378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
658a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// Helper functions for converting between register numbers and names.
659a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgclass Registers {
660a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org public:
661a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Return the name of the register.
662a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  static const char* Name(int reg);
663a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
664a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Lookup the register number for the name provided.
665a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  static int Number(const char* name);
666a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
667a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  struct RegisterAlias {
668a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org    int reg;
669c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    const char* name;
670a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  };
671a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
672a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org private:
673a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  static const char* names_[kNumRegisters];
674a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  static const RegisterAlias aliases_[];
675a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org};
676a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
677c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org// Helper functions for converting between VFP register numbers and names.
678c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.orgclass VFPRegisters {
679c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org public:
680c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Return the name of the register.
6815d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  static const char* Name(int reg, bool is_double);
6825d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
6835d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Lookup the register number for the name provided.
6845d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Set flag pointed by is_double to true if register
6855d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // is double-precision.
6865d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  static int Number(const char* name, bool* is_double);
687c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org
688c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org private:
689c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  static const char* names_[kNumVFPRegisters];
690c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org};
691a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
692a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
693378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org} }  // namespace v8::internal
69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6955ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_ARM_CONSTANTS_ARM_H_
696