| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 // Handle double (heap number) exponents. | 1175 // Handle double (heap number) exponents. |
| 1176 if (exponent_type_ != INTEGER) { | 1176 if (exponent_type_ != INTEGER) { |
| 1177 // Detect integer exponents stored as doubles and handle those in the | 1177 // Detect integer exponents stored as doubles and handle those in the |
| 1178 // integer fast-path. | 1178 // integer fast-path. |
| 1179 __ TryConvertDoubleToInt64(exponent_integer, exponent_double, | 1179 __ TryConvertDoubleToInt64(exponent_integer, exponent_double, |
| 1180 scratch0_double, &exponent_is_integer); | 1180 scratch0_double, &exponent_is_integer); |
| 1181 | 1181 |
| 1182 if (exponent_type_ == ON_STACK) { | 1182 if (exponent_type_ == ON_STACK) { |
| 1183 FPRegister half_double = d3; | 1183 FPRegister half_double = d3; |
| 1184 FPRegister minus_half_double = d4; | 1184 FPRegister minus_half_double = d4; |
| 1185 FPRegister zero_double = d5; | |
| 1186 // Detect square root case. Crankshaft detects constant +/-0.5 at compile | 1185 // Detect square root case. Crankshaft detects constant +/-0.5 at compile |
| 1187 // time and uses DoMathPowHalf instead. We then skip this check for | 1186 // time and uses DoMathPowHalf instead. We then skip this check for |
| 1188 // non-constant cases of +/-0.5 as these hardly occur. | 1187 // non-constant cases of +/-0.5 as these hardly occur. |
| 1189 | 1188 |
| 1190 __ Fmov(minus_half_double, -0.5); | 1189 __ Fmov(minus_half_double, -0.5); |
| 1191 __ Fmov(half_double, 0.5); | 1190 __ Fmov(half_double, 0.5); |
| 1192 __ Fcmp(minus_half_double, exponent_double); | 1191 __ Fcmp(minus_half_double, exponent_double); |
| 1193 __ Fccmp(half_double, exponent_double, NZFlag, ne); | 1192 __ Fccmp(half_double, exponent_double, NZFlag, ne); |
| 1194 // Condition flags at this point: | 1193 // Condition flags at this point: |
| 1195 // 0.5; nZCv // Identified by eq && pl | 1194 // 0.5; nZCv // Identified by eq && pl |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1208 // exponent == -0.5: The result is +0. | 1207 // exponent == -0.5: The result is +0. |
| 1209 // (base == +0) || (base == -0) | 1208 // (base == +0) || (base == -0) |
| 1210 // exponent == 0.5: The result is +0. | 1209 // exponent == 0.5: The result is +0. |
| 1211 // exponent == -0.5: The result is +INFINITY. | 1210 // exponent == -0.5: The result is +INFINITY. |
| 1212 // (base < 0) && base.isFinite(): The result is NaN. | 1211 // (base < 0) && base.isFinite(): The result is NaN. |
| 1213 // | 1212 // |
| 1214 // Fsqrt (and Fdiv for the -0.5 case) can handle all of those except | 1213 // Fsqrt (and Fdiv for the -0.5 case) can handle all of those except |
| 1215 // where base is -INFINITY or -0. | 1214 // where base is -INFINITY or -0. |
| 1216 | 1215 |
| 1217 // Add +0 to base. This has no effect other than turning -0 into +0. | 1216 // Add +0 to base. This has no effect other than turning -0 into +0. |
| 1218 __ Fmov(zero_double, 0.0); | 1217 __ Fadd(base_double, base_double, fp_zero); |
| 1219 __ Fadd(base_double, base_double, zero_double); | |
| 1220 // The operation -0+0 results in +0 in all cases except where the | 1218 // The operation -0+0 results in +0 in all cases except where the |
| 1221 // FPCR rounding mode is 'round towards minus infinity' (RM). The | 1219 // FPCR rounding mode is 'round towards minus infinity' (RM). The |
| 1222 // A64 simulator does not currently simulate FPCR (where the rounding | 1220 // A64 simulator does not currently simulate FPCR (where the rounding |
| 1223 // mode is set), so test the operation with some debug code. | 1221 // mode is set), so test the operation with some debug code. |
| 1224 if (masm->emit_debug_code()) { | 1222 if (masm->emit_debug_code()) { |
| 1225 Register temp = masm->Tmp1(); | 1223 Register temp = masm->Tmp1(); |
| 1226 // d5 zero_double The value +0.0 as a double. | 1224 __ Fneg(scratch0_double, fp_zero); |
| 1227 __ Fneg(scratch0_double, zero_double); | |
| 1228 // Verify that we correctly generated +0.0 and -0.0. | 1225 // Verify that we correctly generated +0.0 and -0.0. |
| 1229 // bits(+0.0) = 0x0000000000000000 | 1226 // bits(+0.0) = 0x0000000000000000 |
| 1230 // bits(-0.0) = 0x8000000000000000 | 1227 // bits(-0.0) = 0x8000000000000000 |
| 1231 __ Fmov(temp, zero_double); | 1228 __ Fmov(temp, fp_zero); |
| 1232 __ CheckRegisterIsClear(temp, kCouldNotGenerateZero); | 1229 __ CheckRegisterIsClear(temp, kCouldNotGenerateZero); |
| 1233 __ Fmov(temp, scratch0_double); | 1230 __ Fmov(temp, scratch0_double); |
| 1234 __ Eor(temp, temp, kDSignMask); | 1231 __ Eor(temp, temp, kDSignMask); |
| 1235 __ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero); | 1232 __ CheckRegisterIsClear(temp, kCouldNotGenerateNegativeZero); |
| 1236 // Check that -0.0 + 0.0 == +0.0. | 1233 // Check that -0.0 + 0.0 == +0.0. |
| 1237 __ Fadd(scratch0_double, scratch0_double, zero_double); | 1234 __ Fadd(scratch0_double, scratch0_double, fp_zero); |
| 1238 __ Fmov(temp, scratch0_double); | 1235 __ Fmov(temp, scratch0_double); |
| 1239 __ CheckRegisterIsClear(temp, kExpectedPositiveZero); | 1236 __ CheckRegisterIsClear(temp, kExpectedPositiveZero); |
| 1240 } | 1237 } |
| 1241 | 1238 |
| 1242 // If base is -INFINITY, make it +INFINITY. | 1239 // If base is -INFINITY, make it +INFINITY. |
| 1243 // * Calculate base - base: All infinities will become NaNs since both | 1240 // * Calculate base - base: All infinities will become NaNs since both |
| 1244 // -INFINITY+INFINITY and +INFINITY-INFINITY are NaN in A64. | 1241 // -INFINITY+INFINITY and +INFINITY-INFINITY are NaN in A64. |
| 1245 // * If the result is NaN, calculate abs(base). | 1242 // * If the result is NaN, calculate abs(base). |
| 1246 __ Fsub(scratch0_double, base_double, base_double); | 1243 __ Fsub(scratch0_double, base_double, base_double); |
| 1247 __ Fcmp(scratch0_double, 0.0); | 1244 __ Fcmp(scratch0_double, 0.0); |
| (...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 // | 1781 // |
| 1785 // We must not write to jssp until after the PushCalleeSavedRegisters() | 1782 // We must not write to jssp until after the PushCalleeSavedRegisters() |
| 1786 // call, since jssp is itself a callee-saved register. | 1783 // call, since jssp is itself a callee-saved register. |
| 1787 __ SetStackPointer(csp); | 1784 __ SetStackPointer(csp); |
| 1788 __ PushCalleeSavedRegisters(); | 1785 __ PushCalleeSavedRegisters(); |
| 1789 __ Mov(jssp, csp); | 1786 __ Mov(jssp, csp); |
| 1790 __ SetStackPointer(jssp); | 1787 __ SetStackPointer(jssp); |
| 1791 | 1788 |
| 1792 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 1789 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 1793 | 1790 |
| 1791 // Set up the reserved register for 0.0. |
| 1792 __ Fmov(fp_zero, 0.0); |
| 1793 |
| 1794 // Build an entry frame (see layout below). | 1794 // Build an entry frame (see layout below). |
| 1795 Isolate* isolate = masm->isolate(); | 1795 Isolate* isolate = masm->isolate(); |
| 1796 | 1796 |
| 1797 // Build an entry frame. | 1797 // Build an entry frame. |
| 1798 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 1798 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
| 1799 int64_t bad_frame_pointer = -1L; // Bad frame pointer to fail if it is used. | 1799 int64_t bad_frame_pointer = -1L; // Bad frame pointer to fail if it is used. |
| 1800 __ Mov(x13, bad_frame_pointer); | 1800 __ Mov(x13, bad_frame_pointer); |
| 1801 __ Mov(x12, Operand(Smi::FromInt(marker))); | 1801 __ Mov(x12, Operand(Smi::FromInt(marker))); |
| 1802 __ Mov(x11, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate))); | 1802 __ Mov(x11, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate))); |
| 1803 __ Ldr(x10, MemOperand(x11)); | 1803 __ Ldr(x10, MemOperand(x11)); |
| (...skipping 3998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5802 MemOperand(fp, 6 * kPointerSize), | 5802 MemOperand(fp, 6 * kPointerSize), |
| 5803 NULL); | 5803 NULL); |
| 5804 } | 5804 } |
| 5805 | 5805 |
| 5806 | 5806 |
| 5807 #undef __ | 5807 #undef __ |
| 5808 | 5808 |
| 5809 } } // namespace v8::internal | 5809 } } // namespace v8::internal |
| 5810 | 5810 |
| 5811 #endif // V8_TARGET_ARCH_A64 | 5811 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |