OLD | NEW |
1 // Copyright 2010 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 20 matching lines...) Expand all Loading... |
32 #include "arm/simulator-arm.h" | 32 #include "arm/simulator-arm.h" |
33 #include "arm/assembler-arm-inl.h" | 33 #include "arm/assembler-arm-inl.h" |
34 #include "cctest.h" | 34 #include "cctest.h" |
35 | 35 |
36 using namespace v8::internal; | 36 using namespace v8::internal; |
37 | 37 |
38 | 38 |
39 // Define these function prototypes to match JSEntryFunction in execution.cc. | 39 // Define these function prototypes to match JSEntryFunction in execution.cc. |
40 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); | 40 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); |
41 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); | 41 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); |
42 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); | 42 typedef Object* (*F3)(void* p0, int p1, int p2, int p3, int p4); |
| 43 typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4); |
43 | 44 |
44 | 45 |
45 static v8::Persistent<v8::Context> env; | 46 static v8::Persistent<v8::Context> env; |
46 | 47 |
47 | 48 |
48 static void InitializeVM() { | 49 static void InitializeVM() { |
49 if (env.IsEmpty()) { | 50 if (env.IsEmpty()) { |
50 env = v8::Context::New(); | 51 env = v8::Context::New(); |
51 } | 52 } |
52 } | 53 } |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 TestRoundingMode(u32_f64, RN, 123456.2, 123456); | 602 TestRoundingMode(u32_f64, RN, 123456.2, 123456); |
602 TestRoundingMode(u32_f64, RN, static_cast<double>(kMaxInt), kMaxInt); | 603 TestRoundingMode(u32_f64, RN, static_cast<double>(kMaxInt), kMaxInt); |
603 TestRoundingMode(u32_f64, RN, (kMaxInt + 0.49), kMaxInt); | 604 TestRoundingMode(u32_f64, RN, (kMaxInt + 0.49), kMaxInt); |
604 TestRoundingMode(u32_f64, RN, (kMaxInt + 0.5), | 605 TestRoundingMode(u32_f64, RN, (kMaxInt + 0.5), |
605 static_cast<uint32_t>(kMaxInt) + 1); | 606 static_cast<uint32_t>(kMaxInt) + 1); |
606 TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.49), kMaxUInt); | 607 TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.49), kMaxUInt); |
607 TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.5), kMaxUInt, true); | 608 TestRoundingMode(u32_f64, RN, (kMaxUInt + 0.5), kMaxUInt, true); |
608 TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true); | 609 TestRoundingMode(u32_f64, RN, (kMaxUInt + 1.0), kMaxUInt, true); |
609 } | 610 } |
610 | 611 |
| 612 TEST(8) { |
| 613 // Test VFP multi load/store with ia_w. |
| 614 InitializeVM(); |
| 615 v8::HandleScope scope; |
| 616 |
| 617 typedef struct { |
| 618 double a; |
| 619 double b; |
| 620 double c; |
| 621 double d; |
| 622 double e; |
| 623 double f; |
| 624 double g; |
| 625 double h; |
| 626 } D; |
| 627 D d; |
| 628 |
| 629 typedef struct { |
| 630 float a; |
| 631 float b; |
| 632 float c; |
| 633 float d; |
| 634 float e; |
| 635 float f; |
| 636 float g; |
| 637 float h; |
| 638 } F; |
| 639 F f; |
| 640 |
| 641 // Create a function that uses vldm/vstm to move some double and |
| 642 // single precision values around in memory. |
| 643 Assembler assm(Isolate::Current(), NULL, 0); |
| 644 |
| 645 if (CpuFeatures::IsSupported(VFP3)) { |
| 646 CpuFeatures::Scope scope(VFP3); |
| 647 |
| 648 __ mov(ip, Operand(sp)); |
| 649 __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); |
| 650 __ sub(fp, ip, Operand(4)); |
| 651 |
| 652 __ add(r4, r0, Operand(OFFSET_OF(D, a))); |
| 653 __ vldm(ia_w, r4, d0, d3); |
| 654 __ vldm(ia_w, r4, d4, d7); |
| 655 |
| 656 __ add(r4, r0, Operand(OFFSET_OF(D, a))); |
| 657 __ vstm(ia_w, r4, d6, d7); |
| 658 __ vstm(ia_w, r4, d0, d5); |
| 659 |
| 660 __ add(r4, r1, Operand(OFFSET_OF(F, a))); |
| 661 __ vldm(ia_w, r4, s0, s3); |
| 662 __ vldm(ia_w, r4, s4, s7); |
| 663 |
| 664 __ add(r4, r1, Operand(OFFSET_OF(F, a))); |
| 665 __ vstm(ia_w, r4, s6, s7); |
| 666 __ vstm(ia_w, r4, s0, s5); |
| 667 |
| 668 __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); |
| 669 |
| 670 CodeDesc desc; |
| 671 assm.GetCode(&desc); |
| 672 Object* code = HEAP->CreateCode( |
| 673 desc, |
| 674 Code::ComputeFlags(Code::STUB), |
| 675 Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); |
| 676 CHECK(code->IsCode()); |
| 677 #ifdef DEBUG |
| 678 Code::cast(code)->Print(); |
| 679 #endif |
| 680 F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry()); |
| 681 d.a = 1.1; |
| 682 d.b = 2.2; |
| 683 d.c = 3.3; |
| 684 d.d = 4.4; |
| 685 d.e = 5.5; |
| 686 d.f = 6.6; |
| 687 d.g = 7.7; |
| 688 d.h = 8.8; |
| 689 |
| 690 f.a = 1.0; |
| 691 f.b = 2.0; |
| 692 f.c = 3.0; |
| 693 f.d = 4.0; |
| 694 f.e = 5.0; |
| 695 f.f = 6.0; |
| 696 f.g = 7.0; |
| 697 f.h = 8.0; |
| 698 |
| 699 Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); |
| 700 USE(dummy); |
| 701 |
| 702 CHECK_EQ(7.7, d.a); |
| 703 CHECK_EQ(8.8, d.b); |
| 704 CHECK_EQ(1.1, d.c); |
| 705 CHECK_EQ(2.2, d.d); |
| 706 CHECK_EQ(3.3, d.e); |
| 707 CHECK_EQ(4.4, d.f); |
| 708 CHECK_EQ(5.5, d.g); |
| 709 CHECK_EQ(6.6, d.h); |
| 710 |
| 711 CHECK_EQ(7.0, f.a); |
| 712 CHECK_EQ(8.0, f.b); |
| 713 CHECK_EQ(1.0, f.c); |
| 714 CHECK_EQ(2.0, f.d); |
| 715 CHECK_EQ(3.0, f.e); |
| 716 CHECK_EQ(4.0, f.f); |
| 717 CHECK_EQ(5.0, f.g); |
| 718 CHECK_EQ(6.0, f.h); |
| 719 } |
| 720 } |
| 721 |
| 722 |
| 723 TEST(9) { |
| 724 // Test VFP multi load/store with ia. |
| 725 InitializeVM(); |
| 726 v8::HandleScope scope; |
| 727 |
| 728 typedef struct { |
| 729 double a; |
| 730 double b; |
| 731 double c; |
| 732 double d; |
| 733 double e; |
| 734 double f; |
| 735 double g; |
| 736 double h; |
| 737 } D; |
| 738 D d; |
| 739 |
| 740 typedef struct { |
| 741 float a; |
| 742 float b; |
| 743 float c; |
| 744 float d; |
| 745 float e; |
| 746 float f; |
| 747 float g; |
| 748 float h; |
| 749 } F; |
| 750 F f; |
| 751 |
| 752 // Create a function that uses vldm/vstm to move some double and |
| 753 // single precision values around in memory. |
| 754 Assembler assm(Isolate::Current(), NULL, 0); |
| 755 |
| 756 if (CpuFeatures::IsSupported(VFP3)) { |
| 757 CpuFeatures::Scope scope(VFP3); |
| 758 |
| 759 __ mov(ip, Operand(sp)); |
| 760 __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); |
| 761 __ sub(fp, ip, Operand(4)); |
| 762 |
| 763 __ add(r4, r0, Operand(OFFSET_OF(D, a))); |
| 764 __ vldm(ia, r4, d0, d3); |
| 765 __ add(r4, r4, Operand(4 * 8)); |
| 766 __ vldm(ia, r4, d4, d7); |
| 767 |
| 768 __ add(r4, r0, Operand(OFFSET_OF(D, a))); |
| 769 __ vstm(ia, r4, d6, d7); |
| 770 __ add(r4, r4, Operand(2 * 8)); |
| 771 __ vstm(ia, r4, d0, d5); |
| 772 |
| 773 __ add(r4, r1, Operand(OFFSET_OF(F, a))); |
| 774 __ vldm(ia, r4, s0, s3); |
| 775 __ add(r4, r4, Operand(4 * 4)); |
| 776 __ vldm(ia, r4, s4, s7); |
| 777 |
| 778 __ add(r4, r1, Operand(OFFSET_OF(F, a))); |
| 779 __ vstm(ia, r4, s6, s7); |
| 780 __ add(r4, r4, Operand(2 * 4)); |
| 781 __ vstm(ia, r4, s0, s5); |
| 782 |
| 783 __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); |
| 784 |
| 785 CodeDesc desc; |
| 786 assm.GetCode(&desc); |
| 787 Object* code = HEAP->CreateCode( |
| 788 desc, |
| 789 Code::ComputeFlags(Code::STUB), |
| 790 Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); |
| 791 CHECK(code->IsCode()); |
| 792 #ifdef DEBUG |
| 793 Code::cast(code)->Print(); |
| 794 #endif |
| 795 F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry()); |
| 796 d.a = 1.1; |
| 797 d.b = 2.2; |
| 798 d.c = 3.3; |
| 799 d.d = 4.4; |
| 800 d.e = 5.5; |
| 801 d.f = 6.6; |
| 802 d.g = 7.7; |
| 803 d.h = 8.8; |
| 804 |
| 805 f.a = 1.0; |
| 806 f.b = 2.0; |
| 807 f.c = 3.0; |
| 808 f.d = 4.0; |
| 809 f.e = 5.0; |
| 810 f.f = 6.0; |
| 811 f.g = 7.0; |
| 812 f.h = 8.0; |
| 813 |
| 814 Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); |
| 815 USE(dummy); |
| 816 |
| 817 CHECK_EQ(7.7, d.a); |
| 818 CHECK_EQ(8.8, d.b); |
| 819 CHECK_EQ(1.1, d.c); |
| 820 CHECK_EQ(2.2, d.d); |
| 821 CHECK_EQ(3.3, d.e); |
| 822 CHECK_EQ(4.4, d.f); |
| 823 CHECK_EQ(5.5, d.g); |
| 824 CHECK_EQ(6.6, d.h); |
| 825 |
| 826 CHECK_EQ(7.0, f.a); |
| 827 CHECK_EQ(8.0, f.b); |
| 828 CHECK_EQ(1.0, f.c); |
| 829 CHECK_EQ(2.0, f.d); |
| 830 CHECK_EQ(3.0, f.e); |
| 831 CHECK_EQ(4.0, f.f); |
| 832 CHECK_EQ(5.0, f.g); |
| 833 CHECK_EQ(6.0, f.h); |
| 834 } |
| 835 } |
| 836 |
| 837 |
| 838 TEST(10) { |
| 839 // Test VFP multi load/store with db_w. |
| 840 InitializeVM(); |
| 841 v8::HandleScope scope; |
| 842 |
| 843 typedef struct { |
| 844 double a; |
| 845 double b; |
| 846 double c; |
| 847 double d; |
| 848 double e; |
| 849 double f; |
| 850 double g; |
| 851 double h; |
| 852 } D; |
| 853 D d; |
| 854 |
| 855 typedef struct { |
| 856 float a; |
| 857 float b; |
| 858 float c; |
| 859 float d; |
| 860 float e; |
| 861 float f; |
| 862 float g; |
| 863 float h; |
| 864 } F; |
| 865 F f; |
| 866 |
| 867 // Create a function that uses vldm/vstm to move some double and |
| 868 // single precision values around in memory. |
| 869 Assembler assm(Isolate::Current(), NULL, 0); |
| 870 |
| 871 if (CpuFeatures::IsSupported(VFP3)) { |
| 872 CpuFeatures::Scope scope(VFP3); |
| 873 |
| 874 __ mov(ip, Operand(sp)); |
| 875 __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); |
| 876 __ sub(fp, ip, Operand(4)); |
| 877 |
| 878 __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8)); |
| 879 __ vldm(db_w, r4, d4, d7); |
| 880 __ vldm(db_w, r4, d0, d3); |
| 881 |
| 882 __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8)); |
| 883 __ vstm(db_w, r4, d0, d5); |
| 884 __ vstm(db_w, r4, d6, d7); |
| 885 |
| 886 __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4)); |
| 887 __ vldm(db_w, r4, s4, s7); |
| 888 __ vldm(db_w, r4, s0, s3); |
| 889 |
| 890 __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4)); |
| 891 __ vstm(db_w, r4, s0, s5); |
| 892 __ vstm(db_w, r4, s6, s7); |
| 893 |
| 894 __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); |
| 895 |
| 896 CodeDesc desc; |
| 897 assm.GetCode(&desc); |
| 898 Object* code = HEAP->CreateCode( |
| 899 desc, |
| 900 Code::ComputeFlags(Code::STUB), |
| 901 Handle<Object>(HEAP->undefined_value()))->ToObjectChecked(); |
| 902 CHECK(code->IsCode()); |
| 903 #ifdef DEBUG |
| 904 Code::cast(code)->Print(); |
| 905 #endif |
| 906 F4 fn = FUNCTION_CAST<F4>(Code::cast(code)->entry()); |
| 907 d.a = 1.1; |
| 908 d.b = 2.2; |
| 909 d.c = 3.3; |
| 910 d.d = 4.4; |
| 911 d.e = 5.5; |
| 912 d.f = 6.6; |
| 913 d.g = 7.7; |
| 914 d.h = 8.8; |
| 915 |
| 916 f.a = 1.0; |
| 917 f.b = 2.0; |
| 918 f.c = 3.0; |
| 919 f.d = 4.0; |
| 920 f.e = 5.0; |
| 921 f.f = 6.0; |
| 922 f.g = 7.0; |
| 923 f.h = 8.0; |
| 924 |
| 925 Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); |
| 926 USE(dummy); |
| 927 |
| 928 CHECK_EQ(7.7, d.a); |
| 929 CHECK_EQ(8.8, d.b); |
| 930 CHECK_EQ(1.1, d.c); |
| 931 CHECK_EQ(2.2, d.d); |
| 932 CHECK_EQ(3.3, d.e); |
| 933 CHECK_EQ(4.4, d.f); |
| 934 CHECK_EQ(5.5, d.g); |
| 935 CHECK_EQ(6.6, d.h); |
| 936 |
| 937 CHECK_EQ(7.0, f.a); |
| 938 CHECK_EQ(8.0, f.b); |
| 939 CHECK_EQ(1.0, f.c); |
| 940 CHECK_EQ(2.0, f.d); |
| 941 CHECK_EQ(3.0, f.e); |
| 942 CHECK_EQ(4.0, f.f); |
| 943 CHECK_EQ(5.0, f.g); |
| 944 CHECK_EQ(6.0, f.h); |
| 945 } |
| 946 } |
| 947 |
611 #undef __ | 948 #undef __ |
OLD | NEW |