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