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 4879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4890 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); | 4890 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); |
4891 __ cmp(reg, Operand(Smi::kMaxValue)); | 4891 __ cmp(reg, Operand(Smi::kMaxValue)); |
4892 __ b(hi, deferred->entry()); | 4892 __ b(hi, deferred->entry()); |
4893 __ SmiTag(reg, reg); | 4893 __ SmiTag(reg, reg); |
4894 __ bind(deferred->exit()); | 4894 __ bind(deferred->exit()); |
4895 } | 4895 } |
4896 | 4896 |
4897 | 4897 |
4898 // Convert unsigned integer with specified number of leading zeroes in binary | 4898 // Convert unsigned integer with specified number of leading zeroes in binary |
4899 // representation to IEEE 754 double. | 4899 // representation to IEEE 754 double. |
4900 // Integer to convert is passed in register hiword. | 4900 // Integer to convert is passed in register src. |
4901 // Resulting double is returned in registers hiword:loword. | 4901 // Resulting double is returned in registers hiword:loword. |
4902 // This functions does not work correctly for 0. | 4902 // This functions does not work correctly for 0. |
4903 static void GenerateUInt2Double(MacroAssembler* masm, | 4903 static void GenerateUInt2Double(MacroAssembler* masm, |
| 4904 Register src, |
4904 Register hiword, | 4905 Register hiword, |
4905 Register loword, | 4906 Register loword, |
4906 Register scratch, | 4907 Register scratch, |
4907 int leading_zeroes) { | 4908 int leading_zeroes) { |
4908 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1; | 4909 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1; |
4909 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits; | 4910 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits; |
4910 | 4911 |
4911 const int mantissa_shift_for_hi_word = | 4912 const int mantissa_shift_for_hi_word = |
4912 meaningful_bits - HeapNumber::kMantissaBitsInTopWord; | 4913 meaningful_bits - HeapNumber::kMantissaBitsInTopWord; |
4913 const int mantissa_shift_for_lo_word = | 4914 const int mantissa_shift_for_lo_word = |
4914 kBitsPerInt - mantissa_shift_for_hi_word; | 4915 kBitsPerInt - mantissa_shift_for_hi_word; |
4915 masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift)); | 4916 masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift)); |
4916 if (mantissa_shift_for_hi_word > 0) { | 4917 if (mantissa_shift_for_hi_word > 0) { |
4917 masm->mov(loword, Operand(hiword, LSL, mantissa_shift_for_lo_word)); | 4918 masm->mov(loword, Operand(src, LSL, mantissa_shift_for_lo_word)); |
4918 masm->orr(hiword, scratch, | 4919 masm->orr(hiword, scratch, |
4919 Operand(hiword, LSR, mantissa_shift_for_hi_word)); | 4920 Operand(src, LSR, mantissa_shift_for_hi_word)); |
4920 } else { | 4921 } else { |
4921 masm->mov(loword, Operand::Zero()); | 4922 masm->mov(loword, Operand::Zero()); |
4922 masm->orr(hiword, scratch, | 4923 masm->orr(hiword, scratch, |
4923 Operand(hiword, LSL, -mantissa_shift_for_hi_word)); | 4924 Operand(src, LSL, -mantissa_shift_for_hi_word)); |
4924 } | 4925 } |
4925 | 4926 |
4926 // If least significant bit of biased exponent was not 1 it was corrupted | 4927 // If least significant bit of biased exponent was not 1 it was corrupted |
4927 // by most significant bit of mantissa so we should fix that. | 4928 // by most significant bit of mantissa so we should fix that. |
4928 if (!(biased_exponent & 1)) { | 4929 if (!(biased_exponent & 1)) { |
4929 masm->bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); | 4930 masm->bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift)); |
4930 } | 4931 } |
4931 } | 4932 } |
4932 | 4933 |
4933 | 4934 |
(...skipping 28 matching lines...) Expand all Loading... |
4962 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0, | 4963 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0, |
4963 sfpd_lo, sfpd_hi, | 4964 sfpd_lo, sfpd_hi, |
4964 scratch0(), s0); | 4965 scratch0(), s0); |
4965 } | 4966 } |
4966 } else { | 4967 } else { |
4967 if (CpuFeatures::IsSupported(VFP2)) { | 4968 if (CpuFeatures::IsSupported(VFP2)) { |
4968 CpuFeatureScope scope(masm(), VFP2); | 4969 CpuFeatureScope scope(masm(), VFP2); |
4969 __ vmov(flt_scratch, src); | 4970 __ vmov(flt_scratch, src); |
4970 __ vcvt_f64_u32(dbl_scratch, flt_scratch); | 4971 __ vcvt_f64_u32(dbl_scratch, flt_scratch); |
4971 } else { | 4972 } else { |
4972 Label no_leading_zero, done; | 4973 Label no_leading_zero, convert_done; |
4973 __ tst(src, Operand(0x80000000)); | 4974 __ tst(src, Operand(0x80000000)); |
4974 __ b(ne, &no_leading_zero); | 4975 __ b(ne, &no_leading_zero); |
4975 | 4976 |
4976 // Integer has one leading zeros. | 4977 // Integer has one leading zeros. |
4977 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1); | 4978 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 1); |
4978 __ b(&done); | 4979 __ b(&convert_done); |
4979 | 4980 |
4980 __ bind(&no_leading_zero); | 4981 __ bind(&no_leading_zero); |
4981 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 0); | 4982 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, r9, 0); |
4982 __ b(&done); | 4983 __ bind(&convert_done); |
4983 } | 4984 } |
4984 } | 4985 } |
4985 | 4986 |
4986 if (FLAG_inline_new) { | 4987 if (FLAG_inline_new) { |
4987 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); | 4988 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); |
4988 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); | 4989 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); |
4989 __ Move(dst, r5); | 4990 __ Move(dst, r5); |
4990 __ b(&done); | 4991 __ b(&done); |
4991 } | 4992 } |
4992 | 4993 |
4993 // Slow case: Call the runtime system to do the number allocation. | 4994 // Slow case: Call the runtime system to do the number allocation. |
4994 __ bind(&slow); | 4995 __ bind(&slow); |
4995 | 4996 |
4996 // TODO(3095996): Put a valid pointer value in the stack slot where the result | 4997 // TODO(3095996): Put a valid pointer value in the stack slot where the result |
4997 // register is stored, as this register is in the pointer map, but contains an | 4998 // register is stored, as this register is in the pointer map, but contains an |
4998 // integer value. | 4999 // integer value. |
| 5000 if (!CpuFeatures::IsSupported(VFP2)) { |
| 5001 // Preserve sfpd_lo. |
| 5002 __ mov(r9, sfpd_lo); |
| 5003 } |
4999 __ mov(ip, Operand::Zero()); | 5004 __ mov(ip, Operand::Zero()); |
5000 __ StoreToSafepointRegisterSlot(ip, dst); | 5005 __ StoreToSafepointRegisterSlot(ip, dst); |
5001 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 5006 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
5002 __ Move(dst, r0); | 5007 __ Move(dst, r0); |
| 5008 if (!CpuFeatures::IsSupported(VFP2)) { |
| 5009 // Restore sfpd_lo. |
| 5010 __ mov(sfpd_lo, r9); |
| 5011 } |
5003 __ sub(dst, dst, Operand(kHeapObjectTag)); | 5012 __ sub(dst, dst, Operand(kHeapObjectTag)); |
5004 | 5013 |
5005 // Done. Put the value in dbl_scratch into the value of the allocated heap | 5014 // Done. Put the value in dbl_scratch into the value of the allocated heap |
5006 // number. | 5015 // number. |
5007 __ bind(&done); | 5016 __ bind(&done); |
5008 if (CpuFeatures::IsSupported(VFP2)) { | 5017 if (CpuFeatures::IsSupported(VFP2)) { |
5009 CpuFeatureScope scope(masm(), VFP2); | 5018 CpuFeatureScope scope(masm(), VFP2); |
5010 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); | 5019 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); |
5011 } else { | 5020 } else { |
5012 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); | 5021 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); |
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6393 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6402 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
6394 __ ldr(result, FieldMemOperand(scratch, | 6403 __ ldr(result, FieldMemOperand(scratch, |
6395 FixedArray::kHeaderSize - kPointerSize)); | 6404 FixedArray::kHeaderSize - kPointerSize)); |
6396 __ bind(&done); | 6405 __ bind(&done); |
6397 } | 6406 } |
6398 | 6407 |
6399 | 6408 |
6400 #undef __ | 6409 #undef __ |
6401 | 6410 |
6402 } } // namespace v8::internal | 6411 } } // namespace v8::internal |
OLD | NEW |