Replace 2 ARM ldr instructions with one ldrd in the code generated
for a SubStringStub and StringCompareStub in the ARM backend. This is a commit of http://codereview.chromium.org/3341012 for Andreas Anyuru. Review URL: http://codereview.chromium.org/3387003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5457 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
bd6a8c1e4e
commit
62ec3292de
1
AUTHORS
1
AUTHORS
@ -9,6 +9,7 @@ ARM Ltd.
|
||||
|
||||
Alexander Botero-Lowry <alexbl@FreeBSD.org>
|
||||
Alexandre Vassalotti <avassalotti@gmail.com>
|
||||
Andreas Anyuru <andreas.anyuru@gmail.com>
|
||||
Burcu Dogan <burcujdogan@gmail.com>
|
||||
Craig Schlenter <craig.schlenter@gmail.com>
|
||||
Daniel Andersson <kodandersson@gmail.com>
|
||||
|
@ -4187,17 +4187,21 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
|
||||
// Check bounds and smi-ness.
|
||||
__ ldr(r7, MemOperand(sp, kToOffset));
|
||||
__ ldr(r6, MemOperand(sp, kFromOffset));
|
||||
Register to = r6;
|
||||
Register from = r7;
|
||||
__ Ldrd(to, from, MemOperand(sp, kToOffset));
|
||||
STATIC_ASSERT(kFromOffset == kToOffset + 4);
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
|
||||
// I.e., arithmetic shift right by one un-smi-tags.
|
||||
__ mov(r2, Operand(r7, ASR, 1), SetCC);
|
||||
__ mov(r3, Operand(r6, ASR, 1), SetCC, cc);
|
||||
// If either r2 or r6 had the smi tag bit set, then carry is set now.
|
||||
__ mov(r2, Operand(to, ASR, 1), SetCC);
|
||||
__ mov(r3, Operand(from, ASR, 1), SetCC, cc);
|
||||
// If either to or from had the smi tag bit set, then carry is set now.
|
||||
__ b(cs, &runtime); // Either "from" or "to" is not a smi.
|
||||
__ b(mi, &runtime); // From is negative.
|
||||
|
||||
// Both to and from are smis.
|
||||
|
||||
__ sub(r2, r2, Operand(r3), SetCC);
|
||||
__ b(mi, &runtime); // Fail if from > to.
|
||||
// Special handling of sub-strings of length 1 and 2. One character strings
|
||||
@ -4208,8 +4212,8 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
// r2: length
|
||||
// r3: from index (untaged smi)
|
||||
// r6: from (smi)
|
||||
// r7: to (smi)
|
||||
// r6 (a.k.a. to): to (smi)
|
||||
// r7 (a.k.a. from): from offset (smi)
|
||||
|
||||
// Make sure first argument is a sequential (or flat) string.
|
||||
__ ldr(r5, MemOperand(sp, kStringOffset));
|
||||
@ -4221,10 +4225,10 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
// r1: instance type
|
||||
// r2: length
|
||||
// r3: from index (untaged smi)
|
||||
// r3: from index (untagged smi)
|
||||
// r5: string
|
||||
// r6: from (smi)
|
||||
// r7: to (smi)
|
||||
// r6 (a.k.a. to): to (smi)
|
||||
// r7 (a.k.a. from): from offset (smi)
|
||||
Label seq_string;
|
||||
__ and_(r4, r1, Operand(kStringRepresentationMask));
|
||||
STATIC_ASSERT(kSeqStringTag < kConsStringTag);
|
||||
@ -4250,17 +4254,18 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
// r2: length
|
||||
// r3: from index (untaged smi)
|
||||
// r5: string
|
||||
// r6: from (smi)
|
||||
// r7: to (smi)
|
||||
// r6 (a.k.a. to): to (smi)
|
||||
// r7 (a.k.a. from): from offset (smi)
|
||||
__ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
|
||||
__ cmp(r4, Operand(r7));
|
||||
__ cmp(r4, Operand(to));
|
||||
__ b(lt, &runtime); // Fail if to > length.
|
||||
to = no_reg;
|
||||
|
||||
// r1: instance type.
|
||||
// r2: result string length.
|
||||
// r3: from index (untaged smi)
|
||||
// r5: string.
|
||||
// r6: from offset (smi)
|
||||
// r7 (a.k.a. from): from offset (smi)
|
||||
// Check for flat ascii string.
|
||||
Label non_ascii_flat;
|
||||
__ tst(r1, Operand(kStringEncodingMask));
|
||||
@ -4302,12 +4307,12 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
// r0: result string.
|
||||
// r2: result string length.
|
||||
// r5: string.
|
||||
// r6: from offset (smi)
|
||||
// r7 (a.k.a. from): from offset (smi)
|
||||
// Locate first character of result.
|
||||
__ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
|
||||
// Locate 'from' character of string.
|
||||
__ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
|
||||
__ add(r5, r5, Operand(r6, ASR, 1));
|
||||
__ add(r5, r5, Operand(from, ASR, 1));
|
||||
|
||||
// r0: result string.
|
||||
// r1: first character of result string.
|
||||
@ -4323,7 +4328,7 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(&non_ascii_flat);
|
||||
// r2: result string length.
|
||||
// r5: string.
|
||||
// r6: from offset (smi)
|
||||
// r7 (a.k.a. from): from offset (smi)
|
||||
// Check for flat two byte string.
|
||||
|
||||
// Allocate the result.
|
||||
@ -4335,18 +4340,19 @@ void SubStringStub::Generate(MacroAssembler* masm) {
|
||||
// Locate first character of result.
|
||||
__ add(r1, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
||||
// Locate 'from' character of string.
|
||||
__ add(r5, r5, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
||||
__ add(r5, r5, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
||||
// As "from" is a smi it is 2 times the value which matches the size of a two
|
||||
// byte character.
|
||||
__ add(r5, r5, Operand(r6));
|
||||
__ add(r5, r5, Operand(from));
|
||||
from = no_reg;
|
||||
|
||||
// r0: result string.
|
||||
// r1: first character of result.
|
||||
// r2: result length.
|
||||
// r5: first character of string to copy.
|
||||
STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
|
||||
StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
|
||||
DEST_ALWAYS_ALIGNED);
|
||||
StringHelper::GenerateCopyCharactersLong(
|
||||
masm, r1, r5, r2, r3, r4, r6, r7, r9, DEST_ALWAYS_ALIGNED);
|
||||
__ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
|
||||
__ add(sp, sp, Operand(3 * kPointerSize));
|
||||
__ Ret();
|
||||
@ -4422,8 +4428,7 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
|
||||
// Stack frame on entry.
|
||||
// sp[0]: right string
|
||||
// sp[4]: left string
|
||||
__ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // left
|
||||
__ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // right
|
||||
__ Ldrd(r0 , r1, MemOperand(sp)); // Load right in r0, left in r1.
|
||||
|
||||
Label not_same;
|
||||
__ cmp(r0, r1);
|
||||
@ -4438,12 +4443,12 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
|
||||
__ bind(¬_same);
|
||||
|
||||
// Check that both objects are sequential ascii strings.
|
||||
__ JumpIfNotBothSequentialAsciiStrings(r0, r1, r2, r3, &runtime);
|
||||
__ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime);
|
||||
|
||||
// Compare flat ascii strings natively. Remove arguments from stack first.
|
||||
__ IncrementCounter(&Counters::string_compare_native, 1, r2, r3);
|
||||
__ add(sp, sp, Operand(2 * kPointerSize));
|
||||
GenerateCompareFlatAsciiStrings(masm, r0, r1, r2, r3, r4, r5);
|
||||
GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
|
||||
|
||||
// Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
|
||||
// tagged as a small integer.
|
||||
|
Loading…
Reference in New Issue
Block a user