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 static void set_heap_number(Handle<HeapObject> number, Address pc) { | |
Jarin
2017/05/31 11:55:54
Please add a brief description before the function
| |
1560 Memory::Address_at(constant_pool_entry_address(pc, 0 /* dummy */)) = | |
1561 reinterpret_cast<Address>(number.location()); | |
1562 } | |
1563 | |
1541 // Writes a single byte or word of data in the code stream. Used | 1564 // Writes a single byte or word of data in the code stream. Used |
1542 // for inline tables, e.g., jump-tables. CheckConstantPool() should be | 1565 // 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 | 1566 // called before any use of db/dd/dq/dp to ensure that constant pools |
1544 // are not emitted as part of the tables generated. | 1567 // are not emitted as part of the tables generated. |
1545 void db(uint8_t data); | 1568 void db(uint8_t data); |
1546 void dd(uint32_t data); | 1569 void dd(uint32_t data); |
1547 void dq(uint64_t data); | 1570 void dq(uint64_t data); |
1548 void dp(uintptr_t data) { dd(data); } | 1571 void dp(uintptr_t data) { dd(data); } |
1549 | 1572 |
1550 // Emits the address of the code stub's first instruction. | 1573 // Emits the address of the code stub's first instruction. |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1811 | 1834 |
1812 void Emit(Address addr); | 1835 void Emit(Address addr); |
1813 void FlushICache(Isolate* isolate); | 1836 void FlushICache(Isolate* isolate); |
1814 }; | 1837 }; |
1815 | 1838 |
1816 | 1839 |
1817 } // namespace internal | 1840 } // namespace internal |
1818 } // namespace v8 | 1841 } // namespace v8 |
1819 | 1842 |
1820 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1843 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |