| 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 |