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

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

Issue 6879009: Support Float64Arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: address comments 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.cc » ('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(!smi_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 5142 matching lines...) Expand 10 before | Expand all | Expand 10 after
5884 __ str(pc, MemOperand(sp, 0)); 5771 __ str(pc, MemOperand(sp, 0));
5885 __ Jump(target); // Call the C++ function. 5772 __ Jump(target); // Call the C++ function.
5886 } 5773 }
5887 5774
5888 5775
5889 #undef __ 5776 #undef __
5890 5777
5891 } } // namespace v8::internal 5778 } } // namespace v8::internal
5892 5779
5893 #endif // V8_TARGET_ARCH_ARM 5780 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/lithium-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698