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 1923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1934 // it. | 1934 // it. |
1935 GenerateJumpFunctionIgnoreReceiver(function); | 1935 GenerateJumpFunctionIgnoreReceiver(function); |
1936 | 1936 |
1937 HandlerFrontendFooter(&miss); | 1937 HandlerFrontendFooter(&miss); |
1938 | 1938 |
1939 // Return the generated code. | 1939 // Return the generated code. |
1940 return GetCode(type, name); | 1940 return GetCode(type, name); |
1941 } | 1941 } |
1942 | 1942 |
1943 | 1943 |
1944 Handle<Code> CallStubCompiler::CompileMathFloorCall( | |
1945 Handle<Object> object, | |
1946 Handle<JSObject> holder, | |
1947 Handle<Cell> cell, | |
1948 Handle<JSFunction> function, | |
1949 Handle<String> name, | |
1950 Code::StubType type) { | |
1951 const int argc = arguments().immediate(); | |
1952 // If the object is not a JSObject or we got an unexpected number of | |
1953 // arguments, bail out to the regular call. | |
1954 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | |
1955 | |
1956 Label miss, slow; | |
1957 | |
1958 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | |
1959 if (!cell.is_null()) { | |
1960 ASSERT(cell->value() == *function); | |
1961 GenerateLoadFunctionFromCell(cell, function, &miss); | |
1962 } | |
1963 | |
1964 // Load the (only) argument into r0. | |
1965 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); | |
1966 | |
1967 // If the argument is a smi, just return. | |
1968 __ SmiTst(r0); | |
1969 __ Drop(argc + 1, eq); | |
1970 __ Ret(eq); | |
1971 | |
1972 __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK); | |
1973 | |
1974 Label smi_check, just_return; | |
1975 | |
1976 // Load the HeapNumber value. | |
1977 // We will need access to the value in the core registers, so we load it | |
1978 // with ldrd and move it to the fpu. It also spares a sub instruction for | |
1979 // updating the HeapNumber value address, as vldr expects a multiple | |
1980 // of 4 offset. | |
1981 __ Ldrd(r4, r5, FieldMemOperand(r0, HeapNumber::kValueOffset)); | |
1982 __ vmov(d1, r4, r5); | |
1983 | |
1984 // Check for NaN, Infinities and -0. | |
1985 // They are invariant through a Math.Floor call, so just | |
1986 // return the original argument. | |
1987 __ Sbfx(r3, r5, HeapNumber::kExponentShift, HeapNumber::kExponentBits); | |
1988 __ cmp(r3, Operand(-1)); | |
1989 __ b(eq, &just_return); | |
1990 __ eor(r3, r5, Operand(0x80000000u)); | |
1991 __ orr(r3, r3, r4, SetCC); | |
1992 __ b(eq, &just_return); | |
1993 // Test for values that can be exactly represented as a | |
1994 // signed 32-bit integer. | |
1995 __ TryDoubleToInt32Exact(r0, d1, d2); | |
1996 // If exact, check smi | |
1997 __ b(eq, &smi_check); | |
1998 __ cmp(r5, Operand(0)); | |
1999 | |
2000 // If input is in ]+0, +inf[, the cmp has cleared overflow and negative | |
2001 // (V=0 and N=0), the two following instructions won't execute and | |
2002 // we fall through smi_check to check if the result can fit into a smi. | |
2003 | |
2004 // If input is in ]-inf, -0[, sub one and, go to slow if we have | |
2005 // an overflow. Else we fall through smi check. | |
2006 // Hint: if x is a negative, non integer number, | |
2007 // floor(x) <=> round_to_zero(x) - 1. | |
2008 __ sub(r0, r0, Operand(1), SetCC, mi); | |
2009 __ b(vs, &slow); | |
2010 | |
2011 __ bind(&smi_check); | |
2012 // Check if the result can fit into an smi. If we had an overflow, | |
2013 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. | |
2014 // If result doesn't fit into an smi, branch to slow. | |
2015 __ SmiTag(r0, SetCC); | |
2016 __ b(vs, &slow); | |
2017 | |
2018 __ bind(&just_return); | |
2019 __ Drop(argc + 1); | |
2020 __ Ret(); | |
2021 | |
2022 __ bind(&slow); | |
2023 // We do not have to patch the receiver because the function makes no use of | |
2024 // it. | |
2025 GenerateJumpFunctionIgnoreReceiver(function); | |
2026 | |
2027 HandlerFrontendFooter(&miss); | |
2028 | |
2029 // Return the generated code. | |
2030 return GetCode(type, name); | |
2031 } | |
2032 | |
2033 | |
2034 Handle<Code> CallStubCompiler::CompileMathAbsCall( | |
2035 Handle<Object> object, | |
2036 Handle<JSObject> holder, | |
2037 Handle<Cell> cell, | |
2038 Handle<JSFunction> function, | |
2039 Handle<String> name, | |
2040 Code::StubType type) { | |
2041 const int argc = arguments().immediate(); | |
2042 // If the object is not a JSObject or we got an unexpected number of | |
2043 // arguments, bail out to the regular call. | |
2044 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | |
2045 | |
2046 Label miss; | |
2047 | |
2048 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); | |
2049 if (!cell.is_null()) { | |
2050 ASSERT(cell->value() == *function); | |
2051 GenerateLoadFunctionFromCell(cell, function, &miss); | |
2052 } | |
2053 | |
2054 // Load the (only) argument into r0. | |
2055 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); | |
2056 | |
2057 // Check if the argument is a smi. | |
2058 Label not_smi; | |
2059 __ JumpIfNotSmi(r0, ¬_smi); | |
2060 | |
2061 // Do bitwise not or do nothing depending on the sign of the | |
2062 // argument. | |
2063 __ eor(r1, r0, Operand(r0, ASR, kBitsPerInt - 1)); | |
2064 | |
2065 // Add 1 or do nothing depending on the sign of the argument. | |
2066 __ sub(r0, r1, Operand(r0, ASR, kBitsPerInt - 1), SetCC); | |
2067 | |
2068 // If the result is still negative, go to the slow case. | |
2069 // This only happens for the most negative smi. | |
2070 Label slow; | |
2071 __ b(mi, &slow); | |
2072 | |
2073 // Smi case done. | |
2074 __ Drop(argc + 1); | |
2075 __ Ret(); | |
2076 | |
2077 // Check if the argument is a heap number and load its exponent and | |
2078 // sign. | |
2079 __ bind(¬_smi); | |
2080 __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK); | |
2081 __ ldr(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | |
2082 | |
2083 // Check the sign of the argument. If the argument is positive, | |
2084 // just return it. | |
2085 Label negative_sign; | |
2086 __ tst(r1, Operand(HeapNumber::kSignMask)); | |
2087 __ b(ne, &negative_sign); | |
2088 __ Drop(argc + 1); | |
2089 __ Ret(); | |
2090 | |
2091 // If the argument is negative, clear the sign, and return a new | |
2092 // number. | |
2093 __ bind(&negative_sign); | |
2094 __ eor(r1, r1, Operand(HeapNumber::kSignMask)); | |
2095 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | |
2096 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | |
2097 __ AllocateHeapNumber(r0, r4, r5, r6, &slow); | |
2098 __ str(r1, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | |
2099 __ str(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | |
2100 __ Drop(argc + 1); | |
2101 __ Ret(); | |
2102 | |
2103 __ bind(&slow); | |
2104 // We do not have to patch the receiver because the function makes no use of | |
2105 // it. | |
2106 GenerateJumpFunctionIgnoreReceiver(function); | |
2107 | |
2108 HandlerFrontendFooter(&miss); | |
2109 | |
2110 // Return the generated code. | |
2111 return GetCode(type, name); | |
2112 } | |
2113 | |
2114 | |
2115 Handle<Code> CallStubCompiler::CompileFastApiCall( | 1944 Handle<Code> CallStubCompiler::CompileFastApiCall( |
2116 const CallOptimization& optimization, | 1945 const CallOptimization& optimization, |
2117 Handle<Object> object, | 1946 Handle<Object> object, |
2118 Handle<JSObject> holder, | 1947 Handle<JSObject> holder, |
2119 Handle<Cell> cell, | 1948 Handle<Cell> cell, |
2120 Handle<JSFunction> function, | 1949 Handle<JSFunction> function, |
2121 Handle<String> name) { | 1950 Handle<String> name) { |
2122 Counters* counters = isolate()->counters(); | 1951 Counters* counters = isolate()->counters(); |
2123 | 1952 |
2124 ASSERT(optimization.is_simple_api_call()); | 1953 ASSERT(optimization.is_simple_api_call()); |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2726 // ----------------------------------- | 2555 // ----------------------------------- |
2727 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 2556 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
2728 } | 2557 } |
2729 | 2558 |
2730 | 2559 |
2731 #undef __ | 2560 #undef __ |
2732 | 2561 |
2733 } } // namespace v8::internal | 2562 } } // namespace v8::internal |
2734 | 2563 |
2735 #endif // V8_TARGET_ARCH_ARM | 2564 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |