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