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 |