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 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 kNumReservedRegisters - 1); | 221 kNumReservedRegisters - 1); |
222 if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters; | 222 if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters; |
223 return VFPRegisters::Name(index, true); | 223 return VFPRegisters::Name(index, true); |
224 } | 224 } |
225 | 225 |
226 | 226 |
227 // ----------------------------------------------------------------------------- | 227 // ----------------------------------------------------------------------------- |
228 // Implementation of RelocInfo | 228 // Implementation of RelocInfo |
229 | 229 |
230 // static | 230 // static |
231 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; | 231 const int RelocInfo::kApplyMask = 0; |
232 | 232 |
233 | 233 |
234 bool RelocInfo::IsCodedSpecially() { | 234 bool RelocInfo::IsCodedSpecially() { |
235 // The deserializer needs to know whether a pointer is specially coded. Being | 235 // The deserializer needs to know whether a pointer is specially coded. Being |
236 // specially coded on ARM means that it is a movw/movt instruction, or is an | 236 // specially coded on ARM means that it is a movw/movt instruction, or is an |
237 // out of line constant pool entry. These only occur if | 237 // out of line constant pool entry. These only occur if |
238 // FLAG_enable_ool_constant_pool is true. | 238 // FLAG_enable_ool_constant_pool is true. |
239 return FLAG_enable_ool_constant_pool; | 239 return FLAG_enable_ool_constant_pool; |
240 } | 240 } |
241 | 241 |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 // The link chain is terminated by a branch offset pointing to the | 769 // The link chain is terminated by a branch offset pointing to the |
770 // same position. | 770 // same position. |
771 | 771 |
772 | 772 |
773 int Assembler::target_at(int pos) { | 773 int Assembler::target_at(int pos) { |
774 Instr instr = instr_at(pos); | 774 Instr instr = instr_at(pos); |
775 if (is_uint24(instr)) { | 775 if (is_uint24(instr)) { |
776 // Emitted link to a label, not part of a branch. | 776 // Emitted link to a label, not part of a branch. |
777 return instr; | 777 return instr; |
778 } | 778 } |
779 if ((instr & 7 * B25) == 5 * B25) { | 779 DCHECK_EQ(5 * B25, instr & 7 * B25); // b, bl, or blx imm24 |
780 int imm26 = ((instr & kImm24Mask) << 8) >> 6; | 780 int imm26 = ((instr & kImm24Mask) << 8) >> 6; |
781 // b, bl, or blx imm24 | 781 if ((Instruction::ConditionField(instr) == kSpecialCondition) && |
782 if ((Instruction::ConditionField(instr) == kSpecialCondition) && | 782 ((instr & B24) != 0)) { |
783 ((instr & B24) != 0)) { | 783 // blx uses bit 24 to encode bit 2 of imm26 |
784 // blx uses bit 24 to encode bit 2 of imm26 | 784 imm26 += 2; |
785 imm26 += 2; | |
786 } | |
787 return pos + kPcLoadDelta + imm26; | |
788 } | 785 } |
789 // Internal reference to the label. | 786 return pos + kPcLoadDelta + imm26; |
790 DCHECK_EQ(7 * B25 | 1 * B0, instr & (7 * B25 | 1 * B0)); | |
791 int imm26 = (((instr >> 1) & kImm24Mask) << 8) >> 6; | |
792 return pos + imm26; | |
793 } | 787 } |
794 | 788 |
795 | 789 |
796 void Assembler::target_at_put(int pos, int target_pos) { | 790 void Assembler::target_at_put(int pos, int target_pos) { |
797 Instr instr = instr_at(pos); | 791 Instr instr = instr_at(pos); |
798 if (is_uint24(instr)) { | 792 if (is_uint24(instr)) { |
799 DCHECK(target_pos == pos || target_pos >= 0); | 793 DCHECK(target_pos == pos || target_pos >= 0); |
800 // Emitted link to a label, not part of a branch. | 794 // Emitted link to a label, not part of a branch. |
801 // Load the position of the label relative to the generated code object | 795 // Load the position of the label relative to the generated code object |
802 // pointer in a register. | 796 // pointer in a register. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
856 3, | 850 3, |
857 CodePatcher::DONT_FLUSH); | 851 CodePatcher::DONT_FLUSH); |
858 patcher.masm()->mov(dst, Operand(target8_0)); | 852 patcher.masm()->mov(dst, Operand(target8_0)); |
859 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8)); | 853 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8)); |
860 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16)); | 854 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16)); |
861 } | 855 } |
862 } | 856 } |
863 } | 857 } |
864 return; | 858 return; |
865 } | 859 } |
866 if ((instr & 7 * B25) == 5 * B25) { | 860 int imm26 = target_pos - (pos + kPcLoadDelta); |
867 // b, bl, or blx imm24 | 861 DCHECK_EQ(5 * B25, instr & 7 * B25); // b, bl, or blx imm24 |
868 int imm26 = target_pos - (pos + kPcLoadDelta); | 862 if (Instruction::ConditionField(instr) == kSpecialCondition) { |
869 if (Instruction::ConditionField(instr) == kSpecialCondition) { | 863 // blx uses bit 24 to encode bit 2 of imm26 |
870 // blx uses bit 24 to encode bit 2 of imm26 | 864 DCHECK_EQ(0, imm26 & 1); |
871 DCHECK((imm26 & 1) == 0); | 865 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1) * B24; |
872 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1) * B24; | 866 } else { |
873 } else { | 867 DCHECK_EQ(0, imm26 & 3); |
874 DCHECK((imm26 & 3) == 0); | 868 instr &= ~kImm24Mask; |
875 instr &= ~kImm24Mask; | |
876 } | |
877 int imm24 = imm26 >> 2; | |
878 DCHECK(is_int24(imm24)); | |
879 instr_at_put(pos, instr | (imm24 & kImm24Mask)); | |
880 return; | |
881 } | 869 } |
882 // Patch internal reference to label. | 870 int imm24 = imm26 >> 2; |
883 DCHECK_EQ(7 * B25 | 1 * B0, instr & (7 * B25 | 1 * B0)); | 871 DCHECK(is_int24(imm24)); |
884 instr_at_put(pos, reinterpret_cast<Instr>(buffer_ + target_pos)); | 872 instr_at_put(pos, instr | (imm24 & kImm24Mask)); |
885 } | 873 } |
886 | 874 |
887 | 875 |
888 void Assembler::print(Label* L) { | 876 void Assembler::print(Label* L) { |
889 if (L->is_unused()) { | 877 if (L->is_unused()) { |
890 PrintF("unused label\n"); | 878 PrintF("unused label\n"); |
891 } else if (L->is_bound()) { | 879 } else if (L->is_bound()) { |
892 PrintF("bound label to %d\n", L->pos()); | 880 PrintF("bound label to %d\n", L->pos()); |
893 } else if (L->is_linked()) { | 881 } else if (L->is_linked()) { |
894 Label l = *L; | 882 Label l = *L; |
(...skipping 2659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3554 desc.reloc_size); | 3542 desc.reloc_size); |
3555 | 3543 |
3556 // Switch buffers. | 3544 // Switch buffers. |
3557 DeleteArray(buffer_); | 3545 DeleteArray(buffer_); |
3558 buffer_ = desc.buffer; | 3546 buffer_ = desc.buffer; |
3559 buffer_size_ = desc.buffer_size; | 3547 buffer_size_ = desc.buffer_size; |
3560 pc_ += pc_delta; | 3548 pc_ += pc_delta; |
3561 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, | 3549 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, |
3562 reloc_info_writer.last_pc() + pc_delta); | 3550 reloc_info_writer.last_pc() + pc_delta); |
3563 | 3551 |
3564 // Relocate internal references. | 3552 // None of our relocation types are pc relative pointing outside the code |
3565 for (RelocIterator it(desc); !it.done(); it.next()) { | 3553 // buffer nor pc absolute pointing inside the code buffer, so there is no need |
3566 if (it.rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE) { | 3554 // to relocate any emitted relocation entries. |
3567 // Don't patch unbound internal references (bit 0 set); those are still | |
3568 // hooked up in the Label chain and will be automatically patched once | |
3569 // the label is bound. | |
3570 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc()); | |
3571 if ((*p & 1 * B0) == 0) *p += pc_delta; | |
3572 } | |
3573 } | |
3574 | 3555 |
3575 // Relocate pending relocation entries. | 3556 // Relocate pending relocation entries. |
3576 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) { | 3557 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) { |
3577 RelocInfo& rinfo = pending_32_bit_reloc_info_[i]; | 3558 RelocInfo& rinfo = pending_32_bit_reloc_info_[i]; |
3578 DCHECK(rinfo.rmode() != RelocInfo::COMMENT && | 3559 DCHECK(rinfo.rmode() != RelocInfo::COMMENT && |
3579 rinfo.rmode() != RelocInfo::POSITION); | 3560 rinfo.rmode() != RelocInfo::POSITION); |
3580 if (rinfo.rmode() != RelocInfo::JS_RETURN) { | 3561 if (rinfo.rmode() != RelocInfo::JS_RETURN) { |
3581 rinfo.set_pc(rinfo.pc() + pc_delta); | 3562 rinfo.set_pc(rinfo.pc() + pc_delta); |
3582 } | 3563 } |
3583 } | 3564 } |
(...skipping 23 matching lines...) Expand all Loading... |
3607 // to write pure data with no pointers and the constant pool should | 3588 // to write pure data with no pointers and the constant pool should |
3608 // be emitted before using dd. | 3589 // be emitted before using dd. |
3609 DCHECK(num_pending_32_bit_reloc_info_ == 0); | 3590 DCHECK(num_pending_32_bit_reloc_info_ == 0); |
3610 DCHECK(num_pending_64_bit_reloc_info_ == 0); | 3591 DCHECK(num_pending_64_bit_reloc_info_ == 0); |
3611 CheckBuffer(); | 3592 CheckBuffer(); |
3612 *reinterpret_cast<uint32_t*>(pc_) = data; | 3593 *reinterpret_cast<uint32_t*>(pc_) = data; |
3613 pc_ += sizeof(uint32_t); | 3594 pc_ += sizeof(uint32_t); |
3614 } | 3595 } |
3615 | 3596 |
3616 | 3597 |
3617 void Assembler::dd(Label* label) { | |
3618 CheckBuffer(); | |
3619 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE); | |
3620 if (label->is_bound()) { | |
3621 uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos()); | |
3622 DCHECK_EQ(0u, data & 1 * B0); | |
3623 *reinterpret_cast<uint32_t*>(pc_) = data; | |
3624 pc_ += sizeof(uint32_t); | |
3625 } else { | |
3626 int target_pos; | |
3627 if (label->is_linked()) { | |
3628 // Point to previous instruction that uses the link. | |
3629 target_pos = label->pos(); | |
3630 } else { | |
3631 // First entry of the link chain points to itself. | |
3632 target_pos = pc_offset(); | |
3633 } | |
3634 label->link_to(pc_offset()); | |
3635 // Encode internal reference to unbound label. We set the least significant | |
3636 // bit to distinguish unbound internal references in GrowBuffer() below. | |
3637 int imm26 = target_pos - pc_offset(); | |
3638 DCHECK_EQ(0, imm26 & 3); | |
3639 int imm24 = imm26 >> 2; | |
3640 DCHECK(is_int24(imm24)); | |
3641 // We use bit pattern 0000111<imm24>1 because that doesn't match any branch | |
3642 // or load that would also appear on the label chain. | |
3643 emit(7 * B25 | ((imm24 & kImm24Mask) << 1) | 1 * B0); | |
3644 } | |
3645 } | |
3646 | |
3647 | |
3648 void Assembler::emit_code_stub_address(Code* stub) { | 3598 void Assembler::emit_code_stub_address(Code* stub) { |
3649 CheckBuffer(); | 3599 CheckBuffer(); |
3650 *reinterpret_cast<uint32_t*>(pc_) = | 3600 *reinterpret_cast<uint32_t*>(pc_) = |
3651 reinterpret_cast<uint32_t>(stub->instruction_start()); | 3601 reinterpret_cast<uint32_t>(stub->instruction_start()); |
3652 pc_ += sizeof(uint32_t); | 3602 pc_ += sizeof(uint32_t); |
3653 } | 3603 } |
3654 | 3604 |
3655 | 3605 |
3656 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 3606 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
3657 RelocInfo rinfo(pc_, rmode, data, NULL); | 3607 RelocInfo rinfo(pc_, rmode, data, NULL); |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4159 assm->instr_at_put( | 4109 assm->instr_at_put( |
4160 rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset)); | 4110 rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset)); |
4161 } | 4111 } |
4162 } | 4112 } |
4163 } | 4113 } |
4164 | 4114 |
4165 | 4115 |
4166 } } // namespace v8::internal | 4116 } } // namespace v8::internal |
4167 | 4117 |
4168 #endif // V8_TARGET_ARCH_ARM | 4118 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |