Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: src/arm/assembler-arm.cc

Issue 1069633002: [arm] Use position independent table switches. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698