| 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 1186 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 3575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6367 __ LeaveInternalFrame(); | 6365 __ LeaveInternalFrame(); |
| 6368 // Compute the entry point of the rewritten stub. | 6366 // Compute the entry point of the rewritten stub. |
| 6369 __ Addu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 6367 __ Addu(a2, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 6370 // Restore registers. | 6368 // Restore registers. |
| 6371 __ pop(ra); | 6369 __ pop(ra); |
| 6372 __ pop(a0); | 6370 __ pop(a0); |
| 6373 __ pop(a1); | 6371 __ pop(a1); |
| 6374 __ Jump(a2); | 6372 __ Jump(a2); |
| 6375 } | 6373 } |
| 6376 | 6374 |
| 6375 |
| 6377 void DirectCEntryStub::Generate(MacroAssembler* masm) { | 6376 void DirectCEntryStub::Generate(MacroAssembler* masm) { |
| 6378 // 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 |
| 6379 // stack, thus dropping the allocated space for the return value. | 6378 // stack, thus dropping the allocated space for the return value. |
| 6380 // 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. |
| 6381 __ lw(t9, MemOperand(sp, kCArgsSlotsSize)); | 6380 __ lw(t9, MemOperand(sp, kCArgsSlotsSize)); |
| 6382 | 6381 |
| 6383 if (FLAG_debug_code && EnableSlowAsserts()) { | 6382 if (FLAG_debug_code && EnableSlowAsserts()) { |
| 6384 // 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 |
| 6385 // filled with kZapValue by the GC. | 6384 // filled with kZapValue by the GC. |
| 6386 // Dereference the address and check for this. | 6385 // Dereference the address and check for this. |
| 6387 __ lw(t0, MemOperand(t9)); | 6386 __ lw(t0, MemOperand(t9)); |
| 6388 __ Assert(ne, "Received invalid return address.", t0, | 6387 __ Assert(ne, "Received invalid return address.", t0, |
| 6389 Operand(reinterpret_cast<uint32_t>(kZapValue))); | 6388 Operand(reinterpret_cast<uint32_t>(kZapValue))); |
| 6390 } | 6389 } |
| 6391 __ Jump(t9); | 6390 __ Jump(t9); |
| 6392 } | 6391 } |
| 6393 | 6392 |
| 6394 | 6393 |
| 6395 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, | 6394 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, |
| 6396 ExternalReference function) { | 6395 ExternalReference function) { |
| 6397 __ li(t9, Operand(function)); | 6396 __ li(t9, Operand(function)); |
| 6398 this->GenerateCall(masm, t9); | 6397 this->GenerateCall(masm, t9); |
| 6399 } | 6398 } |
| 6400 | 6399 |
| 6400 |
| 6401 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, | 6401 void DirectCEntryStub::GenerateCall(MacroAssembler* masm, |
| 6402 Register target) { | 6402 Register target) { |
| 6403 __ Move(t9, target); | 6403 __ Move(t9, target); |
| 6404 __ AssertStackIsAligned(); | 6404 __ AssertStackIsAligned(); |
| 6405 // Allocate space for arg slots. | 6405 // Allocate space for arg slots. |
| 6406 __ Subu(sp, sp, kCArgsSlotsSize); | 6406 __ Subu(sp, sp, kCArgsSlotsSize); |
| 6407 | 6407 |
| 6408 // 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 |
| 6409 // number of generated instructions is constant. | 6409 // number of generated instructions is constant. |
| 6410 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... |
| 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 |