OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 using i::Operand; | 48 using i::Operand; |
49 using i::RelocInfo; | 49 using i::RelocInfo; |
50 using i::Representation; | 50 using i::Representation; |
51 using i::Smi; | 51 using i::Smi; |
52 using i::SmiIndex; | 52 using i::SmiIndex; |
53 using i::byte; | 53 using i::byte; |
54 using i::carry; | 54 using i::carry; |
55 using i::greater; | 55 using i::greater; |
56 using i::greater_equal; | 56 using i::greater_equal; |
57 using i::kIntSize; | 57 using i::kIntSize; |
| 58 using i::kFloatSize; |
| 59 using i::kDoubleSize; |
58 using i::kPointerSize; | 60 using i::kPointerSize; |
| 61 using i::kSimd128Size; |
59 using i::kSmiTagMask; | 62 using i::kSmiTagMask; |
60 using i::kSmiValueSize; | 63 using i::kSmiValueSize; |
61 using i::less_equal; | 64 using i::less_equal; |
62 using i::negative; | 65 using i::negative; |
63 using i::not_carry; | 66 using i::not_carry; |
64 using i::not_equal; | 67 using i::not_equal; |
65 using i::equal; | 68 using i::equal; |
66 using i::not_zero; | 69 using i::not_zero; |
67 using i::positive; | 70 using i::positive; |
68 using i::r11; | 71 using i::r11; |
69 using i::r13; | 72 using i::r13; |
70 using i::r14; | 73 using i::r14; |
71 using i::r15; | 74 using i::r15; |
72 using i::r8; | 75 using i::r8; |
73 using i::r9; | 76 using i::r9; |
74 using i::rax; | 77 using i::rax; |
75 using i::rbp; | 78 using i::rbp; |
76 using i::rbx; | 79 using i::rbx; |
77 using i::rcx; | 80 using i::rcx; |
78 using i::rdi; | 81 using i::rdi; |
79 using i::rdx; | 82 using i::rdx; |
80 using i::rsi; | 83 using i::rsi; |
81 using i::rsp; | 84 using i::rsp; |
| 85 using i::xmm0; |
| 86 using i::xmm1; |
| 87 using i::xmm2; |
| 88 using i::xmm3; |
| 89 using i::xmm4; |
| 90 using i::xmm5; |
| 91 using i::xmm6; |
| 92 using i::xmm7; |
| 93 using i::xmm8; |
| 94 using i::xmm9; |
| 95 using i::xmm10; |
| 96 using i::xmm11; |
| 97 using i::xmm12; |
| 98 using i::xmm13; |
| 99 using i::xmm14; |
| 100 using i::xmm15; |
82 using i::times_pointer_size; | 101 using i::times_pointer_size; |
83 | 102 |
84 // Test the x64 assembler by compiling some simple functions into | 103 // Test the x64 assembler by compiling some simple functions into |
85 // a buffer and executing them. These tests do not initialize the | 104 // a buffer and executing them. These tests do not initialize the |
86 // V8 library, create a context, or use any V8 objects. | 105 // V8 library, create a context, or use any V8 objects. |
87 // The AMD64 calling convention is used, with the first five arguments | 106 // The AMD64 calling convention is used, with the first five arguments |
88 // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in | 107 // in RSI, RDI, RDX, RCX, R8, and R9, and floating point arguments in |
89 // the XMM registers. The return value is in RAX. | 108 // the XMM registers. The return value is in RAX. |
90 // This calling convention is used on Linux, with GCC, and on Mac OS, | 109 // This calling convention is used on Linux, with GCC, and on Mac OS, |
91 // with GCC. A different convention is used on 64-bit windows. | 110 // with GCC. A different convention is used on 64-bit windows. |
(...skipping 2629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2721 ExitCode(masm); | 2740 ExitCode(masm); |
2722 __ ret(0); | 2741 __ ret(0); |
2723 | 2742 |
2724 CodeDesc desc; | 2743 CodeDesc desc; |
2725 masm->GetCode(&desc); | 2744 masm->GetCode(&desc); |
2726 // Call the function from C++. | 2745 // Call the function from C++. |
2727 int result = FUNCTION_CAST<F0>(buffer)(); | 2746 int result = FUNCTION_CAST<F0>(buffer)(); |
2728 CHECK_EQ(0, result); | 2747 CHECK_EQ(0, result); |
2729 } | 2748 } |
2730 | 2749 |
| 2750 void TestFloat32x4Abs(MacroAssembler* masm, Label* exit, float x, float y, |
| 2751 float z, float w) { |
| 2752 __ subq(rsp, Immediate(kSimd128Size)); |
| 2753 |
| 2754 __ Move(xmm1, x); |
| 2755 __ Movss(Operand(rsp, 0 * kFloatSize), xmm1); |
| 2756 __ Move(xmm2, y); |
| 2757 __ Movss(Operand(rsp, 1 * kFloatSize), xmm2); |
| 2758 __ Move(xmm3, z); |
| 2759 __ Movss(Operand(rsp, 2 * kFloatSize), xmm3); |
| 2760 __ Move(xmm4, w); |
| 2761 __ Movss(Operand(rsp, 3 * kFloatSize), xmm4); |
| 2762 __ Movups(xmm0, Operand(rsp, 0)); |
| 2763 |
| 2764 __ Absps(xmm0); |
| 2765 __ Movups(Operand(rsp, 0), xmm0); |
| 2766 |
| 2767 __ incq(rax); |
| 2768 __ Move(xmm1, fabsf(x)); |
| 2769 __ Ucomiss(xmm1, Operand(rsp, 0 * kFloatSize)); |
| 2770 __ j(not_equal, exit); |
| 2771 __ incq(rax); |
| 2772 __ Move(xmm2, fabsf(y)); |
| 2773 __ Ucomiss(xmm2, Operand(rsp, 1 * kFloatSize)); |
| 2774 __ j(not_equal, exit); |
| 2775 __ incq(rax); |
| 2776 __ Move(xmm3, fabsf(z)); |
| 2777 __ Ucomiss(xmm3, Operand(rsp, 2 * kFloatSize)); |
| 2778 __ j(not_equal, exit); |
| 2779 __ incq(rax); |
| 2780 __ Move(xmm4, fabsf(w)); |
| 2781 __ Ucomiss(xmm4, Operand(rsp, 3 * kFloatSize)); |
| 2782 __ j(not_equal, exit); |
| 2783 |
| 2784 __ addq(rsp, Immediate(kSimd128Size)); |
| 2785 } |
| 2786 |
| 2787 void TestFloat32x4Neg(MacroAssembler* masm, Label* exit, float x, float y, |
| 2788 float z, float w) { |
| 2789 __ subq(rsp, Immediate(kSimd128Size)); |
| 2790 |
| 2791 __ Move(xmm1, x); |
| 2792 __ Movss(Operand(rsp, 0 * kFloatSize), xmm1); |
| 2793 __ Move(xmm2, y); |
| 2794 __ Movss(Operand(rsp, 1 * kFloatSize), xmm2); |
| 2795 __ Move(xmm3, z); |
| 2796 __ Movss(Operand(rsp, 2 * kFloatSize), xmm3); |
| 2797 __ Move(xmm4, w); |
| 2798 __ Movss(Operand(rsp, 3 * kFloatSize), xmm4); |
| 2799 __ Movups(xmm0, Operand(rsp, 0)); |
| 2800 |
| 2801 __ Negps(xmm0); |
| 2802 __ Movups(Operand(rsp, 0), xmm0); |
| 2803 |
| 2804 __ incq(rax); |
| 2805 __ Move(xmm1, -x); |
| 2806 __ Ucomiss(xmm1, Operand(rsp, 0 * kFloatSize)); |
| 2807 __ j(not_equal, exit); |
| 2808 __ incq(rax); |
| 2809 __ Move(xmm2, -y); |
| 2810 __ Ucomiss(xmm2, Operand(rsp, 1 * kFloatSize)); |
| 2811 __ j(not_equal, exit); |
| 2812 __ incq(rax); |
| 2813 __ Move(xmm3, -z); |
| 2814 __ Ucomiss(xmm3, Operand(rsp, 2 * kFloatSize)); |
| 2815 __ j(not_equal, exit); |
| 2816 __ incq(rax); |
| 2817 __ Move(xmm4, -w); |
| 2818 __ Ucomiss(xmm4, Operand(rsp, 3 * kFloatSize)); |
| 2819 __ j(not_equal, exit); |
| 2820 |
| 2821 __ addq(rsp, Immediate(kSimd128Size)); |
| 2822 } |
| 2823 |
| 2824 void TestFloat64x2Abs(MacroAssembler* masm, Label* exit, double x, double y) { |
| 2825 __ subq(rsp, Immediate(kSimd128Size)); |
| 2826 |
| 2827 __ Move(xmm1, x); |
| 2828 __ Movsd(Operand(rsp, 0 * kDoubleSize), xmm1); |
| 2829 __ Move(xmm2, y); |
| 2830 __ Movsd(Operand(rsp, 1 * kDoubleSize), xmm2); |
| 2831 __ Movupd(xmm0, Operand(rsp, 0)); |
| 2832 |
| 2833 __ Abspd(xmm0); |
| 2834 __ Movupd(Operand(rsp, 0), xmm0); |
| 2835 |
| 2836 __ incq(rax); |
| 2837 __ Move(xmm1, fabs(x)); |
| 2838 __ Ucomisd(xmm1, Operand(rsp, 0 * kDoubleSize)); |
| 2839 __ j(not_equal, exit); |
| 2840 __ incq(rax); |
| 2841 __ Move(xmm2, fabs(y)); |
| 2842 __ Ucomisd(xmm2, Operand(rsp, 1 * kDoubleSize)); |
| 2843 __ j(not_equal, exit); |
| 2844 |
| 2845 __ addq(rsp, Immediate(kSimd128Size)); |
| 2846 } |
| 2847 |
| 2848 void TestFloat64x2Neg(MacroAssembler* masm, Label* exit, double x, double y) { |
| 2849 __ subq(rsp, Immediate(kSimd128Size)); |
| 2850 |
| 2851 __ Move(xmm1, x); |
| 2852 __ Movsd(Operand(rsp, 0 * kDoubleSize), xmm1); |
| 2853 __ Move(xmm2, y); |
| 2854 __ Movsd(Operand(rsp, 1 * kDoubleSize), xmm2); |
| 2855 __ Movupd(xmm0, Operand(rsp, 0)); |
| 2856 |
| 2857 __ Negpd(xmm0); |
| 2858 __ Movupd(Operand(rsp, 0), xmm0); |
| 2859 |
| 2860 __ incq(rax); |
| 2861 __ Move(xmm1, -x); |
| 2862 __ Ucomisd(xmm1, Operand(rsp, 0 * kDoubleSize)); |
| 2863 __ j(not_equal, exit); |
| 2864 __ incq(rax); |
| 2865 __ Move(xmm2, -y); |
| 2866 __ Ucomisd(xmm2, Operand(rsp, 1 * kDoubleSize)); |
| 2867 __ j(not_equal, exit); |
| 2868 |
| 2869 __ addq(rsp, Immediate(kSimd128Size)); |
| 2870 } |
| 2871 |
| 2872 TEST(SIMDMacros) { |
| 2873 // Allocate an executable page of memory. |
| 2874 size_t actual_size; |
| 2875 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
| 2876 Assembler::kMinimalBufferSize * 2, &actual_size, true)); |
| 2877 CHECK(buffer); |
| 2878 Isolate* isolate = CcTest::i_isolate(); |
| 2879 HandleScope handles(isolate); |
| 2880 MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), |
| 2881 v8::internal::CodeObjectRequired::kYes); |
| 2882 |
| 2883 MacroAssembler* masm = &assembler; |
| 2884 EntryCode(masm); |
| 2885 Label exit; |
| 2886 |
| 2887 __ xorq(rax, rax); |
| 2888 TestFloat32x4Abs(masm, &exit, 1.5, -1.5, 0.5, -0.5); |
| 2889 TestFloat32x4Neg(masm, &exit, 1.5, -1.5, 0.5, -0.5); |
| 2890 TestFloat64x2Abs(masm, &exit, 1.75, -1.75); |
| 2891 TestFloat64x2Neg(masm, &exit, 1.75, -1.75); |
| 2892 |
| 2893 __ xorq(rax, rax); // Success. |
| 2894 __ bind(&exit); |
| 2895 ExitCode(masm); |
| 2896 __ ret(0); |
| 2897 |
| 2898 CodeDesc desc; |
| 2899 masm->GetCode(&desc); |
| 2900 // Call the function from C++. |
| 2901 int result = FUNCTION_CAST<F0>(buffer)(); |
| 2902 CHECK_EQ(0, result); |
| 2903 } |
2731 | 2904 |
2732 #undef __ | 2905 #undef __ |
OLD | NEW |