| 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 |