| 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 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 // Save FCSR. | 665 // Save FCSR. |
| 666 __ cfc1(scratch1, FCSR); | 666 __ cfc1(scratch1, FCSR); |
| 667 // Disable FPU exceptions. | 667 // Disable FPU exceptions. |
| 668 __ ctc1(zero_reg, FCSR); | 668 __ ctc1(zero_reg, FCSR); |
| 669 __ trunc_w_d(single_scratch, double_dst); | 669 __ trunc_w_d(single_scratch, double_dst); |
| 670 // Retrieve FCSR. | 670 // Retrieve FCSR. |
| 671 __ cfc1(scratch2, FCSR); | 671 __ cfc1(scratch2, FCSR); |
| 672 // Restore FCSR. | 672 // Restore FCSR. |
| 673 __ ctc1(scratch1, FCSR); | 673 __ ctc1(scratch1, FCSR); |
| 674 | 674 |
| 675 // Check for inexact conversion. | 675 // Check for inexact conversion or exception. |
| 676 __ srl(scratch2, scratch2, kFCSRFlagShift); | 676 __ And(scratch2, scratch2, kFCSRFlagMask); |
| 677 __ And(scratch2, scratch2, (kFCSRFlagMask | kFCSRInexactFlagBit)); | |
| 678 | 677 |
| 679 // Jump to not_int32 if the operation did not succeed. | 678 // Jump to not_int32 if the operation did not succeed. |
| 680 __ Branch(not_int32, ne, scratch2, Operand(zero_reg)); | 679 __ Branch(not_int32, ne, scratch2, Operand(zero_reg)); |
| 681 | 680 |
| 682 if (destination == kCoreRegisters) { | 681 if (destination == kCoreRegisters) { |
| 683 __ Move(dst1, dst2, double_dst); | 682 __ Move(dst1, dst2, double_dst); |
| 684 } | 683 } |
| 685 | 684 |
| 686 } else { | 685 } else { |
| 687 ASSERT(!scratch1.is(object) && !scratch2.is(object)); | 686 ASSERT(!scratch1.is(object) && !scratch2.is(object)); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 // Save FCSR. | 749 // Save FCSR. |
| 751 __ cfc1(scratch1, FCSR); | 750 __ cfc1(scratch1, FCSR); |
| 752 // Disable FPU exceptions. | 751 // Disable FPU exceptions. |
| 753 __ ctc1(zero_reg, FCSR); | 752 __ ctc1(zero_reg, FCSR); |
| 754 __ trunc_w_d(double_scratch, double_scratch); | 753 __ trunc_w_d(double_scratch, double_scratch); |
| 755 // Retrieve FCSR. | 754 // Retrieve FCSR. |
| 756 __ cfc1(scratch2, FCSR); | 755 __ cfc1(scratch2, FCSR); |
| 757 // Restore FCSR. | 756 // Restore FCSR. |
| 758 __ ctc1(scratch1, FCSR); | 757 __ ctc1(scratch1, FCSR); |
| 759 | 758 |
| 760 // Check for inexact conversion. | 759 // Check for inexact conversion or exception. |
| 761 __ srl(scratch2, scratch2, kFCSRFlagShift); | 760 __ And(scratch2, scratch2, kFCSRFlagMask); |
| 762 __ And(scratch2, scratch2, (kFCSRFlagMask | kFCSRInexactFlagBit)); | |
| 763 | 761 |
| 764 // Jump to not_int32 if the operation did not succeed. | 762 // Jump to not_int32 if the operation did not succeed. |
| 765 __ Branch(not_int32, ne, scratch2, Operand(zero_reg)); | 763 __ Branch(not_int32, ne, scratch2, Operand(zero_reg)); |
| 766 // Get the result in the destination register. | 764 // Get the result in the destination register. |
| 767 __ mfc1(dst, double_scratch); | 765 __ mfc1(dst, double_scratch); |
| 768 | 766 |
| 769 } else { | 767 } else { |
| 770 // Load the double value in the destination registers. | 768 // Load the double value in the destination registers. |
| 771 __ lw(scratch2, FieldMemOperand(object, HeapNumber::kExponentOffset)); | 769 __ lw(scratch2, FieldMemOperand(object, HeapNumber::kExponentOffset)); |
| 772 __ lw(scratch1, FieldMemOperand(object, HeapNumber::kMantissaOffset)); | 770 __ lw(scratch1, FieldMemOperand(object, HeapNumber::kMantissaOffset)); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 // we now know they test equal. | 976 // we now know they test equal. |
| 979 if (cc != eq || !never_nan_nan) { | 977 if (cc != eq || !never_nan_nan) { |
| 980 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); | 978 __ li(exp_mask_reg, Operand(HeapNumber::kExponentMask)); |
| 981 | 979 |
| 982 // Test for NaN. Sadly, we can't just compare to factory->nan_value(), | 980 // Test for NaN. Sadly, we can't just compare to factory->nan_value(), |
| 983 // so we do the second best thing - test it ourselves. | 981 // 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 | 982 // 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. | 983 // Smis. If it's not a heap number, then return equal. |
| 986 if (cc == less || cc == greater) { | 984 if (cc == less || cc == greater) { |
| 987 __ GetObjectType(a0, t4, t4); | 985 __ GetObjectType(a0, t4, t4); |
| 988 __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE)); | 986 __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 989 } else { | 987 } else { |
| 990 __ GetObjectType(a0, t4, t4); | 988 __ GetObjectType(a0, t4, t4); |
| 991 __ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE)); | 989 __ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE)); |
| 992 // Comparing JS objects with <=, >= is complicated. | 990 // Comparing JS objects with <=, >= is complicated. |
| 993 if (cc != eq) { | 991 if (cc != eq) { |
| 994 __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE)); | 992 __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 995 // Normally here we fall through to return_equal, but undefined is | 993 // Normally here we fall through to return_equal, but undefined is |
| 996 // special: (undefined == undefined) == true, but | 994 // special: (undefined == undefined) == true, but |
| 997 // (undefined <= undefined) == false! See ECMAScript 11.8.5. | 995 // (undefined <= undefined) == false! See ECMAScript 11.8.5. |
| 998 if (cc == less_equal || cc == greater_equal) { | 996 if (cc == less_equal || cc == greater_equal) { |
| 999 __ Branch(&return_equal, ne, t4, Operand(ODDBALL_TYPE)); | 997 __ Branch(&return_equal, ne, t4, Operand(ODDBALL_TYPE)); |
| 1000 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); | 998 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); |
| 1001 __ Branch(&return_equal, ne, a0, Operand(t2)); | 999 __ Branch(&return_equal, ne, a0, Operand(t2)); |
| 1002 if (cc == le) { | 1000 if (cc == le) { |
| 1003 // undefined <= undefined should fail. | 1001 // undefined <= undefined should fail. |
| 1004 __ li(v0, Operand(GREATER)); | 1002 __ li(v0, Operand(GREATER)); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 __ bind(&less_than); | 1300 __ bind(&less_than); |
| 1303 __ li(v0, Operand(LESS)); | 1301 __ li(v0, Operand(LESS)); |
| 1304 __ Ret(); | 1302 __ Ret(); |
| 1305 } | 1303 } |
| 1306 } | 1304 } |
| 1307 | 1305 |
| 1308 | 1306 |
| 1309 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, | 1307 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, |
| 1310 Register lhs, | 1308 Register lhs, |
| 1311 Register rhs) { | 1309 Register rhs) { |
| 1312 // If either operand is a JSObject or an oddball value, then they are | 1310 // If either operand is a JS object or an oddball value, then they are |
| 1313 // not equal since their pointers are different. | 1311 // not equal since their pointers are different. |
| 1314 // There is no test for undetectability in strict equality. | 1312 // There is no test for undetectability in strict equality. |
| 1315 STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); | 1313 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE); |
| 1316 Label first_non_object; | 1314 Label first_non_object; |
| 1317 // Get the type of the first operand into a2 and compare it with | 1315 // Get the type of the first operand into a2 and compare it with |
| 1318 // FIRST_JS_OBJECT_TYPE. | 1316 // FIRST_SPEC_OBJECT_TYPE. |
| 1319 __ GetObjectType(lhs, a2, a2); | 1317 __ GetObjectType(lhs, a2, a2); |
| 1320 __ Branch(&first_non_object, less, a2, Operand(FIRST_JS_OBJECT_TYPE)); | 1318 __ Branch(&first_non_object, less, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 1321 | 1319 |
| 1322 // Return non-zero. | 1320 // Return non-zero. |
| 1323 Label return_not_equal; | 1321 Label return_not_equal; |
| 1324 __ bind(&return_not_equal); | 1322 __ bind(&return_not_equal); |
| 1325 __ li(v0, Operand(1)); | 1323 __ li(v0, Operand(1)); |
| 1326 __ Ret(); | 1324 __ Ret(); |
| 1327 | 1325 |
| 1328 __ bind(&first_non_object); | 1326 __ bind(&first_non_object); |
| 1329 // Check for oddballs: true, false, null, undefined. | 1327 // Check for oddballs: true, false, null, undefined. |
| 1330 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); | 1328 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); |
| 1331 | 1329 |
| 1332 __ GetObjectType(rhs, a3, a3); | 1330 __ GetObjectType(rhs, a3, a3); |
| 1333 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_JS_OBJECT_TYPE)); | 1331 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 1334 | 1332 |
| 1335 // Check for oddballs: true, false, null, undefined. | 1333 // Check for oddballs: true, false, null, undefined. |
| 1336 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); | 1334 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); |
| 1337 | 1335 |
| 1338 // Now that we have the types we might as well check for symbol-symbol. | 1336 // 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. | 1337 // Ensure that no non-strings have the symbol bit set. |
| 1340 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsSymbolMask); | 1338 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsSymbolMask); |
| 1341 STATIC_ASSERT(kSymbolTag != 0); | 1339 STATIC_ASSERT(kSymbolTag != 0); |
| 1342 __ And(t2, a2, Operand(a3)); | 1340 __ And(t2, a2, Operand(a3)); |
| 1343 __ And(t0, t2, Operand(kIsSymbolMask)); | 1341 __ 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)); | 1397 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); |
| 1400 __ And(at, a3, Operand(kIsSymbolMask)); | 1398 __ And(at, a3, Operand(kIsSymbolMask)); |
| 1401 __ Branch(possible_strings, eq, at, Operand(zero_reg)); | 1399 __ Branch(possible_strings, eq, at, Operand(zero_reg)); |
| 1402 | 1400 |
| 1403 // Both are symbols. We already checked they weren't the same pointer | 1401 // Both are symbols. We already checked they weren't the same pointer |
| 1404 // so they are not equal. | 1402 // so they are not equal. |
| 1405 __ li(v0, Operand(1)); // Non-zero indicates not equal. | 1403 __ li(v0, Operand(1)); // Non-zero indicates not equal. |
| 1406 __ Ret(); | 1404 __ Ret(); |
| 1407 | 1405 |
| 1408 __ bind(&object_test); | 1406 __ bind(&object_test); |
| 1409 __ Branch(not_both_strings, lt, a2, Operand(FIRST_JS_OBJECT_TYPE)); | 1407 __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 1410 __ GetObjectType(rhs, a2, a3); | 1408 __ GetObjectType(rhs, a2, a3); |
| 1411 __ Branch(not_both_strings, lt, a3, Operand(FIRST_JS_OBJECT_TYPE)); | 1409 __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 1412 | 1410 |
| 1413 // If both objects are undetectable, they are equal. Otherwise, they | 1411 // If both objects are undetectable, they are equal. Otherwise, they |
| 1414 // are not equal, since they are different objects and an object is not | 1412 // are not equal, since they are different objects and an object is not |
| 1415 // equal to undefined. | 1413 // equal to undefined. |
| 1416 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); | 1414 __ lw(a3, FieldMemOperand(lhs, HeapObject::kMapOffset)); |
| 1417 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); | 1415 __ lbu(a2, FieldMemOperand(a2, Map::kBitFieldOffset)); |
| 1418 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); | 1416 __ lbu(a3, FieldMemOperand(a3, Map::kBitFieldOffset)); |
| 1419 __ and_(a0, a2, a3); | 1417 __ and_(a0, a2, a3); |
| 1420 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); | 1418 __ And(a0, a0, Operand(1 << Map::kIsUndetectable)); |
| 1421 __ Xor(v0, a0, Operand(1 << Map::kIsUndetectable)); | 1419 __ 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)); | 1775 __ And(scratch0, scratch0, Operand(1 << Map::kIsUndetectable)); |
| 1778 __ Branch(&false_result, eq, scratch0, Operand(1 << Map::kIsUndetectable)); | 1776 __ Branch(&false_result, eq, scratch0, Operand(1 << Map::kIsUndetectable)); |
| 1779 | 1777 |
| 1780 // JavaScript object => true. | 1778 // JavaScript object => true. |
| 1781 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); | 1779 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); |
| 1782 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); | 1780 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); |
| 1783 | 1781 |
| 1784 // "tos_" is a register and contains a non-zero value. | 1782 // "tos_" is a register and contains a non-zero value. |
| 1785 // Hence we implicitly return true if the greater than | 1783 // Hence we implicitly return true if the greater than |
| 1786 // condition is satisfied. | 1784 // condition is satisfied. |
| 1787 __ Ret(gt, scratch0, Operand(FIRST_JS_OBJECT_TYPE)); | 1785 __ Ret(gt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); |
| 1788 | 1786 |
| 1789 // Check for string. | 1787 // Check for string. |
| 1790 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); | 1788 __ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset)); |
| 1791 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); | 1789 __ lbu(scratch0, FieldMemOperand(scratch0, Map::kInstanceTypeOffset)); |
| 1792 // "tos_" is a register and contains a non-zero value. | 1790 // "tos_" is a register and contains a non-zero value. |
| 1793 // Hence we implicitly return true if the greater than | 1791 // Hence we implicitly return true if the greater than |
| 1794 // condition is satisfied. | 1792 // condition is satisfied. |
| 1795 __ Ret(gt, scratch0, Operand(FIRST_NONSTRING_TYPE)); | 1793 __ Ret(gt, scratch0, Operand(FIRST_NONSTRING_TYPE)); |
| 1796 | 1794 |
| 1797 // String value => false iff empty, i.e., length is zero. | 1795 // String value => false iff empty, i.e., length is zero. |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1959 | 1957 |
| 1960 void UnaryOpStub::GenerateHeapNumberStubBitNot(MacroAssembler* masm) { | 1958 void UnaryOpStub::GenerateHeapNumberStubBitNot(MacroAssembler* masm) { |
| 1961 Label non_smi, slow; | 1959 Label non_smi, slow; |
| 1962 GenerateSmiCodeBitNot(masm, &non_smi); | 1960 GenerateSmiCodeBitNot(masm, &non_smi); |
| 1963 __ bind(&non_smi); | 1961 __ bind(&non_smi); |
| 1964 GenerateHeapNumberCodeBitNot(masm, &slow); | 1962 GenerateHeapNumberCodeBitNot(masm, &slow); |
| 1965 __ bind(&slow); | 1963 __ bind(&slow); |
| 1966 GenerateTypeTransition(masm); | 1964 GenerateTypeTransition(masm); |
| 1967 } | 1965 } |
| 1968 | 1966 |
| 1967 |
| 1969 void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm, | 1968 void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm, |
| 1970 Label* slow) { | 1969 Label* slow) { |
| 1971 EmitCheckForHeapNumber(masm, a0, a1, t2, slow); | 1970 EmitCheckForHeapNumber(masm, a0, a1, t2, slow); |
| 1972 // a0 is a heap number. Get a new heap number in a1. | 1971 // a0 is a heap number. Get a new heap number in a1. |
| 1973 if (mode_ == UNARY_OVERWRITE) { | 1972 if (mode_ == UNARY_OVERWRITE) { |
| 1974 __ lw(a2, FieldMemOperand(a0, HeapNumber::kExponentOffset)); | 1973 __ lw(a2, FieldMemOperand(a0, HeapNumber::kExponentOffset)); |
| 1975 __ Xor(a2, a2, Operand(HeapNumber::kSignMask)); // Flip sign. | 1974 __ Xor(a2, a2, Operand(HeapNumber::kSignMask)); // Flip sign. |
| 1976 __ sw(a2, FieldMemOperand(a0, HeapNumber::kExponentOffset)); | 1975 __ sw(a2, FieldMemOperand(a0, HeapNumber::kExponentOffset)); |
| 1977 } else { | 1976 } else { |
| 1978 Label slow_allocate_heapnumber, heapnumber_allocated; | 1977 Label slow_allocate_heapnumber, heapnumber_allocated; |
| (...skipping 791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2770 // Save FCSR. | 2769 // Save FCSR. |
| 2771 __ cfc1(scratch1, FCSR); | 2770 __ cfc1(scratch1, FCSR); |
| 2772 // Disable FPU exceptions. | 2771 // Disable FPU exceptions. |
| 2773 __ ctc1(zero_reg, FCSR); | 2772 __ ctc1(zero_reg, FCSR); |
| 2774 __ trunc_w_d(single_scratch, f10); | 2773 __ trunc_w_d(single_scratch, f10); |
| 2775 // Retrieve FCSR. | 2774 // Retrieve FCSR. |
| 2776 __ cfc1(scratch2, FCSR); | 2775 __ cfc1(scratch2, FCSR); |
| 2777 // Restore FCSR. | 2776 // Restore FCSR. |
| 2778 __ ctc1(scratch1, FCSR); | 2777 __ ctc1(scratch1, FCSR); |
| 2779 | 2778 |
| 2780 // Check for inexact conversion. | 2779 // Check for inexact conversion or exception. |
| 2781 __ srl(scratch2, scratch2, kFCSRFlagShift); | |
| 2782 __ And(scratch2, scratch2, kFCSRFlagMask); | 2780 __ And(scratch2, scratch2, kFCSRFlagMask); |
| 2783 | 2781 |
| 2784 if (result_type_ <= BinaryOpIC::INT32) { | 2782 if (result_type_ <= BinaryOpIC::INT32) { |
| 2785 // If scratch2 != 0, result does not fit in a 32-bit integer. | 2783 // If scratch2 != 0, result does not fit in a 32-bit integer. |
| 2786 __ Branch(&transition, ne, scratch2, Operand(zero_reg)); | 2784 __ Branch(&transition, ne, scratch2, Operand(zero_reg)); |
| 2787 } | 2785 } |
| 2788 | 2786 |
| 2789 // Check if the result fits in a smi. | 2787 // Check if the result fits in a smi. |
| 2790 __ mfc1(scratch1, single_scratch); | 2788 __ mfc1(scratch1, single_scratch); |
| 2791 __ Addu(scratch2, scratch1, Operand(0x40000000)); | 2789 __ Addu(scratch2, scratch1, Operand(0x40000000)); |
| (...skipping 1911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4703 __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE)); | 4701 __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE)); |
| 4704 | 4702 |
| 4705 // Fast-case: Invoke the function now. | 4703 // Fast-case: Invoke the function now. |
| 4706 // a1: pushed function | 4704 // a1: pushed function |
| 4707 ParameterCount actual(argc_); | 4705 ParameterCount actual(argc_); |
| 4708 | 4706 |
| 4709 if (ReceiverMightBeImplicit()) { | 4707 if (ReceiverMightBeImplicit()) { |
| 4710 Label call_as_function; | 4708 Label call_as_function; |
| 4711 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 4709 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 4712 __ Branch(&call_as_function, eq, t0, Operand(at)); | 4710 __ Branch(&call_as_function, eq, t0, Operand(at)); |
| 4713 __ InvokeFunction(a1, actual, JUMP_FUNCTION); | 4711 __ InvokeFunction(a1, |
| 4712 actual, |
| 4713 JUMP_FUNCTION, |
| 4714 NullCallWrapper(), |
| 4715 CALL_AS_METHOD); |
| 4714 __ bind(&call_as_function); | 4716 __ bind(&call_as_function); |
| 4715 } | 4717 } |
| 4716 __ InvokeFunction(a1, | 4718 __ InvokeFunction(a1, |
| 4717 actual, | 4719 actual, |
| 4718 JUMP_FUNCTION, | 4720 JUMP_FUNCTION, |
| 4719 NullCallWrapper(), | 4721 NullCallWrapper(), |
| 4720 CALL_AS_FUNCTION); | 4722 CALL_AS_FUNCTION); |
| 4721 | 4723 |
| 4722 // Slow-case: Non-function called. | 4724 // Slow-case: Non-function called. |
| 4723 __ bind(&slow); | 4725 __ bind(&slow); |
| (...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6363 __ LeaveInternalFrame(); | 6365 __ LeaveInternalFrame(); |
| 6364 // Compute the entry point of the rewritten stub. | 6366 // Compute the entry point of the rewritten stub. |
| 6365 __ Addu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 6367 __ Addu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 6366 // Restore registers. | 6368 // Restore registers. |
| 6367 __ pop(ra); | 6369 __ pop(ra); |
| 6368 __ pop(a0); | 6370 __ pop(a0); |
| 6369 __ pop(a1); | 6371 __ pop(a1); |
| 6370 __ Jump(a2); | 6372 __ Jump(a2); |
| 6371 } | 6373 } |
| 6372 | 6374 |
| 6375 |
| 6373 void DirectCEntryStub::Generate(MacroAssembler* masm) { | 6376 void DirectCEntryStub::Generate(MacroAssembler* masm) { |
| 6374 // No need to pop or drop anything, LeaveExitFrame will restore the old | 6377 // No need to pop or drop anything, LeaveExitFrame will restore the old |
| 6375 // stack, thus dropping the allocated space for the return value. | 6378 // stack, thus dropping the allocated space for the return value. |
| 6376 // The saved ra is after the reserved stack space for the 4 args. | 6379 // The saved ra is after the reserved stack space for the 4 args. |
| 6377 __ lw(t9, MemOperand(sp, kCArgsSlotsSize)); | 6380 __ lw(t9, MemOperand(sp, kCArgsSlotsSize)); |
| 6378 | 6381 |
| 6379 if (FLAG_debug_code && EnableSlowAsserts()) { | 6382 if (FLAG_debug_code && EnableSlowAsserts()) { |
| 6380 // In case of an error the return address may point to a memory area | 6383 // In case of an error the return address may point to a memory area |
| 6381 // filled with kZapValue by the GC. | 6384 // filled with kZapValue by the GC. |
| 6382 // Dereference the address and check for this. | 6385 // Dereference the address and check for this. |
| 6383 __ lw(t0, MemOperand(t9)); | 6386 __ lw(t0, MemOperand(t9)); |
| 6384 __ Assert(ne, "Received invalid return address.", t0, | 6387 __ Assert(ne, "Received invalid return address.", t0, |
| 6385 Operand(reinterpret_cast<uint32_t>(kZapValue))); | 6388 Operand(reinterpret_cast<uint32_t>(kZapValue))); |
| 6386 } | 6389 } |
| 6387 __ Jump(t9); | 6390 __ Jump(t9); |
| 6388 } | 6391 } |
| 6389 | 6392 |
| 6390 | 6393 |
| 6391 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, | 6394 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, |
| 6392 ExternalReference function) { | 6395 ExternalReference function) { |
| 6393 __ li(t9, Operand(function)); | 6396 __ li(t9, Operand(function)); |
| 6394 this->GenerateCall(masm, t9); | 6397 this->GenerateCall(masm, t9); |
| 6395 } | 6398 } |
| 6396 | 6399 |
| 6400 |
| 6397 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, | 6401 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, |
| 6398 Register target) { | 6402 Register target) { |
| 6399 __ Move(t9, target); | 6403 __ Move(t9, target); |
| 6400 __ AssertStackIsAligned(); | 6404 __ AssertStackIsAligned(); |
| 6401 // Allocate space for arg slots. | 6405 // Allocate space for arg slots. |
| 6402 __ Subu(sp, sp, kCArgsSlotsSize); | 6406 __ Subu(sp, sp, kCArgsSlotsSize); |
| 6403 | 6407 |
| 6404 // Block the trampoline pool through the whole function to make sure the | 6408 // Block the trampoline pool through the whole function to make sure the |
| 6405 // number of generated instructions is constant. | 6409 // number of generated instructions is constant. |
| 6406 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); | 6410 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6665 __ mov(result, zero_reg); | 6669 __ mov(result, zero_reg); |
| 6666 __ Ret(); | 6670 __ Ret(); |
| 6667 } | 6671 } |
| 6668 | 6672 |
| 6669 | 6673 |
| 6670 #undef __ | 6674 #undef __ |
| 6671 | 6675 |
| 6672 } } // namespace v8::internal | 6676 } } // namespace v8::internal |
| 6673 | 6677 |
| 6674 #endif // V8_TARGET_ARCH_MIPS | 6678 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |