constants-arm.h 24.1 KB
Newer Older
1
// Copyright 2011 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
#ifndef V8_ARM_CONSTANTS_ARM_H_
#define V8_ARM_CONSTANTS_ARM_H_
7

8 9 10 11
#include <stdint.h>

#include "src/base/logging.h"
#include "src/base/macros.h"
12
#include "src/boxed-float.h"
13
#include "src/globals.h"
14
#include "src/utils.h"
15

16 17 18
// ARM EABI is required.
#if defined(__arm__) && !defined(__ARM_EABI__)
#error ARM EABI support is required.
19 20
#endif

21 22
namespace v8 {
namespace internal {
23

24
// Constant pool marker.
25 26 27 28 29
// Use UDF, the permanently undefined instruction.
const int kConstantPoolMarkerMask = 0xfff000f0;
const int kConstantPoolMarker = 0xe7f000f0;
const int kConstantPoolLengthMaxMask = 0xffff;
inline int EncodeConstantPoolLength(int length) {
30
  DCHECK((length & kConstantPoolLengthMaxMask) == length);
31 32 33
  return ((length & 0xfff0) << 4) | (length & 0xf);
}
inline int DecodeConstantPoolLength(int instr) {
34
  DCHECK_EQ(instr & kConstantPoolMarkerMask, kConstantPoolMarker);
35 36
  return ((instr >> 4) & 0xfff0) | (instr & 0xf);
}
37

38
// Number of registers in normal ARM mode.
39
const int kNumRegisters = 16;
40

41
// VFP support.
42
const int kNumVFPSingleRegisters = 32;
43
const int kNumVFPDoubleRegisters = 32;
44
const int kNumVFPRegisters = kNumVFPSingleRegisters + kNumVFPDoubleRegisters;
45

46
// PC is register 15.
47 48
const int kPCRegister = 15;
const int kNoRegister = -1;
49

50 51 52 53 54
// Used in embedded constant pool builder - max reach in bits for
// various load instructions (unsigned)
const int kLdrMaxReachBits = 12;
const int kVldrMaxReachBits = 10;

55 56 57 58 59 60
// Actual value of root register is offset from the root array's start
// to take advantage of negative displacement values. Loads allow a uint12
// value with a separate sign bit (range [-4095, +4095]), so the first root
// is still addressable with a single load instruction.
constexpr int kRootRegisterBias = 4095;

61 62 63
// -----------------------------------------------------------------------------
// Conditions.

64 65 66
// Defines constants and accessor classes to assemble, disassemble and
// simulate ARM instructions.
//
67 68 69
// Section references in the code refer to the "ARM Architecture Reference
// Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
//
70 71 72
// Constants for specific fields are defined in their respective named enums.
// General constants are in an anonymous enum in class Instr.

73
// Values for the condition field as defined in section A3.2
74
enum Condition {
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
  kNoCondition = -1,

  eq =  0 << 28,                 // Z set            Equal.
  ne =  1 << 28,                 // Z clear          Not equal.
  cs =  2 << 28,                 // C set            Unsigned higher or same.
  cc =  3 << 28,                 // C clear          Unsigned lower.
  mi =  4 << 28,                 // N set            Negative.
  pl =  5 << 28,                 // N clear          Positive or zero.
  vs =  6 << 28,                 // V set            Overflow.
  vc =  7 << 28,                 // V clear          No overflow.
  hi =  8 << 28,                 // C set, Z clear   Unsigned higher.
  ls =  9 << 28,                 // C clear or Z set Unsigned lower or same.
  ge = 10 << 28,                 // N == V           Greater or equal.
  lt = 11 << 28,                 // N != V           Less than.
  gt = 12 << 28,                 // Z clear, N == V  Greater than.
  le = 13 << 28,                 // Z set or N != V  Less then or equal
  al = 14 << 28,                 //                  Always.

  kSpecialCondition = 15 << 28,  // Special condition (refer to section A3.2.1).
  kNumberOfConditions = 16,

  // Aliases.
  hs = cs,                       // C set            Unsigned higher or same.
  lo = cc                        // C clear          Unsigned lower.
99 100 101
};


102
inline Condition NegateCondition(Condition cond) {
103
  DCHECK(cond != al);
104 105 106 107 108 109 110 111 112 113 114 115 116 117
  return static_cast<Condition>(cond ^ ne);
}


// -----------------------------------------------------------------------------
// Instructions encoding.

// Instr is merely used by the Assembler to distinguish 32bit integers
// representing instructions from usual 32 bit values.
// Instruction objects are pointers to 32bit values, and provide methods to
// access the various ISA fields.
typedef int32_t Instr;


118 119
// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
// as defined in section A3.4
120
enum Opcode {
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
  AND =  0 << 21,  // Logical AND.
  EOR =  1 << 21,  // Logical Exclusive OR.
  SUB =  2 << 21,  // Subtract.
  RSB =  3 << 21,  // Reverse Subtract.
  ADD =  4 << 21,  // Add.
  ADC =  5 << 21,  // Add with Carry.
  SBC =  6 << 21,  // Subtract with Carry.
  RSC =  7 << 21,  // Reverse Subtract with Carry.
  TST =  8 << 21,  // Test.
  TEQ =  9 << 21,  // Test Equivalence.
  CMP = 10 << 21,  // Compare.
  CMN = 11 << 21,  // Compare Negated.
  ORR = 12 << 21,  // Logical (inclusive) OR.
  MOV = 13 << 21,  // Move.
  BIC = 14 << 21,  // Bit Clear.
  MVN = 15 << 21   // Move Not.
137 138 139
};


140 141 142
// The bits for bit 7-4 for some type 0 miscellaneous instructions.
enum MiscInstructionsBits74 {
  // With bits 22-21 01.
143 144 145 146
  BX   =  1 << 4,
  BXJ  =  2 << 4,
  BLX  =  3 << 4,
  BKPT =  7 << 4,
147

148
  // With bits 22-21 11.
149 150 151 152 153 154
  CLZ  =  1 << 4
};


// Instruction encoding bits and masks.
enum {
155 156 157 158 159 160 161 162 163 164 165
  H = 1 << 5,   // Halfword (or byte).
  S6 = 1 << 6,  // Signed (or unsigned).
  L = 1 << 20,  // Load (or store).
  S = 1 << 20,  // Set condition code (or leave unchanged).
  W = 1 << 21,  // Writeback base register (or leave unchanged).
  A = 1 << 21,  // Accumulate in multiply instruction (or not).
  B = 1 << 22,  // Unsigned byte (or word).
  N = 1 << 22,  // Long (or short).
  U = 1 << 23,  // Positive (or negative) offset/index.
  P = 1 << 24,  // Offset/pre-indexed addressing (or post-indexed addressing).
  I = 1 << 25,  // Immediate shifter operand (or not).
166
  B0 = 1 << 0,
167 168 169 170 171 172
  B4 = 1 << 4,
  B5 = 1 << 5,
  B6 = 1 << 6,
  B7 = 1 << 7,
  B8 = 1 << 8,
  B9 = 1 << 9,
173
  B10 = 1 << 10,
174 175
  B12 = 1 << 12,
  B16 = 1 << 16,
176
  B17 = 1 << 17,
177 178 179 180 181 182 183 184 185 186 187 188 189
  B18 = 1 << 18,
  B19 = 1 << 19,
  B20 = 1 << 20,
  B21 = 1 << 21,
  B22 = 1 << 22,
  B23 = 1 << 23,
  B24 = 1 << 24,
  B25 = 1 << 25,
  B26 = 1 << 26,
  B27 = 1 << 27,
  B28 = 1 << 28,

  // Instruction bit masks.
190 191 192
  kCondMask = 15 << 28,
  kALUMask = 0x6f << 21,
  kRdMask = 15 << 12,  // In str instruction.
193 194
  kCoprocessorMask = 15 << 8,
  kOpCodeMask = 15 << 21,  // In data-processing instructions.
195 196 197 198 199
  kImm24Mask = (1 << 24) - 1,
  kImm16Mask = (1 << 16) - 1,
  kImm8Mask = (1 << 8) - 1,
  kOff12Mask = (1 << 12) - 1,
  kOff8Mask = (1 << 8) - 1
200 201
};

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
enum BarrierOption {
  OSHLD = 0x1,
  OSHST = 0x2,
  OSH = 0x3,
  NSHLD = 0x5,
  NSHST = 0x6,
  NSH = 0x7,
  ISHLD = 0x9,
  ISHST = 0xa,
  ISH = 0xb,
  LD = 0xd,
  ST = 0xe,
  SY = 0xf,
};


218 219 220 221 222 223 224 225 226 227 228 229 230 231
// -----------------------------------------------------------------------------
// Addressing modes and instruction variants.

// Condition code updating mode.
enum SBit {
  SetCC   = 1 << 20,  // Set condition code.
  LeaveCC = 0 << 20   // Leave condition code unchanged.
};


// Status register selection.
enum SRegister {
  CPSR = 0 << 22,
  SPSR = 1 << 22
232 233 234
};


235
// Shifter types for Data-processing operands as defined in section A5.1.2.
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
enum ShiftOp {
  LSL = 0 << 5,   // Logical shift left.
  LSR = 1 << 5,   // Logical shift right.
  ASR = 2 << 5,   // Arithmetic shift right.
  ROR = 3 << 5,   // Rotate right.

  // RRX is encoded as ROR with shift_imm == 0.
  // Use a special code to make the distinction. The RRX ShiftOp is only used
  // as an argument, and will never actually be encoded. The Assembler will
  // detect it and emit the correct ROR shift operand with shift_imm == 0.
  RRX = -1,
  kNumberOfShifts = 4
};


// Status register fields.
enum SRegisterField {
  CPSR_c = CPSR | 1 << 16,
  CPSR_x = CPSR | 1 << 17,
  CPSR_s = CPSR | 1 << 18,
  CPSR_f = CPSR | 1 << 19,
  SPSR_c = SPSR | 1 << 16,
  SPSR_x = SPSR | 1 << 17,
  SPSR_s = SPSR | 1 << 18,
  SPSR_f = SPSR | 1 << 19
261 262
};

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
// Status register field mask (or'ed SRegisterField enum values).
typedef uint32_t SRegisterFieldMask;


// Memory operand addressing mode.
enum AddrMode {
  // Bit encoding P U W.
  Offset       = (8|4|0) << 21,  // Offset (without writeback to base).
  PreIndex     = (8|4|1) << 21,  // Pre-indexed addressing with writeback.
  PostIndex    = (0|4|0) << 21,  // Post-indexed addressing with writeback.
  NegOffset    = (8|0|0) << 21,  // Negative offset (without writeback to base).
  NegPreIndex  = (8|0|1) << 21,  // Negative pre-indexed with writeback.
  NegPostIndex = (0|0|0) << 21   // Negative post-indexed with writeback.
};


// Load/store multiple addressing mode.
enum BlockAddrMode {
  // Bit encoding P U W .
  da           = (0|0|0) << 21,  // Decrement after.
  ia           = (0|4|0) << 21,  // Increment after.
  db           = (8|0|0) << 21,  // Decrement before.
  ib           = (8|4|0) << 21,  // Increment before.
  da_w         = (0|0|1) << 21,  // Decrement after with writeback to base.
  ia_w         = (0|4|1) << 21,  // Increment after with writeback to base.
  db_w         = (8|0|1) << 21,  // Decrement before with writeback to base.
  ib_w         = (8|4|1) << 21,  // Increment before with writeback to base.

  // Alias modes for comparison when writeback does not matter.
  da_x         = (0|0|0) << 21,  // Decrement after.
  ia_x         = (0|4|0) << 21,  // Increment after.
  db_x         = (8|0|0) << 21,  // Decrement before.
295 296 297
  ib_x         = (8|4|0) << 21,  // Increment before.

  kBlockAddrModeMask = (8|4|1) << 21
298 299 300 301 302 303 304 305 306
};


// Coprocessor load/store operand size.
enum LFlag {
  Long  = 1 << 22,  // Long load/store coprocessor.
  Short = 0 << 22   // Short load/store coprocessor.
};

307 308
// Neon sizes.
enum NeonSize { Neon8 = 0x0, Neon16 = 0x1, Neon32 = 0x2, Neon64 = 0x3 };
309

310 311
// NEON data type
enum NeonDataType {
312 313 314 315 316 317 318
  NeonS8 = 0,
  NeonS16 = 1,
  NeonS32 = 2,
  // Gap to make it easier to extract U and size.
  NeonU8 = 4,
  NeonU16 = 5,
  NeonU32 = 6
319 320
};

321 322 323
inline int NeonU(NeonDataType dt) { return static_cast<int>(dt) >> 2; }
inline int NeonSz(NeonDataType dt) { return static_cast<int>(dt) & 0x3; }

324
// Convert sizes to data types (U bit is clear).
325 326
inline NeonDataType NeonSizeToDataType(NeonSize size) {
  DCHECK_NE(Neon64, size);
327 328 329
  return static_cast<NeonDataType>(size);
}

330 331 332 333
inline NeonSize NeonDataTypeToSize(NeonDataType dt) {
  return static_cast<NeonSize>(NeonSz(dt));
}

334 335 336 337 338 339 340
enum NeonListType {
  nlt_1 = 0x7,
  nlt_2 = 0xA,
  nlt_3 = 0x6,
  nlt_4 = 0x2
};

341 342
// -----------------------------------------------------------------------------
// Supervisor Call (svc) specific support.
343

344 345
// Special Software Interrupt codes when used in the presence of the ARM
// simulator.
346 347
// svc (formerly swi) provides a 24bit immediate value. Use bits 22:0 for
// standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature.
348 349
enum SoftwareInterruptCodes {
  // transition to C code
Benedikt Meurer's avatar
Benedikt Meurer committed
350
  kCallRtRedirected = 0x10,
351
  // break point
Benedikt Meurer's avatar
Benedikt Meurer committed
352
  kBreakpoint = 0x20,
353
  // stop
354
  kStopCode = 1 << 23
355
};
356 357 358
const uint32_t kStopCodeMask = kStopCode - 1;
const uint32_t kMaxStopCode = kStopCode - 1;
const int32_t  kDefaultStopCode = -1;
359 360


361 362 363
// Type of VFP register. Determines register encoding.
enum VFPRegPrecision {
  kSinglePrecision = 0,
364 365
  kDoublePrecision = 1,
  kSimd128Precision = 2
366 367
};

368
// VFP FPSCR constants.
369 370 371 372 373
enum VFPConversionMode {
  kFPSCRRounding = 0,
  kDefaultRoundToZero = 1
};

374 375
// This mask does not include the "inexact" or "input denormal" cumulative
// exceptions flags, because we usually don't want to check for it.
376 377 378 379 380 381
const uint32_t kVFPExceptionMask = 0xf;
const uint32_t kVFPInvalidOpExceptionBit = 1 << 0;
const uint32_t kVFPOverflowExceptionBit = 1 << 2;
const uint32_t kVFPUnderflowExceptionBit = 1 << 3;
const uint32_t kVFPInexactExceptionBit = 1 << 4;
const uint32_t kVFPFlushToZeroMask = 1 << 24;
382
const uint32_t kVFPDefaultNaNModeControlBit = 1 << 25;
383

384 385 386 387
const uint32_t kVFPNConditionFlagBit = 1 << 31;
const uint32_t kVFPZConditionFlagBit = 1 << 30;
const uint32_t kVFPCConditionFlagBit = 1 << 29;
const uint32_t kVFPVConditionFlagBit = 1 << 28;
388 389


390
// VFP rounding modes. See ARM DDI 0406B Page A2-29.
391 392 393 394 395 396 397 398 399 400 401
enum VFPRoundingMode {
  RN = 0 << 22,   // Round to Nearest.
  RP = 1 << 22,   // Round towards Plus Infinity.
  RM = 2 << 22,   // Round towards Minus Infinity.
  RZ = 3 << 22,   // Round towards zero.

  // Aliases.
  kRoundToNearest = RN,
  kRoundToPlusInf = RP,
  kRoundToMinusInf = RM,
  kRoundToZero = RZ
402
};
403

404
const uint32_t kVFPRoundingModeMask = 3 << 22;
405

406 407 408 409 410
enum CheckForInexactConversion {
  kCheckForInexactConversion,
  kDontCheckForInexactConversion
};

411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
// -----------------------------------------------------------------------------
// Hints.

// Branch hints are not used on the ARM.  They are defined so that they can
// appear in shared function signatures, but will be ignored in ARM
// implementations.
enum Hint { no_hint };

// Hints are not used on the arm.  Negating is trivial.
inline Hint NegateHint(Hint ignored) { return no_hint; }


// -----------------------------------------------------------------------------
// Instruction abstraction.

// The class Instruction enables access to individual fields defined in the ARM
427
// architecture instruction set encoding as described in figure A3-1.
428
// Note that the Assembler uses typedef int32_t Instr.
429 430 431 432 433
//
// Example: Test whether the instruction at ptr does set the condition code
// bits.
//
// bool InstructionSetsConditionCodes(byte* ptr) {
434 435
//   Instruction* instr = Instruction::At(ptr);
//   int type = instr->TypeValue();
436 437 438
//   return ((type == 0) || (type == 1)) && instr->HasS();
// }
//
439 440 441 442

constexpr uint8_t kInstrSize = 4;
constexpr uint8_t kInstrSizeLog2 = 2;

443
class Instruction {
444
 public:
445 446 447 448 449 450 451 452 453 454 455
  // Difference between address of current opcode and value read from pc
  // register.
  static constexpr int kPcLoadDelta = 8;

// Helper macro to define static accessors.
// We use the cast to char* trick to bypass the strict anti-aliasing rules.
#define DECLARE_STATIC_TYPED_ACCESSOR(return_type, Name) \
  static inline return_type Name(Instr instr) {          \
    char* temp = reinterpret_cast<char*>(&instr);        \
    return reinterpret_cast<Instruction*>(temp)->Name(); \
  }
456

457
#define DECLARE_STATIC_ACCESSOR(Name) DECLARE_STATIC_TYPED_ACCESSOR(int, Name)
458

459
  // Get the raw instruction bits.
460 461
  inline Instr InstructionBits() const {
    return *reinterpret_cast<const Instr*>(this);
462 463
  }

464
  // Set the raw instruction bits to value.
465 466
  inline void SetInstructionBits(Instr value) {
    *reinterpret_cast<Instr*>(this) = value;
467 468
  }

469 470
  // Extract a single bit from the instruction bits and return it as bit 0 in
  // the result.
471 472 473 474
  inline int Bit(int nr) const {
    return (InstructionBits() >> nr) & 1;
  }

475 476
  // Extract a bit field <hi:lo> from the instruction bits and return it in the
  // least-significant bits of the result.
477 478 479 480
  inline int Bits(int hi, int lo) const {
    return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
  }

481
  // Read a bit field <hi:lo>, leaving its position unchanged in the result.
482 483 484 485 486 487
  inline int BitField(int hi, int lo) const {
    return InstructionBits() & (((2 << (hi - lo)) - 1) << lo);
  }

  // Static support.

488 489
  // Extract a single bit from the instruction bits and return it as bit 0 in
  // the result.
490 491 492 493
  static inline int Bit(Instr instr, int nr) {
    return (instr >> nr) & 1;
  }

494 495
  // Extract a bit field <hi:lo> from the instruction bits and return it in the
  // least-significant bits of the result.
496 497 498 499
  static inline int Bits(Instr instr, int hi, int lo) {
    return (instr >> lo) & ((2 << (hi - lo)) - 1);
  }

500
  // Read a bit field <hi:lo>, leaving its position unchanged in the result.
501 502 503 504
  static inline int BitField(Instr instr, int hi, int lo) {
    return instr & (((2 << (hi - lo)) - 1) << lo);
  }

505
  // Accessors for the different named fields used in the ARM encoding.
506
  // The naming of these accessor corresponds to figure A3-1.
507 508
  //
  // Two kind of accessors are declared:
509
  // - <Name>Field() will return the raw field, i.e. the field's bits at their
510
  //   original place in the instruction encoding.
511 512
  //   e.g. if instr is the 'addgt r0, r1, r2' instruction, encoded as
  //   0xC0810002 ConditionField(instr) will return 0xC0000000.
513
  // - <Name>Value() will return the field value, shifted back to bit 0.
514 515
  //   e.g. if instr is the 'addgt r0, r1, r2' instruction, encoded as
  //   0xC0810002 ConditionField(instr) will return 0xC.
516 517


518
  // Generally applicable fields
519
  inline int ConditionValue() const { return Bits(31, 28); }
520 521 522
  inline Condition ConditionField() const {
    return static_cast<Condition>(BitField(31, 28));
  }
523
  DECLARE_STATIC_TYPED_ACCESSOR(int, ConditionValue);
524
  DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionField);
525

526
  inline int TypeValue() const { return Bits(27, 25); }
527
  inline int SpecialValue() const { return Bits(27, 23); }
528

529
  inline int RnValue() const { return Bits(19, 16); }
530
  DECLARE_STATIC_ACCESSOR(RnValue);
531 532 533 534
  inline int RdValue() const { return Bits(15, 12); }
  DECLARE_STATIC_ACCESSOR(RdValue);

  inline int CoprocessorValue() const { return Bits(11, 8); }
535 536
  // Support for VFP.
  // Vn(19-16) | Vd(15-12) |  Vm(3-0)
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
  inline int VnValue() const { return Bits(19, 16); }
  inline int VmValue() const { return Bits(3, 0); }
  inline int VdValue() const { return Bits(15, 12); }
  inline int NValue() const { return Bit(7); }
  inline int MValue() const { return Bit(5); }
  inline int DValue() const { return Bit(22); }
  inline int RtValue() const { return Bits(15, 12); }
  inline int PValue() const { return Bit(24); }
  inline int UValue() const { return Bit(23); }
  inline int Opc1Value() const { return (Bit(23) << 2) | Bits(21, 20); }
  inline int Opc2Value() const { return Bits(19, 16); }
  inline int Opc3Value() const { return Bits(7, 6); }
  inline int SzValue() const { return Bit(8); }
  inline int VLValue() const { return Bit(20); }
  inline int VCValue() const { return Bit(8); }
  inline int VAValue() const { return Bits(23, 21); }
  inline int VBValue() const { return Bits(6, 5); }
  inline int VFPNRegValue(VFPRegPrecision pre) {
    return VFPGlueRegValue(pre, 16, 7);
556
  }
557 558
  inline int VFPMRegValue(VFPRegPrecision pre) {
    return VFPGlueRegValue(pre, 0, 5);
559
  }
560 561
  inline int VFPDRegValue(VFPRegPrecision pre) {
    return VFPGlueRegValue(pre, 12, 22);
562
  }
563

564
  // Fields used in Data processing instructions
565
  inline int OpcodeValue() const {
566 567
    return static_cast<Opcode>(Bits(24, 21));
  }
568 569 570 571
  inline Opcode OpcodeField() const {
    return static_cast<Opcode>(BitField(24, 21));
  }
  inline int SValue() const { return Bit(20); }
572
    // with register
573
  inline int RmValue() const { return Bits(3, 0); }
574
  DECLARE_STATIC_ACCESSOR(RmValue);
575 576 577 578 579 580 581
  inline int ShiftValue() const { return static_cast<ShiftOp>(Bits(6, 5)); }
  inline ShiftOp ShiftField() const {
    return static_cast<ShiftOp>(BitField(6, 5));
  }
  inline int RegShiftValue() const { return Bit(4); }
  inline int RsValue() const { return Bits(11, 8); }
  inline int ShiftAmountValue() const { return Bits(11, 7); }
582
    // with immediate
583
  inline int RotateValue() const { return Bits(11, 8); }
584
  DECLARE_STATIC_ACCESSOR(RotateValue);
585
  inline int Immed8Value() const { return Bits(7, 0); }
586
  DECLARE_STATIC_ACCESSOR(Immed8Value);
587 588 589
  inline int Immed4Value() const { return Bits(19, 16); }
  inline int ImmedMovwMovtValue() const {
      return Immed4Value() << 12 | Offset12Value(); }
590
  DECLARE_STATIC_ACCESSOR(ImmedMovwMovtValue);
591 592

  // Fields used in Load/Store instructions
593 594 595 596 597
  inline int PUValue() const { return Bits(24, 23); }
  inline int PUField() const { return BitField(24, 23); }
  inline int  BValue() const { return Bit(22); }
  inline int  WValue() const { return Bit(21); }
  inline int  LValue() const { return Bit(20); }
598 599
    // with register uses same fields as Data processing instructions above
    // with immediate
600
  inline int Offset12Value() const { return Bits(11, 0); }
601
    // multiple
602
  inline int RlistValue() const { return Bits(15, 0); }
603
    // extra loads and stores
604 605 606 607
  inline int SignValue() const { return Bit(6); }
  inline int HValue() const { return Bit(5); }
  inline int ImmedHValue() const { return Bits(11, 8); }
  inline int ImmedLValue() const { return Bits(3, 0); }
608 609

  // Fields used in Branch instructions
610
  inline int LinkValue() const { return Bit(24); }
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
  inline int SImmed24Value() const {
    return signed_bitextract_32(23, 0, InstructionBits());
  }

  bool IsBranch() { return Bit(27) == 1 && Bit(25) == 1; }

  int GetBranchOffset() {
    DCHECK(IsBranch());
    return SImmed24Value() * kInstrSize;
  }

  void SetBranchOffset(int32_t branch_offset) {
    DCHECK(IsBranch());
    DCHECK_EQ(branch_offset % kInstrSize, 0);
    int32_t new_imm24 = branch_offset / kInstrSize;
    CHECK(is_int24(new_imm24));
    SetInstructionBits((InstructionBits() & ~(kImm24Mask)) |
                       (new_imm24 & kImm24Mask));
  }
630 631

  // Fields used in Software interrupt instructions
632
  inline SoftwareInterruptCodes SvcValue() const {
633 634 635 636 637 638 639
    return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
  }

  // Test for special encodings of type 0 instructions (extra loads and stores,
  // as well as multiplications).
  inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); }

640 641 642 643 644 645
  // Test for miscellaneous instructions encodings of type 0 instructions.
  inline bool IsMiscType0() const { return (Bit(24) == 1)
                                           && (Bit(23) == 0)
                                           && (Bit(20) == 0)
                                           && ((Bit(7) == 0)); }

646 647
  // Test for nop-like instructions which fall under type 1.
  inline bool IsNopLikeType1() const { return Bits(24, 8) == 0x120F0; }
648

649 650
  // Test for a stop instruction.
  inline bool IsStop() const {
651
    return (TypeValue() == 7) && (Bit(24) == 1) && (SvcValue() >= kStopCode);
652 653
  }

654
  // Special accessors that test for existence of a value.
655 656 657 658 659 660 661 662
  inline bool HasS()    const { return SValue() == 1; }
  inline bool HasB()    const { return BValue() == 1; }
  inline bool HasW()    const { return WValue() == 1; }
  inline bool HasL()    const { return LValue() == 1; }
  inline bool HasU()    const { return UValue() == 1; }
  inline bool HasSign() const { return SignValue() == 1; }
  inline bool HasH()    const { return HValue() == 1; }
  inline bool HasLink() const { return LinkValue() == 1; }
663

664
  // Decode the double immediate from a vmov instruction.
665
  Float64 DoubleImmedVmov() const;
666

667 668
  // Instructions are read of out a code stream. The only way to get a
  // reference to an instruction is to convert a pointer. There is no way
669 670
  // to allocate or create instances of class Instruction.
  // Use the At(pc) function to create references to Instruction.
671
  static Instruction* At(Address pc) {
672 673 674
    return reinterpret_cast<Instruction*>(pc);
  }

675 676

 private:
677
  // Join split register codes, depending on register precision.
678 679 680
  // four_bit is the position of the least-significant bit of the four
  // bit specifier. one_bit is the position of the additional single bit
  // specifier.
681
  inline int VFPGlueRegValue(VFPRegPrecision pre, int four_bit, int one_bit) {
682 683
    if (pre == kSinglePrecision) {
      return (Bits(four_bit + 3, four_bit) << 1) | Bit(one_bit);
684 685 686 687 688 689 690 691
    } else {
      int reg_num = (Bit(one_bit) << 4) | Bits(four_bit + 3, four_bit);
      if (pre == kDoublePrecision) {
        return reg_num;
      }
      DCHECK_EQ(kSimd128Precision, pre);
      DCHECK_EQ(reg_num & 1, 0);
      return reg_num / 2;
692 693 694
    }
  }

695 696
  // We need to prevent the creation of instances of class Instruction.
  DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
697 698 699
};


700 701 702 703 704 705 706 707 708 709 710
// Helper functions for converting between register numbers and names.
class Registers {
 public:
  // Return the name of the register.
  static const char* Name(int reg);

  // Lookup the register number for the name provided.
  static int Number(const char* name);

  struct RegisterAlias {
    int reg;
711
    const char* name;
712 713 714 715 716 717 718
  };

 private:
  static const char* names_[kNumRegisters];
  static const RegisterAlias aliases_[];
};

719 720 721 722
// Helper functions for converting between VFP register numbers and names.
class VFPRegisters {
 public:
  // Return the name of the register.
723 724 725 726 727 728
  static const char* Name(int reg, bool is_double);

  // Lookup the register number for the name provided.
  // Set flag pointed by is_double to true if register
  // is double-precision.
  static int Number(const char* name, bool* is_double);
729 730 731 732

 private:
  static const char* names_[kNumVFPRegisters];
};
733

734 735
// Relative jumps on ARM can address ±32 MB.
constexpr size_t kMaxPCRelativeCodeRangeInMB = 32;
736

737 738
}  // namespace internal
}  // namespace v8
739

740
#endif  // V8_ARM_CONSTANTS_ARM_H_