| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
| 4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
| 5 // met: | 5 // met: |
| 6 // | 6 // |
| 7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
| 9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
| 10 // copyright notice, this list of conditions and the following | 10 // copyright notice, this list of conditions and the following |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 28 | 28 |
| 29 #include "v8.h" | 29 #include "v8.h" |
| 30 | 30 |
| 31 #if V8_TARGET_ARCH_A64 | 31 #if V8_TARGET_ARCH_A64 |
| 32 | 32 |
| 33 #define A64_DEFINE_REG_STATICS |
| 34 |
| 33 #include "a64/assembler-a64-inl.h" | 35 #include "a64/assembler-a64-inl.h" |
| 34 | 36 |
| 35 namespace v8 { | 37 namespace v8 { |
| 36 namespace internal { | 38 namespace internal { |
| 37 | 39 |
| 38 | 40 |
| 39 // ----------------------------------------------------------------------------- | 41 // ----------------------------------------------------------------------------- |
| 40 // CpuFeatures utilities (for V8 compatibility). | 42 // CpuFeatures utilities (for V8 compatibility). |
| 41 | 43 |
| 42 ExternalReference ExternalReference::cpu_features() { | 44 ExternalReference ExternalReference::cpu_features() { |
| 43 return ExternalReference(&CpuFeatures::supported_); | 45 return ExternalReference(&CpuFeatures::supported_); |
| 44 } | 46 } |
| 45 | 47 |
| 46 | 48 |
| 47 // ----------------------------------------------------------------------------- | 49 // ----------------------------------------------------------------------------- |
| 48 // CPURegList utilities. | 50 // CPURegList utilities. |
| 49 | 51 |
| 50 CPURegister CPURegList::PopLowestIndex() { | 52 CPURegister CPURegList::PopLowestIndex() { |
| 51 ASSERT(IsValid()); | 53 ASSERT(IsValid()); |
| 52 if (IsEmpty()) { | 54 if (IsEmpty()) { |
| 53 return NoCPUReg; | 55 return NoCPUReg; |
| 54 } | 56 } |
| 55 int index = CountTrailingZeros(list_, kRegListSizeInBits); | 57 int index = CountTrailingZeros(list_, kRegListSizeInBits); |
| 56 ASSERT((1 << index) & list_); | 58 ASSERT((1 << index) & list_); |
| 57 Remove(index); | 59 Remove(index); |
| 58 return CPURegister(index, size_, type_); | 60 return CPURegister::Create(index, size_, type_); |
| 59 } | 61 } |
| 60 | 62 |
| 61 | 63 |
| 62 CPURegister CPURegList::PopHighestIndex() { | 64 CPURegister CPURegList::PopHighestIndex() { |
| 63 ASSERT(IsValid()); | 65 ASSERT(IsValid()); |
| 64 if (IsEmpty()) { | 66 if (IsEmpty()) { |
| 65 return NoCPUReg; | 67 return NoCPUReg; |
| 66 } | 68 } |
| 67 int index = CountLeadingZeros(list_, kRegListSizeInBits); | 69 int index = CountLeadingZeros(list_, kRegListSizeInBits); |
| 68 index = kRegListSizeInBits - 1 - index; | 70 index = kRegListSizeInBits - 1 - index; |
| 69 ASSERT((1 << index) & list_); | 71 ASSERT((1 << index) & list_); |
| 70 Remove(index); | 72 Remove(index); |
| 71 return CPURegister(index, size_, type_); | 73 return CPURegister::Create(index, size_, type_); |
| 72 } | 74 } |
| 73 | 75 |
| 74 | 76 |
| 75 void CPURegList::RemoveCalleeSaved() { | 77 void CPURegList::RemoveCalleeSaved() { |
| 76 if (type() == CPURegister::kRegister) { | 78 if (type() == CPURegister::kRegister) { |
| 77 Remove(GetCalleeSaved(RegisterSizeInBits())); | 79 Remove(GetCalleeSaved(RegisterSizeInBits())); |
| 78 } else if (type() == CPURegister::kFPRegister) { | 80 } else if (type() == CPURegister::kFPRegister) { |
| 79 Remove(GetCalleeSavedFP(RegisterSizeInBits())); | 81 Remove(GetCalleeSavedFP(RegisterSizeInBits())); |
| 80 } else { | 82 } else { |
| 81 ASSERT(type() == CPURegister::kNoRegister); | 83 ASSERT(type() == CPURegister::kNoRegister); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 104 | 106 |
| 105 | 107 |
| 106 CPURegList CPURegList::GetCallerSavedFP(unsigned size) { | 108 CPURegList CPURegList::GetCallerSavedFP(unsigned size) { |
| 107 // Registers d0-d7 and d16-d31 are caller-saved. | 109 // Registers d0-d7 and d16-d31 are caller-saved. |
| 108 CPURegList list = CPURegList(CPURegister::kFPRegister, size, 0, 7); | 110 CPURegList list = CPURegList(CPURegister::kFPRegister, size, 0, 7); |
| 109 list.Combine(CPURegList(CPURegister::kFPRegister, size, 16, 31)); | 111 list.Combine(CPURegList(CPURegister::kFPRegister, size, 16, 31)); |
| 110 return list; | 112 return list; |
| 111 } | 113 } |
| 112 | 114 |
| 113 | 115 |
| 114 const CPURegList kCalleeSaved = CPURegList::GetCalleeSaved(); | |
| 115 const CPURegList kCalleeSavedFP = CPURegList::GetCalleeSavedFP(); | |
| 116 const CPURegList kCallerSaved = CPURegList::GetCallerSaved(); | |
| 117 const CPURegList kCallerSavedFP = CPURegList::GetCallerSavedFP(); | |
| 118 | |
| 119 | |
| 120 // This function defines the list of registers which are associated with a | 116 // This function defines the list of registers which are associated with a |
| 121 // safepoint slot. Safepoint register slots are saved contiguously on the stack. | 117 // safepoint slot. Safepoint register slots are saved contiguously on the stack. |
| 122 // MacroAssembler::SafepointRegisterStackIndex handles mapping from register | 118 // MacroAssembler::SafepointRegisterStackIndex handles mapping from register |
| 123 // code to index in the safepoint register slots. Any change here can affect | 119 // code to index in the safepoint register slots. Any change here can affect |
| 124 // this mapping. | 120 // this mapping. |
| 125 CPURegList CPURegList::GetSafepointSavedRegisters() { | 121 CPURegList CPURegList::GetSafepointSavedRegisters() { |
| 126 CPURegList list = CPURegList::GetCalleeSaved(); | 122 CPURegList list = CPURegList::GetCalleeSaved(); |
| 127 list.Combine(CPURegList(CPURegister::kRegister, kXRegSize, kJSCallerSaved)); | 123 list.Combine(CPURegList(CPURegister::kRegister, kXRegSize, kJSCallerSaved)); |
| 128 | 124 |
| 129 // Note that unfortunately we can't use symbolic names for registers and have | 125 // Note that unfortunately we can't use symbolic names for registers and have |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 } | 173 } |
| 178 | 174 |
| 179 | 175 |
| 180 // Patch the code at the current PC with a call to the target address. | 176 // Patch the code at the current PC with a call to the target address. |
| 181 // Additional guard instructions can be added if required. | 177 // Additional guard instructions can be added if required. |
| 182 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { | 178 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { |
| 183 UNIMPLEMENTED(); | 179 UNIMPLEMENTED(); |
| 184 } | 180 } |
| 185 | 181 |
| 186 | 182 |
| 187 // Registers. | |
| 188 #define XREG(n) x##n, | |
| 189 const Register Register::xregisters[] = { | |
| 190 REGISTER_CODE_LIST(XREG) | |
| 191 }; | |
| 192 #undef XREG | |
| 193 | |
| 194 #define WREG(n) w##n, | |
| 195 const Register Register::wregisters[] = { | |
| 196 REGISTER_CODE_LIST(WREG) | |
| 197 }; | |
| 198 #undef WREG | |
| 199 | |
| 200 #define SREG(n) s##n, | |
| 201 const FPRegister FPRegister::sregisters[] = { | |
| 202 REGISTER_CODE_LIST(SREG) | |
| 203 }; | |
| 204 #undef SREG | |
| 205 | |
| 206 #define DREG(n) d##n, | |
| 207 const FPRegister FPRegister::dregisters[] = { | |
| 208 REGISTER_CODE_LIST(DREG) | |
| 209 }; | |
| 210 #undef DREG | |
| 211 | |
| 212 bool AreAliased(const CPURegister& reg1, const CPURegister& reg2, | 183 bool AreAliased(const CPURegister& reg1, const CPURegister& reg2, |
| 213 const CPURegister& reg3, const CPURegister& reg4, | 184 const CPURegister& reg3, const CPURegister& reg4, |
| 214 const CPURegister& reg5, const CPURegister& reg6, | 185 const CPURegister& reg5, const CPURegister& reg6, |
| 215 const CPURegister& reg7, const CPURegister& reg8) { | 186 const CPURegister& reg7, const CPURegister& reg8) { |
| 216 int number_of_valid_regs = 0; | 187 int number_of_valid_regs = 0; |
| 217 int number_of_valid_fpregs = 0; | 188 int number_of_valid_fpregs = 0; |
| 218 | 189 |
| 219 RegList unique_regs = 0; | 190 RegList unique_regs = 0; |
| 220 RegList unique_fpregs = 0; | 191 RegList unique_fpregs = 0; |
| 221 | 192 |
| (...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 } | 1919 } |
| 1949 | 1920 |
| 1950 | 1921 |
| 1951 void Assembler::EmitExtendShift(const Register& rd, | 1922 void Assembler::EmitExtendShift(const Register& rd, |
| 1952 const Register& rn, | 1923 const Register& rn, |
| 1953 Extend extend, | 1924 Extend extend, |
| 1954 unsigned left_shift) { | 1925 unsigned left_shift) { |
| 1955 ASSERT(rd.SizeInBits() >= rn.SizeInBits()); | 1926 ASSERT(rd.SizeInBits() >= rn.SizeInBits()); |
| 1956 unsigned reg_size = rd.SizeInBits(); | 1927 unsigned reg_size = rd.SizeInBits(); |
| 1957 // Use the correct size of register. | 1928 // Use the correct size of register. |
| 1958 Register rn_ = Register(rn.code(), rd.SizeInBits()); | 1929 Register rn_ = Register::Create(rn.code(), rd.SizeInBits()); |
| 1959 // Bits extracted are high_bit:0. | 1930 // Bits extracted are high_bit:0. |
| 1960 unsigned high_bit = (8 << (extend & 0x3)) - 1; | 1931 unsigned high_bit = (8 << (extend & 0x3)) - 1; |
| 1961 // Number of bits left in the result that are not introduced by the shift. | 1932 // Number of bits left in the result that are not introduced by the shift. |
| 1962 unsigned non_shift_bits = (reg_size - left_shift) & (reg_size - 1); | 1933 unsigned non_shift_bits = (reg_size - left_shift) & (reg_size - 1); |
| 1963 | 1934 |
| 1964 if ((non_shift_bits > high_bit) || (non_shift_bits == 0)) { | 1935 if ((non_shift_bits > high_bit) || (non_shift_bits == 0)) { |
| 1965 switch (extend) { | 1936 switch (extend) { |
| 1966 case UXTB: | 1937 case UXTB: |
| 1967 case UXTH: | 1938 case UXTH: |
| 1968 case UXTW: ubfm(rd, rn_, non_shift_bits, high_bit); break; | 1939 case UXTW: ubfm(rd, rn_, non_shift_bits, high_bit); break; |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2514 // code. | 2485 // code. |
| 2515 #ifdef ENABLE_DEBUGGER_SUPPORT | 2486 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 2516 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); | 2487 RecordRelocInfo(RelocInfo::CONST_POOL, static_cast<intptr_t>(size)); |
| 2517 #endif | 2488 #endif |
| 2518 } | 2489 } |
| 2519 | 2490 |
| 2520 | 2491 |
| 2521 } } // namespace v8::internal | 2492 } } // namespace v8::internal |
| 2522 | 2493 |
| 2523 #endif // V8_TARGET_ARCH_A64 | 2494 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |