OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_CONSTANTS_ARM_H_ | 5 #ifndef VM_CONSTANTS_ARM_H_ |
6 #define VM_CONSTANTS_ARM_H_ | 6 #define VM_CONSTANTS_ARM_H_ |
7 | 7 |
8 namespace dart { | 8 namespace dart { |
9 | 9 |
10 // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at | 10 // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 const int kNumberOfFpuRegisters = kNumberOfDRegisters; | 131 const int kNumberOfFpuRegisters = kNumberOfDRegisters; |
132 | 132 |
133 | 133 |
134 // Register aliases. | 134 // Register aliases. |
135 const Register TMP = kNoRegister; // No scratch register used by assembler. | 135 const Register TMP = kNoRegister; // No scratch register used by assembler. |
136 const Register CTX = R9; // Caches current context in generated code. | 136 const Register CTX = R9; // Caches current context in generated code. |
137 const Register SPREG = SP; | 137 const Register SPREG = SP; |
138 const Register FPREG = FP; | 138 const Register FPREG = FP; |
139 | 139 |
140 | 140 |
141 // Exception object is passed in this register to the catch handlers when an | |
142 // exception is thrown. | |
143 const Register kExceptionObjectReg = R0; | |
Ivan Posva
2013/01/24 18:25:57
Are you sure this is the right register? Or do you
regis
2013/01/24 21:47:48
The exception register is EAX/RAX on ia32/x64, so
| |
144 | |
145 | |
141 // Values for the condition field as defined in section A3.2. | 146 // Values for the condition field as defined in section A3.2. |
142 enum Condition { | 147 enum Condition { |
143 kNoCondition = -1, | 148 kNoCondition = -1, |
144 EQ = 0, // equal | 149 EQ = 0, // equal |
145 NE = 1, // not equal | 150 NE = 1, // not equal |
146 CS = 2, // carry set/unsigned higher or same | 151 CS = 2, // carry set/unsigned higher or same |
147 CC = 3, // carry clear/unsigned lower | 152 CC = 3, // carry clear/unsigned lower |
148 MI = 4, // minus/negative | 153 MI = 4, // minus/negative |
149 PL = 5, // plus/positive or zero | 154 PL = 5, // plus/positive or zero |
150 VS = 6, // overflow | 155 VS = 6, // overflow |
151 VC = 7, // no overflow | 156 VC = 7, // no overflow |
152 HI = 8, // unsigned higher | 157 HI = 8, // unsigned higher |
153 LS = 9, // unsigned lower or same | 158 LS = 9, // unsigned lower or same |
154 GE = 10, // signed greater than or equal | 159 GE = 10, // signed greater than or equal |
155 LT = 11, // signed less than | 160 LT = 11, // signed less than |
156 GT = 12, // signed greater than | 161 GT = 12, // signed greater than |
157 LE = 13, // signed less than or equal | 162 LE = 13, // signed less than or equal |
158 AL = 14, // always (unconditional) | 163 AL = 14, // always (unconditional) |
159 kSpecialCondition = 15, // special condition (refer to section A3.2.1) | 164 kSpecialCondition = 15, // special condition (refer to section A3.2.1) |
160 kMaxCondition = 16, | 165 kMaxCondition = 16, |
161 }; | 166 }; |
162 | 167 |
168 | |
169 // Opcodes for Data-processing instructions (instructions with a type 0 and 1) | |
170 // as defined in section A3.4 | |
171 enum Opcode { | |
172 kNoOperand = -1, | |
173 AND = 0, // Logical AND | |
174 EOR = 1, // Logical Exclusive OR | |
175 SUB = 2, // Subtract | |
176 RSB = 3, // Reverse Subtract | |
177 ADD = 4, // Add | |
178 ADC = 5, // Add with Carry | |
179 SBC = 6, // Subtract with Carry | |
180 RSC = 7, // Reverse Subtract with Carry | |
181 TST = 8, // Test | |
182 TEQ = 9, // Test Equivalence | |
183 CMP = 10, // Compare | |
184 CMN = 11, // Compare Negated | |
185 ORR = 12, // Logical (inclusive) OR | |
186 MOV = 13, // Move | |
187 BIC = 14, // Bit Clear | |
188 MVN = 15, // Move Not | |
189 kMaxOperand = 16 | |
190 }; | |
191 | |
192 | |
193 // Shifter types for Data-processing operands as defined in section A5.1.2. | |
194 enum Shift { | |
195 kNoShift = -1, | |
196 LSL = 0, // Logical shift left | |
197 LSR = 1, // Logical shift right | |
198 ASR = 2, // Arithmetic shift right | |
199 ROR = 3, // Rotate right | |
200 kMaxShift = 4 | |
201 }; | |
202 | |
203 | |
204 // Special Supervisor Call 24-bit codes used in the presence of the ARM | |
205 // simulator for redirection, breakpoints, stop messages, and spill markers. | |
206 // See /usr/include/asm/unistd.h | |
207 const uint32_t kRedirectionSvcCode = 0x90001f; // unused syscall, was sys_stty | |
208 const uint32_t kBreakpointSvcCode = 0x900020; // unused syscall, was sys_gtty | |
209 const uint32_t kStopMessageSvcCode = 0x9f0001; // __ARM_NR_breakpoint | |
210 const uint32_t kSpillMarkerSvcBase = 0x9f0100; // unused ARM private syscall | |
211 const uint32_t kWordSpillMarkerSvcCode = kSpillMarkerSvcBase + 1; | |
212 const uint32_t kDWordSpillMarkerSvcCode = kSpillMarkerSvcBase + 2; | |
213 | |
214 | |
215 // Constants used for the decoding or encoding of the individual fields of | |
216 // instructions. Based on the "Figure 3-1 ARM instruction set summary". | |
217 enum InstructionFields { | |
218 kConditionShift = 28, | |
219 kConditionBits = 4, | |
220 kTypeShift = 25, | |
221 kTypeBits = 3, | |
222 kLinkShift = 24, | |
223 kLinkBits = 1, | |
224 kUShift = 23, | |
225 kUBits = 1, | |
226 kOpcodeShift = 21, | |
227 kOpcodeBits = 4, | |
228 kSShift = 20, | |
229 kSBits = 1, | |
230 kRnShift = 16, | |
231 kRnBits = 4, | |
232 kRdShift = 12, | |
233 kRdBits = 4, | |
234 kRsShift = 8, | |
235 kRsBits = 4, | |
236 kRmShift = 0, | |
237 kRmBits = 4, | |
238 | |
239 // Immediate instruction fields encoding. | |
240 kRotateShift = 8, | |
241 kRotateBits = 4, | |
242 kImmed8Shift = 0, | |
243 kImmed8Bits = 8, | |
244 | |
245 // Shift instruction register fields encodings. | |
246 kShiftImmShift = 7, | |
247 kShiftRegisterShift = 8, | |
248 kShiftImmBits = 5, | |
249 kShiftShift = 5, | |
250 kShiftBits = 2, | |
251 | |
252 // Load/store instruction offset field encoding. | |
253 kOffset12Shift = 0, | |
254 kOffset12Bits = 12, | |
255 kOffset12Mask = 0x00000fff, | |
256 | |
257 // Mul instruction register fields encodings. | |
258 kMulRdShift = 16, | |
259 kMulRdBits = 4, | |
260 kMulRnShift = 12, | |
261 kMulRnBits = 4, | |
262 | |
263 kBranchOffsetMask = 0x00ffffff | |
264 }; | |
265 | |
266 | |
267 // The class Instr enables access to individual fields defined in the ARM | |
268 // architecture instruction set encoding as described in figure A3-1. | |
269 // | |
270 // Example: Test whether the instruction at ptr sets the condition code bits. | |
271 // | |
272 // bool InstructionSetsConditionCodes(byte* ptr) { | |
273 // Instr* instr = Instr::At(ptr); | |
274 // int type = instr->TypeField(); | |
275 // return ((type == 0) || (type == 1)) && instr->HasS(); | |
276 // } | |
277 // | |
278 class Instr { | |
279 public: | |
280 enum { | |
281 kInstrSize = 4, | |
282 kInstrSizeLog2 = 2, | |
283 kPCReadOffset = 8 | |
284 }; | |
285 | |
286 static const int kBreakPointInstructionSize = kInstrSize; | |
287 bool IsBreakPoint() { | |
288 return IsBkpt(); | |
289 } | |
290 | |
291 // Get the raw instruction bits. | |
292 inline int32_t InstructionBits() const { | |
293 return *reinterpret_cast<const int32_t*>(this); | |
294 } | |
295 | |
296 // Set the raw instruction bits to value. | |
297 inline void SetInstructionBits(int32_t value) { | |
298 *reinterpret_cast<int32_t*>(this) = value; | |
299 } | |
300 | |
301 // Read one particular bit out of the instruction bits. | |
302 inline int Bit(int nr) const { | |
303 return (InstructionBits() >> nr) & 1; | |
304 } | |
305 | |
306 // Read a bit field out of the instruction bits. | |
307 inline int Bits(int shift, int count) const { | |
308 return (InstructionBits() >> shift) & ((1 << count) - 1); | |
309 } | |
310 | |
311 | |
312 // Accessors for the different named fields used in the ARM encoding. | |
313 // The naming of these accessor corresponds to figure A3-1. | |
314 // Generally applicable fields | |
315 inline Condition ConditionField() const { | |
316 return static_cast<Condition>(Bits(kConditionShift, kConditionBits)); | |
317 } | |
318 inline int TypeField() const { return Bits(kTypeShift, kTypeBits); } | |
319 | |
320 inline Register RnField() const { return static_cast<Register>( | |
321 Bits(kRnShift, kRnBits)); } | |
322 inline Register RdField() const { return static_cast<Register>( | |
323 Bits(kRdShift, kRdBits)); } | |
324 | |
325 // Fields used in Data processing instructions | |
326 inline Opcode OpcodeField() const { | |
327 return static_cast<Opcode>(Bits(kOpcodeShift, kOpcodeBits)); | |
328 } | |
329 inline int SField() const { return Bits(kSShift, kSBits); } | |
330 // with register | |
331 inline Register RmField() const { | |
332 return static_cast<Register>(Bits(kRmShift, kRmBits)); | |
333 } | |
334 inline Shift ShiftField() const { return static_cast<Shift>( | |
335 Bits(kShiftShift, kShiftBits)); } | |
336 inline int RegShiftField() const { return Bit(4); } | |
337 inline Register RsField() const { | |
338 return static_cast<Register>(Bits(kRsShift, kRsBits)); | |
339 } | |
340 inline int ShiftAmountField() const { return Bits(kShiftImmShift, | |
341 kShiftImmBits); } | |
342 // with immediate | |
343 inline int RotateField() const { return Bits(kRotateShift, kRotateBits); } | |
344 inline int Immed8Field() const { return Bits(kImmed8Shift, kImmed8Bits); } | |
345 | |
346 // Fields used in Load/Store instructions | |
347 inline int PUField() const { return Bits(23, 2); } | |
348 inline int BField() const { return Bit(22); } | |
349 inline int WField() const { return Bit(21); } | |
350 inline int LField() const { return Bit(20); } | |
351 // with register uses same fields as Data processing instructions above | |
352 // with immediate | |
353 inline int Offset12Field() const { return Bits(kOffset12Shift, | |
354 kOffset12Bits); } | |
355 // multiple | |
356 inline int RlistField() const { return Bits(0, 16); } | |
357 // extra loads and stores | |
358 inline int SignField() const { return Bit(6); } | |
359 inline int HField() const { return Bit(5); } | |
360 inline int ImmedHField() const { return Bits(8, 4); } | |
361 inline int ImmedLField() const { return Bits(0, 4); } | |
362 | |
363 // Fields used in Branch instructions | |
364 inline int LinkField() const { return Bits(kLinkShift, kLinkBits); } | |
365 inline int SImmed24Field() const { return ((InstructionBits() << 8) >> 8); } | |
366 | |
367 // Fields used in Supervisor Call instructions | |
368 inline uint32_t SvcField() const { return Bits(0, 24); } | |
369 | |
370 // Field used in Breakpoint instruction | |
371 inline uint16_t BkptField() const { | |
372 return ((Bits(8, 12) << 4) | Bits(0, 4)); | |
373 } | |
374 | |
375 // Field used in 16-bit immediate move instructions | |
376 inline uint16_t MovwField() const { | |
377 return ((Bits(16, 4) << 12) | Bits(0, 12)); | |
378 } | |
379 | |
380 // Field used in VFP float immediate move instruction | |
381 inline float ImmFloatField() const { | |
382 uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) | | |
383 (Bits(16, 2) << 23) | (Bits(0, 4) << 19); | |
384 return bit_cast<float, uint32_t>(imm32); | |
385 } | |
386 | |
387 // Field used in VFP double immediate move instruction | |
388 inline double ImmDoubleField() const { | |
389 uint64_t imm64 = (Bit(19)*(1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) | | |
390 (Bits(16, 2)*(1LL << 52)) | (Bits(0, 4)*(1LL << 48)); | |
391 return bit_cast<double, uint64_t>(imm64); | |
392 } | |
393 | |
394 // Test for data processing instructions of type 0 or 1. | |
395 // See "ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition", | |
396 // section A5.1 "ARM instruction set encoding". | |
397 inline bool IsDataProcessing() const { | |
398 ASSERT(ConditionField() != kSpecialCondition); | |
399 ASSERT(Bits(26, 2) == 0); // Type 0 or 1. | |
400 return ((Bits(20, 5) & 0x19) != 0x10) && | |
401 ((Bit(25) == 1) || // Data processing immediate. | |
402 (Bit(4) == 0) || // Data processing register. | |
403 (Bit(7) == 0)); // Data processing register-shifted register. | |
404 } | |
405 | |
406 // Tests for special encodings of type 0 instructions (extra loads and stores, | |
407 // as well as multiplications, synchronization primitives, and miscellaneous). | |
408 // Can only be called for a type 0 or 1 instruction. | |
409 inline bool IsMiscellaneous() const { | |
410 ASSERT(Bits(26, 2) == 0); // Type 0 or 1. | |
411 return ((Bit(25) == 0) && ((Bits(20, 5) & 0x19) == 0x10) && (Bit(7) == 0)); | |
412 } | |
413 inline bool IsMultiplyOrSyncPrimitive() const { | |
414 ASSERT(Bits(26, 2) == 0); // Type 0 or 1. | |
415 return ((Bit(25) == 0) && (Bits(4, 4) == 9)); | |
416 } | |
417 | |
418 // Test for Supervisor Call instruction. | |
419 inline bool IsSvc() const { | |
420 return ((InstructionBits() & 0xff000000) == 0xef000000); | |
421 } | |
422 | |
423 // Test for Breakpoint instruction. | |
424 inline bool IsBkpt() const { | |
425 return ((InstructionBits() & 0xfff000f0) == 0xe1200070); | |
426 } | |
427 | |
428 // VFP register fields. | |
429 inline SRegister SnField() const { | |
430 return static_cast<SRegister>((Bits(kRnShift, kRnBits) << 1) + Bit(7)); | |
431 } | |
432 inline SRegister SdField() const { | |
433 return static_cast<SRegister>((Bits(kRdShift, kRdBits) << 1) + Bit(22)); | |
434 } | |
435 inline SRegister SmField() const { | |
436 return static_cast<SRegister>((Bits(kRmShift, kRmBits) << 1) + Bit(5)); | |
437 } | |
438 inline DRegister DnField() const { | |
439 return static_cast<DRegister>(Bits(kRnShift, kRnBits) + (Bit(7) << 4)); | |
440 } | |
441 inline DRegister DdField() const { | |
442 return static_cast<DRegister>(Bits(kRdShift, kRdBits) + (Bit(22) << 4)); | |
443 } | |
444 inline DRegister DmField() const { | |
445 return static_cast<DRegister>(Bits(kRmShift, kRmBits) + (Bit(5) << 4)); | |
446 } | |
447 | |
448 // Test for VFP data processing or single transfer instructions of type 7. | |
449 inline bool IsVFPDataProcessingOrSingleTransfer() const { | |
450 ASSERT(ConditionField() != kSpecialCondition); | |
451 ASSERT(TypeField() == 7); | |
452 return ((Bit(24) == 0) && (Bits(9, 3) == 5)); | |
453 // Bit(4) == 0: Data Processing | |
454 // Bit(4) == 1: 8, 16, or 32-bit Transfer between ARM Core and VFP | |
455 } | |
456 | |
457 // Test for VFP 64-bit transfer instructions of type 6. | |
458 inline bool IsVFPDoubleTransfer() const { | |
459 ASSERT(ConditionField() != kSpecialCondition); | |
460 ASSERT(TypeField() == 6); | |
461 return ((Bits(21, 4) == 2) && (Bits(9, 3) == 5) && | |
462 ((Bits(4, 4) & 0xd) == 1)); | |
463 } | |
464 | |
465 // Test for VFP load and store instructions of type 6. | |
466 inline bool IsVFPLoadStore() const { | |
467 ASSERT(ConditionField() != kSpecialCondition); | |
468 ASSERT(TypeField() == 6); | |
469 return ((Bits(20, 5) & 0x12) == 0x10) && (Bits(9, 3) == 5); | |
470 } | |
471 | |
472 // Special accessors that test for existence of a value. | |
473 inline bool HasS() const { return SField() == 1; } | |
474 inline bool HasB() const { return BField() == 1; } | |
475 inline bool HasW() const { return WField() == 1; } | |
476 inline bool HasL() const { return LField() == 1; } | |
477 inline bool HasSign() const { return SignField() == 1; } | |
478 inline bool HasH() const { return HField() == 1; } | |
479 inline bool HasLink() const { return LinkField() == 1; } | |
480 | |
481 // Instructions are read out of a code stream. The only way to get a | |
482 // reference to an instruction is to convert a pointer. There is no way | |
483 // to allocate or create instances of class Instr. | |
484 // Use the At(pc) function to create references to Instr. | |
485 static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); } | |
486 Instr* Next() { return this + kInstrSize; } | |
487 | |
488 private: | |
489 DISALLOW_ALLOCATION(); | |
490 DISALLOW_IMPLICIT_CONSTRUCTORS(Instr); | |
491 }; | |
492 | |
163 } // namespace dart | 493 } // namespace dart |
164 | 494 |
165 #endif // VM_CONSTANTS_ARM_H_ | 495 #endif // VM_CONSTANTS_ARM_H_ |
OLD | NEW |