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

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

Issue 6903060: Version 3.3.2.... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 8 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 | « src/arm/code-stubs-arm.h ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // Compute lower part of fraction (last 12 bits). 357 // Compute lower part of fraction (last 12 bits).
358 __ mov(mantissa, Operand(source_, LSL, HeapNumber::kMantissaBitsInTopWord)); 358 __ mov(mantissa, Operand(source_, LSL, HeapNumber::kMantissaBitsInTopWord));
359 // And the top (top 20 bits). 359 // And the top (top 20 bits).
360 __ orr(exponent, 360 __ orr(exponent,
361 exponent, 361 exponent,
362 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord)); 362 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord));
363 __ Ret(); 363 __ Ret();
364 } 364 }
365 365
366 366
367 class FloatingPointHelper : public AllStatic {
368 public:
369
370 enum Destination {
371 kVFPRegisters,
372 kCoreRegisters
373 };
374
375
376 // Loads smis from r0 and r1 (right and left in binary operations) into
377 // floating point registers. Depending on the destination the values ends up
378 // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is
379 // floating point registers VFP3 must be supported. If core registers are
380 // requested when VFP3 is supported d6 and d7 will be scratched.
381 static void LoadSmis(MacroAssembler* masm,
382 Destination destination,
383 Register scratch1,
384 Register scratch2);
385
386 // Loads objects from r0 and r1 (right and left in binary operations) into
387 // floating point registers. Depending on the destination the values ends up
388 // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is
389 // floating point registers VFP3 must be supported. If core registers are
390 // requested when VFP3 is supported d6 and d7 will still be scratched. If
391 // either r0 or r1 is not a number (not smi and not heap number object) the
392 // not_number label is jumped to with r0 and r1 intact.
393 static void LoadOperands(MacroAssembler* masm,
394 FloatingPointHelper::Destination destination,
395 Register heap_number_map,
396 Register scratch1,
397 Register scratch2,
398 Label* not_number);
399
400 // Convert the smi or heap number in object to an int32 using the rules
401 // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
402 // and brought into the range -2^31 .. +2^31 - 1.
403 static void ConvertNumberToInt32(MacroAssembler* masm,
404 Register object,
405 Register dst,
406 Register heap_number_map,
407 Register scratch1,
408 Register scratch2,
409 Register scratch3,
410 DwVfpRegister double_scratch,
411 Label* not_int32);
412
413 // Load the number from object into double_dst in the double format.
414 // Control will jump to not_int32 if the value cannot be exactly represented
415 // by a 32-bit integer.
416 // Floating point value in the 32-bit integer range that are not exact integer
417 // won't be loaded.
418 static void LoadNumberAsInt32Double(MacroAssembler* masm,
419 Register object,
420 Destination destination,
421 DwVfpRegister double_dst,
422 Register dst1,
423 Register dst2,
424 Register heap_number_map,
425 Register scratch1,
426 Register scratch2,
427 SwVfpRegister single_scratch,
428 Label* not_int32);
429
430 // Loads the number from object into dst as a 32-bit integer.
431 // Control will jump to not_int32 if the object cannot be exactly represented
432 // by a 32-bit integer.
433 // Floating point value in the 32-bit integer range that are not exact integer
434 // won't be converted.
435 // scratch3 is not used when VFP3 is supported.
436 static void LoadNumberAsInt32(MacroAssembler* masm,
437 Register object,
438 Register dst,
439 Register heap_number_map,
440 Register scratch1,
441 Register scratch2,
442 Register scratch3,
443 DwVfpRegister double_scratch,
444 Label* not_int32);
445
446 // Generate non VFP3 code to check if a double can be exactly represented by a
447 // 32-bit integer. This does not check for 0 or -0, which need
448 // to be checked for separately.
449 // Control jumps to not_int32 if the value is not a 32-bit integer, and falls
450 // through otherwise.
451 // src1 and src2 will be cloberred.
452 //
453 // Expected input:
454 // - src1: higher (exponent) part of the double value.
455 // - src2: lower (mantissa) part of the double value.
456 // Output status:
457 // - dst: 32 higher bits of the mantissa. (mantissa[51:20])
458 // - src2: contains 1.
459 // - other registers are clobbered.
460 static void DoubleIs32BitInteger(MacroAssembler* masm,
461 Register src1,
462 Register src2,
463 Register dst,
464 Register scratch,
465 Label* not_int32);
466
467 // Generates code to call a C function to do a double operation using core
468 // registers. (Used when VFP3 is not supported.)
469 // This code never falls through, but returns with a heap number containing
470 // the result in r0.
471 // Register heapnumber_result must be a heap number in which the
472 // result of the operation will be stored.
473 // Requires the following layout on entry:
474 // r0: Left value (least significant part of mantissa).
475 // r1: Left value (sign, exponent, top of mantissa).
476 // r2: Right value (least significant part of mantissa).
477 // r3: Right value (sign, exponent, top of mantissa).
478 static void CallCCodeForDoubleOperation(MacroAssembler* masm,
479 Token::Value op,
480 Register heap_number_result,
481 Register scratch);
482
483 private:
484 static void LoadNumber(MacroAssembler* masm,
485 FloatingPointHelper::Destination destination,
486 Register object,
487 DwVfpRegister dst,
488 Register dst1,
489 Register dst2,
490 Register heap_number_map,
491 Register scratch1,
492 Register scratch2,
493 Label* not_number);
494 };
495
496
497 void FloatingPointHelper::LoadSmis(MacroAssembler* masm, 367 void FloatingPointHelper::LoadSmis(MacroAssembler* masm,
498 FloatingPointHelper::Destination destination, 368 FloatingPointHelper::Destination destination,
499 Register scratch1, 369 Register scratch1,
500 Register scratch2) { 370 Register scratch2) {
501 if (CpuFeatures::IsSupported(VFP3)) { 371 if (CpuFeatures::IsSupported(VFP3)) {
502 CpuFeatures::Scope scope(VFP3); 372 CpuFeatures::Scope scope(VFP3);
503 __ mov(scratch1, Operand(r0, ASR, kSmiTagSize)); 373 __ mov(scratch1, Operand(r0, ASR, kSmiTagSize));
504 __ vmov(d7.high(), scratch1); 374 __ vmov(d7.high(), scratch1);
505 __ vcvt_f64_s32(d7, d7.high()); 375 __ vcvt_f64_s32(d7, d7.high());
506 __ mov(scratch1, Operand(r1, ASR, kSmiTagSize)); 376 __ mov(scratch1, Operand(r1, ASR, kSmiTagSize));
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 scratch2, 514 scratch2,
645 scratch3); 515 scratch3);
646 __ jmp(&done); 516 __ jmp(&done);
647 517
648 __ bind(&is_smi); 518 __ bind(&is_smi);
649 __ SmiUntag(dst, object); 519 __ SmiUntag(dst, object);
650 __ bind(&done); 520 __ bind(&done);
651 } 521 }
652 522
653 523
654 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, 524 void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
655 Register object, 525 Register int_scratch,
656 Destination destination, 526 Destination destination,
657 DwVfpRegister double_dst, 527 DwVfpRegister double_dst,
658 Register dst1, 528 Register dst1,
659 Register dst2, 529 Register dst2,
660 Register heap_number_map, 530 Register scratch2,
661 Register scratch1, 531 SwVfpRegister single_scratch) {
662 Register scratch2, 532 ASSERT(!int_scratch.is(scratch2));
663 SwVfpRegister single_scratch,
664 Label* not_int32) {
665 ASSERT(!scratch1.is(object) && !scratch2.is(object));
666 ASSERT(!scratch1.is(scratch2));
667 ASSERT(!heap_number_map.is(object) &&
668 !heap_number_map.is(scratch1) &&
669 !heap_number_map.is(scratch2));
670 533
671 Label done, obj_is_not_smi; 534 Label done;
672 535
673 __ JumpIfNotSmi(object, &obj_is_not_smi);
674 __ SmiUntag(scratch1, object);
675 if (CpuFeatures::IsSupported(VFP3)) { 536 if (CpuFeatures::IsSupported(VFP3)) {
676 CpuFeatures::Scope scope(VFP3); 537 CpuFeatures::Scope scope(VFP3);
677 __ vmov(single_scratch, scratch1); 538 __ vmov(single_scratch, int_scratch);
678 __ vcvt_f64_s32(double_dst, single_scratch); 539 __ vcvt_f64_s32(double_dst, single_scratch);
679 if (destination == kCoreRegisters) { 540 if (destination == kCoreRegisters) {
680 __ vmov(dst1, dst2, double_dst); 541 __ vmov(dst1, dst2, double_dst);
681 } 542 }
682 } else { 543 } else {
683 Label fewer_than_20_useful_bits; 544 Label fewer_than_20_useful_bits;
684 // Expected output: 545 // Expected output:
685 // | dst2 | dst1 | 546 // | dst2 | dst1 |
686 // | s | exp | mantissa | 547 // | s | exp | mantissa |
687 548
688 // Check for zero. 549 // Check for zero.
689 __ cmp(scratch1, Operand(0)); 550 __ cmp(int_scratch, Operand(0));
690 __ mov(dst2, scratch1); 551 __ mov(dst2, int_scratch);
691 __ mov(dst1, scratch1); 552 __ mov(dst1, int_scratch);
692 __ b(eq, &done); 553 __ b(eq, &done);
693 554
694 // Preload the sign of the value. 555 // Preload the sign of the value.
695 __ and_(dst2, scratch1, Operand(HeapNumber::kSignMask), SetCC); 556 __ and_(dst2, int_scratch, Operand(HeapNumber::kSignMask), SetCC);
696 // Get the absolute value of the object (as an unsigned integer). 557 // Get the absolute value of the object (as an unsigned integer).
697 __ rsb(scratch1, scratch1, Operand(0), SetCC, mi); 558 __ rsb(int_scratch, int_scratch, Operand(0), SetCC, mi);
698 559
699 // Get mantisssa[51:20]. 560 // Get mantisssa[51:20].
700 561
701 // Get the position of the first set bit. 562 // Get the position of the first set bit.
702 __ CountLeadingZeros(dst1, scratch1, scratch2); 563 __ CountLeadingZeros(dst1, int_scratch, scratch2);
703 __ rsb(dst1, dst1, Operand(31)); 564 __ rsb(dst1, dst1, Operand(31));
704 565
705 // Set the exponent. 566 // Set the exponent.
706 __ add(scratch2, dst1, Operand(HeapNumber::kExponentBias)); 567 __ add(scratch2, dst1, Operand(HeapNumber::kExponentBias));
707 __ Bfi(dst2, scratch2, scratch2, 568 __ Bfi(dst2, scratch2, scratch2,
708 HeapNumber::kExponentShift, HeapNumber::kExponentBits); 569 HeapNumber::kExponentShift, HeapNumber::kExponentBits);
709 570
710 // Clear the first non null bit. 571 // Clear the first non null bit.
711 __ mov(scratch2, Operand(1)); 572 __ mov(scratch2, Operand(1));
712 __ bic(scratch1, scratch1, Operand(scratch2, LSL, dst1)); 573 __ bic(int_scratch, int_scratch, Operand(scratch2, LSL, dst1));
713 574
714 __ cmp(dst1, Operand(HeapNumber::kMantissaBitsInTopWord)); 575 __ cmp(dst1, Operand(HeapNumber::kMantissaBitsInTopWord));
715 // Get the number of bits to set in the lower part of the mantissa. 576 // Get the number of bits to set in the lower part of the mantissa.
716 __ sub(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC); 577 __ sub(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC);
717 __ b(mi, &fewer_than_20_useful_bits); 578 __ b(mi, &fewer_than_20_useful_bits);
718 // Set the higher 20 bits of the mantissa. 579 // Set the higher 20 bits of the mantissa.
719 __ orr(dst2, dst2, Operand(scratch1, LSR, scratch2)); 580 __ orr(dst2, dst2, Operand(int_scratch, LSR, scratch2));
720 __ rsb(scratch2, scratch2, Operand(32)); 581 __ rsb(scratch2, scratch2, Operand(32));
721 __ mov(dst1, Operand(scratch1, LSL, scratch2)); 582 __ mov(dst1, Operand(int_scratch, LSL, scratch2));
722 __ b(&done); 583 __ b(&done);
723 584
724 __ bind(&fewer_than_20_useful_bits); 585 __ bind(&fewer_than_20_useful_bits);
725 __ rsb(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord)); 586 __ rsb(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord));
726 __ mov(scratch2, Operand(scratch1, LSL, scratch2)); 587 __ mov(scratch2, Operand(int_scratch, LSL, scratch2));
727 __ orr(dst2, dst2, scratch2); 588 __ orr(dst2, dst2, scratch2);
728 // Set dst1 to 0. 589 // Set dst1 to 0.
729 __ mov(dst1, Operand(0)); 590 __ mov(dst1, Operand(0));
730 } 591 }
592 __ bind(&done);
593 }
731 594
595
596 void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
597 Register object,
598 Destination destination,
599 DwVfpRegister double_dst,
600 Register dst1,
601 Register dst2,
602 Register heap_number_map,
603 Register scratch1,
604 Register scratch2,
605 SwVfpRegister single_scratch,
606 Label* not_int32) {
607 ASSERT(!scratch1.is(object) && !scratch2.is(object));
608 ASSERT(!scratch1.is(scratch2));
609 ASSERT(!heap_number_map.is(object) &&
610 !heap_number_map.is(scratch1) &&
611 !heap_number_map.is(scratch2));
612
613 Label done, obj_is_not_smi;
614
615 __ JumpIfNotSmi(object, &obj_is_not_smi);
616 __ SmiUntag(scratch1, object);
617 ConvertIntToDouble(masm, scratch1, destination, double_dst, dst1, dst2,
618 scratch2, single_scratch);
732 __ b(&done); 619 __ b(&done);
733 620
734 __ bind(&obj_is_not_smi); 621 __ bind(&obj_is_not_smi);
735 if (FLAG_debug_code) { 622 if (FLAG_debug_code) {
736 __ AbortIfNotRootValue(heap_number_map, 623 __ AbortIfNotRootValue(heap_number_map,
737 Heap::kHeapNumberMapRootIndex, 624 Heap::kHeapNumberMapRootIndex,
738 "HeapNumberMap register clobbered."); 625 "HeapNumberMap register clobbered.");
739 } 626 }
740 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 627 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
741 628
(...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after
2433 } 2320 }
2434 2321
2435 // A DIV operation expecting an integer result falls through 2322 // A DIV operation expecting an integer result falls through
2436 // to type transition. 2323 // to type transition.
2437 2324
2438 } else { 2325 } else {
2439 // We preserved r0 and r1 to be able to call runtime. 2326 // We preserved r0 and r1 to be able to call runtime.
2440 // Save the left value on the stack. 2327 // Save the left value on the stack.
2441 __ Push(r5, r4); 2328 __ Push(r5, r4);
2442 2329
2330 Label pop_and_call_runtime;
2331
2443 // Allocate a heap number to store the result. 2332 // Allocate a heap number to store the result.
2444 heap_number_result = r5; 2333 heap_number_result = r5;
2445 GenerateHeapResultAllocation(masm, 2334 GenerateHeapResultAllocation(masm,
2446 heap_number_result, 2335 heap_number_result,
2447 heap_number_map, 2336 heap_number_map,
2448 scratch1, 2337 scratch1,
2449 scratch2, 2338 scratch2,
2450 &call_runtime); 2339 &pop_and_call_runtime);
2451 2340
2452 // Load the left value from the value saved on the stack. 2341 // Load the left value from the value saved on the stack.
2453 __ Pop(r1, r0); 2342 __ Pop(r1, r0);
2454 2343
2455 // Call the C function to handle the double operation. 2344 // Call the C function to handle the double operation.
2456 FloatingPointHelper::CallCCodeForDoubleOperation( 2345 FloatingPointHelper::CallCCodeForDoubleOperation(
2457 masm, op_, heap_number_result, scratch1); 2346 masm, op_, heap_number_result, scratch1);
2458 if (FLAG_debug_code) { 2347 if (FLAG_debug_code) {
2459 __ stop("Unreachable code."); 2348 __ stop("Unreachable code.");
2460 } 2349 }
2350
2351 __ bind(&pop_and_call_runtime);
2352 __ Drop(2);
2353 __ b(&call_runtime);
2461 } 2354 }
2462 2355
2463 break; 2356 break;
2464 } 2357 }
2465 2358
2466 case Token::BIT_OR: 2359 case Token::BIT_OR:
2467 case Token::BIT_XOR: 2360 case Token::BIT_XOR:
2468 case Token::BIT_AND: 2361 case Token::BIT_AND:
2469 case Token::SAR: 2362 case Token::SAR:
2470 case Token::SHR: 2363 case Token::SHR:
(...skipping 3413 matching lines...) Expand 10 before | Expand all | Expand 10 after
5884 __ str(pc, MemOperand(sp, 0)); 5777 __ str(pc, MemOperand(sp, 0));
5885 __ Jump(target); // Call the C++ function. 5778 __ Jump(target); // Call the C++ function.
5886 } 5779 }
5887 5780
5888 5781
5889 #undef __ 5782 #undef __
5890 5783
5891 } } // namespace v8::internal 5784 } } // namespace v8::internal
5892 5785
5893 #endif // V8_TARGET_ARCH_ARM 5786 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698