OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1852 // tagged as a small integer. | 1852 // tagged as a small integer. |
1853 __ InvokeBuiltin(native, JUMP_FUNCTION); | 1853 __ InvokeBuiltin(native, JUMP_FUNCTION); |
1854 } | 1854 } |
1855 | 1855 |
1856 | 1856 |
1857 // The stub expects its argument in the tos_ register and returns its result in | 1857 // The stub expects its argument in the tos_ register and returns its result in |
1858 // it, too: zero for false, and a non-zero value for true. | 1858 // it, too: zero for false, and a non-zero value for true. |
1859 void ToBooleanStub::Generate(MacroAssembler* masm) { | 1859 void ToBooleanStub::Generate(MacroAssembler* masm) { |
1860 // This stub overrides SometimesSetsUpAFrame() to return false. That means | 1860 // This stub overrides SometimesSetsUpAFrame() to return false. That means |
1861 // we cannot call anything that could cause a GC from this stub. | 1861 // we cannot call anything that could cause a GC from this stub. |
1862 // This stub uses VFP3 instructions. | |
1863 CpuFeatures::Scope scope(VFP2); | |
1864 | |
1865 Label patch; | 1862 Label patch; |
1866 const Register map = r9.is(tos_) ? r7 : r9; | 1863 const Register map = r9.is(tos_) ? r7 : r9; |
1864 const Register temp = map; | |
1867 | 1865 |
1868 // undefined -> false. | 1866 // undefined -> false. |
1869 CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false); | 1867 CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false); |
1870 | 1868 |
1871 // Boolean -> its value. | 1869 // Boolean -> its value. |
1872 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false); | 1870 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false); |
1873 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true); | 1871 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true); |
1874 | 1872 |
1875 // 'null' -> false. | 1873 // 'null' -> false. |
1876 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false); | 1874 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1909 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); | 1907 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); |
1910 __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset), lt); | 1908 __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset), lt); |
1911 __ Ret(lt); // the string length is OK as the return value | 1909 __ Ret(lt); // the string length is OK as the return value |
1912 } | 1910 } |
1913 | 1911 |
1914 if (types_.Contains(HEAP_NUMBER)) { | 1912 if (types_.Contains(HEAP_NUMBER)) { |
1915 // Heap number -> false iff +0, -0, or NaN. | 1913 // Heap number -> false iff +0, -0, or NaN. |
1916 Label not_heap_number; | 1914 Label not_heap_number; |
1917 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); | 1915 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); |
1918 __ b(ne, ¬_heap_number); | 1916 __ b(ne, ¬_heap_number); |
1919 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset)); | 1917 |
1920 __ VFPCompareAndSetFlags(d1, 0.0); | 1918 if (CpuFeatures::IsSupported(VFP2)) { |
1921 // "tos_" is a register, and contains a non zero value by default. | 1919 CpuFeatures::Scope scope(VFP2); |
1922 // Hence we only need to overwrite "tos_" with zero to return false for | 1920 |
1923 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. | 1921 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset)); |
1924 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO | 1922 __ VFPCompareAndSetFlags(d1, 0.0); |
1925 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN | 1923 // "tos_" is a register, and contains a non zero value by default. |
1924 // Hence we only need to overwrite "tos_" with zero to return false for | |
1925 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. | |
1926 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO | |
1927 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN | |
1928 } else { | |
1929 Label done, not_nan, not_zero; | |
1930 __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kExponentOffset)); | |
1931 // -0 maps to false: | |
1932 __ bic( | |
1933 temp, temp, Operand(HeapNumber::kSignMask, RelocInfo::NONE), SetCC); | |
1934 __ b(ne, ¬_zero); | |
1935 // If exponent word is zero then the answer depends on the mantissa word. | |
1936 __ ldr(tos_, FieldMemOperand(tos_, HeapNumber::kMantissaOffset)); | |
1937 __ jmp(&done); | |
1938 | |
1939 // Check for NaN. | |
1940 __ bind(¬_zero); | |
1941 // We already zeroed the sign bit, now shift out the mantissa so we only | |
1942 // have the exponent left. | |
1943 __ mov(temp, Operand(temp, LSR, HeapNumber::kMantissaBitsInTopWord)); | |
1944 unsigned int shifted_exponent_mask = | |
1945 HeapNumber::kExponentOffset >> HeapNumber::kMantissaBitsInTopWord; | |
Yang
2012/08/10 09:57:11
kExponentOffset's unit is bytes (8 on 32-bit syste
Erik Corry
2012/08/10 12:24:18
Good catch. Changed to kExponentMask.
| |
1946 __ cmp(temp, Operand(shifted_exponent_mask, RelocInfo::NONE)); | |
1947 __ b(ne, ¬_nan); // If exponent is not 0x7ff then it can't be a NaN. | |
1948 | |
1949 // Reload exponent word. | |
1950 __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kExponentOffset)); | |
1951 __ tst(temp, Operand(HeapNumber::kMantissaMask, RelocInfo::NONE)); | |
1952 // If mantissa is not zero then we have a NaN, so return 0. | |
1953 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne); | |
1954 __ b(ne, &done); | |
1955 | |
1956 // Load mantissa word. | |
1957 __ ldr(temp, FieldMemOperand(tos_, HeapNumber::kMantissaOffset)); | |
1958 __ cmp(temp, Operand(0, RelocInfo::NONE)); | |
1959 // If mantissa is not zero then we have a NaN, so return 0. | |
1960 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, ne); | |
1961 __ b(ne, &done); | |
1962 | |
1963 __ bind(¬_nan); | |
1964 __ mov(tos_, Operand(1, RelocInfo::NONE)); | |
1965 __ bind(&done); | |
1966 } | |
1926 __ Ret(); | 1967 __ Ret(); |
1927 __ bind(¬_heap_number); | 1968 __ bind(¬_heap_number); |
1928 } | 1969 } |
1929 | 1970 |
1930 __ bind(&patch); | 1971 __ bind(&patch); |
1931 GenerateTypeTransition(masm); | 1972 GenerateTypeTransition(masm); |
1932 } | 1973 } |
1933 | 1974 |
1934 | 1975 |
1935 void ToBooleanStub::CheckOddball(MacroAssembler* masm, | 1976 void ToBooleanStub::CheckOddball(MacroAssembler* masm, |
(...skipping 5635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7571 | 7612 |
7572 __ Pop(lr, r5, r1); | 7613 __ Pop(lr, r5, r1); |
7573 __ Ret(); | 7614 __ Ret(); |
7574 } | 7615 } |
7575 | 7616 |
7576 #undef __ | 7617 #undef __ |
7577 | 7618 |
7578 } } // namespace v8::internal | 7619 } } // namespace v8::internal |
7579 | 7620 |
7580 #endif // V8_TARGET_ARCH_ARM | 7621 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |