OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 // requested when VFP3 is supported d6 and d7 will still be scratched. If | 390 // requested when VFP3 is supported d6 and d7 will still be scratched. If |
391 // either r0 or r1 is not a number (not smi and not heap number object) the | 391 // either r0 or r1 is not a number (not smi and not heap number object) the |
392 // not_number label is jumped to with r0 and r1 intact. | 392 // not_number label is jumped to with r0 and r1 intact. |
393 static void LoadOperands(MacroAssembler* masm, | 393 static void LoadOperands(MacroAssembler* masm, |
394 FloatingPointHelper::Destination destination, | 394 FloatingPointHelper::Destination destination, |
395 Register heap_number_map, | 395 Register heap_number_map, |
396 Register scratch1, | 396 Register scratch1, |
397 Register scratch2, | 397 Register scratch2, |
398 Label* not_number); | 398 Label* not_number); |
399 | 399 |
400 // Loads the number from object into dst as a 32-bit integer if possible. If | 400 // Convert the smi or heap number in object to an int32 using the rules |
401 // the object cannot be converted to a 32-bit integer control continues at | 401 // for ToInt32 as described in ECMAScript 9.5.: the value is truncated |
402 // the label not_int32. If VFP is supported double_scratch is used | 402 // and brought into the range -2^31 .. +2^31 - 1. |
403 // but not scratch2. | 403 static void ConvertNumberToInt32(MacroAssembler* masm, |
404 // Floating point value in the 32-bit integer range will be rounded | 404 Register object, |
405 // to an integer. | 405 Register dst, |
406 static void LoadNumberAsInteger(MacroAssembler* masm, | 406 Register heap_number_map, |
407 Register object, | 407 Register scratch1, |
408 Register dst, | 408 Register scratch2, |
409 Register heap_number_map, | 409 Register scratch3, |
410 Register scratch1, | 410 DwVfpRegister double_scratch, |
411 Register scratch2, | 411 Label* not_int32); |
412 DwVfpRegister double_scratch, | |
413 Label* not_int32); | |
414 | 412 |
415 // Load the number from object into double_dst in the double format. | 413 // Load the number from object into double_dst in the double format. |
416 // Control will jump to not_int32 if the value cannot be exactly represented | 414 // Control will jump to not_int32 if the value cannot be exactly represented |
417 // by a 32-bit integer. | 415 // by a 32-bit integer. |
418 // Floating point value in the 32-bit integer range that are not exact integer | 416 // Floating point value in the 32-bit integer range that are not exact integer |
419 // won't be loaded. | 417 // won't be loaded. |
420 static void LoadNumberAsInt32Double(MacroAssembler* masm, | 418 static void LoadNumberAsInt32Double(MacroAssembler* masm, |
421 Register object, | 419 Register object, |
422 Destination destination, | 420 Destination destination, |
423 DwVfpRegister double_dst, | 421 DwVfpRegister double_dst, |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 ConvertToDoubleStub stub(dst2, dst1, scratch1, scratch2); | 597 ConvertToDoubleStub stub(dst2, dst1, scratch1, scratch2); |
600 __ push(lr); | 598 __ push(lr); |
601 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); | 599 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); |
602 __ pop(lr); | 600 __ pop(lr); |
603 } | 601 } |
604 | 602 |
605 __ bind(&done); | 603 __ bind(&done); |
606 } | 604 } |
607 | 605 |
608 | 606 |
609 void FloatingPointHelper::LoadNumberAsInteger(MacroAssembler* masm, | 607 void FloatingPointHelper::ConvertNumberToInt32(MacroAssembler* masm, |
610 Register object, | 608 Register object, |
611 Register dst, | 609 Register dst, |
612 Register heap_number_map, | 610 Register heap_number_map, |
613 Register scratch1, | 611 Register scratch1, |
614 Register scratch2, | 612 Register scratch2, |
615 DwVfpRegister double_scratch, | 613 Register scratch3, |
616 Label* not_int32) { | 614 DwVfpRegister double_scratch, |
| 615 Label* not_number) { |
617 if (FLAG_debug_code) { | 616 if (FLAG_debug_code) { |
618 __ AbortIfNotRootValue(heap_number_map, | 617 __ AbortIfNotRootValue(heap_number_map, |
619 Heap::kHeapNumberMapRootIndex, | 618 Heap::kHeapNumberMapRootIndex, |
620 "HeapNumberMap register clobbered."); | 619 "HeapNumberMap register clobbered."); |
621 } | 620 } |
622 Label is_smi, done; | 621 Label is_smi; |
| 622 Label done; |
| 623 Label not_in_int32_range; |
| 624 |
623 __ JumpIfSmi(object, &is_smi); | 625 __ JumpIfSmi(object, &is_smi); |
624 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); | 626 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); |
625 __ cmp(scratch1, heap_number_map); | 627 __ cmp(scratch1, heap_number_map); |
626 __ b(ne, not_int32); | 628 __ b(ne, not_number); |
627 __ ConvertToInt32( | 629 __ ConvertToInt32(object, |
628 object, dst, scratch1, scratch2, double_scratch, not_int32); | 630 dst, |
| 631 scratch1, |
| 632 scratch2, |
| 633 double_scratch, |
| 634 ¬_in_int32_range); |
629 __ jmp(&done); | 635 __ jmp(&done); |
| 636 |
| 637 __ bind(¬_in_int32_range); |
| 638 __ ldr(scratch2, FieldMemOperand(object, HeapNumber::kExponentOffset)); |
| 639 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMantissaOffset)); |
| 640 |
| 641 // Register scratch1 contains mantissa word, scratch2 contains |
| 642 // sign, exponent and mantissa. Extract biased exponent into dst. |
| 643 __ Ubfx(dst, |
| 644 scratch2, |
| 645 HeapNumber::kExponentShift, |
| 646 HeapNumber::kExponentBits); |
| 647 |
| 648 // Express exponent as delta to 31. |
| 649 __ sub(dst, dst, Operand(HeapNumber::kExponentBias + 31)); |
| 650 |
| 651 Label normal_exponent; |
| 652 // If the delta is larger than kMantissaBits plus one, all bits |
| 653 // would be shifted away, which means that we can return 0. |
| 654 __ cmp(dst, Operand(HeapNumber::kMantissaBits + 1)); |
| 655 __ b(&normal_exponent, lt); |
| 656 __ mov(dst, Operand(0)); |
| 657 __ jmp(&done); |
| 658 |
| 659 __ bind(&normal_exponent); |
| 660 const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1; |
| 661 // Calculate shift. |
| 662 __ add(scratch3, dst, Operand(kShiftBase)); |
| 663 |
| 664 // Put implicit 1 before the mantissa part in scratch2. |
| 665 __ orr(scratch2, |
| 666 scratch2, |
| 667 Operand(1 << HeapNumber::kMantissaBitsInTopWord)); |
| 668 |
| 669 // Save sign. |
| 670 Register sign = dst; |
| 671 __ and_(sign, scratch2, Operand(HeapNumber::kSignMask)); |
| 672 |
| 673 // Shift mantisssa bits the correct position in high word. |
| 674 __ mov(scratch2, Operand(scratch2, LSL, scratch3)); |
| 675 |
| 676 // Replace the shifted bits with bits from the lower mantissa word. |
| 677 Label pos_shift, shift_done; |
| 678 __ rsb(scratch3, scratch3, Operand(32), SetCC); |
| 679 __ b(&pos_shift, ge); |
| 680 |
| 681 // Negate scratch3. |
| 682 __ rsb(scratch3, scratch3, Operand(0)); |
| 683 __ mov(scratch1, Operand(scratch1, LSL, scratch3)); |
| 684 __ jmp(&shift_done); |
| 685 |
| 686 __ bind(&pos_shift); |
| 687 __ mov(scratch1, Operand(scratch1, LSR, scratch3)); |
| 688 |
| 689 __ bind(&shift_done); |
| 690 __ orr(scratch2, scratch2, Operand(scratch1)); |
| 691 |
| 692 // Restore sign if necessary. |
| 693 __ cmp(sign, Operand(0)); |
| 694 __ rsb(dst, scratch2, Operand(0), LeaveCC, ne); |
| 695 __ mov(dst, scratch2, LeaveCC, eq); |
| 696 __ jmp(&done); |
| 697 |
630 __ bind(&is_smi); | 698 __ bind(&is_smi); |
631 __ SmiUntag(dst, object); | 699 __ SmiUntag(dst, object); |
632 __ bind(&done); | 700 __ bind(&done); |
633 } | 701 } |
634 | 702 |
635 | 703 |
636 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, | 704 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, |
637 Register object, | 705 Register object, |
638 Destination destination, | 706 Destination destination, |
639 DwVfpRegister double_dst, | 707 DwVfpRegister double_dst, |
(...skipping 2377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3017 | 3085 |
3018 | 3086 |
3019 void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm, | 3087 void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm, |
3020 bool smi_operands, | 3088 bool smi_operands, |
3021 Label* not_numbers, | 3089 Label* not_numbers, |
3022 Label* gc_required) { | 3090 Label* gc_required) { |
3023 Register left = r1; | 3091 Register left = r1; |
3024 Register right = r0; | 3092 Register right = r0; |
3025 Register scratch1 = r7; | 3093 Register scratch1 = r7; |
3026 Register scratch2 = r9; | 3094 Register scratch2 = r9; |
| 3095 Register scratch3 = r4; |
3027 | 3096 |
3028 ASSERT(smi_operands || (not_numbers != NULL)); | 3097 ASSERT(smi_operands || (not_numbers != NULL)); |
3029 if (smi_operands && FLAG_debug_code) { | 3098 if (smi_operands && FLAG_debug_code) { |
3030 __ AbortIfNotSmi(left); | 3099 __ AbortIfNotSmi(left); |
3031 __ AbortIfNotSmi(right); | 3100 __ AbortIfNotSmi(right); |
3032 } | 3101 } |
3033 | 3102 |
3034 Register heap_number_map = r6; | 3103 Register heap_number_map = r6; |
3035 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 3104 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
3036 | 3105 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3104 case Token::BIT_XOR: | 3173 case Token::BIT_XOR: |
3105 case Token::BIT_AND: | 3174 case Token::BIT_AND: |
3106 case Token::SAR: | 3175 case Token::SAR: |
3107 case Token::SHR: | 3176 case Token::SHR: |
3108 case Token::SHL: { | 3177 case Token::SHL: { |
3109 if (smi_operands) { | 3178 if (smi_operands) { |
3110 __ SmiUntag(r3, left); | 3179 __ SmiUntag(r3, left); |
3111 __ SmiUntag(r2, right); | 3180 __ SmiUntag(r2, right); |
3112 } else { | 3181 } else { |
3113 // Convert operands to 32-bit integers. Right in r2 and left in r3. | 3182 // Convert operands to 32-bit integers. Right in r2 and left in r3. |
3114 FloatingPointHelper::LoadNumberAsInteger(masm, | 3183 FloatingPointHelper::ConvertNumberToInt32(masm, |
3115 left, | 3184 left, |
3116 r3, | 3185 r3, |
3117 heap_number_map, | 3186 heap_number_map, |
3118 scratch1, | 3187 scratch1, |
3119 scratch2, | 3188 scratch2, |
3120 d0, | 3189 scratch3, |
3121 not_numbers); | 3190 d0, |
3122 FloatingPointHelper::LoadNumberAsInteger(masm, | 3191 not_numbers); |
3123 right, | 3192 FloatingPointHelper::ConvertNumberToInt32(masm, |
3124 r2, | 3193 right, |
3125 heap_number_map, | 3194 r2, |
3126 scratch1, | 3195 heap_number_map, |
3127 scratch2, | 3196 scratch1, |
3128 d0, | 3197 scratch2, |
3129 not_numbers); | 3198 scratch3, |
| 3199 d0, |
| 3200 not_numbers); |
3130 } | 3201 } |
3131 | 3202 |
3132 Label result_not_a_smi; | 3203 Label result_not_a_smi; |
3133 switch (op_) { | 3204 switch (op_) { |
3134 case Token::BIT_OR: | 3205 case Token::BIT_OR: |
3135 __ orr(r2, r3, Operand(r2)); | 3206 __ orr(r2, r3, Operand(r2)); |
3136 break; | 3207 break; |
3137 case Token::BIT_XOR: | 3208 case Token::BIT_XOR: |
3138 __ eor(r2, r3, Operand(r2)); | 3209 __ eor(r2, r3, Operand(r2)); |
3139 break; | 3210 break; |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3565 __ bind(&transition); | 3636 __ bind(&transition); |
3566 GenerateTypeTransition(masm); | 3637 GenerateTypeTransition(masm); |
3567 } | 3638 } |
3568 | 3639 |
3569 __ bind(&call_runtime); | 3640 __ bind(&call_runtime); |
3570 GenerateCallRuntime(masm); | 3641 GenerateCallRuntime(masm); |
3571 } | 3642 } |
3572 | 3643 |
3573 | 3644 |
3574 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { | 3645 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
3575 Label not_numbers, call_runtime; | 3646 Label call_runtime; |
3576 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); | 3647 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); |
3577 | 3648 |
3578 GenerateFPOperation(masm, false, ¬_numbers, &call_runtime); | 3649 GenerateFPOperation(masm, false, &call_runtime, &call_runtime); |
3579 | |
3580 __ bind(¬_numbers); | |
3581 GenerateTypeTransition(masm); | |
3582 | 3650 |
3583 __ bind(&call_runtime); | 3651 __ bind(&call_runtime); |
3584 GenerateCallRuntime(masm); | 3652 GenerateCallRuntime(masm); |
3585 } | 3653 } |
3586 | 3654 |
3587 | 3655 |
3588 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 3656 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
3589 Label call_runtime, call_string_add_or_runtime; | 3657 Label call_runtime, call_string_add_or_runtime; |
3590 | 3658 |
3591 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); | 3659 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); |
(...skipping 3238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6830 __ str(pc, MemOperand(sp, 0)); | 6898 __ str(pc, MemOperand(sp, 0)); |
6831 __ Jump(target); // Call the C++ function. | 6899 __ Jump(target); // Call the C++ function. |
6832 } | 6900 } |
6833 | 6901 |
6834 | 6902 |
6835 #undef __ | 6903 #undef __ |
6836 | 6904 |
6837 } } // namespace v8::internal | 6905 } } // namespace v8::internal |
6838 | 6906 |
6839 #endif // V8_TARGET_ARCH_ARM | 6907 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |