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