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 |