Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 6658034: ARM: Implement inline conversion of heap numbers to int32 values for bitoperations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed text in source comments. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 &not_in_int32_range);
629 __ jmp(&done); 635 __ jmp(&done);
636
637 __ bind(&not_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
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
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
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, &not_numbers, &call_runtime); 3649 GenerateFPOperation(masm, false, &call_runtime, &call_runtime);
3579
3580 __ bind(&not_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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698