Chromium Code Reviews| 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 |