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 |