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