constants-arm.h revision 7f4d5bd8c03935e2c0cd412e561b8fc5a6a880ae
1// Copyright 2010 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// The simulator emulates the EABI so we define the USE_ARM_EABI macro if we
32// are not running on real ARM hardware.  One reason for this is that the
33// old ABI uses fp registers in the calling convention and the simulator does
34// not simulate fp registers or coroutine instructions.
35#if defined(__ARM_EABI__) || !defined(__arm__)
36# define USE_ARM_EABI 1
37#endif
38
39// This means that interwork-compatible jump instructions are generated.  We
40// want to generate them on the simulator too so it makes snapshots that can
41// be used on real hardware.
42#if defined(__THUMB_INTERWORK__) || !defined(__arm__)
43# define USE_THUMB_INTERWORK 1
44#endif
45
46#if defined(__ARM_ARCH_7A__) || \
47    defined(__ARM_ARCH_7R__) || \
48    defined(__ARM_ARCH_7__)
49# define CAN_USE_ARMV7_INSTRUCTIONS 1
50#endif
51
52#if defined(__ARM_ARCH_6__) ||   \
53    defined(__ARM_ARCH_6J__) ||  \
54    defined(__ARM_ARCH_6K__) ||  \
55    defined(__ARM_ARCH_6Z__) ||  \
56    defined(__ARM_ARCH_6ZK__) || \
57    defined(__ARM_ARCH_6T2__) || \
58    defined(CAN_USE_ARMV7_INSTRUCTIONS)
59# define CAN_USE_ARMV6_INSTRUCTIONS 1
60#endif
61
62#if defined(__ARM_ARCH_5T__)            || \
63    defined(__ARM_ARCH_5TE__)           || \
64    defined(CAN_USE_ARMV6_INSTRUCTIONS)
65# define CAN_USE_ARMV5_INSTRUCTIONS 1
66# define CAN_USE_THUMB_INSTRUCTIONS 1
67#endif
68
69// Simulator should support ARM5 instructions and unaligned access by default.
70#if !defined(__arm__)
71# define CAN_USE_ARMV5_INSTRUCTIONS 1
72# define CAN_USE_THUMB_INSTRUCTIONS 1
73
74# ifndef CAN_USE_UNALIGNED_ACCESSES
75#  define CAN_USE_UNALIGNED_ACCESSES 1
76# endif
77
78#endif
79
80#if CAN_USE_UNALIGNED_ACCESSES
81#define V8_TARGET_CAN_READ_UNALIGNED 1
82#endif
83
84// Using blx may yield better code, so use it when required or when available
85#if defined(USE_THUMB_INTERWORK) || defined(CAN_USE_ARMV5_INSTRUCTIONS)
86#define USE_BLX 1
87#endif
88
89namespace assembler {
90namespace arm {
91
92// Number of registers in normal ARM mode.
93static const int kNumRegisters = 16;
94
95// VFP support.
96static const int kNumVFPSingleRegisters = 32;
97static const int kNumVFPDoubleRegisters = 16;
98static const int kNumVFPRegisters =
99    kNumVFPSingleRegisters + kNumVFPDoubleRegisters;
100
101// PC is register 15.
102static const int kPCRegister = 15;
103static const int kNoRegister = -1;
104
105// Defines constants and accessor classes to assemble, disassemble and
106// simulate ARM instructions.
107//
108// Section references in the code refer to the "ARM Architecture Reference
109// Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
110//
111// Constants for specific fields are defined in their respective named enums.
112// General constants are in an anonymous enum in class Instr.
113
114typedef unsigned char byte;
115
116// Values for the condition field as defined in section A3.2
117enum Condition {
118  no_condition = -1,
119  EQ =  0,  // equal
120  NE =  1,  // not equal
121  CS =  2,  // carry set/unsigned higher or same
122  CC =  3,  // carry clear/unsigned lower
123  MI =  4,  // minus/negative
124  PL =  5,  // plus/positive or zero
125  VS =  6,  // overflow
126  VC =  7,  // no overflow
127  HI =  8,  // unsigned higher
128  LS =  9,  // unsigned lower or same
129  GE = 10,  // signed greater than or equal
130  LT = 11,  // signed less than
131  GT = 12,  // signed greater than
132  LE = 13,  // signed less than or equal
133  AL = 14,  // always (unconditional)
134  special_condition = 15,  // special condition (refer to section A3.2.1)
135  max_condition = 16
136};
137
138
139// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
140// as defined in section A3.4
141enum Opcode {
142  no_operand = -1,
143  AND =  0,  // Logical AND
144  EOR =  1,  // Logical Exclusive OR
145  SUB =  2,  // Subtract
146  RSB =  3,  // Reverse Subtract
147  ADD =  4,  // Add
148  ADC =  5,  // Add with Carry
149  SBC =  6,  // Subtract with Carry
150  RSC =  7,  // Reverse Subtract with Carry
151  TST =  8,  // Test
152  TEQ =  9,  // Test Equivalence
153  CMP = 10,  // Compare
154  CMN = 11,  // Compare Negated
155  ORR = 12,  // Logical (inclusive) OR
156  MOV = 13,  // Move
157  BIC = 14,  // Bit Clear
158  MVN = 15,  // Move Not
159  max_operand = 16
160};
161
162
163// The bits for bit 7-4 for some type 0 miscellaneous instructions.
164enum MiscInstructionsBits74 {
165  // With bits 22-21 01.
166  BX   =  1,
167  BXJ  =  2,
168  BLX  =  3,
169  BKPT =  7,
170
171  // With bits 22-21 11.
172  CLZ  =  1
173};
174
175
176// Shifter types for Data-processing operands as defined in section A5.1.2.
177enum Shift {
178  no_shift = -1,
179  LSL = 0,  // Logical shift left
180  LSR = 1,  // Logical shift right
181  ASR = 2,  // Arithmetic shift right
182  ROR = 3,  // Rotate right
183  max_shift = 4
184};
185
186
187// Special Software Interrupt codes when used in the presence of the ARM
188// simulator.
189enum SoftwareInterruptCodes {
190  // transition to C code
191  call_rt_redirected = 0x10,
192  // break point
193  break_point = 0x20
194};
195
196
197typedef int32_t instr_t;
198
199
200// The class Instr enables access to individual fields defined in the ARM
201// architecture instruction set encoding as described in figure A3-1.
202//
203// Example: Test whether the instruction at ptr does set the condition code
204// bits.
205//
206// bool InstructionSetsConditionCodes(byte* ptr) {
207//   Instr* instr = Instr::At(ptr);
208//   int type = instr->TypeField();
209//   return ((type == 0) || (type == 1)) && instr->HasS();
210// }
211//
212class Instr {
213 public:
214  enum {
215    kInstrSize = 4,
216    kInstrSizeLog2 = 2,
217    kPCReadOffset = 8
218  };
219
220  // Get the raw instruction bits.
221  inline instr_t InstructionBits() const {
222    return *reinterpret_cast<const instr_t*>(this);
223  }
224
225  // Set the raw instruction bits to value.
226  inline void SetInstructionBits(instr_t value) {
227    *reinterpret_cast<instr_t*>(this) = value;
228  }
229
230  // Read one particular bit out of the instruction bits.
231  inline int Bit(int nr) const {
232    return (InstructionBits() >> nr) & 1;
233  }
234
235  // Read a bit field out of the instruction bits.
236  inline int Bits(int hi, int lo) const {
237    return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
238  }
239
240
241  // Accessors for the different named fields used in the ARM encoding.
242  // The naming of these accessor corresponds to figure A3-1.
243  // Generally applicable fields
244  inline Condition ConditionField() const {
245    return static_cast<Condition>(Bits(31, 28));
246  }
247  inline int TypeField() const { return Bits(27, 25); }
248
249  inline int RnField() const { return Bits(19, 16); }
250  inline int RdField() const { return Bits(15, 12); }
251
252  inline int CoprocessorField() const { return Bits(11, 8); }
253  // Support for VFP.
254  // Vn(19-16) | Vd(15-12) |  Vm(3-0)
255  inline int VnField() const { return Bits(19, 16); }
256  inline int VmField() const { return Bits(3, 0); }
257  inline int VdField() const { return Bits(15, 12); }
258  inline int NField() const { return Bit(7); }
259  inline int MField() const { return Bit(5); }
260  inline int DField() const { return Bit(22); }
261  inline int RtField() const { return Bits(15, 12); }
262  inline int PField() const { return Bit(24); }
263  inline int UField() const { return Bit(23); }
264  inline int Opc1Field() const { return (Bit(23) << 2) | Bits(21, 20); }
265  inline int Opc2Field() const { return Bits(19, 16); }
266  inline int Opc3Field() const { return Bits(7, 6); }
267  inline int SzField() const { return Bit(8); }
268  inline int VLField() const { return Bit(20); }
269  inline int VCField() const { return Bit(8); }
270  inline int VAField() const { return Bits(23, 21); }
271  inline int VBField() const { return Bits(6, 5); }
272
273  // Fields used in Data processing instructions
274  inline Opcode OpcodeField() const {
275    return static_cast<Opcode>(Bits(24, 21));
276  }
277  inline int SField() const { return Bit(20); }
278    // with register
279  inline int RmField() const { return Bits(3, 0); }
280  inline Shift ShiftField() const { return static_cast<Shift>(Bits(6, 5)); }
281  inline int RegShiftField() const { return Bit(4); }
282  inline int RsField() const { return Bits(11, 8); }
283  inline int ShiftAmountField() const { return Bits(11, 7); }
284    // with immediate
285  inline int RotateField() const { return Bits(11, 8); }
286  inline int Immed8Field() const { return Bits(7, 0); }
287
288  // Fields used in Load/Store instructions
289  inline int PUField() const { return Bits(24, 23); }
290  inline int  BField() const { return Bit(22); }
291  inline int  WField() const { return Bit(21); }
292  inline int  LField() const { return Bit(20); }
293    // with register uses same fields as Data processing instructions above
294    // with immediate
295  inline int Offset12Field() const { return Bits(11, 0); }
296    // multiple
297  inline int RlistField() const { return Bits(15, 0); }
298    // extra loads and stores
299  inline int SignField() const { return Bit(6); }
300  inline int HField() const { return Bit(5); }
301  inline int ImmedHField() const { return Bits(11, 8); }
302  inline int ImmedLField() const { return Bits(3, 0); }
303
304  // Fields used in Branch instructions
305  inline int LinkField() const { return Bit(24); }
306  inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
307
308  // Fields used in Software interrupt instructions
309  inline SoftwareInterruptCodes SwiField() const {
310    return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
311  }
312
313  // Test for special encodings of type 0 instructions (extra loads and stores,
314  // as well as multiplications).
315  inline bool IsSpecialType0() const { return (Bit(7) == 1) && (Bit(4) == 1); }
316
317  // Test for miscellaneous instructions encodings of type 0 instructions.
318  inline bool IsMiscType0() const { return (Bit(24) == 1)
319                                           && (Bit(23) == 0)
320                                           && (Bit(20) == 0)
321                                           && ((Bit(7) == 0)); }
322
323  // Special accessors that test for existence of a value.
324  inline bool HasS()    const { return SField() == 1; }
325  inline bool HasB()    const { return BField() == 1; }
326  inline bool HasW()    const { return WField() == 1; }
327  inline bool HasL()    const { return LField() == 1; }
328  inline bool HasU()    const { return UField() == 1; }
329  inline bool HasSign() const { return SignField() == 1; }
330  inline bool HasH()    const { return HField() == 1; }
331  inline bool HasLink() const { return LinkField() == 1; }
332
333  // Instructions are read of out a code stream. The only way to get a
334  // reference to an instruction is to convert a pointer. There is no way
335  // to allocate or create instances of class Instr.
336  // Use the At(pc) function to create references to Instr.
337  static Instr* At(byte* pc) { return reinterpret_cast<Instr*>(pc); }
338
339 private:
340  // We need to prevent the creation of instances of class Instr.
341  DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
342};
343
344
345// Helper functions for converting between register numbers and names.
346class Registers {
347 public:
348  // Return the name of the register.
349  static const char* Name(int reg);
350
351  // Lookup the register number for the name provided.
352  static int Number(const char* name);
353
354  struct RegisterAlias {
355    int reg;
356    const char* name;
357  };
358
359 private:
360  static const char* names_[kNumRegisters];
361  static const RegisterAlias aliases_[];
362};
363
364// Helper functions for converting between VFP register numbers and names.
365class VFPRegisters {
366 public:
367  // Return the name of the register.
368  static const char* Name(int reg, bool is_double);
369
370  // Lookup the register number for the name provided.
371  // Set flag pointed by is_double to true if register
372  // is double-precision.
373  static int Number(const char* name, bool* is_double);
374
375 private:
376  static const char* names_[kNumVFPRegisters];
377};
378
379
380} }  // namespace assembler::arm
381
382#endif  // V8_ARM_CONSTANTS_ARM_H_
383