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

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

Issue 6927044: Extract common code in string compare loops. (Closed)
Patch Set: Created 9 years, 7 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
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/ia32/code-stubs-ia32.h » ('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 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 5412 matching lines...) Expand 10 before | Expand all | Expand 10 after
5423 Label compare_chars; 5423 Label compare_chars;
5424 __ bind(&check_zero_length); 5424 __ bind(&check_zero_length);
5425 STATIC_ASSERT(kSmiTag == 0); 5425 STATIC_ASSERT(kSmiTag == 0);
5426 __ tst(length, Operand(length)); 5426 __ tst(length, Operand(length));
5427 __ b(ne, &compare_chars); 5427 __ b(ne, &compare_chars);
5428 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 5428 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
5429 __ Ret(); 5429 __ Ret();
5430 5430
5431 // Compare characters. 5431 // Compare characters.
5432 __ bind(&compare_chars); 5432 __ bind(&compare_chars);
5433 5433 GenerateAsciiCharsCompareLoop(masm,
5434 // Change index to run from -length to -1 by adding length to string 5434 left, right, length, scratch2, scratch3,
5435 // start. This means that loop ends when index reaches zero, which 5435 &strings_not_equal);
5436 // doesn't need an additional compare.
5437 __ SmiUntag(length);
5438 __ add(scratch2, length,
5439 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
5440 __ add(left, left, Operand(scratch2));
5441 __ add(right, right, Operand(scratch2));
5442 __ rsb(length, length, Operand(0));
5443 Register index = length; // index = -length;
5444
5445 // Compare loop.
5446 Label loop;
5447 __ bind(&loop);
5448 __ ldrb(scratch2, MemOperand(left, index));
5449 __ ldrb(scratch3, MemOperand(right, index));
5450 __ cmp(scratch2, scratch3);
5451 __ b(ne, &strings_not_equal);
5452 __ add(index, index, Operand(1), SetCC);
5453 __ b(ne, &loop);
5454 5436
5455 // Characters are equal. 5437 // Characters are equal.
5456 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 5438 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
5457 __ Ret(); 5439 __ Ret();
5458 } 5440 }
5459 5441
5460 5442
5461 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 5443 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
5462 Register left, 5444 Register left,
5463 Register right, 5445 Register right,
5464 Register scratch1, 5446 Register scratch1,
5465 Register scratch2, 5447 Register scratch2,
5466 Register scratch3, 5448 Register scratch3,
5467 Register scratch4) { 5449 Register scratch4) {
5468 Label compare_lengths; 5450 Label result_not_equal, compare_lengths;
5469 // Find minimum length and length difference. 5451 // Find minimum length and length difference.
5470 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); 5452 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
5471 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); 5453 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
5472 __ sub(scratch3, scratch1, Operand(scratch2), SetCC); 5454 __ sub(scratch3, scratch1, Operand(scratch2), SetCC);
5473 Register length_delta = scratch3; 5455 Register length_delta = scratch3;
5474 __ mov(scratch1, scratch2, LeaveCC, gt); 5456 __ mov(scratch1, scratch2, LeaveCC, gt);
5475 Register min_length = scratch1; 5457 Register min_length = scratch1;
5476 STATIC_ASSERT(kSmiTag == 0); 5458 STATIC_ASSERT(kSmiTag == 0);
5477 __ tst(min_length, Operand(min_length)); 5459 __ tst(min_length, Operand(min_length));
5478 __ b(eq, &compare_lengths); 5460 __ b(eq, &compare_lengths);
5479 5461
5480 // Untag smi. 5462 // Compare loop.
5481 __ mov(min_length, Operand(min_length, ASR, kSmiTagSize)); 5463 GenerateAsciiCharsCompareLoop(masm,
5464 left, right, min_length, scratch2, scratch4,
5465 &result_not_equal);
5482 5466
5483 // Setup registers so that we only need to increment one register 5467 // Compare lengths - strings up to min-length are equal.
5484 // in the loop.
5485 __ add(scratch2, min_length,
5486 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
5487 __ add(left, left, Operand(scratch2));
5488 __ add(right, right, Operand(scratch2));
5489 // Registers left and right points to the min_length character of strings.
5490 __ rsb(min_length, min_length, Operand(-1));
5491 Register index = min_length;
5492 // Index starts at -min_length.
5493
5494 {
5495 // Compare loop.
5496 Label loop;
5497 __ bind(&loop);
5498 // Compare characters.
5499 __ add(index, index, Operand(1), SetCC);
5500 __ ldrb(scratch2, MemOperand(left, index), ne);
5501 __ ldrb(scratch4, MemOperand(right, index), ne);
5502 // Skip to compare lengths with eq condition true.
5503 __ b(eq, &compare_lengths);
5504 __ cmp(scratch2, scratch4);
5505 __ b(eq, &loop);
5506 // Fallthrough with eq condition false.
5507 }
5508 // Compare lengths - strings up to min-length are equal.
5509 __ bind(&compare_lengths); 5468 __ bind(&compare_lengths);
5510 ASSERT(Smi::FromInt(EQUAL) == static_cast<Smi*>(0)); 5469 ASSERT(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
5511 // Use zero length_delta as result. 5470 // Use length_delta as result if it's zero.
5512 __ mov(r0, Operand(length_delta), SetCC, eq); 5471 __ mov(r0, Operand(length_delta), SetCC);
5513 // Fall through to here if characters compare not-equal. 5472 __ bind(&result_not_equal);
5473 // Conditionally update the result based either on length_delta or
5474 // the last comparion performed in the loop above.
5514 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt); 5475 __ mov(r0, Operand(Smi::FromInt(GREATER)), LeaveCC, gt);
5515 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt); 5476 __ mov(r0, Operand(Smi::FromInt(LESS)), LeaveCC, lt);
5516 __ Ret(); 5477 __ Ret();
5517 } 5478 }
5518 5479
5519 5480
5481 void StringCompareStub::GenerateAsciiCharsCompareLoop(
5482 MacroAssembler* masm,
5483 Register left,
5484 Register right,
5485 Register length,
5486 Register scratch1,
5487 Register scratch2,
5488 Label* chars_not_equal) {
5489 // Change index to run from -length to -1 by adding length to string
5490 // start. This means that loop ends when index reaches zero, which
5491 // doesn't need an additional compare.
5492 __ SmiUntag(length);
5493 __ add(scratch1, length,
5494 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
5495 __ add(left, left, Operand(scratch1));
5496 __ add(right, right, Operand(scratch1));
5497 __ rsb(length, length, Operand(0));
5498 Register index = length; // index = -length;
5499
5500 // Compare loop.
5501 Label loop;
5502 __ bind(&loop);
5503 __ ldrb(scratch1, MemOperand(left, index));
5504 __ ldrb(scratch2, MemOperand(right, index));
5505 __ cmp(scratch1, scratch2);
5506 __ b(ne, chars_not_equal);
5507 __ add(index, index, Operand(1), SetCC);
5508 __ b(ne, &loop);
5509 }
5510
5511
5520 void StringCompareStub::Generate(MacroAssembler* masm) { 5512 void StringCompareStub::Generate(MacroAssembler* masm) {
5521 Label runtime; 5513 Label runtime;
5522 5514
5523 Counters* counters = masm->isolate()->counters(); 5515 Counters* counters = masm->isolate()->counters();
5524 5516
5525 // Stack frame on entry. 5517 // Stack frame on entry.
5526 // sp[0]: right string 5518 // sp[0]: right string
5527 // sp[4]: left string 5519 // sp[4]: left string
5528 __ Ldrd(r0 , r1, MemOperand(sp)); // Load right in r0, left in r1. 5520 __ Ldrd(r0 , r1, MemOperand(sp)); // Load right in r0, left in r1.
5529 5521
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
6102 __ str(pc, MemOperand(sp, 0)); 6094 __ str(pc, MemOperand(sp, 0));
6103 __ Jump(target); // Call the C++ function. 6095 __ Jump(target); // Call the C++ function.
6104 } 6096 }
6105 6097
6106 6098
6107 #undef __ 6099 #undef __
6108 6100
6109 } } // namespace v8::internal 6101 } } // namespace v8::internal
6110 6102
6111 #endif // V8_TARGET_ARCH_ARM 6103 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/ia32/code-stubs-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698