| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/os.h" | 9 #include "vm/os.h" |
| 10 #include "vm/unit_test.h" | 10 #include "vm/unit_test.h" |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 int64_t b = 14; | 707 int64_t b = 14; |
| 708 int64_t res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); | 708 int64_t res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
| 709 EXPECT_EQ((a + b), res); | 709 EXPECT_EQ((a + b), res); |
| 710 a = 2147483647; | 710 a = 2147483647; |
| 711 b = 600000; | 711 b = 600000; |
| 712 res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); | 712 res = reinterpret_cast<LongAddRegCode>(test->entry())(a, b); |
| 713 EXPECT_EQ((a + b), res); | 713 EXPECT_EQ((a + b), res); |
| 714 } | 714 } |
| 715 | 715 |
| 716 | 716 |
| 717 ASSEMBLER_TEST_GENERATE(LongAddImmediate, assembler) { |
| 718 __ pushq(CallingConventions::kArg1Reg); |
| 719 __ movl(RAX, Address(RSP, 0)); // left low. |
| 720 __ movl(RDX, Address(RSP, 4)); // left high. |
| 721 __ addl(RAX, Immediate(12)); // right low immediate. |
| 722 __ adcl(RDX, Immediate(11)); // right high immediate. |
| 723 // Result is in RAX/RDX. |
| 724 __ movl(Address(RSP, 0), RAX); // result low. |
| 725 __ movl(Address(RSP, 4), RDX); // result high. |
| 726 __ popq(RAX); |
| 727 __ ret(); |
| 728 } |
| 729 |
| 730 |
| 731 ASSEMBLER_TEST_RUN(LongAddImmediate, test) { |
| 732 typedef int64_t (*LongAddImmediateCode)(int64_t a); |
| 733 int64_t a = (13LL << 32) + 14; |
| 734 int64_t b = (11LL << 32) + 12; |
| 735 int64_t res = reinterpret_cast<LongAddImmediateCode>(test->entry())(a); |
| 736 EXPECT_EQ((a + b), res); |
| 737 a = (13LL << 32) - 1; |
| 738 res = reinterpret_cast<LongAddImmediateCode>(test->entry())(a); |
| 739 EXPECT_EQ((a + b), res); |
| 740 } |
| 741 |
| 742 |
| 717 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { | 743 ASSEMBLER_TEST_GENERATE(LongAddAddress, assembler) { |
| 718 __ pushq(CallingConventions::kArg2Reg); | 744 __ pushq(CallingConventions::kArg2Reg); |
| 719 __ pushq(CallingConventions::kArg1Reg); | 745 __ pushq(CallingConventions::kArg1Reg); |
| 720 __ movl(RAX, Address(RSP, 0)); // left low. | 746 __ movl(RAX, Address(RSP, 0)); // left low. |
| 721 __ movl(RDX, Address(RSP, 4)); // left high. | 747 __ movl(RDX, Address(RSP, 4)); // left high. |
| 722 __ addl(RAX, Address(RSP, 8)); // low. | 748 __ addl(RAX, Address(RSP, 8)); // low. |
| 723 __ adcl(RDX, Address(RSP, 12)); // high. | 749 __ adcl(RDX, Address(RSP, 12)); // high. |
| 724 // Result is in RAX/RDX. | 750 // Result is in RAX/RDX. |
| 725 __ movl(Address(RSP, 0), RAX); // result low. | 751 __ movl(Address(RSP, 0), RAX); // result low. |
| 726 __ movl(Address(RSP, 4), RDX); // result high. | 752 __ movl(Address(RSP, 4), RDX); // result high. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 int64_t b = 14; | 793 int64_t b = 14; |
| 768 int64_t res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); | 794 int64_t res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
| 769 EXPECT_EQ((a - b), res); | 795 EXPECT_EQ((a - b), res); |
| 770 a = 600000; | 796 a = 600000; |
| 771 b = 2147483647; | 797 b = 2147483647; |
| 772 res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); | 798 res = reinterpret_cast<LongSubRegCode>(test->entry())(a, b); |
| 773 EXPECT_EQ((a - b), res); | 799 EXPECT_EQ((a - b), res); |
| 774 } | 800 } |
| 775 | 801 |
| 776 | 802 |
| 803 ASSEMBLER_TEST_GENERATE(LongSubImmediate, assembler) { |
| 804 __ pushq(CallingConventions::kArg1Reg); |
| 805 __ movl(RAX, Address(RSP, 0)); // left low. |
| 806 __ movl(RDX, Address(RSP, 4)); // left high. |
| 807 __ subl(RAX, Immediate(12)); // right low immediate. |
| 808 __ sbbl(RDX, Immediate(11)); // right high immediate. |
| 809 // Result is in RAX/RDX. |
| 810 __ movl(Address(RSP, 0), RAX); // result low. |
| 811 __ movl(Address(RSP, 4), RDX); // result high. |
| 812 __ popq(RAX); |
| 813 __ ret(); |
| 814 } |
| 815 |
| 816 |
| 817 ASSEMBLER_TEST_RUN(LongSubImmediate, test) { |
| 818 typedef int64_t (*LongSubImmediateCode)(int64_t a); |
| 819 int64_t a = (13LL << 32) + 14; |
| 820 int64_t b = (11LL << 32) + 12; |
| 821 int64_t res = reinterpret_cast<LongSubImmediateCode>(test->entry())(a); |
| 822 EXPECT_EQ((a - b), res); |
| 823 a = (13LL << 32) + 10; |
| 824 res = reinterpret_cast<LongSubImmediateCode>(test->entry())(a); |
| 825 EXPECT_EQ((a - b), res); |
| 826 } |
| 827 |
| 828 |
| 777 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { | 829 ASSEMBLER_TEST_GENERATE(LongSubAddress, assembler) { |
| 778 __ pushq(CallingConventions::kArg2Reg); | 830 __ pushq(CallingConventions::kArg2Reg); |
| 779 __ pushq(CallingConventions::kArg1Reg); | 831 __ pushq(CallingConventions::kArg1Reg); |
| 780 __ movl(RAX, Address(RSP, 0)); // left low. | 832 __ movl(RAX, Address(RSP, 0)); // left low. |
| 781 __ movl(RDX, Address(RSP, 4)); // left high. | 833 __ movl(RDX, Address(RSP, 4)); // left high. |
| 782 __ subl(RAX, Address(RSP, 8)); // low. | 834 __ subl(RAX, Address(RSP, 8)); // low. |
| 783 __ sbbl(RDX, Address(RSP, 12)); // high. | 835 __ sbbl(RDX, Address(RSP, 12)); // high. |
| 784 // Result is in RAX/RDX. | 836 // Result is in RAX/RDX. |
| 785 __ movl(Address(RSP, 0), RAX); // result low. | 837 __ movl(Address(RSP, 0), RAX); // result low. |
| 786 __ movl(Address(RSP, 4), RDX); // result high. | 838 __ movl(Address(RSP, 4), RDX); // result high. |
| 787 __ popq(RAX); | 839 __ popq(RAX); |
| 788 __ popq(RDX); | 840 __ popq(RDX); |
| 789 __ ret(); | 841 __ ret(); |
| 790 } | 842 } |
| 791 | 843 |
| 792 | 844 |
| 793 ASSEMBLER_TEST_RUN(LongSubAddress, test) { | 845 ASSEMBLER_TEST_RUN(LongSubAddress, test) { |
| 794 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); | 846 typedef int64_t (*LongSubAddressCode)(int64_t a, int64_t b); |
| 795 int64_t a = 12; | 847 int64_t a = 12; |
| 796 int64_t b = 14; | 848 int64_t b = 14; |
| 797 int64_t res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); | 849 int64_t res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
| 798 EXPECT_EQ((a - b), res); | 850 EXPECT_EQ((a - b), res); |
| 799 a = 600000; | 851 a = 600000; |
| 800 b = 2147483647; | 852 b = 2147483647; |
| 801 res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); | 853 res = reinterpret_cast<LongSubAddressCode>(test->entry())(a, b); |
| 802 EXPECT_EQ((a - b), res); | 854 EXPECT_EQ((a - b), res); |
| 803 } | 855 } |
| 804 | 856 |
| 805 | 857 |
| 858 ASSEMBLER_TEST_GENERATE(AddReg, assembler) { |
| 859 __ movq(R10, CallingConventions::kArg1Reg); // al. |
| 860 __ addq(R10, CallingConventions::kArg3Reg); // bl. |
| 861 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
| 862 __ adcq(RAX, CallingConventions::kArg4Reg); // bh. |
| 863 // RAX = high64(ah:al + bh:bl). |
| 864 __ ret(); |
| 865 } |
| 866 |
| 867 |
| 868 ASSEMBLER_TEST_RUN(AddReg, test) { |
| 869 typedef int64_t (*AddRegCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
| 870 int64_t al = 11; |
| 871 int64_t ah = 12; |
| 872 int64_t bl = 13; |
| 873 int64_t bh = 14; |
| 874 int64_t res = reinterpret_cast<AddRegCode>(test->entry())(al, ah, bl, bh); |
| 875 EXPECT_EQ((ah + bh), res); |
| 876 al = -1; |
| 877 res = reinterpret_cast<AddRegCode>(test->entry())(al, ah, bl, bh); |
| 878 EXPECT_EQ((ah + bh + 1), res); |
| 879 } |
| 880 |
| 881 |
| 882 ASSEMBLER_TEST_GENERATE(AddImmediate, assembler) { |
| 883 __ movq(R10, CallingConventions::kArg1Reg); // al. |
| 884 __ addq(R10, Immediate(13)); // bl. |
| 885 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
| 886 __ adcq(RAX, Immediate(14)); // bh. |
| 887 // RAX = high64(ah:al + bh:bl). |
| 888 __ ret(); |
| 889 } |
| 890 |
| 891 |
| 892 ASSEMBLER_TEST_RUN(AddImmediate, test) { |
| 893 typedef int64_t (*AddImmediateCode)(int64_t al, int64_t ah); |
| 894 int64_t al = 11; |
| 895 int64_t ah = 12; |
| 896 int64_t bh = 14; |
| 897 int64_t res = reinterpret_cast<AddImmediateCode>(test->entry())(al, ah); |
| 898 EXPECT_EQ((ah + bh), res); |
| 899 al = -1; |
| 900 res = reinterpret_cast<AddImmediateCode>(test->entry())(al, ah); |
| 901 EXPECT_EQ((ah + bh + 1), res); |
| 902 } |
| 903 |
| 904 |
| 905 ASSEMBLER_TEST_GENERATE(AddAddress, assembler) { |
| 906 __ pushq(CallingConventions::kArg4Reg); |
| 907 __ pushq(CallingConventions::kArg3Reg); |
| 908 __ pushq(CallingConventions::kArg2Reg); |
| 909 __ pushq(CallingConventions::kArg1Reg); |
| 910 __ movq(R10, Address(RSP, 0 * kWordSize)); // al. |
| 911 __ addq(R10, Address(RSP, 2 * kWordSize)); // bl. |
| 912 __ movq(RAX, Address(RSP, 1 * kWordSize)); // ah. |
| 913 __ adcq(RAX, Address(RSP, 3 * kWordSize)); // bh. |
| 914 // RAX = high64(ah:al + bh:bl). |
| 915 __ Drop(4); |
| 916 __ ret(); |
| 917 } |
| 918 |
| 919 |
| 920 ASSEMBLER_TEST_RUN(AddAddress, test) { |
| 921 typedef int64_t (*AddCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
| 922 int64_t al = 11; |
| 923 int64_t ah = 12; |
| 924 int64_t bl = 13; |
| 925 int64_t bh = 14; |
| 926 int64_t res = reinterpret_cast<AddCode>(test->entry())(al, ah, bl, bh); |
| 927 EXPECT_EQ((ah + bh), res); |
| 928 al = -1; |
| 929 res = reinterpret_cast<AddCode>(test->entry())(al, ah, bl, bh); |
| 930 EXPECT_EQ((ah + bh + 1), res); |
| 931 } |
| 932 |
| 933 |
| 934 ASSEMBLER_TEST_GENERATE(SubReg, assembler) { |
| 935 __ movq(R10, CallingConventions::kArg1Reg); // al. |
| 936 __ subq(R10, CallingConventions::kArg3Reg); // bl. |
| 937 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
| 938 __ sbbq(RAX, CallingConventions::kArg4Reg); // bh. |
| 939 // RAX = high64(ah:al - bh:bl). |
| 940 __ ret(); |
| 941 } |
| 942 |
| 943 |
| 944 ASSEMBLER_TEST_RUN(SubReg, test) { |
| 945 typedef int64_t (*SubRegCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
| 946 int64_t al = 14; |
| 947 int64_t ah = 13; |
| 948 int64_t bl = 12; |
| 949 int64_t bh = 11; |
| 950 int64_t res = reinterpret_cast<SubRegCode>(test->entry())(al, ah, bl, bh); |
| 951 EXPECT_EQ((ah - bh), res); |
| 952 al = 10; |
| 953 res = reinterpret_cast<SubRegCode>(test->entry())(al, ah, bl, bh); |
| 954 EXPECT_EQ((ah - bh - 1), res); |
| 955 } |
| 956 |
| 957 |
| 958 ASSEMBLER_TEST_GENERATE(SubImmediate, assembler) { |
| 959 __ movq(R10, CallingConventions::kArg1Reg); // al. |
| 960 __ subq(R10, Immediate(12)); // bl. |
| 961 __ movq(RAX, CallingConventions::kArg2Reg); // ah. |
| 962 __ sbbq(RAX, Immediate(11)); // bh. |
| 963 // RAX = high64(ah:al - bh:bl). |
| 964 __ ret(); |
| 965 } |
| 966 |
| 967 |
| 968 ASSEMBLER_TEST_RUN(SubImmediate, test) { |
| 969 typedef int64_t (*SubImmediateCode)(int64_t al, int64_t ah); |
| 970 int64_t al = 14; |
| 971 int64_t ah = 13; |
| 972 int64_t bh = 11; |
| 973 int64_t res = reinterpret_cast<SubImmediateCode>(test->entry())(al, ah); |
| 974 EXPECT_EQ((ah - bh), res); |
| 975 al = 10; |
| 976 res = reinterpret_cast<SubImmediateCode>(test->entry())(al, ah); |
| 977 EXPECT_EQ((ah - bh - 1), res); |
| 978 } |
| 979 |
| 980 |
| 981 ASSEMBLER_TEST_GENERATE(SubAddress, assembler) { |
| 982 __ pushq(CallingConventions::kArg4Reg); |
| 983 __ pushq(CallingConventions::kArg3Reg); |
| 984 __ pushq(CallingConventions::kArg2Reg); |
| 985 __ pushq(CallingConventions::kArg1Reg); |
| 986 __ movq(R10, Address(RSP, 0 * kWordSize)); // al. |
| 987 __ subq(R10, Address(RSP, 2 * kWordSize)); // bl. |
| 988 __ movq(RAX, Address(RSP, 1 * kWordSize)); // ah. |
| 989 __ sbbq(RAX, Address(RSP, 3 * kWordSize)); // bh. |
| 990 // RAX = high64(ah:al - bh:bl). |
| 991 __ Drop(4); |
| 992 __ ret(); |
| 993 } |
| 994 |
| 995 |
| 996 ASSEMBLER_TEST_RUN(SubAddress, test) { |
| 997 typedef int64_t (*SubCode)(int64_t al, int64_t ah, int64_t bl, int64_t bh); |
| 998 int64_t al = 14; |
| 999 int64_t ah = 13; |
| 1000 int64_t bl = 12; |
| 1001 int64_t bh = 11; |
| 1002 int64_t res = reinterpret_cast<SubCode>(test->entry())(al, ah, bl, bh); |
| 1003 EXPECT_EQ((ah - bh), res); |
| 1004 al = 10; |
| 1005 res = reinterpret_cast<SubCode>(test->entry())(al, ah, bl, bh); |
| 1006 EXPECT_EQ((ah - bh - 1), res); |
| 1007 } |
| 1008 |
| 1009 |
| 806 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { | 1010 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) { |
| 807 __ movl(RCX, Immediate(42)); | 1011 __ movl(RCX, Immediate(42)); |
| 808 __ xorl(RCX, RCX); | 1012 __ xorl(RCX, RCX); |
| 809 __ orl(RCX, Immediate(256)); | 1013 __ orl(RCX, Immediate(256)); |
| 810 __ movl(RAX, Immediate(4)); | 1014 __ movl(RAX, Immediate(4)); |
| 811 __ orl(RCX, RAX); | 1015 __ orl(RCX, RAX); |
| 812 __ movl(RAX, Immediate(0xfff0)); | 1016 __ movl(RAX, Immediate(0xfff0)); |
| 813 __ andl(RCX, RAX); | 1017 __ andl(RCX, RAX); |
| 814 __ movl(RAX, Immediate(1)); | 1018 __ movl(RAX, Immediate(1)); |
| 815 __ orl(RCX, RAX); | 1019 __ orl(RCX, RAX); |
| (...skipping 2379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3195 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>( | 3399 int res = reinterpret_cast<ConditionalMovesNoOverflowCode>( |
| 3196 test->entry())(0x7fffffffffffffff, 2); | 3400 test->entry())(0x7fffffffffffffff, 2); |
| 3197 EXPECT_EQ(1, res); | 3401 EXPECT_EQ(1, res); |
| 3198 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); | 3402 res = reinterpret_cast<ConditionalMovesNoOverflowCode>(test->entry())(1, 1); |
| 3199 EXPECT_EQ(0, res); | 3403 EXPECT_EQ(0, res); |
| 3200 } | 3404 } |
| 3201 | 3405 |
| 3202 } // namespace dart | 3406 } // namespace dart |
| 3203 | 3407 |
| 3204 #endif // defined TARGET_ARCH_X64 | 3408 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |