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