• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 
17 #ifndef ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
18 #define ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
19 
20 #include <stdint.h>
21 
22 #include <iosfwd>
23 
24 #include "arch/arm/registers_arm.h"
25 #include "base/casts.h"
26 #include "base/logging.h"
27 #include "globals.h"
28 
29 namespace art {
30 namespace arm {
31 
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 
51 enum ScaleFactor {
52   TIMES_1 = 0,
53   TIMES_2 = 1,
54   TIMES_4 = 2,
55   TIMES_8 = 3
56 };
57 
58 // Values for double-precision floating point registers.
59 enum 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 };
100 std::ostream& operator<<(std::ostream& os, const DRegister& rhs);
101 
102 
103 // Values for the condition field as defined in section A3.2.
104 enum 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 };
124 std::ostream& operator<<(std::ostream& os, const Condition& rhs);
125 
126 
127 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
128 // as defined in section A3.4
129 enum 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.
152 enum 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 
162 // Constants used for the decoding or encoding of the individual fields of
163 // instructions. Based on the "Figure 3-1 ARM instruction set summary".
164 enum 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.
215 const int kRegisterSize = 4;
216 
217 // List of registers used in load/store multiple.
218 typedef uint16_t RegList;
219 
220 // 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 //
232 class Instr {
233  public:
234   enum {
235     kInstrSize = 4,
236     kInstrSizeLog2 = 2,
237     kPCReadOffset = 8
238   };
239 
IsBreakPoint()240   bool IsBreakPoint() {
241     return IsBkpt();
242   }
243 
244   // Get the raw instruction bits.
InstructionBits()245   inline int32_t InstructionBits() const {
246     return *reinterpret_cast<const int32_t*>(this);
247   }
248 
249   // Set the raw instruction bits to value.
SetInstructionBits(int32_t 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.
Bit(int nr)255   inline int Bit(int nr) const {
256     return (InstructionBits() >> nr) & 1;
257   }
258 
259   // Read a bit field out of the instruction bits.
Bits(int shift,int count)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
ConditionField()268   inline Condition ConditionField() const {
269     return static_cast<Condition>(Bits(kConditionShift, kConditionBits));
270   }
TypeField()271   inline int TypeField() const { return Bits(kTypeShift, kTypeBits); }
272 
RnField()273   inline Register RnField() const { return static_cast<Register>(
274                                         Bits(kRnShift, kRnBits)); }
RdField()275   inline Register RdField() const { return static_cast<Register>(
276                                         Bits(kRdShift, kRdBits)); }
277 
278   // Fields used in Data processing instructions
OpcodeField()279   inline Opcode OpcodeField() const {
280     return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits));
281   }
SField()282   inline int SField() const { return Bits(kSShift, kSBits); }
283   // with register
RmField()284   inline Register RmField() const {
285     return static_cast<Register>(Bits(kRmShift, kRmBits));
286   }
ShiftField()287   inline Shift ShiftField() const { return static_cast<Shift>(
288                                         Bits(kShiftShift, kShiftBits)); }
RegShiftField()289   inline int RegShiftField() const { return Bit(4); }
RsField()290   inline Register RsField() const {
291     return static_cast<Register>(Bits(kRsShift, kRsBits));
292   }
ShiftAmountField()293   inline int ShiftAmountField() const { return Bits(kShiftImmShift,
294                                                     kShiftImmBits); }
295   // with immediate
RotateField()296   inline int RotateField() const { return Bits(kRotateShift, kRotateBits); }
Immed8Field()297   inline int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); }
298 
299   // Fields used in Load/Store instructions
PUField()300   inline int PUField() const { return Bits(23, 2); }
BField()301   inline int  BField() const { return Bit(22); }
WField()302   inline int  WField() const { return Bit(21); }
LField()303   inline int  LField() const { return Bit(20); }
304   // with register uses same fields as Data processing instructions above
305   // with immediate
Offset12Field()306   inline int Offset12Field() const { return Bits(kOffset12Shift,
307                                                  kOffset12Bits); }
308   // multiple
RlistField()309   inline int RlistField() const { return Bits(0, 16); }
310   // extra loads and stores
SignField()311   inline int SignField() const { return Bit(6); }
HField()312   inline int HField() const { return Bit(5); }
ImmedHField()313   inline int ImmedHField() const { return Bits(8, 4); }
ImmedLField()314   inline int ImmedLField() const { return Bits(0, 4); }
315 
316   // Fields used in Branch instructions
LinkField()317   inline int LinkField() const { return Bits(kLinkShift, kLinkBits); }
SImmed24Field()318   inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); }
319 
320   // Fields used in Supervisor Call instructions
SvcField()321   inline uint32_t SvcField() const { return Bits(0, 24); }
322 
323   // Field used in Breakpoint instruction
BkptField()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
MovwField()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
ImmFloatField()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
ImmDoubleField()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".
IsDataProcessing()350   inline bool IsDataProcessing() const {
351     CHECK_NE(ConditionField(), kSpecialCondition);
352     CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
353     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.
IsMiscellaneous()362   inline bool IsMiscellaneous() const {
363     CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
364     return ((Bit(25) == 0) && ((Bits(20, 5) & 0x19) == 0x10) && (Bit(7) == 0));
365   }
IsMultiplyOrSyncPrimitive()366   inline bool IsMultiplyOrSyncPrimitive() const {
367     CHECK_EQ(Bits(26, 2), 0);  // Type 0 or 1.
368     return ((Bit(25) == 0) && (Bits(4, 4) == 9));
369   }
370 
371   // Test for Supervisor Call instruction.
IsSvc()372   inline bool IsSvc() const {
373     return ((InstructionBits() & 0xff000000) == 0xef000000);
374   }
375 
376   // Test for Breakpoint instruction.
IsBkpt()377   inline bool IsBkpt() const {
378     return ((InstructionBits() & 0xfff000f0) == 0xe1200070);
379   }
380 
381   // VFP register fields.
SnField()382   inline SRegister SnField() const {
383     return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7));
384   }
SdField()385   inline SRegister SdField() const {
386     return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22));
387   }
SmField()388   inline SRegister SmField() const {
389     return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5));
390   }
DnField()391   inline DRegister DnField() const {
392     return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4));
393   }
DdField()394   inline DRegister DdField() const {
395     return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4));
396   }
DmField()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.
IsVFPDataProcessingOrSingleTransfer()402   inline bool IsVFPDataProcessingOrSingleTransfer() const {
403     CHECK_NE(ConditionField(), kSpecialCondition);
404     CHECK_EQ(TypeField(), 7);
405     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.
IsVFPDoubleTransfer()411   inline bool IsVFPDoubleTransfer() const {
412     CHECK_NE(ConditionField(), kSpecialCondition);
413     CHECK_EQ(TypeField(), 6);
414     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.
IsVFPLoadStore()419   inline bool IsVFPLoadStore() const {
420     CHECK_NE(ConditionField(), kSpecialCondition);
421     CHECK_EQ(TypeField(), 6);
422     return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5);
423   }
424 
425   // Special accessors that test for existence of a value.
HasS()426   inline bool HasS() const { return SField() == 1; }
HasB()427   inline bool HasB() const { return BField() == 1; }
HasW()428   inline bool HasW() const { return WField() == 1; }
HasL()429   inline bool HasL() const { return LField() == 1; }
HasSign()430   inline bool HasSign() const { return SignField() == 1; }
HasH()431   inline bool HasH() const { return HField() == 1; }
HasLink()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.
At(uword pc)438   static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
Next()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 
446 }  // namespace arm
447 }  // namespace art
448 
449 #endif  // ART_COMPILER_UTILS_ARM_CONSTANTS_ARM_H_
450