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

Side by Side Diff: runtime/vm/intrinsifier_x64.cc

Issue 12317011: Inline ByteArray._setIndexed in the flow graph optimizer. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed assert with ICData::New Created 7 years, 10 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 | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/object.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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 RDX); 195 RDX);
196 // Caller is responsible of preserving the value if necessary. 196 // Caller is responsible of preserving the value if necessary.
197 __ ret(); 197 __ ret();
198 __ Bind(&fall_through); 198 __ Bind(&fall_through);
199 return false; 199 return false;
200 } 200 }
201 201
202 202
203 // Allocate a GrowableObjectArray using the backing array specified. 203 // Allocate a GrowableObjectArray using the backing array specified.
204 // On stack: type argument (+2), data (+1), return-address (+0). 204 // On stack: type argument (+2), data (+1), return-address (+0).
205 bool Intrinsifier::GArray_Allocate(Assembler* assembler) { 205 bool Intrinsifier::GrowableArray_Allocate(Assembler* assembler) {
206 // This snippet of inlined code uses the following registers: 206 // This snippet of inlined code uses the following registers:
207 // RAX, RCX, R13 207 // RAX, RCX, R13
208 // and the newly allocated object is returned in RAX. 208 // and the newly allocated object is returned in RAX.
209 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 209 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
210 const intptr_t kArrayOffset = 1 * kWordSize; 210 const intptr_t kArrayOffset = 1 * kWordSize;
211 Label fall_through; 211 Label fall_through;
212 212
213 // Compute the size to be allocated, it is based on the array length 213 // Compute the size to be allocated, it is based on the array length
214 // and is computed as: 214 // and is computed as:
215 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) + 215 // RoundedAllocationSize(sizeof(RawGrowableObjectArray)) +
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 __ movq(R12, Address(RSP, + 1 * kWordSize)); // Index. 433 __ movq(R12, Address(RSP, + 1 * kWordSize)); // Index.
434 __ testq(R12, Immediate(kSmiTagMask)); 434 __ testq(R12, Immediate(kSmiTagMask));
435 __ j(NOT_ZERO, fall_through, Assembler::kNearJump); // Non-smi index. 435 __ j(NOT_ZERO, fall_through, Assembler::kNearJump); // Non-smi index.
436 // Range check. 436 // Range check.
437 __ cmpq(R12, FieldAddress(RAX, ByteArray::length_offset())); 437 __ cmpq(R12, FieldAddress(RAX, ByteArray::length_offset()));
438 // Runtime throws exception. 438 // Runtime throws exception.
439 __ j(ABOVE_EQUAL, fall_through, Assembler::kNearJump); 439 __ j(ABOVE_EQUAL, fall_through, Assembler::kNearJump);
440 } 440 }
441 441
442 442
443 // Tests if index is a valid length (Smi and within valid index range),
444 // jumps to fall_through if it is not.
445 // Returns index in R12, array in RAX.
446 // This should be used only for setIndexed intrinsics.
447 static void TestByteArraySetIndex(Assembler* assembler, Label* fall_through) {
448 __ movq(RAX, Address(RSP, + 3 * kWordSize)); // Array.
449 __ movq(R12, Address(RSP, + 2 * kWordSize)); // Index.
450 __ testq(R12, Immediate(kSmiTagMask));
451 __ j(NOT_ZERO, fall_through, Assembler::kNearJump); // Non-smi index.
452 // Range check.
453 __ cmpq(R12, FieldAddress(RAX, ByteArray::length_offset()));
454 // Runtime throws exception.
455 __ j(ABOVE_EQUAL, fall_through, Assembler::kNearJump);
456 }
457
458
459 bool Intrinsifier::Int8Array_getIndexed(Assembler* assembler) {
460 Label fall_through;
461 TestByteArrayGetIndex(assembler, &fall_through);
462 // R12: index as Smi.
463 // RAX: array.
464 __ SmiUntag(R12);
465 __ movsxb(RAX, FieldAddress(RAX,
466 R12,
467 TIMES_1,
468 Int8Array::data_offset()));
469 __ SmiTag(RAX);
470 __ ret();
471 __ Bind(&fall_through);
472 return false;
473 }
474
475
476 bool Intrinsifier::Int8Array_setIndexed(Assembler* assembler) {
477 Label fall_through;
478 TestByteArraySetIndex(assembler, &fall_through);
479 // R12: index as Smi.
480 // RAX: array.
481 __ SmiUntag(R12);
482 __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Value.
483 __ testq(RDI, Immediate(kSmiTagMask));
484 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
485 __ SmiUntag(RDI);
486 // Check that the value is a byte. Add 128 to the value to bring it into
487 // the range 0..FF.
488 __ addq(RDI, Immediate(128));
489 __ cmpq(RDI, Immediate(0xFF));
490 __ j(ABOVE, &fall_through, Assembler::kNearJump);
491 // Undo addition.
492 __ subq(RDI, Immediate(128));
493 __ movb(FieldAddress(RAX, R12, TIMES_1, Uint8Array::data_offset()), RDI);
494 __ ret();
495 __ Bind(&fall_through);
496 return false;
497 }
498
499
500 #define TYPED_ARRAY_ALLOCATION(type_name, scale_factor) \ 443 #define TYPED_ARRAY_ALLOCATION(type_name, scale_factor) \
501 Label fall_through; \ 444 Label fall_through; \
502 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \ 445 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \
503 __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */ \ 446 __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */ \
504 /* Check that length is a positive Smi. */ \ 447 /* Check that length is a positive Smi. */ \
505 /* RDI: requested array length argument. */ \ 448 /* RDI: requested array length argument. */ \
506 __ testq(RDI, Immediate(kSmiTagSize)); \ 449 __ testq(RDI, Immediate(kSmiTagSize)); \
507 __ j(NOT_ZERO, &fall_through); \ 450 __ j(NOT_ZERO, &fall_through); \
508 __ cmpq(RDI, Immediate(0)); \ 451 __ cmpq(RDI, Immediate(0)); \
509 __ j(LESS, &fall_through); \ 452 __ j(LESS, &fall_through); \
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 __ ret(); \ 530 __ ret(); \
588 __ Bind(&fall_through); \ 531 __ Bind(&fall_through); \
589 532
590 533
591 bool Intrinsifier::Int8Array_new(Assembler* assembler) { 534 bool Intrinsifier::Int8Array_new(Assembler* assembler) {
592 TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1); 535 TYPED_ARRAY_ALLOCATION(Int8Array, TIMES_1);
593 return false; 536 return false;
594 } 537 }
595 538
596 539
597 bool Intrinsifier::Uint8Array_getIndexed(Assembler* assembler) {
598 Label fall_through;
599 TestByteArrayGetIndex(assembler, &fall_through);
600 // R12: index as Smi.
601 // RAX: array.
602 __ SmiUntag(R12);
603 __ movzxb(RAX, FieldAddress(RAX,
604 R12,
605 TIMES_1,
606 Uint8Array::data_offset()));
607 __ SmiTag(RAX);
608 __ ret();
609 __ Bind(&fall_through);
610 return false;
611 }
612
613
614 bool Intrinsifier::Uint8Array_setIndexed(Assembler* assembler) {
615 Label fall_through;
616 TestByteArraySetIndex(assembler, &fall_through);
617 // R12: index as Smi.
618 // RAX: array.
619 __ SmiUntag(R12);
620 __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Value.
621 __ testq(RDI, Immediate(kSmiTagMask));
622 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
623 __ SmiUntag(RDI);
624 // Check that value is a byte.
625 __ cmpq(RDI, Immediate(0xFF));
626 __ j(ABOVE, &fall_through, Assembler::kNearJump);
627 __ movb(FieldAddress(RAX, R12, TIMES_1, Uint8Array::data_offset()), RDI);
628 __ ret();
629 __ Bind(&fall_through);
630 return false;
631 }
632
633
634 bool Intrinsifier::Uint8Array_new(Assembler* assembler) { 540 bool Intrinsifier::Uint8Array_new(Assembler* assembler) {
635 TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1); 541 TYPED_ARRAY_ALLOCATION(Uint8Array, TIMES_1);
636 return false; 542 return false;
637 } 543 }
638 544
639 545
640 bool Intrinsifier::UintClamped8Array_getIndexed(Assembler* assembler) {
641 Label fall_through;
642 TestByteArrayGetIndex(assembler, &fall_through);
643 // R12: index as Smi.
644 // RAX: array.
645 __ SmiUntag(R12);
646 __ movzxb(RAX, FieldAddress(RAX,
647 R12,
648 TIMES_1,
649 Uint8ClampedArray::data_offset()));
650 __ SmiTag(RAX);
651 __ ret();
652 __ Bind(&fall_through);
653 return false;
654 }
655
656
657 bool Intrinsifier::Uint8ClampedArray_setIndexed(Assembler* assembler) {
658 Label fall_through, store_value, load_0xff;
659 TestByteArraySetIndex(assembler, &fall_through);
660 // R12: index as Smi.
661 // RAX: array.
662 __ SmiUntag(R12);
663 __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Value.
664 __ testq(RDI, Immediate(kSmiTagMask));
665 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
666
667 __ SmiUntag(RDI);
668 __ cmpq(RDI, Immediate(0xFF));
669 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
670 __ j(GREATER, &load_0xff, Assembler::kNearJump);
671 __ xorq(RDI, RDI); // Zero.
672 __ jmp(&store_value, Assembler::kNearJump);
673 __ Bind(&load_0xff);
674 __ movq(RDI, Immediate(0xFF));
675
676 __ Bind(&store_value);
677 __ movb(
678 FieldAddress(RAX, R12, TIMES_1, Uint8ClampedArray::data_offset()), RDI);
679 __ ret();
680 __ Bind(&fall_through);
681 return false;
682 }
683
684
685 bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) { 546 bool Intrinsifier::Uint8ClampedArray_new(Assembler* assembler) {
686 TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1); 547 TYPED_ARRAY_ALLOCATION(Uint8ClampedArray, TIMES_1);
687 return false; 548 return false;
688 } 549 }
689 550
690 551
691 bool Intrinsifier::Int16Array_getIndexed(Assembler* assembler) {
692 Label fall_through;
693 TestByteArrayGetIndex(assembler, &fall_through);
694 // R12: index as Smi.
695 // RAX: array.
696 __ movsxw(RAX, FieldAddress(RAX,
697 R12,
698 TIMES_1,
699 Int16Array::data_offset()));
700 __ SmiTag(RAX);
701 __ ret();
702 __ Bind(&fall_through);
703 return false;
704 }
705
706
707 bool Intrinsifier::Int16Array_new(Assembler* assembler) { 552 bool Intrinsifier::Int16Array_new(Assembler* assembler) {
708 TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2); 553 TYPED_ARRAY_ALLOCATION(Int16Array, TIMES_2);
709 return false; 554 return false;
710 } 555 }
711 556
712 557
713 bool Intrinsifier::Uint16Array_getIndexed(Assembler* assembler) {
714 Label fall_through;
715 TestByteArrayGetIndex(assembler, &fall_through);
716 // R12: index as Smi.
717 // RAX: array.
718 __ movzxw(RAX, FieldAddress(RAX,
719 R12,
720 TIMES_1,
721 Uint16Array::data_offset()));
722 __ SmiTag(RAX);
723 __ ret();
724 __ Bind(&fall_through);
725 return false;
726 }
727
728
729 bool Intrinsifier::Uint16Array_setIndexed(Assembler* assembler) {
730 Label fall_through;
731 TestByteArraySetIndex(assembler, &fall_through);
732 // R12: index as Smi.
733 // RAX: array.
734 __ movq(RDI, Address(RSP, + 1 * kWordSize));
735 __ SmiUntag(RDI);
736 // RDI: untagged value.
737 __ testl(RDI, Immediate(kSmiTagMask));
738 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
739 __ movw(FieldAddress(RAX, R12, TIMES_1, Uint16Array::data_offset()), RDI);
740 __ ret();
741 __ Bind(&fall_through);
742 return false;
743 }
744
745
746 bool Intrinsifier::Uint16Array_new(Assembler* assembler) { 558 bool Intrinsifier::Uint16Array_new(Assembler* assembler) {
747 TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2); 559 TYPED_ARRAY_ALLOCATION(Uint16Array, TIMES_2);
748 return false; 560 return false;
749 } 561 }
750 562
751 563
752 bool Intrinsifier::Int32Array_getIndexed(Assembler* assembler) {
753 Label fall_through;
754 TestByteArrayGetIndex(assembler, &fall_through);
755 // R12: index as Smi.
756 // RAX: array.
757 __ movsxl(RAX, FieldAddress(RAX,
758 R12,
759 TIMES_2,
760 Int32Array::data_offset()));
761 __ SmiTag(RAX);
762 __ ret();
763 __ Bind(&fall_through);
764 return false;
765 }
766
767
768 bool Intrinsifier::Int32Array_new(Assembler* assembler) { 564 bool Intrinsifier::Int32Array_new(Assembler* assembler) {
769 TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4); 565 TYPED_ARRAY_ALLOCATION(Int32Array, TIMES_4);
770 return false; 566 return false;
771 } 567 }
772 568
773 569
774 bool Intrinsifier::Uint32Array_getIndexed(Assembler* assembler) {
775 Label fall_through;
776 TestByteArrayGetIndex(assembler, &fall_through);
777 // R12: index as Smi.
778 // RAX: array.
779 __ movl(RAX, FieldAddress(RAX,
780 R12,
781 TIMES_2,
782 Uint32Array::data_offset()));
783 __ SmiTag(RAX);
784 __ ret();
785 __ Bind(&fall_through);
786 return false;
787 }
788
789
790 bool Intrinsifier::Uint32Array_new(Assembler* assembler) { 570 bool Intrinsifier::Uint32Array_new(Assembler* assembler) {
791 TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4); 571 TYPED_ARRAY_ALLOCATION(Uint32Array, TIMES_4);
792 return false; 572 return false;
793 } 573 }
794 574
795 575
796 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) { 576 bool Intrinsifier::Int64Array_getIndexed(Assembler* assembler) {
797 Label fall_through; 577 Label fall_through;
798 TestByteArrayGetIndex(assembler, &fall_through); 578 TestByteArrayGetIndex(assembler, &fall_through);
799 // R12: index as Smi. 579 // R12: index as Smi.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 return false; 623 return false;
844 } 624 }
845 625
846 626
847 bool Intrinsifier::Uint64Array_new(Assembler* assembler) { 627 bool Intrinsifier::Uint64Array_new(Assembler* assembler) {
848 TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8); 628 TYPED_ARRAY_ALLOCATION(Uint64Array, TIMES_8);
849 return false; 629 return false;
850 } 630 }
851 631
852 632
853 bool Intrinsifier::Float32Array_getIndexed(Assembler* assembler) {
854 Label fall_through;
855 TestByteArrayGetIndex(assembler, &fall_through);
856 // R12: index as Smi.
857 // RAX: array.
858 // Load single precision float into XMM7.
859 __ movss(XMM7, FieldAddress(RAX, R12, TIMES_2,
860 Float32Array::data_offset()));
861 // Convert into a double precision float.
862 __ cvtss2sd(XMM7, XMM7);
863 // Allocate a double instance.
864 const Class& double_class = Class::Handle(
865 Isolate::Current()->object_store()->double_class());
866 AssemblerMacros::TryAllocate(assembler,
867 double_class,
868 &fall_through,
869 Assembler::kNearJump, RAX);
870 // Store XMM7 into double instance.
871 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM7);
872 __ ret();
873 __ Bind(&fall_through);
874 return false;
875 }
876
877
878 bool Intrinsifier::Float32Array_setIndexed(Assembler* assembler) {
879 Label fall_through;
880 TestByteArraySetIndex(assembler, &fall_through);
881 // R12: index as Smi.
882 // RAX: array.
883 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
884 // If RDX is not an instance of double, jump to fall through.
885 __ testq(RDX, Immediate(kSmiTagMask));
886 __ j(ZERO, &fall_through, Assembler::kNearJump);
887 __ CompareClassId(RDX, kDoubleCid);
888 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
889 // Load double value into XMM7.
890 __ movsd(XMM7, FieldAddress(RDX, Double::value_offset()));
891 // Convert from double precision float to single precision float.
892 __ cvtsd2ss(XMM7, XMM7);
893 // Store into array.
894 __ movss(FieldAddress(RAX, R12, TIMES_2, Float32Array::data_offset()), XMM7);
895 // End fast path.
896 __ ret();
897 __ Bind(&fall_through);
898 return false;
899 }
900
901
902 bool Intrinsifier::Float32Array_new(Assembler* assembler) { 633 bool Intrinsifier::Float32Array_new(Assembler* assembler) {
903 TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4); 634 TYPED_ARRAY_ALLOCATION(Float32Array, TIMES_4);
904 return false; 635 return false;
905 } 636 }
906 637
907 638
908 bool Intrinsifier::Float64Array_getIndexed(Assembler* assembler) {
909 Label fall_through;
910 TestByteArrayGetIndex(assembler, &fall_through);
911 // R12: index as Smi.
912 // RAX: array.
913 // Load double precision float into XMM7.
914 __ movsd(XMM7, FieldAddress(RAX, R12, TIMES_4,
915 Float64Array::data_offset()));
916 // Allocate a double instance.
917 const Class& double_class = Class::Handle(
918 Isolate::Current()->object_store()->double_class());
919 AssemblerMacros::TryAllocate(assembler,
920 double_class,
921 &fall_through,
922 Assembler::kNearJump, RAX);
923 // Store XMM7 into double instance.
924 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM7);
925 __ ret();
926 __ Bind(&fall_through);
927 return false;
928 }
929
930
931 bool Intrinsifier::Float64Array_setIndexed(Assembler* assembler) {
932 Label fall_through;
933 TestByteArraySetIndex(assembler, &fall_through);
934 // R12: index as Smi.
935 // RAX: array.
936 __ movq(RDX, Address(RSP, + 1 * kWordSize)); // Value.
937 // If RDX is not an instance of double, jump to fall through.
938 __ testq(RDX, Immediate(kSmiTagMask));
939 __ j(ZERO, &fall_through, Assembler::kNearJump);
940 __ CompareClassId(RDX, kDoubleCid);
941 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
942 // Load double value into XMM7.
943 __ movsd(XMM7, FieldAddress(RDX, Double::value_offset()));
944 // Store into array.
945 __ movsd(FieldAddress(RAX, R12, TIMES_4, Float64Array::data_offset()), XMM7);
946 __ ret();
947 __ Bind(&fall_through);
948 return false;
949 }
950
951
952 bool Intrinsifier::Float64Array_new(Assembler* assembler) { 639 bool Intrinsifier::Float64Array_new(Assembler* assembler) {
953 TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8); 640 TYPED_ARRAY_ALLOCATION(Float64Array, TIMES_8);
954 return false; 641 return false;
955 } 642 }
956 643
957 644
958 bool Intrinsifier::ExternalUint8Array_getIndexed(Assembler* assembler) {
959 Label fall_through;
960 TestByteArrayGetIndex(assembler, &fall_through);
961 // R12: index as Smi.
962 // RAX: array.
963 __ SmiUntag(R12);
964 __ movq(RAX, FieldAddress(RAX, ExternalUint8Array::data_offset()));
965 __ movzxb(RAX, Address(RAX, R12, TIMES_1, 0));
966 __ SmiTag(RAX);
967 __ ret();
968 __ Bind(&fall_through);
969 return false;
970 }
971
972
973 bool Intrinsifier::ExternalUint8ClampedArray_getIndexed(Assembler* assembler) {
974 Label fall_through;
975 TestByteArrayGetIndex(assembler, &fall_through);
976 // R12: index as Smi.
977 // RAX: array.
978 __ SmiUntag(R12);
979 __ movq(RAX, FieldAddress(RAX, ExternalUint8ClampedArray::data_offset()));
980 __ movzxb(RAX, Address(RAX, R12, TIMES_1, 0));
981 __ SmiTag(RAX);
982 __ ret();
983 __ Bind(&fall_through);
984 return false;
985 }
986
987
988 bool Intrinsifier::ExternalUint8ClampedArray_setIndexed(Assembler* assembler) {
989 Label fall_through, store_value, load_0xff;
990 TestByteArraySetIndex(assembler, &fall_through);
991 // R12: index as Smi.
992 // RAX: array.
993 __ SmiUntag(R12);
994 __ movq(RDI, Address(RSP, + 1 * kWordSize)); // Value.
995 __ testq(RDI, Immediate(kSmiTagMask));
996 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
997
998 __ SmiUntag(RDI);
999 __ cmpq(RDI, Immediate(0xFF));
1000 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump);
1001 __ j(GREATER, &load_0xff, Assembler::kNearJump);
1002 __ xorq(RDI, RDI); // Zero.
1003 __ jmp(&store_value, Assembler::kNearJump);
1004 __ Bind(&load_0xff);
1005 __ movq(RDI, Immediate(0xFF));
1006
1007 __ Bind(&store_value);
1008 __ movq(RAX, FieldAddress(RAX, ExternalUint8ClampedArray::data_offset()));
1009 __ movb(Address(RAX, R12, TIMES_1, 0), RDI);
1010 __ ret();
1011 __ Bind(&fall_through);
1012 return false;
1013 }
1014
1015
1016 // Tests if two top most arguments are smis, jumps to label not_smi if not. 645 // Tests if two top most arguments are smis, jumps to label not_smi if not.
1017 // Topmost argument is in RAX. 646 // Topmost argument is in RAX.
1018 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) { 647 static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
1019 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 648 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1020 __ movq(RCX, Address(RSP, + 2 * kWordSize)); 649 __ movq(RCX, Address(RSP, + 2 * kWordSize));
1021 __ orq(RCX, RAX); 650 __ orq(RCX, RAX);
1022 __ testq(RCX, Immediate(kSmiTagMask)); 651 __ testq(RCX, Immediate(kSmiTagMask));
1023 __ j(NOT_ZERO, not_smi, Assembler::kNearJump); 652 __ j(NOT_ZERO, not_smi, Assembler::kNearJump);
1024 } 653 }
1025 654
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 __ LoadObject(RAX, Bool::True()); 1392 __ LoadObject(RAX, Bool::True());
1764 __ ret(); 1393 __ ret();
1765 return true; 1394 return true;
1766 } 1395 }
1767 1396
1768 #undef __ 1397 #undef __
1769 1398
1770 } // namespace dart 1399 } // namespace dart
1771 1400
1772 #endif // defined TARGET_ARCH_X64 1401 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_mips.cc ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698