• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_ARM_CONSTANTS_ARM_H_
29 #define V8_ARM_CONSTANTS_ARM_H_
30 
31 // ARM EABI is required.
32 #if defined(__arm__) && !defined(__ARM_EABI__)
33 #error ARM EABI support is required.
34 #endif
35 
36 // This means that interwork-compatible jump instructions are generated.  We
37 // want to generate them on the simulator too so it makes snapshots that can
38 // be used on real hardware.
39 #if defined(__THUMB_INTERWORK__) || !defined(__arm__)
40 # define USE_THUMB_INTERWORK 1
41 #endif
42 
43 #if defined(__ARM_ARCH_7A__) || \
44     defined(__ARM_ARCH_7R__) || \
45     defined(__ARM_ARCH_7__)
46 # define CAN_USE_ARMV7_INSTRUCTIONS 1
47 #endif
48 
49 #if defined(__ARM_ARCH_6__) ||   \
50     defined(__ARM_ARCH_6J__) ||  \
51     defined(__ARM_ARCH_6K__) ||  \
52     defined(__ARM_ARCH_6Z__) ||  \
53     defined(__ARM_ARCH_6ZK__) || \
54     defined(__ARM_ARCH_6T2__) || \
55     defined(CAN_USE_ARMV7_INSTRUCTIONS)
56 # define CAN_USE_ARMV6_INSTRUCTIONS 1
57 #endif
58 
59 #if defined(__ARM_ARCH_5T__)            || \
60     defined(__ARM_ARCH_5TE__)           || \
61     defined(CAN_USE_ARMV6_INSTRUCTIONS)
62 # define CAN_USE_ARMV5_INSTRUCTIONS 1
63 # define CAN_USE_THUMB_INSTRUCTIONS 1
64 #endif
65 
66 // Simulator should support ARM5 instructions and unaligned access by default.
67 #if !defined(__arm__)
68 # define CAN_USE_ARMV5_INSTRUCTIONS 1
69 # define CAN_USE_THUMB_INSTRUCTIONS 1
70 
71 # ifndef CAN_USE_UNALIGNED_ACCESSES
72 #  define CAN_USE_UNALIGNED_ACCESSES 1
73 # endif
74 
75 #endif
76 
77 #if CAN_USE_UNALIGNED_ACCESSES
78 #define V8_TARGET_CAN_READ_UNALIGNED 1
79 #endif
80 
81 // Using blx may yield better code, so use it when required or when available
82 #if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS)
83 #define USE_BLX 1
84 #endif
85 
86 namespace v8 {
87 namespace internal {
88 
89 // Constant pool marker.
90 const int kConstantPoolMarkerMask = 0xffe00000;
91 const int kConstantPoolMarker = 0x0c000000;
92 const int kConstantPoolLengthMask = 0x001ffff;
93 
94 // Number of registers in normal ARM mode.
95 const int kNumRegisters = 16;
96 
97 // VFP support.
98 const int kNumVFPSingleRegisters = 32;
99 const int kNumVFPDoubleRegisters = 16;
100 const int kNumVFPRegisters = kNumVFPSingleRegisters + kNumVFPDoubleRegisters;
101 
102 // PC is register 15.
103 const int kPCRegister = 15;
104 const int kNoRegister = -1;
105 
106 // -----------------------------------------------------------------------------
107 // Conditions.
108 
109 // Defines constants and accessor classes to assemble, disassemble and
110 // simulate ARM instructions.
111 //
112 // Section references in the code refer to the "ARM Architecture Reference
113 // Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
114 //
115 // Constants for specific fields are defined in their respective named enums.
116 // General constants are in an anonymous enum in class Instr.
117 
118 // Values for the condition field as defined in section A3.2
119 enum Condition {
120   kNoCondition = -1,
121 
122   eq =  0 << 28,                 // Z set            Equal.
123   ne =  1 << 28,                 // Z clear          Not equal.
124   cs =  2 << 28,                 // C set            Unsigned higher or same.
125   cc =  3 << 28,                 // C clear          Unsigned lower.
126   mi =  4 << 28,                 // N set            Negative.
127   pl =  5 << 28,                 // N clear          Positive or zero.
128   vs =  6 << 28,                 // V set            Overflow.
129   vc =  7 << 28,                 // V clear          No overflow.
130   hi =  8 << 28,                 // C set, Z clear   Unsigned higher.
131   ls =  9 << 28,                 // C clear or Z set Unsigned lower or same.
132   ge = 10 << 28,                 // N == V           Greater or equal.
133   lt = 11 << 28,                 // N != V           Less than.
134   gt = 12 << 28,                 // Z clear, N == V  Greater than.
135   le = 13 << 28,                 // Z set or N != V  Less then or equal
136   al = 14 << 28,                 //                  Always.
137 
138   kSpecialCondition = 15 << 28,  // Special condition (refer to section A3.2.1).
139   kNumberOfConditions = 16,
140 
141   // Aliases.
142   hs = cs,                       // C set            Unsigned higher or same.
143   lo = cc                        // C clear          Unsigned lower.
144 };
145 
146 
NegateCondition(Condition cond)147 inline Condition NegateCondition(Condition cond) {
148   ASSERT(cond != al);
149   return static_cast<Condition>(cond ^ ne);
150 }
151 
152 
153 // Corresponds to transposing the operands of a comparison.
ReverseCondition(Condition cond)154 inline Condition ReverseCondition(Condition cond) {
155   switch (cond) {
156     case lo:
157       return hi;
158     case hi:
159       return lo;
160     case hs:
161       return ls;
162     case ls:
163       return hs;
164     case lt:
165       return gt;
166     case gt:
167       return lt;
168     case ge:
169       return le;
170     case le:
171       return ge;
172     default:
173       return cond;
174   };
175 }
176 
177 
178 // -----------------------------------------------------------------------------
179 // Instructions encoding.
180 
181 // Instr is merely used by the Assembler to distinguish 32bit integers
182 // representing instructions from usual 32 bit values.
183 // Instruction objects are pointers to 32bit values, and provide methods to
184 // access the various ISA fields.
185 typedef int32_t Instr;
186 
187 
188 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
189 // as defined in section A3.4
190 enum Opcode {
191   AND =  0 << 21,  // Logical AND.
192   EOR =  1 << 21,  // Logical Exclusive OR.
193   SUB =  2 << 21,  // Subtract.
194   RSB =  3 << 21,  // Reverse Subtract.
195   ADD =  4 << 21,  // Add.
196   ADC =  5 << 21,  // Add with Carry.
197   SBC =  6 << 21,  // Subtract with Carry.
198   RSC =  7 << 21,  // Reverse Subtract with Carry.
199   TST =  8 << 21,  // Test.
200   TEQ =  9 << 21,  // Test Equivalence.
201   CMP = 10 << 21,  // Compare.
202   CMN = 11 << 21,  // Compare Negated.
203   ORR = 12 << 21,  // Logical (inclusive) OR.
204   MOV = 13 << 21,  // Move.
205   BIC = 14 << 21,  // Bit Clear.
206   MVN = 15 << 21   // Move Not.
207 };
208 
209 
210 // The bits for bit 7-4 for some type 0 miscellaneous instructions.
211 enum MiscInstructionsBits74 {
212   // With bits 22-21 01.
213   BX   =  1 << 4,
214   BXJ  =  2 << 4,
215   BLX  =  3 << 4,
216   BKPT =  7 << 4,
217 
218   // With bits 22-21 11.
219   CLZ  =  1 << 4
220 };
221 
222 
223 // Instruction encoding bits and masks.
224 enum {
225   H   = 1 << 5,   // Halfword (or byte).
226   S6  = 1 << 6,   // Signed (or unsigned).
227   L   = 1 << 20,  // Load (or store).
228   S   = 1 << 20,  // Set condition code (or leave unchanged).
229   W   = 1 << 21,  // Writeback base register (or leave unchanged).
230   A   = 1 << 21,  // Accumulate in multiply instruction (or not).
231   B   = 1 << 22,  // Unsigned byte (or word).
232   N   = 1 << 22,  // Long (or short).
233   U   = 1 << 23,  // Positive (or negative) offset/index.
234   P   = 1 << 24,  // Offset/pre-indexed addressing (or post-indexed addressing).
235   I   = 1 << 25,  // Immediate shifter operand (or not).
236 
237   B4  = 1 << 4,
238   B5  = 1 << 5,
239   B6  = 1 << 6,
240   B7  = 1 << 7,
241   B8  = 1 << 8,
242   B9  = 1 << 9,
243   B12 = 1 << 12,
244   B16 = 1 << 16,
245   B18 = 1 << 18,
246   B19 = 1 << 19,
247   B20 = 1 << 20,
248   B21 = 1 << 21,
249   B22 = 1 << 22,
250   B23 = 1 << 23,
251   B24 = 1 << 24,
252   B25 = 1 << 25,
253   B26 = 1 << 26,
254   B27 = 1 << 27,
255   B28 = 1 << 28,
256 
257   // Instruction bit masks.
258   kCondMask   = 15 << 28,
259   kALUMask    = 0x6f << 21,
260   kRdMask     = 15 << 12,  // In str instruction.
261   kCoprocessorMask = 15 << 8,
262   kOpCodeMask = 15 << 21,  // In data-processing instructions.
263   kImm24Mask  = (1 << 24) - 1,
264   kOff12Mask  = (1 << 12) - 1
265 };
266 
267 
268 // -----------------------------------------------------------------------------
269 // Addressing modes and instruction variants.
270 
271 // Condition code updating mode.
272 enum SBit {
273   SetCC   = 1 << 20,  // Set condition code.
274   LeaveCC = 0 << 20   // Leave condition code unchanged.
275 };
276 
277 
278 // Status register selection.
279 enum SRegister {
280   CPSR = 0 << 22,
281   SPSR = 1 << 22
282 };
283 
284 
285 // Shifter types for Data-processing operands as defined in section A5.1.2.
286 enum ShiftOp {
287   LSL = 0 << 5,   // Logical shift left.
288   LSR = 1 << 5,   // Logical shift right.
289   ASR = 2 << 5,   // Arithmetic shift right.
290   ROR = 3 << 5,   // Rotate right.
291 
292   // RRX is encoded as ROR with shift_imm == 0.
293   // Use a special code to make the distinction. The RRX ShiftOp is only used
294   // as an argument, and will never actually be encoded. The Assembler will
295   // detect it and emit the correct ROR shift operand with shift_imm == 0.
296   RRX = -1,
297   kNumberOfShifts = 4
298 };
299 
300 
301 // Status register fields.
302 enum SRegisterField {
303   CPSR_c = CPSR | 1 << 16,
304   CPSR_x = CPSR | 1 << 17,
305   CPSR_s = CPSR | 1 << 18,
306   CPSR_f = CPSR | 1 << 19,
307   SPSR_c = SPSR | 1 << 16,
308   SPSR_x = SPSR | 1 << 17,
309   SPSR_s = SPSR | 1 << 18,
310   SPSR_f = SPSR | 1 << 19
311 };
312 
313 // Status register field mask (or'ed SRegisterField enum values).
314 typedef uint32_t SRegisterFieldMask;
315 
316 
317 // Memory operand addressing mode.
318 enum AddrMode {
319   // Bit encoding P U W.
320   Offset       = (8|4|0) << 21,  // Offset (without writeback to base).
321   PreIndex     = (8|4|1) << 21,  // Pre-indexed addressing with writeback.
322   PostIndex    = (0|4|0) << 21,  // Post-indexed addressing with writeback.
323   NegOffset    = (8|0|0) << 21,  // Negative offset (without writeback to base).
324   NegPreIndex  = (8|0|1) << 21,  // Negative pre-indexed with writeback.
325   NegPostIndex = (0|0|0) << 21   // Negative post-indexed with writeback.
326 };
327 
328 
329 // Load/store multiple addressing mode.
330 enum BlockAddrMode {
331   // Bit encoding P U W .
332   da           = (0|0|0) << 21,  // Decrement after.
333   ia           = (0|4|0) << 21,  // Increment after.
334   db           = (8|0|0) << 21,  // Decrement before.
335   ib           = (8|4|0) << 21,  // Increment before.
336   da_w         = (0|0|1) << 21,  // Decrement after with writeback to base.
337   ia_w         = (0|4|1) << 21,  // Increment after with writeback to base.
338   db_w         = (8|0|1) << 21,  // Decrement before with writeback to base.
339   ib_w         = (8|4|1) << 21,  // Increment before with writeback to base.
340 
341   // Alias modes for comparison when writeback does not matter.
342   da_x         = (0|0|0) << 21,  // Decrement after.
343   ia_x         = (0|4|0) << 21,  // Increment after.
344   db_x         = (8|0|0) << 21,  // Decrement before.
345   ib_x         = (8|4|0) << 21,  // Increment before.
346 
347   kBlockAddrModeMask = (8|4|1) << 21
348 };
349 
350 
351 // Coprocessor load/store operand size.
352 enum LFlag {
353   Long  = 1 << 22,  // Long load/store coprocessor.
354   Short = 0 << 22   // Short load/store coprocessor.
355 };
356 
357 
358 // -----------------------------------------------------------------------------
359 // Supervisor Call (svc) specific support.
360 
361 // Special Software Interrupt codes when used in the presence of the ARM
362 // simulator.
363 // svc (formerly swi) provides a 24bit immediate value. Use bits 22:0 for
364 // standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature.
365 enum SoftwareInterruptCodes {
366   // transition to C code
367   kCallRtRedirected= 0x10,
368   // break point
369   kBreakpoint= 0x20,
370   // stop
371   kStopCode = 1 << 23
372 };
373 const uint32_t kStopCodeMask = kStopCode - 1;
374 const uint32_t kMaxStopCode = kStopCode - 1;
375 const int32_t  kDefaultStopCode = -1;
376 
377 
378 // Type of VFP register. Determines register encoding.
379 enum VFPRegPrecision {
380   kSinglePrecision = 0,
381   kDoublePrecision = 1
382 };
383 
384 
385 // VFP FPSCR constants.
386 enum VFPConversionMode {
387   kFPSCRRounding = 0,
388   kDefaultRoundToZero = 1
389 };
390 
391 // This mask does not include the "inexact" or "input denormal" cumulative
392 // exceptions flags, because we usually don't want to check for it.
393 const uint32_t kVFPExceptionMask = 0xf;
394 const uint32_t kVFPInvalidOpExceptionBit = 1 << 0;
395 const uint32_t kVFPOverflowExceptionBit = 1 << 2;
396 const uint32_t kVFPUnderflowExceptionBit = 1 << 3;
397 const uint32_t kVFPInexactExceptionBit = 1 << 4;
398 const uint32_t kVFPFlushToZeroMask = 1 << 24;
399 
400 const uint32_t kVFPNConditionFlagBit = 1 << 31;
401 const uint32_t kVFPZConditionFlagBit = 1 << 30;
402 const uint32_t kVFPCConditionFlagBit = 1 << 29;
403 const uint32_t kVFPVConditionFlagBit = 1 << 28;
404 
405 
406 // VFP rounding modes. See ARM DDI 0406B Page A2-29.
407 enum VFPRoundingMode {
408   RN = 0 << 22,   // Round to Nearest.
409   RP = 1 << 22,   // Round towards Plus Infinity.
410   RM = 2 << 22,   // Round towards Minus Infinity.
411   RZ = 3 << 22,   // Round towards zero.
412 
413   // Aliases.
414   kRoundToNearest = RN,
415   kRoundToPlusInf = RP,
416   kRoundToMinusInf = RM,
417   kRoundToZero = RZ
418 };
419 
420 const uint32_t kVFPRoundingModeMask = 3 << 22;
421 
422 enum CheckForInexactConversion {
423   kCheckForInexactConversion,
424   kDontCheckForInexactConversion
425 };
426 
427 // -----------------------------------------------------------------------------
428 // Hints.
429 
430 // Branch hints are not used on the ARM.  They are defined so that they can
431 // appear in shared function signatures, but will be ignored in ARM
432 // implementations.
433 enum Hint { no_hint };
434 
435 // Hints are not used on the arm.  Negating is trivial.
NegateHint(Hint ignored)436 inline Hint NegateHint(Hint ignored) { return no_hint; }
437 
438 
439 // -----------------------------------------------------------------------------
440 // Specific instructions, constants, and masks.
441 // These constants are declared in assembler-arm.cc, as they use named registers
442 // and other constants.
443 
444 
445 // add(sp, sp, 4) instruction (aka Pop())
446 extern const Instr kPopInstruction;
447 
448 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
449 // register r is not encoded.
450 extern const Instr kPushRegPattern;
451 
452 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
453 // register r is not encoded.
454 extern const Instr kPopRegPattern;
455 
456 // mov lr, pc
457 extern const Instr kMovLrPc;
458 // ldr rd, [pc, #offset]
459 extern const Instr kLdrPCMask;
460 extern const Instr kLdrPCPattern;
461 // blxcc rm
462 extern const Instr kBlxRegMask;
463 
464 extern const Instr kBlxRegPattern;
465 
466 extern const Instr kMovMvnMask;
467 extern const Instr kMovMvnPattern;
468 extern const Instr kMovMvnFlip;
469 extern const Instr kMovLeaveCCMask;
470 extern const Instr kMovLeaveCCPattern;
471 extern const Instr kMovwMask;
472 extern const Instr kMovwPattern;
473 extern const Instr kMovwLeaveCCFlip;
474 extern const Instr kCmpCmnMask;
475 extern const Instr kCmpCmnPattern;
476 extern const Instr kCmpCmnFlip;
477 extern const Instr kAddSubFlip;
478 extern const Instr kAndBicFlip;
479 
480 // A mask for the Rd register for push, pop, ldr, str instructions.
481 extern const Instr kLdrRegFpOffsetPattern;
482 
483 extern const Instr kStrRegFpOffsetPattern;
484 
485 extern const Instr kLdrRegFpNegOffsetPattern;
486 
487 extern const Instr kStrRegFpNegOffsetPattern;
488 
489 extern const Instr kLdrStrInstrTypeMask;
490 extern const Instr kLdrStrInstrArgumentMask;
491 extern const Instr kLdrStrOffsetMask;
492 
493 
494 // -----------------------------------------------------------------------------
495 // Instruction abstraction.
496 
497 // The class Instruction enables access to individual fields defined in the ARM
498 // architecture instruction set encoding as described in figure A3-1.
499 // Note that the Assembler uses typedef int32_t Instr.
500 //
501 // Example: Test whether the instruction at ptr does set the condition code
502 // bits.
503 //
504 // bool InstructionSetsConditionCodes(byte* ptr) {
505 //   Instruction* instr = Instruction::At(ptr);
506 //   int type = instr->TypeValue();
507 //   return ((type == 0) || (type == 1)) && instr->HasS();
508 // }
509 //
510 class Instruction {
511  public:
512   enum {
513     kInstrSize = 4,
514     kInstrSizeLog2 = 2,
515     kPCReadOffset = 8
516   };
517 
518   // Helper macro to define static accessors.
519   // We use the cast to char* trick to bypass the strict anti-aliasing rules.
520   #define DECLARE_STATIC_TYPED_ACCESSOR(return_type, Name)                     \
521     static inline return_type Name(Instr instr) {                              \
522       char* temp = reinterpret_cast<char*>(&instr);                            \
523       return reinterpret_cast<Instruction*>(temp)->Name();                     \
524     }
525 
526   #define DECLARE_STATIC_ACCESSOR(Name) DECLARE_STATIC_TYPED_ACCESSOR(int, Name)
527 
528   // Get the raw instruction bits.
InstructionBits()529   inline Instr InstructionBits() const {
530     return *reinterpret_cast<const Instr*>(this);
531   }
532 
533   // Set the raw instruction bits to value.
SetInstructionBits(Instr value)534   inline void SetInstructionBits(Instr value) {
535     *reinterpret_cast<Instr*>(this) = value;
536   }
537 
538   // Read one particular bit out of the instruction bits.
Bit(int nr)539   inline int Bit(int nr) const {
540     return (InstructionBits() >> nr) & 1;
541   }
542 
543   // Read a bit field's value out of the instruction bits.
Bits(int hi,int lo)544   inline int Bits(int hi, int lo) const {
545     return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
546   }
547 
548   // Read a bit field out of the instruction bits.
BitField(int hi,int lo)549   inline int BitField(int hi, int lo) const {
550     return InstructionBits() & (((2 << (hi - lo)) - 1) << lo);
551   }
552 
553   // Static support.
554 
555   // Read one particular bit out of the instruction bits.
Bit(Instr instr,int nr)556   static inline int Bit(Instr instr, int nr) {
557     return (instr >> nr) & 1;
558   }
559 
560   // Read the value of a bit field out of the instruction bits.
Bits(Instr instr,int hi,int lo)561   static inline int Bits(Instr instr, int hi, int lo) {
562     return (instr >> lo) & ((2 << (hi - lo)) - 1);
563   }
564 
565 
566   // Read a bit field out of the instruction bits.
BitField(Instr instr,int hi,int lo)567   static inline int BitField(Instr instr, int hi, int lo) {
568     return instr & (((2 << (hi - lo)) - 1) << lo);
569   }
570 
571 
572   // Accessors for the different named fields used in the ARM encoding.
573   // The naming of these accessor corresponds to figure A3-1.
574   //
575   // Two kind of accessors are declared:
576   // - <Name>Field() will return the raw field, i.e. the field's bits at their
577   //   original place in the instruction encoding.
578   //   e.g. if instr is the 'addgt r0, r1, r2' instruction, encoded as
579   //   0xC0810002 ConditionField(instr) will return 0xC0000000.
580   // - <Name>Value() will return the field value, shifted back to bit 0.
581   //   e.g. if instr is the 'addgt r0, r1, r2' instruction, encoded as
582   //   0xC0810002 ConditionField(instr) will return 0xC.
583 
584 
585   // Generally applicable fields
ConditionValue()586   inline Condition ConditionValue() const {
587     return static_cast<Condition>(Bits(31, 28));
588   }
ConditionField()589   inline Condition ConditionField() const {
590     return static_cast<Condition>(BitField(31, 28));
591   }
592   DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionValue);
593   DECLARE_STATIC_TYPED_ACCESSOR(Condition, ConditionField);
594 
TypeValue()595   inline int TypeValue() const { return Bits(27, 25); }
596 
RnValue()597   inline int RnValue() const { return Bits(19, 16); }
598   DECLARE_STATIC_ACCESSOR(RnValue);
RdValue()599   inline int RdValue() const { return Bits(15, 12); }
600   DECLARE_STATIC_ACCESSOR(RdValue);
601 
CoprocessorValue()602   inline int CoprocessorValue() const { return Bits(11, 8); }
603   // Support for VFP.
604   // Vn(19-16) | Vd(15-12) |  Vm(3-0)
VnValue()605   inline int VnValue() const { return Bits(19, 16); }
VmValue()606   inline int VmValue() const { return Bits(3, 0); }
VdValue()607   inline int VdValue() const { return Bits(15, 12); }
NValue()608   inline int NValue() const { return Bit(7); }
MValue()609   inline int MValue() const { return Bit(5); }
DValue()610   inline int DValue() const { return Bit(22); }
RtValue()611   inline int RtValue() const { return Bits(15, 12); }
PValue()612   inline int PValue() const { return Bit(24); }
UValue()613   inline int UValue() const { return Bit(23); }
Opc1Value()614   inline int Opc1Value() const { return (Bit(23) << 2) | Bits(21, 20); }
Opc2Value()615   inline int Opc2Value() const { return Bits(19, 16); }
Opc3Value()616   inline int Opc3Value() const { return Bits(7, 6); }
SzValue()617   inline int SzValue() const { return Bit(8); }
VLValue()618   inline int VLValue() const { return Bit(20); }
VCValue()619   inline int VCValue() const { return Bit(8); }
VAValue()620   inline int VAValue() const { return Bits(23, 21); }
VBValue()621   inline int VBValue() const { return Bits(6, 5); }
VFPNRegValue(VFPRegPrecision pre)622   inline int VFPNRegValue(VFPRegPrecision pre) {
623     return VFPGlueRegValue(pre, 16, 7);
624   }
VFPMRegValue(VFPRegPrecision pre)625   inline int VFPMRegValue(VFPRegPrecision pre) {
626     return VFPGlueRegValue(pre, 0, 5);
627   }
VFPDRegValue(VFPRegPrecision pre)628   inline int VFPDRegValue(VFPRegPrecision pre) {
629     return VFPGlueRegValue(pre, 12, 22);
630   }
631 
632   // Fields used in Data processing instructions
OpcodeValue()633   inline int OpcodeValue() const {
634     return static_cast<Opcode>(Bits(24, 21));
635   }
OpcodeField()636   inline Opcode OpcodeField() const {
637     return static_cast<Opcode>(BitField(24, 21));
638   }
SValue()639   inline int SValue() const { return Bit(20); }
640     // with register
RmValue()641   inline int RmValue() const { return Bits(3, 0); }
642   DECLARE_STATIC_ACCESSOR(RmValue);
ShiftValue()643   inline int ShiftValue() const { return static_cast<ShiftOp>(Bits(6, 5)); }
ShiftField()644   inline ShiftOp ShiftField() const {
645     return static_cast<ShiftOp>(BitField(6, 5));
646   }
RegShiftValue()647   inline int RegShiftValue() const { return Bit(4); }
RsValue()648   inline int RsValue() const { return Bits(11, 8); }
ShiftAmountValue()649   inline int ShiftAmountValue() const { return Bits(11, 7); }
650     // with immediate
RotateValue()651   inline int RotateValue() const { return Bits(11, 8); }
Immed8Value()652   inline int Immed8Value() const { return Bits(7, 0); }
Immed4Value()653   inline int Immed4Value() const { return Bits(19, 16); }
ImmedMovwMovtValue()654   inline int ImmedMovwMovtValue() const {
655       return Immed4Value() << 12 | Offset12Value(); }
656 
657   // Fields used in Load/Store instructions
PUValue()658   inline int PUValue() const { return Bits(24, 23); }
PUField()659   inline int PUField() const { return BitField(24, 23); }
BValue()660   inline int  BValue() const { return Bit(22); }
WValue()661   inline int  WValue() const { return Bit(21); }
LValue()662   inline int  LValue() const { return Bit(20); }
663     // with register uses same fields as Data processing instructions above
664     // with immediate
Offset12Value()665   inline int Offset12Value() const { return Bits(11, 0); }
666     // multiple
RlistValue()667   inline int RlistValue() const { return Bits(15, 0); }
668     // extra loads and stores
SignValue()669   inline int SignValue() const { return Bit(6); }
HValue()670   inline int HValue() const { return Bit(5); }
ImmedHValue()671   inline int ImmedHValue() const { return Bits(11, 8); }
ImmedLValue()672   inline int ImmedLValue() const { return Bits(3, 0); }
673 
674   // Fields used in Branch instructions
LinkValue()675   inline int LinkValue() const { return Bit(24); }
SImmed24Value()676   inline int SImmed24Value() const { return ((InstructionBits() << 8) >> 8); }
677 
678   // Fields used in Software interrupt instructions
SvcValue()679   inline SoftwareInterruptCodes SvcValue() const {
680     return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
681   }
682 
683   // Test for special encodings of type 0 instructions (extra loads and stores,
684   // as well as multiplications).
IsSpecialType0()685   inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); }
686 
687   // Test for miscellaneous instructions encodings of type 0 instructions.
IsMiscType0()688   inline bool IsMiscType0() const { return (Bit(24) == 1)
689                                            && (Bit(23) == 0)
690                                            && (Bit(20) == 0)
691                                            && ((Bit(7) == 0)); }
692 
693   // Test for a stop instruction.
IsStop()694   inline bool IsStop() const {
695     return (TypeValue() == 7) && (Bit(24) == 1) && (SvcValue() >= kStopCode);
696   }
697 
698   // Special accessors that test for existence of a value.
HasS()699   inline bool HasS()    const { return SValue() == 1; }
HasB()700   inline bool HasB()    const { return BValue() == 1; }
HasW()701   inline bool HasW()    const { return WValue() == 1; }
HasL()702   inline bool HasL()    const { return LValue() == 1; }
HasU()703   inline bool HasU()    const { return UValue() == 1; }
HasSign()704   inline bool HasSign() const { return SignValue() == 1; }
HasH()705   inline bool HasH()    const { return HValue() == 1; }
HasLink()706   inline bool HasLink() const { return LinkValue() == 1; }
707 
708   // Decoding the double immediate in the vmov instruction.
709   double DoubleImmedVmov() const;
710 
711   // Instructions are read of out a code stream. The only way to get a
712   // reference to an instruction is to convert a pointer. There is no way
713   // to allocate or create instances of class Instruction.
714   // Use the At(pc) function to create references to Instruction.
At(byte * pc)715   static Instruction* At(byte* pc) {
716     return reinterpret_cast<Instruction*>(pc);
717   }
718 
719 
720  private:
721   // Join split register codes, depending on single or double precision.
722   // four_bit is the position of the least-significant bit of the four
723   // bit specifier. one_bit is the position of the additional single bit
724   // specifier.
VFPGlueRegValue(VFPRegPrecision pre,int four_bit,int one_bit)725   inline int VFPGlueRegValue(VFPRegPrecision pre, int four_bit, int one_bit) {
726     if (pre == kSinglePrecision) {
727       return (Bits(four_bit + 3, four_bit) << 1) | Bit(one_bit);
728     }
729     return (Bit(one_bit) << 4) | Bits(four_bit + 3, four_bit);
730   }
731 
732   // We need to prevent the creation of instances of class Instruction.
733   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
734 };
735 
736 
737 // Helper functions for converting between register numbers and names.
738 class Registers {
739  public:
740   // Return the name of the register.
741   static const char* Name(int reg);
742 
743   // Lookup the register number for the name provided.
744   static int Number(const char* name);
745 
746   struct RegisterAlias {
747     int reg;
748     const char* name;
749   };
750 
751  private:
752   static const char* names_[kNumRegisters];
753   static const RegisterAlias aliases_[];
754 };
755 
756 // Helper functions for converting between VFP register numbers and names.
757 class VFPRegisters {
758  public:
759   // Return the name of the register.
760   static const char* Name(int reg, bool is_double);
761 
762   // Lookup the register number for the name provided.
763   // Set flag pointed by is_double to true if register
764   // is double-precision.
765   static int Number(const char* name, bool* is_double);
766 
767  private:
768   static const char* names_[kNumVFPRegisters];
769 };
770 
771 
772 } }  // namespace v8::internal
773 
774 #endif  // V8_ARM_CONSTANTS_ARM_H_
775