| 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 3696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3707 class DeferredNumberTagI: public LDeferredCode { | 3707 class DeferredNumberTagI: public LDeferredCode { |
| 3708 public: | 3708 public: |
| 3709 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | 3709 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
| 3710 : LDeferredCode(codegen), instr_(instr) { } | 3710 : LDeferredCode(codegen), instr_(instr) { } |
| 3711 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } | 3711 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } |
| 3712 virtual LInstruction* instr() { return instr_; } | 3712 virtual LInstruction* instr() { return instr_; } |
| 3713 private: | 3713 private: |
| 3714 LNumberTagI* instr_; | 3714 LNumberTagI* instr_; |
| 3715 }; | 3715 }; |
| 3716 | 3716 |
| 3717 LOperand* input = instr->InputAt(0); | 3717 Register src = ToRegister(instr->InputAt(0)); |
| 3718 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 3718 Register dst = ToRegister(instr->result()); |
| 3719 Register reg = ToRegister(input); | |
| 3720 Register overflow = scratch0(); | 3719 Register overflow = scratch0(); |
| 3721 | 3720 |
| 3722 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); | 3721 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); |
| 3723 __ SmiTagCheckOverflow(reg, overflow); | 3722 __ SmiTagCheckOverflow(dst, src, overflow); |
| 3724 __ BranchOnOverflow(deferred->entry(), overflow); | 3723 __ BranchOnOverflow(deferred->entry(), overflow); |
| 3725 __ bind(deferred->exit()); | 3724 __ bind(deferred->exit()); |
| 3726 } | 3725 } |
| 3727 | 3726 |
| 3728 | 3727 |
| 3729 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | 3728 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { |
| 3730 Label slow; | 3729 Label slow; |
| 3731 Register reg = ToRegister(instr->InputAt(0)); | 3730 Register src = ToRegister(instr->InputAt(0)); |
| 3731 Register dst = ToRegister(instr->result()); |
| 3732 FPURegister dbl_scratch = double_scratch0(); | 3732 FPURegister dbl_scratch = double_scratch0(); |
| 3733 | 3733 |
| 3734 // Preserve the value of all registers. | 3734 // Preserve the value of all registers. |
| 3735 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 3735 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
| 3736 | 3736 |
| 3737 // There was overflow, so bits 30 and 31 of the original integer | 3737 // There was overflow, so bits 30 and 31 of the original integer |
| 3738 // disagree. Try to allocate a heap number in new space and store | 3738 // disagree. Try to allocate a heap number in new space and store |
| 3739 // the value in there. If that fails, call the runtime system. | 3739 // the value in there. If that fails, call the runtime system. |
| 3740 Label done; | 3740 Label done; |
| 3741 __ SmiUntag(reg); | 3741 if (dst.is(src)) { |
| 3742 __ Xor(reg, reg, Operand(0x80000000)); | 3742 __ SmiUntag(src, dst); |
| 3743 __ mtc1(reg, dbl_scratch); | 3743 __ Xor(src, src, Operand(0x80000000)); |
| 3744 } |
| 3745 __ mtc1(src, dbl_scratch); |
| 3744 __ cvt_d_w(dbl_scratch, dbl_scratch); | 3746 __ cvt_d_w(dbl_scratch, dbl_scratch); |
| 3745 if (FLAG_inline_new) { | 3747 if (FLAG_inline_new) { |
| 3746 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); | 3748 __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); |
| 3747 __ AllocateHeapNumber(t1, a3, t0, t2, &slow); | 3749 __ AllocateHeapNumber(t1, a3, t0, t2, &slow); |
| 3748 if (!reg.is(t1)) __ mov(reg, t1); | 3750 __ Move(dst, t1); |
| 3749 __ Branch(&done); | 3751 __ Branch(&done); |
| 3750 } | 3752 } |
| 3751 | 3753 |
| 3752 // Slow case: Call the runtime system to do the number allocation. | 3754 // Slow case: Call the runtime system to do the number allocation. |
| 3753 __ bind(&slow); | 3755 __ bind(&slow); |
| 3754 | 3756 |
| 3755 // TODO(3095996): Put a valid pointer value in the stack slot where the result | 3757 // TODO(3095996): Put a valid pointer value in the stack slot where the result |
| 3756 // register is stored, as this register is in the pointer map, but contains an | 3758 // register is stored, as this register is in the pointer map, but contains an |
| 3757 // integer value. | 3759 // integer value. |
| 3758 __ StoreToSafepointRegisterSlot(zero_reg, reg); | 3760 __ StoreToSafepointRegisterSlot(zero_reg, src); |
| 3761 __ StoreToSafepointRegisterSlot(zero_reg, dst); |
| 3759 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 3762 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 3760 if (!reg.is(v0)) __ mov(reg, v0); | 3763 __ Move(dst, v0); |
| 3761 | 3764 |
| 3762 // Done. Put the value in dbl_scratch into the value of the allocated heap | 3765 // Done. Put the value in dbl_scratch into the value of the allocated heap |
| 3763 // number. | 3766 // number. |
| 3764 __ bind(&done); | 3767 __ bind(&done); |
| 3765 __ sdc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 3768 __ sdc1(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset)); |
| 3766 __ StoreToSafepointRegisterSlot(reg, reg); | 3769 __ StoreToSafepointRegisterSlot(dst, dst); |
| 3767 } | 3770 } |
| 3768 | 3771 |
| 3769 | 3772 |
| 3770 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 3773 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
| 3771 class DeferredNumberTagD: public LDeferredCode { | 3774 class DeferredNumberTagD: public LDeferredCode { |
| 3772 public: | 3775 public: |
| 3773 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 3776 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
| 3774 : LDeferredCode(codegen), instr_(instr) { } | 3777 : LDeferredCode(codegen), instr_(instr) { } |
| 3775 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } | 3778 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } |
| 3776 virtual LInstruction* instr() { return instr_; } | 3779 virtual LInstruction* instr() { return instr_; } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3803 Register reg = ToRegister(instr->result()); | 3806 Register reg = ToRegister(instr->result()); |
| 3804 __ mov(reg, zero_reg); | 3807 __ mov(reg, zero_reg); |
| 3805 | 3808 |
| 3806 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 3809 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
| 3807 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 3810 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 3808 __ StoreToSafepointRegisterSlot(v0, reg); | 3811 __ StoreToSafepointRegisterSlot(v0, reg); |
| 3809 } | 3812 } |
| 3810 | 3813 |
| 3811 | 3814 |
| 3812 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 3815 void LCodeGen::DoSmiTag(LSmiTag* instr) { |
| 3813 LOperand* input = instr->InputAt(0); | |
| 3814 ASSERT(input->IsRegister() && input->Equals(instr->result())); | |
| 3815 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); | 3816 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); |
| 3816 __ SmiTag(ToRegister(input)); | 3817 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0))); |
| 3817 } | 3818 } |
| 3818 | 3819 |
| 3819 | 3820 |
| 3820 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { | 3821 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { |
| 3821 Register scratch = scratch0(); | 3822 Register scratch = scratch0(); |
| 3822 LOperand* input = instr->InputAt(0); | 3823 Register input = ToRegister(instr->InputAt(0)); |
| 3823 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 3824 Register result = ToRegister(instr->result()); |
| 3824 if (instr->needs_check()) { | 3825 if (instr->needs_check()) { |
| 3825 STATIC_ASSERT(kHeapObjectTag == 1); | 3826 STATIC_ASSERT(kHeapObjectTag == 1); |
| 3826 // If the input is a HeapObject, value of scratch won't be zero. | 3827 // If the input is a HeapObject, value of scratch won't be zero. |
| 3827 __ And(scratch, ToRegister(input), Operand(kHeapObjectTag)); | 3828 __ And(scratch, input, Operand(kHeapObjectTag)); |
| 3828 __ SmiUntag(ToRegister(input)); | 3829 __ SmiUntag(result, input); |
| 3829 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); | 3830 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); |
| 3830 } else { | 3831 } else { |
| 3831 __ SmiUntag(ToRegister(input)); | 3832 __ SmiUntag(result, input); |
| 3832 } | 3833 } |
| 3833 } | 3834 } |
| 3834 | 3835 |
| 3835 | 3836 |
| 3836 void LCodeGen::EmitNumberUntagD(Register input_reg, | 3837 void LCodeGen::EmitNumberUntagD(Register input_reg, |
| 3837 DoubleRegister result_reg, | 3838 DoubleRegister result_reg, |
| 3838 bool deoptimize_on_undefined, | 3839 bool deoptimize_on_undefined, |
| 3839 bool deoptimize_on_minus_zero, | 3840 bool deoptimize_on_minus_zero, |
| 3840 LEnvironment* env) { | 3841 LEnvironment* env) { |
| 3841 Register scratch = scratch0(); | 3842 Register scratch = scratch0(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3869 if (deoptimize_on_minus_zero) { | 3870 if (deoptimize_on_minus_zero) { |
| 3870 __ mfc1(at, result_reg.low()); | 3871 __ mfc1(at, result_reg.low()); |
| 3871 __ Branch(&done, ne, at, Operand(zero_reg)); | 3872 __ Branch(&done, ne, at, Operand(zero_reg)); |
| 3872 __ mfc1(scratch, result_reg.high()); | 3873 __ mfc1(scratch, result_reg.high()); |
| 3873 DeoptimizeIf(eq, env, scratch, Operand(HeapNumber::kSignMask)); | 3874 DeoptimizeIf(eq, env, scratch, Operand(HeapNumber::kSignMask)); |
| 3874 } | 3875 } |
| 3875 __ Branch(&done); | 3876 __ Branch(&done); |
| 3876 | 3877 |
| 3877 // Smi to double register conversion | 3878 // Smi to double register conversion |
| 3878 __ bind(&load_smi); | 3879 __ bind(&load_smi); |
| 3879 __ SmiUntag(input_reg); // Untag smi before converting to float. | 3880 __ SmiUntag(scratch, input_reg); // Untag smi before converting to float. |
| 3880 __ mtc1(input_reg, result_reg); | 3881 __ mtc1(scratch, result_reg); |
| 3881 __ cvt_d_w(result_reg, result_reg); | 3882 __ cvt_d_w(result_reg, result_reg); |
| 3882 __ SmiTag(input_reg); // Retag smi. | |
| 3883 __ bind(&done); | 3883 __ bind(&done); |
| 3884 } | 3884 } |
| 3885 | 3885 |
| 3886 | 3886 |
| 3887 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 3887 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
| 3888 Register input_reg = ToRegister(instr->InputAt(0)); | 3888 Register input_reg = ToRegister(instr->InputAt(0)); |
| 3889 Register scratch1 = scratch0(); | 3889 Register scratch1 = scratch0(); |
| 3890 Register scratch2 = ToRegister(instr->TempAt(0)); | 3890 Register scratch2 = ToRegister(instr->TempAt(0)); |
| 3891 DoubleRegister double_scratch = double_scratch0(); | 3891 DoubleRegister double_scratch = double_scratch0(); |
| 3892 FPURegister single_scratch = double_scratch.low(); | 3892 FPURegister single_scratch = double_scratch.low(); |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4740 ASSERT(!environment->HasBeenRegistered()); | 4740 ASSERT(!environment->HasBeenRegistered()); |
| 4741 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 4741 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
| 4742 ASSERT(osr_pc_offset_ == -1); | 4742 ASSERT(osr_pc_offset_ == -1); |
| 4743 osr_pc_offset_ = masm()->pc_offset(); | 4743 osr_pc_offset_ = masm()->pc_offset(); |
| 4744 } | 4744 } |
| 4745 | 4745 |
| 4746 | 4746 |
| 4747 #undef __ | 4747 #undef __ |
| 4748 | 4748 |
| 4749 } } // namespace v8::internal | 4749 } } // namespace v8::internal |
| OLD | NEW |