OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 // we now know they test equal. | 978 // we now know they test equal. |
979 if (cc != eq || !never_nan_nan) { | 979 if (cc != eq || !never_nan_nan) { |
980 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | 980 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); |
981 | 981 |
982 // Test for NaN. Sadly, we can't just compare to factory->nan_value(), | 982 // Test for NaN. Sadly, we can't just compare to factory->nan_value(), |
983 // so we do the second best thing - test it ourselves. | 983 // so we do the second best thing - test it ourselves. |
984 // They are both equal and they are not both Smis so both of them are not | 984 // They are both equal and they are not both Smis so both of them are not |
985 // Smis. If it's not a heap number, then return equal. | 985 // Smis. If it's not a heap number, then return equal. |
986 if (cc == less || cc == greater) { | 986 if (cc == less || cc == greater) { |
987 __ GetObjectType(a0, t4, t4); | 987 __ GetObjectType(a0, t4, t4); |
988 __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE)); | 988 __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE)); |
989 } else { | 989 } else { |
990 __ GetObjectType(a0, t4, t4); | 990 __ GetObjectType(a0, t4, t4); |
991 __ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE)); | 991 __ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE)); |
992 // Comparing JS objects with <=, >= is complicated. | 992 // Comparing JS objects with <=, >= is complicated. |
993 if (cc != eq) { | 993 if (cc != eq) { |
994 __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE)); | 994 __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE)); |
995 // Normally here we fall through to return_equal, but undefined is | 995 // Normally here we fall through to return_equal, but undefined is |
996 // special: (undefined == undefined) == true, but | 996 // special: (undefined == undefined) == true, but |
997 // (undefined <= undefined) == false! See ECMAScript 11.8.5. | 997 // (undefined <= undefined) == false! See ECMAScript 11.8.5. |
998 if (cc == less_equal || cc == greater_equal) { | 998 if (cc == less_equal || cc == greater_equal) { |
999 __ Branch(&return_equal, ne, t4, Operand(ODDBALL_TYPE)); | 999 __ Branch(&return_equal, ne, t4, Operand(ODDBALL_TYPE)); |
1000 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); | 1000 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); |
1001 __ Branch(&return_equal, ne, a0, Operand(t2)); | 1001 __ Branch(&return_equal, ne, a0, Operand(t2)); |
1002 if (cc == le) { | 1002 if (cc == le) { |
1003 // undefined <= undefined should fail. | 1003 // undefined <= undefined should fail. |
1004 __ li(v0, Operand(GREATER)); | 1004 __ li(v0, Operand(GREATER)); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 __ bind(&less_than); | 1302 __ bind(&less_than); |
1303 __ li(v0, Operand(LESS)); | 1303 __ li(v0, Operand(LESS)); |
1304 __ Ret(); | 1304 __ Ret(); |
1305 } | 1305 } |
1306 } | 1306 } |
1307 | 1307 |
1308 | 1308 |
1309 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, | 1309 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, |
1310 Register lhs, | 1310 Register lhs, |
1311 Register rhs) { | 1311 Register rhs) { |
1312 // If either operand is a JSObject or an oddball value, then they are | 1312 // If either operand is a JS object or an oddball value, then they are |
1313 // not equal since their pointers are different. | 1313 // not equal since their pointers are different. |
1314 // There is no test for undetectability in strict equality. | 1314 // There is no test for undetectability in strict equality. |
1315 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 1315 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE); |
1316 Label first_non_object; | 1316 Label first_non_object; |
1317 // Get the type of the first operand into a2 and compare it with | 1317 // Get the type of the first operand into a2 and compare it with |
1318 // FIRST_JS_OBJECT_TYPE. | 1318 // FIRST_SPEC_OBJECT_TYPE. |
1319 __ GetObjectType(lhs, a2, a2); | 1319 __ GetObjectType(lhs, a2, a2); |
1320 __ Branch(&first_non_object, less, a2, Operand(FIRST_JS_OBJECT_TYPE)); | 1320 __ Branch(&first_non_object, less, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); |
1321 | 1321 |
1322 // Return non-zero. | 1322 // Return non-zero. |
1323 Label return_not_equal; | 1323 Label return_not_equal; |
1324 __ bind(&return_not_equal); | 1324 __ bind(&return_not_equal); |
1325 __ li(v0, Operand(1)); | 1325 __ li(v0, Operand(1)); |
1326 __ Ret(); | 1326 __ Ret(); |
1327 | 1327 |
1328 __ bind(&first_non_object); | 1328 __ bind(&first_non_object); |
1329 // Check for oddballs: true, false, null, undefined. | 1329 // Check for oddballs: true, false, null, undefined. |
1330 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); | 1330 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); |
1331 | 1331 |
1332 __ GetObjectType(rhs, a3, a3); | 1332 __ GetObjectType(rhs, a3, a3); |
1333 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_JS_OBJECT_TYPE)); | 1333 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); |
1334 | 1334 |
1335 // Check for oddballs: true, false, null, undefined. | 1335 // Check for oddballs: true, false, null, undefined. |
1336 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); | 1336 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); |
1337 | 1337 |
1338 // Now that we have the types we might as well check for symbol-symbol. | 1338 // Now that we have the types we might as well check for symbol-symbol. |
1339 // Ensure that no non-strings have the symbol bit set. | 1339 // Ensure that no non-strings have the symbol bit set. |
1340 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsSymbolMask); | 1340 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsSymbolMask); |
1341 STATIC_ASSERT(kSymbolTag != 0); | 1341 STATIC_ASSERT(kSymbolTag != 0); |
1342 __ And(t2, a2, Operand(a3)); | 1342 __ And(t2, a2, Operand(a3)); |
1343 __ And(t0, t2, Operand(kIsSymbolMask)); | 1343 __ And(t0, t2, Operand(kIsSymbolMask)); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1399 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); | 1399 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); |
1400 __ And(at, a3, Operand(kIsSymbolMask)); | 1400 __ And(at, a3, Operand(kIsSymbolMask)); |
1401 __ Branch(possible_strings, eq, at, Operand(zero_reg)); | 1401 __ Branch(possible_strings, eq, at, Operand(zero_reg)); |
1402 | 1402 |
1403 // Both are symbols. We already checked they weren't the same pointer | 1403 // Both are symbols. We already checked they weren't the same pointer |
1404 // so they are not equal. | 1404 // so they are not equal. |
1405 __ li(v0, Operand(1)); // Non-zero indicates not equal. | 1405 __ li(v0, Operand(1)); // Non-zero indicates not equal. |
1406 __ Ret(); | 1406 __ Ret(); |
1407 | 1407 |
1408 __ bind(&object_test); | 1408 __ bind(&object_test); |
1409 __ Branch(not_both_strings, lt, a2, Operand(FIRST_JS_OBJECT_TYPE)); | 1409 __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); |
1410 __ GetObjectType(rhs, a2, a3); | 1410 __ GetObjectType(rhs, a2, a3); |
1411 __ Branch(not_both_strings, lt, a3, Operand(FIRST_JS_OBJECT_TYPE)); | 1411 __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); |
1412 | 1412 |
1413 // If both objects are undetectable, they are equal. Otherwise, they | 1413 // If both objects are undetectable, they are equal. Otherwise, they |
1414 // are not equal, since they are different objects and an object is not | 1414 // are not equal, since they are different objects and an object is not |
1415 // equal to undefined. | 1415 // equal to undefined. |
1416 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); | 1416 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
1417 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); | 1417 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); |
1418 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); | 1418 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); |
1419 __ and_(a0, a2, a3); | 1419 __ and_(a0, a2, a3); |
1420 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); | 1420 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); |
1421 __ Xor(v0, a0, Operand(1 << Map::kIsUndetectable)); | 1421 __ Xor(v0, a0, Operand(1 << Map::kIsUndetectable)); |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 __ And(scratch0, scratch0, Operand(1 << Map::kIsUndetectable)); | 1777 __ And(scratch0, scratch0, Operand(1 << Map::kIsUndetectable)); |
1778 __ Branch(&false_result, eq, scratch0, Operand(1 << Map::kIsUndetectable)); | 1778 __ Branch(&false_result, eq, scratch0, Operand(1 << Map::kIsUndetectable)); |
1779 | 1779 |
1780 // JavaScript object => true. | 1780 // JavaScript object => true. |
1781 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); | 1781 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); |
1782 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); | 1782 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); |
1783 | 1783 |
1784 // "tos_" is a register and contains a non-zero value. | 1784 // "tos_" is a register and contains a non-zero value. |
1785 // Hence we implicitly return true if the greater than | 1785 // Hence we implicitly return true if the greater than |
1786 // condition is satisfied. | 1786 // condition is satisfied. |
1787 __ Ret(gt, scratch0, Operand(FIRST_JS_OBJECT_TYPE)); | 1787 __ Ret(gt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); |
1788 | 1788 |
1789 // Check for string. | 1789 // Check for string. |
1790 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); | 1790 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); |
1791 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); | 1791 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); |
1792 // "tos_" is a register and contains a non-zero value. | 1792 // "tos_" is a register and contains a non-zero value. |
1793 // Hence we implicitly return true if the greater than | 1793 // Hence we implicitly return true if the greater than |
1794 // condition is satisfied. | 1794 // condition is satisfied. |
1795 __ Ret(gt, scratch0, Operand(FIRST_NONSTRING_TYPE)); | 1795 __ Ret(gt, scratch0, Operand(FIRST_NONSTRING_TYPE)); |
1796 | 1796 |
1797 // String value => false iff empty, i.e., length is zero. | 1797 // String value => false iff empty, i.e., length is zero. |
(...skipping 4871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6669 __ mov(result, zero_reg); | 6669 __ mov(result, zero_reg); |
6670 __ Ret(); | 6670 __ Ret(); |
6671 } | 6671 } |
6672 | 6672 |
6673 | 6673 |
6674 #undef __ | 6674 #undef __ |
6675 | 6675 |
6676 } } // namespace v8::internal | 6676 } } // namespace v8::internal |
6677 | 6677 |
6678 #endif // V8_TARGET_ARCH_MIPS | 6678 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |