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

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

Issue 6274009: ARM: Merging constants in simulator and assembler header files and other clea... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 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
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 23 matching lines...) Expand all
34 #include "regexp-macro-assembler.h" 34 #include "regexp-macro-assembler.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 39
40 #define __ ACCESS_MASM(masm) 40 #define __ ACCESS_MASM(masm)
41 41
42 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 42 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
43 Label* slow, 43 Label* slow,
44 Condition cc, 44 Condition cond,
45 bool never_nan_nan); 45 bool never_nan_nan);
46 static void EmitSmiNonsmiComparison(MacroAssembler* masm, 46 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
47 Register lhs, 47 Register lhs,
48 Register rhs, 48 Register rhs,
49 Label* lhs_not_nan, 49 Label* lhs_not_nan,
50 Label* slow, 50 Label* slow,
51 bool strict); 51 bool strict);
52 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc); 52 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cond);
53 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, 53 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
54 Register lhs, 54 Register lhs,
55 Register rhs); 55 Register rhs);
56 56
57 57
58 void FastNewClosureStub::Generate(MacroAssembler* masm) { 58 void FastNewClosureStub::Generate(MacroAssembler* masm) {
59 // Create a new closure from the given function info in new 59 // Create a new closure from the given function info in new
60 // space. Set the context to the current context in cp. 60 // space. Set the context to the current context in cp.
61 Label gc; 61 Label gc;
62 62
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset)); 537 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset));
538 __ Ret(); 538 __ Ret();
539 } 539 }
540 540
541 541
542 // Handle the case where the lhs and rhs are the same object. 542 // Handle the case where the lhs and rhs are the same object.
543 // Equality is almost reflexive (everything but NaN), so this is a test 543 // Equality is almost reflexive (everything but NaN), so this is a test
544 // for "identity and not NaN". 544 // for "identity and not NaN".
545 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 545 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
546 Label* slow, 546 Label* slow,
547 Condition cc, 547 Condition cond,
548 bool never_nan_nan) { 548 bool never_nan_nan) {
549 Label not_identical; 549 Label not_identical;
550 Label heap_number, return_equal; 550 Label heap_number, return_equal;
551 __ cmp(r0, r1); 551 __ cmp(r0, r1);
552 __ b(ne, &not_identical); 552 __ b(ne, &not_identical);
553 553
554 // The two objects are identical. If we know that one of them isn't NaN then 554 // The two objects are identical. If we know that one of them isn't NaN then
555 // we now know they test equal. 555 // we now know they test equal.
556 if (cc != eq || !never_nan_nan) { 556 if (cond != eq || !never_nan_nan) {
557 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(), 557 // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
558 // so we do the second best thing - test it ourselves. 558 // so we do the second best thing - test it ourselves.
559 // They are both equal and they are not both Smis so both of them are not 559 // They are both equal and they are not both Smis so both of them are not
560 // Smis. If it's not a heap number, then return equal. 560 // Smis. If it's not a heap number, then return equal.
561 if (cc == lt || cc == gt) { 561 if (cond == lt || cond == gt) {
562 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE); 562 __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE);
563 __ b(ge, slow); 563 __ b(ge, slow);
564 } else { 564 } else {
565 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); 565 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
566 __ b(eq, &heap_number); 566 __ b(eq, &heap_number);
567 // Comparing JS objects with <=, >= is complicated. 567 // Comparing JS objects with <=, >= is complicated.
568 if (cc != eq) { 568 if (cond != eq) {
569 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE)); 569 __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
570 __ b(ge, slow); 570 __ b(ge, slow);
571 // Normally here we fall through to return_equal, but undefined is 571 // Normally here we fall through to return_equal, but undefined is
572 // special: (undefined == undefined) == true, but 572 // special: (undefined == undefined) == true, but
573 // (undefined <= undefined) == false! See ECMAScript 11.8.5. 573 // (undefined <= undefined) == false! See ECMAScript 11.8.5.
574 if (cc == le || cc == ge) { 574 if (cond == le || cond == ge) {
575 __ cmp(r4, Operand(ODDBALL_TYPE)); 575 __ cmp(r4, Operand(ODDBALL_TYPE));
576 __ b(ne, &return_equal); 576 __ b(ne, &return_equal);
577 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 577 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
578 __ cmp(r0, r2); 578 __ cmp(r0, r2);
579 __ b(ne, &return_equal); 579 __ b(ne, &return_equal);
580 if (cc == le) { 580 if (cond == le) {
581 // undefined <= undefined should fail. 581 // undefined <= undefined should fail.
582 __ mov(r0, Operand(GREATER)); 582 __ mov(r0, Operand(GREATER));
583 } else { 583 } else {
584 // undefined >= undefined should fail. 584 // undefined >= undefined should fail.
585 __ mov(r0, Operand(LESS)); 585 __ mov(r0, Operand(LESS));
586 } 586 }
587 __ Ret(); 587 __ Ret();
588 } 588 }
589 } 589 }
590 } 590 }
591 } 591 }
592 592
593 __ bind(&return_equal); 593 __ bind(&return_equal);
594 if (cc == lt) { 594 if (cond == lt) {
595 __ mov(r0, Operand(GREATER)); // Things aren't less than themselves. 595 __ mov(r0, Operand(GREATER)); // Things aren't less than themselves.
596 } else if (cc == gt) { 596 } else if (cond == gt) {
597 __ mov(r0, Operand(LESS)); // Things aren't greater than themselves. 597 __ mov(r0, Operand(LESS)); // Things aren't greater than themselves.
598 } else { 598 } else {
599 __ mov(r0, Operand(EQUAL)); // Things are <=, >=, ==, === themselves. 599 __ mov(r0, Operand(EQUAL)); // Things are <=, >=, ==, === themselves.
600 } 600 }
601 __ Ret(); 601 __ Ret();
602 602
603 if (cc != eq || !never_nan_nan) { 603 if (cond != eq || !never_nan_nan) {
604 // For less and greater we don't have to check for NaN since the result of 604 // For less and greater we don't have to check for NaN since the result of
605 // x < x is false regardless. For the others here is some code to check 605 // x < x is false regardless. For the others here is some code to check
606 // for NaN. 606 // for NaN.
607 if (cc != lt && cc != gt) { 607 if (cond != lt && cond != gt) {
608 __ bind(&heap_number); 608 __ bind(&heap_number);
609 // It is a heap number, so return non-equal if it's NaN and equal if it's 609 // It is a heap number, so return non-equal if it's NaN and equal if it's
610 // not NaN. 610 // not NaN.
611 611
612 // The representation of NaN values has all exponent bits (52..62) set, 612 // The representation of NaN values has all exponent bits (52..62) set,
613 // and not all mantissa bits (0..51) clear. 613 // and not all mantissa bits (0..51) clear.
614 // Read top bits of double representation (second word of value). 614 // Read top bits of double representation (second word of value).
615 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); 615 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
616 // Test that exponent bits are all set. 616 // Test that exponent bits are all set.
617 __ Sbfx(r3, r2, HeapNumber::kExponentShift, HeapNumber::kExponentBits); 617 __ Sbfx(r3, r2, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
618 // NaNs have all-one exponents so they sign extend to -1. 618 // NaNs have all-one exponents so they sign extend to -1.
619 __ cmp(r3, Operand(-1)); 619 __ cmp(r3, Operand(-1));
620 __ b(ne, &return_equal); 620 __ b(ne, &return_equal);
621 621
622 // Shift out flag and all exponent bits, retaining only mantissa. 622 // Shift out flag and all exponent bits, retaining only mantissa.
623 __ mov(r2, Operand(r2, LSL, HeapNumber::kNonMantissaBitsInTopWord)); 623 __ mov(r2, Operand(r2, LSL, HeapNumber::kNonMantissaBitsInTopWord));
624 // Or with all low-bits of mantissa. 624 // Or with all low-bits of mantissa.
625 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); 625 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
626 __ orr(r0, r3, Operand(r2), SetCC); 626 __ orr(r0, r3, Operand(r2), SetCC);
627 // For equal we already have the right value in r0: Return zero (equal) 627 // For equal we already have the right value in r0: Return zero (equal)
628 // if all bits in mantissa are zero (it's an Infinity) and non-zero if 628 // if all bits in mantissa are zero (it's an Infinity) and non-zero if
629 // not (it's a NaN). For <= and >= we need to load r0 with the failing 629 // not (it's a NaN). For <= and >= we need to load r0 with the failing
630 // value if it's a NaN. 630 // value if it's a NaN.
631 if (cc != eq) { 631 if (cond != eq) {
632 // All-zero means Infinity means equal. 632 // All-zero means Infinity means equal.
633 __ Ret(eq); 633 __ Ret(eq);
634 if (cc == le) { 634 if (cond == le) {
635 __ mov(r0, Operand(GREATER)); // NaN <= NaN should fail. 635 __ mov(r0, Operand(GREATER)); // NaN <= NaN should fail.
636 } else { 636 } else {
637 __ mov(r0, Operand(LESS)); // NaN >= NaN should fail. 637 __ mov(r0, Operand(LESS)); // NaN >= NaN should fail.
638 } 638 }
639 } 639 }
640 __ Ret(); 640 __ Ret();
641 } 641 }
642 // No fall through here. 642 // No fall through here.
643 } 643 }
644 644
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 // Convert rhs to a double in r0, r1. 731 // Convert rhs to a double in r0, r1.
732 __ mov(r7, Operand(rhs)); 732 __ mov(r7, Operand(rhs));
733 ConvertToDoubleStub stub2(r1, r0, r7, r6); 733 ConvertToDoubleStub stub2(r1, r0, r7, r6);
734 __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET); 734 __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
735 __ pop(lr); 735 __ pop(lr);
736 } 736 }
737 // Fall through to both_loaded_as_doubles. 737 // Fall through to both_loaded_as_doubles.
738 } 738 }
739 739
740 740
741 void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cc) { 741 void EmitNanCheck(MacroAssembler* masm, Label* lhs_not_nan, Condition cond) {
742 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset); 742 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
743 Register rhs_exponent = exp_first ? r0 : r1; 743 Register rhs_exponent = exp_first ? r0 : r1;
744 Register lhs_exponent = exp_first ? r2 : r3; 744 Register lhs_exponent = exp_first ? r2 : r3;
745 Register rhs_mantissa = exp_first ? r1 : r0; 745 Register rhs_mantissa = exp_first ? r1 : r0;
746 Register lhs_mantissa = exp_first ? r3 : r2; 746 Register lhs_mantissa = exp_first ? r3 : r2;
747 Label one_is_nan, neither_is_nan; 747 Label one_is_nan, neither_is_nan;
748 748
749 __ Sbfx(r4, 749 __ Sbfx(r4,
750 lhs_exponent, 750 lhs_exponent,
751 HeapNumber::kExponentShift, 751 HeapNumber::kExponentShift,
(...skipping 19 matching lines...) Expand all
771 __ mov(r4, 771 __ mov(r4,
772 Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord), 772 Operand(rhs_exponent, LSL, HeapNumber::kNonMantissaBitsInTopWord),
773 SetCC); 773 SetCC);
774 __ b(ne, &one_is_nan); 774 __ b(ne, &one_is_nan);
775 __ cmp(rhs_mantissa, Operand(0, RelocInfo::NONE)); 775 __ cmp(rhs_mantissa, Operand(0, RelocInfo::NONE));
776 __ b(eq, &neither_is_nan); 776 __ b(eq, &neither_is_nan);
777 777
778 __ bind(&one_is_nan); 778 __ bind(&one_is_nan);
779 // NaN comparisons always fail. 779 // NaN comparisons always fail.
780 // Load whatever we need in r0 to make the comparison fail. 780 // Load whatever we need in r0 to make the comparison fail.
781 if (cc == lt || cc == le) { 781 if (cond == lt || cond == le) {
782 __ mov(r0, Operand(GREATER)); 782 __ mov(r0, Operand(GREATER));
783 } else { 783 } else {
784 __ mov(r0, Operand(LESS)); 784 __ mov(r0, Operand(LESS));
785 } 785 }
786 __ Ret(); 786 __ Ret();
787 787
788 __ bind(&neither_is_nan); 788 __ bind(&neither_is_nan);
789 } 789 }
790 790
791 791
792 // See comment at call site. 792 // See comment at call site.
793 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc) { 793 static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm,
794 Condition cond) {
794 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset); 795 bool exp_first = (HeapNumber::kExponentOffset == HeapNumber::kValueOffset);
795 Register rhs_exponent = exp_first ? r0 : r1; 796 Register rhs_exponent = exp_first ? r0 : r1;
796 Register lhs_exponent = exp_first ? r2 : r3; 797 Register lhs_exponent = exp_first ? r2 : r3;
797 Register rhs_mantissa = exp_first ? r1 : r0; 798 Register rhs_mantissa = exp_first ? r1 : r0;
798 Register lhs_mantissa = exp_first ? r3 : r2; 799 Register lhs_mantissa = exp_first ? r3 : r2;
799 800
800 // r0, r1, r2, r3 have the two doubles. Neither is a NaN. 801 // r0, r1, r2, r3 have the two doubles. Neither is a NaN.
801 if (cc == eq) { 802 if (cond == eq) {
802 // Doubles are not equal unless they have the same bit pattern. 803 // Doubles are not equal unless they have the same bit pattern.
803 // Exception: 0 and -0. 804 // Exception: 0 and -0.
804 __ cmp(rhs_mantissa, Operand(lhs_mantissa)); 805 __ cmp(rhs_mantissa, Operand(lhs_mantissa));
805 __ orr(r0, rhs_mantissa, Operand(lhs_mantissa), LeaveCC, ne); 806 __ orr(r0, rhs_mantissa, Operand(lhs_mantissa), LeaveCC, ne);
806 // Return non-zero if the numbers are unequal. 807 // Return non-zero if the numbers are unequal.
807 __ Ret(ne); 808 __ Ret(ne);
808 809
809 __ sub(r0, rhs_exponent, Operand(lhs_exponent), SetCC); 810 __ sub(r0, rhs_exponent, Operand(lhs_exponent), SetCC);
810 // If exponents are equal then return 0. 811 // If exponents are equal then return 0.
811 __ Ret(eq); 812 __ Ret(eq);
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 __ orr(r2, r1, r0); 1081 __ orr(r2, r1, r0);
1081 __ tst(r2, Operand(kSmiTagMask)); 1082 __ tst(r2, Operand(kSmiTagMask));
1082 __ b(ne, &not_two_smis); 1083 __ b(ne, &not_two_smis);
1083 __ mov(r1, Operand(r1, ASR, 1)); 1084 __ mov(r1, Operand(r1, ASR, 1));
1084 __ sub(r0, r1, Operand(r0, ASR, 1)); 1085 __ sub(r0, r1, Operand(r0, ASR, 1));
1085 __ Ret(); 1086 __ Ret();
1086 __ bind(&not_two_smis); 1087 __ bind(&not_two_smis);
1087 } else if (FLAG_debug_code) { 1088 } else if (FLAG_debug_code) {
1088 __ orr(r2, r1, r0); 1089 __ orr(r2, r1, r0);
1089 __ tst(r2, Operand(kSmiTagMask)); 1090 __ tst(r2, Operand(kSmiTagMask));
1090 __ Assert(nz, "CompareStub: unexpected smi operands."); 1091 __ Assert(ne, "CompareStub: unexpected smi operands.");
1091 } 1092 }
1092 1093
1093 // NOTICE! This code is only reached after a smi-fast-case check, so 1094 // NOTICE! This code is only reached after a smi-fast-case check, so
1094 // it is certain that at least one operand isn't a smi. 1095 // it is certain that at least one operand isn't a smi.
1095 1096
1096 // Handle the case where the objects are identical. Either returns the answer 1097 // Handle the case where the objects are identical. Either returns the answer
1097 // or goes to slow. Only falls through if the objects were not identical. 1098 // or goes to slow. Only falls through if the objects were not identical.
1098 EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_); 1099 EmitIdenticalObjectComparison(masm, &slow, cc_, never_nan_nan_);
1099 1100
1100 // If either is a Smi (we know that not both are), then they can only 1101 // If either is a Smi (we know that not both are), then they can only
(...skipping 2691 matching lines...) Expand 10 before | Expand all | Expand 10 after
3792 STATIC_ASSERT(kSmiTag == 0); 3793 STATIC_ASSERT(kSmiTag == 0);
3793 __ tst(r0, Operand(kSmiTagMask)); 3794 __ tst(r0, Operand(kSmiTagMask));
3794 __ b(eq, &runtime); 3795 __ b(eq, &runtime);
3795 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); 3796 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
3796 __ b(ne, &runtime); 3797 __ b(ne, &runtime);
3797 3798
3798 // Check that the RegExp has been compiled (data contains a fixed array). 3799 // Check that the RegExp has been compiled (data contains a fixed array).
3799 __ ldr(regexp_data, FieldMemOperand(r0, JSRegExp::kDataOffset)); 3800 __ ldr(regexp_data, FieldMemOperand(r0, JSRegExp::kDataOffset));
3800 if (FLAG_debug_code) { 3801 if (FLAG_debug_code) {
3801 __ tst(regexp_data, Operand(kSmiTagMask)); 3802 __ tst(regexp_data, Operand(kSmiTagMask));
3802 __ Check(nz, "Unexpected type for RegExp data, FixedArray expected"); 3803 __ Check(ne, "Unexpected type for RegExp data, FixedArray expected");
3803 __ CompareObjectType(regexp_data, r0, r0, FIXED_ARRAY_TYPE); 3804 __ CompareObjectType(regexp_data, r0, r0, FIXED_ARRAY_TYPE);
3804 __ Check(eq, "Unexpected type for RegExp data, FixedArray expected"); 3805 __ Check(eq, "Unexpected type for RegExp data, FixedArray expected");
3805 } 3806 }
3806 3807
3807 // regexp_data: RegExp data (FixedArray) 3808 // regexp_data: RegExp data (FixedArray)
3808 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP. 3809 // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
3809 __ ldr(r0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset)); 3810 __ ldr(r0, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset));
3810 __ cmp(r0, Operand(Smi::FromInt(JSRegExp::IRREGEXP))); 3811 __ cmp(r0, Operand(Smi::FromInt(JSRegExp::IRREGEXP)));
3811 __ b(ne, &runtime); 3812 __ b(ne, &runtime);
3812 3813
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3895 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset)); 3896 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset));
3896 __ LoadRoot(r1, Heap::kEmptyStringRootIndex); 3897 __ LoadRoot(r1, Heap::kEmptyStringRootIndex);
3897 __ cmp(r0, r1); 3898 __ cmp(r0, r1);
3898 __ b(ne, &runtime); 3899 __ b(ne, &runtime);
3899 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); 3900 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
3900 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); 3901 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
3901 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); 3902 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
3902 // Is first part a flat string? 3903 // Is first part a flat string?
3903 STATIC_ASSERT(kSeqStringTag == 0); 3904 STATIC_ASSERT(kSeqStringTag == 0);
3904 __ tst(r0, Operand(kStringRepresentationMask)); 3905 __ tst(r0, Operand(kStringRepresentationMask));
3905 __ b(nz, &runtime); 3906 __ b(ne, &runtime);
3906 3907
3907 __ bind(&seq_string); 3908 __ bind(&seq_string);
3908 // subject: Subject string 3909 // subject: Subject string
3909 // regexp_data: RegExp data (FixedArray) 3910 // regexp_data: RegExp data (FixedArray)
3910 // r0: Instance type of subject string 3911 // r0: Instance type of subject string
3911 STATIC_ASSERT(4 == kAsciiStringTag); 3912 STATIC_ASSERT(4 == kAsciiStringTag);
3912 STATIC_ASSERT(kTwoByteStringTag == 0); 3913 STATIC_ASSERT(kTwoByteStringTag == 0);
3913 // Find the code object based on the assumptions above. 3914 // Find the code object based on the assumptions above.
3914 __ and_(r0, r0, Operand(kStringEncodingMask)); 3915 __ and_(r0, r0, Operand(kStringEncodingMask));
3915 __ mov(r3, Operand(r0, ASR, 2), SetCC); 3916 __ mov(r3, Operand(r0, ASR, 2), SetCC);
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
4343 __ LoadRoot(ip, Heap::kEmptyStringRootIndex); 4344 __ LoadRoot(ip, Heap::kEmptyStringRootIndex);
4344 __ cmp(result_, Operand(ip)); 4345 __ cmp(result_, Operand(ip));
4345 __ b(ne, &call_runtime_); 4346 __ b(ne, &call_runtime_);
4346 // Get the first of the two strings and load its instance type. 4347 // Get the first of the two strings and load its instance type.
4347 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset)); 4348 __ ldr(object_, FieldMemOperand(object_, ConsString::kFirstOffset));
4348 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 4349 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
4349 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 4350 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
4350 // If the first cons component is also non-flat, then go to runtime. 4351 // If the first cons component is also non-flat, then go to runtime.
4351 STATIC_ASSERT(kSeqStringTag == 0); 4352 STATIC_ASSERT(kSeqStringTag == 0);
4352 __ tst(result_, Operand(kStringRepresentationMask)); 4353 __ tst(result_, Operand(kStringRepresentationMask));
4353 __ b(nz, &call_runtime_); 4354 __ b(ne, &call_runtime_);
4354 4355
4355 // Check for 1-byte or 2-byte string. 4356 // Check for 1-byte or 2-byte string.
4356 __ bind(&flat_string); 4357 __ bind(&flat_string);
4357 STATIC_ASSERT(kAsciiStringTag != 0); 4358 STATIC_ASSERT(kAsciiStringTag != 0);
4358 __ tst(result_, Operand(kStringEncodingMask)); 4359 __ tst(result_, Operand(kStringEncodingMask));
4359 __ b(nz, &ascii_string); 4360 __ b(ne, &ascii_string);
4360 4361
4361 // 2-byte string. 4362 // 2-byte string.
4362 // Load the 2-byte character code into the result register. We can 4363 // Load the 2-byte character code into the result register. We can
4363 // add without shifting since the smi tag size is the log2 of the 4364 // add without shifting since the smi tag size is the log2 of the
4364 // number of bytes in a two-byte character. 4365 // number of bytes in a two-byte character.
4365 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1 && kSmiShiftSize == 0); 4366 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1 && kSmiShiftSize == 0);
4366 __ add(scratch_, object_, Operand(scratch_)); 4367 __ add(scratch_, object_, Operand(scratch_));
4367 __ ldrh(result_, FieldMemOperand(scratch_, SeqTwoByteString::kHeaderSize)); 4368 __ ldrh(result_, FieldMemOperand(scratch_, SeqTwoByteString::kHeaderSize));
4368 __ jmp(&got_char_code); 4369 __ jmp(&got_char_code);
4369 4370
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
4434 // StringCharFromCodeGenerator 4435 // StringCharFromCodeGenerator
4435 4436
4436 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { 4437 void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
4437 // Fast case of Heap::LookupSingleCharacterStringFromCode. 4438 // Fast case of Heap::LookupSingleCharacterStringFromCode.
4438 STATIC_ASSERT(kSmiTag == 0); 4439 STATIC_ASSERT(kSmiTag == 0);
4439 STATIC_ASSERT(kSmiShiftSize == 0); 4440 STATIC_ASSERT(kSmiShiftSize == 0);
4440 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1)); 4441 ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
4441 __ tst(code_, 4442 __ tst(code_,
4442 Operand(kSmiTagMask | 4443 Operand(kSmiTagMask |
4443 ((~String::kMaxAsciiCharCode) << kSmiTagSize))); 4444 ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
4444 __ b(nz, &slow_case_); 4445 __ b(ne, &slow_case_);
4445 4446
4446 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 4447 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
4447 // At this point code register contains smi tagged ascii char code. 4448 // At this point code register contains smi tagged ascii char code.
4448 STATIC_ASSERT(kSmiTag == 0); 4449 STATIC_ASSERT(kSmiTag == 0);
4449 __ add(result_, result_, Operand(code_, LSL, kPointerSizeLog2 - kSmiTagSize)); 4450 __ add(result_, result_, Operand(code_, LSL, kPointerSizeLog2 - kSmiTagSize));
4450 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 4451 __ ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
4451 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 4452 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
4452 __ cmp(result_, Operand(ip)); 4453 __ cmp(result_, Operand(ip));
4453 __ b(eq, &slow_case_); 4454 __ b(eq, &slow_case_);
4454 __ bind(&exit_); 4455 __ bind(&exit_);
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
4881 void StringHelper::GenerateHashGetHash(MacroAssembler* masm, 4882 void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
4882 Register hash) { 4883 Register hash) {
4883 // hash += hash << 3; 4884 // hash += hash << 3;
4884 __ add(hash, hash, Operand(hash, LSL, 3)); 4885 __ add(hash, hash, Operand(hash, LSL, 3));
4885 // hash ^= hash >> 11; 4886 // hash ^= hash >> 11;
4886 __ eor(hash, hash, Operand(hash, ASR, 11)); 4887 __ eor(hash, hash, Operand(hash, ASR, 11));
4887 // hash += hash << 15; 4888 // hash += hash << 15;
4888 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); 4889 __ add(hash, hash, Operand(hash, LSL, 15), SetCC);
4889 4890
4890 // if (hash == 0) hash = 27; 4891 // if (hash == 0) hash = 27;
4891 __ mov(hash, Operand(27), LeaveCC, nz); 4892 __ mov(hash, Operand(27), LeaveCC, ne);
4892 } 4893 }
4893 4894
4894 4895
4895 void SubStringStub::Generate(MacroAssembler* masm) { 4896 void SubStringStub::Generate(MacroAssembler* masm) {
4896 Label runtime; 4897 Label runtime;
4897 4898
4898 // Stack frame on entry. 4899 // Stack frame on entry.
4899 // lr: return address 4900 // lr: return address
4900 // sp[0]: to 4901 // sp[0]: to
4901 // sp[4]: from 4902 // sp[4]: from
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after
5620 __ pop(r1); 5621 __ pop(r1);
5621 __ Jump(r2); 5622 __ Jump(r2);
5622 } 5623 }
5623 5624
5624 5625
5625 #undef __ 5626 #undef __
5626 5627
5627 } } // namespace v8::internal 5628 } } // namespace v8::internal
5628 5629
5629 #endif // V8_TARGET_ARCH_ARM 5630 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« src/arm/assembler-arm.cc ('K') | « src/arm/builtins-arm.cc ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698