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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 // Loads the number from object into dst as a 32-bit integer if possible. If |
401 // the object cannot be converted to a 32-bit integer control continues at | 401 // the object cannot be converted to a 32-bit integer control continues at |
402 // the label not_int32. If VFP is supported double_scratch is used | 402 // the label not_int32. If VFP is supported double_scratch is used |
403 // but not scratch2. | 403 // but not scratch2. |
404 // Floating point value in the 32-bit integer range will be rounded | 404 // Floating point value in the 32-bit integer range will be rounded |
405 // to an integer. | 405 // to an integer. |
406 static void LoadNumberAsInteger(MacroAssembler* masm, | 406 static void LoadNumberAsInteger(MacroAssembler* masm, |
Søren Thygesen Gjesse
2011/03/10 14:20:30
Maybe this function should have a name that indica
Karl Klose
2011/03/11 09:27:39
Done. I renamed the function to ConvertNumberToInt
| |
407 Register object, | 407 Register object, |
408 Register dst, | 408 Register dst, |
409 Register heap_number_map, | 409 Register heap_number_map, |
410 Register scratch1, | 410 Register scratch1, |
411 Register scratch2, | 411 Register scratch2, |
412 Register scratch3, | |
412 DwVfpRegister double_scratch, | 413 DwVfpRegister double_scratch, |
413 Label* not_int32); | 414 Label* not_int32); |
414 | 415 |
415 // Load the number from object into double_dst in the double format. | 416 // 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 | 417 // Control will jump to not_int32 if the value cannot be exactly represented |
417 // by a 32-bit integer. | 418 // by a 32-bit integer. |
418 // Floating point value in the 32-bit integer range that are not exact integer | 419 // Floating point value in the 32-bit integer range that are not exact integer |
419 // won't be loaded. | 420 // won't be loaded. |
420 static void LoadNumberAsInt32Double(MacroAssembler* masm, | 421 static void LoadNumberAsInt32Double(MacroAssembler* masm, |
421 Register object, | 422 Register object, |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
605 __ bind(&done); | 606 __ bind(&done); |
606 } | 607 } |
607 | 608 |
608 | 609 |
609 void FloatingPointHelper::LoadNumberAsInteger(MacroAssembler* masm, | 610 void FloatingPointHelper::LoadNumberAsInteger(MacroAssembler* masm, |
610 Register object, | 611 Register object, |
611 Register dst, | 612 Register dst, |
612 Register heap_number_map, | 613 Register heap_number_map, |
613 Register scratch1, | 614 Register scratch1, |
614 Register scratch2, | 615 Register scratch2, |
616 Register scratch3, | |
615 DwVfpRegister double_scratch, | 617 DwVfpRegister double_scratch, |
616 Label* not_int32) { | 618 Label* not_int32) { |
617 if (FLAG_debug_code) { | 619 if (FLAG_debug_code) { |
618 __ AbortIfNotRootValue(heap_number_map, | 620 __ AbortIfNotRootValue(heap_number_map, |
619 Heap::kHeapNumberMapRootIndex, | 621 Heap::kHeapNumberMapRootIndex, |
620 "HeapNumberMap register clobbered."); | 622 "HeapNumberMap register clobbered."); |
621 } | 623 } |
622 Label is_smi, done; | 624 Label is_smi; |
625 Label done; | |
626 Label not_in_int32_range; | |
627 | |
623 __ JumpIfSmi(object, &is_smi); | 628 __ JumpIfSmi(object, &is_smi); |
624 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); | 629 __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); |
625 __ cmp(scratch1, heap_number_map); | 630 __ cmp(scratch1, heap_number_map); |
626 __ b(ne, not_int32); | 631 __ b(ne, not_int32); |
627 __ ConvertToInt32( | 632 __ ConvertToInt32( |
628 object, dst, scratch1, scratch2, double_scratch, not_int32); | 633 object, dst, scratch1, scratch2, double_scratch, ¬_in_int32_range); |
629 __ jmp(&done); | 634 __ jmp(&done); |
635 | |
636 __ bind(¬_in_int32_range); | |
637 if (CpuFeatures::IsSupported(VFP3)) { | |
638 CpuFeatures::Scope scope(VFP3); | |
Søren Thygesen Gjesse
2011/03/10 14:20:30
Should we not support non-vfp here? VFP instructio
Karl Klose
2011/03/11 09:27:39
Done, see comment below.
| |
639 __ vldr(double_scratch, FieldMemOperand(object, HeapNumber::kValueOffset)); | |
Rodolph Perfetta
2011/03/10 14:36:44
Use Ldrd, it will be faster (no transfer VFP-ARM)
Karl Klose
2011/03/11 09:27:39
I decided to use two ldr instructions to avoid put
| |
640 __ vmov(scratch1, scratch2, double_scratch); | |
641 | |
642 // Register scratch1 contains mantissa word, scratch2 contains | |
643 // sign, exponent and mantissa. | |
Rodolph Perfetta
2011/03/10 14:36:44
the and and mov could be rewritten as a Ubfx
Karl Klose
2011/03/11 09:27:39
Done.
| |
644 __ and_(dst, scratch2, Operand(HeapNumber::kExponentMask)); | |
645 __ mov(dst, Operand(dst, LSR, HeapNumber::kExponentShift)); | |
646 __ sub(dst, dst, Operand(1023)); | |
Søren Thygesen Gjesse
2011/03/10 14:20:30
1023 -> HeapNumber::kExponentBias
Karl Klose
2011/03/11 09:27:39
Done.
| |
647 | |
648 Label normal_exponent; | |
649 // Express exponent as delta to 31. | |
650 // If the delta is larger than 53, all bits would be shifted | |
651 // away, which means that we can return 0. | |
652 __ sub(dst, dst, Operand(31)); | |
Søren Thygesen Gjesse
2011/03/10 14:20:30
You could combine this sub with the one before sub
Karl Klose
2011/03/11 09:27:39
Done.
| |
653 __ cmp(dst, Operand(53)); | |
Søren Thygesen Gjesse
2011/03/10 14:20:30
We have HeapNumber::kMantissaBits which is 52.
Karl Klose
2011/03/11 09:27:39
Done.
| |
654 __ b(&normal_exponent, lt); | |
655 __ mov(dst, Operand(0)); | |
656 __ jmp(&done); | |
657 | |
658 __ bind(&normal_exponent); | |
659 const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1; | |
660 // Calculate shift. | |
661 __ add(scratch3, dst, Operand(kShiftBase)); | |
662 | |
663 // Put implicit 1 before the mantissa part in scratch2 and | |
664 // shift the mantissa bits to the correct position. | |
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 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, neg_shift; | |
678 // scratch3 = 32 - scratch3. | |
Rodolph Perfetta
2011/03/10 14:36:44
__ rsb(scratch3, scratch3, Operand(32), SetCC) can
Karl Klose
2011/03/11 09:27:39
Done.
| |
679 __ mvn(scratch3, Operand(scratch3)); | |
680 __ add(scratch3, scratch3, Operand(33)); | |
681 __ cmp(scratch3, Operand(0)); | |
682 __ b(&pos_shift, ge); | |
683 | |
684 // Negate scratch3. | |
Rodolph Perfetta
2011/03/10 14:36:44
__ rsb(scratch3, scratch3, Operand(0)) will neaget
Karl Klose
2011/03/11 09:27:39
Done.
| |
685 __ mvn(scratch3, Operand(scratch3)); | |
686 __ add(scratch3, scratch3, Operand(1)); | |
687 __ mov(scratch1, Operand(scratch1, LSL, scratch3)); | |
688 __ jmp(&neg_shift); | |
689 | |
690 __ bind(&pos_shift); | |
691 __ mov(scratch1, Operand(scratch1, LSR, scratch3)); | |
692 | |
693 __ bind(&neg_shift); | |
Søren Thygesen Gjesse
2011/03/10 14:20:30
neg_shift -> shift_done?
Karl Klose
2011/03/11 09:27:39
Done.
| |
694 __ orr(scratch2, scratch2, Operand(scratch1)); | |
695 | |
696 // Restore sign if necessary. | |
Rodolph Perfetta
2011/03/10 14:36:44
__ cmp(sign, Operand(0));
Karl Klose
2011/03/11 09:27:39
Done.
| |
697 __ tst(sign, sign); | |
Rodolph Perfetta
2011/03/10 14:36:44
rsb again here.
Karl Klose
2011/03/11 09:27:39
Done.
| |
698 __ mvn(scratch2, Operand(scratch2), LeaveCC, ne); | |
699 __ add(scratch2, scratch2, Operand(1), LeaveCC, ne); | |
700 __ mov(dst, scratch2); | |
701 __ jmp(&done); | |
702 } else { | |
703 __ jmp(not_int32); | |
704 } | |
705 | |
630 __ bind(&is_smi); | 706 __ bind(&is_smi); |
631 __ SmiUntag(dst, object); | 707 __ SmiUntag(dst, object); |
632 __ bind(&done); | 708 __ bind(&done); |
633 } | 709 } |
634 | 710 |
635 | 711 |
636 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, | 712 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, |
637 Register object, | 713 Register object, |
638 Destination destination, | 714 Destination destination, |
639 DwVfpRegister double_dst, | 715 DwVfpRegister double_dst, |
(...skipping 2377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3017 | 3093 |
3018 | 3094 |
3019 void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm, | 3095 void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm, |
3020 bool smi_operands, | 3096 bool smi_operands, |
3021 Label* not_numbers, | 3097 Label* not_numbers, |
3022 Label* gc_required) { | 3098 Label* gc_required) { |
3023 Register left = r1; | 3099 Register left = r1; |
3024 Register right = r0; | 3100 Register right = r0; |
3025 Register scratch1 = r7; | 3101 Register scratch1 = r7; |
3026 Register scratch2 = r9; | 3102 Register scratch2 = r9; |
3103 Register scratch3 = r4; | |
3027 | 3104 |
3028 ASSERT(smi_operands || (not_numbers != NULL)); | 3105 ASSERT(smi_operands || (not_numbers != NULL)); |
3029 if (smi_operands && FLAG_debug_code) { | 3106 if (smi_operands && FLAG_debug_code) { |
3030 __ AbortIfNotSmi(left); | 3107 __ AbortIfNotSmi(left); |
3031 __ AbortIfNotSmi(right); | 3108 __ AbortIfNotSmi(right); |
3032 } | 3109 } |
3033 | 3110 |
3034 Register heap_number_map = r6; | 3111 Register heap_number_map = r6; |
3035 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 3112 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
3036 | 3113 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3110 __ SmiUntag(r3, left); | 3187 __ SmiUntag(r3, left); |
3111 __ SmiUntag(r2, right); | 3188 __ SmiUntag(r2, right); |
3112 } else { | 3189 } else { |
3113 // Convert operands to 32-bit integers. Right in r2 and left in r3. | 3190 // Convert operands to 32-bit integers. Right in r2 and left in r3. |
3114 FloatingPointHelper::LoadNumberAsInteger(masm, | 3191 FloatingPointHelper::LoadNumberAsInteger(masm, |
3115 left, | 3192 left, |
3116 r3, | 3193 r3, |
3117 heap_number_map, | 3194 heap_number_map, |
3118 scratch1, | 3195 scratch1, |
3119 scratch2, | 3196 scratch2, |
3197 scratch3, | |
3120 d0, | 3198 d0, |
3121 not_numbers); | 3199 not_numbers); |
3122 FloatingPointHelper::LoadNumberAsInteger(masm, | 3200 FloatingPointHelper::LoadNumberAsInteger(masm, |
3123 right, | 3201 right, |
3124 r2, | 3202 r2, |
3125 heap_number_map, | 3203 heap_number_map, |
3126 scratch1, | 3204 scratch1, |
3127 scratch2, | 3205 scratch2, |
3206 scratch3, | |
3128 d0, | 3207 d0, |
3129 not_numbers); | 3208 not_numbers); |
3130 } | 3209 } |
3131 | 3210 |
3132 Label result_not_a_smi; | 3211 Label result_not_a_smi; |
3133 switch (op_) { | 3212 switch (op_) { |
3134 case Token::BIT_OR: | 3213 case Token::BIT_OR: |
3135 __ orr(r2, r3, Operand(r2)); | 3214 __ orr(r2, r3, Operand(r2)); |
3136 break; | 3215 break; |
3137 case Token::BIT_XOR: | 3216 case Token::BIT_XOR: |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3565 __ bind(&transition); | 3644 __ bind(&transition); |
3566 GenerateTypeTransition(masm); | 3645 GenerateTypeTransition(masm); |
3567 } | 3646 } |
3568 | 3647 |
3569 __ bind(&call_runtime); | 3648 __ bind(&call_runtime); |
3570 GenerateCallRuntime(masm); | 3649 GenerateCallRuntime(masm); |
3571 } | 3650 } |
3572 | 3651 |
3573 | 3652 |
3574 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { | 3653 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
3575 Label not_numbers, call_runtime; | 3654 Label call_runtime; |
3576 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); | 3655 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); |
3577 | 3656 |
3578 GenerateFPOperation(masm, false, ¬_numbers, &call_runtime); | 3657 GenerateFPOperation(masm, false, &call_runtime, &call_runtime); |
3579 | |
3580 __ bind(¬_numbers); | |
3581 GenerateTypeTransition(masm); | |
3582 | 3658 |
3583 __ bind(&call_runtime); | 3659 __ bind(&call_runtime); |
3584 GenerateCallRuntime(masm); | 3660 GenerateCallRuntime(masm); |
3585 } | 3661 } |
3586 | 3662 |
3587 | 3663 |
3588 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 3664 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
3589 Label call_runtime, call_string_add_or_runtime; | 3665 Label call_runtime, call_string_add_or_runtime; |
3590 | 3666 |
3591 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); | 3667 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)); | 6906 __ str(pc, MemOperand(sp, 0)); |
6831 __ Jump(target); // Call the C++ function. | 6907 __ Jump(target); // Call the C++ function. |
6832 } | 6908 } |
6833 | 6909 |
6834 | 6910 |
6835 #undef __ | 6911 #undef __ |
6836 | 6912 |
6837 } } // namespace v8::internal | 6913 } } // namespace v8::internal |
6838 | 6914 |
6839 #endif // V8_TARGET_ARCH_ARM | 6915 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |