OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 } | 711 } |
712 | 712 |
713 | 713 |
714 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 714 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
715 return AssignEnvironment(new(zone()) LDeoptimize); | 715 return AssignEnvironment(new(zone()) LDeoptimize); |
716 } | 716 } |
717 | 717 |
718 | 718 |
719 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 719 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
720 HBitwiseBinaryOperation* instr) { | 720 HBitwiseBinaryOperation* instr) { |
721 if (instr->representation().IsTagged()) { | 721 if (instr->representation().IsSmiOrTagged()) { |
722 ASSERT(instr->left()->representation().IsTagged()); | 722 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
723 ASSERT(instr->right()->representation().IsTagged()); | 723 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
724 | 724 |
725 LOperand* left = UseFixed(instr->left(), rdx); | 725 LOperand* left = UseFixed(instr->left(), rdx); |
726 LOperand* right = UseFixed(instr->right(), rax); | 726 LOperand* right = UseFixed(instr->right(), rax); |
727 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); | 727 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); |
728 return MarkAsCall(DefineFixed(result, rax), instr); | 728 return MarkAsCall(DefineFixed(result, rax), instr); |
729 } | 729 } |
730 | 730 |
731 ASSERT(instr->representation().IsInteger32()); | 731 ASSERT(instr->representation().IsInteger32()); |
732 ASSERT(instr->left()->representation().IsInteger32()); | 732 ASSERT(instr->left()->representation().IsInteger32()); |
733 ASSERT(instr->right()->representation().IsInteger32()); | 733 ASSERT(instr->right()->representation().IsInteger32()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 | 781 |
782 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 782 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
783 HArithmeticBinaryOperation* instr) { | 783 HArithmeticBinaryOperation* instr) { |
784 ASSERT(op == Token::ADD || | 784 ASSERT(op == Token::ADD || |
785 op == Token::DIV || | 785 op == Token::DIV || |
786 op == Token::MOD || | 786 op == Token::MOD || |
787 op == Token::MUL || | 787 op == Token::MUL || |
788 op == Token::SUB); | 788 op == Token::SUB); |
789 HValue* left = instr->left(); | 789 HValue* left = instr->left(); |
790 HValue* right = instr->right(); | 790 HValue* right = instr->right(); |
791 ASSERT(left->representation().IsTagged()); | 791 ASSERT(left->representation().IsSmiOrTagged()); |
792 ASSERT(right->representation().IsTagged()); | 792 ASSERT(right->representation().IsSmiOrTagged()); |
793 LOperand* left_operand = UseFixed(left, rdx); | 793 LOperand* left_operand = UseFixed(left, rdx); |
794 LOperand* right_operand = UseFixed(right, rax); | 794 LOperand* right_operand = UseFixed(right, rax); |
795 LArithmeticT* result = | 795 LArithmeticT* result = |
796 new(zone()) LArithmeticT(op, left_operand, right_operand); | 796 new(zone()) LArithmeticT(op, left_operand, right_operand); |
797 return MarkAsCall(DefineFixed(result, rax), instr); | 797 return MarkAsCall(DefineFixed(result, rax), instr); |
798 } | 798 } |
799 | 799 |
800 | 800 |
801 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { | 801 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
802 ASSERT(is_building()); | 802 ASSERT(is_building()); |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 | 1301 |
1302 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 1302 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
1303 if (instr->representation().IsInteger32()) { | 1303 if (instr->representation().IsInteger32()) { |
1304 ASSERT(instr->left()->representation().IsInteger32()); | 1304 ASSERT(instr->left()->representation().IsInteger32()); |
1305 ASSERT(instr->right()->representation().IsInteger32()); | 1305 ASSERT(instr->right()->representation().IsInteger32()); |
1306 | 1306 |
1307 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1307 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1308 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); | 1308 LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); |
1309 return DefineSameAsFirst(new(zone()) LBitI(left, right)); | 1309 return DefineSameAsFirst(new(zone()) LBitI(left, right)); |
1310 } else { | 1310 } else { |
1311 ASSERT(instr->representation().IsTagged()); | 1311 ASSERT(instr->representation().IsSmiOrTagged()); |
1312 ASSERT(instr->left()->representation().IsTagged()); | 1312 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
1313 ASSERT(instr->right()->representation().IsTagged()); | 1313 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
1314 | 1314 |
1315 LOperand* left = UseFixed(instr->left(), rdx); | 1315 LOperand* left = UseFixed(instr->left(), rdx); |
1316 LOperand* right = UseFixed(instr->right(), rax); | 1316 LOperand* right = UseFixed(instr->right(), rax); |
1317 LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); | 1317 LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); |
1318 return MarkAsCall(DefineFixed(result, rax), instr); | 1318 return MarkAsCall(DefineFixed(result, rax), instr); |
1319 } | 1319 } |
1320 } | 1320 } |
1321 | 1321 |
1322 | 1322 |
1323 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { | 1323 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { |
(...skipping 18 matching lines...) Expand all Loading... |
1342 return AssignEnvironment(DefineSameAsFirst(div)); | 1342 return AssignEnvironment(DefineSameAsFirst(div)); |
1343 } | 1343 } |
1344 // The temporary operand is necessary to ensure that right is not allocated | 1344 // The temporary operand is necessary to ensure that right is not allocated |
1345 // into rdx. | 1345 // into rdx. |
1346 LOperand* temp = FixedTemp(rdx); | 1346 LOperand* temp = FixedTemp(rdx); |
1347 LOperand* dividend = UseFixed(instr->left(), rax); | 1347 LOperand* dividend = UseFixed(instr->left(), rax); |
1348 LOperand* divisor = UseRegister(instr->right()); | 1348 LOperand* divisor = UseRegister(instr->right()); |
1349 LDivI* result = new(zone()) LDivI(dividend, divisor, temp); | 1349 LDivI* result = new(zone()) LDivI(dividend, divisor, temp); |
1350 return AssignEnvironment(DefineFixed(result, rax)); | 1350 return AssignEnvironment(DefineFixed(result, rax)); |
1351 } else { | 1351 } else { |
1352 ASSERT(instr->representation().IsTagged()); | 1352 ASSERT(instr->representation().IsSmiOrTagged()); |
1353 return DoArithmeticT(Token::DIV, instr); | 1353 return DoArithmeticT(Token::DIV, instr); |
1354 } | 1354 } |
1355 } | 1355 } |
1356 | 1356 |
1357 | 1357 |
1358 HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { | 1358 HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { |
1359 // A value with an integer representation does not need to be transformed. | 1359 // A value with an integer representation does not need to be transformed. |
1360 if (dividend->representation().IsInteger32()) { | 1360 if (dividend->representation().IsInteger32()) { |
1361 return dividend; | 1361 return dividend; |
1362 // A change from an integer32 can be replaced by the integer32 value. | 1362 // A change from an integer32 can be replaced by the integer32 value. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 LOperand* divisor = UseRegister(instr->right()); | 1443 LOperand* divisor = UseRegister(instr->right()); |
1444 LModI* mod = new(zone()) LModI(value, divisor, temp); | 1444 LModI* mod = new(zone()) LModI(value, divisor, temp); |
1445 result = DefineFixed(mod, rdx); | 1445 result = DefineFixed(mod, rdx); |
1446 } | 1446 } |
1447 | 1447 |
1448 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1448 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
1449 instr->CheckFlag(HValue::kCanBeDivByZero) || | 1449 instr->CheckFlag(HValue::kCanBeDivByZero) || |
1450 instr->CheckFlag(HValue::kCanOverflow)) | 1450 instr->CheckFlag(HValue::kCanOverflow)) |
1451 ? AssignEnvironment(result) | 1451 ? AssignEnvironment(result) |
1452 : result; | 1452 : result; |
1453 } else if (instr->representation().IsTagged()) { | 1453 } else if (instr->representation().IsSmiOrTagged()) { |
1454 return DoArithmeticT(Token::MOD, instr); | 1454 return DoArithmeticT(Token::MOD, instr); |
1455 } else { | 1455 } else { |
1456 ASSERT(instr->representation().IsDouble()); | 1456 ASSERT(instr->representation().IsDouble()); |
1457 // We call a C function for double modulo. It can't trigger a GC. | 1457 // We call a C function for double modulo. It can't trigger a GC. |
1458 // We need to use fixed result register for the call. | 1458 // We need to use fixed result register for the call. |
1459 // TODO(fschneider): Allow any register as input registers. | 1459 // TODO(fschneider): Allow any register as input registers. |
1460 LOperand* left = UseFixedDouble(instr->left(), xmm2); | 1460 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
1461 LOperand* right = UseFixedDouble(instr->right(), xmm1); | 1461 LOperand* right = UseFixedDouble(instr->right(), xmm1); |
1462 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); | 1462 LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right); |
1463 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1463 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
1464 } | 1464 } |
1465 } | 1465 } |
1466 | 1466 |
1467 | 1467 |
1468 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1468 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1469 if (instr->representation().IsInteger32()) { | 1469 if (instr->representation().IsInteger32()) { |
1470 ASSERT(instr->left()->representation().IsInteger32()); | 1470 ASSERT(instr->left()->representation().IsInteger32()); |
1471 ASSERT(instr->right()->representation().IsInteger32()); | 1471 ASSERT(instr->right()->representation().IsInteger32()); |
1472 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1472 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1473 LOperand* right = UseOrConstant(instr->BetterRightOperand()); | 1473 LOperand* right = UseOrConstant(instr->BetterRightOperand()); |
1474 LMulI* mul = new(zone()) LMulI(left, right); | 1474 LMulI* mul = new(zone()) LMulI(left, right); |
1475 if (instr->CheckFlag(HValue::kCanOverflow) || | 1475 if (instr->CheckFlag(HValue::kCanOverflow) || |
1476 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1476 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1477 AssignEnvironment(mul); | 1477 AssignEnvironment(mul); |
1478 } | 1478 } |
1479 return DefineSameAsFirst(mul); | 1479 return DefineSameAsFirst(mul); |
1480 } else if (instr->representation().IsDouble()) { | 1480 } else if (instr->representation().IsDouble()) { |
1481 return DoArithmeticD(Token::MUL, instr); | 1481 return DoArithmeticD(Token::MUL, instr); |
1482 } else { | 1482 } else { |
1483 ASSERT(instr->representation().IsTagged()); | 1483 ASSERT(instr->representation().IsSmiOrTagged()); |
1484 return DoArithmeticT(Token::MUL, instr); | 1484 return DoArithmeticT(Token::MUL, instr); |
1485 } | 1485 } |
1486 } | 1486 } |
1487 | 1487 |
1488 | 1488 |
1489 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1489 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
1490 if (instr->representation().IsInteger32()) { | 1490 if (instr->representation().IsInteger32()) { |
1491 ASSERT(instr->left()->representation().IsInteger32()); | 1491 ASSERT(instr->left()->representation().IsInteger32()); |
1492 ASSERT(instr->right()->representation().IsInteger32()); | 1492 ASSERT(instr->right()->representation().IsInteger32()); |
1493 LOperand* left = UseRegisterAtStart(instr->left()); | 1493 LOperand* left = UseRegisterAtStart(instr->left()); |
1494 LOperand* right = UseOrConstantAtStart(instr->right()); | 1494 LOperand* right = UseOrConstantAtStart(instr->right()); |
1495 LSubI* sub = new(zone()) LSubI(left, right); | 1495 LSubI* sub = new(zone()) LSubI(left, right); |
1496 LInstruction* result = DefineSameAsFirst(sub); | 1496 LInstruction* result = DefineSameAsFirst(sub); |
1497 if (instr->CheckFlag(HValue::kCanOverflow)) { | 1497 if (instr->CheckFlag(HValue::kCanOverflow)) { |
1498 result = AssignEnvironment(result); | 1498 result = AssignEnvironment(result); |
1499 } | 1499 } |
1500 return result; | 1500 return result; |
1501 } else if (instr->representation().IsDouble()) { | 1501 } else if (instr->representation().IsDouble()) { |
1502 return DoArithmeticD(Token::SUB, instr); | 1502 return DoArithmeticD(Token::SUB, instr); |
1503 } else { | 1503 } else { |
1504 ASSERT(instr->representation().IsTagged()); | 1504 ASSERT(instr->representation().IsSmiOrTagged()); |
1505 return DoArithmeticT(Token::SUB, instr); | 1505 return DoArithmeticT(Token::SUB, instr); |
1506 } | 1506 } |
1507 } | 1507 } |
1508 | 1508 |
1509 | 1509 |
1510 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 1510 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
1511 if (instr->representation().IsInteger32()) { | 1511 if (instr->representation().IsInteger32()) { |
1512 // Check to see if it would be advantageous to use an lea instruction rather | 1512 // Check to see if it would be advantageous to use an lea instruction rather |
1513 // than an add. This is the case when no overflow check is needed and there | 1513 // than an add. This is the case when no overflow check is needed and there |
1514 // are multiple uses of the add's inputs, so using a 3-register add will | 1514 // are multiple uses of the add's inputs, so using a 3-register add will |
(...skipping 11 matching lines...) Expand all Loading... |
1526 LInstruction* result = use_lea | 1526 LInstruction* result = use_lea |
1527 ? DefineAsRegister(add) | 1527 ? DefineAsRegister(add) |
1528 : DefineSameAsFirst(add); | 1528 : DefineSameAsFirst(add); |
1529 if (can_overflow) { | 1529 if (can_overflow) { |
1530 result = AssignEnvironment(result); | 1530 result = AssignEnvironment(result); |
1531 } | 1531 } |
1532 return result; | 1532 return result; |
1533 } else if (instr->representation().IsDouble()) { | 1533 } else if (instr->representation().IsDouble()) { |
1534 return DoArithmeticD(Token::ADD, instr); | 1534 return DoArithmeticD(Token::ADD, instr); |
1535 } else { | 1535 } else { |
1536 ASSERT(instr->representation().IsTagged()); | 1536 ASSERT(instr->representation().IsSmiOrTagged()); |
1537 return DoArithmeticT(Token::ADD, instr); | 1537 return DoArithmeticT(Token::ADD, instr); |
1538 } | 1538 } |
1539 return NULL; | 1539 return NULL; |
1540 } | 1540 } |
1541 | 1541 |
1542 | 1542 |
1543 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1543 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
1544 LOperand* left = NULL; | 1544 LOperand* left = NULL; |
1545 LOperand* right = NULL; | 1545 LOperand* right = NULL; |
1546 if (instr->representation().IsInteger32()) { | 1546 if (instr->representation().IsInteger32()) { |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 return NULL; | 1807 return NULL; |
1808 } | 1808 } |
1809 | 1809 |
1810 | 1810 |
1811 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1811 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
1812 Representation from = instr->from(); | 1812 Representation from = instr->from(); |
1813 Representation to = instr->to(); | 1813 Representation to = instr->to(); |
1814 if (from.IsSmi()) { | 1814 if (from.IsSmi()) { |
1815 if (to.IsTagged()) { | 1815 if (to.IsTagged()) { |
1816 LOperand* value = UseRegister(instr->value()); | 1816 LOperand* value = UseRegister(instr->value()); |
1817 // For now, always deopt on hole. | |
1818 if (instr->value()->IsLoadKeyed() && | |
1819 HLoadKeyed::cast(instr->value())->UsesMustHandleHole()) { | |
1820 return AssignEnvironment( | |
1821 DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); | |
1822 } | |
1823 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1817 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
1824 } | 1818 } |
1825 from = Representation::Tagged(); | 1819 from = Representation::Tagged(); |
1826 } | 1820 } |
1827 // Only mark conversions that might need to allocate as calling rather than | 1821 // Only mark conversions that might need to allocate as calling rather than |
1828 // all changes. This makes simple, non-allocating conversion not have to force | 1822 // all changes. This makes simple, non-allocating conversion not have to force |
1829 // building a stack frame. | 1823 // building a stack frame. |
1830 if (from.IsTagged()) { | 1824 if (from.IsTagged()) { |
1831 if (to.IsDouble()) { | 1825 if (to.IsDouble()) { |
1832 info()->MarkAsDeferredCalling(); | 1826 info()->MarkAsDeferredCalling(); |
1833 LOperand* value = UseRegister(instr->value()); | 1827 LOperand* value = UseRegister(instr->value()); |
1834 LNumberUntagD* res = new(zone()) LNumberUntagD(value); | 1828 LNumberUntagD* res = new(zone()) LNumberUntagD(value); |
1835 return AssignEnvironment(DefineAsRegister(res)); | 1829 return AssignEnvironment(DefineAsRegister(res)); |
1836 } else if (to.IsSmi()) { | 1830 } else if (to.IsSmi()) { |
1837 HValue* val = instr->value(); | 1831 HValue* val = instr->value(); |
1838 LOperand* value = UseRegister(val); | 1832 LOperand* value = UseRegister(val); |
1839 if (val->type().IsSmi()) { | 1833 if (val->type().IsSmi()) { |
1840 return DefineSameAsFirst(new(zone()) LDummyUse(value)); | 1834 return DefineSameAsFirst(new(zone()) LDummyUse(value)); |
1841 } | 1835 } |
1842 return AssignEnvironment( | 1836 return AssignEnvironment( |
1843 DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); | 1837 DefineSameAsFirst(new(zone()) LCheckSmiAndReturn(value))); |
1844 } else { | 1838 } else { |
1845 ASSERT(to.IsInteger32()); | 1839 ASSERT(to.IsInteger32()); |
1846 LOperand* value = UseRegister(instr->value()); | 1840 LOperand* value = UseRegister(instr->value()); |
1847 if (instr->value()->type().IsSmi()) { | 1841 if (instr->value()->type().IsSmi()) { |
1848 LInstruction* result = | 1842 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
1849 DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); | |
1850 if (instr->value()->IsLoadKeyed()) { | |
1851 HLoadKeyed* load_keyed = HLoadKeyed::cast(instr->value()); | |
1852 if (load_keyed->UsesMustHandleHole() && | |
1853 load_keyed->hole_mode() == NEVER_RETURN_HOLE) { | |
1854 return AssignEnvironment(result); | |
1855 } | |
1856 } | |
1857 return result; | |
1858 } else { | 1843 } else { |
1859 bool truncating = instr->CanTruncateToInt32(); | 1844 bool truncating = instr->CanTruncateToInt32(); |
1860 LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1); | 1845 LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1); |
1861 LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp); | 1846 LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp); |
1862 return AssignEnvironment(DefineSameAsFirst(res)); | 1847 return AssignEnvironment(DefineSameAsFirst(res)); |
1863 } | 1848 } |
1864 } | 1849 } |
1865 } else if (from.IsDouble()) { | 1850 } else if (from.IsDouble()) { |
1866 if (to.IsTagged()) { | 1851 if (to.IsTagged()) { |
1867 info()->MarkAsDeferredCalling(); | 1852 info()->MarkAsDeferredCalling(); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1964 | 1949 |
1965 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 1950 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
1966 HValue* value = instr->value(); | 1951 HValue* value = instr->value(); |
1967 Representation input_rep = value->representation(); | 1952 Representation input_rep = value->representation(); |
1968 LOperand* reg = UseRegister(value); | 1953 LOperand* reg = UseRegister(value); |
1969 if (input_rep.IsDouble()) { | 1954 if (input_rep.IsDouble()) { |
1970 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); | 1955 return DefineAsRegister(new(zone()) LClampDToUint8(reg)); |
1971 } else if (input_rep.IsInteger32()) { | 1956 } else if (input_rep.IsInteger32()) { |
1972 return DefineSameAsFirst(new(zone()) LClampIToUint8(reg)); | 1957 return DefineSameAsFirst(new(zone()) LClampIToUint8(reg)); |
1973 } else { | 1958 } else { |
1974 ASSERT(input_rep.IsTagged()); | 1959 ASSERT(input_rep.IsSmiOrTagged()); |
1975 // Register allocator doesn't (yet) support allocation of double | 1960 // Register allocator doesn't (yet) support allocation of double |
1976 // temps. Reserve xmm1 explicitly. | 1961 // temps. Reserve xmm1 explicitly. |
1977 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, | 1962 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, |
1978 FixedTemp(xmm1)); | 1963 FixedTemp(xmm1)); |
1979 return AssignEnvironment(DefineSameAsFirst(result)); | 1964 return AssignEnvironment(DefineSameAsFirst(result)); |
1980 } | 1965 } |
1981 } | 1966 } |
1982 | 1967 |
1983 | 1968 |
1984 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { | 1969 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2586 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2571 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2587 LOperand* object = UseRegister(instr->object()); | 2572 LOperand* object = UseRegister(instr->object()); |
2588 LOperand* index = UseTempRegister(instr->index()); | 2573 LOperand* index = UseTempRegister(instr->index()); |
2589 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2574 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2590 } | 2575 } |
2591 | 2576 |
2592 | 2577 |
2593 } } // namespace v8::internal | 2578 } } // namespace v8::internal |
2594 | 2579 |
2595 #endif // V8_TARGET_ARCH_X64 | 2580 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |