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

Side by Side Diff: src/arm/codegen-arm.cc

Issue 549147: Load HeapNumbers directly into floating-point registers in BinaryOpSlowCase. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 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 | « no previous file | 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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 5255 matching lines...) Expand 10 before | Expand all | Expand 10 after
5266 const Builtins::JavaScript& builtin, 5266 const Builtins::JavaScript& builtin,
5267 Token::Value operation, 5267 Token::Value operation,
5268 OverwriteMode mode) { 5268 OverwriteMode mode) {
5269 Label slow, slow_pop_2_first, do_the_call; 5269 Label slow, slow_pop_2_first, do_the_call;
5270 Label r0_is_smi, r1_is_smi, finished_loading_r0, finished_loading_r1; 5270 Label r0_is_smi, r1_is_smi, finished_loading_r0, finished_loading_r1;
5271 // Smi-smi case (overflow). 5271 // Smi-smi case (overflow).
5272 // Since both are Smis there is no heap number to overwrite, so allocate. 5272 // Since both are Smis there is no heap number to overwrite, so allocate.
5273 // The new heap number is in r5. r6 and r7 are scratch. 5273 // The new heap number is in r5. r6 and r7 are scratch.
5274 AllocateHeapNumber(masm, &slow, r5, r6, r7); 5274 AllocateHeapNumber(masm, &slow, r5, r6, r7);
5275 5275
5276 if (CpuFeatures::IsSupported(VFP3)) { 5276 if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
5277 CpuFeatures::Scope scope(VFP3); 5277 CpuFeatures::Scope scope(VFP3);
5278 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); 5278 __ mov(r7, Operand(r0, ASR, kSmiTagSize));
5279 __ IntegerToDoubleConversionWithVFP3(r1, r1, r0); 5279 __ vmov(s15, r7);
5280 __ vcvt(d7, s15);
5281 __ mov(r7, Operand(r1, ASR, kSmiTagSize));
5282 __ vmov(s13, r7);
5283 __ vcvt(d6, s13);
5280 } else { 5284 } else {
5281 // Write Smi from r0 to r3 and r2 in double format. r6 is scratch. 5285 // Write Smi from r0 to r3 and r2 in double format. r6 is scratch.
5282 __ mov(r7, Operand(r0)); 5286 __ mov(r7, Operand(r0));
5283 ConvertToDoubleStub stub1(r3, r2, r7, r6); 5287 ConvertToDoubleStub stub1(r3, r2, r7, r6);
5284 __ push(lr); 5288 __ push(lr);
5285 __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET); 5289 __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
5286 // Write Smi from r1 to r1 and r0 in double format. r6 is scratch. 5290 // Write Smi from r1 to r1 and r0 in double format. r6 is scratch.
5287 __ mov(r7, Operand(r1)); 5291 __ mov(r7, Operand(r1));
5288 ConvertToDoubleStub stub2(r1, r0, r7, r6); 5292 ConvertToDoubleStub stub2(r1, r0, r7, r6);
5289 __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET); 5293 __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
5351 } 5355 }
5352 5356
5353 // Move r0 to a double in r2-r3. 5357 // Move r0 to a double in r2-r3.
5354 __ tst(r0, Operand(kSmiTagMask)); 5358 __ tst(r0, Operand(kSmiTagMask));
5355 __ b(eq, &r0_is_smi); // It's a Smi so don't check it's a heap number. 5359 __ b(eq, &r0_is_smi); // It's a Smi so don't check it's a heap number.
5356 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE); 5360 __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
5357 __ b(ne, &slow); 5361 __ b(ne, &slow);
5358 if (mode == OVERWRITE_RIGHT) { 5362 if (mode == OVERWRITE_RIGHT) {
5359 __ mov(r5, Operand(r0)); // Overwrite this heap number. 5363 __ mov(r5, Operand(r0)); // Overwrite this heap number.
5360 } 5364 }
5361 // Calling convention says that second double is in r2 and r3. 5365 if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
5362 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset)); 5366 CpuFeatures::Scope scope(VFP3);
5363 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + 4)); 5367 // Load the double from tagged HeapNumber r0 to d7.
5368 __ sub(r7, r0, Operand(kHeapObjectTag));
5369 __ vldr(d7, r7, HeapNumber::kValueOffset);
5370 } else {
5371 // Calling convention says that second double is in r2 and r3.
5372 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset));
5373 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + 4));
5374 }
5364 __ jmp(&finished_loading_r0); 5375 __ jmp(&finished_loading_r0);
5365 __ bind(&r0_is_smi); 5376 __ bind(&r0_is_smi);
5366 if (mode == OVERWRITE_RIGHT) { 5377 if (mode == OVERWRITE_RIGHT) {
5367 // We can't overwrite a Smi so get address of new heap number into r5. 5378 // We can't overwrite a Smi so get address of new heap number into r5.
5368 AllocateHeapNumber(masm, &slow, r5, r6, r7); 5379 AllocateHeapNumber(masm, &slow, r5, r6, r7);
5369 } 5380 }
5370 5381
5371 5382 if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
5372 if (CpuFeatures::IsSupported(VFP3)) {
5373 CpuFeatures::Scope scope(VFP3); 5383 CpuFeatures::Scope scope(VFP3);
5374 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); 5384 // Convert smi in r0 to double in d7
5385 __ mov(r7, Operand(r0, ASR, kSmiTagSize));
5386 __ vmov(s15, r7);
5387 __ vcvt(d7, s15);
5375 } else { 5388 } else {
5376 // Write Smi from r0 to r3 and r2 in double format. 5389 // Write Smi from r0 to r3 and r2 in double format.
5377 __ mov(r7, Operand(r0)); 5390 __ mov(r7, Operand(r0));
5378 ConvertToDoubleStub stub3(r3, r2, r7, r6); 5391 ConvertToDoubleStub stub3(r3, r2, r7, r6);
5379 __ push(lr); 5392 __ push(lr);
5380 __ Call(stub3.GetCode(), RelocInfo::CODE_TARGET); 5393 __ Call(stub3.GetCode(), RelocInfo::CODE_TARGET);
5381 __ pop(lr); 5394 __ pop(lr);
5382 } 5395 }
5383 5396
5384 __ bind(&finished_loading_r0); 5397 __ bind(&finished_loading_r0);
5385 5398
5386 // Move r1 to a double in r0-r1. 5399 // Move r1 to a double in r0-r1.
5387 __ tst(r1, Operand(kSmiTagMask)); 5400 __ tst(r1, Operand(kSmiTagMask));
5388 __ b(eq, &r1_is_smi); // It's a Smi so don't check it's a heap number. 5401 __ b(eq, &r1_is_smi); // It's a Smi so don't check it's a heap number.
5389 __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE); 5402 __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE);
5390 __ b(ne, &slow); 5403 __ b(ne, &slow);
5391 if (mode == OVERWRITE_LEFT) { 5404 if (mode == OVERWRITE_LEFT) {
5392 __ mov(r5, Operand(r1)); // Overwrite this heap number. 5405 __ mov(r5, Operand(r1)); // Overwrite this heap number.
5393 } 5406 }
5394 // Calling convention says that first double is in r0 and r1. 5407 if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
5395 __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset)); 5408 CpuFeatures::Scope scope(VFP3);
5396 __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + 4)); 5409 // Load the double from tagged HeapNumber r1 to d6.
5410 __ sub(r7, r1, Operand(kHeapObjectTag));
5411 __ vldr(d6, r7, HeapNumber::kValueOffset);
5412 } else {
5413 // Calling convention says that first double is in r0 and r1.
5414 __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset));
5415 __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + 4));
5416 }
5397 __ jmp(&finished_loading_r1); 5417 __ jmp(&finished_loading_r1);
5398 __ bind(&r1_is_smi); 5418 __ bind(&r1_is_smi);
5399 if (mode == OVERWRITE_LEFT) { 5419 if (mode == OVERWRITE_LEFT) {
5400 // We can't overwrite a Smi so get address of new heap number into r5. 5420 // We can't overwrite a Smi so get address of new heap number into r5.
5401 AllocateHeapNumber(masm, &slow, r5, r6, r7); 5421 AllocateHeapNumber(masm, &slow, r5, r6, r7);
5402 } 5422 }
5403 5423
5404 if (CpuFeatures::IsSupported(VFP3)) { 5424 if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
5405 CpuFeatures::Scope scope(VFP3); 5425 CpuFeatures::Scope scope(VFP3);
5406 __ IntegerToDoubleConversionWithVFP3(r1, r1, r0); 5426 // Convert smi in r1 to double in d6
5427 __ mov(r7, Operand(r1, ASR, kSmiTagSize));
5428 __ vmov(s13, r7);
5429 __ vcvt(d6, s13);
5407 } else { 5430 } else {
5408 // Write Smi from r1 to r1 and r0 in double format. 5431 // Write Smi from r1 to r1 and r0 in double format.
5409 __ mov(r7, Operand(r1)); 5432 __ mov(r7, Operand(r1));
5410 ConvertToDoubleStub stub4(r1, r0, r7, r6); 5433 ConvertToDoubleStub stub4(r1, r0, r7, r6);
5411 __ push(lr); 5434 __ push(lr);
5412 __ Call(stub4.GetCode(), RelocInfo::CODE_TARGET); 5435 __ Call(stub4.GetCode(), RelocInfo::CODE_TARGET);
5413 __ pop(lr); 5436 __ pop(lr);
5414 } 5437 }
5415 5438
5416 __ bind(&finished_loading_r1); 5439 __ bind(&finished_loading_r1);
5417 5440
5418 __ bind(&do_the_call); 5441 __ bind(&do_the_call);
5419 // r0: Left value (least significant part of mantissa). 5442 // If we are inlining the operation using VFP3 instructions for
5420 // r1: Left value (sign, exponent, top of mantissa). 5443 // add, subtract, multiply, or divide, the arguments are in d6 and d7.
5421 // r2: Right value (least significant part of mantissa).
5422 // r3: Right value (sign, exponent, top of mantissa).
5423 // r5: Address of heap number for result.
5424
5425 if (CpuFeatures::IsSupported(VFP3) && 5444 if (CpuFeatures::IsSupported(VFP3) &&
5426 ((Token::MUL == operation) || 5445 ((Token::MUL == operation) ||
5427 (Token::DIV == operation) || 5446 (Token::DIV == operation) ||
5428 (Token::ADD == operation) || 5447 (Token::ADD == operation) ||
5429 (Token::SUB == operation))) { 5448 (Token::SUB == operation))) {
5430 CpuFeatures::Scope scope(VFP3); 5449 CpuFeatures::Scope scope(VFP3);
5431 // ARMv7 VFP3 instructions to implement 5450 // ARMv7 VFP3 instructions to implement
5432 // double precision, add, subtract, multiply, divide. 5451 // double precision, add, subtract, multiply, divide.
5433 __ vmov(d6, r0, r1);
5434 __ vmov(d7, r2, r3);
5435 5452
5436 if (Token::MUL == operation) { 5453 if (Token::MUL == operation) {
5437 __ vmul(d5, d6, d7); 5454 __ vmul(d5, d6, d7);
5438 } else if (Token::DIV == operation) { 5455 } else if (Token::DIV == operation) {
5439 __ vdiv(d5, d6, d7); 5456 __ vdiv(d5, d6, d7);
5440 } else if (Token::ADD == operation) { 5457 } else if (Token::ADD == operation) {
5441 __ vadd(d5, d6, d7); 5458 __ vadd(d5, d6, d7);
5442 } else if (Token::SUB == operation) { 5459 } else if (Token::SUB == operation) {
5443 __ vsub(d5, d6, d7); 5460 __ vsub(d5, d6, d7);
5444 } else { 5461 } else {
5445 UNREACHABLE(); 5462 UNREACHABLE();
5446 } 5463 }
5447 5464 __ sub(r0, r5, Operand(kHeapObjectTag));
5448 __ vmov(r0, r1, d5); 5465 __ vstr(d5, r0, HeapNumber::kValueOffset);
5449 5466 __ add(r0, r0, Operand(kHeapObjectTag));
5450 __ str(r0, FieldMemOperand(r5, HeapNumber::kValueOffset));
5451 __ str(r1, FieldMemOperand(r5, HeapNumber::kValueOffset + 4));
5452 __ mov(r0, Operand(r5));
5453 __ mov(pc, lr); 5467 __ mov(pc, lr);
5454 return; 5468 return;
5455 } 5469 }
5470
5471 // If we did not inline the operation, then the arguments are in:
5472 // r0: Left value (least significant part of mantissa).
5473 // r1: Left value (sign, exponent, top of mantissa).
5474 // r2: Right value (least significant part of mantissa).
5475 // r3: Right value (sign, exponent, top of mantissa).
5476 // r5: Address of heap number for result.
5477
5456 __ push(lr); // For later. 5478 __ push(lr); // For later.
5457 __ push(r5); // Address of heap number that is answer. 5479 __ push(r5); // Address of heap number that is answer.
5458 __ AlignStack(0); 5480 __ AlignStack(0);
5459 // Call C routine that may not cause GC or other trouble. 5481 // Call C routine that may not cause GC or other trouble.
5460 __ mov(r5, Operand(ExternalReference::double_fp_operation(operation))); 5482 __ mov(r5, Operand(ExternalReference::double_fp_operation(operation)));
5461 __ Call(r5); 5483 __ Call(r5);
5462 __ pop(r4); // Address of heap number. 5484 __ pop(r4); // Address of heap number.
5463 __ cmp(r4, Operand(Smi::FromInt(0))); 5485 __ cmp(r4, Operand(Smi::FromInt(0)));
5464 __ pop(r4, eq); // Conditional pop instruction to get rid of alignment push. 5486 __ pop(r4, eq); // Conditional pop instruction to get rid of alignment push.
5465 // Store answer in the overwritable heap number. 5487 // Store answer in the overwritable heap number.
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after
6848 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6870 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6849 // tagged as a small integer. 6871 // tagged as a small integer.
6850 __ bind(&runtime); 6872 __ bind(&runtime);
6851 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 6873 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
6852 } 6874 }
6853 6875
6854 6876
6855 #undef __ 6877 #undef __
6856 6878
6857 } } // namespace v8::internal 6879 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698