Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: runtime/vm/constants_arm.h

Issue 12041056: Initial revision of ARM simulator and (empty) MIPS simulator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/dart.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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; // Unimplemented.
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_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/dart.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698