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 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize); | 517 return Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize); |
518 } | 518 } |
519 INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) { | 519 INLINE(static Operand DoubleOffsetFromSmiKey(Register key)) { |
520 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); | 520 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); |
521 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); | 521 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); |
522 } | 522 } |
523 | 523 |
524 // rm <shift_op> rs | 524 // rm <shift_op> rs |
525 explicit Operand(Register rm, ShiftOp shift_op, Register rs); | 525 explicit Operand(Register rm, ShiftOp shift_op, Register rs); |
526 | 526 |
| 527 static Operand EmbeddedNumber(double value); // Smi or HeapNumber |
| 528 |
527 // Return true if this is a register operand. | 529 // Return true if this is a register operand. |
528 INLINE(bool is_reg() const) { | 530 INLINE(bool is_reg() const) { |
529 return rm_.is_valid() && | 531 return rm_.is_valid() && |
530 rs_.is(no_reg) && | 532 rs_.is(no_reg) && |
531 shift_op_ == LSL && | 533 shift_op_ == LSL && |
532 shift_imm_ == 0; | 534 shift_imm_ == 0; |
533 } | 535 } |
534 | 536 |
535 // Return the number of actual instructions required to implement the given | 537 // Return the number of actual instructions required to implement the given |
536 // instruction for this particular operand. This can be a single instruction, | 538 // instruction for this particular operand. This can be a single instruction, |
537 // if no load into the ip register is necessary, or anything between 2 and 4 | 539 // if no load into the ip register is necessary, or anything between 2 and 4 |
538 // instructions when we need to load from the constant pool (depending upon | 540 // instructions when we need to load from the constant pool (depending upon |
539 // whether the constant pool entry is in the small or extended section). If | 541 // whether the constant pool entry is in the small or extended section). If |
540 // the instruction this operand is used for is a MOV or MVN instruction the | 542 // the instruction this operand is used for is a MOV or MVN instruction the |
541 // actual instruction to use is required for this calculation. For other | 543 // actual instruction to use is required for this calculation. For other |
542 // instructions instr is ignored. | 544 // instructions instr is ignored. |
543 // | 545 // |
544 // The value returned is only valid as long as no entries are added to the | 546 // The value returned is only valid as long as no entries are added to the |
545 // constant pool between this call and the actual instruction being emitted. | 547 // constant pool between this call and the actual instruction being emitted. |
546 int instructions_required(const Assembler* assembler, Instr instr = 0) const; | 548 int instructions_required(const Assembler* assembler, Instr instr = 0) const; |
547 bool must_output_reloc_info(const Assembler* assembler) const; | 549 bool must_output_reloc_info(const Assembler* assembler) const; |
548 | 550 |
549 inline int32_t immediate() const { | 551 inline int32_t immediate() const { |
550 DCHECK(!rm_.is_valid()); | 552 DCHECK(!rm_.is_valid()); |
551 return imm32_; | 553 DCHECK(!is_heap_number()); |
| 554 return value_.immediate; |
| 555 } |
| 556 |
| 557 double heap_number() const { |
| 558 DCHECK(is_heap_number()); |
| 559 return value_.heap_number; |
552 } | 560 } |
553 | 561 |
554 Register rm() const { return rm_; } | 562 Register rm() const { return rm_; } |
555 Register rs() const { return rs_; } | 563 Register rs() const { return rs_; } |
556 ShiftOp shift_op() const { return shift_op_; } | 564 ShiftOp shift_op() const { return shift_op_; } |
| 565 bool is_heap_number() const { |
| 566 DCHECK_IMPLIES(is_heap_number_, !rm_.is_valid()); |
| 567 DCHECK_IMPLIES(is_heap_number_, rmode_ == RelocInfo::EMBEDDED_OBJECT); |
| 568 return is_heap_number_; |
| 569 } |
| 570 |
557 | 571 |
558 private: | 572 private: |
559 Register rm_; | 573 Register rm_; |
560 Register rs_; | 574 Register rs_; |
561 ShiftOp shift_op_; | 575 ShiftOp shift_op_; |
562 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg | 576 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg |
563 int32_t imm32_; // valid if rm_ == no_reg | 577 union { |
| 578 double heap_number; // if is_heap_number_ |
| 579 int32_t immediate; // otherwise |
| 580 } value_; // valid if rm_ == no_reg |
| 581 bool is_heap_number_ = false; |
564 RelocInfo::Mode rmode_; | 582 RelocInfo::Mode rmode_; |
565 | 583 |
566 friend class Assembler; | 584 friend class Assembler; |
567 }; | 585 }; |
568 | 586 |
569 | 587 |
570 // Class MemOperand represents a memory operand in load and store instructions | 588 // Class MemOperand represents a memory operand in load and store instructions |
571 class MemOperand BASE_EMBEDDED { | 589 class MemOperand BASE_EMBEDDED { |
572 public: | 590 public: |
573 // [rn +/- offset] Offset/NegOffset | 591 // [rn +/- offset] Offset/NegOffset |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 // is too small, a fatal error occurs. No deallocation of the buffer is done | 714 // is too small, a fatal error occurs. No deallocation of the buffer is done |
697 // upon destruction of the assembler. | 715 // upon destruction of the assembler. |
698 Assembler(Isolate* isolate, void* buffer, int buffer_size) | 716 Assembler(Isolate* isolate, void* buffer, int buffer_size) |
699 : Assembler(IsolateData(isolate), buffer, buffer_size) {} | 717 : Assembler(IsolateData(isolate), buffer, buffer_size) {} |
700 Assembler(IsolateData isolate_data, void* buffer, int buffer_size); | 718 Assembler(IsolateData isolate_data, void* buffer, int buffer_size); |
701 virtual ~Assembler(); | 719 virtual ~Assembler(); |
702 | 720 |
703 // GetCode emits any pending (non-emitted) code and fills the descriptor | 721 // GetCode emits any pending (non-emitted) code and fills the descriptor |
704 // desc. GetCode() is idempotent; it returns the same result if no other | 722 // desc. GetCode() is idempotent; it returns the same result if no other |
705 // Assembler functions are invoked in between GetCode() calls. | 723 // Assembler functions are invoked in between GetCode() calls. |
706 void GetCode(CodeDesc* desc); | 724 void GetCode(Isolate* isolate, CodeDesc* desc); |
707 | 725 |
708 // Label operations & relative jumps (PPUM Appendix D) | 726 // Label operations & relative jumps (PPUM Appendix D) |
709 // | 727 // |
710 // Takes a branch opcode (cc) and a label (L) and generates | 728 // Takes a branch opcode (cc) and a label (L) and generates |
711 // either a backward branch or a forward branch and links it | 729 // either a backward branch or a forward branch and links it |
712 // to the label fixup chain. Usage: | 730 // to the label fixup chain. Usage: |
713 // | 731 // |
714 // Label L; // unbound label | 732 // Label L; // unbound label |
715 // j(cc, &L); // forward branch to unbound label | 733 // j(cc, &L); // forward branch to unbound label |
716 // bind(&L); // bind label to the current pc | 734 // bind(&L); // bind label to the current pc |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1531 // constant pools and cause the version of the code with debugger support to | 1549 // constant pools and cause the version of the code with debugger support to |
1532 // have constant pools generated in different places. | 1550 // have constant pools generated in different places. |
1533 // Recording the position and size of emitted constant pools allows to | 1551 // Recording the position and size of emitted constant pools allows to |
1534 // correctly compute the offset mappings between the different versions of a | 1552 // correctly compute the offset mappings between the different versions of a |
1535 // function in all situations. | 1553 // function in all situations. |
1536 // | 1554 // |
1537 // The parameter indicates the size of the constant pool (in bytes), including | 1555 // The parameter indicates the size of the constant pool (in bytes), including |
1538 // the marker and branch over the data. | 1556 // the marker and branch over the data. |
1539 void RecordConstPool(int size); | 1557 void RecordConstPool(int size); |
1540 | 1558 |
| 1559 // Patch the dummy heap number that we emitted during code assembly in the |
| 1560 // constant pool entry referenced by {pc}. Replace it with the actual heap |
| 1561 // object (handle). |
| 1562 static void set_heap_number(Handle<HeapObject> number, Address pc) { |
| 1563 Memory::Address_at(constant_pool_entry_address(pc, 0 /* unused */)) = |
| 1564 reinterpret_cast<Address>(number.location()); |
| 1565 } |
| 1566 |
1541 // Writes a single byte or word of data in the code stream. Used | 1567 // Writes a single byte or word of data in the code stream. Used |
1542 // for inline tables, e.g., jump-tables. CheckConstantPool() should be | 1568 // for inline tables, e.g., jump-tables. CheckConstantPool() should be |
1543 // called before any use of db/dd/dq/dp to ensure that constant pools | 1569 // called before any use of db/dd/dq/dp to ensure that constant pools |
1544 // are not emitted as part of the tables generated. | 1570 // are not emitted as part of the tables generated. |
1545 void db(uint8_t data); | 1571 void db(uint8_t data); |
1546 void dd(uint32_t data); | 1572 void dd(uint32_t data); |
1547 void dq(uint64_t data); | 1573 void dq(uint64_t data); |
1548 void dp(uintptr_t data) { dd(data); } | 1574 void dp(uintptr_t data) { dd(data); } |
1549 | 1575 |
1550 // Emits the address of the code stub's first instruction. | 1576 // Emits the address of the code stub's first instruction. |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1811 | 1837 |
1812 void Emit(Address addr); | 1838 void Emit(Address addr); |
1813 void FlushICache(Isolate* isolate); | 1839 void FlushICache(Isolate* isolate); |
1814 }; | 1840 }; |
1815 | 1841 |
1816 | 1842 |
1817 } // namespace internal | 1843 } // namespace internal |
1818 } // namespace v8 | 1844 } // namespace v8 |
1819 | 1845 |
1820 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1846 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |