blob: 2d2acb7fa2a7861c7a4cc6b505512e822d73b3cf [file] [log] [blame]
Carl Shapiroa2e18e12011-06-21 18:57:55 -07001// Copyright 2009 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_CONSTANTS_ARM_H_
4#define ART_SRC_CONSTANTS_ARM_H_
5
6#include <stdint.h>
Ian Rogersb033c752011-07-20 12:22:35 -07007#include <iosfwd>
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07008#include "casts.h"
9#include "globals.h"
10#include "logging.h"
Carl Shapiroa2e18e12011-06-21 18:57:55 -070011
12namespace art {
13
14// Defines constants and accessor classes to assemble, disassemble and
15// simulate ARM instructions.
16//
17// Section references in the code refer to the "ARM Architecture Reference
18// Manual" from July 2005 (available at http://www.arm.com/miscPDFs/14128.pdf)
19//
20// Constants for specific fields are defined in their respective named enums.
21// General constants are in an anonymous enum in class Instr.
22
23
24// We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at
25// a time, so that compile time optimizations can be applied.
26// Warning: VFPv3-D32 is untested.
27#define VFPv3_D16
28#if defined(VFPv3_D16) == defined(VFPv3_D32)
29#error "Exactly one of VFPv3_D16 or VFPv3_D32 can be defined at a time."
30#endif
31
32
33// Values for registers.
34enum Register {
35 R0 = 0,
36 R1 = 1,
37 R2 = 2,
38 R3 = 3,
39 R4 = 4,
40 R5 = 5,
41 R6 = 6,
42 R7 = 7,
43 R8 = 8,
44 R9 = 9,
45 R10 = 10,
46 R11 = 11,
47 R12 = 12,
48 R13 = 13,
49 R14 = 14,
50 R15 = 15,
Ian Rogersb033c752011-07-20 12:22:35 -070051 TR = 9, // thread register
Carl Shapiroa2e18e12011-06-21 18:57:55 -070052 FP = 11,
53 IP = 12,
54 SP = 13,
55 LR = 14,
56 PC = 15,
57 kNumberOfCoreRegisters = 16,
58 kNoRegister = -1,
59};
Elliott Hughes1f359b02011-07-17 14:27:17 -070060std::ostream& operator<<(std::ostream& os, const Register& rhs);
Carl Shapiroa2e18e12011-06-21 18:57:55 -070061
62
63enum ScaleFactor {
64 TIMES_1 = 0,
65 TIMES_2 = 1,
66 TIMES_4 = 2,
67 TIMES_8 = 3
68};
69
70
71// Values for single-precision floating point registers.
72enum SRegister {
73 S0 = 0,
74 S1 = 1,
75 S2 = 2,
76 S3 = 3,
77 S4 = 4,
78 S5 = 5,
79 S6 = 6,
80 S7 = 7,
81 S8 = 8,
82 S9 = 9,
83 S10 = 10,
84 S11 = 11,
85 S12 = 12,
86 S13 = 13,
87 S14 = 14,
88 S15 = 15,
89 S16 = 16,
90 S17 = 17,
91 S18 = 18,
92 S19 = 19,
93 S20 = 20,
94 S21 = 21,
95 S22 = 22,
96 S23 = 23,
97 S24 = 24,
98 S25 = 25,
99 S26 = 26,
100 S27 = 27,
101 S28 = 28,
102 S29 = 29,
103 S30 = 30,
104 S31 = 31,
105 kNumberOfSRegisters = 32,
106 kNoSRegister = -1,
107};
Elliott Hughes1f359b02011-07-17 14:27:17 -0700108std::ostream& operator<<(std::ostream& os, const SRegister& rhs);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700109
110
111// Values for double-precision floating point registers.
112enum DRegister {
113 D0 = 0,
114 D1 = 1,
115 D2 = 2,
116 D3 = 3,
117 D4 = 4,
118 D5 = 5,
119 D6 = 6,
120 D7 = 7,
121 D8 = 8,
122 D9 = 9,
123 D10 = 10,
124 D11 = 11,
125 D12 = 12,
126 D13 = 13,
127 D14 = 14,
128 D15 = 15,
129#ifdef VFPv3_D16
130 kNumberOfDRegisters = 16,
131#else
132 D16 = 16,
133 D17 = 17,
134 D18 = 18,
135 D19 = 19,
136 D20 = 20,
137 D21 = 21,
138 D22 = 22,
139 D23 = 23,
140 D24 = 24,
141 D25 = 25,
142 D26 = 26,
143 D27 = 27,
144 D28 = 28,
145 D29 = 29,
146 D30 = 30,
147 D31 = 31,
148 kNumberOfDRegisters = 32,
149#endif
150 kNumberOfOverlappingDRegisters = 16,
151 kNoDRegister = -1,
152};
Elliott Hughes1f359b02011-07-17 14:27:17 -0700153std::ostream& operator<<(std::ostream& os, const DRegister& rhs);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700154
155
156// Values for the condition field as defined in section A3.2.
157enum Condition {
158 kNoCondition = -1,
159 EQ = 0, // equal
160 NE = 1, // not equal
161 CS = 2, // carry set/unsigned higher or same
162 CC = 3, // carry clear/unsigned lower
163 MI = 4, // minus/negative
164 PL = 5, // plus/positive or zero
165 VS = 6, // overflow
166 VC = 7, // no overflow
167 HI = 8, // unsigned higher
168 LS = 9, // unsigned lower or same
169 GE = 10, // signed greater than or equal
170 LT = 11, // signed less than
171 GT = 12, // signed greater than
172 LE = 13, // signed less than or equal
173 AL = 14, // always (unconditional)
174 kSpecialCondition = 15, // special condition (refer to section A3.2.1)
175 kMaxCondition = 16,
176};
Elliott Hughes1f359b02011-07-17 14:27:17 -0700177std::ostream& operator<<(std::ostream& os, const Condition& rhs);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700178
179
180// Opcodes for Data-processing instructions (instructions with a type 0 and 1)
181// as defined in section A3.4
182enum Opcode {
183 kNoOperand = -1,
184 AND = 0, // Logical AND
185 EOR = 1, // Logical Exclusive OR
186 SUB = 2, // Subtract
187 RSB = 3, // Reverse Subtract
188 ADD = 4, // Add
189 ADC = 5, // Add with Carry
190 SBC = 6, // Subtract with Carry
191 RSC = 7, // Reverse Subtract with Carry
192 TST = 8, // Test
193 TEQ = 9, // Test Equivalence
194 CMP = 10, // Compare
195 CMN = 11, // Compare Negated
196 ORR = 12, // Logical (inclusive) OR
197 MOV = 13, // Move
198 BIC = 14, // Bit Clear
199 MVN = 15, // Move Not
200 kMaxOperand = 16
201};
202
203
204// Shifter types for Data-processing operands as defined in section A5.1.2.
205enum Shift {
206 kNoShift = -1,
207 LSL = 0, // Logical shift left
208 LSR = 1, // Logical shift right
209 ASR = 2, // Arithmetic shift right
210 ROR = 3, // Rotate right
211 kMaxShift = 4
212};
213
214
215// Special Supervisor Call 24-bit codes used in the presence of the ARM
216// simulator for redirection, breakpoints, stop messages, and spill markers.
217// See /usr/include/asm/unistd.h
218const uint32_t kRedirectionSvcCode = 0x90001f; // unused syscall, was sys_stty
219const uint32_t kBreakpointSvcCode = 0x900020; // unused syscall, was sys_gtty
220const uint32_t kStopMessageSvcCode = 0x9f0001; // __ARM_NR_breakpoint
221const uint32_t kSpillMarkerSvcBase = 0x9f0100; // unused ARM private syscall
222const uint32_t kWordSpillMarkerSvcCode = kSpillMarkerSvcBase + 1;
223const uint32_t kDWordSpillMarkerSvcCode = kSpillMarkerSvcBase + 2;
224
225
226// Constants used for the decoding or encoding of the individual fields of
227// instructions. Based on the "Figure 3-1 ARM instruction set summary".
228enum InstructionFields {
229 kConditionShift = 28,
230 kConditionBits = 4,
231 kTypeShift = 25,
232 kTypeBits = 3,
233 kLinkShift = 24,
234 kLinkBits = 1,
235 kUShift = 23,
236 kUBits = 1,
237 kOpcodeShift = 21,
238 kOpcodeBits = 4,
239 kSShift = 20,
240 kSBits = 1,
241 kRnShift = 16,
242 kRnBits = 4,
243 kRdShift = 12,
244 kRdBits = 4,
245 kRsShift = 8,
246 kRsBits = 4,
247 kRmShift = 0,
248 kRmBits = 4,
249
250 // Immediate instruction fields encoding.
251 kRotateShift = 8,
252 kRotateBits = 4,
253 kImmed8Shift = 0,
254 kImmed8Bits = 8,
255
256 // Shift instruction register fields encodings.
257 kShiftImmShift = 7,
258 kShiftRegisterShift = 8,
259 kShiftImmBits = 5,
260 kShiftShift = 5,
261 kShiftBits = 2,
262
263 // Load/store instruction offset field encoding.
264 kOffset12Shift = 0,
265 kOffset12Bits = 12,
266 kOffset12Mask = 0x00000fff,
267
268 // Mul instruction register fields encodings.
269 kMulRdShift = 16,
270 kMulRdBits = 4,
271 kMulRnShift = 12,
272 kMulRnBits = 4,
273
274 kBranchOffsetMask = 0x00ffffff
275};
276
277
278// Size (in bytes) of registers.
279const int kRegisterSize = 4;
280
281// List of registers used in load/store multiple.
282typedef uint16_t RegList;
283
284const RegList kAllCoreRegistersList = 0xFFFF;
285
286// C++ ABI call registers
287const int kAbiRegisterCount = 4;
288const Register kAbiRegisters[kAbiRegisterCount] = { R0, R1, R2, R3 };
289const RegList kAbiRegisterList = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3);
290
291// Parfait callee-saved registers.
292#ifdef DEBUG
293// Save FP only in Debug mode.
294static const Register kUnsavedCoreRegisters[] = { IP, SP, LR, PC };
295static const RegList kUnsavedCoreRegistersList =
296 (1 << IP | 1 << SP | 1 << LR | 1 << PC);
297#else
298static const Register kUnsavedCoreRegisters[] = { FP, IP, SP, LR, PC };
299static const RegList kUnsavedCoreRegistersList =
300 (1 << FP | 1 << IP | 1 << SP | 1 << LR | 1 << PC);
301#endif // DEBUG
302static const RegList kSavedCoreRegistersList =
303 kAllCoreRegistersList & (~kUnsavedCoreRegistersList);
304static const int kNumberOfUnsavedCoreRegisters =
305 arraysize(kUnsavedCoreRegisters);
306static const int kNumberOfSavedCoreRegisters =
307 kNumberOfCoreRegisters - kNumberOfUnsavedCoreRegisters;
308
309// D8-D15 are ABI callee saved. No need to save them. If there are more than 16
310// D-registers than the following ones (D16 ...) are not ABI callee saved and
311// must be saved by parfait.
312static const int kNumberOfUnsavedDRegisters = 8;
313static const int kNumberOfSavedDRegisters =
314 kNumberOfDRegisters - kNumberOfUnsavedDRegisters;
315
316// Frame layout constants.
317const int kExitLinkByteOffsetFromFp = 9 * kPointerSize;
318const int kSpByteOffsetFromPreviousFp = 2 * kPointerSize;
319const int kPcAddressByteOffsetFromSp = -1 * kPointerSize;
320const int kPcAddressByteOffsetFromExitFp = -1 * kPointerSize;
321const int kCallSaveArea = 2 * kPointerSize;
322const int kCallerSavedCoreRegistersByteOffsetFromFp = -2 * kPointerSize;
323
324// The class Instr enables access to individual fields defined in the ARM
325// architecture instruction set encoding as described in figure A3-1.
326//
327// Example: Test whether the instruction at ptr does set the condition code
328// bits.
329//
330// bool InstructionSetsConditionCodes(byte* ptr) {
331// Instr* instr = Instr::At(ptr);
332// int type = instr->TypeField();
333// return ((type == 0) || (type == 1)) && instr->HasS();
334// }
335//
336class Instr {
337 public:
338 enum {
339 kInstrSize = 4,
340 kInstrSizeLog2 = 2,
341 kPCReadOffset = 8
342 };
343
344 static const int kBreakPointInstructionSize = kInstrSize;
345 bool IsBreakPoint() {
346 return IsBkpt();
347 }
348
349 // Get the raw instruction bits.
350 inline int32_t InstructionBits() const {
351 return *reinterpret_cast<const int32_t*>(this);
352 }
353
354 // Set the raw instruction bits to value.
355 inline void SetInstructionBits(int32_t value) {
356 *reinterpret_cast<int32_t*>(this) = value;
357 }
358
359 // Read one particular bit out of the instruction bits.
360 inline int Bit(int nr) const {
361 return (InstructionBits() >> nr) & 1;
362 }
363
364 // Read a bit field out of the instruction bits.
365 inline int Bits(int shift, int count) const {
366 return (InstructionBits() >> shift) & ((1 << count) - 1);
367 }
368
369
370 // Accessors for the different named fields used in the ARM encoding.
371 // The naming of these accessor corresponds to figure A3-1.
372 // Generally applicable fields
373 inline Condition ConditionField() const {
374 return static_cast<Condition>(Bits(kConditionShift, kConditionBits));
375 }
376 inline int TypeField() const { return Bits(kTypeShift, kTypeBits); }
377
378 inline Register RnField() const { return static_cast<Register>(
379 Bits(kRnShift, kRnBits)); }
380 inline Register RdField() const { return static_cast<Register>(
381 Bits(kRdShift, kRdBits)); }
382
383 // Fields used in Data processing instructions
384 inline Opcode OpcodeField() const {
385 return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
386 }
387 inline int SField() const { return Bits(kSShift, kSBits); }
388 // with register
389 inline Register RmField() const {
390 return static_cast<Register>(Bits(kRmShift, kRmBits));
391 }
392 inline Shift ShiftField() const { return static_cast<Shift>(
393 Bits(kShiftShift, kShiftBits)); }
394 inline int RegShiftField() const { return Bit(4); }
395 inline Register RsField() const {
396 return static_cast<Register>(Bits(kRsShift, kRsBits));
397 }
398 inline int ShiftAmountField() const { return Bits(kShiftImmShift,
399 kShiftImmBits); }
400 // with immediate
401 inline int RotateField() const { return Bits(kRotateShift, kRotateBits); }
402 inline int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); }
403
404 // Fields used in Load/Store instructions
405 inline int PUField() const { return Bits(23, 2); }
406 inline int BField() const { return Bit(22); }
407 inline int WField() const { return Bit(21); }
408 inline int LField() const { return Bit(20); }
409 // with register uses same fields as Data processing instructions above
410 // with immediate
411 inline int Offset12Field() const { return Bits(kOffset12Shift,
412 kOffset12Bits); }
413 // multiple
414 inline int RlistField() const { return Bits(0, 16); }
415 // extra loads and stores
416 inline int SignField() const { return Bit(6); }
417 inline int HField() const { return Bit(5); }
418 inline int ImmedHField() const { return Bits(8, 4); }
419 inline int ImmedLField() const { return Bits(0, 4); }
420
421 // Fields used in Branch instructions
422 inline int LinkField() const { return Bits(kLinkShift, kLinkBits); }
423 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
424
425 // Fields used in Supervisor Call instructions
426 inline uint32_t SvcField() const { return Bits(0, 24); }
427
428 // Field used in Breakpoint instruction
429 inline uint16_t BkptField() const {
430 return ((Bits(8, 12) << 4) | Bits(0, 4));
431 }
432
433 // Field used in 16-bit immediate move instructions
434 inline uint16_t MovwField() const {
435 return ((Bits(16, 4) << 12) | Bits(0, 12));
436 }
437
438 // Field used in VFP float immediate move instruction
439 inline float ImmFloatField() const {
440 uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) |
441 (Bits(16, 2) << 23) | (Bits(0, 4) << 19);
442 return bit_cast<float, uint32_t>(imm32);
443 }
444
445 // Field used in VFP double immediate move instruction
446 inline double ImmDoubleField() const {
447 uint64_t imm64 = (Bit(19)*(1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) |
448 (Bits(16, 2)*(1LL << 52)) | (Bits(0, 4)*(1LL << 48));
449 return bit_cast<double, uint64_t>(imm64);
450 }
451
452 // Test for data processing instructions of type 0 or 1.
453 // See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition",
454 // section A5.1 "ARM instruction set encoding".
455 inline bool IsDataProcessing() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700456 CHECK_NE(ConditionField(), kSpecialCondition);
457 CHECK_EQ(Bits(26, 2), 0); // Type 0 or 1.
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700458 return ((Bits(20, 5) & 0x19) != 0x10) &&
459 ((Bit(25) == 1) || // Data processing immediate.
460 (Bit(4) == 0) || // Data processing register.
461 (Bit(7) == 0)); // Data processing register-shifted register.
462 }
463
464 // Tests for special encodings of type 0 instructions (extra loads and stores,
465 // as well as multiplications, synchronization primitives, and miscellaneous).
466 // Can only be called for a type 0 or 1 instruction.
467 inline bool IsMiscellaneous() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700468 CHECK_EQ(Bits(26, 2), 0); // Type 0 or 1.
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700469 return ((Bit(25) == 0) && ((Bits(20, 5) & 0x19) == 0x10) && (Bit(7) == 0));
470 }
471 inline bool IsMultiplyOrSyncPrimitive() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700472 CHECK_EQ(Bits(26, 2), 0); // Type 0 or 1.
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700473 return ((Bit(25) == 0) && (Bits(4, 4) == 9));
474 }
475
476 // Test for Supervisor Call instruction.
477 inline bool IsSvc() const {
478 return ((InstructionBits() & 0xff000000) == 0xef000000);
479 }
480
481 // Test for Breakpoint instruction.
482 inline bool IsBkpt() const {
483 return ((InstructionBits() & 0xfff000f0) == 0xe1200070);
484 }
485
486 // VFP register fields.
487 inline SRegister SnField() const {
488 return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7));
489 }
490 inline SRegister SdField() const {
491 return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22));
492 }
493 inline SRegister SmField() const {
494 return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5));
495 }
496 inline DRegister DnField() const {
497 return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4));
498 }
499 inline DRegister DdField() const {
500 return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4));
501 }
502 inline DRegister DmField() const {
503 return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4));
504 }
505
506 // Test for VFP data processing or single transfer instructions of type 7.
507 inline bool IsVFPDataProcessingOrSingleTransfer() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700508 CHECK_NE(ConditionField(), kSpecialCondition);
509 CHECK_EQ(TypeField(), 7);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700510 return ((Bit(24) == 0) && (Bits(9, 3) == 5));
511 // Bit(4) == 0: Data Processing
512 // Bit(4) == 1: 8, 16, or 32-bit Transfer between ARM Core and VFP
513 }
514
515 // Test for VFP 64-bit transfer instructions of type 6.
516 inline bool IsVFPDoubleTransfer() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700517 CHECK_NE(ConditionField(), kSpecialCondition);
518 CHECK_EQ(TypeField(), 6);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700519 return ((Bits(21, 4) == 2) && (Bits(9, 3) == 5) &&
520 ((Bits(4, 4) & 0xd) == 1));
521 }
522
523 // Test for VFP load and store instructions of type 6.
524 inline bool IsVFPLoadStore() const {
Ian Rogersb033c752011-07-20 12:22:35 -0700525 CHECK_NE(ConditionField(), kSpecialCondition);
526 CHECK_EQ(TypeField(), 6);
Carl Shapiroa2e18e12011-06-21 18:57:55 -0700527 return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5);
528 }
529
530 // Special accessors that test for existence of a value.
531 inline bool HasS() const { return SField() == 1; }
532 inline bool HasB() const { return BField() == 1; }
533 inline bool HasW() const { return WField() == 1; }
534 inline bool HasL() const { return LField() == 1; }
535 inline bool HasSign() const { return SignField() == 1; }
536 inline bool HasH() const { return HField() == 1; }
537 inline bool HasLink() const { return LinkField() == 1; }
538
539 // Instructions are read out of a code stream. The only way to get a
540 // reference to an instruction is to convert a pointer. There is no way
541 // to allocate or create instances of class Instr.
542 // Use the At(pc) function to create references to Instr.
543 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
544 Instr* Next() { return this + kInstrSize; }
545
546 private:
547 // We need to prevent the creation of instances of class Instr.
548 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
549};
550
551} // namespace art
552
553#endif // ART_SRC_CONSTANTS_ARM_H_