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 |