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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 #endif | 49 #endif |
50 unsigned CpuFeatures::supported_ = 0; | 50 unsigned CpuFeatures::supported_ = 0; |
51 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0; | 51 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0; |
52 | 52 |
53 | 53 |
54 ExternalReference ExternalReference::cpu_features() { | 54 ExternalReference ExternalReference::cpu_features() { |
55 ASSERT(CpuFeatures::initialized_); | 55 ASSERT(CpuFeatures::initialized_); |
56 return ExternalReference(&CpuFeatures::supported_); | 56 return ExternalReference(&CpuFeatures::supported_); |
57 } | 57 } |
58 | 58 |
| 59 |
59 // Get the CPU features enabled by the build. For cross compilation the | 60 // Get the CPU features enabled by the build. For cross compilation the |
60 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS | 61 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS |
61 // can be defined to enable ARMv7 and VFPv3 instructions when building the | 62 // can be defined to enable ARMv7 and VFPv3 instructions when building the |
62 // snapshot. | 63 // snapshot. |
63 static unsigned CpuFeaturesImpliedByCompiler() { | 64 static unsigned CpuFeaturesImpliedByCompiler() { |
64 unsigned answer = 0; | 65 unsigned answer = 0; |
65 #ifdef CAN_USE_ARMV7_INSTRUCTIONS | 66 #ifdef CAN_USE_ARMV7_INSTRUCTIONS |
66 if (FLAG_enable_armv7) { | 67 if (FLAG_enable_armv7) { |
67 answer |= 1u << ARMv7; | 68 answer |= 1u << ARMv7; |
68 } | 69 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 } | 350 } |
350 | 351 |
351 | 352 |
352 MemOperand::MemOperand(Register rn, int32_t offset, AddrMode am) { | 353 MemOperand::MemOperand(Register rn, int32_t offset, AddrMode am) { |
353 rn_ = rn; | 354 rn_ = rn; |
354 rm_ = no_reg; | 355 rm_ = no_reg; |
355 offset_ = offset; | 356 offset_ = offset; |
356 am_ = am; | 357 am_ = am; |
357 } | 358 } |
358 | 359 |
| 360 |
359 MemOperand::MemOperand(Register rn, Register rm, AddrMode am) { | 361 MemOperand::MemOperand(Register rn, Register rm, AddrMode am) { |
360 rn_ = rn; | 362 rn_ = rn; |
361 rm_ = rm; | 363 rm_ = rm; |
362 shift_op_ = LSL; | 364 shift_op_ = LSL; |
363 shift_imm_ = 0; | 365 shift_imm_ = 0; |
364 am_ = am; | 366 am_ = am; |
365 } | 367 } |
366 | 368 |
367 | 369 |
368 MemOperand::MemOperand(Register rn, Register rm, | 370 MemOperand::MemOperand(Register rn, Register rm, |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 ASSERT(IsCmpImmediate(instr)); | 672 ASSERT(IsCmpImmediate(instr)); |
671 return GetRn(instr); | 673 return GetRn(instr); |
672 } | 674 } |
673 | 675 |
674 | 676 |
675 int Assembler::GetCmpImmediateRawImmediate(Instr instr) { | 677 int Assembler::GetCmpImmediateRawImmediate(Instr instr) { |
676 ASSERT(IsCmpImmediate(instr)); | 678 ASSERT(IsCmpImmediate(instr)); |
677 return instr & kOff12Mask; | 679 return instr & kOff12Mask; |
678 } | 680 } |
679 | 681 |
| 682 |
680 // Labels refer to positions in the (to be) generated code. | 683 // Labels refer to positions in the (to be) generated code. |
681 // There are bound, linked, and unused labels. | 684 // There are bound, linked, and unused labels. |
682 // | 685 // |
683 // Bound labels refer to known positions in the already | 686 // Bound labels refer to known positions in the already |
684 // generated code. pos() is the position the label refers to. | 687 // generated code. pos() is the position the label refers to. |
685 // | 688 // |
686 // Linked labels refer to unknown positions in the code | 689 // Linked labels refer to unknown positions in the code |
687 // to be generated; pos() is the position of the last | 690 // to be generated; pos() is the position of the last |
688 // instruction using the label. | 691 // instruction using the label. |
689 | 692 |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1633 void Assembler::strd(Register src1, Register src2, | 1636 void Assembler::strd(Register src1, Register src2, |
1634 const MemOperand& dst, Condition cond) { | 1637 const MemOperand& dst, Condition cond) { |
1635 ASSERT(dst.rm().is(no_reg)); | 1638 ASSERT(dst.rm().is(no_reg)); |
1636 ASSERT(!src1.is(lr)); // r14. | 1639 ASSERT(!src1.is(lr)); // r14. |
1637 ASSERT_EQ(0, src1.code() % 2); | 1640 ASSERT_EQ(0, src1.code() % 2); |
1638 ASSERT_EQ(src1.code() + 1, src2.code()); | 1641 ASSERT_EQ(src1.code() + 1, src2.code()); |
1639 ASSERT(IsEnabled(ARMv7)); | 1642 ASSERT(IsEnabled(ARMv7)); |
1640 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); | 1643 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); |
1641 } | 1644 } |
1642 | 1645 |
| 1646 |
1643 // Load/Store multiple instructions. | 1647 // Load/Store multiple instructions. |
1644 void Assembler::ldm(BlockAddrMode am, | 1648 void Assembler::ldm(BlockAddrMode am, |
1645 Register base, | 1649 Register base, |
1646 RegList dst, | 1650 RegList dst, |
1647 Condition cond) { | 1651 Condition cond) { |
1648 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. | 1652 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. |
1649 ASSERT(base.is(sp) || (dst & sp.bit()) == 0); | 1653 ASSERT(base.is(sp) || (dst & sp.bit()) == 0); |
1650 | 1654 |
1651 addrmod4(cond | B27 | am | L, base, dst); | 1655 addrmod4(cond | B27 | am | L, base, dst); |
1652 | 1656 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 ASSERT(am == ia || am == ia_w || am == db_w); | 2071 ASSERT(am == ia || am == ia_w || am == db_w); |
2068 ASSERT(!base.is(pc)); | 2072 ASSERT(!base.is(pc)); |
2069 | 2073 |
2070 int sd, d; | 2074 int sd, d; |
2071 first.split_code(&sd, &d); | 2075 first.split_code(&sd, &d); |
2072 int count = last.code() - first.code() + 1; | 2076 int count = last.code() - first.code() + 1; |
2073 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 2077 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
2074 0xA*B8 | count); | 2078 0xA*B8 | count); |
2075 } | 2079 } |
2076 | 2080 |
| 2081 |
2077 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { | 2082 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
2078 uint64_t i; | 2083 uint64_t i; |
2079 OS::MemCopy(&i, &d, 8); | 2084 OS::MemCopy(&i, &d, 8); |
2080 | 2085 |
2081 *lo = i & 0xffffffff; | 2086 *lo = i & 0xffffffff; |
2082 *hi = i >> 32; | 2087 *hi = i >> 32; |
2083 } | 2088 } |
2084 | 2089 |
| 2090 |
2085 // Only works for little endian floating point formats. | 2091 // Only works for little endian floating point formats. |
2086 // We don't support VFP on the mixed endian floating point platform. | 2092 // We don't support VFP on the mixed endian floating point platform. |
2087 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { | 2093 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { |
2088 ASSERT(CpuFeatures::IsSupported(VFP3)); | 2094 ASSERT(CpuFeatures::IsSupported(VFP3)); |
2089 | 2095 |
2090 // VMOV can accept an immediate of the form: | 2096 // VMOV can accept an immediate of the form: |
2091 // | 2097 // |
2092 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 | 2098 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 |
2093 // | 2099 // |
2094 // The immediate is encoded using an 8-bit quantity, comprised of two | 2100 // The immediate is encoded using an 8-bit quantity, comprised of two |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2767 | 2773 |
2768 | 2774 |
2769 void Assembler::RecordConstPool(int size) { | 2775 void Assembler::RecordConstPool(int size) { |
2770 // We only need this for debugger support, to correctly compute offsets in the | 2776 // We only need this for debugger support, to correctly compute offsets in the |
2771 // code. | 2777 // code. |
2772 #ifdef ENABLE_DEBUGGER_SUPPORT | 2778 #ifdef ENABLE_DEBUGGER_SUPPORT |
2773 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); | 2779 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); |
2774 #endif | 2780 #endif |
2775 } | 2781 } |
2776 | 2782 |
| 2783 |
2777 void Assembler::GrowBuffer() { | 2784 void Assembler::GrowBuffer() { |
2778 if (!own_buffer_) FATAL("external code buffer is too small"); | 2785 if (!own_buffer_) FATAL("external code buffer is too small"); |
2779 | 2786 |
2780 // Compute new buffer size. | 2787 // Compute new buffer size. |
2781 CodeDesc desc; // the new buffer | 2788 CodeDesc desc; // the new buffer |
2782 if (buffer_size_ < 4*KB) { | 2789 if (buffer_size_ < 4*KB) { |
2783 desc.buffer_size = 4*KB; | 2790 desc.buffer_size = 4*KB; |
2784 } else if (buffer_size_ < 1*MB) { | 2791 } else if (buffer_size_ < 1*MB) { |
2785 desc.buffer_size = 2*buffer_size_; | 2792 desc.buffer_size = 2*buffer_size_; |
2786 } else { | 2793 } else { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2887 RecordedAstId().ToInt(), | 2894 RecordedAstId().ToInt(), |
2888 NULL); | 2895 NULL); |
2889 ClearRecordedAstId(); | 2896 ClearRecordedAstId(); |
2890 reloc_info_writer.Write(&reloc_info_with_ast_id); | 2897 reloc_info_writer.Write(&reloc_info_with_ast_id); |
2891 } else { | 2898 } else { |
2892 reloc_info_writer.Write(&rinfo); | 2899 reloc_info_writer.Write(&rinfo); |
2893 } | 2900 } |
2894 } | 2901 } |
2895 } | 2902 } |
2896 | 2903 |
| 2904 |
2897 void Assembler::RecordRelocInfo(double data) { | 2905 void Assembler::RecordRelocInfo(double data) { |
2898 // We do not try to reuse pool constants. | 2906 // We do not try to reuse pool constants. |
2899 RelocInfo rinfo(pc_, data); | 2907 RelocInfo rinfo(pc_, data); |
2900 RecordRelocInfoConstantPoolEntryHelper(rinfo); | 2908 RecordRelocInfoConstantPoolEntryHelper(rinfo); |
2901 } | 2909 } |
2902 | 2910 |
2903 | 2911 |
2904 void Assembler::RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo) { | 2912 void Assembler::RecordRelocInfoConstantPoolEntryHelper(const RelocInfo& rinfo) { |
2905 ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo); | 2913 ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo); |
2906 if (num_pending_reloc_info_ == 0) { | 2914 if (num_pending_reloc_info_ == 0) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3102 | 3110 |
3103 // Since a constant pool was just emitted, move the check offset forward by | 3111 // Since a constant pool was just emitted, move the check offset forward by |
3104 // the standard interval. | 3112 // the standard interval. |
3105 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 3113 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
3106 } | 3114 } |
3107 | 3115 |
3108 | 3116 |
3109 } } // namespace v8::internal | 3117 } } // namespace v8::internal |
3110 | 3118 |
3111 #endif // V8_TARGET_ARCH_ARM | 3119 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |