| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 866 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
| 867 __ cmp(r3, ip); | 867 __ cmp(r3, ip); |
| 868 __ b(eq, &probe_dictionary); | 868 __ b(eq, &probe_dictionary); |
| 869 | 869 |
| 870 // Load the map of the receiver, compute the keyed lookup cache hash | 870 // Load the map of the receiver, compute the keyed lookup cache hash |
| 871 // based on 32 bits of the map pointer and the string hash. | 871 // based on 32 bits of the map pointer and the string hash. |
| 872 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 872 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| 873 __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift)); | 873 __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift)); |
| 874 __ ldr(r4, FieldMemOperand(r0, String::kHashFieldOffset)); | 874 __ ldr(r4, FieldMemOperand(r0, String::kHashFieldOffset)); |
| 875 __ eor(r3, r3, Operand(r4, ASR, String::kHashShift)); | 875 __ eor(r3, r3, Operand(r4, ASR, String::kHashShift)); |
| 876 __ and_(r3, r3, Operand(KeyedLookupCache::kCapacityMask)); | 876 __ And(r3, r3, Operand(KeyedLookupCache::kCapacityMask)); |
| 877 | 877 |
| 878 // Load the key (consisting of map and symbol) from the cache and | 878 // Load the key (consisting of map and symbol) from the cache and |
| 879 // check for match. | 879 // check for match. |
| 880 ExternalReference cache_keys = ExternalReference::keyed_lookup_cache_keys(); | 880 ExternalReference cache_keys = ExternalReference::keyed_lookup_cache_keys(); |
| 881 __ mov(r4, Operand(cache_keys)); | 881 __ mov(r4, Operand(cache_keys)); |
| 882 __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1)); | 882 __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1)); |
| 883 __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); // Move r4 to symbol. | 883 __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); // Move r4 to symbol. |
| 884 __ cmp(r2, r5); | 884 __ cmp(r2, r5); |
| 885 __ b(ne, &slow); | 885 __ b(ne, &slow); |
| 886 __ ldr(r5, MemOperand(r4)); | 886 __ ldr(r5, MemOperand(r4)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 // conflict. | 925 // conflict. |
| 926 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < | 926 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < |
| 927 (1 << String::kArrayIndexValueBits)); | 927 (1 << String::kArrayIndexValueBits)); |
| 928 __ bind(&index_string); | 928 __ bind(&index_string); |
| 929 // r0: key (string) | 929 // r0: key (string) |
| 930 // r1: receiver | 930 // r1: receiver |
| 931 // r3: hash field | 931 // r3: hash field |
| 932 // We want the smi-tagged index in r0. kArrayIndexValueMask has zeros in | 932 // We want the smi-tagged index in r0. kArrayIndexValueMask has zeros in |
| 933 // the low kHashShift bits. | 933 // the low kHashShift bits. |
| 934 ASSERT(String::kHashShift >= kSmiTagSize); | 934 ASSERT(String::kHashShift >= kSmiTagSize); |
| 935 __ and_(r3, r3, Operand(String::kArrayIndexValueMask)); | 935 __ Ubfx(r3, r3, String::kHashShift, String::kArrayIndexValueBits); |
| 936 // Here we actually clobber the key (r0) which will be used if calling into | 936 // Here we actually clobber the key (r0) which will be used if calling into |
| 937 // runtime later. However as the new key is the numeric value of a string key | 937 // runtime later. However as the new key is the numeric value of a string key |
| 938 // there is no difference in using either key. | 938 // there is no difference in using either key. |
| 939 __ mov(r0, Operand(r3, ASR, String::kHashShift - kSmiTagSize)); | 939 __ mov(r0, Operand(r3, LSL, kSmiTagSize)); |
| 940 // Now jump to the place where smi keys are handled. | 940 // Now jump to the place where smi keys are handled. |
| 941 __ jmp(&index_smi); | 941 __ jmp(&index_smi); |
| 942 } | 942 } |
| 943 | 943 |
| 944 | 944 |
| 945 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 945 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
| 946 // ---------- S t a t e -------------- | 946 // ---------- S t a t e -------------- |
| 947 // -- lr : return address | 947 // -- lr : return address |
| 948 // -- r0 : key (index) | 948 // -- r0 : key (index) |
| 949 // -- r1 : receiver | 949 // -- r1 : receiver |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 | 1658 |
| 1659 // r3: base pointer of external storage. | 1659 // r3: base pointer of external storage. |
| 1660 // r4: key (integer). | 1660 // r4: key (integer). |
| 1661 | 1661 |
| 1662 // The WebGL specification leaves the behavior of storing NaN and | 1662 // The WebGL specification leaves the behavior of storing NaN and |
| 1663 // +/-Infinity into integer arrays basically undefined. For more | 1663 // +/-Infinity into integer arrays basically undefined. For more |
| 1664 // reproducible behavior, convert these to zero. | 1664 // reproducible behavior, convert these to zero. |
| 1665 if (CpuFeatures::IsSupported(VFP3)) { | 1665 if (CpuFeatures::IsSupported(VFP3)) { |
| 1666 CpuFeatures::Scope scope(VFP3); | 1666 CpuFeatures::Scope scope(VFP3); |
| 1667 | 1667 |
| 1668 // vldr requires offset to be a multiple of 4 so we can not | |
| 1669 // include -kHeapObjectTag into it. | |
| 1670 __ sub(r5, r0, Operand(kHeapObjectTag)); | |
| 1671 __ vldr(d0, r5, HeapNumber::kValueOffset); | |
| 1672 | 1668 |
| 1673 if (array_type == kExternalFloatArray) { | 1669 if (array_type == kExternalFloatArray) { |
| 1670 // vldr requires offset to be a multiple of 4 so we can not |
| 1671 // include -kHeapObjectTag into it. |
| 1672 __ sub(r5, r0, Operand(kHeapObjectTag)); |
| 1673 __ vldr(d0, r5, HeapNumber::kValueOffset); |
| 1674 __ vcvt_f32_f64(s0, d0); | 1674 __ vcvt_f32_f64(s0, d0); |
| 1675 __ vmov(r5, s0); | 1675 __ vmov(r5, s0); |
| 1676 __ str(r5, MemOperand(r3, r4, LSL, 2)); | 1676 __ str(r5, MemOperand(r3, r4, LSL, 2)); |
| 1677 } else { | 1677 } else { |
| 1678 Label done; | 1678 // Need to perform float-to-int conversion. |
| 1679 // Test for NaN or infinity (both give zero). |
| 1680 __ ldr(r6, FieldMemOperand(r5, HeapNumber::kExponentOffset)); |
| 1679 | 1681 |
| 1680 // Need to perform float-to-int conversion. | 1682 // Hoisted load. vldr requires offset to be a multiple of 4 so we can not |
| 1681 // Test for NaN. | 1683 // include -kHeapObjectTag into it. |
| 1682 __ vcmp(d0, d0); | 1684 __ sub(r5, r0, Operand(kHeapObjectTag)); |
| 1683 // Move vector status bits to normal status bits. | 1685 __ vldr(d0, r5, HeapNumber::kValueOffset); |
| 1684 __ vmrs(v8::internal::pc); | |
| 1685 __ mov(r5, Operand(0), LeaveCC, vs); // NaN converts to 0. | |
| 1686 __ b(vs, &done); | |
| 1687 | 1686 |
| 1688 // Test whether exponent equal to 0x7FF (infinity or NaN). | 1687 __ Sbfx(r6, r6, HeapNumber::kExponentShift, HeapNumber::kExponentBits); |
| 1689 __ vmov(r6, r7, d0); | 1688 // NaNs and Infinities have all-one exponents so they sign extend to -1. |
| 1690 __ mov(r5, Operand(0x7FF00000)); | 1689 __ cmp(r6, Operand(-1)); |
| 1691 __ and_(r6, r6, Operand(r5)); | 1690 __ mov(r5, Operand(Smi::FromInt(0)), LeaveCC, eq); |
| 1692 __ teq(r6, Operand(r5)); | |
| 1693 __ mov(r6, Operand(0), LeaveCC, eq); | |
| 1694 | 1691 |
| 1695 // Not infinity or NaN simply convert to int. | 1692 // Not infinity or NaN simply convert to int. |
| 1696 if (IsElementTypeSigned(array_type)) { | 1693 if (IsElementTypeSigned(array_type)) { |
| 1697 __ vcvt_s32_f64(s0, d0, ne); | 1694 __ vcvt_s32_f64(s0, d0, ne); |
| 1698 } else { | 1695 } else { |
| 1699 __ vcvt_u32_f64(s0, d0, ne); | 1696 __ vcvt_u32_f64(s0, d0, ne); |
| 1700 } | 1697 } |
| 1701 | |
| 1702 __ vmov(r5, s0, ne); | 1698 __ vmov(r5, s0, ne); |
| 1703 | 1699 |
| 1704 __ bind(&done); | |
| 1705 switch (array_type) { | 1700 switch (array_type) { |
| 1706 case kExternalByteArray: | 1701 case kExternalByteArray: |
| 1707 case kExternalUnsignedByteArray: | 1702 case kExternalUnsignedByteArray: |
| 1708 __ strb(r5, MemOperand(r3, r4, LSL, 0)); | 1703 __ strb(r5, MemOperand(r3, r4, LSL, 0)); |
| 1709 break; | 1704 break; |
| 1710 case kExternalShortArray: | 1705 case kExternalShortArray: |
| 1711 case kExternalUnsignedShortArray: | 1706 case kExternalUnsignedShortArray: |
| 1712 __ strh(r5, MemOperand(r3, r4, LSL, 1)); | 1707 __ strh(r5, MemOperand(r3, r4, LSL, 1)); |
| 1713 break; | 1708 break; |
| 1714 case kExternalIntArray: | 1709 case kExternalIntArray: |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1940 GenerateMiss(masm); | 1935 GenerateMiss(masm); |
| 1941 } | 1936 } |
| 1942 | 1937 |
| 1943 | 1938 |
| 1944 #undef __ | 1939 #undef __ |
| 1945 | 1940 |
| 1946 | 1941 |
| 1947 } } // namespace v8::internal | 1942 } } // namespace v8::internal |
| 1948 | 1943 |
| 1949 #endif // V8_TARGET_ARCH_ARM | 1944 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |