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