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