Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(435)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 21014003: Optionally use 31-bits SMI value for 64-bit system (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Introduce SmiFunctionInvoker to abstract the difference between FullCodeGen and LCodeGen Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 codegen_->RecordSafepoint(pointers_, deopt_mode_); 57 codegen_->RecordSafepoint(pointers_, deopt_mode_);
58 } 58 }
59 59
60 private: 60 private:
61 LCodeGen* codegen_; 61 LCodeGen* codegen_;
62 LPointerMap* pointers_; 62 LPointerMap* pointers_;
63 Safepoint::DeoptMode deopt_mode_; 63 Safepoint::DeoptMode deopt_mode_;
64 }; 64 };
65 65
66 66
67 class LSmiFunctionInvoker : public MacroAssembler::SmiFunctionInvoker {
68 public:
69 LSmiFunctionInvoker(LCodeGen* codegen,
70 LEnvironment* environment,
71 bool check_minus_zero)
72 : MacroAssembler::SmiFunctionInvoker(NULL),
73 codegen_(codegen),
74 environment_(environment),
75 check_minus_zero_(check_minus_zero) { }
76 virtual ~LSmiFunctionInvoker() { }
77 virtual void Bailout() {
78 codegen_->DeoptimizeIf(no_condition, environment_);
79 }
80 virtual Label* on_not_smi_result() { return NULL; }
81 virtual bool reserve_source_operands() { return false; }
82 virtual bool check_minus_zero() { return check_minus_zero_; }
83
84 private:
85 LCodeGen* codegen_;
86 LEnvironment* environment_;
87 bool check_minus_zero_;
88 };
89
90
67 #define __ masm()-> 91 #define __ masm()->
68 92
69 bool LCodeGen::GenerateCode() { 93 bool LCodeGen::GenerateCode() {
70 LPhase phase("Z_Code generation", chunk()); 94 LPhase phase("Z_Code generation", chunk());
71 ASSERT(is_unused()); 95 ASSERT(is_unused());
72 status_ = GENERATING; 96 status_ = GENERATING;
73 97
74 // Open a frame scope to indicate that there is a frame on the stack. The 98 // Open a frame scope to indicate that there is a frame on the stack. The
75 // MANUAL indicates that the scope shouldn't actually generate code to set up 99 // MANUAL indicates that the scope shouldn't actually generate code to set up
76 // the frame (that is done in GeneratePrologue). 100 // the frame (that is done in GeneratePrologue).
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 } 433 }
410 434
411 435
412 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { 436 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const {
413 return op->IsConstantOperand() && 437 return op->IsConstantOperand() &&
414 chunk_->LookupLiteralRepresentation(op).IsTagged(); 438 chunk_->LookupLiteralRepresentation(op).IsTagged();
415 } 439 }
416 440
417 441
418 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { 442 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
419 HConstant* constant = chunk_->LookupConstant(op); 443 return ToRepresentation(op, Representation::Integer32());
420 return constant->Integer32Value();
421 } 444 }
422 445
423 446
447 int32_t LCodeGen::ToRepresentation(LConstantOperand* op,
448 const Representation& r) const {
449 HConstant* constant = chunk_->LookupConstant(op);
450 int32_t value = constant->Integer32Value();
451 if (r.IsInteger32()) return value;
452 ASSERT(r.IsSmiOrTagged());
453 return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value)));
454 }
455
456
424 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { 457 Smi* LCodeGen::ToSmi(LConstantOperand* op) const {
425 HConstant* constant = chunk_->LookupConstant(op); 458 HConstant* constant = chunk_->LookupConstant(op);
426 return Smi::FromInt(constant->Integer32Value()); 459 return Smi::FromInt(constant->Integer32Value());
427 } 460 }
428 461
429 462
430 double LCodeGen::ToDouble(LConstantOperand* op) const { 463 double LCodeGen::ToDouble(LConstantOperand* op) const {
431 HConstant* constant = chunk_->LookupConstant(op); 464 HConstant* constant = chunk_->LookupConstant(op);
432 ASSERT(constant->HasDoubleValue()); 465 ASSERT(constant->HasDoubleValue());
433 return constant->DoubleValue(); 466 return constant->DoubleValue();
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 } 1388 }
1356 1389
1357 1390
1358 void LCodeGen::DoBitI(LBitI* instr) { 1391 void LCodeGen::DoBitI(LBitI* instr) {
1359 LOperand* left = instr->left(); 1392 LOperand* left = instr->left();
1360 LOperand* right = instr->right(); 1393 LOperand* right = instr->right();
1361 ASSERT(left->Equals(instr->result())); 1394 ASSERT(left->Equals(instr->result()));
1362 ASSERT(left->IsRegister()); 1395 ASSERT(left->IsRegister());
1363 1396
1364 if (right->IsConstantOperand()) { 1397 if (right->IsConstantOperand()) {
1365 int right_operand = ToInteger32(LConstantOperand::cast(right)); 1398 int right_operand = ToRepresentation(LConstantOperand::cast(right),
1399 instr->hydrogen()->representation());
1366 switch (instr->op()) { 1400 switch (instr->op()) {
1367 case Token::BIT_AND: 1401 case Token::BIT_AND:
1368 __ andl(ToRegister(left), Immediate(right_operand)); 1402 if (instr->hydrogen()->representation().IsSmi()) {
danno 2013/08/07 18:41:26 Is this really correct (here and below)? The non-s
haitao.feng 2013/08/12 09:54:24 It is really correct. This code utilizes a hardwar
1403 __ and_(ToRegister(left), Immediate(right_operand));
1404 } else {
1405 __ andl(ToRegister(left), Immediate(right_operand));
1406 }
1369 break; 1407 break;
1370 case Token::BIT_OR: 1408 case Token::BIT_OR:
1371 __ orl(ToRegister(left), Immediate(right_operand)); 1409 if (instr->hydrogen()->representation().IsSmi()) {
1410 __ or_(ToRegister(left), Immediate(right_operand));
danno 2013/08/07 18:41:26 Same here.
haitao.feng 2013/08/12 09:54:24 Explained above.
1411 } else {
1412 __ orl(ToRegister(left), Immediate(right_operand));
1413 }
1372 break; 1414 break;
1373 case Token::BIT_XOR: 1415 case Token::BIT_XOR:
1374 __ xorl(ToRegister(left), Immediate(right_operand)); 1416 if (instr->hydrogen()->representation().IsSmi()) {
danno 2013/08/07 18:41:26 Same here.
haitao.feng 2013/08/12 09:54:24 Explained above.
1417 __ xor_(ToRegister(left), Immediate(right_operand));
1418 } else {
1419 __ xorl(ToRegister(left), Immediate(right_operand));
1420 }
1375 break; 1421 break;
1376 default: 1422 default:
1377 UNREACHABLE(); 1423 UNREACHABLE();
1378 break; 1424 break;
1379 } 1425 }
1380 } else if (right->IsStackSlot()) { 1426 } else if (right->IsStackSlot()) {
1381 switch (instr->op()) { 1427 switch (instr->op()) {
1382 case Token::BIT_AND: 1428 case Token::BIT_AND:
1383 __ and_(ToRegister(left), ToOperand(right)); 1429 __ and_(ToRegister(left), ToOperand(right));
1384 break; 1430 break;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 if (shift_count == 0 && instr->can_deopt()) { 1505 if (shift_count == 0 && instr->can_deopt()) {
1460 __ testl(ToRegister(left), ToRegister(left)); 1506 __ testl(ToRegister(left), ToRegister(left));
1461 DeoptimizeIf(negative, instr->environment()); 1507 DeoptimizeIf(negative, instr->environment());
1462 } else { 1508 } else {
1463 __ shrl(ToRegister(left), Immediate(shift_count)); 1509 __ shrl(ToRegister(left), Immediate(shift_count));
1464 } 1510 }
1465 break; 1511 break;
1466 case Token::SHL: 1512 case Token::SHL:
1467 if (shift_count != 0) { 1513 if (shift_count != 0) {
1468 if (instr->hydrogen_value()->representation().IsSmi()) { 1514 if (instr->hydrogen_value()->representation().IsSmi()) {
1469 __ shl(ToRegister(left), Immediate(shift_count)); 1515 if (kSmiValueSize == 32 || !instr->can_deopt()) {
1516 __ shl(ToRegister(left), Immediate(shift_count));
1517 } else {
1518 ASSERT(kSmiValueSize == 31 && instr->can_deopt());
1519 LSmiFunctionInvoker invoker(this, instr->environment(), false);
1520 __ SmiShiftLeftConstant(ToRegister(left), ToRegister(left),
1521 shift_count, invoker);
1522 }
1470 } else { 1523 } else {
1471 __ shll(ToRegister(left), Immediate(shift_count)); 1524 __ shll(ToRegister(left), Immediate(shift_count));
1472 } 1525 }
1473 } 1526 }
1474 break; 1527 break;
1475 default: 1528 default:
1476 UNREACHABLE(); 1529 UNREACHABLE();
1477 break; 1530 break;
1478 } 1531 }
1479 } 1532 }
1480 } 1533 }
1481 1534
1482 1535
1483 void LCodeGen::DoSubI(LSubI* instr) { 1536 void LCodeGen::DoSubI(LSubI* instr) {
1484 LOperand* left = instr->left(); 1537 LOperand* left = instr->left();
1485 LOperand* right = instr->right(); 1538 LOperand* right = instr->right();
1486 ASSERT(left->Equals(instr->result())); 1539 ASSERT(left->Equals(instr->result()));
1487 1540
1488 if (right->IsConstantOperand()) { 1541 if (right->IsConstantOperand()) {
1489 __ subl(ToRegister(left), 1542 __ subl(ToRegister(left),
1490 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1543 Immediate(ToRepresentation(LConstantOperand::cast(right),
1544 instr->hydrogen()->representation())));
1491 } else if (right->IsRegister()) { 1545 } else if (right->IsRegister()) {
1492 if (instr->hydrogen_value()->representation().IsSmi()) { 1546 if (instr->hydrogen_value()->representation().IsSmi()) {
1493 __ subq(ToRegister(left), ToRegister(right)); 1547 if (kSmiValueSize == 32) {
1548 __ subq(ToRegister(left), ToRegister(right));
1549 } else {
1550 ASSERT(kSmiValueSize == 31);
1551 __ subl(ToRegister(left), ToRegister(right));
1552 }
1494 } else { 1553 } else {
1495 __ subl(ToRegister(left), ToRegister(right)); 1554 __ subl(ToRegister(left), ToRegister(right));
1496 } 1555 }
1497 } else { 1556 } else {
1498 if (instr->hydrogen_value()->representation().IsSmi()) { 1557 if (instr->hydrogen_value()->representation().IsSmi()) {
1499 __ subq(ToRegister(left), ToOperand(right)); 1558 if (kSmiValueSize == 32) {
1559 __ subq(ToRegister(left), ToOperand(right));
1560 } else {
1561 ASSERT(kSmiValueSize == 31);
1562 __ subl(ToRegister(left), ToOperand(right));
1563 }
1500 } else { 1564 } else {
1501 __ subl(ToRegister(left), ToOperand(right)); 1565 __ subl(ToRegister(left), ToOperand(right));
1502 } 1566 }
1503 } 1567 }
1504 1568
1505 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1569 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1506 DeoptimizeIf(overflow, instr->environment()); 1570 DeoptimizeIf(overflow, instr->environment());
1507 } 1571 }
1572
1573 if (kSmiValueSize == 31 &&
1574 instr->hydrogen_value()->representation().IsSmi()) {
1575 __ movsxlq(ToRegister(left), ToRegister(left));
1576 }
1508 } 1577 }
1509 1578
1510 1579
1511 void LCodeGen::DoConstantI(LConstantI* instr) { 1580 void LCodeGen::DoConstantI(LConstantI* instr) {
1512 __ Set(ToRegister(instr->result()), instr->value()); 1581 __ Set(ToRegister(instr->result()), instr->value());
1513 } 1582 }
1514 1583
1515 1584
1516 void LCodeGen::DoConstantS(LConstantS* instr) { 1585 void LCodeGen::DoConstantS(LConstantS* instr) {
1517 __ Move(ToRegister(instr->result()), instr->value()); 1586 __ Move(ToRegister(instr->result()), instr->value());
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 } 1742 }
1674 } 1743 }
1675 1744
1676 1745
1677 void LCodeGen::DoAddI(LAddI* instr) { 1746 void LCodeGen::DoAddI(LAddI* instr) {
1678 LOperand* left = instr->left(); 1747 LOperand* left = instr->left();
1679 LOperand* right = instr->right(); 1748 LOperand* right = instr->right();
1680 1749
1681 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 1750 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1682 if (right->IsConstantOperand()) { 1751 if (right->IsConstantOperand()) {
1683 int32_t offset = ToInteger32(LConstantOperand::cast(right)); 1752 int32_t offset = ToRepresentation(LConstantOperand::cast(right),
1684 __ leal(ToRegister(instr->result()), 1753 instr->hydrogen()->representation());
1685 MemOperand(ToRegister(left), offset)); 1754 if (instr->hydrogen()->representation().IsSmi()) {
1755 __ lea(ToRegister(instr->result()),
danno 2013/08/07 18:41:26 Here and below, I think all Smi operations should
haitao.feng 2013/08/12 09:54:24 Done.
1756 MemOperand(ToRegister(left), offset));
1757 } else {
1758 __ leal(ToRegister(instr->result()),
1759 MemOperand(ToRegister(left), offset));
1760 }
1686 } else { 1761 } else {
1687 Operand address(ToRegister(left), ToRegister(right), times_1, 0); 1762 Operand address(ToRegister(left), ToRegister(right), times_1, 0);
1688 if (instr->hydrogen()->representation().IsSmi()) { 1763 if (instr->hydrogen()->representation().IsSmi()) {
1689 __ lea(ToRegister(instr->result()), address); 1764 __ lea(ToRegister(instr->result()), address);
1690 } else { 1765 } else {
1691 __ leal(ToRegister(instr->result()), address); 1766 __ leal(ToRegister(instr->result()), address);
1692 } 1767 }
1693 } 1768 }
1694 } else { 1769 } else {
1695 if (right->IsConstantOperand()) { 1770 if (right->IsConstantOperand()) {
1696 __ addl(ToRegister(left), 1771 __ addl(ToRegister(left),
1697 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1772 Immediate(ToRepresentation(LConstantOperand::cast(right),
1773 instr->hydrogen()->representation())));
1698 } else if (right->IsRegister()) { 1774 } else if (right->IsRegister()) {
1699 if (instr->hydrogen_value()->representation().IsSmi()) { 1775 if (instr->hydrogen_value()->representation().IsSmi()) {
1700 __ addq(ToRegister(left), ToRegister(right)); 1776 if (kSmiValueSize == 32) {
1777 __ addq(ToRegister(left), ToRegister(right));
1778 } else {
1779 ASSERT(kSmiValueSize == 31);
1780 __ addl(ToRegister(left), ToRegister(right));
1781 }
1701 } else { 1782 } else {
1702 __ addl(ToRegister(left), ToRegister(right)); 1783 __ addl(ToRegister(left), ToRegister(right));
1703 } 1784 }
1704 } else { 1785 } else {
1705 if (instr->hydrogen_value()->representation().IsSmi()) { 1786 if (instr->hydrogen_value()->representation().IsSmi()) {
1706 __ addq(ToRegister(left), ToOperand(right)); 1787 if (kSmiValueSize == 32) {
1788 __ addq(ToRegister(left), ToOperand(right));
1789 } else {
1790 ASSERT(kSmiValueSize == 31);
1791 __ addl(ToRegister(left), ToOperand(right));
1792 }
1707 } else { 1793 } else {
1708 __ addl(ToRegister(left), ToOperand(right)); 1794 __ addl(ToRegister(left), ToOperand(right));
1709 } 1795 }
1710 } 1796 }
1711 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1797 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1712 DeoptimizeIf(overflow, instr->environment()); 1798 DeoptimizeIf(overflow, instr->environment());
1713 } 1799 }
1800
1801 if (kSmiValueSize == 31 &&
1802 instr->hydrogen_value()->representation().IsSmi()) {
1803 __ movsxlq(ToRegister(left), ToRegister(left));
1804 }
1714 } 1805 }
1715 } 1806 }
1716 1807
1717 1808
1718 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1809 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1719 LOperand* left = instr->left(); 1810 LOperand* left = instr->left();
1720 LOperand* right = instr->right(); 1811 LOperand* right = instr->right();
1721 ASSERT(left->Equals(instr->result())); 1812 ASSERT(left->Equals(instr->result()));
1722 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1813 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1723 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { 1814 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1724 Label return_left; 1815 Label return_left;
1725 Condition condition = (operation == HMathMinMax::kMathMin) 1816 Condition condition = (operation == HMathMinMax::kMathMin)
1726 ? less_equal 1817 ? less_equal
1727 : greater_equal; 1818 : greater_equal;
1728 Register left_reg = ToRegister(left); 1819 Register left_reg = ToRegister(left);
1729 if (right->IsConstantOperand()) { 1820 if (right->IsConstantOperand()) {
1730 Immediate right_imm = 1821 Immediate right_imm =
1731 Immediate(ToInteger32(LConstantOperand::cast(right))); 1822 Immediate(ToRepresentation(LConstantOperand::cast(right),
1732 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); 1823 instr->hydrogen()->representation()));
1733 __ cmpl(left_reg, right_imm); 1824 __ cmpl(left_reg, right_imm);
1734 __ j(condition, &return_left, Label::kNear); 1825 __ j(condition, &return_left, Label::kNear);
1735 __ movq(left_reg, right_imm); 1826 __ movq(left_reg, right_imm);
1736 } else if (right->IsRegister()) { 1827 } else if (right->IsRegister()) {
1737 Register right_reg = ToRegister(right); 1828 Register right_reg = ToRegister(right);
1738 if (instr->hydrogen_value()->representation().IsSmi()) { 1829 if (instr->hydrogen_value()->representation().IsSmi()) {
1739 __ cmpq(left_reg, right_reg); 1830 __ cmpq(left_reg, right_reg);
1740 } else { 1831 } else {
1741 __ cmpl(left_reg, right_reg); 1832 __ cmpl(left_reg, right_reg);
1742 } 1833 }
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2920 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3011 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2921 ElementsKind elements_kind = instr->elements_kind(); 3012 ElementsKind elements_kind = instr->elements_kind();
2922 LOperand* key = instr->key(); 3013 LOperand* key = instr->key();
2923 if (!key->IsConstantOperand()) { 3014 if (!key->IsConstantOperand()) {
2924 Register key_reg = ToRegister(key); 3015 Register key_reg = ToRegister(key);
2925 // Even though the HLoad/StoreKeyed (in this case) instructions force 3016 // Even though the HLoad/StoreKeyed (in this case) instructions force
2926 // the input representation for the key to be an integer, the input 3017 // the input representation for the key to be an integer, the input
2927 // gets replaced during bound check elimination with the index argument 3018 // gets replaced during bound check elimination with the index argument
2928 // to the bounds check, which can be tagged, so that case must be 3019 // to the bounds check, which can be tagged, so that case must be
2929 // handled here, too. 3020 // handled here, too.
2930 if (instr->hydrogen()->IsDehoisted()) { 3021 if (kSmiValueSize == 31 &&
3022 instr->hydrogen()->key()->representation().IsSmi()) {
3023 __ SmiToInteger64(key_reg, key_reg);
3024 } else if (instr->hydrogen()->IsDehoisted()) {
2931 // Sign extend key because it could be a 32 bit negative value 3025 // Sign extend key because it could be a 32 bit negative value
2932 // and the dehoisted address computation happens in 64 bits 3026 // and the dehoisted address computation happens in 64 bits
2933 __ movsxlq(key_reg, key_reg); 3027 __ movsxlq(key_reg, key_reg);
2934 } 3028 }
2935 } 3029 }
2936 Operand operand(BuildFastArrayOperand( 3030 Operand operand(BuildFastArrayOperand(
2937 instr->elements(), 3031 instr->elements(),
2938 key, 3032 key,
2939 elements_kind, 3033 elements_kind,
2940 0, 3034 0,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 3085
2992 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3086 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2993 XMMRegister result(ToDoubleRegister(instr->result())); 3087 XMMRegister result(ToDoubleRegister(instr->result()));
2994 LOperand* key = instr->key(); 3088 LOperand* key = instr->key();
2995 if (!key->IsConstantOperand()) { 3089 if (!key->IsConstantOperand()) {
2996 Register key_reg = ToRegister(key); 3090 Register key_reg = ToRegister(key);
2997 // Even though the HLoad/StoreKeyed instructions force the input 3091 // Even though the HLoad/StoreKeyed instructions force the input
2998 // representation for the key to be an integer, the input gets replaced 3092 // representation for the key to be an integer, the input gets replaced
2999 // during bound check elimination with the index argument to the bounds 3093 // during bound check elimination with the index argument to the bounds
3000 // check, which can be tagged, so that case must be handled here, too. 3094 // check, which can be tagged, so that case must be handled here, too.
3001 if (instr->hydrogen()->IsDehoisted()) { 3095 if (kSmiValueSize == 31 &&
3096 instr->hydrogen()->key()->representation().IsSmi()) {
3097 __ SmiToInteger64(key_reg, key_reg);
3098 } else if (instr->hydrogen()->IsDehoisted()) {
3002 // Sign extend key because it could be a 32 bit negative value 3099 // Sign extend key because it could be a 32 bit negative value
3003 // and the dehoisted address computation happens in 64 bits 3100 // and the dehoisted address computation happens in 64 bits
3004 __ movsxlq(key_reg, key_reg); 3101 __ movsxlq(key_reg, key_reg);
3005 } 3102 }
3006 } 3103 }
3007 3104
3008 if (instr->hydrogen()->RequiresHoleCheck()) { 3105 if (instr->hydrogen()->RequiresHoleCheck()) {
3009 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 3106 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
3010 sizeof(kHoleNanLower32); 3107 sizeof(kHoleNanLower32);
3011 Operand hole_check_operand = BuildFastArrayOperand( 3108 Operand hole_check_operand = BuildFastArrayOperand(
(...skipping 19 matching lines...) Expand all
3031 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3128 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3032 Register result = ToRegister(instr->result()); 3129 Register result = ToRegister(instr->result());
3033 LOperand* key = instr->key(); 3130 LOperand* key = instr->key();
3034 if (!key->IsConstantOperand()) { 3131 if (!key->IsConstantOperand()) {
3035 Register key_reg = ToRegister(key); 3132 Register key_reg = ToRegister(key);
3036 // Even though the HLoad/StoreKeyedFastElement instructions force 3133 // Even though the HLoad/StoreKeyedFastElement instructions force
3037 // the input representation for the key to be an integer, the input 3134 // the input representation for the key to be an integer, the input
3038 // gets replaced during bound check elimination with the index 3135 // gets replaced during bound check elimination with the index
3039 // argument to the bounds check, which can be tagged, so that 3136 // argument to the bounds check, which can be tagged, so that
3040 // case must be handled here, too. 3137 // case must be handled here, too.
3041 if (instr->hydrogen()->IsDehoisted()) { 3138 if (kSmiValueSize == 31 &&
3139 instr->hydrogen()->key()->representation().IsSmi()) {
3140 __ SmiToInteger64(key_reg, key_reg);
3141 } else if (instr->hydrogen()->IsDehoisted()) {
3042 // Sign extend key because it could be a 32 bit negative value 3142 // Sign extend key because it could be a 32 bit negative value
3043 // and the dehoisted address computation happens in 64 bits 3143 // and the dehoisted address computation happens in 64 bits
3044 __ movsxlq(key_reg, key_reg); 3144 __ movsxlq(key_reg, key_reg);
3045 } 3145 }
3046 } 3146 }
3047 3147
3048 // Load the result. 3148 // Load the result.
3049 __ movq(result, 3149 __ movq(result,
3050 BuildFastArrayOperand(instr->elements(), 3150 BuildFastArrayOperand(instr->elements(),
3051 key, 3151 key,
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
3419 Register input_reg = ToRegister(instr->value()); 3519 Register input_reg = ToRegister(instr->value());
3420 __ testl(input_reg, input_reg); 3520 __ testl(input_reg, input_reg);
3421 Label is_positive; 3521 Label is_positive;
3422 __ j(not_sign, &is_positive, Label::kNear); 3522 __ j(not_sign, &is_positive, Label::kNear);
3423 __ negl(input_reg); // Sets flags. 3523 __ negl(input_reg); // Sets flags.
3424 DeoptimizeIf(negative, instr->environment()); 3524 DeoptimizeIf(negative, instr->environment());
3425 __ bind(&is_positive); 3525 __ bind(&is_positive);
3426 } 3526 }
3427 3527
3428 3528
3429 void LCodeGen::EmitInteger64MathAbs(LMathAbs* instr) { 3529 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) {
haitao.feng 2013/08/06 07:58:56 Please ignore this part as Weiliang submitted a CL
3430 Register input_reg = ToRegister(instr->value()); 3530 Register input_reg = ToRegister(instr->value());
3431 __ testq(input_reg, input_reg); 3531 __ testq(input_reg, input_reg);
3432 Label is_positive; 3532 Label is_positive;
3433 __ j(not_sign, &is_positive, Label::kNear); 3533 __ j(not_sign, &is_positive, Label::kNear);
3434 __ neg(input_reg); // Sets flags. 3534 if (kSmiValueSize == 32) {
3535 __ neg(input_reg); // Sets flags.
3536 } else {
3537 ASSERT(kSmiValueSize == 31);
3538 __ negl(input_reg); // Sets flags.
3539 }
3435 DeoptimizeIf(negative, instr->environment()); 3540 DeoptimizeIf(negative, instr->environment());
3436 __ bind(&is_positive); 3541 __ bind(&is_positive);
3437 } 3542 }
3438 3543
3439 3544
3440 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3545 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3441 // Class for deferred case. 3546 // Class for deferred case.
3442 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3547 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3443 public: 3548 public:
3444 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) 3549 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
(...skipping 11 matching lines...) Expand all
3456 3561
3457 if (r.IsDouble()) { 3562 if (r.IsDouble()) {
3458 XMMRegister scratch = xmm0; 3563 XMMRegister scratch = xmm0;
3459 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3564 XMMRegister input_reg = ToDoubleRegister(instr->value());
3460 __ xorps(scratch, scratch); 3565 __ xorps(scratch, scratch);
3461 __ subsd(scratch, input_reg); 3566 __ subsd(scratch, input_reg);
3462 __ andpd(input_reg, scratch); 3567 __ andpd(input_reg, scratch);
3463 } else if (r.IsInteger32()) { 3568 } else if (r.IsInteger32()) {
3464 EmitIntegerMathAbs(instr); 3569 EmitIntegerMathAbs(instr);
3465 } else if (r.IsSmi()) { 3570 } else if (r.IsSmi()) {
3466 EmitInteger64MathAbs(instr); 3571 EmitSmiMathAbs(instr);
3467 } else { // Tagged case. 3572 } else { // Tagged case.
3468 DeferredMathAbsTaggedHeapNumber* deferred = 3573 DeferredMathAbsTaggedHeapNumber* deferred =
3469 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3574 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3470 Register input_reg = ToRegister(instr->value()); 3575 Register input_reg = ToRegister(instr->value());
3471 // Smi check. 3576 // Smi check.
3472 __ JumpIfNotSmi(input_reg, deferred->entry()); 3577 __ JumpIfNotSmi(input_reg, deferred->entry());
3473 __ SmiToInteger32(input_reg, input_reg); 3578 EmitSmiMathAbs(instr);
3474 EmitIntegerMathAbs(instr);
3475 __ Integer32ToSmi(input_reg, input_reg);
3476 __ bind(deferred->exit()); 3579 __ bind(deferred->exit());
3477 } 3580 }
3478 } 3581 }
3479 3582
3480 3583
3481 void LCodeGen::DoMathFloor(LMathFloor* instr) { 3584 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3482 XMMRegister xmm_scratch = xmm0; 3585 XMMRegister xmm_scratch = xmm0;
3483 Register output_reg = ToRegister(instr->result()); 3586 Register output_reg = ToRegister(instr->result());
3484 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3587 XMMRegister input_reg = ToDoubleRegister(instr->value());
3485 3588
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
4133 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4236 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4134 ElementsKind elements_kind = instr->elements_kind(); 4237 ElementsKind elements_kind = instr->elements_kind();
4135 LOperand* key = instr->key(); 4238 LOperand* key = instr->key();
4136 if (!key->IsConstantOperand()) { 4239 if (!key->IsConstantOperand()) {
4137 Register key_reg = ToRegister(key); 4240 Register key_reg = ToRegister(key);
4138 // Even though the HLoad/StoreKeyedFastElement instructions force 4241 // Even though the HLoad/StoreKeyedFastElement instructions force
4139 // the input representation for the key to be an integer, the input 4242 // the input representation for the key to be an integer, the input
4140 // gets replaced during bound check elimination with the index 4243 // gets replaced during bound check elimination with the index
4141 // argument to the bounds check, which can be tagged, so that case 4244 // argument to the bounds check, which can be tagged, so that case
4142 // must be handled here, too. 4245 // must be handled here, too.
4143 if (instr->hydrogen()->IsDehoisted()) { 4246 if (kSmiValueSize == 31 &&
4247 instr->hydrogen()->key()->representation().IsSmi()) {
4248 __ SmiToInteger64(key_reg, key_reg);
4249 } else if (instr->hydrogen()->IsDehoisted()) {
4144 // Sign extend key because it could be a 32 bit negative value 4250 // Sign extend key because it could be a 32 bit negative value
4145 // and the dehoisted address computation happens in 64 bits 4251 // and the dehoisted address computation happens in 64 bits
4146 __ movsxlq(key_reg, key_reg); 4252 __ movsxlq(key_reg, key_reg);
4147 } 4253 }
4148 } 4254 }
4149 Operand operand(BuildFastArrayOperand( 4255 Operand operand(BuildFastArrayOperand(
4150 instr->elements(), 4256 instr->elements(),
4151 key, 4257 key,
4152 elements_kind, 4258 elements_kind,
4153 0, 4259 0,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4195 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4301 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4196 XMMRegister value = ToDoubleRegister(instr->value()); 4302 XMMRegister value = ToDoubleRegister(instr->value());
4197 LOperand* key = instr->key(); 4303 LOperand* key = instr->key();
4198 if (!key->IsConstantOperand()) { 4304 if (!key->IsConstantOperand()) {
4199 Register key_reg = ToRegister(key); 4305 Register key_reg = ToRegister(key);
4200 // Even though the HLoad/StoreKeyedFastElement instructions force 4306 // Even though the HLoad/StoreKeyedFastElement instructions force
4201 // the input representation for the key to be an integer, the 4307 // the input representation for the key to be an integer, the
4202 // input gets replaced during bound check elimination with the index 4308 // input gets replaced during bound check elimination with the index
4203 // argument to the bounds check, which can be tagged, so that case 4309 // argument to the bounds check, which can be tagged, so that case
4204 // must be handled here, too. 4310 // must be handled here, too.
4205 if (instr->hydrogen()->IsDehoisted()) { 4311 if (kSmiValueSize == 31 &&
4312 instr->hydrogen()->key()->representation().IsSmi()) {
4313 __ SmiToInteger64(key_reg, key_reg);
4314 } else if (instr->hydrogen()->IsDehoisted()) {
4206 // Sign extend key because it could be a 32 bit negative value 4315 // Sign extend key because it could be a 32 bit negative value
4207 // and the dehoisted address computation happens in 64 bits 4316 // and the dehoisted address computation happens in 64 bits
4208 __ movsxlq(key_reg, key_reg); 4317 __ movsxlq(key_reg, key_reg);
4209 } 4318 }
4210 } 4319 }
4211 4320
4212 if (instr->NeedsCanonicalization()) { 4321 if (instr->NeedsCanonicalization()) {
4213 Label have_value; 4322 Label have_value;
4214 4323
4215 __ ucomisd(value, value); 4324 __ ucomisd(value, value);
(...skipping 20 matching lines...) Expand all
4236 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4345 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4237 Register elements = ToRegister(instr->elements()); 4346 Register elements = ToRegister(instr->elements());
4238 LOperand* key = instr->key(); 4347 LOperand* key = instr->key();
4239 if (!key->IsConstantOperand()) { 4348 if (!key->IsConstantOperand()) {
4240 Register key_reg = ToRegister(key); 4349 Register key_reg = ToRegister(key);
4241 // Even though the HLoad/StoreKeyedFastElement instructions force 4350 // Even though the HLoad/StoreKeyedFastElement instructions force
4242 // the input representation for the key to be an integer, the 4351 // the input representation for the key to be an integer, the
4243 // input gets replaced during bound check elimination with the index 4352 // input gets replaced during bound check elimination with the index
4244 // argument to the bounds check, which can be tagged, so that case 4353 // argument to the bounds check, which can be tagged, so that case
4245 // must be handled here, too. 4354 // must be handled here, too.
4246 if (instr->hydrogen()->IsDehoisted()) { 4355 if (kSmiValueSize == 31 &&
4356 instr->hydrogen()->key()->representation().IsSmi()) {
4357 __ SmiToInteger64(key_reg, key_reg);
4358 } else if (instr->hydrogen()->IsDehoisted()) {
4247 // Sign extend key because it could be a 32 bit negative value 4359 // Sign extend key because it could be a 32 bit negative value
4248 // and the dehoisted address computation happens in 64 bits 4360 // and the dehoisted address computation happens in 64 bits
4249 __ movsxlq(key_reg, key_reg); 4361 __ movsxlq(key_reg, key_reg);
4250 } 4362 }
4251 } 4363 }
4252 4364
4253 Operand operand = 4365 Operand operand =
4254 BuildFastArrayOperand(instr->elements(), 4366 BuildFastArrayOperand(instr->elements(),
4255 key, 4367 key,
4256 FAST_ELEMENTS, 4368 FAST_ELEMENTS,
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
4493 LOperand* output = instr->result(); 4605 LOperand* output = instr->result();
4494 LOperand* temp = instr->temp(); 4606 LOperand* temp = instr->temp();
4495 4607
4496 __ LoadUint32(ToDoubleRegister(output), 4608 __ LoadUint32(ToDoubleRegister(output),
4497 ToRegister(input), 4609 ToRegister(input),
4498 ToDoubleRegister(temp)); 4610 ToDoubleRegister(temp));
4499 } 4611 }
4500 4612
4501 4613
4502 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4614 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4503 LOperand* input = instr->value(); 4615 if (kSmiValueSize == 32) {
4504 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4616 LOperand* input = instr->value();
4505 Register reg = ToRegister(input); 4617 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4618 Register reg = ToRegister(input);
4506 4619
4507 __ Integer32ToSmi(reg, reg); 4620 __ Integer32ToSmi(reg, reg);
4621 } else {
4622 ASSERT(kSmiValueSize == 31);
4623 class DeferredNumberTagI: public LDeferredCode {
4624 public:
4625 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4626 : LDeferredCode(codegen), instr_(instr) { }
4627 virtual void Generate() {
4628 codegen()->DoDeferredNumberTagI(instr_);
4629 }
4630 virtual LInstruction* instr() { return instr_; }
4631 private:
4632 LNumberTagI* instr_;
4633 };
4634
4635 LOperand* input = instr->value();
4636 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4637 Register reg = ToRegister(input);
4638
4639 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4640 __ shll(reg, Immediate(kSmiTagSize + kSmiShiftSize));
4641 __ j(overflow, deferred->entry());
4642 __ movsxlq(reg, reg);
4643 __ bind(deferred->exit());
4644 }
4508 } 4645 }
4509 4646
4510 4647
4648 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
4649 ASSERT(kSmiValueSize == 31);
4650 Label slow;
4651 Register reg = ToRegister(instr->value());
4652 Register tmp = reg.is(rax) ? kScratchRegister : rax;
4653
4654 // Preserve the value of all registers.
4655 PushSafepointRegistersScope scope(this);
4656
4657 Label done;
4658 // There was overflow, so bits 30 and 31 of the original integer
4659 // disagree. Try to allocate a heap number in new space and store
4660 // the value in there. If that fails, call the runtime system.
4661 __ SmiToInteger32(reg, reg);
4662 __ xorl(reg, Immediate(0x80000000));
4663 __ cvtlsi2sd(xmm1, reg);
4664
4665 if (FLAG_inline_new) {
4666 __ AllocateHeapNumber(reg, tmp, &slow);
4667 __ jmp(&done, Label::kNear);
4668 }
4669
4670 // Slow case: Call the runtime system to do the number allocation.
4671 __ bind(&slow);
4672
4673 // Put a valid pointer value in the stack slot where the result
4674 // register is stored, as this register is in the pointer map, but contains an
4675 // integer value.
4676 __ StoreToSafepointRegisterSlot(reg, Immediate(0));
4677 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4678 // Set the pointer to the new heap number in tmp.
4679 if (!reg.is(rax)) __ movq(reg, rax);
4680
4681 // Heap number allocated. Put the value in xmm0 into the value of the
4682 // allocated heap number.
4683 __ bind(&done);
4684 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1);
4685 __ StoreToSafepointRegisterSlot(reg, reg);
4686 }
4687
4688
4511 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4689 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4512 class DeferredNumberTagU: public LDeferredCode { 4690 class DeferredNumberTagU: public LDeferredCode {
4513 public: 4691 public:
4514 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) 4692 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4515 : LDeferredCode(codegen), instr_(instr) { } 4693 : LDeferredCode(codegen), instr_(instr) { }
4516 virtual void Generate() { 4694 virtual void Generate() {
4517 codegen()->DoDeferredNumberTagU(instr_); 4695 codegen()->DoDeferredNumberTagU(instr_);
4518 } 4696 }
4519 virtual LInstruction* instr() { return instr_; } 4697 virtual LInstruction* instr() { return instr_; }
4520 private: 4698 private:
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after
5577 FixedArray::kHeaderSize - kPointerSize)); 5755 FixedArray::kHeaderSize - kPointerSize));
5578 __ bind(&done); 5756 __ bind(&done);
5579 } 5757 }
5580 5758
5581 5759
5582 #undef __ 5760 #undef __
5583 5761
5584 } } // namespace v8::internal 5762 } } // namespace v8::internal
5585 5763
5586 #endif // V8_TARGET_ARCH_X64 5764 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698