OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |