OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 9762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9773 | 9773 |
9774 CHECK(reg32.IsEmpty()); | 9774 CHECK(reg32.IsEmpty()); |
9775 CHECK(reg64.IsEmpty()); | 9775 CHECK(reg64.IsEmpty()); |
9776 CHECK(fpreg32.IsEmpty()); | 9776 CHECK(fpreg32.IsEmpty()); |
9777 CHECK(fpreg64.IsEmpty()); | 9777 CHECK(fpreg64.IsEmpty()); |
9778 } | 9778 } |
9779 | 9779 |
9780 | 9780 |
9781 TEST(printf) { | 9781 TEST(printf) { |
9782 INIT_V8(); | 9782 INIT_V8(); |
9783 SETUP(); | 9783 SETUP_SIZE(BUF_SIZE * 2); |
9784 START(); | 9784 START(); |
9785 | 9785 |
9786 char const * test_plain_string = "Printf with no arguments.\n"; | 9786 char const * test_plain_string = "Printf with no arguments.\n"; |
9787 char const * test_substring = "'This is a substring.'"; | 9787 char const * test_substring = "'This is a substring.'"; |
9788 RegisterDump before; | 9788 RegisterDump before; |
9789 | 9789 |
9790 // Initialize x29 to the value of the stack pointer. We will use x29 as a | 9790 // Initialize x29 to the value of the stack pointer. We will use x29 as a |
9791 // temporary stack pointer later, and initializing it in this way allows the | 9791 // temporary stack pointer later, and initializing it in this way allows the |
9792 // RegisterDump check to pass. | 9792 // RegisterDump check to pass. |
9793 __ Mov(x29, __ StackPointer()); | 9793 __ Mov(x29, __ StackPointer()); |
(...skipping 20 matching lines...) Expand all Loading... |
9814 | 9814 |
9815 // Test printing callee-saved registers. | 9815 // Test printing callee-saved registers. |
9816 __ Mov(x28, 0x123456789abcdef); | 9816 __ Mov(x28, 0x123456789abcdef); |
9817 __ Fmov(d10, 42.0); | 9817 __ Fmov(d10, 42.0); |
9818 | 9818 |
9819 // Test with three arguments. | 9819 // Test with three arguments. |
9820 __ Mov(x10, 3); | 9820 __ Mov(x10, 3); |
9821 __ Mov(x11, 40); | 9821 __ Mov(x11, 40); |
9822 __ Mov(x12, 500); | 9822 __ Mov(x12, 500); |
9823 | 9823 |
9824 // x8 and x9 are used by debug code in part of the macro assembler. However, | 9824 // A single character. |
9825 // Printf guarantees to preserve them (so we can use Printf in debug code), | 9825 __ Mov(w13, 'x'); |
9826 // and we need to test that they are properly preserved. The above code | |
9827 // shouldn't need to use them, but we initialize x8 and x9 last to be on the | |
9828 // safe side. This test still assumes that none of the code from | |
9829 // before->Dump() to the end of the test can clobber x8 or x9, so where | |
9830 // possible we use the Assembler directly to be safe. | |
9831 __ orr(x8, xzr, 0x8888888888888888); | |
9832 __ orr(x9, xzr, 0x9999999999999999); | |
9833 | 9826 |
9834 // Check that we don't clobber any registers, except those that we explicitly | 9827 // Check that we don't clobber any registers. |
9835 // write results into. | |
9836 before.Dump(&masm); | 9828 before.Dump(&masm); |
9837 | 9829 |
9838 __ Printf(test_plain_string); // NOLINT(runtime/printf) | 9830 __ Printf(test_plain_string); // NOLINT(runtime/printf) |
9839 __ Printf("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1); | 9831 __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1); |
| 9832 __ Printf("w5: %" PRId32 ", x5: %" PRId64"\n", w5, x5); |
9840 __ Printf("d0: %f\n", d0); | 9833 __ Printf("d0: %f\n", d0); |
9841 __ Printf("Test %%s: %s\n", x2); | 9834 __ Printf("Test %%s: %s\n", x2); |
9842 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n" | 9835 __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32 "\n" |
9843 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n", | 9836 "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n", |
9844 w3, w4, x5, x6); | 9837 w3, w4, x5, x6); |
9845 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4); | 9838 __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4); |
9846 __ Printf("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28); | 9839 __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28); |
9847 __ Printf("%g\n", d10); | 9840 __ Printf("%g\n", d10); |
| 9841 __ Printf("%%%%%s%%%c%%\n", x2, w13); |
| 9842 |
| 9843 // Print the stack pointer (csp). |
| 9844 ASSERT(csp.Is(__ StackPointer())); |
| 9845 __ Printf("StackPointer(csp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n", |
| 9846 __ StackPointer(), __ StackPointer().W()); |
9848 | 9847 |
9849 // Test with a different stack pointer. | 9848 // Test with a different stack pointer. |
9850 const Register old_stack_pointer = __ StackPointer(); | 9849 const Register old_stack_pointer = __ StackPointer(); |
9851 __ mov(x29, old_stack_pointer); | 9850 __ Mov(x29, old_stack_pointer); |
9852 __ SetStackPointer(x29); | 9851 __ SetStackPointer(x29); |
9853 __ Printf("old_stack_pointer: 0x%016" PRIx64 "\n", old_stack_pointer); | 9852 // Print the stack pointer (not csp). |
9854 __ mov(old_stack_pointer, __ StackPointer()); | 9853 __ Printf("StackPointer(not csp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n", |
| 9854 __ StackPointer(), __ StackPointer().W()); |
| 9855 __ Mov(old_stack_pointer, __ StackPointer()); |
9855 __ SetStackPointer(old_stack_pointer); | 9856 __ SetStackPointer(old_stack_pointer); |
9856 | 9857 |
| 9858 // Test with three arguments. |
9857 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12); | 9859 __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12); |
9858 | 9860 |
| 9861 // Mixed argument types. |
| 9862 __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n", |
| 9863 w3, s1, x5, d3); |
| 9864 __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n", |
| 9865 s1, d3, w3, x5); |
| 9866 |
9859 END(); | 9867 END(); |
9860 RUN(); | 9868 RUN(); |
9861 | 9869 |
9862 // We cannot easily test the output of the Printf sequences, and because | 9870 // We cannot easily test the output of the Printf sequences, and because |
9863 // Printf preserves all registers by default, we can't look at the number of | 9871 // Printf preserves all registers by default, we can't look at the number of |
9864 // bytes that were printed. However, the printf_no_preserve test should check | 9872 // bytes that were printed. However, the printf_no_preserve test should check |
9865 // that, and here we just test that we didn't clobber any registers. | 9873 // that, and here we just test that we didn't clobber any registers. |
9866 ASSERT_EQUAL_REGISTERS(before); | 9874 ASSERT_EQUAL_REGISTERS(before); |
9867 | 9875 |
9868 TEARDOWN(); | 9876 TEARDOWN(); |
9869 } | 9877 } |
9870 | 9878 |
9871 | 9879 |
9872 TEST(printf_no_preserve) { | 9880 TEST(printf_no_preserve) { |
9873 INIT_V8(); | 9881 INIT_V8(); |
9874 SETUP(); | 9882 SETUP(); |
9875 START(); | 9883 START(); |
9876 | 9884 |
9877 char const * test_plain_string = "Printf with no arguments.\n"; | 9885 char const * test_plain_string = "Printf with no arguments.\n"; |
9878 char const * test_substring = "'This is a substring.'"; | 9886 char const * test_substring = "'This is a substring.'"; |
9879 | 9887 |
9880 __ PrintfNoPreserve(test_plain_string); // NOLINT(runtime/printf) | 9888 __ PrintfNoPreserve(test_plain_string); |
9881 __ Mov(x19, x0); | 9889 __ Mov(x19, x0); |
9882 | 9890 |
9883 // Test simple integer arguments. | 9891 // Test simple integer arguments. |
9884 __ Mov(x0, 1234); | 9892 __ Mov(x0, 1234); |
9885 __ Mov(x1, 0x1234); | 9893 __ Mov(x1, 0x1234); |
9886 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1); | 9894 __ PrintfNoPreserve("x0: %" PRId64", x1: 0x%08" PRIx64 "\n", x0, x1); |
9887 __ Mov(x20, x0); | 9895 __ Mov(x20, x0); |
9888 | 9896 |
9889 // Test simple floating-point arguments. | 9897 // Test simple floating-point arguments. |
9890 __ Fmov(d0, 1.234); | 9898 __ Fmov(d0, 1.234); |
(...skipping 17 matching lines...) Expand all Loading... |
9908 | 9916 |
9909 __ Fmov(s1, 1.234); | 9917 __ Fmov(s1, 1.234); |
9910 __ Fmov(s2, 2.345); | 9918 __ Fmov(s2, 2.345); |
9911 __ Fmov(d3, 3.456); | 9919 __ Fmov(d3, 3.456); |
9912 __ Fmov(d4, 4.567); | 9920 __ Fmov(d4, 4.567); |
9913 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4); | 9921 __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4); |
9914 __ Mov(x24, x0); | 9922 __ Mov(x24, x0); |
9915 | 9923 |
9916 // Test printing callee-saved registers. | 9924 // Test printing callee-saved registers. |
9917 __ Mov(x28, 0x123456789abcdef); | 9925 __ Mov(x28, 0x123456789abcdef); |
9918 __ PrintfNoPreserve("0x%08" PRIx32 ", 0x%016" PRIx64 "\n", x28, x28); | 9926 __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28); |
9919 __ Mov(x25, x0); | 9927 __ Mov(x25, x0); |
9920 | 9928 |
9921 __ Fmov(d10, 42.0); | 9929 __ Fmov(d10, 42.0); |
9922 __ PrintfNoPreserve("%g\n", d10); | 9930 __ PrintfNoPreserve("%g\n", d10); |
9923 __ Mov(x26, x0); | 9931 __ Mov(x26, x0); |
9924 | 9932 |
9925 // Test with a different stack pointer. | 9933 // Test with a different stack pointer. |
9926 const Register old_stack_pointer = __ StackPointer(); | 9934 const Register old_stack_pointer = __ StackPointer(); |
9927 __ Mov(x29, old_stack_pointer); | 9935 __ Mov(x29, old_stack_pointer); |
9928 __ SetStackPointer(x29); | 9936 __ SetStackPointer(x29); |
9929 | 9937 // Print the stack pointer (not csp). |
9930 __ PrintfNoPreserve("old_stack_pointer: 0x%016" PRIx64 "\n", | 9938 __ PrintfNoPreserve( |
9931 old_stack_pointer); | 9939 "StackPointer(not csp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n", |
| 9940 __ StackPointer(), __ StackPointer().W()); |
9932 __ Mov(x27, x0); | 9941 __ Mov(x27, x0); |
9933 | |
9934 __ Mov(old_stack_pointer, __ StackPointer()); | 9942 __ Mov(old_stack_pointer, __ StackPointer()); |
9935 __ SetStackPointer(old_stack_pointer); | 9943 __ SetStackPointer(old_stack_pointer); |
9936 | 9944 |
9937 // Test with three arguments. | 9945 // Test with three arguments. |
9938 __ Mov(x3, 3); | 9946 __ Mov(x3, 3); |
9939 __ Mov(x4, 40); | 9947 __ Mov(x4, 40); |
9940 __ Mov(x5, 500); | 9948 __ Mov(x5, 500); |
9941 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5); | 9949 __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5); |
9942 __ Mov(x28, x0); | 9950 __ Mov(x28, x0); |
9943 | 9951 |
| 9952 // Mixed argument types. |
| 9953 __ Mov(w3, 0xffffffff); |
| 9954 __ Fmov(s1, 1.234); |
| 9955 __ Mov(x5, 0xffffffffffffffff); |
| 9956 __ Fmov(d3, 3.456); |
| 9957 __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n", |
| 9958 w3, s1, x5, d3); |
| 9959 __ Mov(x29, x0); |
| 9960 |
9944 END(); | 9961 END(); |
9945 RUN(); | 9962 RUN(); |
9946 | 9963 |
9947 // We cannot easily test the exact output of the Printf sequences, but we can | 9964 // We cannot easily test the exact output of the Printf sequences, but we can |
9948 // use the return code to check that the string length was correct. | 9965 // use the return code to check that the string length was correct. |
9949 | 9966 |
9950 // Printf with no arguments. | 9967 // Printf with no arguments. |
9951 ASSERT_EQUAL_64(strlen(test_plain_string), x19); | 9968 ASSERT_EQUAL_64(strlen(test_plain_string), x19); |
9952 // x0: 1234, x1: 0x00001234 | 9969 // x0: 1234, x1: 0x00001234 |
9953 ASSERT_EQUAL_64(25, x20); | 9970 ASSERT_EQUAL_64(25, x20); |
9954 // d0: 1.234000 | 9971 // d0: 1.234000 |
9955 ASSERT_EQUAL_64(13, x21); | 9972 ASSERT_EQUAL_64(13, x21); |
9956 // Test %s: 'This is a substring.' | 9973 // Test %s: 'This is a substring.' |
9957 ASSERT_EQUAL_64(32, x22); | 9974 ASSERT_EQUAL_64(32, x22); |
9958 // w3(uint32): 4294967295 | 9975 // w3(uint32): 4294967295 |
9959 // w4(int32): -1 | 9976 // w4(int32): -1 |
9960 // x5(uint64): 18446744073709551615 | 9977 // x5(uint64): 18446744073709551615 |
9961 // x6(int64): -1 | 9978 // x6(int64): -1 |
9962 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23); | 9979 ASSERT_EQUAL_64(23 + 14 + 33 + 14, x23); |
9963 // %f: 1.234000 | 9980 // %f: 1.234000 |
9964 // %g: 2.345 | 9981 // %g: 2.345 |
9965 // %e: 3.456000e+00 | 9982 // %e: 3.456000e+00 |
9966 // %E: 4.567000E+00 | 9983 // %E: 4.567000E+00 |
9967 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24); | 9984 ASSERT_EQUAL_64(13 + 10 + 17 + 17, x24); |
9968 // 0x89abcdef, 0x0123456789abcdef | 9985 // 0x89abcdef, 0x123456789abcdef |
9969 ASSERT_EQUAL_64(31, x25); | 9986 ASSERT_EQUAL_64(30, x25); |
9970 // 42 | 9987 // 42 |
9971 ASSERT_EQUAL_64(3, x26); | 9988 ASSERT_EQUAL_64(3, x26); |
9972 // old_stack_pointer: 0x00007fb037ae2370 | 9989 // StackPointer(not csp): 0x00007fb037ae2370, 0x37ae2370 |
9973 // Note: This is an example value, but the field width is fixed here so the | 9990 // Note: This is an example value, but the field width is fixed here so the |
9974 // string length is still predictable. | 9991 // string length is still predictable. |
9975 ASSERT_EQUAL_64(38, x27); | 9992 ASSERT_EQUAL_64(54, x27); |
9976 // 3=3, 4=40, 5=500 | 9993 // 3=3, 4=40, 5=500 |
9977 ASSERT_EQUAL_64(17, x28); | 9994 ASSERT_EQUAL_64(17, x28); |
| 9995 // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000 |
| 9996 ASSERT_EQUAL_64(69, x29); |
9978 | 9997 |
9979 TEARDOWN(); | 9998 TEARDOWN(); |
9980 } | 9999 } |
9981 | 10000 |
9982 | 10001 |
9983 // This is a V8-specific test. | 10002 // This is a V8-specific test. |
9984 static void CopyFieldsHelper(CPURegList temps) { | 10003 static void CopyFieldsHelper(CPURegList temps) { |
9985 static const uint64_t kLiteralBase = 0x0100001000100101UL; | 10004 static const uint64_t kLiteralBase = 0x0100001000100101UL; |
9986 static const uint64_t src[] = {kLiteralBase * 1, | 10005 static const uint64_t src[] = {kLiteralBase * 1, |
9987 kLiteralBase * 2, | 10006 kLiteralBase * 2, |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10958 if (RelocInfo::IsVeneerPool(info->rmode())) { | 10977 if (RelocInfo::IsVeneerPool(info->rmode())) { |
10959 ASSERT(info->data() == veneer_pool_size); | 10978 ASSERT(info->data() == veneer_pool_size); |
10960 ++pool_count; | 10979 ++pool_count; |
10961 } | 10980 } |
10962 } | 10981 } |
10963 | 10982 |
10964 ASSERT(pool_count == 2); | 10983 ASSERT(pool_count == 2); |
10965 | 10984 |
10966 TEARDOWN(); | 10985 TEARDOWN(); |
10967 } | 10986 } |
OLD | NEW |