| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 | 1366 |
| 1367 void MacroAssembler::AssertFPCRState(Register fpcr) { | 1367 void MacroAssembler::AssertFPCRState(Register fpcr) { |
| 1368 if (emit_debug_code()) { | 1368 if (emit_debug_code()) { |
| 1369 Label unexpected_mode, done; | 1369 Label unexpected_mode, done; |
| 1370 UseScratchRegisterScope temps(this); | 1370 UseScratchRegisterScope temps(this); |
| 1371 if (fpcr.IsNone()) { | 1371 if (fpcr.IsNone()) { |
| 1372 fpcr = temps.AcquireX(); | 1372 fpcr = temps.AcquireX(); |
| 1373 Mrs(fpcr, FPCR); | 1373 Mrs(fpcr, FPCR); |
| 1374 } | 1374 } |
| 1375 | 1375 |
| 1376 // Settings overridden by ConfiugreFPCR(): | |
| 1377 // - Assert that default-NaN mode is set. | |
| 1378 Tbz(fpcr, DN_offset, &unexpected_mode); | |
| 1379 | |
| 1380 // Settings left to their default values: | 1376 // Settings left to their default values: |
| 1381 // - Assert that flush-to-zero is not set. | 1377 // - Assert that flush-to-zero is not set. |
| 1382 Tbnz(fpcr, FZ_offset, &unexpected_mode); | 1378 Tbnz(fpcr, FZ_offset, &unexpected_mode); |
| 1383 // - Assert that the rounding mode is nearest-with-ties-to-even. | 1379 // - Assert that the rounding mode is nearest-with-ties-to-even. |
| 1384 STATIC_ASSERT(FPTieEven == 0); | 1380 STATIC_ASSERT(FPTieEven == 0); |
| 1385 Tst(fpcr, RMode_mask); | 1381 Tst(fpcr, RMode_mask); |
| 1386 B(eq, &done); | 1382 B(eq, &done); |
| 1387 | 1383 |
| 1388 Bind(&unexpected_mode); | 1384 Bind(&unexpected_mode); |
| 1389 Abort(kUnexpectedFPCRMode); | 1385 Abort(kUnexpectedFPCRMode); |
| 1390 | 1386 |
| 1391 Bind(&done); | 1387 Bind(&done); |
| 1392 } | 1388 } |
| 1393 } | 1389 } |
| 1394 | 1390 |
| 1395 | 1391 |
| 1396 void MacroAssembler::ConfigureFPCR() { | |
| 1397 UseScratchRegisterScope temps(this); | |
| 1398 Register fpcr = temps.AcquireX(); | |
| 1399 Mrs(fpcr, FPCR); | |
| 1400 | |
| 1401 // If necessary, enable default-NaN mode. The default values of the other FPCR | |
| 1402 // options should be suitable, and AssertFPCRState will verify that. | |
| 1403 Label no_write_required; | |
| 1404 Tbnz(fpcr, DN_offset, &no_write_required); | |
| 1405 | |
| 1406 Orr(fpcr, fpcr, DN_mask); | |
| 1407 Msr(FPCR, fpcr); | |
| 1408 | |
| 1409 Bind(&no_write_required); | |
| 1410 AssertFPCRState(fpcr); | |
| 1411 } | |
| 1412 | |
| 1413 | |
| 1414 void MacroAssembler::CanonicalizeNaN(const FPRegister& dst, | 1392 void MacroAssembler::CanonicalizeNaN(const FPRegister& dst, |
| 1415 const FPRegister& src) { | 1393 const FPRegister& src) { |
| 1416 AssertFPCRState(); | 1394 AssertFPCRState(); |
| 1417 | 1395 |
| 1418 // With DN=1 and RMode=FPTieEven, subtracting 0.0 preserves all inputs except | 1396 // Subtracting 0.0 preserves all inputs except for signalling NaNs, which |
| 1419 // for NaNs, which become the default NaN. We use fsub rather than fadd | 1397 // become quiet NaNs. We use fsub rather than fadd because fsub preserves -0.0 |
| 1420 // because sub preserves -0.0 inputs: -0.0 + 0.0 = 0.0, but -0.0 - 0.0 = -0.0. | 1398 // inputs: -0.0 + 0.0 = 0.0, but -0.0 - 0.0 = -0.0. |
| 1421 Fsub(dst, src, fp_zero); | 1399 Fsub(dst, src, fp_zero); |
| 1422 } | 1400 } |
| 1423 | 1401 |
| 1424 | 1402 |
| 1425 void MacroAssembler::LoadRoot(CPURegister destination, | 1403 void MacroAssembler::LoadRoot(CPURegister destination, |
| 1426 Heap::RootListIndex index) { | 1404 Heap::RootListIndex index) { |
| 1427 // TODO(jbramley): Most root values are constants, and can be synthesized | 1405 // TODO(jbramley): Most root values are constants, and can be synthesized |
| 1428 // without a load. Refer to the ARM back end for details. | 1406 // without a load. Refer to the ARM back end for details. |
| 1429 Ldr(destination, MemOperand(root, index << kPointerSizeLog2)); | 1407 Ldr(destination, MemOperand(root, index << kPointerSizeLog2)); |
| 1430 } | 1408 } |
| (...skipping 3672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5103 } | 5081 } |
| 5104 | 5082 |
| 5105 | 5083 |
| 5106 #undef __ | 5084 #undef __ |
| 5107 | 5085 |
| 5108 | 5086 |
| 5109 } // namespace internal | 5087 } // namespace internal |
| 5110 } // namespace v8 | 5088 } // namespace v8 |
| 5111 | 5089 |
| 5112 #endif // V8_TARGET_ARCH_ARM64 | 5090 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |