| 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 2555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2566 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. | 2566 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. |
| 2567 | 2567 |
| 2568 return true; | 2568 return true; |
| 2569 } | 2569 } |
| 2570 | 2570 |
| 2571 | 2571 |
| 2572 void Assembler::vmov(const DwVfpRegister dst, | 2572 void Assembler::vmov(const DwVfpRegister dst, |
| 2573 double imm, | 2573 double imm, |
| 2574 const Register scratch) { | 2574 const Register scratch) { |
| 2575 uint32_t enc; | 2575 uint32_t enc; |
| 2576 // If the embedded constant pool is disabled, we can use the normal, inline |
| 2577 // constant pool. If the embedded constant pool is enabled (via |
| 2578 // FLAG_enable_embedded_constant_pool), we can only use it where the pool |
| 2579 // pointer (pp) is valid. |
| 2580 bool can_use_pool = |
| 2581 !FLAG_enable_embedded_constant_pool || is_constant_pool_available(); |
| 2576 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { | 2582 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { |
| 2577 // The double can be encoded in the instruction. | 2583 // The double can be encoded in the instruction. |
| 2578 // | 2584 // |
| 2579 // Dd = immediate | 2585 // Dd = immediate |
| 2580 // Instruction details available in ARM DDI 0406C.b, A8-936. | 2586 // Instruction details available in ARM DDI 0406C.b, A8-936. |
| 2581 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | | 2587 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
| 2582 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) | 2588 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) |
| 2583 int vd, d; | 2589 int vd, d; |
| 2584 dst.split_code(&vd, &d); | 2590 dst.split_code(&vd, &d); |
| 2585 emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); | 2591 emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); |
| 2586 } else if (FLAG_enable_vldr_imm && is_constant_pool_available()) { | 2592 } else if (FLAG_enable_vldr_imm && can_use_pool) { |
| 2587 // TODO(jfb) Temporarily turned off until we have constant blinding or | 2593 // TODO(jfb) Temporarily turned off until we have constant blinding or |
| 2588 // some equivalent mitigation: an attacker can otherwise control | 2594 // some equivalent mitigation: an attacker can otherwise control |
| 2589 // generated data which also happens to be executable, a Very Bad | 2595 // generated data which also happens to be executable, a Very Bad |
| 2590 // Thing indeed. | 2596 // Thing indeed. |
| 2591 // Blinding gets tricky because we don't have xor, we probably | 2597 // Blinding gets tricky because we don't have xor, we probably |
| 2592 // need to add/subtract without losing precision, which requires a | 2598 // need to add/subtract without losing precision, which requires a |
| 2593 // cookie value that Lithium is probably better positioned to | 2599 // cookie value that Lithium is probably better positioned to |
| 2594 // choose. | 2600 // choose. |
| 2595 // We could also add a few peepholes here like detecting 0.0 and | 2601 // We could also add a few peepholes here like detecting 0.0 and |
| 2596 // -0.0 and doing a vmov from the sequestered d14, forcing denorms | 2602 // -0.0 and doing a vmov from the sequestered d14, forcing denorms |
| (...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3581 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, | 3587 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, |
| 3582 reloc_info_writer.last_pc() + pc_delta); | 3588 reloc_info_writer.last_pc() + pc_delta); |
| 3583 | 3589 |
| 3584 // None of our relocation types are pc relative pointing outside the code | 3590 // None of our relocation types are pc relative pointing outside the code |
| 3585 // buffer nor pc absolute pointing inside the code buffer, so there is no need | 3591 // buffer nor pc absolute pointing inside the code buffer, so there is no need |
| 3586 // to relocate any emitted relocation entries. | 3592 // to relocate any emitted relocation entries. |
| 3587 } | 3593 } |
| 3588 | 3594 |
| 3589 | 3595 |
| 3590 void Assembler::db(uint8_t data) { | 3596 void Assembler::db(uint8_t data) { |
| 3591 // No relocation info should be pending while using db. db is used | 3597 // db is used to write raw data. The constant pool should be emitted or |
| 3592 // to write pure data with no pointers and the constant pool should | 3598 // blocked before using db. |
| 3593 // be emitted before using db. | 3599 DCHECK(is_const_pool_blocked() || (num_pending_32_bit_constants_ == 0)); |
| 3594 DCHECK(num_pending_32_bit_constants_ == 0); | 3600 DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0)); |
| 3595 DCHECK(num_pending_64_bit_constants_ == 0); | |
| 3596 CheckBuffer(); | 3601 CheckBuffer(); |
| 3597 *reinterpret_cast<uint8_t*>(pc_) = data; | 3602 *reinterpret_cast<uint8_t*>(pc_) = data; |
| 3598 pc_ += sizeof(uint8_t); | 3603 pc_ += sizeof(uint8_t); |
| 3599 } | 3604 } |
| 3600 | 3605 |
| 3601 | 3606 |
| 3602 void Assembler::dd(uint32_t data) { | 3607 void Assembler::dd(uint32_t data) { |
| 3603 // No relocation info should be pending while using dd. dd is used | 3608 // dd is used to write raw data. The constant pool should be emitted or |
| 3604 // to write pure data with no pointers and the constant pool should | 3609 // blocked before using dd. |
| 3605 // be emitted before using dd. | 3610 DCHECK(is_const_pool_blocked() || (num_pending_32_bit_constants_ == 0)); |
| 3606 DCHECK(num_pending_32_bit_constants_ == 0); | 3611 DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0)); |
| 3607 DCHECK(num_pending_64_bit_constants_ == 0); | |
| 3608 CheckBuffer(); | 3612 CheckBuffer(); |
| 3609 *reinterpret_cast<uint32_t*>(pc_) = data; | 3613 *reinterpret_cast<uint32_t*>(pc_) = data; |
| 3610 pc_ += sizeof(uint32_t); | 3614 pc_ += sizeof(uint32_t); |
| 3611 } | 3615 } |
| 3612 | 3616 |
| 3613 | 3617 |
| 3614 void Assembler::dq(uint64_t value) { | 3618 void Assembler::dq(uint64_t value) { |
| 3615 // No relocation info should be pending while using dq. dq is used | 3619 // dq is used to write raw data. The constant pool should be emitted or |
| 3616 // to write pure data with no pointers and the constant pool should | 3620 // blocked before using dq. |
| 3617 // be emitted before using dd. | 3621 DCHECK(is_const_pool_blocked() || (num_pending_32_bit_constants_ == 0)); |
| 3618 DCHECK(num_pending_32_bit_constants_ == 0); | 3622 DCHECK(is_const_pool_blocked() || (num_pending_64_bit_constants_ == 0)); |
| 3619 DCHECK(num_pending_64_bit_constants_ == 0); | |
| 3620 CheckBuffer(); | 3623 CheckBuffer(); |
| 3621 *reinterpret_cast<uint64_t*>(pc_) = value; | 3624 *reinterpret_cast<uint64_t*>(pc_) = value; |
| 3622 pc_ += sizeof(uint64_t); | 3625 pc_ += sizeof(uint64_t); |
| 3623 } | 3626 } |
| 3624 | 3627 |
| 3625 | 3628 |
| 3626 void Assembler::emit_code_stub_address(Code* stub) { | 3629 void Assembler::emit_code_stub_address(Code* stub) { |
| 3627 CheckBuffer(); | 3630 CheckBuffer(); |
| 3628 *reinterpret_cast<uint32_t*>(pc_) = | 3631 *reinterpret_cast<uint32_t*>(pc_) = |
| 3629 reinterpret_cast<uint32_t>(stub->instruction_start()); | 3632 reinterpret_cast<uint32_t>(stub->instruction_start()); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3748 return; | 3751 return; |
| 3749 } | 3752 } |
| 3750 | 3753 |
| 3751 // Check that the code buffer is large enough before emitting the constant | 3754 // Check that the code buffer is large enough before emitting the constant |
| 3752 // pool (include the jump over the pool and the constant pool marker and | 3755 // pool (include the jump over the pool and the constant pool marker and |
| 3753 // the gap to the relocation information). | 3756 // the gap to the relocation information). |
| 3754 int jump_instr = require_jump ? kInstrSize : 0; | 3757 int jump_instr = require_jump ? kInstrSize : 0; |
| 3755 int size_up_to_marker = jump_instr + kInstrSize; | 3758 int size_up_to_marker = jump_instr + kInstrSize; |
| 3756 int estimated_size_after_marker = | 3759 int estimated_size_after_marker = |
| 3757 num_pending_32_bit_constants_ * kPointerSize; | 3760 num_pending_32_bit_constants_ * kPointerSize; |
| 3761 bool has_int_values = (num_pending_32_bit_constants_ > 0); |
| 3758 bool has_fp_values = (num_pending_64_bit_constants_ > 0); | 3762 bool has_fp_values = (num_pending_64_bit_constants_ > 0); |
| 3759 bool require_64_bit_align = false; | 3763 bool require_64_bit_align = false; |
| 3760 if (has_fp_values) { | 3764 if (has_fp_values) { |
| 3761 require_64_bit_align = IsAligned( | 3765 require_64_bit_align = |
| 3762 reinterpret_cast<intptr_t>(pc_ + size_up_to_marker), kDoubleAlignment); | 3766 !IsAligned(reinterpret_cast<intptr_t>(pc_ + size_up_to_marker), |
| 3767 kDoubleAlignment); |
| 3763 if (require_64_bit_align) { | 3768 if (require_64_bit_align) { |
| 3764 estimated_size_after_marker += kInstrSize; | 3769 estimated_size_after_marker += kInstrSize; |
| 3765 } | 3770 } |
| 3766 estimated_size_after_marker += num_pending_64_bit_constants_ * kDoubleSize; | 3771 estimated_size_after_marker += num_pending_64_bit_constants_ * kDoubleSize; |
| 3767 } | 3772 } |
| 3768 int estimated_size = size_up_to_marker + estimated_size_after_marker; | 3773 int estimated_size = size_up_to_marker + estimated_size_after_marker; |
| 3769 | 3774 |
| 3770 // We emit a constant pool when: | 3775 // We emit a constant pool when: |
| 3771 // * requested to do so by parameter force_emit (e.g. after each function). | 3776 // * requested to do so by parameter force_emit (e.g. after each function). |
| 3772 // * the distance from the first instruction accessing the constant pool to | 3777 // * the distance from the first instruction accessing the constant pool to |
| 3773 // any of the constant pool entries will exceed its limit the next | 3778 // any of the constant pool entries will exceed its limit the next |
| 3774 // time the pool is checked. This is overly restrictive, but we don't emit | 3779 // time the pool is checked. This is overly restrictive, but we don't emit |
| 3775 // constant pool entries in-order so it's conservatively correct. | 3780 // constant pool entries in-order so it's conservatively correct. |
| 3776 // * the instruction doesn't require a jump after itself to jump over the | 3781 // * the instruction doesn't require a jump after itself to jump over the |
| 3777 // constant pool, and we're getting close to running out of range. | 3782 // constant pool, and we're getting close to running out of range. |
| 3778 if (!force_emit) { | 3783 if (!force_emit) { |
| 3779 DCHECK((first_const_pool_32_use_ >= 0) || (first_const_pool_64_use_ >= 0)); | 3784 DCHECK(has_fp_values || has_int_values); |
| 3780 bool need_emit = false; | 3785 bool need_emit = false; |
| 3781 if (has_fp_values) { | 3786 if (has_fp_values) { |
| 3787 // The 64-bit constants are always emitted before the 32-bit constants, so |
| 3788 // we can ignore the effect of the 32-bit constants on estimated_size. |
| 3782 int dist64 = pc_offset() + estimated_size - | 3789 int dist64 = pc_offset() + estimated_size - |
| 3783 num_pending_32_bit_constants_ * kPointerSize - | 3790 num_pending_32_bit_constants_ * kPointerSize - |
| 3784 first_const_pool_64_use_; | 3791 first_const_pool_64_use_; |
| 3785 if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) || | 3792 if ((dist64 >= kMaxDistToFPPool - kCheckPoolInterval) || |
| 3786 (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) { | 3793 (!require_jump && (dist64 >= kMaxDistToFPPool / 2))) { |
| 3787 need_emit = true; | 3794 need_emit = true; |
| 3788 } | 3795 } |
| 3789 } | 3796 } |
| 3790 int dist32 = pc_offset() + estimated_size - first_const_pool_32_use_; | 3797 if (has_int_values) { |
| 3791 if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) || | 3798 int dist32 = pc_offset() + estimated_size - first_const_pool_32_use_; |
| 3792 (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) { | 3799 if ((dist32 >= kMaxDistToIntPool - kCheckPoolInterval) || |
| 3793 need_emit = true; | 3800 (!require_jump && (dist32 >= kMaxDistToIntPool / 2))) { |
| 3801 need_emit = true; |
| 3802 } |
| 3794 } | 3803 } |
| 3795 if (!need_emit) return; | 3804 if (!need_emit) return; |
| 3796 } | 3805 } |
| 3797 | 3806 |
| 3798 // Deduplicate constants. | 3807 // Deduplicate constants. |
| 3799 int size_after_marker = estimated_size_after_marker; | 3808 int size_after_marker = estimated_size_after_marker; |
| 3800 for (int i = 0; i < num_pending_64_bit_constants_; i++) { | 3809 for (int i = 0; i < num_pending_64_bit_constants_; i++) { |
| 3801 ConstantPoolEntry& entry = pending_64_bit_constants_[i]; | 3810 ConstantPoolEntry& entry = pending_64_bit_constants_[i]; |
| 3802 DCHECK(!entry.is_merged()); | 3811 DCHECK(!entry.is_merged()); |
| 3803 for (int j = 0; j < i; j++) { | 3812 for (int j = 0; j < i; j++) { |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3989 DCHECK(is_uint12(offset)); | 3998 DCHECK(is_uint12(offset)); |
| 3990 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 3999 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
| 3991 } | 4000 } |
| 3992 } | 4001 } |
| 3993 | 4002 |
| 3994 | 4003 |
| 3995 } // namespace internal | 4004 } // namespace internal |
| 3996 } // namespace v8 | 4005 } // namespace v8 |
| 3997 | 4006 |
| 3998 #endif // V8_TARGET_ARCH_ARM | 4007 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |