| 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 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 // static | 231 const int RelocInfo::kApplyMask = 0; |
| 232 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; | |
| 233 | 232 |
| 234 | 233 |
| 235 bool RelocInfo::IsCodedSpecially() { | 234 bool RelocInfo::IsCodedSpecially() { |
| 236 // 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 |
| 237 // 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 |
| 238 // out of line constant pool entry. These only occur if | 237 // out of line constant pool entry. These only occur if |
| 239 // FLAG_enable_ool_constant_pool is true. | 238 // FLAG_enable_ool_constant_pool is true. |
| 240 return FLAG_enable_ool_constant_pool; | 239 return FLAG_enable_ool_constant_pool; |
| 241 } | 240 } |
| 242 | 241 |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 // The link chain is terminated by a branch offset pointing to the | 789 // The link chain is terminated by a branch offset pointing to the |
| 791 // same position. | 790 // same position. |
| 792 | 791 |
| 793 | 792 |
| 794 int Assembler::target_at(int pos) { | 793 int Assembler::target_at(int pos) { |
| 795 Instr instr = instr_at(pos); | 794 Instr instr = instr_at(pos); |
| 796 if (is_uint24(instr)) { | 795 if (is_uint24(instr)) { |
| 797 // Emitted link to a label, not part of a branch. | 796 // Emitted link to a label, not part of a branch. |
| 798 return instr; | 797 return instr; |
| 799 } | 798 } |
| 800 if ((instr & 7 * B25) == 5 * B25) { | 799 DCHECK((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 |
| 801 int imm26 = ((instr & kImm24Mask) << 8) >> 6; | 800 int imm26 = ((instr & kImm24Mask) << 8) >> 6; |
| 802 // b, bl, or blx imm24 | 801 if ((Instruction::ConditionField(instr) == kSpecialCondition) && |
| 803 if ((Instruction::ConditionField(instr) == kSpecialCondition) && | 802 ((instr & B24) != 0)) { |
| 804 ((instr & B24) != 0)) { | 803 // blx uses bit 24 to encode bit 2 of imm26 |
| 805 // blx uses bit 24 to encode bit 2 of imm26 | 804 imm26 += 2; |
| 806 imm26 += 2; | |
| 807 } | |
| 808 return pos + kPcLoadDelta + imm26; | |
| 809 } | 805 } |
| 810 // Internal reference to the label. | 806 return pos + kPcLoadDelta + imm26; |
| 811 DCHECK_EQ(15 * B28 | 7 * B25 | 1 * B0, instr & (15 * B28 | 7 * B25 | 1 * B0)); | |
| 812 int imm26 = (((instr >> 1) & kImm24Mask) << 8) >> 6; | |
| 813 return pos + imm26; | |
| 814 } | 807 } |
| 815 | 808 |
| 816 | 809 |
| 817 void Assembler::target_at_put(int pos, int target_pos) { | 810 void Assembler::target_at_put(int pos, int target_pos) { |
| 818 Instr instr = instr_at(pos); | 811 Instr instr = instr_at(pos); |
| 819 if (is_uint24(instr)) { | 812 if (is_uint24(instr)) { |
| 820 DCHECK(target_pos == pos || target_pos >= 0); | 813 DCHECK(target_pos == pos || target_pos >= 0); |
| 821 // Emitted link to a label, not part of a branch. | 814 // Emitted link to a label, not part of a branch. |
| 822 // Load the position of the label relative to the generated code object | 815 // Load the position of the label relative to the generated code object |
| 823 // pointer in a register. | 816 // pointer in a register. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 3, | 870 3, |
| 878 CodePatcher::DONT_FLUSH); | 871 CodePatcher::DONT_FLUSH); |
| 879 patcher.masm()->mov(dst, Operand(target8_0)); | 872 patcher.masm()->mov(dst, Operand(target8_0)); |
| 880 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8)); | 873 patcher.masm()->orr(dst, dst, Operand(target8_1 << 8)); |
| 881 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16)); | 874 patcher.masm()->orr(dst, dst, Operand(target8_2 << 16)); |
| 882 } | 875 } |
| 883 } | 876 } |
| 884 } | 877 } |
| 885 return; | 878 return; |
| 886 } | 879 } |
| 887 if ((instr & 7 * B25) == 5 * B25) { | 880 int imm26 = target_pos - (pos + kPcLoadDelta); |
| 888 // b, bl, or blx imm24 | 881 DCHECK((instr & 7*B25) == 5*B25); // b, bl, or blx imm24 |
| 889 int imm26 = target_pos - (pos + kPcLoadDelta); | 882 if (Instruction::ConditionField(instr) == kSpecialCondition) { |
| 890 if (Instruction::ConditionField(instr) == kSpecialCondition) { | 883 // blx uses bit 24 to encode bit 2 of imm26 |
| 891 // blx uses bit 24 to encode bit 2 of imm26 | 884 DCHECK((imm26 & 1) == 0); |
| 892 DCHECK((imm26 & 1) == 0); | 885 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24; |
| 893 instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1) * B24; | 886 } else { |
| 894 } else { | 887 DCHECK((imm26 & 3) == 0); |
| 895 DCHECK((imm26 & 3) == 0); | 888 instr &= ~kImm24Mask; |
| 896 instr &= ~kImm24Mask; | |
| 897 } | |
| 898 int imm24 = imm26 >> 2; | |
| 899 DCHECK(is_int24(imm24)); | |
| 900 instr_at_put(pos, instr | (imm24 & kImm24Mask)); | |
| 901 return; | |
| 902 } | 889 } |
| 903 // Patch internal reference to label. | 890 int imm24 = imm26 >> 2; |
| 904 DCHECK_EQ(15 * B28 | 7 * B25 | 1 * B0, instr & (15 * B28 | 7 * B25 | 1 * B0)); | 891 DCHECK(is_int24(imm24)); |
| 905 instr_at_put(pos, reinterpret_cast<Instr>(buffer_ + target_pos)); | 892 instr_at_put(pos, instr | (imm24 & kImm24Mask)); |
| 906 } | 893 } |
| 907 | 894 |
| 908 | 895 |
| 909 void Assembler::print(Label* L) { | 896 void Assembler::print(Label* L) { |
| 910 if (L->is_unused()) { | 897 if (L->is_unused()) { |
| 911 PrintF("unused label\n"); | 898 PrintF("unused label\n"); |
| 912 } else if (L->is_bound()) { | 899 } else if (L->is_bound()) { |
| 913 PrintF("bound label to %d\n", L->pos()); | 900 PrintF("bound label to %d\n", L->pos()); |
| 914 } else if (L->is_linked()) { | 901 } else if (L->is_linked()) { |
| 915 Label l = *L; | 902 Label l = *L; |
| (...skipping 2516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3432 desc.reloc_size); | 3419 desc.reloc_size); |
| 3433 | 3420 |
| 3434 // Switch buffers. | 3421 // Switch buffers. |
| 3435 DeleteArray(buffer_); | 3422 DeleteArray(buffer_); |
| 3436 buffer_ = desc.buffer; | 3423 buffer_ = desc.buffer; |
| 3437 buffer_size_ = desc.buffer_size; | 3424 buffer_size_ = desc.buffer_size; |
| 3438 pc_ += pc_delta; | 3425 pc_ += pc_delta; |
| 3439 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, | 3426 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, |
| 3440 reloc_info_writer.last_pc() + pc_delta); | 3427 reloc_info_writer.last_pc() + pc_delta); |
| 3441 | 3428 |
| 3442 // Relocate internal references. | 3429 // None of our relocation types are pc relative pointing outside the code |
| 3443 for (RelocIterator it(desc); !it.done(); it.next()) { | 3430 // buffer nor pc absolute pointing inside the code buffer, so there is no need |
| 3444 if (it.rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE) { | 3431 // to relocate any emitted relocation entries. |
| 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 } | |
| 3452 | 3432 |
| 3453 // Relocate pending relocation entries. | 3433 // Relocate pending relocation entries. |
| 3454 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) { | 3434 for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) { |
| 3455 RelocInfo& rinfo = pending_32_bit_reloc_info_[i]; | 3435 RelocInfo& rinfo = pending_32_bit_reloc_info_[i]; |
| 3456 DCHECK(rinfo.rmode() != RelocInfo::COMMENT && | 3436 DCHECK(rinfo.rmode() != RelocInfo::COMMENT && |
| 3457 rinfo.rmode() != RelocInfo::POSITION); | 3437 rinfo.rmode() != RelocInfo::POSITION); |
| 3458 if (rinfo.rmode() != RelocInfo::JS_RETURN) { | 3438 if (rinfo.rmode() != RelocInfo::JS_RETURN) { |
| 3459 rinfo.set_pc(rinfo.pc() + pc_delta); | 3439 rinfo.set_pc(rinfo.pc() + pc_delta); |
| 3460 } | 3440 } |
| 3461 } | 3441 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3485 // to write pure data with no pointers and the constant pool should | 3465 // to write pure data with no pointers and the constant pool should |
| 3486 // be emitted before using dd. | 3466 // be emitted before using dd. |
| 3487 DCHECK(num_pending_32_bit_reloc_info_ == 0); | 3467 DCHECK(num_pending_32_bit_reloc_info_ == 0); |
| 3488 DCHECK(num_pending_64_bit_reloc_info_ == 0); | 3468 DCHECK(num_pending_64_bit_reloc_info_ == 0); |
| 3489 CheckBuffer(); | 3469 CheckBuffer(); |
| 3490 *reinterpret_cast<uint32_t*>(pc_) = data; | 3470 *reinterpret_cast<uint32_t*>(pc_) = data; |
| 3491 pc_ += sizeof(uint32_t); | 3471 pc_ += sizeof(uint32_t); |
| 3492 } | 3472 } |
| 3493 | 3473 |
| 3494 | 3474 |
| 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 emit(15 * B28 | 7 * B25 | ((imm24 & kImm24Mask) << 1) | 1 * B0); | |
| 3520 } | |
| 3521 } | |
| 3522 | |
| 3523 | |
| 3524 void Assembler::emit_code_stub_address(Code* stub) { | 3475 void Assembler::emit_code_stub_address(Code* stub) { |
| 3525 CheckBuffer(); | 3476 CheckBuffer(); |
| 3526 *reinterpret_cast<uint32_t*>(pc_) = | 3477 *reinterpret_cast<uint32_t*>(pc_) = |
| 3527 reinterpret_cast<uint32_t>(stub->instruction_start()); | 3478 reinterpret_cast<uint32_t>(stub->instruction_start()); |
| 3528 pc_ += sizeof(uint32_t); | 3479 pc_ += sizeof(uint32_t); |
| 3529 } | 3480 } |
| 3530 | 3481 |
| 3531 | 3482 |
| 3532 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 3483 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| 3533 RelocInfo rinfo(pc_, rmode, data, NULL); | 3484 RelocInfo rinfo(pc_, rmode, data, NULL); |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4035 assm->instr_at_put( | 3986 assm->instr_at_put( |
| 4036 rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset)); | 3987 rinfo.pc(), Assembler::SetLdrRegisterImmediateOffset(instr, offset)); |
| 4037 } | 3988 } |
| 4038 } | 3989 } |
| 4039 } | 3990 } |
| 4040 | 3991 |
| 4041 | 3992 |
| 4042 } } // namespace v8::internal | 3993 } } // namespace v8::internal |
| 4043 | 3994 |
| 4044 #endif // V8_TARGET_ARCH_ARM | 3995 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |