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 3770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3781 class DeferredNumberTagI: public LDeferredCode { | 3781 class DeferredNumberTagI: public LDeferredCode { |
3782 public: | 3782 public: |
3783 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | 3783 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
3784 : LDeferredCode(codegen), instr_(instr) { } | 3784 : LDeferredCode(codegen), instr_(instr) { } |
3785 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } | 3785 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } |
3786 virtual LInstruction* instr() { return instr_; } | 3786 virtual LInstruction* instr() { return instr_; } |
3787 private: | 3787 private: |
3788 LNumberTagI* instr_; | 3788 LNumberTagI* instr_; |
3789 }; | 3789 }; |
3790 | 3790 |
3791 LOperand* input = instr->InputAt(0); | 3791 Register src = ToRegister(instr->InputAt(0)); |
3792 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 3792 Register dst = ToRegister(instr->result()); |
3793 Register reg = ToRegister(input); | |
3794 | 3793 |
3795 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); | 3794 DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr); |
3796 __ SmiTag(reg, SetCC); | 3795 __ SmiTag(dst, src, SetCC); |
3797 __ b(vs, deferred->entry()); | 3796 __ b(vs, deferred->entry()); |
3798 __ bind(deferred->exit()); | 3797 __ bind(deferred->exit()); |
3799 } | 3798 } |
3800 | 3799 |
3801 | 3800 |
3802 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | 3801 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { |
3803 Label slow; | 3802 Label slow; |
3804 Register reg = ToRegister(instr->InputAt(0)); | 3803 Register src = ToRegister(instr->InputAt(0)); |
| 3804 Register dst = ToRegister(instr->result()); |
3805 DoubleRegister dbl_scratch = double_scratch0(); | 3805 DoubleRegister dbl_scratch = double_scratch0(); |
3806 SwVfpRegister flt_scratch = dbl_scratch.low(); | 3806 SwVfpRegister flt_scratch = dbl_scratch.low(); |
3807 | 3807 |
3808 // Preserve the value of all registers. | 3808 // Preserve the value of all registers. |
3809 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 3809 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
3810 | 3810 |
3811 // There was overflow, so bits 30 and 31 of the original integer | 3811 // There was overflow, so bits 30 and 31 of the original integer |
3812 // disagree. Try to allocate a heap number in new space and store | 3812 // disagree. Try to allocate a heap number in new space and store |
3813 // the value in there. If that fails, call the runtime system. | 3813 // the value in there. If that fails, call the runtime system. |
3814 Label done; | 3814 Label done; |
3815 __ SmiUntag(reg); | 3815 if (dst.is(src)) { |
3816 __ eor(reg, reg, Operand(0x80000000)); | 3816 __ SmiUntag(src, dst); |
3817 __ vmov(flt_scratch, reg); | 3817 __ eor(src, src, Operand(0x80000000)); |
| 3818 } |
| 3819 __ vmov(flt_scratch, src); |
3818 __ vcvt_f64_s32(dbl_scratch, flt_scratch); | 3820 __ vcvt_f64_s32(dbl_scratch, flt_scratch); |
3819 if (FLAG_inline_new) { | 3821 if (FLAG_inline_new) { |
3820 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3822 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
3821 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); | 3823 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); |
3822 if (!reg.is(r5)) __ mov(reg, r5); | 3824 __ Move(dst, r5); |
3823 __ b(&done); | 3825 __ b(&done); |
3824 } | 3826 } |
3825 | 3827 |
3826 // Slow case: Call the runtime system to do the number allocation. | 3828 // Slow case: Call the runtime system to do the number allocation. |
3827 __ bind(&slow); | 3829 __ bind(&slow); |
3828 | 3830 |
3829 // TODO(3095996): Put a valid pointer value in the stack slot where the result | 3831 // TODO(3095996): Put a valid pointer value in the stack slot where the result |
3830 // register is stored, as this register is in the pointer map, but contains an | 3832 // register is stored, as this register is in the pointer map, but contains an |
3831 // integer value. | 3833 // integer value. |
3832 __ mov(ip, Operand(0)); | 3834 __ mov(ip, Operand(0)); |
3833 __ StoreToSafepointRegisterSlot(ip, reg); | 3835 __ StoreToSafepointRegisterSlot(ip, src); |
| 3836 __ StoreToSafepointRegisterSlot(ip, dst); |
3834 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 3837 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
3835 if (!reg.is(r0)) __ mov(reg, r0); | 3838 __ Move(dst, r0); |
3836 | 3839 |
3837 // Done. Put the value in dbl_scratch into the value of the allocated heap | 3840 // Done. Put the value in dbl_scratch into the value of the allocated heap |
3838 // number. | 3841 // number. |
3839 __ bind(&done); | 3842 __ bind(&done); |
3840 __ sub(ip, reg, Operand(kHeapObjectTag)); | 3843 __ sub(ip, dst, Operand(kHeapObjectTag)); |
3841 __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset); | 3844 __ vstr(dbl_scratch, ip, HeapNumber::kValueOffset); |
3842 __ StoreToSafepointRegisterSlot(reg, reg); | 3845 __ StoreToSafepointRegisterSlot(dst, dst); |
3843 } | 3846 } |
3844 | 3847 |
3845 | 3848 |
3846 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 3849 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
3847 class DeferredNumberTagD: public LDeferredCode { | 3850 class DeferredNumberTagD: public LDeferredCode { |
3848 public: | 3851 public: |
3849 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 3852 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
3850 : LDeferredCode(codegen), instr_(instr) { } | 3853 : LDeferredCode(codegen), instr_(instr) { } |
3851 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } | 3854 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } |
3852 virtual LInstruction* instr() { return instr_; } | 3855 virtual LInstruction* instr() { return instr_; } |
(...skipping 27 matching lines...) Expand all Loading... |
3880 Register reg = ToRegister(instr->result()); | 3883 Register reg = ToRegister(instr->result()); |
3881 __ mov(reg, Operand(0)); | 3884 __ mov(reg, Operand(0)); |
3882 | 3885 |
3883 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 3886 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
3884 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 3887 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
3885 __ StoreToSafepointRegisterSlot(r0, reg); | 3888 __ StoreToSafepointRegisterSlot(r0, reg); |
3886 } | 3889 } |
3887 | 3890 |
3888 | 3891 |
3889 void LCodeGen::DoSmiTag(LSmiTag* instr) { | 3892 void LCodeGen::DoSmiTag(LSmiTag* instr) { |
3890 LOperand* input = instr->InputAt(0); | |
3891 ASSERT(input->IsRegister() && input->Equals(instr->result())); | |
3892 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); | 3893 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); |
3893 __ SmiTag(ToRegister(input)); | 3894 __ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0))); |
3894 } | 3895 } |
3895 | 3896 |
3896 | 3897 |
3897 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { | 3898 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { |
3898 LOperand* input = instr->InputAt(0); | 3899 Register input = ToRegister(instr->InputAt(0)); |
3899 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 3900 Register result = ToRegister(instr->result()); |
3900 if (instr->needs_check()) { | 3901 if (instr->needs_check()) { |
3901 STATIC_ASSERT(kHeapObjectTag == 1); | 3902 STATIC_ASSERT(kHeapObjectTag == 1); |
3902 // If the input is a HeapObject, SmiUntag will set the carry flag. | 3903 // If the input is a HeapObject, SmiUntag will set the carry flag. |
3903 __ SmiUntag(ToRegister(input), SetCC); | 3904 __ SmiUntag(result, input, SetCC); |
3904 DeoptimizeIf(cs, instr->environment()); | 3905 DeoptimizeIf(cs, instr->environment()); |
3905 } else { | 3906 } else { |
3906 __ SmiUntag(ToRegister(input)); | 3907 __ SmiUntag(result, input); |
3907 } | 3908 } |
3908 } | 3909 } |
3909 | 3910 |
3910 | 3911 |
3911 void LCodeGen::EmitNumberUntagD(Register input_reg, | 3912 void LCodeGen::EmitNumberUntagD(Register input_reg, |
3912 DoubleRegister result_reg, | 3913 DoubleRegister result_reg, |
3913 bool deoptimize_on_undefined, | 3914 bool deoptimize_on_undefined, |
3914 bool deoptimize_on_minus_zero, | 3915 bool deoptimize_on_minus_zero, |
3915 LEnvironment* env) { | 3916 LEnvironment* env) { |
3916 Register scratch = scratch0(); | 3917 Register scratch = scratch0(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3952 __ cmp(ip, Operand(0)); | 3953 __ cmp(ip, Operand(0)); |
3953 __ b(ne, &done); | 3954 __ b(ne, &done); |
3954 __ vmov(ip, result_reg.high()); | 3955 __ vmov(ip, result_reg.high()); |
3955 __ cmp(ip, Operand(HeapNumber::kSignMask)); | 3956 __ cmp(ip, Operand(HeapNumber::kSignMask)); |
3956 DeoptimizeIf(eq, env); | 3957 DeoptimizeIf(eq, env); |
3957 } | 3958 } |
3958 __ jmp(&done); | 3959 __ jmp(&done); |
3959 | 3960 |
3960 // Smi to double register conversion | 3961 // Smi to double register conversion |
3961 __ bind(&load_smi); | 3962 __ bind(&load_smi); |
3962 __ SmiUntag(input_reg); // Untag smi before converting to float. | 3963 __ SmiUntag(scratch, input_reg); // Untag smi before converting to float. |
3963 __ vmov(flt_scratch, input_reg); | 3964 __ vmov(flt_scratch, scratch); |
3964 __ vcvt_f64_s32(result_reg, flt_scratch); | 3965 __ vcvt_f64_s32(result_reg, flt_scratch); |
3965 __ SmiTag(input_reg); // Retag smi. | |
3966 __ bind(&done); | 3966 __ bind(&done); |
3967 } | 3967 } |
3968 | 3968 |
3969 | 3969 |
3970 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 3970 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { |
3971 Register input_reg = ToRegister(instr->InputAt(0)); | 3971 Register input_reg = ToRegister(instr->InputAt(0)); |
3972 Register scratch1 = scratch0(); | 3972 Register scratch1 = scratch0(); |
3973 Register scratch2 = ToRegister(instr->TempAt(0)); | 3973 Register scratch2 = ToRegister(instr->TempAt(0)); |
3974 DwVfpRegister double_scratch = double_scratch0(); | 3974 DwVfpRegister double_scratch = double_scratch0(); |
3975 SwVfpRegister single_scratch = double_scratch.low(); | 3975 SwVfpRegister single_scratch = double_scratch.low(); |
(...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4792 ASSERT(osr_pc_offset_ == -1); | 4792 ASSERT(osr_pc_offset_ == -1); |
4793 osr_pc_offset_ = masm()->pc_offset(); | 4793 osr_pc_offset_ = masm()->pc_offset(); |
4794 } | 4794 } |
4795 | 4795 |
4796 | 4796 |
4797 | 4797 |
4798 | 4798 |
4799 #undef __ | 4799 #undef __ |
4800 | 4800 |
4801 } } // namespace v8::internal | 4801 } } // namespace v8::internal |
OLD | NEW |