| OLD | NEW |
| 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 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 827 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 828 HBinaryOperation* instr) { | 828 HBinaryOperation* instr) { |
| 829 ASSERT((op == Token::ADD) || (op == Token::SUB) || (op == Token::MUL) || | 829 ASSERT((op == Token::ADD) || (op == Token::SUB) || (op == Token::MUL) || |
| 830 (op == Token::DIV) || (op == Token::MOD) || (op == Token::SHR) || | 830 (op == Token::DIV) || (op == Token::MOD) || (op == Token::SHR) || |
| 831 (op == Token::SHL) || (op == Token::SAR) || (op == Token::ROR) || | 831 (op == Token::SHL) || (op == Token::SAR) || (op == Token::ROR) || |
| 832 (op == Token::BIT_OR) || (op == Token::BIT_AND) || | 832 (op == Token::BIT_OR) || (op == Token::BIT_AND) || |
| 833 (op == Token::BIT_XOR)); | 833 (op == Token::BIT_XOR)); |
| 834 HValue* left = instr->left(); | 834 HValue* left = instr->left(); |
| 835 HValue* right = instr->right(); | 835 HValue* right = instr->right(); |
| 836 | 836 |
| 837 // TODO(jbramley): Once we've implemented smi support for all arithmetic |
| 838 // operations, these assertions should check IsTagged(). |
| 837 ASSERT(instr->representation().IsSmiOrTagged()); | 839 ASSERT(instr->representation().IsSmiOrTagged()); |
| 838 ASSERT(left->representation().IsSmiOrTagged()); | 840 ASSERT(left->representation().IsSmiOrTagged()); |
| 839 ASSERT(right->representation().IsSmiOrTagged()); | 841 ASSERT(right->representation().IsSmiOrTagged()); |
| 840 | 842 |
| 841 LOperand* left_operand = UseFixed(left, x1); | 843 LOperand* left_operand = UseFixed(left, x1); |
| 842 LOperand* right_operand = UseFixed(right, x0); | 844 LOperand* right_operand = UseFixed(right, x0); |
| 843 LArithmeticT* result = | 845 LArithmeticT* result = |
| 844 new(zone()) LArithmeticT(op, left_operand, right_operand); | 846 new(zone()) LArithmeticT(op, left_operand, right_operand); |
| 845 return MarkAsCall(DefineFixed(result, x0), instr); | 847 return MarkAsCall(DefineFixed(result, x0), instr); |
| 846 } | 848 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 index = UseRegisterOrConstantAtStart(instr->index()); | 890 index = UseRegisterOrConstantAtStart(instr->index()); |
| 889 temp = TempRegister(); | 891 temp = TempRegister(); |
| 890 } | 892 } |
| 891 | 893 |
| 892 return DefineAsRegister( | 894 return DefineAsRegister( |
| 893 new(zone()) LAccessArgumentsAt(args, length, index, temp)); | 895 new(zone()) LAccessArgumentsAt(args, length, index, temp)); |
| 894 } | 896 } |
| 895 | 897 |
| 896 | 898 |
| 897 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { | 899 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { |
| 898 if (instr->representation().IsInteger32()) { | 900 if (instr->representation().IsSmiOrInteger32()) { |
| 899 // TODO(all): LAddI instruction should also handle the addition of | 901 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 900 // two SMI values. | 902 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 901 ASSERT(instr->left()->representation().IsInteger32()); | |
| 902 ASSERT(instr->right()->representation().IsInteger32()); | |
| 903 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 903 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 904 LOperand* right = | 904 LOperand* right = |
| 905 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 905 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
| 906 LInstruction* result = DefineAsRegister(new(zone()) LAddI(left, right)); | 906 LInstruction* result = instr->representation().IsSmi() ? |
| 907 DefineAsRegister(new(zone()) LAddS(left, right)) : |
| 908 DefineAsRegister(new(zone()) LAddI(left, right)); |
| 907 if (instr->CheckFlag(HValue::kCanOverflow)) { | 909 if (instr->CheckFlag(HValue::kCanOverflow)) { |
| 908 result = AssignEnvironment(result); | 910 result = AssignEnvironment(result); |
| 909 } | 911 } |
| 910 return result; | 912 return result; |
| 911 } else if (instr->representation().IsDouble()) { | 913 } else if (instr->representation().IsDouble()) { |
| 912 return DoArithmeticD(Token::ADD, instr); | 914 return DoArithmeticD(Token::ADD, instr); |
| 913 } else { | 915 } else { |
| 914 ASSERT(instr->representation().IsSmiOrTagged()); | 916 ASSERT(instr->representation().IsTagged()); |
| 915 return DoArithmeticT(Token::ADD, instr); | 917 return DoArithmeticT(Token::ADD, instr); |
| 916 } | 918 } |
| 917 } | 919 } |
| 918 | 920 |
| 919 | 921 |
| 920 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { | 922 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { |
| 921 info()->MarkAsDeferredCalling(); | 923 info()->MarkAsDeferredCalling(); |
| 922 LOperand* size = UseRegisterOrConstant(instr->size()); | 924 LOperand* size = UseRegisterOrConstant(instr->size()); |
| 923 LOperand* temp1 = TempRegister(); | 925 LOperand* temp1 = TempRegister(); |
| 924 LOperand* temp2 = TempRegister(); | 926 LOperand* temp2 = TempRegister(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 959 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 958 // There are no real uses of the arguments object. | 960 // There are no real uses of the arguments object. |
| 959 // arguments.length and element access are supported directly on | 961 // arguments.length and element access are supported directly on |
| 960 // stack arguments, and any real arguments object use causes a bailout. | 962 // stack arguments, and any real arguments object use causes a bailout. |
| 961 // So this value is never used. | 963 // So this value is never used. |
| 962 return NULL; | 964 return NULL; |
| 963 } | 965 } |
| 964 | 966 |
| 965 | 967 |
| 966 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { | 968 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { |
| 967 // TODO(all): The latest bleeding_edge handles smi representations too. | 969 if (instr->representation().IsSmiOrInteger32()) { |
| 968 if (instr->representation().IsInteger32()) { | 970 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 969 ASSERT(instr->left()->representation().IsInteger32()); | 971 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 970 ASSERT(instr->right()->representation().IsInteger32()); | |
| 971 | 972 |
| 972 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); | 973 LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 973 LOperand* right = | 974 LOperand* right = |
| 974 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 975 UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
| 975 return DefineAsRegister(new(zone()) LBitI(left, right)); | 976 return instr->representation().IsSmi() ? |
| 977 DefineAsRegister(new(zone()) LBitS(left, right)) : |
| 978 DefineAsRegister(new(zone()) LBitI(left, right)); |
| 976 } else { | 979 } else { |
| 977 return DoArithmeticT(instr->op(), instr); | 980 return DoArithmeticT(instr->op(), instr); |
| 978 } | 981 } |
| 979 } | 982 } |
| 980 | 983 |
| 981 | 984 |
| 982 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { | 985 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { |
| 983 ASSERT(instr->value()->representation().IsInteger32()); | 986 ASSERT(instr->value()->representation().IsInteger32()); |
| 984 ASSERT(instr->representation().IsInteger32()); | 987 ASSERT(instr->representation().IsInteger32()); |
| 985 if (instr->HasNoUses()) return NULL; | 988 if (instr->HasNoUses()) return NULL; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 | 1244 |
| 1242 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 1245 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
| 1243 LOperand* value = UseRegisterAtStart(instr->value()); | 1246 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1244 LOperand* temp = TempRegister(); | 1247 LOperand* temp = TempRegister(); |
| 1245 LInstruction* result = new(zone()) LCheckInstanceType(value, temp); | 1248 LInstruction* result = new(zone()) LCheckInstanceType(value, temp); |
| 1246 return AssignEnvironment(result); | 1249 return AssignEnvironment(result); |
| 1247 } | 1250 } |
| 1248 | 1251 |
| 1249 | 1252 |
| 1250 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { | 1253 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { |
| 1251 LOperand* value = UseRegister(instr->value()); | 1254 if (instr->CanOmitMapChecks()) { |
| 1252 LOperand* temp = TempRegister(); | 1255 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1253 LInstruction* result = new(zone()) LCheckMaps(value, temp); | 1256 return new(zone()) LCheckMaps(value); |
| 1254 return AssignEnvironment(result); | 1257 } else { |
| 1258 LOperand* value = UseRegister(instr->value()); |
| 1259 LOperand* temp = TempRegister(); |
| 1260 LInstruction* result = new(zone()) LCheckMaps(value, temp); |
| 1261 return AssignEnvironment(result); |
| 1262 } |
| 1255 } | 1263 } |
| 1256 | 1264 |
| 1257 | 1265 |
| 1258 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { | 1266 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { |
| 1259 LOperand* value = UseRegisterAtStart(instr->value()); | 1267 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1260 return AssignEnvironment(new(zone()) LCheckNonSmi(value)); | 1268 return AssignEnvironment(new(zone()) LCheckNonSmi(value)); |
| 1261 } | 1269 } |
| 1262 | 1270 |
| 1263 | 1271 |
| 1264 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { | 1272 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
| 1265 // TODO(jbramley): The scratch registers are not needed if | 1273 if (instr->CanOmitPrototypeChecks()) { |
| 1266 // instr->CanOmitPrototypeChecks(). Can we safely test that here? | 1274 return new(zone()) LCheckPrototypeMaps(); |
| 1267 LOperand* temp1 = TempRegister(); | 1275 } else { |
| 1268 LOperand* temp2 = TempRegister(); | 1276 LOperand* temp1 = TempRegister(); |
| 1269 return AssignEnvironment(new(zone()) LCheckPrototypeMaps(temp1, temp2)); | 1277 LOperand* temp2 = TempRegister(); |
| 1278 return AssignEnvironment(new(zone()) LCheckPrototypeMaps(temp1, temp2)); |
| 1279 } |
| 1270 } | 1280 } |
| 1271 | 1281 |
| 1272 | 1282 |
| 1273 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { | 1283 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { |
| 1274 LOperand* value = UseRegisterAtStart(instr->value()); | 1284 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1275 return AssignEnvironment(new(zone()) LCheckSmi(value)); | 1285 return AssignEnvironment(new(zone()) LCheckSmi(value)); |
| 1276 } | 1286 } |
| 1277 | 1287 |
| 1278 | 1288 |
| 1279 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 1289 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 | 1372 |
| 1363 | 1373 |
| 1364 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1374 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1365 ASSERT(instr->value()->representation().IsTagged()); | 1375 ASSERT(instr->value()->representation().IsTagged()); |
| 1366 LOperand* value = UseRegisterAtStart(instr->value()); | 1376 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1367 LOperand* temp = TempRegister(); | 1377 LOperand* temp = TempRegister(); |
| 1368 return new(zone()) LCmpMapAndBranch(value, temp); | 1378 return new(zone()) LCmpMapAndBranch(value, temp); |
| 1369 } | 1379 } |
| 1370 | 1380 |
| 1371 | 1381 |
| 1372 LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch( | |
| 1373 HCompareConstantEqAndBranch* instr) { | |
| 1374 UNIMPLEMENTED_INSTRUCTION(); | |
| 1375 } | |
| 1376 | |
| 1377 | |
| 1378 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 1382 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| 1379 Representation r = instr->representation(); | 1383 Representation r = instr->representation(); |
| 1380 if (r.IsSmi()) { | 1384 if (r.IsSmi()) { |
| 1381 return DefineAsRegister(new(zone()) LConstantS); | 1385 return DefineAsRegister(new(zone()) LConstantS); |
| 1382 } else if (r.IsInteger32()) { | 1386 } else if (r.IsInteger32()) { |
| 1383 return DefineAsRegister(new(zone()) LConstantI); | 1387 return DefineAsRegister(new(zone()) LConstantI); |
| 1384 } else if (r.IsDouble()) { | 1388 } else if (r.IsDouble()) { |
| 1385 return DefineAsRegister(new(zone()) LConstantD); | 1389 return DefineAsRegister(new(zone()) LConstantD); |
| 1386 } else if (r.IsTagged()) { | 1390 } else if (r.IsTagged()) { |
| 1387 return DefineAsRegister(new(zone()) LConstantT); | 1391 return DefineAsRegister(new(zone()) LConstantT); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 | 1691 |
| 1688 | 1692 |
| 1689 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { | 1693 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { |
| 1690 LOperand* global_object = UseFixed(instr->global_object(), x0); | 1694 LOperand* global_object = UseFixed(instr->global_object(), x0); |
| 1691 LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(global_object); | 1695 LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(global_object); |
| 1692 return MarkAsCall(DefineFixed(result, x0), instr); | 1696 return MarkAsCall(DefineFixed(result, x0), instr); |
| 1693 } | 1697 } |
| 1694 | 1698 |
| 1695 | 1699 |
| 1696 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 1700 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 1697 ASSERT(instr->key()->representation().IsInteger32() || | 1701 ASSERT(instr->key()->representation().IsSmiOrInteger32()); |
| 1698 instr->key()->representation().IsSmi()); | |
| 1699 ElementsKind elements_kind = instr->elements_kind(); | 1702 ElementsKind elements_kind = instr->elements_kind(); |
| 1700 LOperand* elements = UseRegister(instr->elements()); | 1703 LOperand* elements = UseRegister(instr->elements()); |
| 1701 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 1704 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 1702 | 1705 |
| 1703 if (!instr->is_external()) { | 1706 if (!instr->is_external()) { |
| 1704 if (instr->representation().IsDouble()) { | 1707 if (instr->representation().IsDouble()) { |
| 1705 LOperand* temp = (!instr->key()->IsConstant() || | 1708 LOperand* temp = (!instr->key()->IsConstant() || |
| 1706 instr->RequiresHoleCheck()) | 1709 instr->RequiresHoleCheck()) |
| 1707 ? TempRegister() | 1710 ? TempRegister() |
| 1708 : NULL; | 1711 : NULL; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1813 LOperand* divisor = UseRegister(right); | 1816 LOperand* divisor = UseRegister(right); |
| 1814 LOperand* remainder = TempRegister(); | 1817 LOperand* remainder = TempRegister(); |
| 1815 return AssignEnvironment(DefineAsRegister( | 1818 return AssignEnvironment(DefineAsRegister( |
| 1816 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); | 1819 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); |
| 1817 } | 1820 } |
| 1818 | 1821 |
| 1819 | 1822 |
| 1820 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1823 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
| 1821 LOperand* left = NULL; | 1824 LOperand* left = NULL; |
| 1822 LOperand* right = NULL; | 1825 LOperand* right = NULL; |
| 1823 if (instr->representation().IsInteger32()) { | 1826 if (instr->representation().IsSmiOrInteger32()) { |
| 1824 ASSERT(instr->left()->representation().IsInteger32()); | 1827 ASSERT(instr->left()->representation().IsInteger32()); |
| 1825 ASSERT(instr->right()->representation().IsInteger32()); | 1828 ASSERT(instr->right()->representation().IsInteger32()); |
| 1826 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1829 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
| 1827 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 1830 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
| 1828 } else { | 1831 } else { |
| 1829 ASSERT(instr->representation().IsDouble()); | 1832 ASSERT(instr->representation().IsDouble()); |
| 1830 ASSERT(instr->left()->representation().IsDouble()); | 1833 ASSERT(instr->left()->representation().IsDouble()); |
| 1831 ASSERT(instr->right()->representation().IsDouble()); | 1834 ASSERT(instr->right()->representation().IsDouble()); |
| 1832 left = UseRegisterAtStart(instr->left()); | 1835 left = UseRegisterAtStart(instr->left()); |
| 1833 right = UseRegisterAtStart(instr->right()); | 1836 right = UseRegisterAtStart(instr->right()); |
| 1834 } | 1837 } |
| 1835 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); | 1838 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); |
| 1836 } | 1839 } |
| 1837 | 1840 |
| 1838 | 1841 |
| 1839 LInstruction* LChunkBuilder::DoMod(HMod* hmod) { | 1842 LInstruction* LChunkBuilder::DoMod(HMod* hmod) { |
| 1840 HValue* hleft = hmod->left(); | 1843 HValue* hleft = hmod->left(); |
| 1841 HValue* hright = hmod->right(); | 1844 HValue* hright = hmod->right(); |
| 1842 | 1845 |
| 1846 // TODO(jbramley): Add smi support. |
| 1843 if (hmod->representation().IsInteger32()) { | 1847 if (hmod->representation().IsInteger32()) { |
| 1844 ASSERT(hleft->representation().IsInteger32()); | 1848 ASSERT(hleft->representation().IsInteger32()); |
| 1845 ASSERT(hleft->representation().IsInteger32()); | 1849 ASSERT(hleft->representation().IsInteger32()); |
| 1846 LOperand* left_op; | 1850 LOperand* left_op; |
| 1847 LOperand* right_op; | 1851 LOperand* right_op; |
| 1848 | 1852 |
| 1849 if (hmod->HasPowerOf2Divisor()) { | 1853 if (hmod->HasPowerOf2Divisor()) { |
| 1850 left_op = UseRegisterAtStart(hleft); | 1854 left_op = UseRegisterAtStart(hleft); |
| 1851 right_op = UseConstant(hright); | 1855 right_op = UseConstant(hright); |
| 1852 } else { | 1856 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1865 | 1869 |
| 1866 } else if (hmod->representation().IsSmiOrTagged()) { | 1870 } else if (hmod->representation().IsSmiOrTagged()) { |
| 1867 return DoArithmeticT(Token::MOD, hmod); | 1871 return DoArithmeticT(Token::MOD, hmod); |
| 1868 } else { | 1872 } else { |
| 1869 return DoArithmeticD(Token::MOD, hmod); | 1873 return DoArithmeticD(Token::MOD, hmod); |
| 1870 } | 1874 } |
| 1871 } | 1875 } |
| 1872 | 1876 |
| 1873 | 1877 |
| 1874 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1878 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1875 if (instr->representation().IsInteger32()) { | 1879 if (instr->representation().IsSmi()) { |
| 1876 ASSERT(instr->left()->representation().IsInteger32()); | 1880 // TODO(jbramley): Implement LMulConstS, then merge this into the Integer32 |
| 1877 ASSERT(instr->right()->representation().IsInteger32()); | 1881 // case. |
| 1882 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1883 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1878 | 1884 |
| 1879 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1885 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1880 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); | 1886 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); |
| 1887 bool needs_environment = can_overflow || bailout_on_minus_zero; |
| 1888 |
| 1889 LOperand* left = UseRegister(instr->BetterLeftOperand()); |
| 1890 LOperand* right = UseRegister(instr->BetterRightOperand()); |
| 1891 |
| 1892 LMulS* mul = new(zone()) LMulS(left, right); |
| 1893 if (needs_environment) AssignEnvironment(mul); |
| 1894 return DefineAsRegister(mul); |
| 1895 } else if (instr->representation().IsSmiOrInteger32()) { |
| 1896 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1897 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1898 |
| 1899 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
| 1900 bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); |
| 1881 bool needs_environment = can_overflow || bailout_on_minus_zero; | 1901 bool needs_environment = can_overflow || bailout_on_minus_zero; |
| 1882 | 1902 |
| 1883 HValue* least_const = instr->BetterLeftOperand(); | 1903 HValue* least_const = instr->BetterLeftOperand(); |
| 1884 HValue* most_const = instr->BetterRightOperand(); | 1904 HValue* most_const = instr->BetterRightOperand(); |
| 1885 | 1905 |
| 1886 LOperand* left = UseRegisterAtStart(least_const); | 1906 LOperand* left = UseRegisterAtStart(least_const); |
| 1887 | 1907 |
| 1888 // LMulConstI can handle a subset of constants: | 1908 // LMulConstI can handle a subset of constants: |
| 1889 // With support for overflow detection: | 1909 // With support for overflow detection: |
| 1890 // -1, 0, 1, 2 | 1910 // -1, 0, 1, 2 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1999 LOperand* temp = TempRegister(); | 2019 LOperand* temp = TempRegister(); |
| 2000 LSeqStringSetChar* result = | 2020 LSeqStringSetChar* result = |
| 2001 new(zone()) LSeqStringSetChar(instr->encoding(), | 2021 new(zone()) LSeqStringSetChar(instr->encoding(), |
| 2002 string, index, value, temp); | 2022 string, index, value, temp); |
| 2003 return DefineAsRegister(result); | 2023 return DefineAsRegister(result); |
| 2004 } | 2024 } |
| 2005 | 2025 |
| 2006 | 2026 |
| 2007 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 2027 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
| 2008 HBitwiseBinaryOperation* instr) { | 2028 HBitwiseBinaryOperation* instr) { |
| 2029 // TODO(jbramley): Support smis inline, like integers. |
| 2009 if (instr->representation().IsSmiOrTagged()) { | 2030 if (instr->representation().IsSmiOrTagged()) { |
| 2010 return DoArithmeticT(op, instr); | 2031 return DoArithmeticT(op, instr); |
| 2011 } | 2032 } |
| 2012 | 2033 |
| 2013 ASSERT(instr->representation().IsInteger32()); | 2034 ASSERT(instr->representation().IsInteger32()); |
| 2014 ASSERT(instr->left()->representation().IsInteger32()); | 2035 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 2015 ASSERT(instr->right()->representation().IsInteger32()); | 2036 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 2016 LOperand* left = UseRegisterAtStart(instr->left()); | 2037 LOperand* left = UseRegisterAtStart(instr->left()); |
| 2017 | 2038 |
| 2018 HValue* right_value = instr->right(); | 2039 HValue* right_value = instr->right(); |
| 2019 LOperand* right = NULL; | 2040 LOperand* right = NULL; |
| 2020 int constant_value = 0; | 2041 int constant_value = 0; |
| 2021 if (right_value->IsConstant()) { | 2042 if (right_value->IsConstant()) { |
| 2022 right = UseConstant(right_value); | 2043 right = UseConstant(right_value); |
| 2023 HConstant* constant = HConstant::cast(right_value); | 2044 HConstant* constant = HConstant::cast(right_value); |
| 2024 constant_value = constant->Integer32Value() & 0x1f; | 2045 constant_value = constant->Integer32Value() & 0x1f; |
| 2025 } else { | 2046 } else { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2095 SetDeferredLazyDeoptimizationEnvironment(result->environment()); | 2116 SetDeferredLazyDeoptimizationEnvironment(result->environment()); |
| 2096 instruction_pending_deoptimization_environment_ = NULL; | 2117 instruction_pending_deoptimization_environment_ = NULL; |
| 2097 pending_deoptimization_ast_id_ = BailoutId::None(); | 2118 pending_deoptimization_ast_id_ = BailoutId::None(); |
| 2098 return result; | 2119 return result; |
| 2099 } | 2120 } |
| 2100 | 2121 |
| 2101 return NULL; | 2122 return NULL; |
| 2102 } | 2123 } |
| 2103 | 2124 |
| 2104 | 2125 |
| 2105 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) { | |
| 2106 return AssignEnvironment(new(zone()) LDeoptimize); | |
| 2107 } | |
| 2108 | |
| 2109 | |
| 2110 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { | 2126 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
| 2111 if (instr->is_function_entry()) { | 2127 if (instr->is_function_entry()) { |
| 2112 return MarkAsCall(new(zone()) LStackCheck, instr); | 2128 return MarkAsCall(new(zone()) LStackCheck, instr); |
| 2113 } else { | 2129 } else { |
| 2114 ASSERT(instr->is_backwards_branch()); | 2130 ASSERT(instr->is_backwards_branch()); |
| 2115 return AssignEnvironment(AssignPointerMap(new(zone()) LStackCheck)); | 2131 return AssignEnvironment(AssignPointerMap(new(zone()) LStackCheck)); |
| 2116 } | 2132 } |
| 2117 } | 2133 } |
| 2118 | 2134 |
| 2119 | 2135 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2284 | 2300 |
| 2285 | 2301 |
| 2286 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { | 2302 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 2287 // TODO(all): This instruction doesn't exist anymore on bleeding_edge. | 2303 // TODO(all): This instruction doesn't exist anymore on bleeding_edge. |
| 2288 LOperand* string = UseRegisterAtStart(instr->value()); | 2304 LOperand* string = UseRegisterAtStart(instr->value()); |
| 2289 return DefineAsRegister(new(zone()) LStringLength(string)); | 2305 return DefineAsRegister(new(zone()) LStringLength(string)); |
| 2290 } | 2306 } |
| 2291 | 2307 |
| 2292 | 2308 |
| 2293 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 2309 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| 2310 // TODO(jbramley): Add smi support. |
| 2294 if (instr->representation().IsInteger32()) { | 2311 if (instr->representation().IsInteger32()) { |
| 2295 ASSERT(instr->left()->representation().IsInteger32()); | 2312 ASSERT(instr->left()->representation().IsInteger32()); |
| 2296 ASSERT(instr->right()->representation().IsInteger32()); | 2313 ASSERT(instr->right()->representation().IsInteger32()); |
| 2297 | 2314 |
| 2298 LOperand *left; | 2315 LOperand *left; |
| 2299 if (instr->left()->IsConstant() && | 2316 if (instr->left()->IsConstant() && |
| 2300 (HConstant::cast(instr->left())->Integer32Value() == 0)) { | 2317 (HConstant::cast(instr->left())->Integer32Value() == 0)) { |
| 2301 left = UseConstant(instr->left()); | 2318 left = UseConstant(instr->left()); |
| 2302 } else { | 2319 } else { |
| 2303 left = UseRegisterAtStart(instr->left()); | 2320 left = UseRegisterAtStart(instr->left()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2337 | 2354 |
| 2338 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { | 2355 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { |
| 2339 LOperand* object = UseFixed(instr->value(), x0); | 2356 LOperand* object = UseFixed(instr->value(), x0); |
| 2340 LToFastProperties* result = new(zone()) LToFastProperties(object); | 2357 LToFastProperties* result = new(zone()) LToFastProperties(object); |
| 2341 return MarkAsCall(DefineFixed(result, x0), instr); | 2358 return MarkAsCall(DefineFixed(result, x0), instr); |
| 2342 } | 2359 } |
| 2343 | 2360 |
| 2344 | 2361 |
| 2345 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2362 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
| 2346 HTransitionElementsKind* instr) { | 2363 HTransitionElementsKind* instr) { |
| 2364 LOperand* object = UseRegister(instr->object()); |
| 2347 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2365 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
| 2348 LOperand* object = UseRegister(instr->object()); | |
| 2349 LTransitionElementsKind* result = | 2366 LTransitionElementsKind* result = |
| 2350 new(zone()) LTransitionElementsKind(object, TempRegister(), | 2367 new(zone()) LTransitionElementsKind(object, TempRegister(), |
| 2351 TempRegister()); | 2368 TempRegister()); |
| 2352 return result; | 2369 return result; |
| 2353 } else if (FLAG_compiled_transitions) { | 2370 } else { |
| 2354 LOperand* object = UseRegister(instr->object()); | |
| 2355 LTransitionElementsKind* result = | 2371 LTransitionElementsKind* result = |
| 2356 new(zone()) LTransitionElementsKind(object, NULL, NULL); | 2372 new(zone()) LTransitionElementsKind(object, TempRegister()); |
| 2357 return AssignPointerMap(result); | 2373 return AssignPointerMap(result); |
| 2358 } else { | |
| 2359 LOperand* object = UseFixed(instr->object(), x0); | |
| 2360 LTransitionElementsKind* result = | |
| 2361 new(zone()) LTransitionElementsKind(object, NULL, NULL); | |
| 2362 return MarkAsCall(result, instr); | |
| 2363 } | 2374 } |
| 2364 } | 2375 } |
| 2365 | 2376 |
| 2366 | 2377 |
| 2367 LInstruction* LChunkBuilder::DoTrapAllocationMemento( | 2378 LInstruction* LChunkBuilder::DoTrapAllocationMemento( |
| 2368 HTrapAllocationMemento* instr) { | 2379 HTrapAllocationMemento* instr) { |
| 2369 LOperand* object = UseRegister(instr->object()); | 2380 LOperand* object = UseRegister(instr->object()); |
| 2370 LOperand* temp1 = TempRegister(); | 2381 LOperand* temp1 = TempRegister(); |
| 2371 LOperand* temp2 = TempRegister(); | 2382 LOperand* temp2 = TempRegister(); |
| 2372 LTrapAllocationMemento* result = | 2383 LTrapAllocationMemento* result = |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2559 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { | 2570 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { |
| 2560 LOperand* receiver = UseRegister(instr->receiver()); | 2571 LOperand* receiver = UseRegister(instr->receiver()); |
| 2561 LOperand* function = UseRegisterAtStart(instr->function()); | 2572 LOperand* function = UseRegisterAtStart(instr->function()); |
| 2562 LOperand* temp = TempRegister(); | 2573 LOperand* temp = TempRegister(); |
| 2563 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function, temp); | 2574 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function, temp); |
| 2564 return AssignEnvironment(DefineAsRegister(result)); | 2575 return AssignEnvironment(DefineAsRegister(result)); |
| 2565 } | 2576 } |
| 2566 | 2577 |
| 2567 | 2578 |
| 2568 } } // namespace v8::internal | 2579 } } // namespace v8::internal |
| OLD | NEW |