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

Side by Side Diff: src/mips64/code-stubs-mips64.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
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_MIPS64 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 __ bind(&check_for_internalized_strings); 733 __ bind(&check_for_internalized_strings);
734 if (cc == eq && !strict()) { 734 if (cc == eq && !strict()) {
735 // Returns an answer for two internalized strings or two 735 // Returns an answer for two internalized strings or two
736 // detectable objects. 736 // detectable objects.
737 // Otherwise jumps to string case or not both strings case. 737 // Otherwise jumps to string case or not both strings case.
738 // Assumes that a2 is the type of lhs_ on entry. 738 // Assumes that a2 is the type of lhs_ on entry.
739 EmitCheckForInternalizedStringsOrObjects( 739 EmitCheckForInternalizedStringsOrObjects(
740 masm, lhs, rhs, &flat_string_check, &slow); 740 masm, lhs, rhs, &flat_string_check, &slow);
741 } 741 }
742 742
743 // Check for both being sequential ASCII strings, and inline if that is the 743 // Check for both being sequential one-byte strings,
744 // case. 744 // and inline if that is the case.
745 __ bind(&flat_string_check); 745 __ bind(&flat_string_check);
746 746
747 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, a2, a3, &slow); 747 __ JumpIfNonSmisNotBothSequentialOneByteStrings(lhs, rhs, a2, a3, &slow);
748 748
749 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2, 749 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, a2,
750 a3); 750 a3);
751 if (cc == eq) { 751 if (cc == eq) {
752 StringHelper::GenerateFlatAsciiStringEquals(masm, lhs, rhs, a2, a3, a4); 752 StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, a2, a3, a4);
753 } else { 753 } else {
754 StringHelper::GenerateCompareFlatAsciiStrings(masm, lhs, rhs, a2, a3, a4, 754 StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, a2, a3, a4,
755 a5); 755 a5);
756 } 756 }
757 // Never falls through to here. 757 // Never falls through to here.
758 758
759 __ bind(&slow); 759 __ bind(&slow);
760 // Prepare for call to builtin. Push object pointers, a0 (lhs) first, 760 // Prepare for call to builtin. Push object pointers, a0 (lhs) first,
761 // a1 (rhs) second. 761 // a1 (rhs) second.
762 __ Push(lhs, rhs); 762 __ Push(lhs, rhs);
763 // Figure out which native to call and setup the arguments. 763 // Figure out which native to call and setup the arguments.
764 Builtins::JavaScript native; 764 Builtins::JavaScript native;
765 if (cc == eq) { 765 if (cc == eq) {
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
2150 // to look like a sequential string when it actually is an external string. 2150 // to look like a sequential string when it actually is an external string.
2151 __ ld(a1, MemOperand(sp, kPreviousIndexOffset)); 2151 __ ld(a1, MemOperand(sp, kPreviousIndexOffset));
2152 __ JumpIfNotSmi(a1, &runtime); 2152 __ JumpIfNotSmi(a1, &runtime);
2153 __ ld(a3, FieldMemOperand(a3, String::kLengthOffset)); 2153 __ ld(a3, FieldMemOperand(a3, String::kLengthOffset));
2154 __ Branch(&runtime, ls, a3, Operand(a1)); 2154 __ Branch(&runtime, ls, a3, Operand(a1));
2155 __ SmiUntag(a1); 2155 __ SmiUntag(a1);
2156 2156
2157 STATIC_ASSERT(kStringEncodingMask == 4); 2157 STATIC_ASSERT(kStringEncodingMask == 4);
2158 STATIC_ASSERT(kOneByteStringTag == 4); 2158 STATIC_ASSERT(kOneByteStringTag == 4);
2159 STATIC_ASSERT(kTwoByteStringTag == 0); 2159 STATIC_ASSERT(kTwoByteStringTag == 0);
2160 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for ASCII. 2160 __ And(a0, a0, Operand(kStringEncodingMask)); // Non-zero for one_byte.
2161 __ ld(t9, FieldMemOperand(regexp_data, JSRegExp::kDataAsciiCodeOffset)); 2161 __ ld(t9, FieldMemOperand(regexp_data, JSRegExp::kDataOneByteCodeOffset));
2162 __ dsra(a3, a0, 2); // a3 is 1 for ASCII, 0 for UC16 (used below). 2162 __ dsra(a3, a0, 2); // a3 is 1 for one_byte, 0 for UC16 (used below).
2163 __ ld(a5, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset)); 2163 __ ld(a5, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset));
2164 __ Movz(t9, a5, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset. 2164 __ Movz(t9, a5, a0); // If UC16 (a0 is 0), replace t9 w/kDataUC16CodeOffset.
2165 2165
2166 // (E) Carry on. String handling is done. 2166 // (E) Carry on. String handling is done.
2167 // t9: irregexp code 2167 // t9: irregexp code
2168 // Check that the irregexp code has been generated for the actual string 2168 // Check that the irregexp code has been generated for the actual string
2169 // encoding. If it has, the field contains a code object otherwise it contains 2169 // encoding. If it has, the field contains a code object otherwise it contains
2170 // a smi (code flushing support). 2170 // a smi (code flushing support).
2171 __ JumpIfSmi(t9, &runtime); 2171 __ JumpIfSmi(t9, &runtime);
2172 2172
2173 // a1: previous index 2173 // a1: previous index
2174 // a3: encoding of subject string (1 if ASCII, 0 if two_byte); 2174 // a3: encoding of subject string (1 if one_byte, 0 if two_byte);
2175 // t9: code 2175 // t9: code
2176 // subject: Subject string 2176 // subject: Subject string
2177 // regexp_data: RegExp data (FixedArray) 2177 // regexp_data: RegExp data (FixedArray)
2178 // All checks done. Now push arguments for native regexp code. 2178 // All checks done. Now push arguments for native regexp code.
2179 __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 2179 __ IncrementCounter(isolate()->counters()->regexp_entry_native(),
2180 1, a0, a2); 2180 1, a0, a2);
2181 2181
2182 // Isolates: note we add an additional parameter here (isolate pointer). 2182 // Isolates: note we add an additional parameter here (isolate pointer).
2183 const int kRegExpExecuteArguments = 9; 2183 const int kRegExpExecuteArguments = 9;
2184 const int kParameterRegisters = (kMipsAbi == kN64) ? 8 : 4; 2184 const int kParameterRegisters = (kMipsAbi == kN64) ? 8 : 4;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2249 __ mov(a0, zero_reg); 2249 __ mov(a0, zero_reg);
2250 __ sd(a0, MemOperand(sp, 2 * kPointerSize)); 2250 __ sd(a0, MemOperand(sp, 2 * kPointerSize));
2251 2251
2252 // Argument 5: static offsets vector buffer. 2252 // Argument 5: static offsets vector buffer.
2253 __ li(a0, Operand( 2253 __ li(a0, Operand(
2254 ExternalReference::address_of_static_offsets_vector(isolate()))); 2254 ExternalReference::address_of_static_offsets_vector(isolate())));
2255 __ sd(a0, MemOperand(sp, 1 * kPointerSize)); 2255 __ sd(a0, MemOperand(sp, 1 * kPointerSize));
2256 } 2256 }
2257 2257
2258 // For arguments 4 and 3 get string length, calculate start of string data 2258 // For arguments 4 and 3 get string length, calculate start of string data
2259 // and calculate the shift of the index (0 for ASCII and 1 for two byte). 2259 // and calculate the shift of the index (0 for one_byte and 1 for two byte).
2260 __ Daddu(t2, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag)); 2260 __ Daddu(t2, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag));
2261 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte. 2261 __ Xor(a3, a3, Operand(1)); // 1 for 2-byte str, 0 for 1-byte.
2262 // Load the length from the original subject string from the previous stack 2262 // Load the length from the original subject string from the previous stack
2263 // frame. Therefore we have to use fp, which points exactly to two pointer 2263 // frame. Therefore we have to use fp, which points exactly to two pointer
2264 // sizes below the previous sp. (Because creating a new stack frame pushes 2264 // sizes below the previous sp. (Because creating a new stack frame pushes
2265 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.) 2265 // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
2266 __ ld(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize)); 2266 __ ld(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
2267 // If slice offset is not 0, load the length from the original sliced string. 2267 // If slice offset is not 0, load the length from the original sliced string.
2268 // Argument 4, a3: End of string data 2268 // Argument 4, a3: End of string data
2269 // Argument 3, a2: Start of string data 2269 // Argument 3, a2: Start of string data
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
2741 __ bind(&do_call); 2741 __ bind(&do_call);
2742 // Set expected number of arguments to zero (not changing r0). 2742 // Set expected number of arguments to zero (not changing r0).
2743 __ li(a2, Operand(0, RelocInfo::NONE32)); 2743 __ li(a2, Operand(0, RelocInfo::NONE32));
2744 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 2744 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
2745 RelocInfo::CODE_TARGET); 2745 RelocInfo::CODE_TARGET);
2746 } 2746 }
2747 2747
2748 2748
2749 // StringCharCodeAtGenerator. 2749 // StringCharCodeAtGenerator.
2750 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 2750 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
2751 Label flat_string;
2752 Label ascii_string;
2753 Label got_char_code;
2754 Label sliced_string;
2755
2756 DCHECK(!a4.is(index_)); 2751 DCHECK(!a4.is(index_));
2757 DCHECK(!a4.is(result_)); 2752 DCHECK(!a4.is(result_));
2758 DCHECK(!a4.is(object_)); 2753 DCHECK(!a4.is(object_));
2759 2754
2760 // If the receiver is a smi trigger the non-string case. 2755 // If the receiver is a smi trigger the non-string case.
2761 __ JumpIfSmi(object_, receiver_not_string_); 2756 __ JumpIfSmi(object_, receiver_not_string_);
2762 2757
2763 // Fetch the instance type of the receiver into result register. 2758 // Fetch the instance type of the receiver into result register.
2764 __ ld(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 2759 __ ld(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
2765 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 2760 __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
3003 STATIC_ASSERT(kSmiTag == 0); 2998 STATIC_ASSERT(kSmiTag == 0);
3004 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1)); 2999 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1));
3005 __ And(a4, 3000 __ And(a4,
3006 code_, 3001 code_,
3007 Operand(kSmiTagMask | 3002 Operand(kSmiTagMask |
3008 ((~String::kMaxOneByteCharCode) << kSmiTagSize))); 3003 ((~String::kMaxOneByteCharCode) << kSmiTagSize)));
3009 __ Branch(&slow_case_, ne, a4, Operand(zero_reg)); 3004 __ Branch(&slow_case_, ne, a4, Operand(zero_reg));
3010 3005
3011 3006
3012 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex); 3007 __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
3013 // At this point code register contains smi tagged ASCII char code. 3008 // At this point code register contains smi tagged one_byte char code.
3014 STATIC_ASSERT(kSmiTag == 0); 3009 STATIC_ASSERT(kSmiTag == 0);
3015 __ SmiScale(a4, code_, kPointerSizeLog2); 3010 __ SmiScale(a4, code_, kPointerSizeLog2);
3016 __ Daddu(result_, result_, a4); 3011 __ Daddu(result_, result_, a4);
3017 __ ld(result_, FieldMemOperand(result_, FixedArray::kHeaderSize)); 3012 __ ld(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
3018 __ LoadRoot(a4, Heap::kUndefinedValueRootIndex); 3013 __ LoadRoot(a4, Heap::kUndefinedValueRootIndex);
3019 __ Branch(&slow_case_, eq, result_, Operand(a4)); 3014 __ Branch(&slow_case_, eq, result_, Operand(a4));
3020 __ bind(&exit_); 3015 __ bind(&exit_);
3021 } 3016 }
3022 3017
3023 3018
3024 void StringCharFromCodeGenerator::GenerateSlow( 3019 void StringCharFromCodeGenerator::GenerateSlow(
3025 MacroAssembler* masm, 3020 MacroAssembler* masm,
3026 const RuntimeCallHelper& call_helper) { 3021 const RuntimeCallHelper& call_helper) {
3027 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); 3022 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase);
3028 3023
3029 __ bind(&slow_case_); 3024 __ bind(&slow_case_);
3030 call_helper.BeforeCall(masm); 3025 call_helper.BeforeCall(masm);
3031 __ push(code_); 3026 __ push(code_);
3032 __ CallRuntime(Runtime::kCharFromCode, 1); 3027 __ CallRuntime(Runtime::kCharFromCode, 1);
3033 __ Move(result_, v0); 3028 __ Move(result_, v0);
3034 3029
3035 call_helper.AfterCall(masm); 3030 call_helper.AfterCall(masm);
3036 __ Branch(&exit_); 3031 __ Branch(&exit_);
3037 3032
3038 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); 3033 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
3039 } 3034 }
3040 3035
3041 3036
3042 enum CopyCharactersFlags { 3037 enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 };
3043 COPY_ASCII = 1,
3044 DEST_ALWAYS_ALIGNED = 2
3045 };
3046 3038
3047 3039
3048 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, 3040 void StringHelper::GenerateCopyCharacters(MacroAssembler* masm,
3049 Register dest, 3041 Register dest,
3050 Register src, 3042 Register src,
3051 Register count, 3043 Register count,
3052 Register scratch, 3044 Register scratch,
3053 String::Encoding encoding) { 3045 String::Encoding encoding) {
3054 if (FLAG_debug_code) { 3046 if (FLAG_debug_code) {
3055 // Check that destination is word aligned. 3047 // Check that destination is word aligned.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
3203 // Allocate new sliced string. At this point we do not reload the instance 3195 // Allocate new sliced string. At this point we do not reload the instance
3204 // type including the string encoding because we simply rely on the info 3196 // type including the string encoding because we simply rely on the info
3205 // provided by the original string. It does not matter if the original 3197 // provided by the original string. It does not matter if the original
3206 // string's encoding is wrong because we always have to recheck encoding of 3198 // string's encoding is wrong because we always have to recheck encoding of
3207 // the newly created string's parent anyways due to externalized strings. 3199 // the newly created string's parent anyways due to externalized strings.
3208 Label two_byte_slice, set_slice_header; 3200 Label two_byte_slice, set_slice_header;
3209 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); 3201 STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
3210 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 3202 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
3211 __ And(a4, a1, Operand(kStringEncodingMask)); 3203 __ And(a4, a1, Operand(kStringEncodingMask));
3212 __ Branch(&two_byte_slice, eq, a4, Operand(zero_reg)); 3204 __ Branch(&two_byte_slice, eq, a4, Operand(zero_reg));
3213 __ AllocateAsciiSlicedString(v0, a2, a6, a7, &runtime); 3205 __ AllocateOneByteSlicedString(v0, a2, a6, a7, &runtime);
3214 __ jmp(&set_slice_header); 3206 __ jmp(&set_slice_header);
3215 __ bind(&two_byte_slice); 3207 __ bind(&two_byte_slice);
3216 __ AllocateTwoByteSlicedString(v0, a2, a6, a7, &runtime); 3208 __ AllocateTwoByteSlicedString(v0, a2, a6, a7, &runtime);
3217 __ bind(&set_slice_header); 3209 __ bind(&set_slice_header);
3218 __ SmiTag(a3); 3210 __ SmiTag(a3);
3219 __ sd(a5, FieldMemOperand(v0, SlicedString::kParentOffset)); 3211 __ sd(a5, FieldMemOperand(v0, SlicedString::kParentOffset));
3220 __ sd(a3, FieldMemOperand(v0, SlicedString::kOffsetOffset)); 3212 __ sd(a3, FieldMemOperand(v0, SlicedString::kOffsetOffset));
3221 __ jmp(&return_v0); 3213 __ jmp(&return_v0);
3222 3214
3223 __ bind(&copy_routine); 3215 __ bind(&copy_routine);
(...skipping 22 matching lines...) Expand all
3246 // Locate first character of underlying subject string. 3238 // Locate first character of underlying subject string.
3247 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 3239 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
3248 __ Daddu(a5, a5, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3240 __ Daddu(a5, a5, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3249 3241
3250 __ bind(&allocate_result); 3242 __ bind(&allocate_result);
3251 // Sequential acii string. Allocate the result. 3243 // Sequential acii string. Allocate the result.
3252 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 3244 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
3253 __ And(a4, a1, Operand(kStringEncodingMask)); 3245 __ And(a4, a1, Operand(kStringEncodingMask));
3254 __ Branch(&two_byte_sequential, eq, a4, Operand(zero_reg)); 3246 __ Branch(&two_byte_sequential, eq, a4, Operand(zero_reg));
3255 3247
3256 // Allocate and copy the resulting ASCII string. 3248 // Allocate and copy the resulting one_byte string.
3257 __ AllocateAsciiString(v0, a2, a4, a6, a7, &runtime); 3249 __ AllocateOneByteString(v0, a2, a4, a6, a7, &runtime);
3258 3250
3259 // Locate first character of substring to copy. 3251 // Locate first character of substring to copy.
3260 __ Daddu(a5, a5, a3); 3252 __ Daddu(a5, a5, a3);
3261 3253
3262 // Locate first character of result. 3254 // Locate first character of result.
3263 __ Daddu(a1, v0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3255 __ Daddu(a1, v0, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3264 3256
3265 // v0: result string 3257 // v0: result string
3266 // a1: first character of result string 3258 // a1: first character of result string
3267 // a2: result string length 3259 // a2: result string length
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3305 // a2: length 3297 // a2: length
3306 // a3: from index (untagged) 3298 // a3: from index (untagged)
3307 StringCharAtGenerator generator( 3299 StringCharAtGenerator generator(
3308 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); 3300 v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
3309 generator.GenerateFast(masm); 3301 generator.GenerateFast(masm);
3310 __ DropAndRet(3); 3302 __ DropAndRet(3);
3311 generator.SkipSlow(masm, &runtime); 3303 generator.SkipSlow(masm, &runtime);
3312 } 3304 }
3313 3305
3314 3306
3315 void StringHelper::GenerateFlatAsciiStringEquals(MacroAssembler* masm, 3307 void StringHelper::GenerateFlatOneByteStringEquals(
3316 Register left, Register right, 3308 MacroAssembler* masm, Register left, Register right, Register scratch1,
3317 Register scratch1, 3309 Register scratch2, Register scratch3) {
3318 Register scratch2,
3319 Register scratch3) {
3320 Register length = scratch1; 3310 Register length = scratch1;
3321 3311
3322 // Compare lengths. 3312 // Compare lengths.
3323 Label strings_not_equal, check_zero_length; 3313 Label strings_not_equal, check_zero_length;
3324 __ ld(length, FieldMemOperand(left, String::kLengthOffset)); 3314 __ ld(length, FieldMemOperand(left, String::kLengthOffset));
3325 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset)); 3315 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset));
3326 __ Branch(&check_zero_length, eq, length, Operand(scratch2)); 3316 __ Branch(&check_zero_length, eq, length, Operand(scratch2));
3327 __ bind(&strings_not_equal); 3317 __ bind(&strings_not_equal);
3328 // Can not put li in delayslot, it has multi instructions. 3318 // Can not put li in delayslot, it has multi instructions.
3329 __ li(v0, Operand(Smi::FromInt(NOT_EQUAL))); 3319 __ li(v0, Operand(Smi::FromInt(NOT_EQUAL)));
3330 __ Ret(); 3320 __ Ret();
3331 3321
3332 // Check if the length is zero. 3322 // Check if the length is zero.
3333 Label compare_chars; 3323 Label compare_chars;
3334 __ bind(&check_zero_length); 3324 __ bind(&check_zero_length);
3335 STATIC_ASSERT(kSmiTag == 0); 3325 STATIC_ASSERT(kSmiTag == 0);
3336 __ Branch(&compare_chars, ne, length, Operand(zero_reg)); 3326 __ Branch(&compare_chars, ne, length, Operand(zero_reg));
3337 DCHECK(is_int16((intptr_t)Smi::FromInt(EQUAL))); 3327 DCHECK(is_int16((intptr_t)Smi::FromInt(EQUAL)));
3338 __ Ret(USE_DELAY_SLOT); 3328 __ Ret(USE_DELAY_SLOT);
3339 __ li(v0, Operand(Smi::FromInt(EQUAL))); 3329 __ li(v0, Operand(Smi::FromInt(EQUAL)));
3340 3330
3341 // Compare characters. 3331 // Compare characters.
3342 __ bind(&compare_chars); 3332 __ bind(&compare_chars);
3343 3333
3344 GenerateAsciiCharsCompareLoop(masm, 3334 GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2, scratch3,
3345 left, right, length, scratch2, scratch3, v0, 3335 v0, &strings_not_equal);
3346 &strings_not_equal);
3347 3336
3348 // Characters are equal. 3337 // Characters are equal.
3349 __ Ret(USE_DELAY_SLOT); 3338 __ Ret(USE_DELAY_SLOT);
3350 __ li(v0, Operand(Smi::FromInt(EQUAL))); 3339 __ li(v0, Operand(Smi::FromInt(EQUAL)));
3351 } 3340 }
3352 3341
3353 3342
3354 void StringHelper::GenerateCompareFlatAsciiStrings( 3343 void StringHelper::GenerateCompareFlatOneByteStrings(
3355 MacroAssembler* masm, Register left, Register right, Register scratch1, 3344 MacroAssembler* masm, Register left, Register right, Register scratch1,
3356 Register scratch2, Register scratch3, Register scratch4) { 3345 Register scratch2, Register scratch3, Register scratch4) {
3357 Label result_not_equal, compare_lengths; 3346 Label result_not_equal, compare_lengths;
3358 // Find minimum length and length difference. 3347 // Find minimum length and length difference.
3359 __ ld(scratch1, FieldMemOperand(left, String::kLengthOffset)); 3348 __ ld(scratch1, FieldMemOperand(left, String::kLengthOffset));
3360 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset)); 3349 __ ld(scratch2, FieldMemOperand(right, String::kLengthOffset));
3361 __ Dsubu(scratch3, scratch1, Operand(scratch2)); 3350 __ Dsubu(scratch3, scratch1, Operand(scratch2));
3362 Register length_delta = scratch3; 3351 Register length_delta = scratch3;
3363 __ slt(scratch4, scratch2, scratch1); 3352 __ slt(scratch4, scratch2, scratch1);
3364 __ Movn(scratch1, scratch2, scratch4); 3353 __ Movn(scratch1, scratch2, scratch4);
3365 Register min_length = scratch1; 3354 Register min_length = scratch1;
3366 STATIC_ASSERT(kSmiTag == 0); 3355 STATIC_ASSERT(kSmiTag == 0);
3367 __ Branch(&compare_lengths, eq, min_length, Operand(zero_reg)); 3356 __ Branch(&compare_lengths, eq, min_length, Operand(zero_reg));
3368 3357
3369 // Compare loop. 3358 // Compare loop.
3370 GenerateAsciiCharsCompareLoop(masm, 3359 GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
3371 left, right, min_length, scratch2, scratch4, v0, 3360 scratch4, v0, &result_not_equal);
3372 &result_not_equal);
3373 3361
3374 // Compare lengths - strings up to min-length are equal. 3362 // Compare lengths - strings up to min-length are equal.
3375 __ bind(&compare_lengths); 3363 __ bind(&compare_lengths);
3376 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0)); 3364 DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
3377 // Use length_delta as result if it's zero. 3365 // Use length_delta as result if it's zero.
3378 __ mov(scratch2, length_delta); 3366 __ mov(scratch2, length_delta);
3379 __ mov(scratch4, zero_reg); 3367 __ mov(scratch4, zero_reg);
3380 __ mov(v0, zero_reg); 3368 __ mov(v0, zero_reg);
3381 3369
3382 __ bind(&result_not_equal); 3370 __ bind(&result_not_equal);
3383 // Conditionally update the result based either on length_delta or 3371 // Conditionally update the result based either on length_delta or
3384 // the last comparion performed in the loop above. 3372 // the last comparion performed in the loop above.
3385 Label ret; 3373 Label ret;
3386 __ Branch(&ret, eq, scratch2, Operand(scratch4)); 3374 __ Branch(&ret, eq, scratch2, Operand(scratch4));
3387 __ li(v0, Operand(Smi::FromInt(GREATER))); 3375 __ li(v0, Operand(Smi::FromInt(GREATER)));
3388 __ Branch(&ret, gt, scratch2, Operand(scratch4)); 3376 __ Branch(&ret, gt, scratch2, Operand(scratch4));
3389 __ li(v0, Operand(Smi::FromInt(LESS))); 3377 __ li(v0, Operand(Smi::FromInt(LESS)));
3390 __ bind(&ret); 3378 __ bind(&ret);
3391 __ Ret(); 3379 __ Ret();
3392 } 3380 }
3393 3381
3394 3382
3395 void StringHelper::GenerateAsciiCharsCompareLoop( 3383 void StringHelper::GenerateOneByteCharsCompareLoop(
3396 MacroAssembler* masm, Register left, Register right, Register length, 3384 MacroAssembler* masm, Register left, Register right, Register length,
3397 Register scratch1, Register scratch2, Register scratch3, 3385 Register scratch1, Register scratch2, Register scratch3,
3398 Label* chars_not_equal) { 3386 Label* chars_not_equal) {
3399 // Change index to run from -length to -1 by adding length to string 3387 // Change index to run from -length to -1 by adding length to string
3400 // start. This means that loop ends when index reaches zero, which 3388 // start. This means that loop ends when index reaches zero, which
3401 // doesn't need an additional compare. 3389 // doesn't need an additional compare.
3402 __ SmiUntag(length); 3390 __ SmiUntag(length);
3403 __ Daddu(scratch1, length, 3391 __ Daddu(scratch1, length,
3404 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3392 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3405 __ Daddu(left, left, Operand(scratch1)); 3393 __ Daddu(left, left, Operand(scratch1));
(...skipping 29 matching lines...) Expand all
3435 Label not_same; 3423 Label not_same;
3436 __ Branch(&not_same, ne, a0, Operand(a1)); 3424 __ Branch(&not_same, ne, a0, Operand(a1));
3437 STATIC_ASSERT(EQUAL == 0); 3425 STATIC_ASSERT(EQUAL == 0);
3438 STATIC_ASSERT(kSmiTag == 0); 3426 STATIC_ASSERT(kSmiTag == 0);
3439 __ li(v0, Operand(Smi::FromInt(EQUAL))); 3427 __ li(v0, Operand(Smi::FromInt(EQUAL)));
3440 __ IncrementCounter(counters->string_compare_native(), 1, a1, a2); 3428 __ IncrementCounter(counters->string_compare_native(), 1, a1, a2);
3441 __ DropAndRet(2); 3429 __ DropAndRet(2);
3442 3430
3443 __ bind(&not_same); 3431 __ bind(&not_same);
3444 3432
3445 // Check that both objects are sequential ASCII strings. 3433 // Check that both objects are sequential one_byte strings.
3446 __ JumpIfNotBothSequentialAsciiStrings(a1, a0, a2, a3, &runtime); 3434 __ JumpIfNotBothSequentialOneByteStrings(a1, a0, a2, a3, &runtime);
3447 3435
3448 // Compare flat ASCII strings natively. Remove arguments from stack first. 3436 // Compare flat one_byte strings natively. Remove arguments from stack first.
3449 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3); 3437 __ IncrementCounter(counters->string_compare_native(), 1, a2, a3);
3450 __ Daddu(sp, sp, Operand(2 * kPointerSize)); 3438 __ Daddu(sp, sp, Operand(2 * kPointerSize));
3451 StringHelper::GenerateCompareFlatAsciiStrings(masm, a1, a0, a2, a3, a4, a5); 3439 StringHelper::GenerateCompareFlatOneByteStrings(masm, a1, a0, a2, a3, a4, a5);
3452 3440
3453 __ bind(&runtime); 3441 __ bind(&runtime);
3454 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3442 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3455 } 3443 }
3456 3444
3457 3445
3458 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { 3446 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
3459 // ----------- S t a t e ------------- 3447 // ----------- S t a t e -------------
3460 // -- a1 : left 3448 // -- a1 : left
3461 // -- a0 : right 3449 // -- a0 : right
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
3734 Label is_symbol; 3722 Label is_symbol;
3735 __ Branch(&is_symbol, ne, tmp5, Operand(zero_reg)); 3723 __ Branch(&is_symbol, ne, tmp5, Operand(zero_reg));
3736 // Make sure a0 is non-zero. At this point input operands are 3724 // Make sure a0 is non-zero. At this point input operands are
3737 // guaranteed to be non-zero. 3725 // guaranteed to be non-zero.
3738 DCHECK(right.is(a0)); 3726 DCHECK(right.is(a0));
3739 __ Ret(USE_DELAY_SLOT); 3727 __ Ret(USE_DELAY_SLOT);
3740 __ mov(v0, a0); // In the delay slot. 3728 __ mov(v0, a0); // In the delay slot.
3741 __ bind(&is_symbol); 3729 __ bind(&is_symbol);
3742 } 3730 }
3743 3731
3744 // Check that both strings are sequential ASCII. 3732 // Check that both strings are sequential one_byte.
3745 Label runtime; 3733 Label runtime;
3746 __ JumpIfBothInstanceTypesAreNotSequentialAscii( 3734 __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4,
3747 tmp1, tmp2, tmp3, tmp4, &runtime); 3735 &runtime);
3748 3736
3749 // Compare flat ASCII strings. Returns when done. 3737 // Compare flat one_byte strings. Returns when done.
3750 if (equality) { 3738 if (equality) {
3751 StringHelper::GenerateFlatAsciiStringEquals(masm, left, right, tmp1, tmp2, 3739 StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1, tmp2,
3752 tmp3); 3740 tmp3);
3753 } else { 3741 } else {
3754 StringHelper::GenerateCompareFlatAsciiStrings(masm, left, right, tmp1, tmp2, 3742 StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, tmp1,
3755 tmp3, tmp4); 3743 tmp2, tmp3, tmp4);
3756 } 3744 }
3757 3745
3758 // Handle more complex cases in runtime. 3746 // Handle more complex cases in runtime.
3759 __ bind(&runtime); 3747 __ bind(&runtime);
3760 __ Push(left, right); 3748 __ Push(left, right);
3761 if (equality) { 3749 if (equality) {
3762 __ TailCallRuntime(Runtime::kStringEquals, 2, 1); 3750 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
3763 } else { 3751 } else {
3764 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 3752 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
3765 } 3753 }
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after
4901 MemOperand(fp, 6 * kPointerSize), 4889 MemOperand(fp, 6 * kPointerSize),
4902 NULL); 4890 NULL);
4903 } 4891 }
4904 4892
4905 4893
4906 #undef __ 4894 #undef __
4907 4895
4908 } } // namespace v8::internal 4896 } } // namespace v8::internal
4909 4897
4910 #endif // V8_TARGET_ARCH_MIPS64 4898 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698