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