OLD | NEW |
---|---|
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 22 matching lines...) Expand all Loading... | |
33 // The original source code covered by the above license above has been | 33 // The original source code covered by the above license above has been |
34 // modified significantly by Google Inc. | 34 // modified significantly by Google Inc. |
35 // Copyright 2010 the V8 project authors. All rights reserved. | 35 // Copyright 2010 the V8 project authors. All rights reserved. |
36 | 36 |
37 // A light-weight ARM Assembler | 37 // A light-weight ARM Assembler |
38 // Generates user mode instructions for the ARM architecture up to version 5 | 38 // Generates user mode instructions for the ARM architecture up to version 5 |
39 | 39 |
40 #ifndef V8_ARM_ASSEMBLER_ARM_H_ | 40 #ifndef V8_ARM_ASSEMBLER_ARM_H_ |
41 #define V8_ARM_ASSEMBLER_ARM_H_ | 41 #define V8_ARM_ASSEMBLER_ARM_H_ |
42 #include <stdio.h> | 42 #include <stdio.h> |
43 #include "constants-arm.h" | |
Mads Ager (chromium)
2011/01/20 12:40:00
Can we keep the include list alphabeticed?
Alexandre
2011/01/21 16:22:15
Done.
| |
43 #include "assembler.h" | 44 #include "assembler.h" |
44 #include "serialize.h" | 45 #include "serialize.h" |
45 | 46 |
47 using namespace assembler::arm; | |
Mads Ager (chromium)
2011/01/20 12:40:00
We are not using 'using' directives. Have a look a
Alexandre
2011/01/21 16:22:15
Removed. We don't need it anymore as the assembler
| |
48 | |
46 namespace v8 { | 49 namespace v8 { |
47 namespace internal { | 50 namespace internal { |
48 | 51 |
49 // CPU Registers. | 52 // CPU Registers. |
50 // | 53 // |
51 // 1) We would prefer to use an enum, but enum values are assignment- | 54 // 1) We would prefer to use an enum, but enum values are assignment- |
52 // compatible with int, which has caused code-generation bugs. | 55 // compatible with int, which has caused code-generation bugs. |
53 // | 56 // |
54 // 2) We would prefer to use a class instead of a struct but we don't like | 57 // 2) We would prefer to use a class instead of a struct but we don't like |
55 // the register initialization to depend on the particular initialization | 58 // the register initialization to depend on the particular initialization |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 const DwVfpRegister d7 = { 7 }; | 296 const DwVfpRegister d7 = { 7 }; |
294 const DwVfpRegister d8 = { 8 }; | 297 const DwVfpRegister d8 = { 8 }; |
295 const DwVfpRegister d9 = { 9 }; | 298 const DwVfpRegister d9 = { 9 }; |
296 const DwVfpRegister d10 = { 10 }; | 299 const DwVfpRegister d10 = { 10 }; |
297 const DwVfpRegister d11 = { 11 }; | 300 const DwVfpRegister d11 = { 11 }; |
298 const DwVfpRegister d12 = { 12 }; | 301 const DwVfpRegister d12 = { 12 }; |
299 const DwVfpRegister d13 = { 13 }; | 302 const DwVfpRegister d13 = { 13 }; |
300 const DwVfpRegister d14 = { 14 }; | 303 const DwVfpRegister d14 = { 14 }; |
301 const DwVfpRegister d15 = { 15 }; | 304 const DwVfpRegister d15 = { 15 }; |
302 | 305 |
303 // VFP FPSCR constants. | |
304 static const uint32_t kVFPNConditionFlagBit = 1 << 31; | |
305 static const uint32_t kVFPZConditionFlagBit = 1 << 30; | |
306 static const uint32_t kVFPCConditionFlagBit = 1 << 29; | |
307 static const uint32_t kVFPVConditionFlagBit = 1 << 28; | |
308 | |
309 static const uint32_t kVFPFlushToZeroMask = 1 << 24; | |
310 | |
311 static const uint32_t kVFPRoundingModeMask = 3 << 22; | |
312 static const uint32_t kVFPRoundToMinusInfinityBits = 2 << 22; | |
313 | |
314 static const uint32_t kVFPExceptionMask = 0xf; | |
315 | 306 |
316 // Coprocessor register | 307 // Coprocessor register |
317 struct CRegister { | 308 struct CRegister { |
318 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 309 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
319 bool is(CRegister creg) const { return code_ == creg.code_; } | 310 bool is(CRegister creg) const { return code_ == creg.code_; } |
320 int code() const { | 311 int code() const { |
321 ASSERT(is_valid()); | 312 ASSERT(is_valid()); |
322 return code_; | 313 return code_; |
323 } | 314 } |
324 int bit() const { | 315 int bit() const { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 p9 = 9, | 356 p9 = 9, |
366 p10 = 10, | 357 p10 = 10, |
367 p11 = 11, | 358 p11 = 11, |
368 p12 = 12, | 359 p12 = 12, |
369 p13 = 13, | 360 p13 = 13, |
370 p14 = 14, | 361 p14 = 14, |
371 p15 = 15 | 362 p15 = 15 |
372 }; | 363 }; |
373 | 364 |
374 | 365 |
375 // Condition field in instructions. | |
376 enum Condition { | |
377 // any value < 0 is considered no_condition | |
378 no_condition = -1, | |
379 | |
380 eq = 0 << 28, // Z set equal. | |
381 ne = 1 << 28, // Z clear not equal. | |
382 nz = 1 << 28, // Z clear not zero. | |
383 cs = 2 << 28, // C set carry set. | |
384 hs = 2 << 28, // C set unsigned higher or same. | |
385 cc = 3 << 28, // C clear carry clear. | |
386 lo = 3 << 28, // C clear unsigned lower. | |
387 mi = 4 << 28, // N set negative. | |
388 pl = 5 << 28, // N clear positive or zero. | |
389 vs = 6 << 28, // V set overflow. | |
390 vc = 7 << 28, // V clear no overflow. | |
391 hi = 8 << 28, // C set, Z clear unsigned higher. | |
392 ls = 9 << 28, // C clear or Z set unsigned lower or same. | |
393 ge = 10 << 28, // N == V greater or equal. | |
394 lt = 11 << 28, // N != V less than. | |
395 gt = 12 << 28, // Z clear, N == V greater than. | |
396 le = 13 << 28, // Z set or N != V less then or equal | |
397 al = 14 << 28 // always. | |
398 }; | |
399 | |
400 | |
401 // Returns the equivalent of !cc. | |
402 inline Condition NegateCondition(Condition cc) { | |
403 ASSERT(cc != al); | |
404 return static_cast<Condition>(cc ^ ne); | |
405 } | |
406 | |
407 | |
408 // Corresponds to transposing the operands of a comparison. | |
409 inline Condition ReverseCondition(Condition cc) { | |
410 switch (cc) { | |
411 case lo: | |
412 return hi; | |
413 case hi: | |
414 return lo; | |
415 case hs: | |
416 return ls; | |
417 case ls: | |
418 return hs; | |
419 case lt: | |
420 return gt; | |
421 case gt: | |
422 return lt; | |
423 case ge: | |
424 return le; | |
425 case le: | |
426 return ge; | |
427 default: | |
428 return cc; | |
429 }; | |
430 } | |
431 | |
432 | |
433 // Branch hints are not used on the ARM. They are defined so that they can | |
434 // appear in shared function signatures, but will be ignored in ARM | |
435 // implementations. | |
436 enum Hint { no_hint }; | |
437 | |
438 // Hints are not used on the arm. Negating is trivial. | |
439 inline Hint NegateHint(Hint ignored) { return no_hint; } | |
440 | |
441 | |
442 // ----------------------------------------------------------------------------- | |
443 // Addressing modes and instruction variants | |
444 | |
445 // Shifter operand shift operation | |
446 enum ShiftOp { | |
447 LSL = 0 << 5, | |
448 LSR = 1 << 5, | |
449 ASR = 2 << 5, | |
450 ROR = 3 << 5, | |
451 RRX = -1 | |
452 }; | |
453 | |
454 | |
455 // Condition code updating mode | |
456 enum SBit { | |
457 SetCC = 1 << 20, // set condition code | |
458 LeaveCC = 0 << 20 // leave condition code unchanged | |
459 }; | |
460 | |
461 | |
462 // Status register selection | |
463 enum SRegister { | |
464 CPSR = 0 << 22, | |
465 SPSR = 1 << 22 | |
466 }; | |
467 | |
468 | |
469 // Status register fields | |
470 enum SRegisterField { | |
471 CPSR_c = CPSR | 1 << 16, | |
472 CPSR_x = CPSR | 1 << 17, | |
473 CPSR_s = CPSR | 1 << 18, | |
474 CPSR_f = CPSR | 1 << 19, | |
475 SPSR_c = SPSR | 1 << 16, | |
476 SPSR_x = SPSR | 1 << 17, | |
477 SPSR_s = SPSR | 1 << 18, | |
478 SPSR_f = SPSR | 1 << 19 | |
479 }; | |
480 | |
481 // Status register field mask (or'ed SRegisterField enum values) | |
482 typedef uint32_t SRegisterFieldMask; | |
483 | |
484 | |
485 // Memory operand addressing mode | |
486 enum AddrMode { | |
487 // bit encoding P U W | |
488 Offset = (8|4|0) << 21, // offset (without writeback to base) | |
489 PreIndex = (8|4|1) << 21, // pre-indexed addressing with writeback | |
490 PostIndex = (0|4|0) << 21, // post-indexed addressing with writeback | |
491 NegOffset = (8|0|0) << 21, // negative offset (without writeback to base) | |
492 NegPreIndex = (8|0|1) << 21, // negative pre-indexed with writeback | |
493 NegPostIndex = (0|0|0) << 21 // negative post-indexed with writeback | |
494 }; | |
495 | |
496 | |
497 // Load/store multiple addressing mode | |
498 enum BlockAddrMode { | |
499 // bit encoding P U W | |
500 da = (0|0|0) << 21, // decrement after | |
501 ia = (0|4|0) << 21, // increment after | |
502 db = (8|0|0) << 21, // decrement before | |
503 ib = (8|4|0) << 21, // increment before | |
504 da_w = (0|0|1) << 21, // decrement after with writeback to base | |
505 ia_w = (0|4|1) << 21, // increment after with writeback to base | |
506 db_w = (8|0|1) << 21, // decrement before with writeback to base | |
507 ib_w = (8|4|1) << 21 // increment before with writeback to base | |
508 }; | |
509 | |
510 | |
511 // Coprocessor load/store operand size | |
512 enum LFlag { | |
513 Long = 1 << 22, // long load/store coprocessor | |
514 Short = 0 << 22 // short load/store coprocessor | |
515 }; | |
516 | |
517 | |
518 // ----------------------------------------------------------------------------- | 366 // ----------------------------------------------------------------------------- |
519 // Machine instruction Operands | 367 // Machine instruction Operands |
520 | 368 |
521 // Class Operand represents a shifter operand in data processing instructions | 369 // Class Operand represents a shifter operand in data processing instructions |
522 class Operand BASE_EMBEDDED { | 370 class Operand BASE_EMBEDDED { |
523 public: | 371 public: |
524 // immediate | 372 // immediate |
525 INLINE(explicit Operand(int32_t immediate, | 373 INLINE(explicit Operand(int32_t immediate, |
526 RelocInfo::Mode rmode = RelocInfo::NONE)); | 374 RelocInfo::Mode rmode = RelocInfo::NONE)); |
527 INLINE(explicit Operand(const ExternalReference& f)); | 375 INLINE(explicit Operand(const ExternalReference& f)); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
651 #endif | 499 #endif |
652 }; | 500 }; |
653 | 501 |
654 private: | 502 private: |
655 static unsigned supported_; | 503 static unsigned supported_; |
656 static unsigned enabled_; | 504 static unsigned enabled_; |
657 static unsigned found_by_runtime_probing_; | 505 static unsigned found_by_runtime_probing_; |
658 }; | 506 }; |
659 | 507 |
660 | 508 |
661 typedef int32_t Instr; | |
662 | |
663 | |
664 extern const Instr kMovLrPc; | 509 extern const Instr kMovLrPc; |
665 extern const Instr kLdrPCMask; | 510 extern const Instr kLdrPCMask; |
666 extern const Instr kLdrPCPattern; | 511 extern const Instr kLdrPCPattern; |
667 extern const Instr kBlxRegMask; | 512 extern const Instr kBlxRegMask; |
668 extern const Instr kBlxRegPattern; | 513 extern const Instr kBlxRegPattern; |
669 | 514 |
670 extern const Instr kMovMvnMask; | 515 extern const Instr kMovMvnMask; |
671 extern const Instr kMovMvnPattern; | 516 extern const Instr kMovMvnPattern; |
672 extern const Instr kMovMvnFlip; | 517 extern const Instr kMovMvnFlip; |
673 | 518 |
674 extern const Instr kMovLeaveCCMask; | 519 extern const Instr kMovLeaveCCMask; |
675 extern const Instr kMovLeaveCCPattern; | 520 extern const Instr kMovLeaveCCPattern; |
676 extern const Instr kMovwMask; | 521 extern const Instr kMovwMask; |
677 extern const Instr kMovwPattern; | 522 extern const Instr kMovwPattern; |
678 extern const Instr kMovwLeaveCCFlip; | 523 extern const Instr kMovwLeaveCCFlip; |
679 | 524 |
680 extern const Instr kCmpCmnMask; | 525 extern const Instr kCmpCmnMask; |
681 extern const Instr kCmpCmnPattern; | 526 extern const Instr kCmpCmnPattern; |
682 extern const Instr kCmpCmnFlip; | 527 extern const Instr kCmpCmnFlip; |
683 | |
684 extern const Instr kALUMask; | |
685 extern const Instr kAddPattern; | |
686 extern const Instr kSubPattern; | |
687 extern const Instr kAndPattern; | |
688 extern const Instr kBicPattern; | |
689 extern const Instr kAddSubFlip; | 528 extern const Instr kAddSubFlip; |
690 extern const Instr kAndBicFlip; | 529 extern const Instr kAndBicFlip; |
691 | 530 |
531 | |
532 | |
692 class Assembler : public Malloced { | 533 class Assembler : public Malloced { |
693 public: | 534 public: |
694 // Create an assembler. Instructions and relocation information are emitted | 535 // Create an assembler. Instructions and relocation information are emitted |
695 // into a buffer, with the instructions starting from the beginning and the | 536 // into a buffer, with the instructions starting from the beginning and the |
696 // relocation information starting from the end of the buffer. See CodeDesc | 537 // relocation information starting from the end of the buffer. See CodeDesc |
697 // for a detailed comment on the layout (globals.h). | 538 // for a detailed comment on the layout (globals.h). |
698 // | 539 // |
699 // If the provided buffer is NULL, the assembler allocates and grows its own | 540 // If the provided buffer is NULL, the assembler allocates and grows its own |
700 // buffer, and buffer_size determines the initial buffer size. The buffer is | 541 // buffer, and buffer_size determines the initial buffer size. The buffer is |
701 // owned by the assembler and deallocated upon destruction of the assembler. | 542 // owned by the assembler and deallocated upon destruction of the assembler. |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
994 const MemOperand& src, Condition cond = al); | 835 const MemOperand& src, Condition cond = al); |
995 void strd(Register src1, | 836 void strd(Register src1, |
996 Register src2, | 837 Register src2, |
997 const MemOperand& dst, Condition cond = al); | 838 const MemOperand& dst, Condition cond = al); |
998 | 839 |
999 // Load/Store multiple instructions | 840 // Load/Store multiple instructions |
1000 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); | 841 void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al); |
1001 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); | 842 void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al); |
1002 | 843 |
1003 // Exception-generating instructions and debugging support | 844 // Exception-generating instructions and debugging support |
1004 static const int kDefaultStopCode = -1; | |
1005 void stop(const char* msg, | 845 void stop(const char* msg, |
1006 Condition cond = al, | 846 Condition cond = al, |
1007 int32_t code = kDefaultStopCode); | 847 int32_t code = kDefaultStopCode); |
1008 | 848 |
1009 void bkpt(uint32_t imm16); // v5 and above | 849 void bkpt(uint32_t imm16); // v5 and above |
1010 void svc(uint32_t imm24, Condition cond = al); | 850 void svc(uint32_t imm24, Condition cond = al); |
1011 | 851 |
1012 // Coprocessor instructions | 852 // Coprocessor instructions |
1013 | 853 |
1014 void cdp(Coprocessor coproc, int opcode_1, | 854 void cdp(Coprocessor coproc, int opcode_1, |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1422 public: | 1262 public: |
1423 explicit EnsureSpace(Assembler* assembler) { | 1263 explicit EnsureSpace(Assembler* assembler) { |
1424 assembler->CheckBuffer(); | 1264 assembler->CheckBuffer(); |
1425 } | 1265 } |
1426 }; | 1266 }; |
1427 | 1267 |
1428 | 1268 |
1429 } } // namespace v8::internal | 1269 } } // namespace v8::internal |
1430 | 1270 |
1431 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1271 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |