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 |