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" |
11 #include "vm/virtual_memory.h" | 11 #include "vm/virtual_memory.h" |
12 | 12 |
13 namespace dart { | 13 namespace dart { |
14 | 14 |
15 #define __ assembler-> | 15 #define __ assembler-> |
16 | 16 |
17 | 17 |
18 ASSEMBLER_TEST_GENERATE(ReadArgument, assembler) { | 18 ASSEMBLER_TEST_GENERATE(ReadArgument, assembler) { |
19 __ pushq(RDI); // First argument is passed in register rdi. | 19 __ pushq(CallingConventions::kArg1Reg); |
20 __ movq(RAX, Address(RSP, 0)); | 20 __ movq(RAX, Address(RSP, 0)); |
21 __ popq(RDX); | 21 __ popq(RDX); |
22 __ ret(); | 22 __ ret(); |
23 } | 23 } |
24 | 24 |
25 | 25 |
26 ASSEMBLER_TEST_RUN(ReadArgument, test) { | 26 ASSEMBLER_TEST_RUN(ReadArgument, test) { |
27 typedef int64_t (*ReadArgumentCode)(int64_t n); | 27 typedef int64_t (*ReadArgumentCode)(int64_t n); |
28 ReadArgumentCode id = reinterpret_cast<ReadArgumentCode>(test->entry()); | 28 ReadArgumentCode id = reinterpret_cast<ReadArgumentCode>(test->entry()); |
29 EXPECT_EQ(42, id(42)); | 29 EXPECT_EQ(42, id(42)); |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 | 1289 |
1290 ASSEMBLER_TEST_GENERATE(CallSimpleLeaf, assembler) { | 1290 ASSEMBLER_TEST_GENERATE(CallSimpleLeaf, assembler) { |
1291 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); | 1291 ExternalLabel call1(reinterpret_cast<uword>(LeafReturn42)); |
1292 ExternalLabel call2(reinterpret_cast<uword>(LeafReturnArgument)); | 1292 ExternalLabel call2(reinterpret_cast<uword>(LeafReturnArgument)); |
1293 int space = ComputeStackSpaceReservation(0, 8); | 1293 int space = ComputeStackSpaceReservation(0, 8); |
1294 __ subq(RSP, Immediate(space)); | 1294 __ subq(RSP, Immediate(space)); |
1295 __ call(&call1); | 1295 __ call(&call1); |
1296 __ addq(RSP, Immediate(space)); | 1296 __ addq(RSP, Immediate(space)); |
1297 space = ComputeStackSpaceReservation(0, 8); | 1297 space = ComputeStackSpaceReservation(0, 8); |
1298 __ subq(RSP, Immediate(space)); | 1298 __ subq(RSP, Immediate(space)); |
1299 __ movl(RDI, RAX); | 1299 __ movl(CallingConventions::kArg1Reg, RAX); |
1300 __ call(&call2); | 1300 __ call(&call2); |
1301 __ addq(RSP, Immediate(space)); | 1301 __ addq(RSP, Immediate(space)); |
1302 __ ret(); | 1302 __ ret(); |
1303 } | 1303 } |
1304 | 1304 |
1305 | 1305 |
1306 ASSEMBLER_TEST_RUN(CallSimpleLeaf, test) { | 1306 ASSEMBLER_TEST_RUN(CallSimpleLeaf, test) { |
1307 typedef int (*CallSimpleLeafCode)(); | 1307 typedef int (*CallSimpleLeafCode)(); |
1308 EXPECT_EQ(42 + 87, reinterpret_cast<CallSimpleLeafCode>(test->entry())()); | 1308 EXPECT_EQ(42 + 87, reinterpret_cast<CallSimpleLeafCode>(test->entry())()); |
1309 } | 1309 } |
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2717 reinterpret_cast<SquareRootDoubleCode>(test->entry())(kDoubleConst); | 2717 reinterpret_cast<SquareRootDoubleCode>(test->entry())(kDoubleConst); |
2718 EXPECT_FLOAT_EQ(sqrt(kDoubleConst), res, 0.0001); | 2718 EXPECT_FLOAT_EQ(sqrt(kDoubleConst), res, 0.0001); |
2719 } | 2719 } |
2720 | 2720 |
2721 | 2721 |
2722 // Called from assembler_test.cc. | 2722 // Called from assembler_test.cc. |
2723 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { | 2723 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { |
2724 __ pushq(PP); // Save caller's pool pointer and load a new one here. | 2724 __ pushq(PP); // Save caller's pool pointer and load a new one here. |
2725 __ LoadPoolPointer(PP); | 2725 __ LoadPoolPointer(PP); |
2726 __ pushq(CTX); | 2726 __ pushq(CTX); |
2727 __ movq(CTX, RDI); | 2727 __ movq(CTX, CallingConventions::kArg1Reg); |
2728 __ StoreIntoObject(RDX, | 2728 __ StoreIntoObject(CallingConventions::kArg3Reg, |
2729 FieldAddress(RDX, GrowableObjectArray::data_offset()), | 2729 FieldAddress(CallingConventions::kArg3Reg, |
2730 RSI); | 2730 GrowableObjectArray::data_offset()), |
| 2731 CallingConventions::kArg2Reg); |
2731 __ popq(CTX); | 2732 __ popq(CTX); |
2732 __ popq(PP); // Restore caller's pool pointer. | 2733 __ popq(PP); // Restore caller's pool pointer. |
2733 __ ret(); | 2734 __ ret(); |
2734 } | 2735 } |
2735 | 2736 |
2736 | 2737 |
2737 ASSEMBLER_TEST_GENERATE(DoubleFPUStackMoves, assembler) { | 2738 ASSEMBLER_TEST_GENERATE(DoubleFPUStackMoves, assembler) { |
2738 int64_t l = bit_cast<int64_t, double>(1024.67); | 2739 int64_t l = bit_cast<int64_t, double>(1024.67); |
2739 __ movq(RAX, Immediate(l)); | 2740 __ movq(RAX, Immediate(l)); |
2740 __ pushq(RAX); | 2741 __ pushq(RAX); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2801 | 2802 |
2802 | 2803 |
2803 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { | 2804 ASSEMBLER_TEST_RUN(IntToDoubleConversion, test) { |
2804 typedef double (*IntToDoubleConversionCode)(); | 2805 typedef double (*IntToDoubleConversionCode)(); |
2805 double res = reinterpret_cast<IntToDoubleConversionCode>(test->entry())(); | 2806 double res = reinterpret_cast<IntToDoubleConversionCode>(test->entry())(); |
2806 EXPECT_FLOAT_EQ(6.0, res, 0.001); | 2807 EXPECT_FLOAT_EQ(6.0, res, 0.001); |
2807 } | 2808 } |
2808 | 2809 |
2809 | 2810 |
2810 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion2, assembler) { | 2811 ASSEMBLER_TEST_GENERATE(IntToDoubleConversion2, assembler) { |
2811 __ pushq(RDI); | 2812 __ pushq(CallingConventions::kArg1Reg); |
2812 __ fildl(Address(RSP, 0)); | 2813 __ fildl(Address(RSP, 0)); |
2813 __ fstpl(Address(RSP, 0)); | 2814 __ fstpl(Address(RSP, 0)); |
2814 __ movsd(XMM0, Address(RSP, 0)); | 2815 __ movsd(XMM0, Address(RSP, 0)); |
2815 __ popq(RAX); | 2816 __ popq(RAX); |
2816 __ ret(); | 2817 __ ret(); |
2817 } | 2818 } |
2818 | 2819 |
2819 | 2820 |
2820 ASSEMBLER_TEST_RUN(IntToDoubleConversion2, test) { | 2821 ASSEMBLER_TEST_RUN(IntToDoubleConversion2, test) { |
2821 typedef double (*IntToDoubleConversion2Code)(int i); | 2822 typedef double (*IntToDoubleConversion2Code)(int i); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2889 | 2890 |
2890 | 2891 |
2891 ASSEMBLER_TEST_RUN(TestSetCC, test) { | 2892 ASSEMBLER_TEST_RUN(TestSetCC, test) { |
2892 typedef uword (*TestSetCC)(); | 2893 typedef uword (*TestSetCC)(); |
2893 uword res = reinterpret_cast<TestSetCC>(test->entry())(); | 2894 uword res = reinterpret_cast<TestSetCC>(test->entry())(); |
2894 EXPECT_EQ(0xFFFFFF00, res); | 2895 EXPECT_EQ(0xFFFFFF00, res); |
2895 } | 2896 } |
2896 | 2897 |
2897 | 2898 |
2898 ASSEMBLER_TEST_GENERATE(TestRepMovsBytes, assembler) { | 2899 ASSEMBLER_TEST_GENERATE(TestRepMovsBytes, assembler) { |
2899 // Save incoming arguments. | 2900 __ pushq(RSI); |
2900 __ pushq(RDI); // Arg0, from. | 2901 __ pushq(RDI); |
2901 __ pushq(RSI); // Arg1, to. | 2902 __ pushq(CallingConventions::kArg1Reg); // from. |
2902 __ pushq(RDX); // Arg2, count. | 2903 __ pushq(CallingConventions::kArg2Reg); // to. |
| 2904 __ pushq(CallingConventions::kArg3Reg); // count. |
2903 __ movq(RSI, Address(RSP, 2 * kWordSize)); // from. | 2905 __ movq(RSI, Address(RSP, 2 * kWordSize)); // from. |
2904 __ movq(RDI, Address(RSP, 1 * kWordSize)); // to. | 2906 __ movq(RDI, Address(RSP, 1 * kWordSize)); // to. |
2905 __ movq(RCX, Address(RSP, 0 * kWordSize)); // count. | 2907 __ movq(RCX, Address(RSP, 0 * kWordSize)); // count. |
2906 __ rep_movsb(); | 2908 __ rep_movsb(); |
2907 // Remove saved arguments. | 2909 // Remove saved arguments. |
2908 __ popq(RAX); | 2910 __ popq(RAX); |
2909 __ popq(RAX); | 2911 __ popq(RAX); |
2910 __ popq(RAX); | 2912 __ popq(RAX); |
| 2913 __ popq(RDI); |
| 2914 __ popq(RSI); |
2911 __ ret(); | 2915 __ ret(); |
2912 } | 2916 } |
2913 | 2917 |
2914 | 2918 |
2915 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { | 2919 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) { |
2916 const char* from = "0123456789"; | 2920 const char* from = "0123456789"; |
2917 const char* to = new char[10]; | 2921 const char* to = new char[10]; |
2918 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); | 2922 typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count); |
2919 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); | 2923 reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10); |
2920 EXPECT_EQ(to[0], '0'); | 2924 EXPECT_EQ(to[0], '0'); |
2921 for (int i = 0; i < 10; i++) { | 2925 for (int i = 0; i < 10; i++) { |
2922 EXPECT_EQ(from[i], to[i]); | 2926 EXPECT_EQ(from[i], to[i]); |
2923 } | 2927 } |
2924 delete [] to; | 2928 delete [] to; |
2925 } | 2929 } |
2926 | 2930 |
2927 | 2931 |
2928 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { | 2932 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) { |
2929 // RDI: Arg0. | 2933 __ cmpq(CallingConventions::kArg1Reg, CallingConventions::kArg2Reg); |
2930 // RSI: Arg1. | |
2931 __ movq(RDX, Immediate(1)); // Greater equal. | 2934 __ movq(RDX, Immediate(1)); // Greater equal. |
2932 __ movq(RCX, Immediate(-1)); // Less | 2935 __ movq(RCX, Immediate(-1)); // Less |
2933 __ cmpq(RDI, RSI); | |
2934 __ cmovlessq(RAX, RCX); | 2936 __ cmovlessq(RAX, RCX); |
2935 __ cmovgeq(RAX, RDX); | 2937 __ cmovgeq(RAX, RDX); |
2936 __ ret(); | 2938 __ ret(); |
2937 } | 2939 } |
2938 | 2940 |
2939 | 2941 |
2940 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { | 2942 ASSEMBLER_TEST_RUN(ConditionalMovesCompare, test) { |
2941 typedef int (*ConditionalMovesCompareCode)(int i, int j); | 2943 typedef int (*ConditionalMovesCompareCode)(int i, int j); |
2942 int res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(10, 5); | 2944 int res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(10, 5); |
2943 EXPECT_EQ(1, res); // Greater equal. | 2945 EXPECT_EQ(1, res); // Greater equal. |
2944 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(5, 5); | 2946 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(5, 5); |
2945 EXPECT_EQ(1, res); // Greater equal. | 2947 EXPECT_EQ(1, res); // Greater equal. |
2946 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(2, 5); | 2948 res = reinterpret_cast<ConditionalMovesCompareCode>(test->entry())(2, 5); |
2947 EXPECT_EQ(-1, res); // Less. | 2949 EXPECT_EQ(-1, res); // Less. |
2948 } | 2950 } |
2949 | 2951 |
2950 } // namespace dart | 2952 } // namespace dart |
2951 | 2953 |
2952 #endif // defined TARGET_ARCH_X64 | 2954 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |