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

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

Issue 3387003: Replace 2 ARM ldr instructions with one ldrd in the code generated... (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 Register to = r6;
4148 __ ldr(r6, MemOperand(sp, kFromOffset)); 4148 Register from = r7;
4149 __ Ldrd(to, from, MemOperand(sp, kToOffset));
4150 STATIC_ASSERT(kFromOffset == kToOffset + 4);
4149 STATIC_ASSERT(kSmiTag == 0); 4151 STATIC_ASSERT(kSmiTag == 0);
4150 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 4152 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
4151 // I.e., arithmetic shift right by one un-smi-tags. 4153 // I.e., arithmetic shift right by one un-smi-tags.
4152 __ mov(r2, Operand(r7, ASR, 1), SetCC); 4154 __ mov(r2, Operand(to, ASR, 1), SetCC);
4153 __ mov(r3, Operand(r6, ASR, 1), SetCC, cc); 4155 __ 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. 4156 // 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. 4157 __ b(cs, &runtime); // Either "from" or "to" is not a smi.
4156 __ b(mi, &runtime); // From is negative. 4158 __ b(mi, &runtime); // From is negative.
4157 4159
4160 // Both to and from are smis.
4161
4158 __ sub(r2, r2, Operand(r3), SetCC); 4162 __ sub(r2, r2, Operand(r3), SetCC);
4159 __ b(mi, &runtime); // Fail if from > to. 4163 __ b(mi, &runtime); // Fail if from > to.
4160 // Special handling of sub-strings of length 1 and 2. One character strings 4164 // 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 4165 // are handled in the runtime system (looked up in the single character
4162 // cache). Two character strings are looked for in the symbol cache. 4166 // cache). Two character strings are looked for in the symbol cache.
4163 __ cmp(r2, Operand(2)); 4167 __ cmp(r2, Operand(2));
4164 __ b(lt, &runtime); 4168 __ b(lt, &runtime);
4165 4169
4166 // r2: length 4170 // r2: length
4167 // r3: from index (untaged smi) 4171 // r3: from index (untaged smi)
4168 // r6: from (smi) 4172 // r6 (a.k.a. to): to (smi)
4169 // r7: to (smi) 4173 // r7 (a.k.a. from): from offset (smi)
4170 4174
4171 // Make sure first argument is a sequential (or flat) string. 4175 // Make sure first argument is a sequential (or flat) string.
4172 __ ldr(r5, MemOperand(sp, kStringOffset)); 4176 __ ldr(r5, MemOperand(sp, kStringOffset));
4173 STATIC_ASSERT(kSmiTag == 0); 4177 STATIC_ASSERT(kSmiTag == 0);
4174 __ tst(r5, Operand(kSmiTagMask)); 4178 __ tst(r5, Operand(kSmiTagMask));
4175 __ b(eq, &runtime); 4179 __ b(eq, &runtime);
4176 Condition is_string = masm->IsObjectStringType(r5, r1); 4180 Condition is_string = masm->IsObjectStringType(r5, r1);
4177 __ b(NegateCondition(is_string), &runtime); 4181 __ b(NegateCondition(is_string), &runtime);
4178 4182
4179 // r1: instance type 4183 // r1: instance type
4180 // r2: length 4184 // r2: length
4181 // r3: from index (untaged smi) 4185 // r3: from index (untagged smi)
4182 // r5: string 4186 // r5: string
4183 // r6: from (smi) 4187 // r6 (a.k.a. to): to (smi)
4184 // r7: to (smi) 4188 // r7 (a.k.a. from): from offset (smi)
4185 Label seq_string; 4189 Label seq_string;
4186 __ and_(r4, r1, Operand(kStringRepresentationMask)); 4190 __ and_(r4, r1, Operand(kStringRepresentationMask));
4187 STATIC_ASSERT(kSeqStringTag < kConsStringTag); 4191 STATIC_ASSERT(kSeqStringTag < kConsStringTag);
4188 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 4192 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
4189 __ cmp(r4, Operand(kConsStringTag)); 4193 __ cmp(r4, Operand(kConsStringTag));
4190 __ b(gt, &runtime); // External strings go to runtime. 4194 __ b(gt, &runtime); // External strings go to runtime.
4191 __ b(lt, &seq_string); // Sequential strings are handled directly. 4195 __ b(lt, &seq_string); // Sequential strings are handled directly.
4192 4196
4193 // Cons string. Try to recurse (once) on the first substring. 4197 // Cons string. Try to recurse (once) on the first substring.
4194 // (This adds a little more generality than necessary to handle flattened 4198 // (This adds a little more generality than necessary to handle flattened
4195 // cons strings, but not much). 4199 // cons strings, but not much).
4196 __ ldr(r5, FieldMemOperand(r5, ConsString::kFirstOffset)); 4200 __ ldr(r5, FieldMemOperand(r5, ConsString::kFirstOffset));
4197 __ ldr(r4, FieldMemOperand(r5, HeapObject::kMapOffset)); 4201 __ ldr(r4, FieldMemOperand(r5, HeapObject::kMapOffset));
4198 __ ldrb(r1, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 4202 __ ldrb(r1, FieldMemOperand(r4, Map::kInstanceTypeOffset));
4199 __ tst(r1, Operand(kStringRepresentationMask)); 4203 __ tst(r1, Operand(kStringRepresentationMask));
4200 STATIC_ASSERT(kSeqStringTag == 0); 4204 STATIC_ASSERT(kSeqStringTag == 0);
4201 __ b(ne, &runtime); // Cons and External strings go to runtime. 4205 __ b(ne, &runtime); // Cons and External strings go to runtime.
4202 4206
4203 // Definitly a sequential string. 4207 // Definitly a sequential string.
4204 __ bind(&seq_string); 4208 __ bind(&seq_string);
4205 4209
4206 // r1: instance type. 4210 // r1: instance type.
4207 // r2: length 4211 // r2: length
4208 // r3: from index (untaged smi) 4212 // r3: from index (untaged smi)
4209 // r5: string 4213 // r5: string
4210 // r6: from (smi) 4214 // r6 (a.k.a. to): to (smi)
4211 // r7: to (smi) 4215 // r7 (a.k.a. from): from offset (smi)
4212 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset)); 4216 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
4213 __ cmp(r4, Operand(r7)); 4217 __ cmp(r4, Operand(to));
4214 __ b(lt, &runtime); // Fail if to > length. 4218 __ b(lt, &runtime); // Fail if to > length.
Søren Thygesen Gjesse 2010/09/15 10:09:07 Looks as if "to" is not live after here, maybe set
Erik Corry 2010/09/15 10:22:42 Done.
4215 4219
4216 // r1: instance type. 4220 // r1: instance type.
4217 // r2: result string length. 4221 // r2: result string length.
4218 // r3: from index (untaged smi) 4222 // r3: from index (untaged smi)
4219 // r5: string. 4223 // r5: string.
4220 // r6: from offset (smi) 4224 // r7 (a.k.a. from): from offset (smi)
4221 // Check for flat ascii string. 4225 // Check for flat ascii string.
4222 Label non_ascii_flat; 4226 Label non_ascii_flat;
4223 __ tst(r1, Operand(kStringEncodingMask)); 4227 __ tst(r1, Operand(kStringEncodingMask));
4224 STATIC_ASSERT(kTwoByteStringTag == 0); 4228 STATIC_ASSERT(kTwoByteStringTag == 0);
4225 __ b(eq, &non_ascii_flat); 4229 __ b(eq, &non_ascii_flat);
4226 4230
4227 Label result_longer_than_two; 4231 Label result_longer_than_two;
4228 __ cmp(r2, Operand(2)); 4232 __ cmp(r2, Operand(2));
4229 __ b(gt, &result_longer_than_two); 4233 __ b(gt, &result_longer_than_two);
4230 4234
4231 // Sub string of length 2 requested. 4235 // Sub string of length 2 requested.
4232 // Get the two characters forming the sub string. 4236 // Get the two characters forming the sub string.
4233 __ add(r5, r5, Operand(r3)); 4237 __ add(r5, r5, Operand(r3));
4234 __ ldrb(r3, FieldMemOperand(r5, SeqAsciiString::kHeaderSize)); 4238 __ ldrb(r3, FieldMemOperand(r5, SeqAsciiString::kHeaderSize));
4235 __ ldrb(r4, FieldMemOperand(r5, SeqAsciiString::kHeaderSize + 1)); 4239 __ ldrb(r4, FieldMemOperand(r5, SeqAsciiString::kHeaderSize + 1));
4236 4240
4237 // Try to lookup two character string in symbol table. 4241 // Try to lookup two character string in symbol table.
4238 Label make_two_character_string; 4242 Label make_two_character_string;
Søren Thygesen Gjesse 2010/09/15 10:09:07 ... and then "from" should be set to no_reg here (
Erik Corry 2010/09/15 10:22:42 No, r7 with its original contents is used below he
4239 StringHelper::GenerateTwoCharacterSymbolTableProbe( 4243 StringHelper::GenerateTwoCharacterSymbolTableProbe(
4240 masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string); 4244 masm, r3, r4, r1, r5, r6, r7, r9, &make_two_character_string);
4241 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4); 4245 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
4242 __ add(sp, sp, Operand(3 * kPointerSize)); 4246 __ add(sp, sp, Operand(3 * kPointerSize));
4243 __ Ret(); 4247 __ Ret();
4244 4248
4245 // r2: result string length. 4249 // r2: result string length.
4246 // r3: two characters combined into halfword in little endian byte order. 4250 // r3: two characters combined into halfword in little endian byte order.
4247 __ bind(&make_two_character_string); 4251 __ bind(&make_two_character_string);
4248 __ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime); 4252 __ AllocateAsciiString(r0, r2, r4, r5, r9, &runtime);
4249 __ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize)); 4253 __ strh(r3, FieldMemOperand(r0, SeqAsciiString::kHeaderSize));
4250 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4); 4254 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
4251 __ add(sp, sp, Operand(3 * kPointerSize)); 4255 __ add(sp, sp, Operand(3 * kPointerSize));
4252 __ Ret(); 4256 __ Ret();
4253 4257
4254 __ bind(&result_longer_than_two); 4258 __ bind(&result_longer_than_two);
4255 4259
4256 // Allocate the result. 4260 // Allocate the result.
4257 __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime); 4261 __ AllocateAsciiString(r0, r2, r3, r4, r1, &runtime);
4258 4262
4259 // r0: result string. 4263 // r0: result string.
4260 // r2: result string length. 4264 // r2: result string length.
4261 // r5: string. 4265 // r5: string.
4262 // r6: from offset (smi) 4266 // r7 (a.k.a. from): from offset (smi)
4263 // Locate first character of result. 4267 // Locate first character of result.
4264 __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 4268 __ add(r1, r0, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
4265 // Locate 'from' character of string. 4269 // Locate 'from' character of string.
4266 __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 4270 __ add(r5, r5, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
4267 __ add(r5, r5, Operand(r6, ASR, 1)); 4271 __ add(r5, r5, Operand(from, ASR, 1));
4268 4272
4269 // r0: result string. 4273 // r0: result string.
4270 // r1: first character of result string. 4274 // r1: first character of result string.
4271 // r2: result string length. 4275 // r2: result string length.
4272 // r5: first character of sub string to copy. 4276 // r5: first character of sub string to copy.
4273 STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0); 4277 STATIC_ASSERT((SeqAsciiString::kHeaderSize & kObjectAlignmentMask) == 0);
4274 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9, 4278 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9,
4275 COPY_ASCII | DEST_ALWAYS_ALIGNED); 4279 COPY_ASCII | DEST_ALWAYS_ALIGNED);
4276 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4); 4280 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
4277 __ add(sp, sp, Operand(3 * kPointerSize)); 4281 __ add(sp, sp, Operand(3 * kPointerSize));
4278 __ Ret(); 4282 __ Ret();
4279 4283
4280 __ bind(&non_ascii_flat); 4284 __ bind(&non_ascii_flat);
4281 // r2: result string length. 4285 // r2: result string length.
4282 // r5: string. 4286 // r5: string.
4283 // r6: from offset (smi) 4287 // r7 (a.k.a. from): from offset (smi)
4284 // Check for flat two byte string. 4288 // Check for flat two byte string.
4285 4289
4286 // Allocate the result. 4290 // Allocate the result.
4287 __ AllocateTwoByteString(r0, r2, r1, r3, r4, &runtime); 4291 __ AllocateTwoByteString(r0, r2, r1, r3, r4, &runtime);
4288 4292
4289 // r0: result string. 4293 // r0: result string.
4290 // r2: result string length. 4294 // r2: result string length.
4291 // r5: string. 4295 // r5: string.
4292 // Locate first character of result. 4296 // Locate first character of result.
4293 __ add(r1, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 4297 __ add(r1, r0, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
4294 // Locate 'from' character of string. 4298 // Locate 'from' character of string.
4295 __ add(r5, r5, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 4299 __ 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 4300 // As "from" is a smi it is 2 times the value which matches the size of a two
4297 // byte character. 4301 // byte character.
4298 __ add(r5, r5, Operand(r6)); 4302 __ add(r5, r5, Operand(from));
4299 4303
4300 // r0: result string. 4304 // r0: result string.
4301 // r1: first character of result. 4305 // r1: first character of result.
4302 // r2: result length. 4306 // r2: result length.
4303 // r5: first character of string to copy. 4307 // r5: first character of string to copy.
4304 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 4308 STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
4305 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7, r9, 4309 StringHelper::GenerateCopyCharactersLong(masm, r1, r5, r2, r3, r4, r6, r7,
Søren Thygesen Gjesse 2010/09/15 10:09:07 All arguments on a single (new line)?
Erik Corry 2010/09/15 10:22:42 Done.
4306 DEST_ALWAYS_ALIGNED); 4310 r9, DEST_ALWAYS_ALIGNED);
4307 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4); 4311 __ IncrementCounter(&Counters::sub_string_native, 1, r3, r4);
4308 __ add(sp, sp, Operand(3 * kPointerSize)); 4312 __ add(sp, sp, Operand(3 * kPointerSize));
4309 __ Ret(); 4313 __ Ret();
4310 4314
4311 // Just jump to runtime to create the sub string. 4315 // Just jump to runtime to create the sub string.
4312 __ bind(&runtime); 4316 __ bind(&runtime);
4313 __ TailCallRuntime(Runtime::kSubString, 3, 1); 4317 __ TailCallRuntime(Runtime::kSubString, 3, 1);
4314 } 4318 }
4315 4319
4316 4320
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4372 __ Ret(); 4376 __ Ret();
4373 } 4377 }
4374 4378
4375 4379
4376 void StringCompareStub::Generate(MacroAssembler* masm) { 4380 void StringCompareStub::Generate(MacroAssembler* masm) {
4377 Label runtime; 4381 Label runtime;
4378 4382
4379 // Stack frame on entry. 4383 // Stack frame on entry.
4380 // sp[0]: right string 4384 // sp[0]: right string
4381 // sp[4]: left string 4385 // sp[4]: left string
4382 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); // left 4386 __ Ldrd(r0 , r1, MemOperand(sp)); // Load right in r0, left in r1.
4383 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); // right
4384 4387
4385 Label not_same; 4388 Label not_same;
4386 __ cmp(r0, r1); 4389 __ cmp(r0, r1);
4387 __ b(ne, &not_same); 4390 __ b(ne, &not_same);
4388 STATIC_ASSERT(EQUAL == 0); 4391 STATIC_ASSERT(EQUAL == 0);
4389 STATIC_ASSERT(kSmiTag == 0); 4392 STATIC_ASSERT(kSmiTag == 0);
4390 __ mov(r0, Operand(Smi::FromInt(EQUAL))); 4393 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
4391 __ IncrementCounter(&Counters::string_compare_native, 1, r1, r2); 4394 __ IncrementCounter(&Counters::string_compare_native, 1, r1, r2);
4392 __ add(sp, sp, Operand(2 * kPointerSize)); 4395 __ add(sp, sp, Operand(2 * kPointerSize));
4393 __ Ret(); 4396 __ Ret();
4394 4397
4395 __ bind(&not_same); 4398 __ bind(&not_same);
4396 4399
4397 // Check that both objects are sequential ascii strings. 4400 // Check that both objects are sequential ascii strings.
4398 __ JumpIfNotBothSequentialAsciiStrings(r0, r1, r2, r3, &runtime); 4401 __ JumpIfNotBothSequentialAsciiStrings(r1, r0, r2, r3, &runtime);
4399 4402
4400 // Compare flat ascii strings natively. Remove arguments from stack first. 4403 // Compare flat ascii strings natively. Remove arguments from stack first.
4401 __ IncrementCounter(&Counters::string_compare_native, 1, r2, r3); 4404 __ IncrementCounter(&Counters::string_compare_native, 1, r2, r3);
4402 __ add(sp, sp, Operand(2 * kPointerSize)); 4405 __ add(sp, sp, Operand(2 * kPointerSize));
4403 GenerateCompareFlatAsciiStrings(masm, r0, r1, r2, r3, r4, r5); 4406 GenerateCompareFlatAsciiStrings(masm, r1, r0, r2, r3, r4, r5);
4404 4407
4405 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 4408 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
4406 // tagged as a small integer. 4409 // tagged as a small integer.
4407 __ bind(&runtime); 4410 __ bind(&runtime);
4408 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 4411 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
4409 } 4412 }
4410 4413
4411 4414
4412 void StringAddStub::Generate(MacroAssembler* masm) { 4415 void StringAddStub::Generate(MacroAssembler* masm) {
4413 Label string_add_runtime; 4416 Label string_add_runtime;
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4679 __ bind(&string_add_runtime); 4682 __ bind(&string_add_runtime);
4680 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 4683 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
4681 } 4684 }
4682 4685
4683 4686
4684 #undef __ 4687 #undef __
4685 4688
4686 } } // namespace v8::internal 4689 } } // namespace v8::internal
4687 4690
4688 #endif // V8_TARGET_ARCH_ARM 4691 #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