OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3715 EDI_UNINITIALIZED); | 3715 EDI_UNINITIALIZED); |
3716 } | 3716 } |
3717 | 3717 |
3718 | 3718 |
3719 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3719 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
3720 Register input_reg = ToRegister(instr->value()); | 3720 Register input_reg = ToRegister(instr->value()); |
3721 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3721 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
3722 factory()->heap_number_map()); | 3722 factory()->heap_number_map()); |
3723 DeoptimizeIf(not_equal, instr->environment()); | 3723 DeoptimizeIf(not_equal, instr->environment()); |
3724 | 3724 |
3725 Label done; | 3725 Label slow, allocated, done; |
3726 Register tmp = input_reg.is(eax) ? ecx : eax; | 3726 Register tmp = input_reg.is(eax) ? ecx : eax; |
3727 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; | 3727 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; |
3728 | 3728 |
3729 // Preserve the value of all registers. | 3729 // Preserve the value of all registers. |
3730 PushSafepointRegistersScope scope(this); | 3730 PushSafepointRegistersScope scope(this); |
3731 | 3731 |
3732 Label negative; | |
3733 __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 3732 __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
3734 // Check the sign of the argument. If the argument is positive, just | 3733 // Check the sign of the argument. If the argument is positive, just |
3735 // return it. We do not need to patch the stack since |input| and | 3734 // return it. We do not need to patch the stack since |input| and |
3736 // |result| are the same register and |input| will be restored | 3735 // |result| are the same register and |input| will be restored |
3737 // unchanged by popping safepoint registers. | 3736 // unchanged by popping safepoint registers. |
3738 __ test(tmp, Immediate(HeapNumber::kSignMask)); | 3737 __ test(tmp, Immediate(HeapNumber::kSignMask)); |
3739 __ j(not_zero, &negative); | 3738 __ j(zero, &done); |
3740 __ jmp(&done); | |
3741 | 3739 |
3742 __ bind(&negative); | |
3743 | |
3744 Label allocated, slow; | |
3745 __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow); | 3740 __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow); |
3746 __ jmp(&allocated); | 3741 __ jmp(&allocated, Label::kNear); |
3747 | 3742 |
3748 // Slow case: Call the runtime system to do the number allocation. | 3743 // Slow case: Call the runtime system to do the number allocation. |
3749 __ bind(&slow); | 3744 __ bind(&slow); |
3750 | |
3751 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, | 3745 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, |
3752 instr, instr->context()); | 3746 instr, instr->context()); |
3753 | |
3754 // Set the pointer to the new heap number in tmp. | 3747 // Set the pointer to the new heap number in tmp. |
3755 if (!tmp.is(eax)) __ mov(tmp, eax); | 3748 if (!tmp.is(eax)) __ mov(tmp, eax); |
3756 | |
3757 // Restore input_reg after call to runtime. | 3749 // Restore input_reg after call to runtime. |
3758 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); | 3750 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); |
3759 | 3751 |
3760 __ bind(&allocated); | 3752 __ bind(&allocated); |
3761 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 3753 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
3762 __ and_(tmp2, ~HeapNumber::kSignMask); | 3754 __ and_(tmp2, ~HeapNumber::kSignMask); |
3763 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); | 3755 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); |
3764 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); | 3756 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); |
3765 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); | 3757 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); |
3766 __ StoreToSafepointRegisterSlot(input_reg, tmp); | 3758 __ StoreToSafepointRegisterSlot(input_reg, tmp); |
3767 | 3759 |
3768 __ bind(&done); | 3760 __ bind(&done); |
3769 } | 3761 } |
3770 | 3762 |
3771 | 3763 |
3772 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { | 3764 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { |
3773 Register input_reg = ToRegister(instr->value()); | 3765 Register input_reg = ToRegister(instr->value()); |
3774 __ test(input_reg, Operand(input_reg)); | 3766 __ test(input_reg, Operand(input_reg)); |
3775 Label is_positive; | 3767 Label is_positive; |
3776 __ j(not_sign, &is_positive); | 3768 __ j(not_sign, &is_positive, Label::kNear); |
3777 __ neg(input_reg); // Sets flags. | 3769 __ neg(input_reg); // Sets flags. |
3778 DeoptimizeIf(negative, instr->environment()); | 3770 DeoptimizeIf(negative, instr->environment()); |
3779 __ bind(&is_positive); | 3771 __ bind(&is_positive); |
3780 } | 3772 } |
3781 | 3773 |
3782 | 3774 |
3783 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3775 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
3784 // Class for deferred case. | 3776 // Class for deferred case. |
3785 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3777 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
3786 public: | 3778 public: |
(...skipping 2703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6490 FixedArray::kHeaderSize - kPointerSize)); | 6482 FixedArray::kHeaderSize - kPointerSize)); |
6491 __ bind(&done); | 6483 __ bind(&done); |
6492 } | 6484 } |
6493 | 6485 |
6494 | 6486 |
6495 #undef __ | 6487 #undef __ |
6496 | 6488 |
6497 } } // namespace v8::internal | 6489 } } // namespace v8::internal |
6498 | 6490 |
6499 #endif // V8_TARGET_ARCH_IA32 | 6491 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |