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

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

Issue 3341012: v8: Replace 2 ARM ldr instructions with one ldrd in the code generated for a SubS... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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
« no previous file with comments | « AUTHORS ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 4126 matching lines...) Expand 10 before | Expand all | Expand 10 after
4137 // both "from" and "to" are smis, and 4137 // both "from" and "to" are smis, and
4138 // 0 <= from <= to <= string.length. 4138 // 0 <= from <= to <= string.length.
4139 // If any of these assumptions fail, we call the runtime system. 4139 // If any of these assumptions fail, we call the runtime system.
4140 4140
4141 static const int kToOffset = 0 * kPointerSize; 4141 static const int kToOffset = 0 * kPointerSize;
4142 static const int kFromOffset = 1 * kPointerSize; 4142 static const int kFromOffset = 1 * kPointerSize;
4143 static const int kStringOffset = 2 * kPointerSize; 4143 static const int kStringOffset = 2 * kPointerSize;
4144 4144
4145 4145
4146 // Check bounds and smi-ness. 4146 // Check bounds and smi-ness.
4147 __ ldr(r7, MemOperand(sp, kToOffset)); 4147 // Both to and from are smis.
Erik Corry 2010/09/15 10:23:53 We don't know that yet, so I moved this comment do
4148 __ ldr(r6, MemOperand(sp, kFromOffset)); 4148 Register to = r6;
4149 Register from = r7;
4150 __ Ldrd(to, from, MemOperand(sp, kToOffset));
4151 STATIC_ASSERT(kFromOffset == kToOffset + 4);
4149 STATIC_ASSERT(kSmiTag == 0); 4152 STATIC_ASSERT(kSmiTag == 0);
4150 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 4153 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
4151 // I.e., arithmetic shift right by one un-smi-tags. 4154 // I.e., arithmetic shift right by one un-smi-tags.
4152 __ mov(r2, Operand(r7, ASR, 1), SetCC); 4155 __ mov(r2, Operand(to, ASR, 1), SetCC);
4153 __ mov(r3, Operand(r6, ASR, 1), SetCC, cc); 4156 __ mov(r3, Operand(from, ASR, 1), SetCC, cc);
4154 // If either r2 or r6 had the smi tag bit set, then carry is set now. 4157 // If either to or from had the smi tag bit set, then carry is set now.
4155 __ b(cs, &runtime); // Either "from" or "to" is not a smi. 4158 __ b(cs, &runtime); // Either "from" or "to" is not a smi.
4156 __ b(mi, &runtime); // From is negative. 4159 __ b(mi, &runtime); // From is negative.
4157 4160
4158 __ sub(r2, r2, Operand(r3), SetCC); 4161 __ sub(r2, r2, Operand(r3), SetCC);
4159 __ b(mi, &runtime); // Fail if from > to. 4162 __ b(mi, &runtime); // Fail if from > to.
4160 // Special handling of sub-strings of length 1 and 2. One character strings 4163 // Special handling of sub-strings of length 1 and 2. One character strings
4161 // are handled in the runtime system (looked up in the single character 4164 // are handled in the runtime system (looked up in the single character
4162 // cache). Two character strings are looked for in the symbol cache. 4165 // cache). Two character strings are looked for in the symbol cache.
4163 __ cmp(r2, Operand(2)); 4166 __ cmp(r2, Operand(2));
4164 __ b(lt, &runtime); 4167 __ b(lt, &runtime);
4165 4168
4166 // r2: length 4169 // r2: length
4167 // r3: from index (untaged smi) 4170 // r3: from index (untaged smi)
4168 // r6: from (smi)
4169 // r7: to (smi)
Erik Corry 2010/09/15 10:23:53 I put these comments back.
4170 4171
4171 // Make sure first argument is a sequential (or flat) string. 4172 // Make sure first argument is a sequential (or flat) string.
4172 __ ldr(r5, MemOperand(sp, kStringOffset)); 4173 __ ldr(r5, MemOperand(sp, kStringOffset));
4173 STATIC_ASSERT(kSmiTag == 0); 4174 STATIC_ASSERT(kSmiTag == 0);
4174 __ tst(r5, Operand(kSmiTagMask)); 4175 __ tst(r5, Operand(kSmiTagMask));
4175 __ b(eq, &runtime); 4176 __ b(eq, &runtime);
4176 Condition is_string = masm->IsObjectStringType(r5, r1); 4177 Condition is_string = masm->IsObjectStringType(r5, r1);
4177 __ b(NegateCondition(is_string), &runtime); 4178 __ b(NegateCondition(is_string), &runtime);
4178 4179
4179 // r1: instance type 4180 // r1: instance type
4180 // r2: length 4181 // r2: length
4181 // r3: from index (untaged smi) 4182 // r3: from index (untaged smi)
4182 // r5: string 4183 // r5: string
4183 // r6: from (smi)
Erik Corry 2010/09/15 10:23:53 And these
4184 // r7: to (smi)
4185 Label seq_string; 4184 Label seq_string;
4186 __ and_(r4, r1, Operand(kStringRepresentationMask)); 4185 __ and_(r4, r1, Operand(kStringRepresentationMask));
4187 STATIC_ASSERT(kSeqStringTag < kConsStringTag); 4186 STATIC_ASSERT(kSeqStringTag < kConsStringTag);
4188 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 4187 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
4189 __ cmp(r4, Operand(kConsStringTag)); 4188 __ cmp(r4, Operand(kConsStringTag));
4190 __ b(gt, &runtime); // External strings go to runtime. 4189 __ b(gt, &runtime); // External strings go to runtime.
4191 __ b(lt, &seq_string); // Sequential strings are handled directly. 4190 __ b(lt, &seq_string); // Sequential strings are handled directly.
4192 4191
4193 // Cons string. Try to recurse (once) on the first substring. 4192 // Cons string. Try to recurse (once) on the first substring.
4194 // (This adds a little more generality than necessary to handle flattened 4193 // (This adds a little more generality than necessary to handle flattened
4195 // cons strings, but not much). 4194 // cons strings, but not much).
4196 __ ldr(r5, FieldMemOperand(r5, ConsString::kFirstOffset)); 4195 __ ldr(r5, FieldMemOperand(r5, ConsString::kFirstOffset));
4197 __ ldr(r4, FieldMemOperand(r5, HeapObject::kMapOffset)); 4196 __ ldr(r4, FieldMemOperand(r5, HeapObject::kMapOffset));
4198 __ ldrb(r1, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 4197 __ ldrb(r1, FieldMemOperand(r4, Map::kInstanceTypeOffset));
4199 __ tst(r1, Operand(kStringRepresentationMask)); 4198 __ tst(r1, Operand(kStringRepresentationMask));
4200 STATIC_ASSERT(kSeqStringTag == 0); 4199 STATIC_ASSERT(kSeqStringTag == 0);
4201 __ b(ne, &runtime); // Cons and External strings go to runtime. 4200 __ b(ne, &runtime); // Cons and External strings go to runtime.
4202 4201
4203 // Definitly a sequential string. 4202 // Definitly a sequential string.
4204 __ bind(&seq_string); 4203 __ bind(&seq_string);
4205 4204
4206 // r1: instance type. 4205 // r1: instance type.
4207 // r2: length 4206 // r2: length
4208 // r3: from index (untaged smi) 4207 // r3: from index (untaged smi)
4209 // r5: string 4208 // r5: string
4210 // r6: from (smi) 4209 // r6 (a.k.a. to): to (smi)
4211 // r7: to (smi)
Erik Corry 2010/09/15 10:23:53 And I put 'to' back here.
4212 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset)); 4210 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
4213 __ cmp(r4, Operand(r7)); 4211 __ cmp(r4, Operand(to));
4214 __ b(lt, &runtime); // Fail if to > length. 4212 __ b(lt, &runtime); // Fail if to > length.
4215 4213
4216 // r1: instance type. 4214 // r1: instance type.
4217 // r2: result string length. 4215 // r2: result string length.
4218 // r3: from index (untaged smi) 4216 // r3: from index (untaged smi)
4219 // r5: string. 4217 // r5: string.
4220 // r6: from offset (smi)
Erik Corry 2010/09/15 10:23:53 We use 'from' below so it is still live here, so I
4221 // Check for flat ascii string. 4218 // Check for flat ascii string.
4222 Label non_ascii_flat; 4219 Label non_ascii_flat;
4223 __ tst(r1, Operand(kStringEncodingMask)); 4220 __ tst(r1, Operand(kStringEncodingMask));
4224 STATIC_ASSERT(kTwoByteStringTag == 0); 4221 STATIC_ASSERT(kTwoByteStringTag == 0);
4225 __ b(eq, &non_ascii_flat); 4222 __ b(eq, &non_ascii_flat);
4226 4223
4227 Label result_longer_than_two; 4224 Label result_longer_than_two;
4228 __ cmp(r2, Operand(2)); 4225 __ cmp(r2, Operand(2));
4229 __ b(gt, &result_longer_than_two); 4226 __ b(gt, &result_longer_than_two);
4230 4227
(...skipping 21 matching lines...) Expand all
4252 __ Ret(); 4249 __ Ret();
4253 4250
4254 __ bind(&result_longer_than_two); 4251 __ bind(&result_longer_than_two);
4255 4252
4256 // Allocate the result. 4253 // Allocate the result.
4257 __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime); 4254 __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime);
4258 4255
4259 // r0: result string. 4256 // r0: result string.
4260 // r2: result string length. 4257 // r2: result string length.
4261 // r5: string. 4258 // r5: string.
4262 // r6: from offset (smi) 4259 // r7 (a.k.a. from): from offset (smi)
4263 // Locate first character of result. 4260 // Locate first character of result.
4264 __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 4261 __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
4265 // Locate 'from' character of string. 4262 // Locate 'from' character of string.
4266 __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 4263 __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
4267 __ add(r5, r5, Operand(r6, ASR, 1)); 4264 __ add(r5, r5, Operand(from, ASR, 1));
4268 4265
4269 // r0: result string. 4266 // r0: result string.
4270 // r1: first character of result string. 4267 // r1: first character of result string.
4271 // r2: result string length. 4268 // r2: result string length.
4272 // r5: first character of sub string to copy. 4269 // r5: first character of sub string to copy.
4273 STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0); 4270 STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
4274 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9, 4271 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
4275 COPY_ASCII | DEST_ALWAYS_ALIGNED); 4272 COPY_ASCII | DEST_ALWAYS_ALIGNED);
4276 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4); 4273 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
4277 __ add(sp, sp, Operand(3 * kPointerSize)); 4274 __ add(sp, sp, Operand(3 * kPointerSize));
4278 __ Ret(); 4275 __ Ret();
4279 4276
4280 __ bind(&non_ascii_flat); 4277 __ bind(&non_ascii_flat);
4281 // r2: result string length. 4278 // r2: result string length.
4282 // r5: string. 4279 // r5: string.
4283 // r6: from offset (smi) 4280 // r7 (a.k.a. from): from offset (smi)
4284 // Check for flat two byte string. 4281 // Check for flat two byte string.
4285 4282
4286 // Allocate the result. 4283 // Allocate the result.
4287 __ AllocateTwoByteString(r0, r2, r1, r3, r4, &runtime); 4284 __ AllocateTwoByteString(r0, r2, r1, r3, r4, &runtime);
4288 4285
4289 // r0: result string. 4286 // r0: result string.
4290 // r2: result string length. 4287 // r2: result string length.
4291 // r5: string. 4288 // r5: string.
4292 // Locate first character of result. 4289 // Locate first character of result.
4293 __ add(r1, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 4290 __ add(r1, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
4294 // Locate 'from' character of string. 4291 // Locate 'from' character of string.
4295 __ add(r5, r5, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 4292 __ add(r5, r5, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
4296 // As "from" is a smi it is 2 times the value which matches the size of a two 4293 // As "from" is a smi it is 2 times the value which matches the size of a two
4297 // byte character. 4294 // byte character.
4298 __ add(r5, r5, Operand(r6)); 4295 __ add(r5, r5, Operand(from));
4299 4296
4300 // r0: result string. 4297 // r0: result string.
4301 // r1: first character of result. 4298 // r1: first character of result.
4302 // r2: result length. 4299 // r2: result length.
4303 // r5: first character of string to copy. 4300 // r5: first character of string to copy.
4304 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 4301 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
4305 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9, 4302 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7,
4306 DEST_ALWAYS_ALIGNED); 4303 r9, DEST_ALWAYS_ALIGNED);
4307 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4); 4304 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
4308 __ add(sp, sp, Operand(3 * kPointerSize)); 4305 __ add(sp, sp, Operand(3 * kPointerSize));
4309 __ Ret(); 4306 __ Ret();
4310 4307
4311 // Just jump to runtime to create the sub string. 4308 // Just jump to runtime to create the sub string.
4312 __ bind(&runtime); 4309 __ bind(&runtime);
4313 __ TailCallRuntime(Runtime::kSubString, 3, 1); 4310 __ TailCallRuntime(Runtime::kSubString, 3, 1);
4314 } 4311 }
4315 4312
4316 4313
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4372 __ Ret(); 4369 __ Ret();
4373 } 4370 }
4374 4371
4375 4372
4376 void StringCompareStub::Generate(MacroAssembler* masm) { 4373 void StringCompareStub::Generate(MacroAssembler* masm) {
4377 Label runtime; 4374 Label runtime;
4378 4375
4379 // Stack frame on entry. 4376 // Stack frame on entry.
4380 // sp[0]: right string 4377 // sp[0]: right string
4381 // sp[4]: left string 4378 // sp[4]: left string
4382 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // left 4379 __ Ldrd(r0 , r1, MemOperand(sp)); // Load right in r0, left in r1.
4383 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // right
4384 4380
4385 Label not_same; 4381 Label not_same;
4386 __ cmp(r0, r1); 4382 __ cmp(r0, r1);
4387 __ b(ne, &not_same); 4383 __ b(ne, &not_same);
4388 STATIC_ASSERT(EQUAL == 0); 4384 STATIC_ASSERT(EQUAL == 0);
4389 STATIC_ASSERT(kSmiTag == 0); 4385 STATIC_ASSERT(kSmiTag == 0);
4390 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 4386 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
4391 __ IncrementCounter(&Counters::string_compare_native, 1, r1, r2); 4387 __ IncrementCounter(&Counters::string_compare_native, 1, r1, r2);
4392 __ add(sp, sp, Operand(2 * kPointerSize)); 4388 __ add(sp, sp, Operand(2 * kPointerSize));
4393 __ Ret(); 4389 __ Ret();
4394 4390
4395 __ bind(&not_same); 4391 __ bind(&not_same);
4396 4392
4397 // Check that both objects are sequential ascii strings. 4393 // Check that both objects are sequential ascii strings.
4398 __ JumpIfNotBothSequentialAsciiStrings(r0, r1, r2, r3, &runtime); 4394 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime);
4399 4395
4400 // Compare flat ascii strings natively. Remove arguments from stack first. 4396 // Compare flat ascii strings natively. Remove arguments from stack first.
4401 __ IncrementCounter(&Counters::string_compare_native, 1, r2, r3); 4397 __ IncrementCounter(&Counters::string_compare_native, 1, r2, r3);
4402 __ add(sp, sp, Operand(2 * kPointerSize)); 4398 __ add(sp, sp, Operand(2 * kPointerSize));
4403 GenerateCompareFlatAsciiStrings(masm, r0, r1, r2, r3, r4, r5); 4399 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
4404 4400
4405 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 4401 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
4406 // tagged as a small integer. 4402 // tagged as a small integer.
4407 __ bind(&runtime); 4403 __ bind(&runtime);
4408 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 4404 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
4409 } 4405 }
4410 4406
4411 4407
4412 void StringAddStub::Generate(MacroAssembler* masm) { 4408 void StringAddStub::Generate(MacroAssembler* masm) {
4413 Label string_add_runtime; 4409 Label string_add_runtime;
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4679 __ bind(&string_add_runtime); 4675 __ bind(&string_add_runtime);
4680 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 4676 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
4681 } 4677 }
4682 4678
4683 4679
4684 #undef __ 4680 #undef __
4685 4681
4686 } } // namespace v8::internal 4682 } } // namespace v8::internal
4687 4683
4688 #endif // V8_TARGET_ARCH_ARM 4684 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « AUTHORS ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698