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 4897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4908 | 4908 |
4909 TEARDOWN(); | 4909 TEARDOWN(); |
4910 } | 4910 } |
4911 | 4911 |
4912 | 4912 |
4913 TEST(fadd) { | 4913 TEST(fadd) { |
4914 INIT_V8(); | 4914 INIT_V8(); |
4915 SETUP(); | 4915 SETUP(); |
4916 | 4916 |
4917 START(); | 4917 START(); |
4918 __ Fmov(s13, -0.0); | 4918 __ Fmov(s14, -0.0f); |
4919 __ Fmov(s14, kFP32PositiveInfinity); | 4919 __ Fmov(s15, kFP32PositiveInfinity); |
4920 __ Fmov(s15, kFP32NegativeInfinity); | 4920 __ Fmov(s16, kFP32NegativeInfinity); |
4921 __ Fmov(s16, 3.25); | 4921 __ Fmov(s17, 3.25f); |
4922 __ Fmov(s17, 1.0); | 4922 __ Fmov(s18, 1.0f); |
4923 __ Fmov(s18, 0); | 4923 __ Fmov(s19, 0.0f); |
4924 | 4924 |
4925 __ Fmov(d26, -0.0); | 4925 __ Fmov(d26, -0.0); |
4926 __ Fmov(d27, kFP64PositiveInfinity); | 4926 __ Fmov(d27, kFP64PositiveInfinity); |
4927 __ Fmov(d28, kFP64NegativeInfinity); | 4927 __ Fmov(d28, kFP64NegativeInfinity); |
4928 __ Fmov(d29, 0); | 4928 __ Fmov(d29, 0.0); |
4929 __ Fmov(d30, -2.0); | 4929 __ Fmov(d30, -2.0); |
4930 __ Fmov(d31, 2.25); | 4930 __ Fmov(d31, 2.25); |
4931 | 4931 |
4932 __ Fadd(s0, s16, s17); | 4932 __ Fadd(s0, s17, s18); |
4933 __ Fadd(s1, s17, s18); | 4933 __ Fadd(s1, s18, s19); |
4934 __ Fadd(s2, s13, s17); | 4934 __ Fadd(s2, s14, s18); |
4935 __ Fadd(s3, s14, s17); | 4935 __ Fadd(s3, s15, s18); |
4936 __ Fadd(s4, s15, s17); | 4936 __ Fadd(s4, s16, s18); |
| 4937 __ Fadd(s5, s15, s16); |
| 4938 __ Fadd(s6, s16, s15); |
4937 | 4939 |
4938 __ Fadd(d5, d30, d31); | 4940 __ Fadd(d7, d30, d31); |
4939 __ Fadd(d6, d29, d31); | 4941 __ Fadd(d8, d29, d31); |
4940 __ Fadd(d7, d26, d31); | 4942 __ Fadd(d9, d26, d31); |
4941 __ Fadd(d8, d27, d31); | 4943 __ Fadd(d10, d27, d31); |
4942 __ Fadd(d9, d28, d31); | 4944 __ Fadd(d11, d28, d31); |
| 4945 __ Fadd(d12, d27, d28); |
| 4946 __ Fadd(d13, d28, d27); |
4943 END(); | 4947 END(); |
4944 | 4948 |
4945 RUN(); | 4949 RUN(); |
4946 | 4950 |
4947 ASSERT_EQUAL_FP32(4.25, s0); | 4951 ASSERT_EQUAL_FP32(4.25, s0); |
4948 ASSERT_EQUAL_FP32(1.0, s1); | 4952 ASSERT_EQUAL_FP32(1.0, s1); |
4949 ASSERT_EQUAL_FP32(1.0, s2); | 4953 ASSERT_EQUAL_FP32(1.0, s2); |
4950 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3); | 4954 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3); |
4951 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4); | 4955 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4); |
4952 ASSERT_EQUAL_FP64(0.25, d5); | 4956 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5); |
4953 ASSERT_EQUAL_FP64(2.25, d6); | 4957 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6); |
4954 ASSERT_EQUAL_FP64(2.25, d7); | 4958 ASSERT_EQUAL_FP64(0.25, d7); |
4955 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d8); | 4959 ASSERT_EQUAL_FP64(2.25, d8); |
4956 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d9); | 4960 ASSERT_EQUAL_FP64(2.25, d9); |
| 4961 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10); |
| 4962 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11); |
| 4963 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12); |
| 4964 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13); |
4957 | 4965 |
4958 TEARDOWN(); | 4966 TEARDOWN(); |
4959 } | 4967 } |
4960 | 4968 |
4961 | 4969 |
4962 TEST(fsub) { | 4970 TEST(fsub) { |
4963 INIT_V8(); | 4971 INIT_V8(); |
4964 SETUP(); | 4972 SETUP(); |
4965 | 4973 |
4966 START(); | 4974 START(); |
4967 __ Fmov(s13, -0.0); | 4975 __ Fmov(s14, -0.0f); |
4968 __ Fmov(s14, kFP32PositiveInfinity); | 4976 __ Fmov(s15, kFP32PositiveInfinity); |
4969 __ Fmov(s15, kFP32NegativeInfinity); | 4977 __ Fmov(s16, kFP32NegativeInfinity); |
4970 __ Fmov(s16, 3.25); | 4978 __ Fmov(s17, 3.25f); |
4971 __ Fmov(s17, 1.0); | 4979 __ Fmov(s18, 1.0f); |
4972 __ Fmov(s18, 0); | 4980 __ Fmov(s19, 0.0f); |
4973 | 4981 |
4974 __ Fmov(d26, -0.0); | 4982 __ Fmov(d26, -0.0); |
4975 __ Fmov(d27, kFP64PositiveInfinity); | 4983 __ Fmov(d27, kFP64PositiveInfinity); |
4976 __ Fmov(d28, kFP64NegativeInfinity); | 4984 __ Fmov(d28, kFP64NegativeInfinity); |
4977 __ Fmov(d29, 0); | 4985 __ Fmov(d29, 0.0); |
4978 __ Fmov(d30, -2.0); | 4986 __ Fmov(d30, -2.0); |
4979 __ Fmov(d31, 2.25); | 4987 __ Fmov(d31, 2.25); |
4980 | 4988 |
4981 __ Fsub(s0, s16, s17); | 4989 __ Fsub(s0, s17, s18); |
4982 __ Fsub(s1, s17, s18); | 4990 __ Fsub(s1, s18, s19); |
4983 __ Fsub(s2, s13, s17); | 4991 __ Fsub(s2, s14, s18); |
4984 __ Fsub(s3, s17, s14); | 4992 __ Fsub(s3, s18, s15); |
4985 __ Fsub(s4, s17, s15); | 4993 __ Fsub(s4, s18, s16); |
| 4994 __ Fsub(s5, s15, s15); |
| 4995 __ Fsub(s6, s16, s16); |
4986 | 4996 |
4987 __ Fsub(d5, d30, d31); | 4997 __ Fsub(d7, d30, d31); |
4988 __ Fsub(d6, d29, d31); | 4998 __ Fsub(d8, d29, d31); |
4989 __ Fsub(d7, d26, d31); | 4999 __ Fsub(d9, d26, d31); |
4990 __ Fsub(d8, d31, d27); | 5000 __ Fsub(d10, d31, d27); |
4991 __ Fsub(d9, d31, d28); | 5001 __ Fsub(d11, d31, d28); |
| 5002 __ Fsub(d12, d27, d27); |
| 5003 __ Fsub(d13, d28, d28); |
4992 END(); | 5004 END(); |
4993 | 5005 |
4994 RUN(); | 5006 RUN(); |
4995 | 5007 |
4996 ASSERT_EQUAL_FP32(2.25, s0); | 5008 ASSERT_EQUAL_FP32(2.25, s0); |
4997 ASSERT_EQUAL_FP32(1.0, s1); | 5009 ASSERT_EQUAL_FP32(1.0, s1); |
4998 ASSERT_EQUAL_FP32(-1.0, s2); | 5010 ASSERT_EQUAL_FP32(-1.0, s2); |
4999 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3); | 5011 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3); |
5000 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4); | 5012 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4); |
5001 ASSERT_EQUAL_FP64(-4.25, d5); | 5013 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5); |
5002 ASSERT_EQUAL_FP64(-2.25, d6); | 5014 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6); |
5003 ASSERT_EQUAL_FP64(-2.25, d7); | 5015 ASSERT_EQUAL_FP64(-4.25, d7); |
5004 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8); | 5016 ASSERT_EQUAL_FP64(-2.25, d8); |
5005 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d9); | 5017 ASSERT_EQUAL_FP64(-2.25, d9); |
| 5018 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10); |
| 5019 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11); |
| 5020 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12); |
| 5021 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13); |
5006 | 5022 |
5007 TEARDOWN(); | 5023 TEARDOWN(); |
5008 } | 5024 } |
5009 | 5025 |
5010 | 5026 |
5011 TEST(fmul) { | 5027 TEST(fmul) { |
5012 INIT_V8(); | 5028 INIT_V8(); |
5013 SETUP(); | 5029 SETUP(); |
5014 | 5030 |
5015 START(); | 5031 START(); |
5016 __ Fmov(s13, -0.0); | 5032 __ Fmov(s14, -0.0f); |
5017 __ Fmov(s14, kFP32PositiveInfinity); | 5033 __ Fmov(s15, kFP32PositiveInfinity); |
5018 __ Fmov(s15, kFP32NegativeInfinity); | 5034 __ Fmov(s16, kFP32NegativeInfinity); |
5019 __ Fmov(s16, 3.25); | 5035 __ Fmov(s17, 3.25f); |
5020 __ Fmov(s17, 2.0); | 5036 __ Fmov(s18, 2.0f); |
5021 __ Fmov(s18, 0); | 5037 __ Fmov(s19, 0.0f); |
5022 __ Fmov(s19, -2.0); | 5038 __ Fmov(s20, -2.0f); |
5023 | 5039 |
5024 __ Fmov(d26, -0.0); | 5040 __ Fmov(d26, -0.0); |
5025 __ Fmov(d27, kFP64PositiveInfinity); | 5041 __ Fmov(d27, kFP64PositiveInfinity); |
5026 __ Fmov(d28, kFP64NegativeInfinity); | 5042 __ Fmov(d28, kFP64NegativeInfinity); |
5027 __ Fmov(d29, 0); | 5043 __ Fmov(d29, 0.0); |
5028 __ Fmov(d30, -2.0); | 5044 __ Fmov(d30, -2.0); |
5029 __ Fmov(d31, 2.25); | 5045 __ Fmov(d31, 2.25); |
5030 | 5046 |
5031 __ Fmul(s0, s16, s17); | 5047 __ Fmul(s0, s17, s18); |
5032 __ Fmul(s1, s17, s18); | 5048 __ Fmul(s1, s18, s19); |
5033 __ Fmul(s2, s13, s13); | 5049 __ Fmul(s2, s14, s14); |
5034 __ Fmul(s3, s14, s19); | 5050 __ Fmul(s3, s15, s20); |
5035 __ Fmul(s4, s15, s19); | 5051 __ Fmul(s4, s16, s20); |
| 5052 __ Fmul(s5, s15, s19); |
| 5053 __ Fmul(s6, s19, s16); |
5036 | 5054 |
5037 __ Fmul(d5, d30, d31); | 5055 __ Fmul(d7, d30, d31); |
5038 __ Fmul(d6, d29, d31); | 5056 __ Fmul(d8, d29, d31); |
5039 __ Fmul(d7, d26, d26); | 5057 __ Fmul(d9, d26, d26); |
5040 __ Fmul(d8, d27, d30); | 5058 __ Fmul(d10, d27, d30); |
5041 __ Fmul(d9, d28, d30); | 5059 __ Fmul(d11, d28, d30); |
| 5060 __ Fmul(d12, d27, d29); |
| 5061 __ Fmul(d13, d29, d28); |
5042 END(); | 5062 END(); |
5043 | 5063 |
5044 RUN(); | 5064 RUN(); |
5045 | 5065 |
5046 ASSERT_EQUAL_FP32(6.5, s0); | 5066 ASSERT_EQUAL_FP32(6.5, s0); |
5047 ASSERT_EQUAL_FP32(0.0, s1); | 5067 ASSERT_EQUAL_FP32(0.0, s1); |
5048 ASSERT_EQUAL_FP32(0.0, s2); | 5068 ASSERT_EQUAL_FP32(0.0, s2); |
5049 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3); | 5069 ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3); |
5050 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4); | 5070 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4); |
5051 ASSERT_EQUAL_FP64(-4.5, d5); | 5071 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5); |
5052 ASSERT_EQUAL_FP64(0.0, d6); | 5072 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6); |
5053 ASSERT_EQUAL_FP64(0.0, d7); | 5073 ASSERT_EQUAL_FP64(-4.5, d7); |
5054 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8); | 5074 ASSERT_EQUAL_FP64(0.0, d8); |
5055 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d9); | 5075 ASSERT_EQUAL_FP64(0.0, d9); |
| 5076 ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10); |
| 5077 ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11); |
| 5078 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12); |
| 5079 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13); |
5056 | 5080 |
5057 TEARDOWN(); | 5081 TEARDOWN(); |
5058 } | 5082 } |
5059 | 5083 |
5060 | 5084 |
5061 static void FmaddFmsubDoubleHelper(double n, double m, double a, | 5085 static void FmaddFmsubHelper(double n, double m, double a, |
5062 double fmadd, double fmsub) { | 5086 double fmadd, double fmsub, |
| 5087 double fnmadd, double fnmsub) { |
5063 SETUP(); | 5088 SETUP(); |
5064 START(); | 5089 START(); |
5065 | 5090 |
5066 __ Fmov(d0, n); | 5091 __ Fmov(d0, n); |
5067 __ Fmov(d1, m); | 5092 __ Fmov(d1, m); |
5068 __ Fmov(d2, a); | 5093 __ Fmov(d2, a); |
5069 __ Fmadd(d28, d0, d1, d2); | 5094 __ Fmadd(d28, d0, d1, d2); |
5070 __ Fmsub(d29, d0, d1, d2); | 5095 __ Fmsub(d29, d0, d1, d2); |
5071 __ Fnmadd(d30, d0, d1, d2); | 5096 __ Fnmadd(d30, d0, d1, d2); |
5072 __ Fnmsub(d31, d0, d1, d2); | 5097 __ Fnmsub(d31, d0, d1, d2); |
5073 | 5098 |
5074 END(); | 5099 END(); |
5075 RUN(); | 5100 RUN(); |
5076 | 5101 |
5077 ASSERT_EQUAL_FP64(fmadd, d28); | 5102 ASSERT_EQUAL_FP64(fmadd, d28); |
5078 ASSERT_EQUAL_FP64(fmsub, d29); | 5103 ASSERT_EQUAL_FP64(fmsub, d29); |
5079 ASSERT_EQUAL_FP64(-fmadd, d30); | 5104 ASSERT_EQUAL_FP64(fnmadd, d30); |
5080 ASSERT_EQUAL_FP64(-fmsub, d31); | 5105 ASSERT_EQUAL_FP64(fnmsub, d31); |
5081 | 5106 |
5082 TEARDOWN(); | 5107 TEARDOWN(); |
5083 } | 5108 } |
5084 | 5109 |
5085 | 5110 |
5086 TEST(fmadd_fmsub_double) { | 5111 TEST(fmadd_fmsub_double) { |
5087 INIT_V8(); | 5112 INIT_V8(); |
5088 double inputs[] = { | |
5089 // Normal numbers, including -0.0. | |
5090 DBL_MAX, DBL_MIN, 3.25, 2.0, 0.0, | |
5091 -DBL_MAX, -DBL_MIN, -3.25, -2.0, -0.0, | |
5092 // Infinities. | |
5093 kFP64NegativeInfinity, kFP64PositiveInfinity, | |
5094 // Subnormal numbers. | |
5095 rawbits_to_double(0x000fffffffffffff), | |
5096 rawbits_to_double(0x0000000000000001), | |
5097 rawbits_to_double(0x000123456789abcd), | |
5098 -rawbits_to_double(0x000fffffffffffff), | |
5099 -rawbits_to_double(0x0000000000000001), | |
5100 -rawbits_to_double(0x000123456789abcd), | |
5101 // NaN. | |
5102 kFP64QuietNaN, | |
5103 -kFP64QuietNaN, | |
5104 }; | |
5105 const int count = sizeof(inputs) / sizeof(inputs[0]); | |
5106 | 5113 |
5107 for (int in = 0; in < count; in++) { | 5114 // It's hard to check the result of fused operations because the only way to |
5108 double n = inputs[in]; | 5115 // calculate the result is using fma, which is what the simulator uses anyway. |
5109 for (int im = 0; im < count; im++) { | 5116 // TODO(jbramley): Add tests to check behaviour against a hardware trace. |
5110 double m = inputs[im]; | |
5111 for (int ia = 0; ia < count; ia++) { | |
5112 double a = inputs[ia]; | |
5113 double fmadd = fma(n, m, a); | |
5114 double fmsub = fma(-n, m, a); | |
5115 | 5117 |
5116 FmaddFmsubDoubleHelper(n, m, a, fmadd, fmsub); | 5118 // Basic operation. |
5117 } | 5119 FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0); |
5118 } | 5120 FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0); |
5119 } | 5121 |
| 5122 // Check the sign of exact zeroes. |
| 5123 // n m a fmadd fmsub fnmadd fnmsub |
| 5124 FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0, +0.0, +0.0, +0.0); |
| 5125 FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0, -0.0, +0.0, +0.0); |
| 5126 FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0, +0.0, -0.0, +0.0); |
| 5127 FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, -0.0); |
| 5128 FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0); |
| 5129 FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0, -0.0, +0.0, +0.0); |
| 5130 FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0, +0.0, -0.0, +0.0); |
| 5131 FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0, +0.0, +0.0, -0.0); |
| 5132 |
| 5133 // Check NaN generation. |
| 5134 FmaddFmsubHelper(kFP64PositiveInfinity, 0.0, 42.0, |
| 5135 kFP64DefaultNaN, kFP64DefaultNaN, |
| 5136 kFP64DefaultNaN, kFP64DefaultNaN); |
| 5137 FmaddFmsubHelper(0.0, kFP64PositiveInfinity, 42.0, |
| 5138 kFP64DefaultNaN, kFP64DefaultNaN, |
| 5139 kFP64DefaultNaN, kFP64DefaultNaN); |
| 5140 FmaddFmsubHelper(kFP64PositiveInfinity, 1.0, kFP64PositiveInfinity, |
| 5141 kFP64PositiveInfinity, // inf + ( inf * 1) = inf |
| 5142 kFP64DefaultNaN, // inf + (-inf * 1) = NaN |
| 5143 kFP64NegativeInfinity, // -inf + (-inf * 1) = -inf |
| 5144 kFP64DefaultNaN); // -inf + ( inf * 1) = NaN |
| 5145 FmaddFmsubHelper(kFP64NegativeInfinity, 1.0, kFP64PositiveInfinity, |
| 5146 kFP64DefaultNaN, // inf + (-inf * 1) = NaN |
| 5147 kFP64PositiveInfinity, // inf + ( inf * 1) = inf |
| 5148 kFP64DefaultNaN, // -inf + ( inf * 1) = NaN |
| 5149 kFP64NegativeInfinity); // -inf + (-inf * 1) = -inf |
5120 } | 5150 } |
5121 | 5151 |
5122 | 5152 |
5123 TEST(fmadd_fmsub_double_rounding) { | 5153 static void FmaddFmsubHelper(float n, float m, float a, |
5124 INIT_V8(); | 5154 float fmadd, float fmsub, |
5125 // Make sure we run plenty of tests where an intermediate rounding stage would | 5155 float fnmadd, float fnmsub) { |
5126 // produce an incorrect result. | |
5127 const int limit = 1000; | |
5128 int count_fmadd = 0; | |
5129 int count_fmsub = 0; | |
5130 | |
5131 uint16_t seed[3] = {42, 43, 44}; | |
5132 seed48(seed); | |
5133 | |
5134 while ((count_fmadd < limit) || (count_fmsub < limit)) { | |
5135 double n, m, a; | |
5136 uint32_t r[2]; | |
5137 ASSERT(sizeof(r) == sizeof(n)); | |
5138 | |
5139 r[0] = mrand48(); | |
5140 r[1] = mrand48(); | |
5141 memcpy(&n, r, sizeof(r)); | |
5142 r[0] = mrand48(); | |
5143 r[1] = mrand48(); | |
5144 memcpy(&m, r, sizeof(r)); | |
5145 r[0] = mrand48(); | |
5146 r[1] = mrand48(); | |
5147 memcpy(&a, r, sizeof(r)); | |
5148 | |
5149 if (!std::isfinite(a) || !std::isfinite(n) || !std::isfinite(m)) { | |
5150 continue; | |
5151 } | |
5152 | |
5153 // Calculate the expected results. | |
5154 double fmadd = fma(n, m, a); | |
5155 double fmsub = fma(-n, m, a); | |
5156 | |
5157 bool test_fmadd = (fmadd != (a + n * m)); | |
5158 bool test_fmsub = (fmsub != (a - n * m)); | |
5159 | |
5160 // If rounding would produce a different result, increment the test count. | |
5161 count_fmadd += test_fmadd; | |
5162 count_fmsub += test_fmsub; | |
5163 | |
5164 if (test_fmadd || test_fmsub) { | |
5165 FmaddFmsubDoubleHelper(n, m, a, fmadd, fmsub); | |
5166 } | |
5167 } | |
5168 } | |
5169 | |
5170 | |
5171 static void FmaddFmsubFloatHelper(float n, float m, float a, | |
5172 float fmadd, float fmsub) { | |
5173 SETUP(); | 5156 SETUP(); |
5174 START(); | 5157 START(); |
5175 | 5158 |
5176 __ Fmov(s0, n); | 5159 __ Fmov(s0, n); |
5177 __ Fmov(s1, m); | 5160 __ Fmov(s1, m); |
5178 __ Fmov(s2, a); | 5161 __ Fmov(s2, a); |
5179 __ Fmadd(s30, s0, s1, s2); | 5162 __ Fmadd(s28, s0, s1, s2); |
5180 __ Fmsub(s31, s0, s1, s2); | 5163 __ Fmsub(s29, s0, s1, s2); |
| 5164 __ Fnmadd(s30, s0, s1, s2); |
| 5165 __ Fnmsub(s31, s0, s1, s2); |
5181 | 5166 |
5182 END(); | 5167 END(); |
5183 RUN(); | 5168 RUN(); |
5184 | 5169 |
5185 ASSERT_EQUAL_FP32(fmadd, s30); | 5170 ASSERT_EQUAL_FP32(fmadd, s28); |
5186 ASSERT_EQUAL_FP32(fmsub, s31); | 5171 ASSERT_EQUAL_FP32(fmsub, s29); |
| 5172 ASSERT_EQUAL_FP32(fnmadd, s30); |
| 5173 ASSERT_EQUAL_FP32(fnmsub, s31); |
5187 | 5174 |
5188 TEARDOWN(); | 5175 TEARDOWN(); |
5189 } | 5176 } |
5190 | 5177 |
5191 | 5178 |
5192 TEST(fmadd_fmsub_float) { | 5179 TEST(fmadd_fmsub_float) { |
5193 INIT_V8(); | 5180 INIT_V8(); |
5194 float inputs[] = { | 5181 // It's hard to check the result of fused operations because the only way to |
5195 // Normal numbers, including -0.0f. | 5182 // calculate the result is using fma, which is what the simulator uses anyway. |
5196 FLT_MAX, FLT_MIN, 3.25f, 2.0f, 0.0f, | 5183 // TODO(jbramley): Add tests to check behaviour against a hardware trace. |
5197 -FLT_MAX, -FLT_MIN, -3.25f, -2.0f, -0.0f, | |
5198 // Infinities. | |
5199 kFP32NegativeInfinity, kFP32PositiveInfinity, | |
5200 // Subnormal numbers. | |
5201 rawbits_to_float(0x07ffffff), | |
5202 rawbits_to_float(0x00000001), | |
5203 rawbits_to_float(0x01234567), | |
5204 -rawbits_to_float(0x07ffffff), | |
5205 -rawbits_to_float(0x00000001), | |
5206 -rawbits_to_float(0x01234567), | |
5207 // NaN. | |
5208 kFP32QuietNaN, | |
5209 -kFP32QuietNaN, | |
5210 }; | |
5211 const int count = sizeof(inputs) / sizeof(inputs[0]); | |
5212 | 5184 |
5213 for (int in = 0; in < count; in++) { | 5185 // Basic operation. |
5214 float n = inputs[in]; | 5186 FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f); |
5215 for (int im = 0; im < count; im++) { | 5187 FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f); |
5216 float m = inputs[im]; | |
5217 for (int ia = 0; ia < count; ia++) { | |
5218 float a = inputs[ia]; | |
5219 float fmadd = fmaf(n, m, a); | |
5220 float fmsub = fmaf(-n, m, a); | |
5221 | 5188 |
5222 FmaddFmsubFloatHelper(n, m, a, fmadd, fmsub); | 5189 // Check the sign of exact zeroes. |
5223 } | 5190 // n m a fmadd fmsub fnmadd fnmsub |
5224 } | 5191 FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f); |
5225 } | 5192 FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f); |
| 5193 FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f); |
| 5194 FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f); |
| 5195 FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f); |
| 5196 FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f); |
| 5197 FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f); |
| 5198 FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f); |
| 5199 |
| 5200 // Check NaN generation. |
| 5201 FmaddFmsubHelper(kFP32PositiveInfinity, 0.0f, 42.0f, |
| 5202 kFP32DefaultNaN, kFP32DefaultNaN, |
| 5203 kFP32DefaultNaN, kFP32DefaultNaN); |
| 5204 FmaddFmsubHelper(0.0f, kFP32PositiveInfinity, 42.0f, |
| 5205 kFP32DefaultNaN, kFP32DefaultNaN, |
| 5206 kFP32DefaultNaN, kFP32DefaultNaN); |
| 5207 FmaddFmsubHelper(kFP32PositiveInfinity, 1.0f, kFP32PositiveInfinity, |
| 5208 kFP32PositiveInfinity, // inf + ( inf * 1) = inf |
| 5209 kFP32DefaultNaN, // inf + (-inf * 1) = NaN |
| 5210 kFP32NegativeInfinity, // -inf + (-inf * 1) = -inf |
| 5211 kFP32DefaultNaN); // -inf + ( inf * 1) = NaN |
| 5212 FmaddFmsubHelper(kFP32NegativeInfinity, 1.0f, kFP32PositiveInfinity, |
| 5213 kFP32DefaultNaN, // inf + (-inf * 1) = NaN |
| 5214 kFP32PositiveInfinity, // inf + ( inf * 1) = inf |
| 5215 kFP32DefaultNaN, // -inf + ( inf * 1) = NaN |
| 5216 kFP32NegativeInfinity); // -inf + (-inf * 1) = -inf |
5226 } | 5217 } |
5227 | 5218 |
5228 | 5219 |
5229 TEST(fmadd_fmsub_float_rounding) { | 5220 TEST(fmadd_fmsub_double_nans) { |
5230 INIT_V8(); | 5221 INIT_V8(); |
5231 // Make sure we run plenty of tests where an intermediate rounding stage would | 5222 // Make sure that NaN propagation works correctly. |
5232 // produce an incorrect result. | 5223 double s1 = rawbits_to_double(0x7ff5555511111111); |
5233 const int limit = 1000; | 5224 double s2 = rawbits_to_double(0x7ff5555522222222); |
5234 int count_fmadd = 0; | 5225 double sa = rawbits_to_double(0x7ff55555aaaaaaaa); |
5235 int count_fmsub = 0; | 5226 double q1 = rawbits_to_double(0x7ffaaaaa11111111); |
| 5227 double q2 = rawbits_to_double(0x7ffaaaaa22222222); |
| 5228 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa); |
| 5229 ASSERT(IsSignallingNaN(s1)); |
| 5230 ASSERT(IsSignallingNaN(s2)); |
| 5231 ASSERT(IsSignallingNaN(sa)); |
| 5232 ASSERT(IsQuietNaN(q1)); |
| 5233 ASSERT(IsQuietNaN(q2)); |
| 5234 ASSERT(IsQuietNaN(qa)); |
5236 | 5235 |
5237 uint16_t seed[3] = {42, 43, 44}; | 5236 // The input NaNs after passing through ProcessNaN. |
5238 seed48(seed); | 5237 double s1_proc = rawbits_to_double(0x7ffd555511111111); |
| 5238 double s2_proc = rawbits_to_double(0x7ffd555522222222); |
| 5239 double sa_proc = rawbits_to_double(0x7ffd5555aaaaaaaa); |
| 5240 double q1_proc = q1; |
| 5241 double q2_proc = q2; |
| 5242 double qa_proc = qa; |
| 5243 ASSERT(IsQuietNaN(s1_proc)); |
| 5244 ASSERT(IsQuietNaN(s2_proc)); |
| 5245 ASSERT(IsQuietNaN(sa_proc)); |
| 5246 ASSERT(IsQuietNaN(q1_proc)); |
| 5247 ASSERT(IsQuietNaN(q2_proc)); |
| 5248 ASSERT(IsQuietNaN(qa_proc)); |
5239 | 5249 |
5240 while ((count_fmadd < limit) || (count_fmsub < limit)) { | 5250 // Quiet NaNs are propagated. |
5241 float n, m, a; | 5251 FmaddFmsubHelper(q1, 0, 0, q1_proc, -q1_proc, -q1_proc, q1_proc); |
5242 uint32_t r; | 5252 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc); |
5243 ASSERT(sizeof(r) == sizeof(n)); | 5253 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
| 5254 FmaddFmsubHelper(q1, q2, 0, q1_proc, -q1_proc, -q1_proc, q1_proc); |
| 5255 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
| 5256 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
| 5257 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
5244 | 5258 |
5245 r = mrand48(); | 5259 // Signalling NaNs are propagated, and made quiet. |
5246 memcpy(&n, &r, sizeof(r)); | 5260 FmaddFmsubHelper(s1, 0, 0, s1_proc, -s1_proc, -s1_proc, s1_proc); |
5247 r = mrand48(); | 5261 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc); |
5248 memcpy(&m, &r, sizeof(r)); | 5262 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
5249 r = mrand48(); | 5263 FmaddFmsubHelper(s1, s2, 0, s1_proc, -s1_proc, -s1_proc, s1_proc); |
5250 memcpy(&a, &r, sizeof(r)); | 5264 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5265 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5266 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
5251 | 5267 |
5252 if (!std::isfinite(a) || !std::isfinite(n) || !std::isfinite(m)) { | 5268 // Signalling NaNs take precedence over quiet NaNs. |
5253 continue; | 5269 FmaddFmsubHelper(s1, q2, qa, s1_proc, -s1_proc, -s1_proc, s1_proc); |
5254 } | 5270 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc); |
| 5271 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5272 FmaddFmsubHelper(s1, s2, qa, s1_proc, -s1_proc, -s1_proc, s1_proc); |
| 5273 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5274 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5275 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
5255 | 5276 |
5256 // Calculate the expected results. | 5277 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a. |
5257 float fmadd = fmaf(n, m, a); | 5278 FmaddFmsubHelper(0, kFP64PositiveInfinity, qa, |
5258 float fmsub = fmaf(-n, m, a); | 5279 kFP64DefaultNaN, kFP64DefaultNaN, |
5259 | 5280 kFP64DefaultNaN, kFP64DefaultNaN); |
5260 bool test_fmadd = (fmadd != (a + n * m)); | 5281 FmaddFmsubHelper(kFP64PositiveInfinity, 0, qa, |
5261 bool test_fmsub = (fmsub != (a - n * m)); | 5282 kFP64DefaultNaN, kFP64DefaultNaN, |
5262 | 5283 kFP64DefaultNaN, kFP64DefaultNaN); |
5263 // If rounding would produce a different result, increment the test count. | 5284 FmaddFmsubHelper(0, kFP64NegativeInfinity, qa, |
5264 count_fmadd += test_fmadd; | 5285 kFP64DefaultNaN, kFP64DefaultNaN, |
5265 count_fmsub += test_fmsub; | 5286 kFP64DefaultNaN, kFP64DefaultNaN); |
5266 | 5287 FmaddFmsubHelper(kFP64NegativeInfinity, 0, qa, |
5267 if (test_fmadd || test_fmsub) { | 5288 kFP64DefaultNaN, kFP64DefaultNaN, |
5268 FmaddFmsubFloatHelper(n, m, a, fmadd, fmsub); | 5289 kFP64DefaultNaN, kFP64DefaultNaN); |
5269 } | |
5270 } | |
5271 } | 5290 } |
5272 | 5291 |
5273 | 5292 |
| 5293 TEST(fmadd_fmsub_float_nans) { |
| 5294 INIT_V8(); |
| 5295 // Make sure that NaN propagation works correctly. |
| 5296 float s1 = rawbits_to_float(0x7f951111); |
| 5297 float s2 = rawbits_to_float(0x7f952222); |
| 5298 float sa = rawbits_to_float(0x7f95aaaa); |
| 5299 float q1 = rawbits_to_float(0x7fea1111); |
| 5300 float q2 = rawbits_to_float(0x7fea2222); |
| 5301 float qa = rawbits_to_float(0x7feaaaaa); |
| 5302 ASSERT(IsSignallingNaN(s1)); |
| 5303 ASSERT(IsSignallingNaN(s2)); |
| 5304 ASSERT(IsSignallingNaN(sa)); |
| 5305 ASSERT(IsQuietNaN(q1)); |
| 5306 ASSERT(IsQuietNaN(q2)); |
| 5307 ASSERT(IsQuietNaN(qa)); |
| 5308 |
| 5309 // The input NaNs after passing through ProcessNaN. |
| 5310 float s1_proc = rawbits_to_float(0x7fd51111); |
| 5311 float s2_proc = rawbits_to_float(0x7fd52222); |
| 5312 float sa_proc = rawbits_to_float(0x7fd5aaaa); |
| 5313 float q1_proc = q1; |
| 5314 float q2_proc = q2; |
| 5315 float qa_proc = qa; |
| 5316 ASSERT(IsQuietNaN(s1_proc)); |
| 5317 ASSERT(IsQuietNaN(s2_proc)); |
| 5318 ASSERT(IsQuietNaN(sa_proc)); |
| 5319 ASSERT(IsQuietNaN(q1_proc)); |
| 5320 ASSERT(IsQuietNaN(q2_proc)); |
| 5321 ASSERT(IsQuietNaN(qa_proc)); |
| 5322 |
| 5323 // Quiet NaNs are propagated. |
| 5324 FmaddFmsubHelper(q1, 0, 0, q1_proc, -q1_proc, -q1_proc, q1_proc); |
| 5325 FmaddFmsubHelper(0, q2, 0, q2_proc, q2_proc, q2_proc, q2_proc); |
| 5326 FmaddFmsubHelper(0, 0, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
| 5327 FmaddFmsubHelper(q1, q2, 0, q1_proc, -q1_proc, -q1_proc, q1_proc); |
| 5328 FmaddFmsubHelper(0, q2, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
| 5329 FmaddFmsubHelper(q1, 0, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
| 5330 FmaddFmsubHelper(q1, q2, qa, qa_proc, qa_proc, -qa_proc, -qa_proc); |
| 5331 |
| 5332 // Signalling NaNs are propagated, and made quiet. |
| 5333 FmaddFmsubHelper(s1, 0, 0, s1_proc, -s1_proc, -s1_proc, s1_proc); |
| 5334 FmaddFmsubHelper(0, s2, 0, s2_proc, s2_proc, s2_proc, s2_proc); |
| 5335 FmaddFmsubHelper(0, 0, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5336 FmaddFmsubHelper(s1, s2, 0, s1_proc, -s1_proc, -s1_proc, s1_proc); |
| 5337 FmaddFmsubHelper(0, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5338 FmaddFmsubHelper(s1, 0, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5339 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5340 |
| 5341 // Signalling NaNs take precedence over quiet NaNs. |
| 5342 FmaddFmsubHelper(s1, q2, qa, s1_proc, -s1_proc, -s1_proc, s1_proc); |
| 5343 FmaddFmsubHelper(q1, s2, qa, s2_proc, s2_proc, s2_proc, s2_proc); |
| 5344 FmaddFmsubHelper(q1, q2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5345 FmaddFmsubHelper(s1, s2, qa, s1_proc, -s1_proc, -s1_proc, s1_proc); |
| 5346 FmaddFmsubHelper(q1, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5347 FmaddFmsubHelper(s1, q2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5348 FmaddFmsubHelper(s1, s2, sa, sa_proc, sa_proc, -sa_proc, -sa_proc); |
| 5349 |
| 5350 // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a. |
| 5351 FmaddFmsubHelper(0, kFP32PositiveInfinity, qa, |
| 5352 kFP32DefaultNaN, kFP32DefaultNaN, |
| 5353 kFP32DefaultNaN, kFP32DefaultNaN); |
| 5354 FmaddFmsubHelper(kFP32PositiveInfinity, 0, qa, |
| 5355 kFP32DefaultNaN, kFP32DefaultNaN, |
| 5356 kFP32DefaultNaN, kFP32DefaultNaN); |
| 5357 FmaddFmsubHelper(0, kFP32NegativeInfinity, qa, |
| 5358 kFP32DefaultNaN, kFP32DefaultNaN, |
| 5359 kFP32DefaultNaN, kFP32DefaultNaN); |
| 5360 FmaddFmsubHelper(kFP32NegativeInfinity, 0, qa, |
| 5361 kFP32DefaultNaN, kFP32DefaultNaN, |
| 5362 kFP32DefaultNaN, kFP32DefaultNaN); |
| 5363 } |
| 5364 |
| 5365 |
5274 TEST(fdiv) { | 5366 TEST(fdiv) { |
5275 INIT_V8(); | 5367 INIT_V8(); |
5276 SETUP(); | 5368 SETUP(); |
5277 | 5369 |
5278 START(); | 5370 START(); |
5279 __ Fmov(s13, -0.0); | 5371 __ Fmov(s14, -0.0f); |
5280 __ Fmov(s14, kFP32PositiveInfinity); | 5372 __ Fmov(s15, kFP32PositiveInfinity); |
5281 __ Fmov(s15, kFP32NegativeInfinity); | 5373 __ Fmov(s16, kFP32NegativeInfinity); |
5282 __ Fmov(s16, 3.25); | 5374 __ Fmov(s17, 3.25f); |
5283 __ Fmov(s17, 2.0); | 5375 __ Fmov(s18, 2.0f); |
5284 __ Fmov(s18, 2.0); | 5376 __ Fmov(s19, 2.0f); |
5285 __ Fmov(s19, -2.0); | 5377 __ Fmov(s20, -2.0f); |
5286 | 5378 |
5287 __ Fmov(d26, -0.0); | 5379 __ Fmov(d26, -0.0); |
5288 __ Fmov(d27, kFP64PositiveInfinity); | 5380 __ Fmov(d27, kFP64PositiveInfinity); |
5289 __ Fmov(d28, kFP64NegativeInfinity); | 5381 __ Fmov(d28, kFP64NegativeInfinity); |
5290 __ Fmov(d29, 0); | 5382 __ Fmov(d29, 0.0); |
5291 __ Fmov(d30, -2.0); | 5383 __ Fmov(d30, -2.0); |
5292 __ Fmov(d31, 2.25); | 5384 __ Fmov(d31, 2.25); |
5293 | 5385 |
5294 __ Fdiv(s0, s16, s17); | 5386 __ Fdiv(s0, s17, s18); |
5295 __ Fdiv(s1, s17, s18); | 5387 __ Fdiv(s1, s18, s19); |
5296 __ Fdiv(s2, s13, s17); | 5388 __ Fdiv(s2, s14, s18); |
5297 __ Fdiv(s3, s17, s14); | 5389 __ Fdiv(s3, s18, s15); |
5298 __ Fdiv(s4, s17, s15); | 5390 __ Fdiv(s4, s18, s16); |
5299 __ Fdiv(d5, d31, d30); | 5391 __ Fdiv(s5, s15, s16); |
5300 __ Fdiv(d6, d29, d31); | 5392 __ Fdiv(s6, s14, s14); |
5301 __ Fdiv(d7, d26, d31); | 5393 |
5302 __ Fdiv(d8, d31, d27); | 5394 __ Fdiv(d7, d31, d30); |
5303 __ Fdiv(d9, d31, d28); | 5395 __ Fdiv(d8, d29, d31); |
| 5396 __ Fdiv(d9, d26, d31); |
| 5397 __ Fdiv(d10, d31, d27); |
| 5398 __ Fdiv(d11, d31, d28); |
| 5399 __ Fdiv(d12, d28, d27); |
| 5400 __ Fdiv(d13, d29, d29); |
5304 END(); | 5401 END(); |
5305 | 5402 |
5306 RUN(); | 5403 RUN(); |
5307 | 5404 |
5308 ASSERT_EQUAL_FP32(1.625, s0); | 5405 ASSERT_EQUAL_FP32(1.625f, s0); |
5309 ASSERT_EQUAL_FP32(1.0, s1); | 5406 ASSERT_EQUAL_FP32(1.0f, s1); |
5310 ASSERT_EQUAL_FP32(-0.0, s2); | 5407 ASSERT_EQUAL_FP32(-0.0f, s2); |
5311 ASSERT_EQUAL_FP32(0.0, s3); | 5408 ASSERT_EQUAL_FP32(0.0f, s3); |
5312 ASSERT_EQUAL_FP32(-0.0, s4); | 5409 ASSERT_EQUAL_FP32(-0.0f, s4); |
5313 ASSERT_EQUAL_FP64(-1.125, d5); | 5410 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5); |
5314 ASSERT_EQUAL_FP64(0.0, d6); | 5411 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6); |
5315 ASSERT_EQUAL_FP64(-0.0, d7); | 5412 ASSERT_EQUAL_FP64(-1.125, d7); |
5316 ASSERT_EQUAL_FP64(0.0, d8); | 5413 ASSERT_EQUAL_FP64(0.0, d8); |
5317 ASSERT_EQUAL_FP64(-0.0, d9); | 5414 ASSERT_EQUAL_FP64(-0.0, d9); |
| 5415 ASSERT_EQUAL_FP64(0.0, d10); |
| 5416 ASSERT_EQUAL_FP64(-0.0, d11); |
| 5417 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12); |
| 5418 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13); |
5318 | 5419 |
5319 TEARDOWN(); | 5420 TEARDOWN(); |
5320 } | 5421 } |
5321 | 5422 |
5322 | 5423 |
5323 static float MinMaxHelper(float n, | 5424 static float MinMaxHelper(float n, |
5324 float m, | 5425 float m, |
5325 bool min, | 5426 bool min, |
5326 float quiet_nan_substitute = 0.0) { | 5427 float quiet_nan_substitute = 0.0) { |
5327 const uint64_t kFP32QuietNaNMask = 0x00400000UL; | |
5328 uint32_t raw_n = float_to_rawbits(n); | 5428 uint32_t raw_n = float_to_rawbits(n); |
5329 uint32_t raw_m = float_to_rawbits(m); | 5429 uint32_t raw_m = float_to_rawbits(m); |
5330 | 5430 |
5331 if (std::isnan(n) && ((raw_n & kFP32QuietNaNMask) == 0)) { | 5431 if (std::isnan(n) && ((raw_n & kSQuietNanMask) == 0)) { |
5332 // n is signalling NaN. | 5432 // n is signalling NaN. |
5333 return n; | 5433 return rawbits_to_float(raw_n | kSQuietNanMask); |
5334 } else if (std::isnan(m) && ((raw_m & kFP32QuietNaNMask) == 0)) { | 5434 } else if (std::isnan(m) && ((raw_m & kSQuietNanMask) == 0)) { |
5335 // m is signalling NaN. | 5435 // m is signalling NaN. |
5336 return m; | 5436 return rawbits_to_float(raw_m | kSQuietNanMask); |
5337 } else if (quiet_nan_substitute == 0.0) { | 5437 } else if (quiet_nan_substitute == 0.0) { |
5338 if (std::isnan(n)) { | 5438 if (std::isnan(n)) { |
5339 // n is quiet NaN. | 5439 // n is quiet NaN. |
5340 return n; | 5440 return n; |
5341 } else if (std::isnan(m)) { | 5441 } else if (std::isnan(m)) { |
5342 // m is quiet NaN. | 5442 // m is quiet NaN. |
5343 return m; | 5443 return m; |
5344 } | 5444 } |
5345 } else { | 5445 } else { |
5346 // Substitute n or m if one is quiet, but not both. | 5446 // Substitute n or m if one is quiet, but not both. |
(...skipping 12 matching lines...) Expand all Loading... |
5359 } | 5459 } |
5360 | 5460 |
5361 return min ? fminf(n, m) : fmaxf(n, m); | 5461 return min ? fminf(n, m) : fmaxf(n, m); |
5362 } | 5462 } |
5363 | 5463 |
5364 | 5464 |
5365 static double MinMaxHelper(double n, | 5465 static double MinMaxHelper(double n, |
5366 double m, | 5466 double m, |
5367 bool min, | 5467 bool min, |
5368 double quiet_nan_substitute = 0.0) { | 5468 double quiet_nan_substitute = 0.0) { |
5369 const uint64_t kFP64QuietNaNMask = 0x0008000000000000UL; | |
5370 uint64_t raw_n = double_to_rawbits(n); | 5469 uint64_t raw_n = double_to_rawbits(n); |
5371 uint64_t raw_m = double_to_rawbits(m); | 5470 uint64_t raw_m = double_to_rawbits(m); |
5372 | 5471 |
5373 if (std::isnan(n) && ((raw_n & kFP64QuietNaNMask) == 0)) { | 5472 if (std::isnan(n) && ((raw_n & kDQuietNanMask) == 0)) { |
5374 // n is signalling NaN. | 5473 // n is signalling NaN. |
5375 return n; | 5474 return rawbits_to_double(raw_n | kDQuietNanMask); |
5376 } else if (std::isnan(m) && ((raw_m & kFP64QuietNaNMask) == 0)) { | 5475 } else if (std::isnan(m) && ((raw_m & kDQuietNanMask) == 0)) { |
5377 // m is signalling NaN. | 5476 // m is signalling NaN. |
5378 return m; | 5477 return rawbits_to_double(raw_m | kDQuietNanMask); |
5379 } else if (quiet_nan_substitute == 0.0) { | 5478 } else if (quiet_nan_substitute == 0.0) { |
5380 if (std::isnan(n)) { | 5479 if (std::isnan(n)) { |
5381 // n is quiet NaN. | 5480 // n is quiet NaN. |
5382 return n; | 5481 return n; |
5383 } else if (std::isnan(m)) { | 5482 } else if (std::isnan(m)) { |
5384 // m is quiet NaN. | 5483 // m is quiet NaN. |
5385 return m; | 5484 return m; |
5386 } | 5485 } |
5387 } else { | 5486 } else { |
5388 // Substitute n or m if one is quiet, but not both. | 5487 // Substitute n or m if one is quiet, but not both. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5423 ASSERT_EQUAL_FP64(max, d29); | 5522 ASSERT_EQUAL_FP64(max, d29); |
5424 ASSERT_EQUAL_FP64(minnm, d30); | 5523 ASSERT_EQUAL_FP64(minnm, d30); |
5425 ASSERT_EQUAL_FP64(maxnm, d31); | 5524 ASSERT_EQUAL_FP64(maxnm, d31); |
5426 | 5525 |
5427 TEARDOWN(); | 5526 TEARDOWN(); |
5428 } | 5527 } |
5429 | 5528 |
5430 | 5529 |
5431 TEST(fmax_fmin_d) { | 5530 TEST(fmax_fmin_d) { |
5432 INIT_V8(); | 5531 INIT_V8(); |
| 5532 // Use non-standard NaNs to check that the payload bits are preserved. |
| 5533 double snan = rawbits_to_double(0x7ff5555512345678); |
| 5534 double qnan = rawbits_to_double(0x7ffaaaaa87654321); |
| 5535 |
| 5536 double snan_processed = rawbits_to_double(0x7ffd555512345678); |
| 5537 double qnan_processed = qnan; |
| 5538 |
| 5539 ASSERT(IsSignallingNaN(snan)); |
| 5540 ASSERT(IsQuietNaN(qnan)); |
| 5541 ASSERT(IsQuietNaN(snan_processed)); |
| 5542 ASSERT(IsQuietNaN(qnan_processed)); |
| 5543 |
5433 // Bootstrap tests. | 5544 // Bootstrap tests. |
5434 FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0); | 5545 FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0); |
5435 FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1); | 5546 FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1); |
5436 FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity, | 5547 FminFmaxDoubleHelper(kFP64PositiveInfinity, kFP64NegativeInfinity, |
5437 kFP64NegativeInfinity, kFP64PositiveInfinity, | 5548 kFP64NegativeInfinity, kFP64PositiveInfinity, |
5438 kFP64NegativeInfinity, kFP64PositiveInfinity); | 5549 kFP64NegativeInfinity, kFP64PositiveInfinity); |
5439 FminFmaxDoubleHelper(kFP64SignallingNaN, 0, | 5550 FminFmaxDoubleHelper(snan, 0, |
5440 kFP64SignallingNaN, kFP64SignallingNaN, | 5551 snan_processed, snan_processed, |
5441 kFP64SignallingNaN, kFP64SignallingNaN); | 5552 snan_processed, snan_processed); |
5442 FminFmaxDoubleHelper(kFP64QuietNaN, 0, | 5553 FminFmaxDoubleHelper(0, snan, |
5443 kFP64QuietNaN, kFP64QuietNaN, | 5554 snan_processed, snan_processed, |
| 5555 snan_processed, snan_processed); |
| 5556 FminFmaxDoubleHelper(qnan, 0, |
| 5557 qnan_processed, qnan_processed, |
5444 0, 0); | 5558 0, 0); |
5445 FminFmaxDoubleHelper(kFP64QuietNaN, kFP64SignallingNaN, | 5559 FminFmaxDoubleHelper(0, qnan, |
5446 kFP64SignallingNaN, kFP64SignallingNaN, | 5560 qnan_processed, qnan_processed, |
5447 kFP64SignallingNaN, kFP64SignallingNaN); | 5561 0, 0); |
| 5562 FminFmaxDoubleHelper(qnan, snan, |
| 5563 snan_processed, snan_processed, |
| 5564 snan_processed, snan_processed); |
| 5565 FminFmaxDoubleHelper(snan, qnan, |
| 5566 snan_processed, snan_processed, |
| 5567 snan_processed, snan_processed); |
5448 | 5568 |
5449 // Iterate over all combinations of inputs. | 5569 // Iterate over all combinations of inputs. |
5450 double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0, | 5570 double inputs[] = { DBL_MAX, DBL_MIN, 1.0, 0.0, |
5451 -DBL_MAX, -DBL_MIN, -1.0, -0.0, | 5571 -DBL_MAX, -DBL_MIN, -1.0, -0.0, |
5452 kFP64PositiveInfinity, kFP64NegativeInfinity, | 5572 kFP64PositiveInfinity, kFP64NegativeInfinity, |
5453 kFP64QuietNaN, kFP64SignallingNaN }; | 5573 kFP64QuietNaN, kFP64SignallingNaN }; |
5454 | 5574 |
5455 const int count = sizeof(inputs) / sizeof(inputs[0]); | 5575 const int count = sizeof(inputs) / sizeof(inputs[0]); |
5456 | 5576 |
5457 for (int in = 0; in < count; in++) { | 5577 for (int in = 0; in < count; in++) { |
(...skipping 29 matching lines...) Expand all Loading... |
5487 ASSERT_EQUAL_FP32(max, s29); | 5607 ASSERT_EQUAL_FP32(max, s29); |
5488 ASSERT_EQUAL_FP32(minnm, s30); | 5608 ASSERT_EQUAL_FP32(minnm, s30); |
5489 ASSERT_EQUAL_FP32(maxnm, s31); | 5609 ASSERT_EQUAL_FP32(maxnm, s31); |
5490 | 5610 |
5491 TEARDOWN(); | 5611 TEARDOWN(); |
5492 } | 5612 } |
5493 | 5613 |
5494 | 5614 |
5495 TEST(fmax_fmin_s) { | 5615 TEST(fmax_fmin_s) { |
5496 INIT_V8(); | 5616 INIT_V8(); |
| 5617 // Use non-standard NaNs to check that the payload bits are preserved. |
| 5618 float snan = rawbits_to_float(0x7f951234); |
| 5619 float qnan = rawbits_to_float(0x7fea8765); |
| 5620 |
| 5621 float snan_processed = rawbits_to_float(0x7fd51234); |
| 5622 float qnan_processed = qnan; |
| 5623 |
| 5624 ASSERT(IsSignallingNaN(snan)); |
| 5625 ASSERT(IsQuietNaN(qnan)); |
| 5626 ASSERT(IsQuietNaN(snan_processed)); |
| 5627 ASSERT(IsQuietNaN(qnan_processed)); |
| 5628 |
5497 // Bootstrap tests. | 5629 // Bootstrap tests. |
5498 FminFmaxFloatHelper(0, 0, 0, 0, 0, 0); | 5630 FminFmaxFloatHelper(0, 0, 0, 0, 0, 0); |
5499 FminFmaxFloatHelper(0, 1, 0, 1, 0, 1); | 5631 FminFmaxFloatHelper(0, 1, 0, 1, 0, 1); |
5500 FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity, | 5632 FminFmaxFloatHelper(kFP32PositiveInfinity, kFP32NegativeInfinity, |
5501 kFP32NegativeInfinity, kFP32PositiveInfinity, | 5633 kFP32NegativeInfinity, kFP32PositiveInfinity, |
5502 kFP32NegativeInfinity, kFP32PositiveInfinity); | 5634 kFP32NegativeInfinity, kFP32PositiveInfinity); |
5503 FminFmaxFloatHelper(kFP32SignallingNaN, 0, | 5635 FminFmaxFloatHelper(snan, 0, |
5504 kFP32SignallingNaN, kFP32SignallingNaN, | 5636 snan_processed, snan_processed, |
5505 kFP32SignallingNaN, kFP32SignallingNaN); | 5637 snan_processed, snan_processed); |
5506 FminFmaxFloatHelper(kFP32QuietNaN, 0, | 5638 FminFmaxFloatHelper(0, snan, |
5507 kFP32QuietNaN, kFP32QuietNaN, | 5639 snan_processed, snan_processed, |
| 5640 snan_processed, snan_processed); |
| 5641 FminFmaxFloatHelper(qnan, 0, |
| 5642 qnan_processed, qnan_processed, |
5508 0, 0); | 5643 0, 0); |
5509 FminFmaxFloatHelper(kFP32QuietNaN, kFP32SignallingNaN, | 5644 FminFmaxFloatHelper(0, qnan, |
5510 kFP32SignallingNaN, kFP32SignallingNaN, | 5645 qnan_processed, qnan_processed, |
5511 kFP32SignallingNaN, kFP32SignallingNaN); | 5646 0, 0); |
| 5647 FminFmaxFloatHelper(qnan, snan, |
| 5648 snan_processed, snan_processed, |
| 5649 snan_processed, snan_processed); |
| 5650 FminFmaxFloatHelper(snan, qnan, |
| 5651 snan_processed, snan_processed, |
| 5652 snan_processed, snan_processed); |
5512 | 5653 |
5513 // Iterate over all combinations of inputs. | 5654 // Iterate over all combinations of inputs. |
5514 float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0, | 5655 float inputs[] = { FLT_MAX, FLT_MIN, 1.0, 0.0, |
5515 -FLT_MAX, -FLT_MIN, -1.0, -0.0, | 5656 -FLT_MAX, -FLT_MIN, -1.0, -0.0, |
5516 kFP32PositiveInfinity, kFP32NegativeInfinity, | 5657 kFP32PositiveInfinity, kFP32NegativeInfinity, |
5517 kFP32QuietNaN, kFP32SignallingNaN }; | 5658 kFP32QuietNaN, kFP32SignallingNaN }; |
5518 | 5659 |
5519 const int count = sizeof(inputs) / sizeof(inputs[0]); | 5660 const int count = sizeof(inputs) / sizeof(inputs[0]); |
5520 | 5661 |
5521 for (int in = 0; in < count; in++) { | 5662 for (int in = 0; in < count; in++) { |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5802 INIT_V8(); | 5943 INIT_V8(); |
5803 SETUP(); | 5944 SETUP(); |
5804 | 5945 |
5805 START(); | 5946 START(); |
5806 __ Fmov(s16, 0.0); | 5947 __ Fmov(s16, 0.0); |
5807 __ Fmov(s17, 1.0); | 5948 __ Fmov(s17, 1.0); |
5808 __ Fmov(s18, 0.25); | 5949 __ Fmov(s18, 0.25); |
5809 __ Fmov(s19, 65536.0); | 5950 __ Fmov(s19, 65536.0); |
5810 __ Fmov(s20, -0.0); | 5951 __ Fmov(s20, -0.0); |
5811 __ Fmov(s21, kFP32PositiveInfinity); | 5952 __ Fmov(s21, kFP32PositiveInfinity); |
5812 __ Fmov(d22, 0.0); | 5953 __ Fmov(s22, -1.0); |
5813 __ Fmov(d23, 1.0); | 5954 __ Fmov(d23, 0.0); |
5814 __ Fmov(d24, 0.25); | 5955 __ Fmov(d24, 1.0); |
5815 __ Fmov(d25, 4294967296.0); | 5956 __ Fmov(d25, 0.25); |
5816 __ Fmov(d26, -0.0); | 5957 __ Fmov(d26, 4294967296.0); |
5817 __ Fmov(d27, kFP64PositiveInfinity); | 5958 __ Fmov(d27, -0.0); |
| 5959 __ Fmov(d28, kFP64PositiveInfinity); |
| 5960 __ Fmov(d29, -1.0); |
5818 | 5961 |
5819 __ Fsqrt(s0, s16); | 5962 __ Fsqrt(s0, s16); |
5820 __ Fsqrt(s1, s17); | 5963 __ Fsqrt(s1, s17); |
5821 __ Fsqrt(s2, s18); | 5964 __ Fsqrt(s2, s18); |
5822 __ Fsqrt(s3, s19); | 5965 __ Fsqrt(s3, s19); |
5823 __ Fsqrt(s4, s20); | 5966 __ Fsqrt(s4, s20); |
5824 __ Fsqrt(s5, s21); | 5967 __ Fsqrt(s5, s21); |
5825 __ Fsqrt(d6, d22); | 5968 __ Fsqrt(s6, s22); |
5826 __ Fsqrt(d7, d23); | 5969 __ Fsqrt(d7, d23); |
5827 __ Fsqrt(d8, d24); | 5970 __ Fsqrt(d8, d24); |
5828 __ Fsqrt(d9, d25); | 5971 __ Fsqrt(d9, d25); |
5829 __ Fsqrt(d10, d26); | 5972 __ Fsqrt(d10, d26); |
5830 __ Fsqrt(d11, d27); | 5973 __ Fsqrt(d11, d27); |
| 5974 __ Fsqrt(d12, d28); |
| 5975 __ Fsqrt(d13, d29); |
5831 END(); | 5976 END(); |
5832 | 5977 |
5833 RUN(); | 5978 RUN(); |
5834 | 5979 |
5835 ASSERT_EQUAL_FP32(0.0, s0); | 5980 ASSERT_EQUAL_FP32(0.0, s0); |
5836 ASSERT_EQUAL_FP32(1.0, s1); | 5981 ASSERT_EQUAL_FP32(1.0, s1); |
5837 ASSERT_EQUAL_FP32(0.5, s2); | 5982 ASSERT_EQUAL_FP32(0.5, s2); |
5838 ASSERT_EQUAL_FP32(256.0, s3); | 5983 ASSERT_EQUAL_FP32(256.0, s3); |
5839 ASSERT_EQUAL_FP32(-0.0, s4); | 5984 ASSERT_EQUAL_FP32(-0.0, s4); |
5840 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5); | 5985 ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5); |
5841 ASSERT_EQUAL_FP64(0.0, d6); | 5986 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6); |
5842 ASSERT_EQUAL_FP64(1.0, d7); | 5987 ASSERT_EQUAL_FP64(0.0, d7); |
5843 ASSERT_EQUAL_FP64(0.5, d8); | 5988 ASSERT_EQUAL_FP64(1.0, d8); |
5844 ASSERT_EQUAL_FP64(65536.0, d9); | 5989 ASSERT_EQUAL_FP64(0.5, d9); |
5845 ASSERT_EQUAL_FP64(-0.0, d10); | 5990 ASSERT_EQUAL_FP64(65536.0, d10); |
5846 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d11); | 5991 ASSERT_EQUAL_FP64(-0.0, d11); |
| 5992 ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12); |
| 5993 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13); |
5847 | 5994 |
5848 TEARDOWN(); | 5995 TEARDOWN(); |
5849 } | 5996 } |
5850 | 5997 |
5851 | 5998 |
5852 TEST(frinta) { | 5999 TEST(frinta) { |
5853 INIT_V8(); | 6000 INIT_V8(); |
5854 SETUP(); | 6001 SETUP(); |
5855 | 6002 |
5856 START(); | 6003 START(); |
(...skipping 3989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9846 __ Isb(); | 9993 __ Isb(); |
9847 | 9994 |
9848 END(); | 9995 END(); |
9849 | 9996 |
9850 RUN(); | 9997 RUN(); |
9851 | 9998 |
9852 TEARDOWN(); | 9999 TEARDOWN(); |
9853 } | 10000 } |
9854 | 10001 |
9855 | 10002 |
| 10003 TEST(process_nan_double) { |
| 10004 INIT_V8(); |
| 10005 // Make sure that NaN propagation works correctly. |
| 10006 double sn = rawbits_to_double(0x7ff5555511111111); |
| 10007 double qn = rawbits_to_double(0x7ffaaaaa11111111); |
| 10008 ASSERT(IsSignallingNaN(sn)); |
| 10009 ASSERT(IsQuietNaN(qn)); |
| 10010 |
| 10011 // The input NaNs after passing through ProcessNaN. |
| 10012 double sn_proc = rawbits_to_double(0x7ffd555511111111); |
| 10013 double qn_proc = qn; |
| 10014 ASSERT(IsQuietNaN(sn_proc)); |
| 10015 ASSERT(IsQuietNaN(qn_proc)); |
| 10016 |
| 10017 SETUP(); |
| 10018 START(); |
| 10019 |
| 10020 // Execute a number of instructions which all use ProcessNaN, and check that |
| 10021 // they all handle the NaN correctly. |
| 10022 __ Fmov(d0, sn); |
| 10023 __ Fmov(d10, qn); |
| 10024 |
| 10025 // Operations that always propagate NaNs unchanged, even signalling NaNs. |
| 10026 // - Signalling NaN |
| 10027 __ Fmov(d1, d0); |
| 10028 __ Fabs(d2, d0); |
| 10029 __ Fneg(d3, d0); |
| 10030 // - Quiet NaN |
| 10031 __ Fmov(d11, d10); |
| 10032 __ Fabs(d12, d10); |
| 10033 __ Fneg(d13, d10); |
| 10034 |
| 10035 // Operations that use ProcessNaN. |
| 10036 // - Signalling NaN |
| 10037 __ Fsqrt(d4, d0); |
| 10038 __ Frinta(d5, d0); |
| 10039 __ Frintn(d6, d0); |
| 10040 __ Frintz(d7, d0); |
| 10041 // - Quiet NaN |
| 10042 __ Fsqrt(d14, d10); |
| 10043 __ Frinta(d15, d10); |
| 10044 __ Frintn(d16, d10); |
| 10045 __ Frintz(d17, d10); |
| 10046 |
| 10047 // The behaviour of fcvt is checked in TEST(fcvt_sd). |
| 10048 |
| 10049 END(); |
| 10050 RUN(); |
| 10051 |
| 10052 uint64_t qn_raw = double_to_rawbits(qn); |
| 10053 uint64_t sn_raw = double_to_rawbits(sn); |
| 10054 |
| 10055 // - Signalling NaN |
| 10056 ASSERT_EQUAL_FP64(sn, d1); |
| 10057 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw & ~kDSignMask), d2); |
| 10058 ASSERT_EQUAL_FP64(rawbits_to_double(sn_raw ^ kDSignMask), d3); |
| 10059 // - Quiet NaN |
| 10060 ASSERT_EQUAL_FP64(qn, d11); |
| 10061 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw & ~kDSignMask), d12); |
| 10062 ASSERT_EQUAL_FP64(rawbits_to_double(qn_raw ^ kDSignMask), d13); |
| 10063 |
| 10064 // - Signalling NaN |
| 10065 ASSERT_EQUAL_FP64(sn_proc, d4); |
| 10066 ASSERT_EQUAL_FP64(sn_proc, d5); |
| 10067 ASSERT_EQUAL_FP64(sn_proc, d6); |
| 10068 ASSERT_EQUAL_FP64(sn_proc, d7); |
| 10069 // - Quiet NaN |
| 10070 ASSERT_EQUAL_FP64(qn_proc, d14); |
| 10071 ASSERT_EQUAL_FP64(qn_proc, d15); |
| 10072 ASSERT_EQUAL_FP64(qn_proc, d16); |
| 10073 ASSERT_EQUAL_FP64(qn_proc, d17); |
| 10074 |
| 10075 TEARDOWN(); |
| 10076 } |
| 10077 |
| 10078 |
| 10079 TEST(process_nan_float) { |
| 10080 INIT_V8(); |
| 10081 // Make sure that NaN propagation works correctly. |
| 10082 float sn = rawbits_to_float(0x7f951111); |
| 10083 float qn = rawbits_to_float(0x7fea1111); |
| 10084 ASSERT(IsSignallingNaN(sn)); |
| 10085 ASSERT(IsQuietNaN(qn)); |
| 10086 |
| 10087 // The input NaNs after passing through ProcessNaN. |
| 10088 float sn_proc = rawbits_to_float(0x7fd51111); |
| 10089 float qn_proc = qn; |
| 10090 ASSERT(IsQuietNaN(sn_proc)); |
| 10091 ASSERT(IsQuietNaN(qn_proc)); |
| 10092 |
| 10093 SETUP(); |
| 10094 START(); |
| 10095 |
| 10096 // Execute a number of instructions which all use ProcessNaN, and check that |
| 10097 // they all handle the NaN correctly. |
| 10098 __ Fmov(s0, sn); |
| 10099 __ Fmov(s10, qn); |
| 10100 |
| 10101 // Operations that always propagate NaNs unchanged, even signalling NaNs. |
| 10102 // - Signalling NaN |
| 10103 __ Fmov(s1, s0); |
| 10104 __ Fabs(s2, s0); |
| 10105 __ Fneg(s3, s0); |
| 10106 // - Quiet NaN |
| 10107 __ Fmov(s11, s10); |
| 10108 __ Fabs(s12, s10); |
| 10109 __ Fneg(s13, s10); |
| 10110 |
| 10111 // Operations that use ProcessNaN. |
| 10112 // - Signalling NaN |
| 10113 __ Fsqrt(s4, s0); |
| 10114 __ Frinta(s5, s0); |
| 10115 __ Frintn(s6, s0); |
| 10116 __ Frintz(s7, s0); |
| 10117 // - Quiet NaN |
| 10118 __ Fsqrt(s14, s10); |
| 10119 __ Frinta(s15, s10); |
| 10120 __ Frintn(s16, s10); |
| 10121 __ Frintz(s17, s10); |
| 10122 |
| 10123 // The behaviour of fcvt is checked in TEST(fcvt_sd). |
| 10124 |
| 10125 END(); |
| 10126 RUN(); |
| 10127 |
| 10128 uint32_t qn_raw = float_to_rawbits(qn); |
| 10129 uint32_t sn_raw = float_to_rawbits(sn); |
| 10130 |
| 10131 // - Signalling NaN |
| 10132 ASSERT_EQUAL_FP32(sn, s1); |
| 10133 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw & ~kSSignMask), s2); |
| 10134 ASSERT_EQUAL_FP32(rawbits_to_float(sn_raw ^ kSSignMask), s3); |
| 10135 // - Quiet NaN |
| 10136 ASSERT_EQUAL_FP32(qn, s11); |
| 10137 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw & ~kSSignMask), s12); |
| 10138 ASSERT_EQUAL_FP32(rawbits_to_float(qn_raw ^ kSSignMask), s13); |
| 10139 |
| 10140 // - Signalling NaN |
| 10141 ASSERT_EQUAL_FP32(sn_proc, s4); |
| 10142 ASSERT_EQUAL_FP32(sn_proc, s5); |
| 10143 ASSERT_EQUAL_FP32(sn_proc, s6); |
| 10144 ASSERT_EQUAL_FP32(sn_proc, s7); |
| 10145 // - Quiet NaN |
| 10146 ASSERT_EQUAL_FP32(qn_proc, s14); |
| 10147 ASSERT_EQUAL_FP32(qn_proc, s15); |
| 10148 ASSERT_EQUAL_FP32(qn_proc, s16); |
| 10149 ASSERT_EQUAL_FP32(qn_proc, s17); |
| 10150 |
| 10151 TEARDOWN(); |
| 10152 } |
| 10153 |
| 10154 |
| 10155 static void ProcessNaNsHelper(double n, double m, double expected) { |
| 10156 ASSERT(isnan(n) || isnan(m)); |
| 10157 ASSERT(isnan(expected)); |
| 10158 |
| 10159 SETUP(); |
| 10160 START(); |
| 10161 |
| 10162 // Execute a number of instructions which all use ProcessNaNs, and check that |
| 10163 // they all propagate NaNs correctly. |
| 10164 __ Fmov(d0, n); |
| 10165 __ Fmov(d1, m); |
| 10166 |
| 10167 __ Fadd(d2, d0, d1); |
| 10168 __ Fsub(d3, d0, d1); |
| 10169 __ Fmul(d4, d0, d1); |
| 10170 __ Fdiv(d5, d0, d1); |
| 10171 __ Fmax(d6, d0, d1); |
| 10172 __ Fmin(d7, d0, d1); |
| 10173 |
| 10174 END(); |
| 10175 RUN(); |
| 10176 |
| 10177 ASSERT_EQUAL_FP64(expected, d2); |
| 10178 ASSERT_EQUAL_FP64(expected, d3); |
| 10179 ASSERT_EQUAL_FP64(expected, d4); |
| 10180 ASSERT_EQUAL_FP64(expected, d5); |
| 10181 ASSERT_EQUAL_FP64(expected, d6); |
| 10182 ASSERT_EQUAL_FP64(expected, d7); |
| 10183 |
| 10184 TEARDOWN(); |
| 10185 } |
| 10186 |
| 10187 |
| 10188 TEST(process_nans_double) { |
| 10189 INIT_V8(); |
| 10190 // Make sure that NaN propagation works correctly. |
| 10191 double sn = rawbits_to_double(0x7ff5555511111111); |
| 10192 double sm = rawbits_to_double(0x7ff5555522222222); |
| 10193 double qn = rawbits_to_double(0x7ffaaaaa11111111); |
| 10194 double qm = rawbits_to_double(0x7ffaaaaa22222222); |
| 10195 ASSERT(IsSignallingNaN(sn)); |
| 10196 ASSERT(IsSignallingNaN(sm)); |
| 10197 ASSERT(IsQuietNaN(qn)); |
| 10198 ASSERT(IsQuietNaN(qm)); |
| 10199 |
| 10200 // The input NaNs after passing through ProcessNaN. |
| 10201 double sn_proc = rawbits_to_double(0x7ffd555511111111); |
| 10202 double sm_proc = rawbits_to_double(0x7ffd555522222222); |
| 10203 double qn_proc = qn; |
| 10204 double qm_proc = qm; |
| 10205 ASSERT(IsQuietNaN(sn_proc)); |
| 10206 ASSERT(IsQuietNaN(sm_proc)); |
| 10207 ASSERT(IsQuietNaN(qn_proc)); |
| 10208 ASSERT(IsQuietNaN(qm_proc)); |
| 10209 |
| 10210 // Quiet NaNs are propagated. |
| 10211 ProcessNaNsHelper(qn, 0, qn_proc); |
| 10212 ProcessNaNsHelper(0, qm, qm_proc); |
| 10213 ProcessNaNsHelper(qn, qm, qn_proc); |
| 10214 |
| 10215 // Signalling NaNs are propagated, and made quiet. |
| 10216 ProcessNaNsHelper(sn, 0, sn_proc); |
| 10217 ProcessNaNsHelper(0, sm, sm_proc); |
| 10218 ProcessNaNsHelper(sn, sm, sn_proc); |
| 10219 |
| 10220 // Signalling NaNs take precedence over quiet NaNs. |
| 10221 ProcessNaNsHelper(sn, qm, sn_proc); |
| 10222 ProcessNaNsHelper(qn, sm, sm_proc); |
| 10223 ProcessNaNsHelper(sn, sm, sn_proc); |
| 10224 } |
| 10225 |
| 10226 |
| 10227 static void ProcessNaNsHelper(float n, float m, float expected) { |
| 10228 ASSERT(isnan(n) || isnan(m)); |
| 10229 ASSERT(isnan(expected)); |
| 10230 |
| 10231 SETUP(); |
| 10232 START(); |
| 10233 |
| 10234 // Execute a number of instructions which all use ProcessNaNs, and check that |
| 10235 // they all propagate NaNs correctly. |
| 10236 __ Fmov(s0, n); |
| 10237 __ Fmov(s1, m); |
| 10238 |
| 10239 __ Fadd(s2, s0, s1); |
| 10240 __ Fsub(s3, s0, s1); |
| 10241 __ Fmul(s4, s0, s1); |
| 10242 __ Fdiv(s5, s0, s1); |
| 10243 __ Fmax(s6, s0, s1); |
| 10244 __ Fmin(s7, s0, s1); |
| 10245 |
| 10246 END(); |
| 10247 RUN(); |
| 10248 |
| 10249 ASSERT_EQUAL_FP32(expected, s2); |
| 10250 ASSERT_EQUAL_FP32(expected, s3); |
| 10251 ASSERT_EQUAL_FP32(expected, s4); |
| 10252 ASSERT_EQUAL_FP32(expected, s5); |
| 10253 ASSERT_EQUAL_FP32(expected, s6); |
| 10254 ASSERT_EQUAL_FP32(expected, s7); |
| 10255 |
| 10256 TEARDOWN(); |
| 10257 } |
| 10258 |
| 10259 |
| 10260 TEST(process_nans_float) { |
| 10261 INIT_V8(); |
| 10262 // Make sure that NaN propagation works correctly. |
| 10263 float sn = rawbits_to_float(0x7f951111); |
| 10264 float sm = rawbits_to_float(0x7f952222); |
| 10265 float qn = rawbits_to_float(0x7fea1111); |
| 10266 float qm = rawbits_to_float(0x7fea2222); |
| 10267 ASSERT(IsSignallingNaN(sn)); |
| 10268 ASSERT(IsSignallingNaN(sm)); |
| 10269 ASSERT(IsQuietNaN(qn)); |
| 10270 ASSERT(IsQuietNaN(qm)); |
| 10271 |
| 10272 // The input NaNs after passing through ProcessNaN. |
| 10273 float sn_proc = rawbits_to_float(0x7fd51111); |
| 10274 float sm_proc = rawbits_to_float(0x7fd52222); |
| 10275 float qn_proc = qn; |
| 10276 float qm_proc = qm; |
| 10277 ASSERT(IsQuietNaN(sn_proc)); |
| 10278 ASSERT(IsQuietNaN(sm_proc)); |
| 10279 ASSERT(IsQuietNaN(qn_proc)); |
| 10280 ASSERT(IsQuietNaN(qm_proc)); |
| 10281 |
| 10282 // Quiet NaNs are propagated. |
| 10283 ProcessNaNsHelper(qn, 0, qn_proc); |
| 10284 ProcessNaNsHelper(0, qm, qm_proc); |
| 10285 ProcessNaNsHelper(qn, qm, qn_proc); |
| 10286 |
| 10287 // Signalling NaNs are propagated, and made quiet. |
| 10288 ProcessNaNsHelper(sn, 0, sn_proc); |
| 10289 ProcessNaNsHelper(0, sm, sm_proc); |
| 10290 ProcessNaNsHelper(sn, sm, sn_proc); |
| 10291 |
| 10292 // Signalling NaNs take precedence over quiet NaNs. |
| 10293 ProcessNaNsHelper(sn, qm, sn_proc); |
| 10294 ProcessNaNsHelper(qn, sm, sm_proc); |
| 10295 ProcessNaNsHelper(sn, sm, sn_proc); |
| 10296 } |
| 10297 |
| 10298 |
| 10299 static void DefaultNaNHelper(float n, float m, float a) { |
| 10300 ASSERT(isnan(n) || isnan(m) || isnan(a)); |
| 10301 |
| 10302 bool test_1op = isnan(n); |
| 10303 bool test_2op = isnan(n) || isnan(m); |
| 10304 |
| 10305 SETUP(); |
| 10306 START(); |
| 10307 |
| 10308 // Enable Default-NaN mode in the FPCR. |
| 10309 __ Mrs(x0, FPCR); |
| 10310 __ Orr(x1, x0, DN_mask); |
| 10311 __ Msr(FPCR, x1); |
| 10312 |
| 10313 // Execute a number of instructions which all use ProcessNaNs, and check that |
| 10314 // they all produce the default NaN. |
| 10315 __ Fmov(s0, n); |
| 10316 __ Fmov(s1, m); |
| 10317 __ Fmov(s2, a); |
| 10318 |
| 10319 if (test_1op) { |
| 10320 // Operations that always propagate NaNs unchanged, even signalling NaNs. |
| 10321 __ Fmov(s10, s0); |
| 10322 __ Fabs(s11, s0); |
| 10323 __ Fneg(s12, s0); |
| 10324 |
| 10325 // Operations that use ProcessNaN. |
| 10326 __ Fsqrt(s13, s0); |
| 10327 __ Frinta(s14, s0); |
| 10328 __ Frintn(s15, s0); |
| 10329 __ Frintz(s16, s0); |
| 10330 |
| 10331 // Fcvt usually has special NaN handling, but it respects default-NaN mode. |
| 10332 __ Fcvt(d17, s0); |
| 10333 } |
| 10334 |
| 10335 if (test_2op) { |
| 10336 __ Fadd(s18, s0, s1); |
| 10337 __ Fsub(s19, s0, s1); |
| 10338 __ Fmul(s20, s0, s1); |
| 10339 __ Fdiv(s21, s0, s1); |
| 10340 __ Fmax(s22, s0, s1); |
| 10341 __ Fmin(s23, s0, s1); |
| 10342 } |
| 10343 |
| 10344 __ Fmadd(s24, s0, s1, s2); |
| 10345 __ Fmsub(s25, s0, s1, s2); |
| 10346 __ Fnmadd(s26, s0, s1, s2); |
| 10347 __ Fnmsub(s27, s0, s1, s2); |
| 10348 |
| 10349 // Restore FPCR. |
| 10350 __ Msr(FPCR, x0); |
| 10351 |
| 10352 END(); |
| 10353 RUN(); |
| 10354 |
| 10355 if (test_1op) { |
| 10356 uint32_t n_raw = float_to_rawbits(n); |
| 10357 ASSERT_EQUAL_FP32(n, s10); |
| 10358 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw & ~kSSignMask), s11); |
| 10359 ASSERT_EQUAL_FP32(rawbits_to_float(n_raw ^ kSSignMask), s12); |
| 10360 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13); |
| 10361 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14); |
| 10362 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15); |
| 10363 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16); |
| 10364 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17); |
| 10365 } |
| 10366 |
| 10367 if (test_2op) { |
| 10368 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18); |
| 10369 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19); |
| 10370 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20); |
| 10371 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21); |
| 10372 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22); |
| 10373 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23); |
| 10374 } |
| 10375 |
| 10376 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24); |
| 10377 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25); |
| 10378 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26); |
| 10379 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27); |
| 10380 |
| 10381 TEARDOWN(); |
| 10382 } |
| 10383 |
| 10384 |
| 10385 TEST(default_nan_float) { |
| 10386 INIT_V8(); |
| 10387 float sn = rawbits_to_float(0x7f951111); |
| 10388 float sm = rawbits_to_float(0x7f952222); |
| 10389 float sa = rawbits_to_float(0x7f95aaaa); |
| 10390 float qn = rawbits_to_float(0x7fea1111); |
| 10391 float qm = rawbits_to_float(0x7fea2222); |
| 10392 float qa = rawbits_to_float(0x7feaaaaa); |
| 10393 ASSERT(IsSignallingNaN(sn)); |
| 10394 ASSERT(IsSignallingNaN(sm)); |
| 10395 ASSERT(IsSignallingNaN(sa)); |
| 10396 ASSERT(IsQuietNaN(qn)); |
| 10397 ASSERT(IsQuietNaN(qm)); |
| 10398 ASSERT(IsQuietNaN(qa)); |
| 10399 |
| 10400 // - Signalling NaNs |
| 10401 DefaultNaNHelper(sn, 0.0f, 0.0f); |
| 10402 DefaultNaNHelper(0.0f, sm, 0.0f); |
| 10403 DefaultNaNHelper(0.0f, 0.0f, sa); |
| 10404 DefaultNaNHelper(sn, sm, 0.0f); |
| 10405 DefaultNaNHelper(0.0f, sm, sa); |
| 10406 DefaultNaNHelper(sn, 0.0f, sa); |
| 10407 DefaultNaNHelper(sn, sm, sa); |
| 10408 // - Quiet NaNs |
| 10409 DefaultNaNHelper(qn, 0.0f, 0.0f); |
| 10410 DefaultNaNHelper(0.0f, qm, 0.0f); |
| 10411 DefaultNaNHelper(0.0f, 0.0f, qa); |
| 10412 DefaultNaNHelper(qn, qm, 0.0f); |
| 10413 DefaultNaNHelper(0.0f, qm, qa); |
| 10414 DefaultNaNHelper(qn, 0.0f, qa); |
| 10415 DefaultNaNHelper(qn, qm, qa); |
| 10416 // - Mixed NaNs |
| 10417 DefaultNaNHelper(qn, sm, sa); |
| 10418 DefaultNaNHelper(sn, qm, sa); |
| 10419 DefaultNaNHelper(sn, sm, qa); |
| 10420 DefaultNaNHelper(qn, qm, sa); |
| 10421 DefaultNaNHelper(sn, qm, qa); |
| 10422 DefaultNaNHelper(qn, sm, qa); |
| 10423 DefaultNaNHelper(qn, qm, qa); |
| 10424 } |
| 10425 |
| 10426 |
| 10427 static void DefaultNaNHelper(double n, double m, double a) { |
| 10428 ASSERT(isnan(n) || isnan(m) || isnan(a)); |
| 10429 |
| 10430 bool test_1op = isnan(n); |
| 10431 bool test_2op = isnan(n) || isnan(m); |
| 10432 |
| 10433 SETUP(); |
| 10434 START(); |
| 10435 |
| 10436 // Enable Default-NaN mode in the FPCR. |
| 10437 __ Mrs(x0, FPCR); |
| 10438 __ Orr(x1, x0, DN_mask); |
| 10439 __ Msr(FPCR, x1); |
| 10440 |
| 10441 // Execute a number of instructions which all use ProcessNaNs, and check that |
| 10442 // they all produce the default NaN. |
| 10443 __ Fmov(d0, n); |
| 10444 __ Fmov(d1, m); |
| 10445 __ Fmov(d2, a); |
| 10446 |
| 10447 if (test_1op) { |
| 10448 // Operations that always propagate NaNs unchanged, even signalling NaNs. |
| 10449 __ Fmov(d10, d0); |
| 10450 __ Fabs(d11, d0); |
| 10451 __ Fneg(d12, d0); |
| 10452 |
| 10453 // Operations that use ProcessNaN. |
| 10454 __ Fsqrt(d13, d0); |
| 10455 __ Frinta(d14, d0); |
| 10456 __ Frintn(d15, d0); |
| 10457 __ Frintz(d16, d0); |
| 10458 |
| 10459 // Fcvt usually has special NaN handling, but it respects default-NaN mode. |
| 10460 __ Fcvt(s17, d0); |
| 10461 } |
| 10462 |
| 10463 if (test_2op) { |
| 10464 __ Fadd(d18, d0, d1); |
| 10465 __ Fsub(d19, d0, d1); |
| 10466 __ Fmul(d20, d0, d1); |
| 10467 __ Fdiv(d21, d0, d1); |
| 10468 __ Fmax(d22, d0, d1); |
| 10469 __ Fmin(d23, d0, d1); |
| 10470 } |
| 10471 |
| 10472 __ Fmadd(d24, d0, d1, d2); |
| 10473 __ Fmsub(d25, d0, d1, d2); |
| 10474 __ Fnmadd(d26, d0, d1, d2); |
| 10475 __ Fnmsub(d27, d0, d1, d2); |
| 10476 |
| 10477 // Restore FPCR. |
| 10478 __ Msr(FPCR, x0); |
| 10479 |
| 10480 END(); |
| 10481 RUN(); |
| 10482 |
| 10483 if (test_1op) { |
| 10484 uint64_t n_raw = double_to_rawbits(n); |
| 10485 ASSERT_EQUAL_FP64(n, d10); |
| 10486 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw & ~kDSignMask), d11); |
| 10487 ASSERT_EQUAL_FP64(rawbits_to_double(n_raw ^ kDSignMask), d12); |
| 10488 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13); |
| 10489 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14); |
| 10490 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15); |
| 10491 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16); |
| 10492 ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17); |
| 10493 } |
| 10494 |
| 10495 if (test_2op) { |
| 10496 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18); |
| 10497 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19); |
| 10498 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20); |
| 10499 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21); |
| 10500 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22); |
| 10501 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23); |
| 10502 } |
| 10503 |
| 10504 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24); |
| 10505 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25); |
| 10506 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26); |
| 10507 ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27); |
| 10508 |
| 10509 TEARDOWN(); |
| 10510 } |
| 10511 |
| 10512 |
| 10513 TEST(default_nan_double) { |
| 10514 INIT_V8(); |
| 10515 double sn = rawbits_to_double(0x7ff5555511111111); |
| 10516 double sm = rawbits_to_double(0x7ff5555522222222); |
| 10517 double sa = rawbits_to_double(0x7ff55555aaaaaaaa); |
| 10518 double qn = rawbits_to_double(0x7ffaaaaa11111111); |
| 10519 double qm = rawbits_to_double(0x7ffaaaaa22222222); |
| 10520 double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa); |
| 10521 ASSERT(IsSignallingNaN(sn)); |
| 10522 ASSERT(IsSignallingNaN(sm)); |
| 10523 ASSERT(IsSignallingNaN(sa)); |
| 10524 ASSERT(IsQuietNaN(qn)); |
| 10525 ASSERT(IsQuietNaN(qm)); |
| 10526 ASSERT(IsQuietNaN(qa)); |
| 10527 |
| 10528 // - Signalling NaNs |
| 10529 DefaultNaNHelper(sn, 0.0, 0.0); |
| 10530 DefaultNaNHelper(0.0, sm, 0.0); |
| 10531 DefaultNaNHelper(0.0, 0.0, sa); |
| 10532 DefaultNaNHelper(sn, sm, 0.0); |
| 10533 DefaultNaNHelper(0.0, sm, sa); |
| 10534 DefaultNaNHelper(sn, 0.0, sa); |
| 10535 DefaultNaNHelper(sn, sm, sa); |
| 10536 // - Quiet NaNs |
| 10537 DefaultNaNHelper(qn, 0.0, 0.0); |
| 10538 DefaultNaNHelper(0.0, qm, 0.0); |
| 10539 DefaultNaNHelper(0.0, 0.0, qa); |
| 10540 DefaultNaNHelper(qn, qm, 0.0); |
| 10541 DefaultNaNHelper(0.0, qm, qa); |
| 10542 DefaultNaNHelper(qn, 0.0, qa); |
| 10543 DefaultNaNHelper(qn, qm, qa); |
| 10544 // - Mixed NaNs |
| 10545 DefaultNaNHelper(qn, sm, sa); |
| 10546 DefaultNaNHelper(sn, qm, sa); |
| 10547 DefaultNaNHelper(sn, sm, qa); |
| 10548 DefaultNaNHelper(qn, qm, sa); |
| 10549 DefaultNaNHelper(sn, qm, qa); |
| 10550 DefaultNaNHelper(qn, sm, qa); |
| 10551 DefaultNaNHelper(qn, qm, qa); |
| 10552 } |
| 10553 |
| 10554 |
9856 TEST(call_no_relocation) { | 10555 TEST(call_no_relocation) { |
9857 Address call_start; | 10556 Address call_start; |
9858 Address return_address; | 10557 Address return_address; |
9859 | 10558 |
9860 INIT_V8(); | 10559 INIT_V8(); |
9861 SETUP(); | 10560 SETUP(); |
9862 | 10561 |
9863 START(); | 10562 START(); |
9864 | 10563 |
9865 Label function; | 10564 Label function; |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10072 if (RelocInfo::IsVeneerPool(info->rmode())) { | 10771 if (RelocInfo::IsVeneerPool(info->rmode())) { |
10073 ASSERT(info->data() == veneer_pool_size); | 10772 ASSERT(info->data() == veneer_pool_size); |
10074 ++pool_count; | 10773 ++pool_count; |
10075 } | 10774 } |
10076 } | 10775 } |
10077 | 10776 |
10078 ASSERT(pool_count == 2); | 10777 ASSERT(pool_count == 2); |
10079 | 10778 |
10080 TEARDOWN(); | 10779 TEARDOWN(); |
10081 } | 10780 } |
OLD | NEW |