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