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

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

Powered by Google App Engine
This is Rietveld 408576698