OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1317 | 1317 |
1318 assembler->Bind(÷nd_is_number); | 1318 assembler->Bind(÷nd_is_number); |
1319 { | 1319 { |
1320 // Check if {divisor} is a Smi. | 1320 // Check if {divisor} is a Smi. |
1321 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); | 1321 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
1322 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, | 1322 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, |
1323 &divisor_is_not_smi); | 1323 &divisor_is_not_smi); |
1324 | 1324 |
1325 assembler->Bind(&divisor_is_smi); | 1325 assembler->Bind(&divisor_is_smi); |
1326 { | 1326 { |
1327 // Convert {divisor} to a double and divide it with the value of | 1327 // Convert {divisor} to a double and use it for a floating point |
1328 // {dividend}. | 1328 // division. |
1329 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1329 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
1330 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); | 1330 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
1331 assembler->Goto(&do_fdiv); | 1331 assembler->Goto(&do_fdiv); |
1332 } | 1332 } |
1333 | 1333 |
1334 assembler->Bind(&divisor_is_not_smi); | 1334 assembler->Bind(&divisor_is_not_smi); |
1335 { | 1335 { |
1336 Node* divisor_map = assembler->LoadMap(divisor); | 1336 Node* divisor_map = assembler->LoadMap(divisor); |
1337 | 1337 |
1338 // Check if {divisor} is a HeapNumber. | 1338 // Check if {divisor} is a HeapNumber. |
1339 Label divisor_is_number(assembler), | 1339 Label divisor_is_number(assembler), |
1340 divisor_is_not_number(assembler, Label::kDeferred); | 1340 divisor_is_not_number(assembler, Label::kDeferred); |
1341 assembler->Branch(assembler->WordEqual(divisor_map, number_map), | 1341 assembler->Branch(assembler->WordEqual(divisor_map, number_map), |
1342 &divisor_is_number, &divisor_is_not_number); | 1342 &divisor_is_number, &divisor_is_not_number); |
1343 | 1343 |
1344 assembler->Bind(&divisor_is_number); | 1344 assembler->Bind(&divisor_is_number); |
1345 { | 1345 { |
1346 // Both {dividend} and {divisor} are HeapNumbers. Load their values | 1346 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
1347 // and | 1347 // and divide them. |
1348 // divide them. | |
1349 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); | 1348 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
1350 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); | 1349 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
1351 assembler->Goto(&do_fdiv); | 1350 assembler->Goto(&do_fdiv); |
1352 } | 1351 } |
1353 | 1352 |
1354 assembler->Bind(&divisor_is_not_number); | 1353 assembler->Bind(&divisor_is_not_number); |
1355 { | 1354 { |
1356 // Convert {divisor} to a number and loop. | 1355 // Convert {divisor} to a number and loop. |
1357 Callable callable = CodeFactory::NonNumberToNumber(isolate()); | 1356 Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
1358 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); | 1357 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); |
(...skipping 28 matching lines...) Expand all Loading... |
1387 Node* lhs = assembler->Parameter(0); | 1386 Node* lhs = assembler->Parameter(0); |
1388 Node* rhs = assembler->Parameter(1); | 1387 Node* rhs = assembler->Parameter(1); |
1389 Node* context = assembler->Parameter(2); | 1388 Node* context = assembler->Parameter(2); |
1390 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); | 1389 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); |
1391 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); | 1390 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); |
1392 Node* value = assembler->Word32And(lhs_value, rhs_value); | 1391 Node* value = assembler->Word32And(lhs_value, rhs_value); |
1393 Node* result = assembler->ChangeInt32ToTagged(value); | 1392 Node* result = assembler->ChangeInt32ToTagged(value); |
1394 assembler->Return(result); | 1393 assembler->Return(result); |
1395 } | 1394 } |
1396 | 1395 |
| 1396 void ModulusStub::GenerateAssembly( |
| 1397 compiler::CodeStubAssembler* assembler) const { |
| 1398 using compiler::Node; |
| 1399 typedef compiler::CodeStubAssembler::Label Label; |
| 1400 typedef compiler::CodeStubAssembler::Variable Variable; |
| 1401 |
| 1402 Node* context = assembler->Parameter(2); |
| 1403 |
| 1404 // Shared entry point for floating point modulus. |
| 1405 Label do_fmod(assembler); |
| 1406 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64), |
| 1407 var_divisor_float64(assembler, MachineRepresentation::kFloat64); |
| 1408 |
| 1409 Node* number_map = assembler->HeapNumberMapConstant(); |
| 1410 |
| 1411 // We might need to loop one or two times due to ToNumber conversions. |
| 1412 Variable var_dividend(assembler, MachineRepresentation::kTagged), |
| 1413 var_divisor(assembler, MachineRepresentation::kTagged); |
| 1414 Variable* loop_variables[] = {&var_dividend, &var_divisor}; |
| 1415 Label loop(assembler, 2, loop_variables); |
| 1416 var_dividend.Bind(assembler->Parameter(0)); |
| 1417 var_divisor.Bind(assembler->Parameter(1)); |
| 1418 assembler->Goto(&loop); |
| 1419 assembler->Bind(&loop); |
| 1420 { |
| 1421 Node* dividend = var_dividend.value(); |
| 1422 Node* divisor = var_divisor.value(); |
| 1423 |
| 1424 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler); |
| 1425 assembler->Branch(assembler->WordIsSmi(dividend), ÷nd_is_smi, |
| 1426 ÷nd_is_not_smi); |
| 1427 |
| 1428 assembler->Bind(÷nd_is_smi); |
| 1429 { |
| 1430 Label dividend_is_not_zero(assembler); |
| 1431 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
| 1432 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, |
| 1433 &divisor_is_not_smi); |
| 1434 |
| 1435 assembler->Bind(&divisor_is_smi); |
| 1436 { |
| 1437 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); |
| 1438 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
| 1439 assembler->Goto(&do_fmod); |
| 1440 } |
| 1441 |
| 1442 assembler->Bind(&divisor_is_not_smi); |
| 1443 { |
| 1444 Node* divisor_map = assembler->LoadMap(divisor); |
| 1445 |
| 1446 // Check if {divisor} is a HeapNumber. |
| 1447 Label divisor_is_number(assembler), |
| 1448 divisor_is_not_number(assembler, Label::kDeferred); |
| 1449 assembler->Branch(assembler->WordEqual(divisor_map, number_map), |
| 1450 &divisor_is_number, &divisor_is_not_number); |
| 1451 |
| 1452 assembler->Bind(&divisor_is_number); |
| 1453 { |
| 1454 // Convert {dividend} to a double and compute its modulus with the |
| 1455 // value of {dividend}. |
| 1456 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend)); |
| 1457 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
| 1458 assembler->Goto(&do_fmod); |
| 1459 } |
| 1460 |
| 1461 assembler->Bind(&divisor_is_not_number); |
| 1462 { |
| 1463 // Convert {divisor} to a number and loop. |
| 1464 Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
| 1465 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); |
| 1466 assembler->Goto(&loop); |
| 1467 } |
| 1468 } |
| 1469 } |
| 1470 |
| 1471 assembler->Bind(÷nd_is_not_smi); |
| 1472 { |
| 1473 Node* dividend_map = assembler->LoadMap(dividend); |
| 1474 |
| 1475 // Check if {dividend} is a HeapNumber. |
| 1476 Label dividend_is_number(assembler), |
| 1477 dividend_is_not_number(assembler, Label::kDeferred); |
| 1478 assembler->Branch(assembler->WordEqual(dividend_map, number_map), |
| 1479 ÷nd_is_number, ÷nd_is_not_number); |
| 1480 |
| 1481 assembler->Bind(÷nd_is_number); |
| 1482 { |
| 1483 // Check if {divisor} is a Smi. |
| 1484 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler); |
| 1485 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi, |
| 1486 &divisor_is_not_smi); |
| 1487 |
| 1488 assembler->Bind(&divisor_is_smi); |
| 1489 { |
| 1490 // Convert {divisor} to a double and compute {dividend}'s modulus with |
| 1491 // it. |
| 1492 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
| 1493 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor)); |
| 1494 assembler->Goto(&do_fmod); |
| 1495 } |
| 1496 |
| 1497 assembler->Bind(&divisor_is_not_smi); |
| 1498 { |
| 1499 Node* divisor_map = assembler->LoadMap(divisor); |
| 1500 |
| 1501 // Check if {divisor} is a HeapNumber. |
| 1502 Label divisor_is_number(assembler), |
| 1503 divisor_is_not_number(assembler, Label::kDeferred); |
| 1504 assembler->Branch(assembler->WordEqual(divisor_map, number_map), |
| 1505 &divisor_is_number, &divisor_is_not_number); |
| 1506 |
| 1507 assembler->Bind(&divisor_is_number); |
| 1508 { |
| 1509 // Both {dividend} and {divisor} are HeapNumbers. Load their values |
| 1510 // and compute their modulus. |
| 1511 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend)); |
| 1512 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor)); |
| 1513 assembler->Goto(&do_fmod); |
| 1514 } |
| 1515 |
| 1516 assembler->Bind(&divisor_is_not_number); |
| 1517 { |
| 1518 // Convert {divisor} to a number and loop. |
| 1519 Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
| 1520 var_divisor.Bind(assembler->CallStub(callable, context, divisor)); |
| 1521 assembler->Goto(&loop); |
| 1522 } |
| 1523 } |
| 1524 } |
| 1525 |
| 1526 assembler->Bind(÷nd_is_not_number); |
| 1527 { |
| 1528 // Convert {dividend} to a Number and loop. |
| 1529 Callable callable = CodeFactory::NonNumberToNumber(isolate()); |
| 1530 var_dividend.Bind(assembler->CallStub(callable, context, dividend)); |
| 1531 assembler->Goto(&loop); |
| 1532 } |
| 1533 } |
| 1534 } |
| 1535 |
| 1536 assembler->Bind(&do_fmod); |
| 1537 { |
| 1538 Node* value = assembler->Float64Mod(var_dividend_float64.value(), |
| 1539 var_divisor_float64.value()); |
| 1540 Node* result = assembler->ChangeFloat64ToTagged(value); |
| 1541 assembler->Return(result); |
| 1542 } |
| 1543 } |
| 1544 |
1397 void BitwiseOrStub::GenerateAssembly( | 1545 void BitwiseOrStub::GenerateAssembly( |
1398 compiler::CodeStubAssembler* assembler) const { | 1546 compiler::CodeStubAssembler* assembler) const { |
1399 using compiler::Node; | 1547 using compiler::Node; |
1400 | 1548 |
1401 Node* lhs = assembler->Parameter(0); | 1549 Node* lhs = assembler->Parameter(0); |
1402 Node* rhs = assembler->Parameter(1); | 1550 Node* rhs = assembler->Parameter(1); |
1403 Node* context = assembler->Parameter(2); | 1551 Node* context = assembler->Parameter(2); |
1404 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); | 1552 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); |
1405 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); | 1553 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); |
1406 Node* value = assembler->Word32Or(lhs_value, rhs_value); | 1554 Node* value = assembler->Word32Or(lhs_value, rhs_value); |
(...skipping 2456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3863 if (type->Is(Type::UntaggedPointer())) { | 4011 if (type->Is(Type::UntaggedPointer())) { |
3864 return Representation::External(); | 4012 return Representation::External(); |
3865 } | 4013 } |
3866 | 4014 |
3867 DCHECK(!type->Is(Type::Untagged())); | 4015 DCHECK(!type->Is(Type::Untagged())); |
3868 return Representation::Tagged(); | 4016 return Representation::Tagged(); |
3869 } | 4017 } |
3870 | 4018 |
3871 } // namespace internal | 4019 } // namespace internal |
3872 } // namespace v8 | 4020 } // namespace v8 |
OLD | NEW |