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

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

Issue 887073007: [arm] Assembler support for internal references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Use different bit pattern Created 5 years, 10 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/arm/constants-arm.h » ('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 DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() == 221 DCHECK(kScratchDoubleReg.code() - kDoubleRegZero.code() ==
222 kNumReservedRegisters - 1); 222 kNumReservedRegisters - 1);
223 if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters; 223 if (index >= kDoubleRegZero.code()) index += kNumReservedRegisters;
224 return VFPRegisters::Name(index, true); 224 return VFPRegisters::Name(index, true);
225 } 225 }
226 226
227 227
228 // ----------------------------------------------------------------------------- 228 // -----------------------------------------------------------------------------
229 // Implementation of RelocInfo 229 // Implementation of RelocInfo
230 230
231 const int RelocInfo::kApplyMask = 0; 231 // static
232 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE;
232 233
233 234
234 bool RelocInfo::IsCodedSpecially() { 235 bool RelocInfo::IsCodedSpecially() {
235 // The deserializer needs to know whether a pointer is specially coded.  Being 236 // 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 237 // 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 238 // out of line constant pool entry.  These only occur if
238 // FLAG_enable_ool_constant_pool is true. 239 // FLAG_enable_ool_constant_pool is true.
239 return FLAG_enable_ool_constant_pool; 240 return FLAG_enable_ool_constant_pool;
240 } 241 }
241 242
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // The link chain is terminated by a branch offset pointing to the 790 // The link chain is terminated by a branch offset pointing to the
790 // same position. 791 // same position.
791 792
792 793
793 int Assembler::target_at(int pos) { 794 int Assembler::target_at(int pos) {
794 Instr instr = instr_at(pos); 795 Instr instr = instr_at(pos);
795 if (is_uint24(instr)) { 796 if (is_uint24(instr)) {
796 // Emitted link to a label, not part of a branch. 797 // Emitted link to a label, not part of a branch.
797 return instr; 798 return instr;
798 } 799 }
799 DCHECK((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 800 if ((instr & 7 * B25) == 5 * B25) {
800 int imm26 = ((instr & kImm24Mask) << 8) >> 6; 801 int imm26 = ((instr & kImm24Mask) << 8) >> 6;
801 if ((Instruction::ConditionField(instr) == kSpecialCondition) && 802 // b, bl, or blx imm24
802 ((instr & B24) != 0)) { 803 if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
803 // blx uses bit 24 to encode bit 2 of imm26 804 ((instr & B24) != 0)) {
804 imm26 += 2; 805 // blx uses bit 24 to encode bit 2 of imm26
806 imm26 += 2;
807 }
808 return pos + kPcLoadDelta + imm26;
805 } 809 }
806 return pos + kPcLoadDelta + imm26; 810 // Internal reference to the label.
811 DCHECK_EQ(7 * B25 | 1 * B0, instr & (7 * B25 | 1 * B0));
812 int imm26 = (((instr >> 1) & kImm24Mask) << 8) >> 6;
813 return pos + imm26;
807 } 814 }
808 815
809 816
810 void Assembler::target_at_put(int pos, int target_pos) { 817 void Assembler::target_at_put(int pos, int target_pos) {
811 Instr instr = instr_at(pos); 818 Instr instr = instr_at(pos);
812 if (is_uint24(instr)) { 819 if (is_uint24(instr)) {
813 DCHECK(target_pos == pos || target_pos >= 0); 820 DCHECK(target_pos == pos || target_pos >= 0);
814 // Emitted link to a label, not part of a branch. 821 // Emitted link to a label, not part of a branch.
815 // Load the position of the label relative to the generated code object 822 // Load the position of the label relative to the generated code object
816 // pointer in a register. 823 // pointer in a register.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 3, 877 3,
871 CodePatcher::DONT_FLUSH); 878 CodePatcher::DONT_FLUSH);
872 patcher.masm()->mov(dst, Operand(target8_0)); 879 patcher.masm()->mov(dst, Operand(target8_0));
873 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8)); 880 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8));
874 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16)); 881 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16));
875 } 882 }
876 } 883 }
877 } 884 }
878 return; 885 return;
879 } 886 }
880 int imm26 = target_pos - (pos + kPcLoadDelta); 887 if ((instr & 7 * B25) == 5 * B25) {
881 DCHECK((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 888 // b, bl, or blx imm24
882 if (Instruction::ConditionField(instr) == kSpecialCondition) { 889 int imm26 = target_pos - (pos + kPcLoadDelta);
883 // blx uses bit 24 to encode bit 2 of imm26 890 if (Instruction::ConditionField(instr) == kSpecialCondition) {
884 DCHECK((imm26 & 1) == 0); 891 // blx uses bit 24 to encode bit 2 of imm26
885 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24; 892 DCHECK((imm26 & 1) == 0);
886 } else { 893 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1) * B24;
887 DCHECK((imm26 & 3) == 0); 894 } else {
888 instr &= ~kImm24Mask; 895 DCHECK((imm26 & 3) == 0);
896 instr &= ~kImm24Mask;
897 }
898 int imm24 = imm26 >> 2;
899 DCHECK(is_int24(imm24));
900 instr_at_put(pos, instr | (imm24 & kImm24Mask));
901 return;
889 } 902 }
890 int imm24 = imm26 >> 2; 903 // Patch internal reference to label.
891 DCHECK(is_int24(imm24)); 904 DCHECK_EQ(7 * B25 | 1 * B0, instr & (7 * B25 | 1 * B0));
892 instr_at_put(pos, instr | (imm24 & kImm24Mask)); 905 instr_at_put(pos, reinterpret_cast<Instr>(buffer_ + target_pos));
893 } 906 }
894 907
895 908
896 void Assembler::print(Label* L) { 909 void Assembler::print(Label* L) {
897 if (L->is_unused()) { 910 if (L->is_unused()) {
898 PrintF("unused label\n"); 911 PrintF("unused label\n");
899 } else if (L->is_bound()) { 912 } else if (L->is_bound()) {
900 PrintF("bound label to %d\n", L->pos()); 913 PrintF("bound label to %d\n", L->pos());
901 } else if (L->is_linked()) { 914 } else if (L->is_linked()) {
902 Label l = *L; 915 Label l = *L;
(...skipping 2516 matching lines...) Expand 10 before | Expand all | Expand 10 after
3419 desc.reloc_size); 3432 desc.reloc_size);
3420 3433
3421 // Switch buffers. 3434 // Switch buffers.
3422 DeleteArray(buffer_); 3435 DeleteArray(buffer_);
3423 buffer_ = desc.buffer; 3436 buffer_ = desc.buffer;
3424 buffer_size_ = desc.buffer_size; 3437 buffer_size_ = desc.buffer_size;
3425 pc_ += pc_delta; 3438 pc_ += pc_delta;
3426 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 3439 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
3427 reloc_info_writer.last_pc() + pc_delta); 3440 reloc_info_writer.last_pc() + pc_delta);
3428 3441
3429 // None of our relocation types are pc relative pointing outside the code 3442 // Relocate internal references.
3430 // buffer nor pc absolute pointing inside the code buffer, so there is no need 3443 for (RelocIterator it(desc); !it.done(); it.next()) {
3431 // to relocate any emitted relocation entries. 3444 if (it.rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE) {
3445 // Don't patch unbound internal references (bit 0 set); those are still
3446 // hooked up in the Label chain and will be automatically patched once
3447 // the label is bound.
3448 int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
3449 if ((*p & 1 * B0) == 0) *p += pc_delta;
3450 }
3451 }
3432 3452
3433 // Relocate pending relocation entries. 3453 // Relocate pending relocation entries.
3434 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) { 3454 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
3435 RelocInfo& rinfo = pending_32_bit_reloc_info_[i]; 3455 RelocInfo& rinfo = pending_32_bit_reloc_info_[i];
3436 DCHECK(rinfo.rmode() != RelocInfo::COMMENT && 3456 DCHECK(rinfo.rmode() != RelocInfo::COMMENT &&
3437 rinfo.rmode() != RelocInfo::POSITION); 3457 rinfo.rmode() != RelocInfo::POSITION);
3438 if (rinfo.rmode() != RelocInfo::JS_RETURN) { 3458 if (rinfo.rmode() != RelocInfo::JS_RETURN) {
3439 rinfo.set_pc(rinfo.pc() + pc_delta); 3459 rinfo.set_pc(rinfo.pc() + pc_delta);
3440 } 3460 }
3441 } 3461 }
(...skipping 23 matching lines...) Expand all
3465 // to write pure data with no pointers and the constant pool should 3485 // to write pure data with no pointers and the constant pool should
3466 // be emitted before using dd. 3486 // be emitted before using dd.
3467 DCHECK(num_pending_32_bit_reloc_info_ == 0); 3487 DCHECK(num_pending_32_bit_reloc_info_ == 0);
3468 DCHECK(num_pending_64_bit_reloc_info_ == 0); 3488 DCHECK(num_pending_64_bit_reloc_info_ == 0);
3469 CheckBuffer(); 3489 CheckBuffer();
3470 *reinterpret_cast<uint32_t*>(pc_) = data; 3490 *reinterpret_cast<uint32_t*>(pc_) = data;
3471 pc_ += sizeof(uint32_t); 3491 pc_ += sizeof(uint32_t);
3472 } 3492 }
3473 3493
3474 3494
3495 void Assembler::dd(Label* label) {
3496 CheckBuffer();
3497 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
3498 if (label->is_bound()) {
3499 uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos());
3500 DCHECK_EQ(0u, data & 1 * B0);
3501 *reinterpret_cast<uint32_t*>(pc_) = data;
3502 pc_ += sizeof(uint32_t);
3503 } else {
3504 int target_pos;
3505 if (label->is_linked()) {
3506 // Point to previous instruction that uses the link.
3507 target_pos = label->pos();
3508 } else {
3509 // First entry of the link chain points to itself.
3510 target_pos = pc_offset();
3511 }
3512 label->link_to(pc_offset());
3513 // Encode internal reference to unbound label. We set the least significant
3514 // bit to distinguish unbound internal references in GrowBuffer() below.
3515 int imm26 = target_pos - pc_offset();
3516 DCHECK_EQ(0, imm26 & 3);
3517 int imm24 = imm26 >> 2;
3518 DCHECK(is_int24(imm24));
3519 // We use bit pattern 0000111<imm24>1 because that doesn't match any branch
3520 // or load that would also appear on the label chain.
3521 emit(7 * B25 | ((imm24 & kImm24Mask) << 1) | 1 * B0);
3522 }
3523 }
3524
3525
3475 void Assembler::emit_code_stub_address(Code* stub) { 3526 void Assembler::emit_code_stub_address(Code* stub) {
3476 CheckBuffer(); 3527 CheckBuffer();
3477 *reinterpret_cast<uint32_t*>(pc_) = 3528 *reinterpret_cast<uint32_t*>(pc_) =
3478 reinterpret_cast<uint32_t>(stub->instruction_start()); 3529 reinterpret_cast<uint32_t>(stub->instruction_start());
3479 pc_ += sizeof(uint32_t); 3530 pc_ += sizeof(uint32_t);
3480 } 3531 }
3481 3532
3482 3533
3483 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 3534 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3484 RelocInfo rinfo(pc_, rmode, data, NULL); 3535 RelocInfo rinfo(pc_, rmode, data, NULL);
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
3986 assm->instr_at_put( 4037 assm->instr_at_put(
3987 rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset)); 4038 rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset));
3988 } 4039 }
3989 } 4040 }
3990 } 4041 }
3991 4042
3992 4043
3993 } } // namespace v8::internal 4044 } } // namespace v8::internal
3994 4045
3995 #endif // V8_TARGET_ARCH_ARM 4046 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698