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