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:
erik.corry@gmail.com 2010-09-15 10:22:55 +00:00
parent bd6a8c1e4e
commit 62ec3292de
2 changed files with 31 additions and 25 deletions

View File

@ -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>

View File

@ -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(&not_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.