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