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

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

Issue 542193003: MIPS: Rename ascii to one-byte where applicable. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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 | « src/mips/code-stubs-mips.h ('k') | src/mips/codegen-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_MIPS 7 #if V8_TARGET_ARCH_MIPS
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 __ bind(&check_for_internalized_strings); 738 __ bind(&check_for_internalized_strings);
739 if (cc == eq && !strict()) { 739 if (cc == eq && !strict()) {
740 // Returns an answer for two internalized strings or two 740 // Returns an answer for two internalized strings or two
741 // detectable objects. 741 // detectable objects.
742 // Otherwise jumps to string case or not both strings case. 742 // Otherwise jumps to string case or not both strings case.
743 // Assumes that a2 is the type of lhs_ on entry. 743 // Assumes that a2 is the type of lhs_ on entry.
744 EmitCheckForInternalizedStringsOrObjects( 744 EmitCheckForInternalizedStringsOrObjects(
745 masm, lhs, rhs, &flat_string_check, &slow); 745 masm, lhs, rhs, &flat_string_check, &slow);
746 } 746 }
747 747
748 // Check for both being sequential ASCII strings, and inline if that is the 748 // Check for both being sequential one-byte strings,
749 // case. 749 // and inline if that is the case.
750 __ bind(&flat_string_check); 750 __ bind(&flat_string_check);
751 751
752 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow); 752 __ JumpIfNonSmisNotBothSequentialOneByteStrings(lhs, rhs, a2, a3, &slow);
753 753
754 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2, 754 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2,
755 a3); 755 a3);
756 if (cc == eq) { 756 if (cc == eq) {
757 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, a2, a3, t0); 757 StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, a2, a3, t0);
758 } else { 758 } else {
759 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, a2, a3, t0, 759 StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, a2, a3, t0,
760 t1); 760 t1);
761 } 761 }
762 // Never falls through to here. 762 // Never falls through to here.
763 763
764 __ bind(&slow); 764 __ bind(&slow);
765 // Prepare for call to builtin. Push object pointers, a0 (lhs) first, 765 // Prepare for call to builtin. Push object pointers, a0 (lhs) first,
766 // a1 (rhs) second. 766 // a1 (rhs) second.
767 __ Push(lhs, rhs); 767 __ Push(lhs, rhs);
768 // Figure out which native to call and setup the arguments. 768 // Figure out which native to call and setup the arguments.
769 Builtins::JavaScript native; 769 Builtins::JavaScript native;
770 if (cc == eq) { 770 if (cc == eq) {
(...skipping 1378 matching lines...) Expand 10 before | Expand all | Expand 10 after
2149 // to look like a sequential string when it actually is an external string. 2149 // to look like a sequential string when it actually is an external string.
2150 __ lw(a1, MemOperand(sp, kPreviousIndexOffset)); 2150 __ lw(a1, MemOperand(sp, kPreviousIndexOffset));
2151 __ JumpIfNotSmi(a1, &runtime); 2151 __ JumpIfNotSmi(a1, &runtime);
2152 __ lw(a3, FieldMemOperand(a3, String::kLengthOffset)); 2152 __ lw(a3, FieldMemOperand(a3, String::kLengthOffset));
2153 __ Branch(&runtime, ls, a3, Operand(a1)); 2153 __ Branch(&runtime, ls, a3, Operand(a1));
2154 __ sra(a1, a1, kSmiTagSize); // Untag the Smi. 2154 __ sra(a1, a1, kSmiTagSize); // Untag the Smi.
2155 2155
2156 STATIC_ASSERT(kStringEncodingMask == 4); 2156 STATIC_ASSERT(kStringEncodingMask == 4);
2157 STATIC_ASSERT(kOneByteStringTag == 4); 2157 STATIC_ASSERT(kOneByteStringTag == 4);
2158 STATIC_ASSERT(kTwoByteStringTag == 0); 2158 STATIC_ASSERT(kTwoByteStringTag == 0);
2159 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ASCII. 2159 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ASCII.
paul.l... 2014/09/10 19:12:56 nit: ascii in comment.
2160 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset)); 2160 __ lw(t9, FieldMemOperand(regexp_data, JSRegExp::kDataOneByteCodeOffset));
2161 __ sra(a3, a0, 2); // a3 is 1 for ASCII, 0 for UC16 (used below). 2161 __ sra(a3, a0, 2); // a3 is 1 for ASCII, 0 for UC16 (used below).
2162 __ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset)); 2162 __ lw(t1, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset));
2163 __ Movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset. 2163 __ Movz(t9, t1, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset.
2164 2164
2165 // (E) Carry on. String handling is done. 2165 // (E) Carry on. String handling is done.
2166 // t9: irregexp code 2166 // t9: irregexp code
2167 // Check that the irregexp code has been generated for the actual string 2167 // Check that the irregexp code has been generated for the actual string
2168 // encoding. If it has, the field contains a code object otherwise it contains 2168 // encoding. If it has, the field contains a code object otherwise it contains
2169 // a smi (code flushing support). 2169 // a smi (code flushing support).
2170 __ JumpIfSmi(t9, &runtime); 2170 __ JumpIfSmi(t9, &runtime);
2171 2171
2172 // a1: previous index 2172 // a1: previous index
2173 // a3: encoding of subject string (1 if ASCII, 0 if two_byte); 2173 // a3: encoding of subject string (1 if one_byte, 0 if two_byte);
2174 // t9: code 2174 // t9: code
2175 // subject: Subject string 2175 // subject: Subject string
2176 // regexp_data: RegExp data (FixedArray) 2176 // regexp_data: RegExp data (FixedArray)
2177 // All checks done. Now push arguments for native regexp code. 2177 // All checks done. Now push arguments for native regexp code.
2178 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 2178 __ IncrementCounter(isolate()->counters()->regexp_entry_native(),
2179 1, a0, a2); 2179 1, a0, a2);
2180 2180
2181 // Isolates: note we add an additional parameter here (isolate pointer). 2181 // Isolates: note we add an additional parameter here (isolate pointer).
2182 const int kRegExpExecuteArguments = 9; 2182 const int kRegExpExecuteArguments = 9;
2183 const int kParameterRegisters = 4; 2183 const int kParameterRegisters = 4;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 // regexps to behave as non-global. This does not affect non-global regexps. 2218 // regexps to behave as non-global. This does not affect non-global regexps.
2219 __ mov(a0, zero_reg); 2219 __ mov(a0, zero_reg);
2220 __ sw(a0, MemOperand(sp, 2 * kPointerSize)); 2220 __ sw(a0, MemOperand(sp, 2 * kPointerSize));
2221 2221
2222 // Argument 5: static offsets vector buffer. 2222 // Argument 5: static offsets vector buffer.
2223 __ li(a0, Operand( 2223 __ li(a0, Operand(
2224 ExternalReference::address_of_static_offsets_vector(isolate()))); 2224 ExternalReference::address_of_static_offsets_vector(isolate())));
2225 __ sw(a0, MemOperand(sp, 1 * kPointerSize)); 2225 __ sw(a0, MemOperand(sp, 1 * kPointerSize));
2226 2226
2227 // For arguments 4 and 3 get string length, calculate start of string data 2227 // For arguments 4 and 3 get string length, calculate start of string data
2228 // and calculate the shift of the index (0 for ASCII and 1 for two byte). 2228 // calculate the shift of the index (0 for one-byte and 1 for two-byte).
2229 __ Addu(t2, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag)); 2229 __ Addu(t2, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag));
2230 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte. 2230 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte.
2231 // Load the length from the original subject string from the previous stack 2231 // Load the length from the original subject string from the previous stack
2232 // frame. Therefore we have to use fp, which points exactly to two pointer 2232 // frame. Therefore we have to use fp, which points exactly to two pointer
2233 // sizes below the previous sp. (Because creating a new stack frame pushes 2233 // sizes below the previous sp. (Because creating a new stack frame pushes
2234 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.) 2234 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
2235 __ lw(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); 2235 __ lw(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
2236 // If slice offset is not 0, load the length from the original sliced string. 2236 // If slice offset is not 0, load the length from the original sliced string.
2237 // Argument 4, a3: End of string data 2237 // Argument 4, a3: End of string data
2238 // Argument 3, a2: Start of string data 2238 // Argument 3, a2: Start of string data
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
2853 __ CallExternalReference(miss, 4); 2853 __ CallExternalReference(miss, 4);
2854 2854
2855 // Move result to a1 and exit the internal frame. 2855 // Move result to a1 and exit the internal frame.
2856 __ mov(a1, v0); 2856 __ mov(a1, v0);
2857 } 2857 }
2858 } 2858 }
2859 2859
2860 2860
2861 // StringCharCodeAtGenerator. 2861 // StringCharCodeAtGenerator.
2862 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 2862 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
2863 Label flat_string;
2864 Label ascii_string;
2865 Label got_char_code;
2866 Label sliced_string;
2867
2868 DCHECK(!t0.is(index_)); 2863 DCHECK(!t0.is(index_));
2869 DCHECK(!t0.is(result_)); 2864 DCHECK(!t0.is(result_));
2870 DCHECK(!t0.is(object_)); 2865 DCHECK(!t0.is(object_));
2871 2866
2872 // If the receiver is a smi trigger the non-string case. 2867 // If the receiver is a smi trigger the non-string case.
2873 __ JumpIfSmi(object_, receiver_not_string_); 2868 __ JumpIfSmi(object_, receiver_not_string_);
2874 2869
2875 // Fetch the instance type of the receiver into result register. 2870 // Fetch the instance type of the receiver into result register.
2876 __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 2871 __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
2877 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 2872 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2969 STATIC_ASSERT(kSmiTag == 0); 2964 STATIC_ASSERT(kSmiTag == 0);
2970 STATIC_ASSERT(kSmiShiftSize == 0); 2965 STATIC_ASSERT(kSmiShiftSize == 0);
2971 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1)); 2966 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1));
2972 __ And(t0, 2967 __ And(t0,
2973 code_, 2968 code_,
2974 Operand(kSmiTagMask | 2969 Operand(kSmiTagMask |
2975 ((~String::kMaxOneByteCharCode) << kSmiTagSize))); 2970 ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
2976 __ Branch(&slow_case_, ne, t0, Operand(zero_reg)); 2971 __ Branch(&slow_case_, ne, t0, Operand(zero_reg));
2977 2972
2978 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 2973 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
2979 // At this point code register contains smi tagged ASCII char code. 2974 // At this point code register contains smi tagged one-byte char code.
2980 STATIC_ASSERT(kSmiTag == 0); 2975 STATIC_ASSERT(kSmiTag == 0);
2981 __ sll(t0, code_, kPointerSizeLog2 - kSmiTagSize); 2976 __ sll(t0, code_, kPointerSizeLog2 - kSmiTagSize);
2982 __ Addu(result_, result_, t0); 2977 __ Addu(result_, result_, t0);
2983 __ lw(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 2978 __ lw(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
2984 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); 2979 __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
2985 __ Branch(&slow_case_, eq, result_, Operand(t0)); 2980 __ Branch(&slow_case_, eq, result_, Operand(t0));
2986 __ bind(&exit_); 2981 __ bind(&exit_);
2987 } 2982 }
2988 2983
2989 2984
2990 void StringCharFromCodeGenerator::GenerateSlow( 2985 void StringCharFromCodeGenerator::GenerateSlow(
2991 MacroAssembler* masm, 2986 MacroAssembler* masm,
2992 const RuntimeCallHelper& call_helper) { 2987 const RuntimeCallHelper& call_helper) {
2993 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); 2988 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase);
2994 2989
2995 __ bind(&slow_case_); 2990 __ bind(&slow_case_);
2996 call_helper.BeforeCall(masm); 2991 call_helper.BeforeCall(masm);
2997 __ push(code_); 2992 __ push(code_);
2998 __ CallRuntime(Runtime::kCharFromCode, 1); 2993 __ CallRuntime(Runtime::kCharFromCode, 1);
2999 __ Move(result_, v0); 2994 __ Move(result_, v0);
3000 2995
3001 call_helper.AfterCall(masm); 2996 call_helper.AfterCall(masm);
3002 __ Branch(&exit_); 2997 __ Branch(&exit_);
3003 2998
3004 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); 2999 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
3005 } 3000 }
3006 3001
3007 3002
3008 enum CopyCharactersFlags { 3003 enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 };
3009 COPY_ASCII = 1,
3010 DEST_ALWAYS_ALIGNED = 2
3011 };
3012 3004
3013 3005
3014 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, 3006 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
3015 Register dest, 3007 Register dest,
3016 Register src, 3008 Register src,
3017 Register count, 3009 Register count,
3018 Register scratch, 3010 Register scratch,
3019 String::Encoding encoding) { 3011 String::Encoding encoding) {
3020 if (FLAG_debug_code) { 3012 if (FLAG_debug_code) {
3021 // Check that destination is word aligned. 3013 // Check that destination is word aligned.
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
3165 // Allocate new sliced string. At this point we do not reload the instance 3157 // Allocate new sliced string. At this point we do not reload the instance
3166 // type including the string encoding because we simply rely on the info 3158 // type including the string encoding because we simply rely on the info
3167 // provided by the original string. It does not matter if the original 3159 // provided by the original string. It does not matter if the original
3168 // string's encoding is wrong because we always have to recheck encoding of 3160 // string's encoding is wrong because we always have to recheck encoding of
3169 // the newly created string's parent anyways due to externalized strings. 3161 // the newly created string's parent anyways due to externalized strings.
3170 Label two_byte_slice, set_slice_header; 3162 Label two_byte_slice, set_slice_header;
3171 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); 3163 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
3172 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 3164 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
3173 __ And(t0, a1, Operand(kStringEncodingMask)); 3165 __ And(t0, a1, Operand(kStringEncodingMask));
3174 __ Branch(&two_byte_slice, eq, t0, Operand(zero_reg)); 3166 __ Branch(&two_byte_slice, eq, t0, Operand(zero_reg));
3175 __ AllocateAsciiSlicedString(v0, a2, t2, t3, &runtime); 3167 __ AllocateOneByteSlicedString(v0, a2, t2, t3, &runtime);
3176 __ jmp(&set_slice_header); 3168 __ jmp(&set_slice_header);
3177 __ bind(&two_byte_slice); 3169 __ bind(&two_byte_slice);
3178 __ AllocateTwoByteSlicedString(v0, a2, t2, t3, &runtime); 3170 __ AllocateTwoByteSlicedString(v0, a2, t2, t3, &runtime);
3179 __ bind(&set_slice_header); 3171 __ bind(&set_slice_header);
3180 __ sll(a3, a3, 1); 3172 __ sll(a3, a3, 1);
3181 __ sw(t1, FieldMemOperand(v0, SlicedString::kParentOffset)); 3173 __ sw(t1, FieldMemOperand(v0, SlicedString::kParentOffset));
3182 __ sw(a3, FieldMemOperand(v0, SlicedString::kOffsetOffset)); 3174 __ sw(a3, FieldMemOperand(v0, SlicedString::kOffsetOffset));
3183 __ jmp(&return_v0); 3175 __ jmp(&return_v0);
3184 3176
3185 __ bind(&copy_routine); 3177 __ bind(&copy_routine);
(...skipping 23 matching lines...) Expand all
3209 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 3201 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
3210 __ Addu(t1, t1, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3202 __ Addu(t1, t1, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3211 3203
3212 __ bind(&allocate_result); 3204 __ bind(&allocate_result);
3213 // Sequential acii string. Allocate the result. 3205 // Sequential acii string. Allocate the result.
3214 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 3206 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
3215 __ And(t0, a1, Operand(kStringEncodingMask)); 3207 __ And(t0, a1, Operand(kStringEncodingMask));
3216 __ Branch(&two_byte_sequential, eq, t0, Operand(zero_reg)); 3208 __ Branch(&two_byte_sequential, eq, t0, Operand(zero_reg));
3217 3209
3218 // Allocate and copy the resulting ASCII string. 3210 // Allocate and copy the resulting ASCII string.
3219 __ AllocateAsciiString(v0, a2, t0, t2, t3, &runtime); 3211 __ AllocateOneByteString(v0, a2, t0, t2, t3, &runtime);
3220 3212
3221 // Locate first character of substring to copy. 3213 // Locate first character of substring to copy.
3222 __ Addu(t1, t1, a3); 3214 __ Addu(t1, t1, a3);
3223 3215
3224 // Locate first character of result. 3216 // Locate first character of result.
3225 __ Addu(a1, v0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3217 __ Addu(a1, v0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3226 3218
3227 // v0: result string 3219 // v0: result string
3228 // a1: first character of result string 3220 // a1: first character of result string
3229 // a2: result string length 3221 // a2: result string length
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3268 // a3: from index (untagged) 3260 // a3: from index (untagged)
3269 __ SmiTag(a3, a3); 3261 __ SmiTag(a3, a3);
3270 StringCharAtGenerator generator( 3262 StringCharAtGenerator generator(
3271 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); 3263 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
3272 generator.GenerateFast(masm); 3264 generator.GenerateFast(masm);
3273 __ DropAndRet(3); 3265 __ DropAndRet(3);
3274 generator.SkipSlow(masm, &runtime); 3266 generator.SkipSlow(masm, &runtime);
3275 } 3267 }
3276 3268
3277 3269
3278 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, 3270 void StringHelper::GenerateFlatOneByteStringEquals(
3279 Register left, Register right, 3271 MacroAssembler* masm, Register left, Register right, Register scratch1,
3280 Register scratch1, 3272 Register scratch2, Register scratch3) {
3281 Register scratch2,
3282 Register scratch3) {
3283 Register length = scratch1; 3273 Register length = scratch1;
3284 3274
3285 // Compare lengths. 3275 // Compare lengths.
3286 Label strings_not_equal, check_zero_length; 3276 Label strings_not_equal, check_zero_length;
3287 __ lw(length, FieldMemOperand(left, String::kLengthOffset)); 3277 __ lw(length, FieldMemOperand(left, String::kLengthOffset));
3288 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset)); 3278 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset));
3289 __ Branch(&check_zero_length, eq, length, Operand(scratch2)); 3279 __ Branch(&check_zero_length, eq, length, Operand(scratch2));
3290 __ bind(&strings_not_equal); 3280 __ bind(&strings_not_equal);
3291 DCHECK(is_int16(NOT_EQUAL)); 3281 DCHECK(is_int16(NOT_EQUAL));
3292 __ Ret(USE_DELAY_SLOT); 3282 __ Ret(USE_DELAY_SLOT);
3293 __ li(v0, Operand(Smi::FromInt(NOT_EQUAL))); 3283 __ li(v0, Operand(Smi::FromInt(NOT_EQUAL)));
3294 3284
3295 // Check if the length is zero. 3285 // Check if the length is zero.
3296 Label compare_chars; 3286 Label compare_chars;
3297 __ bind(&check_zero_length); 3287 __ bind(&check_zero_length);
3298 STATIC_ASSERT(kSmiTag == 0); 3288 STATIC_ASSERT(kSmiTag == 0);
3299 __ Branch(&compare_chars, ne, length, Operand(zero_reg)); 3289 __ Branch(&compare_chars, ne, length, Operand(zero_reg));
3300 DCHECK(is_int16(EQUAL)); 3290 DCHECK(is_int16(EQUAL));
3301 __ Ret(USE_DELAY_SLOT); 3291 __ Ret(USE_DELAY_SLOT);
3302 __ li(v0, Operand(Smi::FromInt(EQUAL))); 3292 __ li(v0, Operand(Smi::FromInt(EQUAL)));
3303 3293
3304 // Compare characters. 3294 // Compare characters.
3305 __ bind(&compare_chars); 3295 __ bind(&compare_chars);
3306 3296
3307 GenerateAsciiCharsCompareLoop(masm, 3297 GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2, scratch3,
3308 left, right, length, scratch2, scratch3, v0, 3298 v0, &strings_not_equal);
3309 &strings_not_equal);
3310 3299
3311 // Characters are equal. 3300 // Characters are equal.
3312 __ Ret(USE_DELAY_SLOT); 3301 __ Ret(USE_DELAY_SLOT);
3313 __ li(v0, Operand(Smi::FromInt(EQUAL))); 3302 __ li(v0, Operand(Smi::FromInt(EQUAL)));
3314 } 3303 }
3315 3304
3316 3305
3317 void StringHelper::GenerateCompareFlatAsciiStrings( 3306 void StringHelper::GenerateCompareFlatOneByteStrings(
3318 MacroAssembler* masm, Register left, Register right, Register scratch1, 3307 MacroAssembler* masm, Register left, Register right, Register scratch1,
3319 Register scratch2, Register scratch3, Register scratch4) { 3308 Register scratch2, Register scratch3, Register scratch4) {
3320 Label result_not_equal, compare_lengths; 3309 Label result_not_equal, compare_lengths;
3321 // Find minimum length and length difference. 3310 // Find minimum length and length difference.
3322 __ lw(scratch1, FieldMemOperand(left, String::kLengthOffset)); 3311 __ lw(scratch1, FieldMemOperand(left, String::kLengthOffset));
3323 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset)); 3312 __ lw(scratch2, FieldMemOperand(right, String::kLengthOffset));
3324 __ Subu(scratch3, scratch1, Operand(scratch2)); 3313 __ Subu(scratch3, scratch1, Operand(scratch2));
3325 Register length_delta = scratch3; 3314 Register length_delta = scratch3;
3326 __ slt(scratch4, scratch2, scratch1); 3315 __ slt(scratch4, scratch2, scratch1);
3327 __ Movn(scratch1, scratch2, scratch4); 3316 __ Movn(scratch1, scratch2, scratch4);
3328 Register min_length = scratch1; 3317 Register min_length = scratch1;
3329 STATIC_ASSERT(kSmiTag == 0); 3318 STATIC_ASSERT(kSmiTag == 0);
3330 __ Branch(&compare_lengths, eq, min_length, Operand(zero_reg)); 3319 __ Branch(&compare_lengths, eq, min_length, Operand(zero_reg));
3331 3320
3332 // Compare loop. 3321 // Compare loop.
3333 GenerateAsciiCharsCompareLoop(masm, 3322 GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
3334 left, right, min_length, scratch2, scratch4, v0, 3323 scratch4, v0, &result_not_equal);
3335 &result_not_equal);
3336 3324
3337 // Compare lengths - strings up to min-length are equal. 3325 // Compare lengths - strings up to min-length are equal.
3338 __ bind(&compare_lengths); 3326 __ bind(&compare_lengths);
3339 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0)); 3327 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
3340 // Use length_delta as result if it's zero. 3328 // Use length_delta as result if it's zero.
3341 __ mov(scratch2, length_delta); 3329 __ mov(scratch2, length_delta);
3342 __ mov(scratch4, zero_reg); 3330 __ mov(scratch4, zero_reg);
3343 __ mov(v0, zero_reg); 3331 __ mov(v0, zero_reg);
3344 3332
3345 __ bind(&result_not_equal); 3333 __ bind(&result_not_equal);
3346 // Conditionally update the result based either on length_delta or 3334 // Conditionally update the result based either on length_delta or
3347 // the last comparion performed in the loop above. 3335 // the last comparion performed in the loop above.
3348 Label ret; 3336 Label ret;
3349 __ Branch(&ret, eq, scratch2, Operand(scratch4)); 3337 __ Branch(&ret, eq, scratch2, Operand(scratch4));
3350 __ li(v0, Operand(Smi::FromInt(GREATER))); 3338 __ li(v0, Operand(Smi::FromInt(GREATER)));
3351 __ Branch(&ret, gt, scratch2, Operand(scratch4)); 3339 __ Branch(&ret, gt, scratch2, Operand(scratch4));
3352 __ li(v0, Operand(Smi::FromInt(LESS))); 3340 __ li(v0, Operand(Smi::FromInt(LESS)));
3353 __ bind(&ret); 3341 __ bind(&ret);
3354 __ Ret(); 3342 __ Ret();
3355 } 3343 }
3356 3344
3357 3345
3358 void StringHelper::GenerateAsciiCharsCompareLoop( 3346 void StringHelper::GenerateOneByteCharsCompareLoop(
3359 MacroAssembler* masm, Register left, Register right, Register length, 3347 MacroAssembler* masm, Register left, Register right, Register length,
3360 Register scratch1, Register scratch2, Register scratch3, 3348 Register scratch1, Register scratch2, Register scratch3,
3361 Label* chars_not_equal) { 3349 Label* chars_not_equal) {
3362 // Change index to run from -length to -1 by adding length to string 3350 // Change index to run from -length to -1 by adding length to string
3363 // start. This means that loop ends when index reaches zero, which 3351 // start. This means that loop ends when index reaches zero, which
3364 // doesn't need an additional compare. 3352 // doesn't need an additional compare.
3365 __ SmiUntag(length); 3353 __ SmiUntag(length);
3366 __ Addu(scratch1, length, 3354 __ Addu(scratch1, length,
3367 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3355 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3368 __ Addu(left, left, Operand(scratch1)); 3356 __ Addu(left, left, Operand(scratch1));
(...skipping 29 matching lines...) Expand all
3398 Label not_same; 3386 Label not_same;
3399 __ Branch(&not_same, ne, a0, Operand(a1)); 3387 __ Branch(&not_same, ne, a0, Operand(a1));
3400 STATIC_ASSERT(EQUAL == 0); 3388 STATIC_ASSERT(EQUAL == 0);
3401 STATIC_ASSERT(kSmiTag == 0); 3389 STATIC_ASSERT(kSmiTag == 0);
3402 __ li(v0, Operand(Smi::FromInt(EQUAL))); 3390 __ li(v0, Operand(Smi::FromInt(EQUAL)));
3403 __ IncrementCounter(counters->string_compare_native(), 1, a1, a2); 3391 __ IncrementCounter(counters->string_compare_native(), 1, a1, a2);
3404 __ DropAndRet(2); 3392 __ DropAndRet(2);
3405 3393
3406 __ bind(&not_same); 3394 __ bind(&not_same);
3407 3395
3408 // Check that both objects are sequential ASCII strings. 3396 // Check that both objects are sequential one-byte strings.
3409 __ JumpIfNotBothSequentialAsciiStrings(a1, a0, a2, a3, &runtime); 3397 __ JumpIfNotBothSequentialOneByteStrings(a1, a0, a2, a3, &runtime);
3410 3398
3411 // Compare flat ASCII strings natively. Remove arguments from stack first. 3399 // Compare flat ASCII strings natively. Remove arguments from stack first.
3412 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3); 3400 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3);
3413 __ Addu(sp, sp, Operand(2 * kPointerSize)); 3401 __ Addu(sp, sp, Operand(2 * kPointerSize));
3414 StringHelper::GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, t0, t1); 3402 StringHelper::GenerateCompareFlatOneByteStrings(masm, a1, a0, a2, a3, t0, t1);
3415 3403
3416 __ bind(&runtime); 3404 __ bind(&runtime);
3417 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3405 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3418 } 3406 }
3419 3407
3420 3408
3421 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3409 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3422 // ----------- S t a t e ------------- 3410 // ----------- S t a t e -------------
3423 // -- a1 : left 3411 // -- a1 : left
3424 // -- a0 : right 3412 // -- a0 : right
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3697 Label is_symbol; 3685 Label is_symbol;
3698 __ Branch(&is_symbol, ne, tmp5, Operand(zero_reg)); 3686 __ Branch(&is_symbol, ne, tmp5, Operand(zero_reg));
3699 // Make sure a0 is non-zero. At this point input operands are 3687 // Make sure a0 is non-zero. At this point input operands are
3700 // guaranteed to be non-zero. 3688 // guaranteed to be non-zero.
3701 DCHECK(right.is(a0)); 3689 DCHECK(right.is(a0));
3702 __ Ret(USE_DELAY_SLOT); 3690 __ Ret(USE_DELAY_SLOT);
3703 __ mov(v0, a0); // In the delay slot. 3691 __ mov(v0, a0); // In the delay slot.
3704 __ bind(&is_symbol); 3692 __ bind(&is_symbol);
3705 } 3693 }
3706 3694
3707 // Check that both strings are sequential ASCII. 3695 // Check that both strings are sequential one-byte.
3708 Label runtime; 3696 Label runtime;
3709 __ JumpIfBothInstanceTypesAreNotSequentialAscii( 3697 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4,
3710 tmp1, tmp2, tmp3, tmp4, &runtime); 3698 &runtime);
3711 3699
3712 // Compare flat ASCII strings. Returns when done. 3700 // Compare flat one-byte strings. Returns when done.
3713 if (equality) { 3701 if (equality) {
3714 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2, 3702 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1, tmp2,
3715 tmp3); 3703 tmp3);
3716 } else { 3704 } else {
3717 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, 3705 StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, tmp1,
3718 tmp3, tmp4); 3706 tmp2, tmp3, tmp4);
3719 } 3707 }
3720 3708
3721 // Handle more complex cases in runtime. 3709 // Handle more complex cases in runtime.
3722 __ bind(&runtime); 3710 __ bind(&runtime);
3723 __ Push(left, right); 3711 __ Push(left, right);
3724 if (equality) { 3712 if (equality) {
3725 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); 3713 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
3726 } else { 3714 } else {
3727 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3715 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3728 } 3716 }
(...skipping 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after
4863 MemOperand(fp, 6 * kPointerSize), 4851 MemOperand(fp, 6 * kPointerSize),
4864 NULL); 4852 NULL);
4865 } 4853 }
4866 4854
4867 4855
4868 #undef __ 4856 #undef __
4869 4857
4870 } } // namespace v8::internal 4858 } } // namespace v8::internal
4871 4859
4872 #endif // V8_TARGET_ARCH_MIPS 4860 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | src/mips/codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698