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

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: Fix bug. 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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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, &not_in_int32_range);
629 __ jmp(&done); 634 __ jmp(&done);
635
636 __ bind(&not_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
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
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
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, &not_numbers, &call_runtime); 3657 GenerateFPOperation(masm, false, &call_runtime, &call_runtime);
3579
3580 __ bind(&not_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
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
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