OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1674 } | 1674 } |
1675 | 1675 |
1676 | 1676 |
1677 void Assembler::orl(Register dst, const Immediate& imm) { | 1677 void Assembler::orl(Register dst, const Immediate& imm) { |
1678 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1678 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1679 EmitRegisterREX(dst, REX_NONE); | 1679 EmitRegisterREX(dst, REX_NONE); |
1680 EmitComplex(1, Operand(dst), imm); | 1680 EmitComplex(1, Operand(dst), imm); |
1681 } | 1681 } |
1682 | 1682 |
1683 | 1683 |
| 1684 void Assembler::orl(const Address& address, Register reg) { |
| 1685 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 1686 EmitOperandREX(reg, address, REX_NONE); |
| 1687 EmitUint8(0x09); |
| 1688 EmitOperand(reg & 7, address); |
| 1689 } |
| 1690 |
| 1691 |
1684 void Assembler::xorl(Register dst, Register src) { | 1692 void Assembler::xorl(Register dst, Register src) { |
1685 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1693 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1686 Operand operand(src); | 1694 Operand operand(src); |
1687 EmitOperandREX(dst, operand, REX_NONE); | 1695 EmitOperandREX(dst, operand, REX_NONE); |
1688 EmitUint8(0x33); | 1696 EmitUint8(0x33); |
1689 EmitOperand(dst & 7, operand); | 1697 EmitOperand(dst & 7, operand); |
1690 } | 1698 } |
1691 | 1699 |
1692 | 1700 |
1693 void Assembler::andq(Register dst, Register src) { | 1701 void Assembler::andq(Register dst, Register src) { |
(...skipping 2079 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3773 LoadClassId(result, object); | 3781 LoadClassId(result, object); |
3774 | 3782 |
3775 movq(object, Immediate(kSmiCid)); | 3783 movq(object, Immediate(kSmiCid)); |
3776 // If object is a Smi, move the Smi cid into result. o/w leave alone. | 3784 // If object is a Smi, move the Smi cid into result. o/w leave alone. |
3777 cmoveq(result, object); | 3785 cmoveq(result, object); |
3778 // Finally, tag the result. | 3786 // Finally, tag the result. |
3779 SmiTag(result); | 3787 SmiTag(result); |
3780 } | 3788 } |
3781 | 3789 |
3782 | 3790 |
| 3791 void Assembler::ComputeRange(Register result, Register value, Label* not_mint) { |
| 3792 Label done, not_smi; |
| 3793 testl(value, Immediate(kSmiTagMask)); |
| 3794 j(NOT_ZERO, ¬_smi, Assembler::kNearJump); |
| 3795 |
| 3796 sarq(value, Immediate(32)); // Take the tag into account. |
| 3797 movq(result, Immediate(ICData::kUint32RangeBit)); // Uint32 |
| 3798 cmpq(value, Immediate(1)); |
| 3799 j(EQUAL, &done, Assembler::kNearJump); |
| 3800 |
| 3801 movq(result, Immediate(ICData::kInt32RangeBit)); |
| 3802 subq(result, value); // 10 (positive int32), 11 (negative int32) |
| 3803 negq(value); |
| 3804 cmpq(value, Immediate(1)); |
| 3805 j(BELOW_EQUAL, &done); |
| 3806 |
| 3807 // On 64-bit we don't need to track sign of smis outside of the Int32 range. |
| 3808 // Just pretend they are all signed. |
| 3809 movq(result, Immediate(ICData::kSignedRangeBit)); |
| 3810 jmp(&done); |
| 3811 |
| 3812 Bind(¬_smi); |
| 3813 CompareClassId(value, kMintCid); |
| 3814 j(NOT_EQUAL, not_mint); |
| 3815 movq(result, Immediate(ICData::kInt64RangeBit)); |
| 3816 |
| 3817 Bind(&done); |
| 3818 } |
| 3819 |
| 3820 |
| 3821 void Assembler::UpdateRangeFeedback(Register value, |
| 3822 intptr_t index, |
| 3823 Register ic_data, |
| 3824 Register scratch, |
| 3825 Label* miss) { |
| 3826 ASSERT(ICData::IsValidRangeFeedbackIndex(index)); |
| 3827 ComputeRange(scratch, value, miss); |
| 3828 if (index != 0) { |
| 3829 shll(scratch, Immediate(ICData::kBitsPerRangeFeedback * index)); |
| 3830 } |
| 3831 orl(FieldAddress(ic_data, ICData::range_feedback_offset()), scratch); |
| 3832 } |
| 3833 |
| 3834 |
3783 Address Assembler::ElementAddressForIntIndex(bool is_external, | 3835 Address Assembler::ElementAddressForIntIndex(bool is_external, |
3784 intptr_t cid, | 3836 intptr_t cid, |
3785 intptr_t index_scale, | 3837 intptr_t index_scale, |
3786 Register array, | 3838 Register array, |
3787 intptr_t index) { | 3839 intptr_t index) { |
3788 if (is_external) { | 3840 if (is_external) { |
3789 return Address(array, index * index_scale); | 3841 return Address(array, index * index_scale); |
3790 } else { | 3842 } else { |
3791 const int64_t disp = static_cast<int64_t>(index) * index_scale + | 3843 const int64_t disp = static_cast<int64_t>(index) * index_scale + |
3792 Instance::DataOffsetFor(cid); | 3844 Instance::DataOffsetFor(cid); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3849 | 3901 |
3850 | 3902 |
3851 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3903 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
3852 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); | 3904 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); |
3853 return xmm_reg_names[reg]; | 3905 return xmm_reg_names[reg]; |
3854 } | 3906 } |
3855 | 3907 |
3856 } // namespace dart | 3908 } // namespace dart |
3857 | 3909 |
3858 #endif // defined TARGET_ARCH_X64 | 3910 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |