OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compiler/code-generator-impl.h" | 9 #include "src/compiler/code-generator-impl.h" |
10 #include "src/compiler/gap-resolver.h" | 10 #include "src/compiler/gap-resolver.h" |
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1372 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1373 break; | 1373 break; |
1374 case kArmVldrF64: | 1374 case kArmVldrF64: |
1375 __ vldr(i.OutputDoubleRegister(), i.InputOffset()); | 1375 __ vldr(i.OutputDoubleRegister(), i.InputOffset()); |
1376 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1376 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1377 break; | 1377 break; |
1378 case kArmVstrF64: | 1378 case kArmVstrF64: |
1379 __ vstr(i.InputDoubleRegister(0), i.InputOffset(1)); | 1379 __ vstr(i.InputDoubleRegister(0), i.InputOffset(1)); |
1380 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 1380 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
1381 break; | 1381 break; |
| 1382 case kArmFloat32Max: { |
| 1383 FloatRegister left_reg = i.InputFloat32Register(0); |
| 1384 FloatRegister right_reg = i.InputFloat32Register(1); |
| 1385 FloatRegister result_reg = i.OutputFloat32Register(); |
| 1386 Label result_is_nan, return_left, return_right, check_zero, done; |
| 1387 __ VFPCompareAndSetFlags(left_reg, right_reg); |
| 1388 __ b(mi, &return_right); |
| 1389 __ b(gt, &return_left); |
| 1390 __ b(vs, &result_is_nan); |
| 1391 // Left equals right => check for -0. |
| 1392 __ VFPCompareAndSetFlags(left_reg, 0.0); |
| 1393 if (left_reg.is(result_reg) || right_reg.is(result_reg)) { |
| 1394 __ b(ne, &done); // left == right != 0. |
| 1395 } else { |
| 1396 __ b(ne, &return_left); // left == right != 0. |
| 1397 } |
| 1398 // At this point, both left and right are either 0 or -0. |
| 1399 // Since we operate on +0 and/or -0, vadd and vand have the same effect; |
| 1400 // the decision for vadd is easy because vand is a NEON instruction. |
| 1401 __ vadd(result_reg, left_reg, right_reg); |
| 1402 __ b(&done); |
| 1403 __ bind(&result_is_nan); |
| 1404 __ vadd(result_reg, left_reg, right_reg); |
| 1405 __ b(&done); |
| 1406 __ bind(&return_right); |
| 1407 __ Move(result_reg, right_reg); |
| 1408 if (!left_reg.is(result_reg)) __ b(&done); |
| 1409 __ bind(&return_left); |
| 1410 __ Move(result_reg, left_reg); |
| 1411 __ bind(&done); |
| 1412 break; |
| 1413 } |
1382 case kArmFloat64Max: { | 1414 case kArmFloat64Max: { |
1383 DwVfpRegister left_reg = i.InputDoubleRegister(0); | 1415 DwVfpRegister left_reg = i.InputDoubleRegister(0); |
1384 DwVfpRegister right_reg = i.InputDoubleRegister(1); | 1416 DwVfpRegister right_reg = i.InputDoubleRegister(1); |
1385 DwVfpRegister result_reg = i.OutputDoubleRegister(); | 1417 DwVfpRegister result_reg = i.OutputDoubleRegister(); |
1386 Label result_is_nan, return_left, return_right, check_zero, done; | 1418 Label result_is_nan, return_left, return_right, check_zero, done; |
1387 __ VFPCompareAndSetFlags(left_reg, right_reg); | 1419 __ VFPCompareAndSetFlags(left_reg, right_reg); |
1388 __ b(mi, &return_right); | 1420 __ b(mi, &return_right); |
1389 __ b(gt, &return_left); | 1421 __ b(gt, &return_left); |
1390 __ b(vs, &result_is_nan); | 1422 __ b(vs, &result_is_nan); |
1391 // Left equals right => check for -0. | 1423 // Left equals right => check for -0. |
(...skipping 12 matching lines...) Expand all Loading... |
1404 __ vadd(result_reg, left_reg, right_reg); | 1436 __ vadd(result_reg, left_reg, right_reg); |
1405 __ b(&done); | 1437 __ b(&done); |
1406 __ bind(&return_right); | 1438 __ bind(&return_right); |
1407 __ Move(result_reg, right_reg); | 1439 __ Move(result_reg, right_reg); |
1408 if (!left_reg.is(result_reg)) __ b(&done); | 1440 if (!left_reg.is(result_reg)) __ b(&done); |
1409 __ bind(&return_left); | 1441 __ bind(&return_left); |
1410 __ Move(result_reg, left_reg); | 1442 __ Move(result_reg, left_reg); |
1411 __ bind(&done); | 1443 __ bind(&done); |
1412 break; | 1444 break; |
1413 } | 1445 } |
| 1446 case kArmFloat32Min: { |
| 1447 FloatRegister left_reg = i.InputFloat32Register(0); |
| 1448 FloatRegister right_reg = i.InputFloat32Register(1); |
| 1449 FloatRegister result_reg = i.OutputFloat32Register(); |
| 1450 Label result_is_nan, return_left, return_right, check_zero, done; |
| 1451 __ VFPCompareAndSetFlags(left_reg, right_reg); |
| 1452 __ b(mi, &return_left); |
| 1453 __ b(gt, &return_right); |
| 1454 __ b(vs, &result_is_nan); |
| 1455 // Left equals right => check for -0. |
| 1456 __ VFPCompareAndSetFlags(left_reg, 0.0); |
| 1457 if (left_reg.is(result_reg) || right_reg.is(result_reg)) { |
| 1458 __ b(ne, &done); // left == right != 0. |
| 1459 } else { |
| 1460 __ b(ne, &return_left); // left == right != 0. |
| 1461 } |
| 1462 // At this point, both left and right are either 0 or -0. |
| 1463 // We could use a single 'vorr' instruction here if we had NEON support. |
| 1464 // The algorithm is: -((-L) + (-R)), which in case of L and R being |
| 1465 // different registers is most efficiently expressed as -((-L) - R). |
| 1466 __ vneg(left_reg, left_reg); |
| 1467 if (left_reg.is(right_reg)) { |
| 1468 __ vadd(result_reg, left_reg, right_reg); |
| 1469 } else { |
| 1470 __ vsub(result_reg, left_reg, right_reg); |
| 1471 } |
| 1472 __ vneg(result_reg, result_reg); |
| 1473 __ b(&done); |
| 1474 __ bind(&result_is_nan); |
| 1475 __ vadd(result_reg, left_reg, right_reg); |
| 1476 __ b(&done); |
| 1477 __ bind(&return_right); |
| 1478 __ Move(result_reg, right_reg); |
| 1479 if (!left_reg.is(result_reg)) __ b(&done); |
| 1480 __ bind(&return_left); |
| 1481 __ Move(result_reg, left_reg); |
| 1482 __ bind(&done); |
| 1483 break; |
| 1484 } |
1414 case kArmFloat64Min: { | 1485 case kArmFloat64Min: { |
1415 DwVfpRegister left_reg = i.InputDoubleRegister(0); | 1486 DwVfpRegister left_reg = i.InputDoubleRegister(0); |
1416 DwVfpRegister right_reg = i.InputDoubleRegister(1); | 1487 DwVfpRegister right_reg = i.InputDoubleRegister(1); |
1417 DwVfpRegister result_reg = i.OutputDoubleRegister(); | 1488 DwVfpRegister result_reg = i.OutputDoubleRegister(); |
1418 Label result_is_nan, return_left, return_right, check_zero, done; | 1489 Label result_is_nan, return_left, return_right, check_zero, done; |
1419 __ VFPCompareAndSetFlags(left_reg, right_reg); | 1490 __ VFPCompareAndSetFlags(left_reg, right_reg); |
1420 __ b(mi, &return_left); | 1491 __ b(mi, &return_left); |
1421 __ b(gt, &return_right); | 1492 __ b(gt, &return_right); |
1422 __ b(vs, &result_is_nan); | 1493 __ b(vs, &result_is_nan); |
1423 // Left equals right => check for -0. | 1494 // Left equals right => check for -0. |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1958 padding_size -= v8::internal::Assembler::kInstrSize; | 2029 padding_size -= v8::internal::Assembler::kInstrSize; |
1959 } | 2030 } |
1960 } | 2031 } |
1961 } | 2032 } |
1962 | 2033 |
1963 #undef __ | 2034 #undef __ |
1964 | 2035 |
1965 } // namespace compiler | 2036 } // namespace compiler |
1966 } // namespace internal | 2037 } // namespace internal |
1967 } // namespace v8 | 2038 } // namespace v8 |
OLD | NEW |