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 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
738 } | 738 } |
739 | 739 |
740 | 740 |
741 void FloatingPointHelper::ConvertNumberToInt32(MacroAssembler* masm, | 741 void FloatingPointHelper::ConvertNumberToInt32(MacroAssembler* masm, |
742 Register object, | 742 Register object, |
743 Register dst, | 743 Register dst, |
744 Register heap_number_map, | 744 Register heap_number_map, |
745 Register scratch1, | 745 Register scratch1, |
746 Register scratch2, | 746 Register scratch2, |
747 Register scratch3, | 747 Register scratch3, |
748 DwVfpRegister double_scratch, | 748 DwVfpRegister double_scratch1, |
749 DwVfpRegister double_scratch2, | |
749 Label* not_number) { | 750 Label* not_number) { |
751 Label done; | |
750 __ AssertRootValue(heap_number_map, | 752 __ AssertRootValue(heap_number_map, |
751 Heap::kHeapNumberMapRootIndex, | 753 Heap::kHeapNumberMapRootIndex, |
752 "HeapNumberMap register clobbered."); | 754 "HeapNumberMap register clobbered."); |
753 Label done; | |
754 Label not_in_int32_range; | |
755 | 755 |
756 __ UntagAndJumpIfSmi(dst, object, &done); | 756 __ UntagAndJumpIfSmi(dst, object, &done); |
757 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); | 757 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); |
758 __ cmp(scratch1, heap_number_map); | 758 __ cmp(scratch1, heap_number_map); |
759 __ b(ne, not_number); | 759 __ b(ne, not_number); |
760 __ ConvertToInt32(object, | 760 __ ECMAConvertNumberToInt32(object, dst, |
761 dst, | 761 scratch1, scratch2, scratch3, |
762 scratch1, | 762 double_scratch1, double_scratch2); |
763 scratch2, | |
764 double_scratch, | |
765 ¬_in_int32_range); | |
766 __ jmp(&done); | |
767 | |
768 __ bind(¬_in_int32_range); | |
769 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset)); | |
770 __ ldr(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset)); | |
771 | |
772 __ EmitOutOfInt32RangeTruncate(dst, | |
773 scratch1, | |
774 scratch2, | |
775 scratch3); | |
776 __ bind(&done); | 763 __ bind(&done); |
777 } | 764 } |
778 | 765 |
779 | 766 |
780 void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, | 767 void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, |
781 Register int_scratch, | 768 Register int_scratch, |
782 Destination destination, | 769 Destination destination, |
783 DwVfpRegister double_dst, | 770 DwVfpRegister double_dst, |
784 Register dst_mantissa, | 771 Register dst_mantissa, |
785 Register dst_exponent, | 772 Register dst_exponent, |
(...skipping 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2283 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 2270 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
2284 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset)); | 2271 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset)); |
2285 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. | 2272 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. |
2286 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset)); | 2273 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset)); |
2287 __ mov(r0, Operand(r1)); | 2274 __ mov(r0, Operand(r1)); |
2288 } | 2275 } |
2289 __ Ret(); | 2276 __ Ret(); |
2290 } | 2277 } |
2291 | 2278 |
2292 | 2279 |
2293 void UnaryOpStub::GenerateHeapNumberCodeBitNot( | 2280 void UnaryOpStub::GenerateHeapNumberCodeBitNot(MacroAssembler* masm, |
2294 MacroAssembler* masm, Label* slow) { | 2281 Label* slow) { |
2295 Label impossible; | |
2296 | |
2297 EmitCheckForHeapNumber(masm, r0, r1, r6, slow); | 2282 EmitCheckForHeapNumber(masm, r0, r1, r6, slow); |
2298 // Convert the heap number is r0 to an untagged integer in r1. | 2283 // Convert the heap number in r0 to an untagged integer in r1. |
2299 __ ConvertToInt32(r0, r1, r2, r3, d0, slow); | 2284 __ ECMAConvertNumberToInt32(r0, r1, r2, r3, r4, d0, d1); |
2300 | 2285 |
2301 // Do the bitwise operation and check if the result fits in a smi. | 2286 // Do the bitwise operation and check if the result fits in a smi. |
2302 Label try_float; | 2287 Label try_float; |
2303 __ mvn(r1, Operand(r1)); | 2288 __ mvn(r1, Operand(r1)); |
2304 __ add(r2, r1, Operand(0x40000000), SetCC); | 2289 __ cmn(r1, Operand(0x40000000)); |
2305 __ b(mi, &try_float); | 2290 __ b(mi, &try_float); |
2306 | 2291 |
2307 // Tag the result as a smi and we're done. | 2292 // Tag the result as a smi and we're done. |
2308 __ mov(r0, Operand(r1, LSL, kSmiTagSize)); | 2293 __ mov(r0, Operand(r1, LSL, kSmiTagSize)); |
2309 __ Ret(); | 2294 __ Ret(); |
2310 | 2295 |
2311 // Try to store the result in a heap number. | 2296 // Try to store the result in a heap number. |
2312 __ bind(&try_float); | 2297 __ bind(&try_float); |
2313 if (mode_ == UNARY_NO_OVERWRITE) { | 2298 if (mode_ == UNARY_NO_OVERWRITE) { |
2314 Label slow_allocate_heapnumber, heapnumber_allocated; | 2299 Label slow_allocate_heapnumber, heapnumber_allocated; |
2315 // Allocate a new heap number without zapping r0, which we need if it fails. | 2300 // Allocate a new heap number without zapping r0, which we need if it fails. |
ulan
2013/03/11 15:11:03
This comment is no longer valid.
Rodolph Perfetta
2013/03/12 11:24:45
Done.
| |
2316 __ AllocateHeapNumber(r2, r3, r4, r6, &slow_allocate_heapnumber); | 2301 __ AllocateHeapNumber(r0, r3, r4, r6, &slow_allocate_heapnumber); |
2317 __ jmp(&heapnumber_allocated); | 2302 __ jmp(&heapnumber_allocated); |
2318 | 2303 |
2319 __ bind(&slow_allocate_heapnumber); | 2304 __ bind(&slow_allocate_heapnumber); |
2320 { | 2305 { |
2321 FrameScope scope(masm, StackFrame::INTERNAL); | 2306 FrameScope scope(masm, StackFrame::INTERNAL); |
2322 __ push(r0); // Push the heap number, not the untagged int32. | 2307 // Push the lower bit of the result (left shifted to look like a smi). |
2308 __ mov(r2, Operand(r1, LSL, 31)); | |
2309 // Push the 31 high bits (bit 0 cleared to look like a smi). | |
2310 __ bic(r1, r1, Operand(1)); | |
2311 __ Push(r2, r1); | |
2323 __ CallRuntime(Runtime::kNumberAlloc, 0); | 2312 __ CallRuntime(Runtime::kNumberAlloc, 0); |
2324 __ mov(r2, r0); // Move the new heap number into r2. | 2313 __ Pop(r2, r1); // Restore the result. |
2325 // Get the heap number into r0, now that the new heap number is in r2. | 2314 __ orr(r1, r1, Operand(r2, LSR, 31)); |
2326 __ pop(r0); | |
2327 } | 2315 } |
2328 | |
2329 // Convert the heap number in r0 to an untagged integer in r1. | |
2330 // This can't go slow-case because it's the same number we already | |
2331 // converted once again. | |
2332 __ ConvertToInt32(r0, r1, r3, r4, d0, &impossible); | |
2333 __ mvn(r1, Operand(r1)); | |
2334 | |
2335 __ bind(&heapnumber_allocated); | 2316 __ bind(&heapnumber_allocated); |
2336 __ mov(r0, r2); // Move newly allocated heap number to r0. | |
2337 } | 2317 } |
2338 | 2318 |
2339 if (CpuFeatures::IsSupported(VFP2)) { | 2319 if (CpuFeatures::IsSupported(VFP2)) { |
2340 // Convert the int32 in r1 to the heap number in r0. r2 is corrupted. | 2320 // Convert the int32 in r1 to the heap number in r0. r2 is corrupted. |
2341 CpuFeatureScope scope(masm, VFP2); | 2321 CpuFeatureScope scope(masm, VFP2); |
2342 __ vmov(s0, r1); | 2322 __ vmov(s0, r1); |
2343 __ vcvt_f64_s32(d0, s0); | 2323 __ vcvt_f64_s32(d0, s0); |
2344 __ sub(r2, r0, Operand(kHeapObjectTag)); | 2324 __ vstr(d0, FieldMemOperand(r0, HeapNumber::kValueOffset)); |
2345 __ vstr(d0, r2, HeapNumber::kValueOffset); | |
2346 __ Ret(); | 2325 __ Ret(); |
2347 } else { | 2326 } else { |
2348 // WriteInt32ToHeapNumberStub does not trigger GC, so we do not | 2327 // WriteInt32ToHeapNumberStub does not trigger GC, so we do not |
2349 // have to set up a frame. | 2328 // have to set up a frame. |
2350 WriteInt32ToHeapNumberStub stub(r1, r0, r2); | 2329 WriteInt32ToHeapNumberStub stub(r1, r0, r2); |
2351 __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); | 2330 __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); |
2352 } | 2331 } |
2353 | |
2354 __ bind(&impossible); | |
2355 if (FLAG_debug_code) { | |
2356 __ stop("Incorrect assumption in bit-not stub"); | |
2357 } | |
2358 } | 2332 } |
2359 | 2333 |
2360 | 2334 |
2361 // TODO(svenpanne): Use virtual functions instead of switch. | 2335 // TODO(svenpanne): Use virtual functions instead of switch. |
2362 void UnaryOpStub::GenerateGenericStub(MacroAssembler* masm) { | 2336 void UnaryOpStub::GenerateGenericStub(MacroAssembler* masm) { |
2363 switch (op_) { | 2337 switch (op_) { |
2364 case Token::SUB: | 2338 case Token::SUB: |
2365 GenerateGenericStubSub(masm); | 2339 GenerateGenericStubSub(masm); |
2366 break; | 2340 break; |
2367 case Token::BIT_NOT: | 2341 case Token::BIT_NOT: |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2779 } else { | 2753 } else { |
2780 // Convert operands to 32-bit integers. Right in r2 and left in r3. | 2754 // Convert operands to 32-bit integers. Right in r2 and left in r3. |
2781 FloatingPointHelper::ConvertNumberToInt32(masm, | 2755 FloatingPointHelper::ConvertNumberToInt32(masm, |
2782 left, | 2756 left, |
2783 r3, | 2757 r3, |
2784 heap_number_map, | 2758 heap_number_map, |
2785 scratch1, | 2759 scratch1, |
2786 scratch2, | 2760 scratch2, |
2787 scratch3, | 2761 scratch3, |
2788 d0, | 2762 d0, |
2763 d1, | |
2789 not_numbers); | 2764 not_numbers); |
2790 FloatingPointHelper::ConvertNumberToInt32(masm, | 2765 FloatingPointHelper::ConvertNumberToInt32(masm, |
2791 right, | 2766 right, |
2792 r2, | 2767 r2, |
2793 heap_number_map, | 2768 heap_number_map, |
2794 scratch1, | 2769 scratch1, |
2795 scratch2, | 2770 scratch2, |
2796 scratch3, | 2771 scratch3, |
2797 d0, | 2772 d0, |
2773 d1, | |
2798 not_numbers); | 2774 not_numbers); |
2799 } | 2775 } |
2800 | 2776 |
2801 Label result_not_a_smi; | 2777 Label result_not_a_smi; |
2802 switch (op) { | 2778 switch (op) { |
2803 case Token::BIT_OR: | 2779 case Token::BIT_OR: |
2804 __ orr(r2, r3, Operand(r2)); | 2780 __ orr(r2, r3, Operand(r2)); |
2805 break; | 2781 break; |
2806 case Token::BIT_XOR: | 2782 case Token::BIT_XOR: |
2807 __ eor(r2, r3, Operand(r2)); | 2783 __ eor(r2, r3, Operand(r2)); |
(...skipping 5279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8087 | 8063 |
8088 __ Pop(lr, r5, r1); | 8064 __ Pop(lr, r5, r1); |
8089 __ Ret(); | 8065 __ Ret(); |
8090 } | 8066 } |
8091 | 8067 |
8092 #undef __ | 8068 #undef __ |
8093 | 8069 |
8094 } } // namespace v8::internal | 8070 } } // namespace v8::internal |
8095 | 8071 |
8096 #endif // V8_TARGET_ARCH_ARM | 8072 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |