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