xref: /aosp_15_r20/external/vixl/test/aarch64/test-assembler-fp-aarch64.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1 // Copyright 2019, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #include <sys/mman.h>
28 
29 #include <cfloat>
30 #include <cmath>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <cstring>
34 
35 #include "test-runner.h"
36 #include "test-utils.h"
37 #include "aarch64/test-utils-aarch64.h"
38 
39 #include "aarch64/cpu-aarch64.h"
40 #include "aarch64/disasm-aarch64.h"
41 #include "aarch64/macro-assembler-aarch64.h"
42 #include "aarch64/simulator-aarch64.h"
43 #include "test-assembler-aarch64.h"
44 
45 namespace vixl {
46 namespace aarch64 {
47 
TEST(load_store_float)48 TEST(load_store_float) {
49   SETUP_WITH_FEATURES(CPUFeatures::kFP);
50 
51   float src[3] = {1.0, 2.0, 3.0};
52   float dst[3] = {0.0, 0.0, 0.0};
53   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
54   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
55 
56   START();
57   __ Mov(x17, src_base);
58   __ Mov(x18, dst_base);
59   __ Mov(x19, src_base);
60   __ Mov(x20, dst_base);
61   __ Mov(x21, src_base);
62   __ Mov(x22, dst_base);
63   __ Ldr(s0, MemOperand(x17, sizeof(src[0])));
64   __ Str(s0, MemOperand(x18, sizeof(dst[0]), PostIndex));
65   __ Ldr(s1, MemOperand(x19, sizeof(src[0]), PostIndex));
66   __ Str(s1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
67   __ Ldr(s2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
68   __ Str(s2, MemOperand(x22, sizeof(dst[0])));
69   END();
70 
71   if (CAN_RUN()) {
72     RUN();
73 
74     ASSERT_EQUAL_FP32(2.0, s0);
75     ASSERT_EQUAL_FP32(2.0, dst[0]);
76     ASSERT_EQUAL_FP32(1.0, s1);
77     ASSERT_EQUAL_FP32(1.0, dst[2]);
78     ASSERT_EQUAL_FP32(3.0, s2);
79     ASSERT_EQUAL_FP32(3.0, dst[1]);
80     ASSERT_EQUAL_64(src_base, x17);
81     ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
82     ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
83     ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
84     ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
85     ASSERT_EQUAL_64(dst_base, x22);
86   }
87 }
88 
89 
TEST(load_store_double)90 TEST(load_store_double) {
91   SETUP_WITH_FEATURES(CPUFeatures::kFP);
92 
93   double src[3] = {1.0, 2.0, 3.0};
94   double dst[3] = {0.0, 0.0, 0.0};
95   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
96   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
97 
98   START();
99   __ Mov(x17, src_base);
100   __ Mov(x18, dst_base);
101   __ Mov(x19, src_base);
102   __ Mov(x20, dst_base);
103   __ Mov(x21, src_base);
104   __ Mov(x22, dst_base);
105   __ Ldr(d0, MemOperand(x17, sizeof(src[0])));
106   __ Str(d0, MemOperand(x18, sizeof(dst[0]), PostIndex));
107   __ Ldr(d1, MemOperand(x19, sizeof(src[0]), PostIndex));
108   __ Str(d1, MemOperand(x20, 2 * sizeof(dst[0]), PreIndex));
109   __ Ldr(d2, MemOperand(x21, 2 * sizeof(src[0]), PreIndex));
110   __ Str(d2, MemOperand(x22, sizeof(dst[0])));
111   END();
112 
113   if (CAN_RUN()) {
114     RUN();
115 
116     ASSERT_EQUAL_FP64(2.0, d0);
117     ASSERT_EQUAL_FP64(2.0, dst[0]);
118     ASSERT_EQUAL_FP64(1.0, d1);
119     ASSERT_EQUAL_FP64(1.0, dst[2]);
120     ASSERT_EQUAL_FP64(3.0, d2);
121     ASSERT_EQUAL_FP64(3.0, dst[1]);
122     ASSERT_EQUAL_64(src_base, x17);
123     ASSERT_EQUAL_64(dst_base + sizeof(dst[0]), x18);
124     ASSERT_EQUAL_64(src_base + sizeof(src[0]), x19);
125     ASSERT_EQUAL_64(dst_base + 2 * sizeof(dst[0]), x20);
126     ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x21);
127     ASSERT_EQUAL_64(dst_base, x22);
128   }
129 }
130 
TEST(ldp_stp_float)131 TEST(ldp_stp_float) {
132   SETUP_WITH_FEATURES(CPUFeatures::kFP);
133 
134   float src[2] = {1.0, 2.0};
135   float dst[3] = {0.0, 0.0, 0.0};
136   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
137   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
138 
139   START();
140   __ Mov(x16, src_base);
141   __ Mov(x17, dst_base);
142   __ Ldp(s31, s0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
143   __ Stp(s0, s31, MemOperand(x17, sizeof(dst[1]), PreIndex));
144   END();
145 
146   if (CAN_RUN()) {
147     RUN();
148 
149     ASSERT_EQUAL_FP32(1.0, s31);
150     ASSERT_EQUAL_FP32(2.0, s0);
151     ASSERT_EQUAL_FP32(0.0, dst[0]);
152     ASSERT_EQUAL_FP32(2.0, dst[1]);
153     ASSERT_EQUAL_FP32(1.0, dst[2]);
154     ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
155     ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
156   }
157 }
158 
159 
TEST(ldp_stp_double)160 TEST(ldp_stp_double) {
161   SETUP_WITH_FEATURES(CPUFeatures::kFP);
162 
163   double src[2] = {1.0, 2.0};
164   double dst[3] = {0.0, 0.0, 0.0};
165   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
166   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
167 
168   START();
169   __ Mov(x16, src_base);
170   __ Mov(x17, dst_base);
171   __ Ldp(d31, d0, MemOperand(x16, 2 * sizeof(src[0]), PostIndex));
172   __ Stp(d0, d31, MemOperand(x17, sizeof(dst[1]), PreIndex));
173   END();
174 
175   if (CAN_RUN()) {
176     RUN();
177 
178     ASSERT_EQUAL_FP64(1.0, d31);
179     ASSERT_EQUAL_FP64(2.0, d0);
180     ASSERT_EQUAL_FP64(0.0, dst[0]);
181     ASSERT_EQUAL_FP64(2.0, dst[1]);
182     ASSERT_EQUAL_FP64(1.0, dst[2]);
183     ASSERT_EQUAL_64(src_base + 2 * sizeof(src[0]), x16);
184     ASSERT_EQUAL_64(dst_base + sizeof(dst[1]), x17);
185   }
186 }
187 
TEST(ldnp_stnp_offset_float)188 TEST(ldnp_stnp_offset_float) {
189   SETUP_WITH_FEATURES(CPUFeatures::kFP);
190 
191   float src[3] = {1.2, 2.3, 3.4};
192   float dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
193   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
194   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
195 
196   START();
197   __ Mov(x16, src_base);
198   __ Mov(x17, dst_base);
199   __ Mov(x18, src_base + 12);
200   __ Mov(x19, dst_base + 24);
201 
202   // Ensure address set up has happened before executing non-temporal ops.
203   __ Dmb(InnerShareable, BarrierAll);
204 
205   __ Ldnp(s0, s1, MemOperand(x16));
206   __ Ldnp(s2, s3, MemOperand(x16, 4));
207   __ Ldnp(s5, s4, MemOperand(x18, -8));
208   __ Stnp(s1, s0, MemOperand(x17));
209   __ Stnp(s3, s2, MemOperand(x17, 8));
210   __ Stnp(s4, s5, MemOperand(x19, -8));
211   END();
212 
213   if (CAN_RUN()) {
214     RUN();
215 
216     ASSERT_EQUAL_FP32(1.2, s0);
217     ASSERT_EQUAL_FP32(2.3, s1);
218     ASSERT_EQUAL_FP32(2.3, dst[0]);
219     ASSERT_EQUAL_FP32(1.2, dst[1]);
220     ASSERT_EQUAL_FP32(2.3, s2);
221     ASSERT_EQUAL_FP32(3.4, s3);
222     ASSERT_EQUAL_FP32(3.4, dst[2]);
223     ASSERT_EQUAL_FP32(2.3, dst[3]);
224     ASSERT_EQUAL_FP32(3.4, s4);
225     ASSERT_EQUAL_FP32(2.3, s5);
226     ASSERT_EQUAL_FP32(3.4, dst[4]);
227     ASSERT_EQUAL_FP32(2.3, dst[5]);
228     ASSERT_EQUAL_64(src_base, x16);
229     ASSERT_EQUAL_64(dst_base, x17);
230     ASSERT_EQUAL_64(src_base + 12, x18);
231     ASSERT_EQUAL_64(dst_base + 24, x19);
232   }
233 }
234 
235 
TEST(ldnp_stnp_offset_double)236 TEST(ldnp_stnp_offset_double) {
237   SETUP_WITH_FEATURES(CPUFeatures::kFP);
238 
239   double src[3] = {1.2, 2.3, 3.4};
240   double dst[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
241   uintptr_t src_base = reinterpret_cast<uintptr_t>(src);
242   uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst);
243 
244   START();
245   __ Mov(x16, src_base);
246   __ Mov(x17, dst_base);
247   __ Mov(x18, src_base + 24);
248   __ Mov(x19, dst_base + 48);
249 
250   // Ensure address set up has happened before executing non-temporal ops.
251   __ Dmb(InnerShareable, BarrierAll);
252 
253   __ Ldnp(d0, d1, MemOperand(x16));
254   __ Ldnp(d2, d3, MemOperand(x16, 8));
255   __ Ldnp(d5, d4, MemOperand(x18, -16));
256   __ Stnp(d1, d0, MemOperand(x17));
257   __ Stnp(d3, d2, MemOperand(x17, 16));
258   __ Stnp(d4, d5, MemOperand(x19, -16));
259   END();
260 
261   if (CAN_RUN()) {
262     RUN();
263 
264     ASSERT_EQUAL_FP64(1.2, d0);
265     ASSERT_EQUAL_FP64(2.3, d1);
266     ASSERT_EQUAL_FP64(2.3, dst[0]);
267     ASSERT_EQUAL_FP64(1.2, dst[1]);
268     ASSERT_EQUAL_FP64(2.3, d2);
269     ASSERT_EQUAL_FP64(3.4, d3);
270     ASSERT_EQUAL_FP64(3.4, dst[2]);
271     ASSERT_EQUAL_FP64(2.3, dst[3]);
272     ASSERT_EQUAL_FP64(3.4, d4);
273     ASSERT_EQUAL_FP64(2.3, d5);
274     ASSERT_EQUAL_FP64(3.4, dst[4]);
275     ASSERT_EQUAL_FP64(2.3, dst[5]);
276     ASSERT_EQUAL_64(src_base, x16);
277     ASSERT_EQUAL_64(dst_base, x17);
278     ASSERT_EQUAL_64(src_base + 24, x18);
279     ASSERT_EQUAL_64(dst_base + 48, x19);
280   }
281 }
282 
283 template <typename T>
LoadFPValueHelper(T values[],int card)284 void LoadFPValueHelper(T values[], int card) {
285   SETUP_WITH_FEATURES(CPUFeatures::kFP);
286 
287   const bool is_32bits = (sizeof(T) == 4);
288   const VRegister& fp_tgt = is_32bits ? VRegister(s2) : VRegister(d2);
289   const Register& tgt1 = is_32bits ? Register(w1) : Register(x1);
290   const Register& tgt2 = is_32bits ? Register(w2) : Register(x2);
291 
292   START();
293   __ Mov(x0, 0);
294 
295   // If one of the values differ then x0 will be one.
296   for (int i = 0; i < card; ++i) {
297     __ Mov(tgt1,
298            is_32bits ? FloatToRawbits(values[i]) : DoubleToRawbits(values[i]));
299     __ Ldr(fp_tgt, values[i]);
300     __ Fmov(tgt2, fp_tgt);
301     __ Cmp(tgt1, tgt2);
302     __ Cset(x0, ne);
303   }
304   END();
305 
306   if (CAN_RUN()) {
307     RUN();
308 
309     // If one of the values differs, the trace can be used to identify which
310     // one.
311     ASSERT_EQUAL_64(0, x0);
312   }
313 }
314 
TEST(ldr_literal_values_d)315 TEST(ldr_literal_values_d) {
316   static const double kValues[] = {-0.0, 0.0, -1.0, 1.0, -1e10, 1e10};
317 
318   LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
319 }
320 
321 
TEST(ldr_literal_values_s)322 TEST(ldr_literal_values_s) {
323   static const float kValues[] = {-0.0, 0.0, -1.0, 1.0, -1e10, 1e10};
324 
325   LoadFPValueHelper(kValues, sizeof(kValues) / sizeof(kValues[0]));
326 }
327 
TEST(fmov_imm)328 TEST(fmov_imm) {
329   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
330 
331   START();
332   __ Fmov(s1, 255.0);
333   __ Fmov(d2, 12.34567);
334   __ Fmov(s3, 0.0);
335   __ Fmov(d4, 0.0);
336   __ Fmov(s5, kFP32PositiveInfinity);
337   __ Fmov(d6, kFP64NegativeInfinity);
338   __ Fmov(h7, RawbitsToFloat16(0x6400U));
339   __ Fmov(h8, kFP16PositiveInfinity);
340   __ Fmov(s11, 1.0);
341   __ Fmov(h12, RawbitsToFloat16(0x7BFF));
342   __ Fmov(h13, RawbitsToFloat16(0x57F2));
343   __ Fmov(d22, -13.0);
344   __ Fmov(h23, RawbitsToFloat16(0xC500U));
345   __ Fmov(h24, Float16(-5.0));
346   __ Fmov(h25, Float16(2049.0));
347   __ Fmov(h21, RawbitsToFloat16(0x6404U));
348   __ Fmov(h26, RawbitsToFloat16(0x0U));
349   __ Fmov(h27, RawbitsToFloat16(0x7e00U));
350   END();
351   if (CAN_RUN()) {
352     RUN();
353 
354     ASSERT_EQUAL_FP32(255.0, s1);
355     ASSERT_EQUAL_FP64(12.34567, d2);
356     ASSERT_EQUAL_FP32(0.0, s3);
357     ASSERT_EQUAL_FP64(0.0, d4);
358     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
359     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d6);
360     ASSERT_EQUAL_FP16(RawbitsToFloat16(0x6400U), h7);
361     ASSERT_EQUAL_FP16(kFP16PositiveInfinity, h8);
362     ASSERT_EQUAL_FP32(1.0, s11);
363     ASSERT_EQUAL_FP16(RawbitsToFloat16(0x7BFF), h12);
364     ASSERT_EQUAL_FP16(RawbitsToFloat16(0x57F2U), h13);
365     ASSERT_EQUAL_FP16(RawbitsToFloat16(0x6404), h21);
366     ASSERT_EQUAL_FP64(-13.0, d22);
367     ASSERT_EQUAL_FP16(Float16(-5.0), h23);
368     ASSERT_EQUAL_FP16(RawbitsToFloat16(0xC500), h24);
369     // 2049 is unpresentable.
370     ASSERT_EQUAL_FP16(RawbitsToFloat16(0x6800), h25);
371     ASSERT_EQUAL_FP16(kFP16PositiveZero, h26);
372     // NaN check.
373     ASSERT_EQUAL_FP16(RawbitsToFloat16(0x7e00), h27);
374   }
375 }
376 
TEST(fmov_reg)377 TEST(fmov_reg) {
378   SETUP_WITH_FEATURES(CPUFeatures::kNEON,
379                       CPUFeatures::kFP,
380                       CPUFeatures::kFPHalf);
381 
382   START();
383 
384   __ Fmov(h3, RawbitsToFloat16(0xCA80U));
385   __ Fmov(h7, h3);
386   __ Fmov(h8, -5.0);
387   __ Fmov(w3, h8);
388   __ Fmov(h9, w3);
389   __ Fmov(h8, Float16(1024.0));
390   __ Fmov(x4, h8);
391   __ Fmov(h10, x4);
392   __ Fmov(s20, 1.0);
393   __ Fmov(w10, s20);
394   __ Fmov(s30, w10);
395   __ Fmov(s5, s20);
396   __ Fmov(d1, -13.0);
397   __ Fmov(x1, d1);
398   __ Fmov(d2, x1);
399   __ Fmov(d4, d1);
400   __ Fmov(d6, RawbitsToDouble(0x0123456789abcdef));
401   __ Fmov(s6, s6);
402   __ Fmov(d0, 0.0);
403   __ Fmov(v0.D(), 1, x1);
404   __ Fmov(x2, v0.D(), 1);
405   __ Fmov(v3.D(), 1, x4);
406   __ Fmov(v3.D(), 0, x1);
407   __ Fmov(x5, v1.D(), 0);
408 
409   END();
410   if (CAN_RUN()) {
411     RUN();
412 
413     ASSERT_EQUAL_FP16(RawbitsToFloat16(0xCA80U), h7);
414     ASSERT_EQUAL_FP16(RawbitsToFloat16(0xC500U), h9);
415     ASSERT_EQUAL_32(0x0000C500, w3);
416     ASSERT_EQUAL_64(0x0000000000006400, x4);
417     ASSERT_EQUAL_FP16(RawbitsToFloat16(0x6400), h10);
418     ASSERT_EQUAL_32(FloatToRawbits(1.0), w10);
419     ASSERT_EQUAL_FP32(1.0, s30);
420     ASSERT_EQUAL_FP32(1.0, s5);
421     ASSERT_EQUAL_64(DoubleToRawbits(-13.0), x1);
422     ASSERT_EQUAL_FP64(-13.0, d2);
423     ASSERT_EQUAL_FP64(-13.0, d4);
424     ASSERT_EQUAL_FP32(RawbitsToFloat(0x89abcdef), s6);
425     ASSERT_EQUAL_128(DoubleToRawbits(-13.0), 0x0000000000000000, q0);
426     ASSERT_EQUAL_64(DoubleToRawbits(-13.0), x2);
427     ASSERT_EQUAL_128(0x0000000000006400, DoubleToRawbits(-13.0), q3);
428     ASSERT_EQUAL_64(DoubleToRawbits(-13.0), x5);
429   }
430 }
431 
432 
TEST(fadd)433 TEST(fadd) {
434   SETUP_WITH_FEATURES(CPUFeatures::kFP);
435 
436   START();
437   __ Fmov(s14, -0.0f);
438   __ Fmov(s15, kFP32PositiveInfinity);
439   __ Fmov(s16, kFP32NegativeInfinity);
440   __ Fmov(s17, 3.25f);
441   __ Fmov(s18, 1.0f);
442   __ Fmov(s19, 0.0f);
443 
444   __ Fmov(d26, -0.0);
445   __ Fmov(d27, kFP64PositiveInfinity);
446   __ Fmov(d28, kFP64NegativeInfinity);
447   __ Fmov(d29, 0.0);
448   __ Fmov(d30, -2.0);
449   __ Fmov(d31, 2.25);
450 
451   __ Fadd(s0, s17, s18);
452   __ Fadd(s1, s18, s19);
453   __ Fadd(s2, s14, s18);
454   __ Fadd(s3, s15, s18);
455   __ Fadd(s4, s16, s18);
456   __ Fadd(s5, s15, s16);
457   __ Fadd(s6, s16, s15);
458 
459   __ Fadd(d7, d30, d31);
460   __ Fadd(d8, d29, d31);
461   __ Fadd(d9, d26, d31);
462   __ Fadd(d10, d27, d31);
463   __ Fadd(d11, d28, d31);
464   __ Fadd(d12, d27, d28);
465   __ Fadd(d13, d28, d27);
466   END();
467 
468   if (CAN_RUN()) {
469     RUN();
470 
471     ASSERT_EQUAL_FP32(4.25, s0);
472     ASSERT_EQUAL_FP32(1.0, s1);
473     ASSERT_EQUAL_FP32(1.0, s2);
474     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
475     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
476     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
477     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
478     ASSERT_EQUAL_FP64(0.25, d7);
479     ASSERT_EQUAL_FP64(2.25, d8);
480     ASSERT_EQUAL_FP64(2.25, d9);
481     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d10);
482     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d11);
483     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
484     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
485   }
486 }
487 
488 
TEST(fadd_h)489 TEST(fadd_h) {
490   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
491 
492   START();
493   __ Fmov(h14, -0.0f);
494   __ Fmov(h15, kFP16PositiveInfinity);
495   __ Fmov(h16, kFP16NegativeInfinity);
496   __ Fmov(h17, 3.25f);
497   __ Fmov(h18, 1.0);
498   __ Fmov(h19, 0.0f);
499   __ Fmov(h20, 5.0f);
500 
501   __ Fadd(h0, h17, h18);
502   __ Fadd(h1, h18, h19);
503   __ Fadd(h2, h14, h18);
504   __ Fadd(h3, h15, h18);
505   __ Fadd(h4, h16, h18);
506   __ Fadd(h5, h15, h16);
507   __ Fadd(h6, h16, h15);
508   __ Fadd(h7, h20, h20);
509   END();
510 
511   if (CAN_RUN()) {
512     RUN();
513 
514     ASSERT_EQUAL_FP16(Float16(4.25), h0);
515     ASSERT_EQUAL_FP16(Float16(1.0), h1);
516     ASSERT_EQUAL_FP16(Float16(1.0), h2);
517     ASSERT_EQUAL_FP16(kFP16PositiveInfinity, h3);
518     ASSERT_EQUAL_FP16(kFP16NegativeInfinity, h4);
519     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h5);
520     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h6);
521     ASSERT_EQUAL_FP16(Float16(10.0), h7);
522   }
523 }
524 
TEST(fsub)525 TEST(fsub) {
526   SETUP_WITH_FEATURES(CPUFeatures::kFP);
527 
528   START();
529   __ Fmov(s14, -0.0f);
530   __ Fmov(s15, kFP32PositiveInfinity);
531   __ Fmov(s16, kFP32NegativeInfinity);
532   __ Fmov(s17, 3.25f);
533   __ Fmov(s18, 1.0f);
534   __ Fmov(s19, 0.0f);
535 
536   __ Fmov(d26, -0.0);
537   __ Fmov(d27, kFP64PositiveInfinity);
538   __ Fmov(d28, kFP64NegativeInfinity);
539   __ Fmov(d29, 0.0);
540   __ Fmov(d30, -2.0);
541   __ Fmov(d31, 2.25);
542 
543   __ Fsub(s0, s17, s18);
544   __ Fsub(s1, s18, s19);
545   __ Fsub(s2, s14, s18);
546   __ Fsub(s3, s18, s15);
547   __ Fsub(s4, s18, s16);
548   __ Fsub(s5, s15, s15);
549   __ Fsub(s6, s16, s16);
550 
551   __ Fsub(d7, d30, d31);
552   __ Fsub(d8, d29, d31);
553   __ Fsub(d9, d26, d31);
554   __ Fsub(d10, d31, d27);
555   __ Fsub(d11, d31, d28);
556   __ Fsub(d12, d27, d27);
557   __ Fsub(d13, d28, d28);
558   END();
559 
560   if (CAN_RUN()) {
561     RUN();
562 
563     ASSERT_EQUAL_FP32(2.25, s0);
564     ASSERT_EQUAL_FP32(1.0, s1);
565     ASSERT_EQUAL_FP32(-1.0, s2);
566     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
567     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
568     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
569     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
570     ASSERT_EQUAL_FP64(-4.25, d7);
571     ASSERT_EQUAL_FP64(-2.25, d8);
572     ASSERT_EQUAL_FP64(-2.25, d9);
573     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
574     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
575     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
576     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
577   }
578 }
579 
580 
TEST(fsub_h)581 TEST(fsub_h) {
582   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
583 
584   START();
585   __ Fmov(h14, -0.0f);
586   __ Fmov(h15, kFP16PositiveInfinity);
587   __ Fmov(h16, kFP16NegativeInfinity);
588   __ Fmov(h17, 3.25f);
589   __ Fmov(h18, 1.0f);
590   __ Fmov(h19, 0.0f);
591 
592   __ Fsub(h0, h17, h18);
593   __ Fsub(h1, h18, h19);
594   __ Fsub(h2, h14, h18);
595   __ Fsub(h3, h18, h15);
596   __ Fsub(h4, h18, h16);
597   __ Fsub(h5, h15, h15);
598   __ Fsub(h6, h16, h16);
599   END();
600 
601   if (CAN_RUN()) {
602     RUN();
603 
604     ASSERT_EQUAL_FP16(Float16(2.25), h0);
605     ASSERT_EQUAL_FP16(Float16(1.0), h1);
606     ASSERT_EQUAL_FP16(Float16(-1.0), h2);
607     ASSERT_EQUAL_FP16(kFP16NegativeInfinity, h3);
608     ASSERT_EQUAL_FP16(kFP16PositiveInfinity, h4);
609     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h5);
610     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h6);
611   }
612 }
613 
614 
TEST(fmul)615 TEST(fmul) {
616   SETUP_WITH_FEATURES(CPUFeatures::kFP);
617 
618   START();
619   __ Fmov(s14, -0.0f);
620   __ Fmov(s15, kFP32PositiveInfinity);
621   __ Fmov(s16, kFP32NegativeInfinity);
622   __ Fmov(s17, 3.25f);
623   __ Fmov(s18, 2.0f);
624   __ Fmov(s19, 0.0f);
625   __ Fmov(s20, -2.0f);
626 
627   __ Fmov(d26, -0.0);
628   __ Fmov(d27, kFP64PositiveInfinity);
629   __ Fmov(d28, kFP64NegativeInfinity);
630   __ Fmov(d29, 0.0);
631   __ Fmov(d30, -2.0);
632   __ Fmov(d31, 2.25);
633 
634   __ Fmul(s0, s17, s18);
635   __ Fmul(s1, s18, s19);
636   __ Fmul(s2, s14, s14);
637   __ Fmul(s3, s15, s20);
638   __ Fmul(s4, s16, s20);
639   __ Fmul(s5, s15, s19);
640   __ Fmul(s6, s19, s16);
641 
642   __ Fmul(d7, d30, d31);
643   __ Fmul(d8, d29, d31);
644   __ Fmul(d9, d26, d26);
645   __ Fmul(d10, d27, d30);
646   __ Fmul(d11, d28, d30);
647   __ Fmul(d12, d27, d29);
648   __ Fmul(d13, d29, d28);
649   END();
650 
651   if (CAN_RUN()) {
652     RUN();
653 
654     ASSERT_EQUAL_FP32(6.5, s0);
655     ASSERT_EQUAL_FP32(0.0, s1);
656     ASSERT_EQUAL_FP32(0.0, s2);
657     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s3);
658     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s4);
659     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
660     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
661     ASSERT_EQUAL_FP64(-4.5, d7);
662     ASSERT_EQUAL_FP64(0.0, d8);
663     ASSERT_EQUAL_FP64(0.0, d9);
664     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
665     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
666     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
667     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
668   }
669 }
670 
671 
TEST(fmul_h)672 TEST(fmul_h) {
673   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
674 
675   START();
676   __ Fmov(h14, -0.0f);
677   __ Fmov(h15, kFP16PositiveInfinity);
678   __ Fmov(h16, kFP16NegativeInfinity);
679   __ Fmov(h17, 3.25f);
680   __ Fmov(h18, 2.0f);
681   __ Fmov(h19, 0.0f);
682   __ Fmov(h20, -2.0f);
683 
684   __ Fmul(h0, h17, h18);
685   __ Fmul(h1, h18, h19);
686   __ Fmul(h2, h14, h14);
687   __ Fmul(h3, h15, h20);
688   __ Fmul(h4, h16, h20);
689   __ Fmul(h5, h15, h19);
690   __ Fmul(h6, h19, h16);
691   END();
692 
693   if (CAN_RUN()) {
694     RUN();
695 
696     ASSERT_EQUAL_FP16(Float16(6.5), h0);
697     ASSERT_EQUAL_FP16(Float16(0.0), h1);
698     ASSERT_EQUAL_FP16(Float16(0.0), h2);
699     ASSERT_EQUAL_FP16(kFP16NegativeInfinity, h3);
700     ASSERT_EQUAL_FP16(kFP16PositiveInfinity, h4);
701     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h5);
702     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h6);
703   }
704 }
705 
706 
TEST(fnmul_h)707 TEST(fnmul_h) {
708   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
709 
710   START();
711   __ Fmov(h14, -0.0f);
712   __ Fmov(h15, kFP16PositiveInfinity);
713   __ Fmov(h16, kFP16NegativeInfinity);
714   __ Fmov(h17, 3.25f);
715   __ Fmov(h18, 2.0f);
716   __ Fmov(h19, 0.0f);
717   __ Fmov(h20, -2.0f);
718 
719   __ Fnmul(h0, h17, h18);
720   __ Fnmul(h1, h18, h19);
721   __ Fnmul(h2, h14, h14);
722   __ Fnmul(h3, h15, h20);
723   __ Fnmul(h4, h16, h20);
724   __ Fnmul(h5, h15, h19);
725   __ Fnmul(h6, h19, h16);
726   END();
727 
728   if (CAN_RUN()) {
729     RUN();
730 
731     ASSERT_EQUAL_FP16(Float16(-6.5), h0);
732     ASSERT_EQUAL_FP16(Float16(-0.0), h1);
733     ASSERT_EQUAL_FP16(Float16(-0.0), h2);
734     ASSERT_EQUAL_FP16(kFP16PositiveInfinity, h3);
735     ASSERT_EQUAL_FP16(kFP16NegativeInfinity, h4);
736     ASSERT_EQUAL_FP16(RawbitsToFloat16(0xfe00), h5);
737     ASSERT_EQUAL_FP16(RawbitsToFloat16(0xfe00), h6);
738   }
739 }
740 
741 
FmaddFmsubHelper(double n,double m,double a,double fmadd,double fmsub,double fnmadd,double fnmsub)742 static void FmaddFmsubHelper(double n,
743                              double m,
744                              double a,
745                              double fmadd,
746                              double fmsub,
747                              double fnmadd,
748                              double fnmsub) {
749   SETUP_WITH_FEATURES(CPUFeatures::kFP);
750 
751   START();
752 
753   __ Fmov(d0, n);
754   __ Fmov(d1, m);
755   __ Fmov(d2, a);
756   __ Fmadd(d28, d0, d1, d2);
757   __ Fmsub(d29, d0, d1, d2);
758   __ Fnmadd(d30, d0, d1, d2);
759   __ Fnmsub(d31, d0, d1, d2);
760 
761   END();
762   if (CAN_RUN()) {
763     RUN();
764 
765     ASSERT_EQUAL_FP64(fmadd, d28);
766     ASSERT_EQUAL_FP64(fmsub, d29);
767     ASSERT_EQUAL_FP64(fnmadd, d30);
768     ASSERT_EQUAL_FP64(fnmsub, d31);
769   }
770 }
771 
772 
TEST(fmadd_fmsub_double)773 TEST(fmadd_fmsub_double) {
774   // It's hard to check the result of fused operations because the only way to
775   // calculate the result is using fma, which is what the Simulator uses anyway.
776 
777   // Basic operation.
778   FmaddFmsubHelper(1.0, 2.0, 3.0, 5.0, 1.0, -5.0, -1.0);
779   FmaddFmsubHelper(-1.0, 2.0, 3.0, 1.0, 5.0, -1.0, -5.0);
780 
781   // Check the sign of exact zeroes.
782   //               n     m     a     fmadd  fmsub  fnmadd fnmsub
783   FmaddFmsubHelper(-0.0, +0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
784   FmaddFmsubHelper(+0.0, +0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
785   FmaddFmsubHelper(+0.0, +0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
786   FmaddFmsubHelper(-0.0, +0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
787   FmaddFmsubHelper(+0.0, -0.0, -0.0, -0.0, +0.0, +0.0, +0.0);
788   FmaddFmsubHelper(-0.0, -0.0, -0.0, +0.0, -0.0, +0.0, +0.0);
789   FmaddFmsubHelper(-0.0, -0.0, +0.0, +0.0, +0.0, -0.0, +0.0);
790   FmaddFmsubHelper(+0.0, -0.0, +0.0, +0.0, +0.0, +0.0, -0.0);
791 
792   // Check NaN generation.
793   FmaddFmsubHelper(kFP64PositiveInfinity,
794                    0.0,
795                    42.0,
796                    kFP64DefaultNaN,
797                    kFP64DefaultNaN,
798                    kFP64DefaultNaN,
799                    kFP64DefaultNaN);
800   FmaddFmsubHelper(0.0,
801                    kFP64PositiveInfinity,
802                    42.0,
803                    kFP64DefaultNaN,
804                    kFP64DefaultNaN,
805                    kFP64DefaultNaN,
806                    kFP64DefaultNaN);
807   FmaddFmsubHelper(kFP64PositiveInfinity,
808                    1.0,
809                    kFP64PositiveInfinity,
810                    kFP64PositiveInfinity,  //  inf + ( inf * 1) = inf
811                    kFP64DefaultNaN,        //  inf + (-inf * 1) = NaN
812                    kFP64NegativeInfinity,  // -inf + (-inf * 1) = -inf
813                    kFP64DefaultNaN);       // -inf + ( inf * 1) = NaN
814   FmaddFmsubHelper(kFP64NegativeInfinity,
815                    1.0,
816                    kFP64PositiveInfinity,
817                    kFP64DefaultNaN,         //  inf + (-inf * 1) = NaN
818                    kFP64PositiveInfinity,   //  inf + ( inf * 1) = inf
819                    kFP64DefaultNaN,         // -inf + ( inf * 1) = NaN
820                    kFP64NegativeInfinity);  // -inf + (-inf * 1) = -inf
821 }
822 
823 
FmaddFmsubHelper(float n,float m,float a,float fmadd,float fmsub,float fnmadd,float fnmsub)824 static void FmaddFmsubHelper(float n,
825                              float m,
826                              float a,
827                              float fmadd,
828                              float fmsub,
829                              float fnmadd,
830                              float fnmsub) {
831   SETUP_WITH_FEATURES(CPUFeatures::kFP);
832 
833   START();
834 
835   __ Fmov(s0, n);
836   __ Fmov(s1, m);
837   __ Fmov(s2, a);
838   __ Fmadd(s28, s0, s1, s2);
839   __ Fmsub(s29, s0, s1, s2);
840   __ Fnmadd(s30, s0, s1, s2);
841   __ Fnmsub(s31, s0, s1, s2);
842 
843   END();
844   if (CAN_RUN()) {
845     RUN();
846 
847     ASSERT_EQUAL_FP32(fmadd, s28);
848     ASSERT_EQUAL_FP32(fmsub, s29);
849     ASSERT_EQUAL_FP32(fnmadd, s30);
850     ASSERT_EQUAL_FP32(fnmsub, s31);
851   }
852 }
853 
854 
TEST(fmadd_fmsub_float)855 TEST(fmadd_fmsub_float) {
856   // It's hard to check the result of fused operations because the only way to
857   // calculate the result is using fma, which is what the simulator uses anyway.
858 
859   // Basic operation.
860   FmaddFmsubHelper(1.0f, 2.0f, 3.0f, 5.0f, 1.0f, -5.0f, -1.0f);
861   FmaddFmsubHelper(-1.0f, 2.0f, 3.0f, 1.0f, 5.0f, -1.0f, -5.0f);
862 
863   // Check the sign of exact zeroes.
864   //               n      m      a      fmadd  fmsub  fnmadd fnmsub
865   FmaddFmsubHelper(-0.0f, +0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
866   FmaddFmsubHelper(+0.0f, +0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
867   FmaddFmsubHelper(+0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
868   FmaddFmsubHelper(-0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
869   FmaddFmsubHelper(+0.0f, -0.0f, -0.0f, -0.0f, +0.0f, +0.0f, +0.0f);
870   FmaddFmsubHelper(-0.0f, -0.0f, -0.0f, +0.0f, -0.0f, +0.0f, +0.0f);
871   FmaddFmsubHelper(-0.0f, -0.0f, +0.0f, +0.0f, +0.0f, -0.0f, +0.0f);
872   FmaddFmsubHelper(+0.0f, -0.0f, +0.0f, +0.0f, +0.0f, +0.0f, -0.0f);
873 
874   // Check NaN generation.
875   FmaddFmsubHelper(kFP32PositiveInfinity,
876                    0.0f,
877                    42.0f,
878                    kFP32DefaultNaN,
879                    kFP32DefaultNaN,
880                    kFP32DefaultNaN,
881                    kFP32DefaultNaN);
882   FmaddFmsubHelper(0.0f,
883                    kFP32PositiveInfinity,
884                    42.0f,
885                    kFP32DefaultNaN,
886                    kFP32DefaultNaN,
887                    kFP32DefaultNaN,
888                    kFP32DefaultNaN);
889   FmaddFmsubHelper(kFP32PositiveInfinity,
890                    1.0f,
891                    kFP32PositiveInfinity,
892                    kFP32PositiveInfinity,  //  inf + ( inf * 1) = inf
893                    kFP32DefaultNaN,        //  inf + (-inf * 1) = NaN
894                    kFP32NegativeInfinity,  // -inf + (-inf * 1) = -inf
895                    kFP32DefaultNaN);       // -inf + ( inf * 1) = NaN
896   FmaddFmsubHelper(kFP32NegativeInfinity,
897                    1.0f,
898                    kFP32PositiveInfinity,
899                    kFP32DefaultNaN,         //  inf + (-inf * 1) = NaN
900                    kFP32PositiveInfinity,   //  inf + ( inf * 1) = inf
901                    kFP32DefaultNaN,         // -inf + ( inf * 1) = NaN
902                    kFP32NegativeInfinity);  // -inf + (-inf * 1) = -inf
903 }
904 
905 
TEST(fmadd_fmsub_double_nans)906 TEST(fmadd_fmsub_double_nans) {
907   // Make sure that NaN propagation works correctly.
908   double sig1 = RawbitsToDouble(0x7ff5555511111111);
909   double sig2 = RawbitsToDouble(0x7ff5555522222222);
910   double siga = RawbitsToDouble(0x7ff55555aaaaaaaa);
911   double qui1 = RawbitsToDouble(0x7ffaaaaa11111111);
912   double qui2 = RawbitsToDouble(0x7ffaaaaa22222222);
913   double quia = RawbitsToDouble(0x7ffaaaaaaaaaaaaa);
914   VIXL_ASSERT(IsSignallingNaN(sig1));
915   VIXL_ASSERT(IsSignallingNaN(sig2));
916   VIXL_ASSERT(IsSignallingNaN(siga));
917   VIXL_ASSERT(IsQuietNaN(qui1));
918   VIXL_ASSERT(IsQuietNaN(qui2));
919   VIXL_ASSERT(IsQuietNaN(quia));
920 
921   // The input NaNs after passing through ProcessNaN.
922   double sig1_proc = RawbitsToDouble(0x7ffd555511111111);
923   double sig2_proc = RawbitsToDouble(0x7ffd555522222222);
924   double siga_proc = RawbitsToDouble(0x7ffd5555aaaaaaaa);
925   double qui1_proc = qui1;
926   double qui2_proc = qui2;
927   double quia_proc = quia;
928   VIXL_ASSERT(IsQuietNaN(sig1_proc));
929   VIXL_ASSERT(IsQuietNaN(sig2_proc));
930   VIXL_ASSERT(IsQuietNaN(siga_proc));
931   VIXL_ASSERT(IsQuietNaN(qui1_proc));
932   VIXL_ASSERT(IsQuietNaN(qui2_proc));
933   VIXL_ASSERT(IsQuietNaN(quia_proc));
934 
935   // Negated NaNs as it would be done on ARMv8 hardware.
936   double sig1_proc_neg = RawbitsToDouble(0xfffd555511111111);
937   double siga_proc_neg = RawbitsToDouble(0xfffd5555aaaaaaaa);
938   double qui1_proc_neg = RawbitsToDouble(0xfffaaaaa11111111);
939   double quia_proc_neg = RawbitsToDouble(0xfffaaaaaaaaaaaaa);
940   VIXL_ASSERT(IsQuietNaN(sig1_proc_neg));
941   VIXL_ASSERT(IsQuietNaN(siga_proc_neg));
942   VIXL_ASSERT(IsQuietNaN(qui1_proc_neg));
943   VIXL_ASSERT(IsQuietNaN(quia_proc_neg));
944 
945   // Quiet NaNs are propagated.
946   FmaddFmsubHelper(qui1,
947                    0,
948                    0,
949                    qui1_proc,
950                    qui1_proc_neg,
951                    qui1_proc_neg,
952                    qui1_proc);
953   FmaddFmsubHelper(0, qui2, 0, qui2_proc, qui2_proc, qui2_proc, qui2_proc);
954   FmaddFmsubHelper(0,
955                    0,
956                    quia,
957                    quia_proc,
958                    quia_proc,
959                    quia_proc_neg,
960                    quia_proc_neg);
961   FmaddFmsubHelper(qui1,
962                    qui2,
963                    0,
964                    qui1_proc,
965                    qui1_proc_neg,
966                    qui1_proc_neg,
967                    qui1_proc);
968   FmaddFmsubHelper(0,
969                    qui2,
970                    quia,
971                    quia_proc,
972                    quia_proc,
973                    quia_proc_neg,
974                    quia_proc_neg);
975   FmaddFmsubHelper(qui1,
976                    0,
977                    quia,
978                    quia_proc,
979                    quia_proc,
980                    quia_proc_neg,
981                    quia_proc_neg);
982   FmaddFmsubHelper(qui1,
983                    qui2,
984                    quia,
985                    quia_proc,
986                    quia_proc,
987                    quia_proc_neg,
988                    quia_proc_neg);
989 
990   // Signalling NaNs are propagated, and made quiet.
991   FmaddFmsubHelper(sig1,
992                    0,
993                    0,
994                    sig1_proc,
995                    sig1_proc_neg,
996                    sig1_proc_neg,
997                    sig1_proc);
998   FmaddFmsubHelper(0, sig2, 0, sig2_proc, sig2_proc, sig2_proc, sig2_proc);
999   FmaddFmsubHelper(0,
1000                    0,
1001                    siga,
1002                    siga_proc,
1003                    siga_proc,
1004                    siga_proc_neg,
1005                    siga_proc_neg);
1006   FmaddFmsubHelper(sig1,
1007                    sig2,
1008                    0,
1009                    sig1_proc,
1010                    sig1_proc_neg,
1011                    sig1_proc_neg,
1012                    sig1_proc);
1013   FmaddFmsubHelper(0,
1014                    sig2,
1015                    siga,
1016                    siga_proc,
1017                    siga_proc,
1018                    siga_proc_neg,
1019                    siga_proc_neg);
1020   FmaddFmsubHelper(sig1,
1021                    0,
1022                    siga,
1023                    siga_proc,
1024                    siga_proc,
1025                    siga_proc_neg,
1026                    siga_proc_neg);
1027   FmaddFmsubHelper(sig1,
1028                    sig2,
1029                    siga,
1030                    siga_proc,
1031                    siga_proc,
1032                    siga_proc_neg,
1033                    siga_proc_neg);
1034 
1035   // Signalling NaNs take precedence over quiet NaNs.
1036   FmaddFmsubHelper(sig1,
1037                    qui2,
1038                    quia,
1039                    sig1_proc,
1040                    sig1_proc_neg,
1041                    sig1_proc_neg,
1042                    sig1_proc);
1043   FmaddFmsubHelper(qui1,
1044                    sig2,
1045                    quia,
1046                    sig2_proc,
1047                    sig2_proc,
1048                    sig2_proc,
1049                    sig2_proc);
1050   FmaddFmsubHelper(qui1,
1051                    qui2,
1052                    siga,
1053                    siga_proc,
1054                    siga_proc,
1055                    siga_proc_neg,
1056                    siga_proc_neg);
1057   FmaddFmsubHelper(sig1,
1058                    sig2,
1059                    quia,
1060                    sig1_proc,
1061                    sig1_proc_neg,
1062                    sig1_proc_neg,
1063                    sig1_proc);
1064   FmaddFmsubHelper(qui1,
1065                    sig2,
1066                    siga,
1067                    siga_proc,
1068                    siga_proc,
1069                    siga_proc_neg,
1070                    siga_proc_neg);
1071   FmaddFmsubHelper(sig1,
1072                    qui2,
1073                    siga,
1074                    siga_proc,
1075                    siga_proc,
1076                    siga_proc_neg,
1077                    siga_proc_neg);
1078   FmaddFmsubHelper(sig1,
1079                    sig2,
1080                    siga,
1081                    siga_proc,
1082                    siga_proc,
1083                    siga_proc_neg,
1084                    siga_proc_neg);
1085 
1086   // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
1087   FmaddFmsubHelper(0,
1088                    kFP64PositiveInfinity,
1089                    quia,
1090                    kFP64DefaultNaN,
1091                    kFP64DefaultNaN,
1092                    kFP64DefaultNaN,
1093                    kFP64DefaultNaN);
1094   FmaddFmsubHelper(kFP64PositiveInfinity,
1095                    0,
1096                    quia,
1097                    kFP64DefaultNaN,
1098                    kFP64DefaultNaN,
1099                    kFP64DefaultNaN,
1100                    kFP64DefaultNaN);
1101   FmaddFmsubHelper(0,
1102                    kFP64NegativeInfinity,
1103                    quia,
1104                    kFP64DefaultNaN,
1105                    kFP64DefaultNaN,
1106                    kFP64DefaultNaN,
1107                    kFP64DefaultNaN);
1108   FmaddFmsubHelper(kFP64NegativeInfinity,
1109                    0,
1110                    quia,
1111                    kFP64DefaultNaN,
1112                    kFP64DefaultNaN,
1113                    kFP64DefaultNaN,
1114                    kFP64DefaultNaN);
1115 }
1116 
1117 
TEST(fmadd_fmsub_float_nans)1118 TEST(fmadd_fmsub_float_nans) {
1119   // Make sure that NaN propagation works correctly.
1120   float sig1 = RawbitsToFloat(0x7f951111);
1121   float sig2 = RawbitsToFloat(0x7f952222);
1122   float siga = RawbitsToFloat(0x7f95aaaa);
1123   float qui1 = RawbitsToFloat(0x7fea1111);
1124   float qui2 = RawbitsToFloat(0x7fea2222);
1125   float quia = RawbitsToFloat(0x7feaaaaa);
1126   VIXL_ASSERT(IsSignallingNaN(sig1));
1127   VIXL_ASSERT(IsSignallingNaN(sig2));
1128   VIXL_ASSERT(IsSignallingNaN(siga));
1129   VIXL_ASSERT(IsQuietNaN(qui1));
1130   VIXL_ASSERT(IsQuietNaN(qui2));
1131   VIXL_ASSERT(IsQuietNaN(quia));
1132 
1133   // The input NaNs after passing through ProcessNaN.
1134   float sig1_proc = RawbitsToFloat(0x7fd51111);
1135   float sig2_proc = RawbitsToFloat(0x7fd52222);
1136   float siga_proc = RawbitsToFloat(0x7fd5aaaa);
1137   float qui1_proc = qui1;
1138   float qui2_proc = qui2;
1139   float quia_proc = quia;
1140   VIXL_ASSERT(IsQuietNaN(sig1_proc));
1141   VIXL_ASSERT(IsQuietNaN(sig2_proc));
1142   VIXL_ASSERT(IsQuietNaN(siga_proc));
1143   VIXL_ASSERT(IsQuietNaN(qui1_proc));
1144   VIXL_ASSERT(IsQuietNaN(qui2_proc));
1145   VIXL_ASSERT(IsQuietNaN(quia_proc));
1146 
1147   // Negated NaNs as it would be done on ARMv8 hardware.
1148   float sig1_proc_neg = RawbitsToFloat(0xffd51111);
1149   float siga_proc_neg = RawbitsToFloat(0xffd5aaaa);
1150   float qui1_proc_neg = RawbitsToFloat(0xffea1111);
1151   float quia_proc_neg = RawbitsToFloat(0xffeaaaaa);
1152   VIXL_ASSERT(IsQuietNaN(sig1_proc_neg));
1153   VIXL_ASSERT(IsQuietNaN(siga_proc_neg));
1154   VIXL_ASSERT(IsQuietNaN(qui1_proc_neg));
1155   VIXL_ASSERT(IsQuietNaN(quia_proc_neg));
1156 
1157   // Quiet NaNs are propagated.
1158   FmaddFmsubHelper(qui1,
1159                    0,
1160                    0,
1161                    qui1_proc,
1162                    qui1_proc_neg,
1163                    qui1_proc_neg,
1164                    qui1_proc);
1165   FmaddFmsubHelper(0, qui2, 0, qui2_proc, qui2_proc, qui2_proc, qui2_proc);
1166   FmaddFmsubHelper(0,
1167                    0,
1168                    quia,
1169                    quia_proc,
1170                    quia_proc,
1171                    quia_proc_neg,
1172                    quia_proc_neg);
1173   FmaddFmsubHelper(qui1,
1174                    qui2,
1175                    0,
1176                    qui1_proc,
1177                    qui1_proc_neg,
1178                    qui1_proc_neg,
1179                    qui1_proc);
1180   FmaddFmsubHelper(0,
1181                    qui2,
1182                    quia,
1183                    quia_proc,
1184                    quia_proc,
1185                    quia_proc_neg,
1186                    quia_proc_neg);
1187   FmaddFmsubHelper(qui1,
1188                    0,
1189                    quia,
1190                    quia_proc,
1191                    quia_proc,
1192                    quia_proc_neg,
1193                    quia_proc_neg);
1194   FmaddFmsubHelper(qui1,
1195                    qui2,
1196                    quia,
1197                    quia_proc,
1198                    quia_proc,
1199                    quia_proc_neg,
1200                    quia_proc_neg);
1201 
1202   // Signalling NaNs are propagated, and made quiet.
1203   FmaddFmsubHelper(sig1,
1204                    0,
1205                    0,
1206                    sig1_proc,
1207                    sig1_proc_neg,
1208                    sig1_proc_neg,
1209                    sig1_proc);
1210   FmaddFmsubHelper(0, sig2, 0, sig2_proc, sig2_proc, sig2_proc, sig2_proc);
1211   FmaddFmsubHelper(0,
1212                    0,
1213                    siga,
1214                    siga_proc,
1215                    siga_proc,
1216                    siga_proc_neg,
1217                    siga_proc_neg);
1218   FmaddFmsubHelper(sig1,
1219                    sig2,
1220                    0,
1221                    sig1_proc,
1222                    sig1_proc_neg,
1223                    sig1_proc_neg,
1224                    sig1_proc);
1225   FmaddFmsubHelper(0,
1226                    sig2,
1227                    siga,
1228                    siga_proc,
1229                    siga_proc,
1230                    siga_proc_neg,
1231                    siga_proc_neg);
1232   FmaddFmsubHelper(sig1,
1233                    0,
1234                    siga,
1235                    siga_proc,
1236                    siga_proc,
1237                    siga_proc_neg,
1238                    siga_proc_neg);
1239   FmaddFmsubHelper(sig1,
1240                    sig2,
1241                    siga,
1242                    siga_proc,
1243                    siga_proc,
1244                    siga_proc_neg,
1245                    siga_proc_neg);
1246 
1247   // Signalling NaNs take precedence over quiet NaNs.
1248   FmaddFmsubHelper(sig1,
1249                    qui2,
1250                    quia,
1251                    sig1_proc,
1252                    sig1_proc_neg,
1253                    sig1_proc_neg,
1254                    sig1_proc);
1255   FmaddFmsubHelper(qui1,
1256                    sig2,
1257                    quia,
1258                    sig2_proc,
1259                    sig2_proc,
1260                    sig2_proc,
1261                    sig2_proc);
1262   FmaddFmsubHelper(qui1,
1263                    qui2,
1264                    siga,
1265                    siga_proc,
1266                    siga_proc,
1267                    siga_proc_neg,
1268                    siga_proc_neg);
1269   FmaddFmsubHelper(sig1,
1270                    sig2,
1271                    quia,
1272                    sig1_proc,
1273                    sig1_proc_neg,
1274                    sig1_proc_neg,
1275                    sig1_proc);
1276   FmaddFmsubHelper(qui1,
1277                    sig2,
1278                    siga,
1279                    siga_proc,
1280                    siga_proc,
1281                    siga_proc_neg,
1282                    siga_proc_neg);
1283   FmaddFmsubHelper(sig1,
1284                    qui2,
1285                    siga,
1286                    siga_proc,
1287                    siga_proc,
1288                    siga_proc_neg,
1289                    siga_proc_neg);
1290   FmaddFmsubHelper(sig1,
1291                    sig2,
1292                    siga,
1293                    siga_proc,
1294                    siga_proc,
1295                    siga_proc_neg,
1296                    siga_proc_neg);
1297 
1298   // A NaN generated by the intermediate op1 * op2 overrides a quiet NaN in a.
1299   FmaddFmsubHelper(0,
1300                    kFP32PositiveInfinity,
1301                    quia,
1302                    kFP32DefaultNaN,
1303                    kFP32DefaultNaN,
1304                    kFP32DefaultNaN,
1305                    kFP32DefaultNaN);
1306   FmaddFmsubHelper(kFP32PositiveInfinity,
1307                    0,
1308                    quia,
1309                    kFP32DefaultNaN,
1310                    kFP32DefaultNaN,
1311                    kFP32DefaultNaN,
1312                    kFP32DefaultNaN);
1313   FmaddFmsubHelper(0,
1314                    kFP32NegativeInfinity,
1315                    quia,
1316                    kFP32DefaultNaN,
1317                    kFP32DefaultNaN,
1318                    kFP32DefaultNaN,
1319                    kFP32DefaultNaN);
1320   FmaddFmsubHelper(kFP32NegativeInfinity,
1321                    0,
1322                    quia,
1323                    kFP32DefaultNaN,
1324                    kFP32DefaultNaN,
1325                    kFP32DefaultNaN,
1326                    kFP32DefaultNaN);
1327 }
1328 
1329 
TEST(fdiv)1330 TEST(fdiv) {
1331   SETUP_WITH_FEATURES(CPUFeatures::kFP);
1332 
1333   START();
1334   __ Fmov(s14, -0.0f);
1335   __ Fmov(s15, kFP32PositiveInfinity);
1336   __ Fmov(s16, kFP32NegativeInfinity);
1337   __ Fmov(s17, 3.25f);
1338   __ Fmov(s18, 2.0f);
1339   __ Fmov(s19, 2.0f);
1340   __ Fmov(s20, -2.0f);
1341 
1342   __ Fmov(d26, -0.0);
1343   __ Fmov(d27, kFP64PositiveInfinity);
1344   __ Fmov(d28, kFP64NegativeInfinity);
1345   __ Fmov(d29, 0.0);
1346   __ Fmov(d30, -2.0);
1347   __ Fmov(d31, 2.25);
1348 
1349   __ Fdiv(s0, s17, s18);
1350   __ Fdiv(s1, s18, s19);
1351   __ Fdiv(s2, s14, s18);
1352   __ Fdiv(s3, s18, s15);
1353   __ Fdiv(s4, s18, s16);
1354   __ Fdiv(s5, s15, s16);
1355   __ Fdiv(s6, s14, s14);
1356 
1357   __ Fdiv(d7, d31, d30);
1358   __ Fdiv(d8, d29, d31);
1359   __ Fdiv(d9, d26, d31);
1360   __ Fdiv(d10, d31, d27);
1361   __ Fdiv(d11, d31, d28);
1362   __ Fdiv(d12, d28, d27);
1363   __ Fdiv(d13, d29, d29);
1364   END();
1365 
1366   if (CAN_RUN()) {
1367     RUN();
1368 
1369     ASSERT_EQUAL_FP32(1.625f, s0);
1370     ASSERT_EQUAL_FP32(1.0f, s1);
1371     ASSERT_EQUAL_FP32(-0.0f, s2);
1372     ASSERT_EQUAL_FP32(0.0f, s3);
1373     ASSERT_EQUAL_FP32(-0.0f, s4);
1374     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s5);
1375     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
1376     ASSERT_EQUAL_FP64(-1.125, d7);
1377     ASSERT_EQUAL_FP64(0.0, d8);
1378     ASSERT_EQUAL_FP64(-0.0, d9);
1379     ASSERT_EQUAL_FP64(0.0, d10);
1380     ASSERT_EQUAL_FP64(-0.0, d11);
1381     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d12);
1382     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
1383   }
1384 }
1385 
1386 
TEST(fdiv_h)1387 TEST(fdiv_h) {
1388   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
1389 
1390   START();
1391   __ Fmov(h14, -0.0f);
1392   __ Fmov(h15, kFP16PositiveInfinity);
1393   __ Fmov(h16, kFP16NegativeInfinity);
1394   __ Fmov(h17, 3.25f);
1395   __ Fmov(h18, 2.0f);
1396   __ Fmov(h19, 2.0f);
1397   __ Fmov(h20, -2.0f);
1398 
1399   __ Fdiv(h0, h17, h18);
1400   __ Fdiv(h1, h18, h19);
1401   __ Fdiv(h2, h14, h18);
1402   __ Fdiv(h3, h18, h15);
1403   __ Fdiv(h4, h18, h16);
1404   __ Fdiv(h5, h15, h16);
1405   __ Fdiv(h6, h14, h14);
1406   END();
1407 
1408   if (CAN_RUN()) {
1409     RUN();
1410 
1411     ASSERT_EQUAL_FP16(Float16(1.625f), h0);
1412     ASSERT_EQUAL_FP16(Float16(1.0f), h1);
1413     ASSERT_EQUAL_FP16(Float16(-0.0f), h2);
1414     ASSERT_EQUAL_FP16(Float16(0.0f), h3);
1415     ASSERT_EQUAL_FP16(Float16(-0.0f), h4);
1416     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h5);
1417     ASSERT_EQUAL_FP16(kFP16DefaultNaN, h6);
1418   }
1419 }
1420 
MinMaxHelper(float n,float m,bool min,float quiet_nan_substitute=0.0)1421 static float MinMaxHelper(float n,
1422                           float m,
1423                           bool min,
1424                           float quiet_nan_substitute = 0.0) {
1425   const uint64_t kFP32QuietNaNMask = 0x00400000;
1426   uint32_t raw_n = FloatToRawbits(n);
1427   uint32_t raw_m = FloatToRawbits(m);
1428 
1429   if (IsNaN(n) && ((raw_n & kFP32QuietNaNMask) == 0)) {
1430     // n is signalling NaN.
1431     return RawbitsToFloat(raw_n | kFP32QuietNaNMask);
1432   } else if (IsNaN(m) && ((raw_m & kFP32QuietNaNMask) == 0)) {
1433     // m is signalling NaN.
1434     return RawbitsToFloat(raw_m | kFP32QuietNaNMask);
1435   } else if (quiet_nan_substitute == 0.0) {
1436     if (IsNaN(n)) {
1437       // n is quiet NaN.
1438       return n;
1439     } else if (IsNaN(m)) {
1440       // m is quiet NaN.
1441       return m;
1442     }
1443   } else {
1444     // Substitute n or m if one is quiet, but not both.
1445     if (IsNaN(n) && !IsNaN(m)) {
1446       // n is quiet NaN: replace with substitute.
1447       n = quiet_nan_substitute;
1448     } else if (!IsNaN(n) && IsNaN(m)) {
1449       // m is quiet NaN: replace with substitute.
1450       m = quiet_nan_substitute;
1451     }
1452   }
1453 
1454   if ((n == 0.0) && (m == 0.0) && (copysign(1.0, n) != copysign(1.0, m))) {
1455     return min ? -0.0 : 0.0;
1456   }
1457 
1458   return min ? fminf(n, m) : fmaxf(n, m);
1459 }
1460 
1461 
MinMaxHelper(double n,double m,bool min,double quiet_nan_substitute=0.0)1462 static double MinMaxHelper(double n,
1463                            double m,
1464                            bool min,
1465                            double quiet_nan_substitute = 0.0) {
1466   const uint64_t kFP64QuietNaNMask = 0x0008000000000000;
1467   uint64_t raw_n = DoubleToRawbits(n);
1468   uint64_t raw_m = DoubleToRawbits(m);
1469 
1470   if (IsNaN(n) && ((raw_n & kFP64QuietNaNMask) == 0)) {
1471     // n is signalling NaN.
1472     return RawbitsToDouble(raw_n | kFP64QuietNaNMask);
1473   } else if (IsNaN(m) && ((raw_m & kFP64QuietNaNMask) == 0)) {
1474     // m is signalling NaN.
1475     return RawbitsToDouble(raw_m | kFP64QuietNaNMask);
1476   } else if (quiet_nan_substitute == 0.0) {
1477     if (IsNaN(n)) {
1478       // n is quiet NaN.
1479       return n;
1480     } else if (IsNaN(m)) {
1481       // m is quiet NaN.
1482       return m;
1483     }
1484   } else {
1485     // Substitute n or m if one is quiet, but not both.
1486     if (IsNaN(n) && !IsNaN(m)) {
1487       // n is quiet NaN: replace with substitute.
1488       n = quiet_nan_substitute;
1489     } else if (!IsNaN(n) && IsNaN(m)) {
1490       // m is quiet NaN: replace with substitute.
1491       m = quiet_nan_substitute;
1492     }
1493   }
1494 
1495   if ((n == 0.0) && (m == 0.0) && (copysign(1.0, n) != copysign(1.0, m))) {
1496     return min ? -0.0 : 0.0;
1497   }
1498 
1499   return min ? fmin(n, m) : fmax(n, m);
1500 }
1501 
1502 
FminFmaxDoubleHelper(double n,double m,double min,double max,double minnm,double maxnm)1503 static void FminFmaxDoubleHelper(
1504     double n, double m, double min, double max, double minnm, double maxnm) {
1505   SETUP_WITH_FEATURES(CPUFeatures::kFP);
1506 
1507   START();
1508   __ Fmov(d0, n);
1509   __ Fmov(d1, m);
1510   __ Fmin(d28, d0, d1);
1511   __ Fmax(d29, d0, d1);
1512   __ Fminnm(d30, d0, d1);
1513   __ Fmaxnm(d31, d0, d1);
1514   END();
1515 
1516   if (CAN_RUN()) {
1517     RUN();
1518 
1519     ASSERT_EQUAL_FP64(min, d28);
1520     ASSERT_EQUAL_FP64(max, d29);
1521     ASSERT_EQUAL_FP64(minnm, d30);
1522     ASSERT_EQUAL_FP64(maxnm, d31);
1523   }
1524 }
1525 
1526 
TEST(fmax_fmin_d)1527 TEST(fmax_fmin_d) {
1528   // Use non-standard NaNs to check that the payload bits are preserved.
1529   double snan = RawbitsToDouble(0x7ff5555512345678);
1530   double qnan = RawbitsToDouble(0x7ffaaaaa87654321);
1531 
1532   double snan_processed = RawbitsToDouble(0x7ffd555512345678);
1533   double qnan_processed = qnan;
1534 
1535   VIXL_ASSERT(IsSignallingNaN(snan));
1536   VIXL_ASSERT(IsQuietNaN(qnan));
1537   VIXL_ASSERT(IsQuietNaN(snan_processed));
1538   VIXL_ASSERT(IsQuietNaN(qnan_processed));
1539 
1540   // Bootstrap tests.
1541   FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0);
1542   FminFmaxDoubleHelper(0, 1, 0, 1, 0, 1);
1543   FminFmaxDoubleHelper(kFP64PositiveInfinity,
1544                        kFP64NegativeInfinity,
1545                        kFP64NegativeInfinity,
1546                        kFP64PositiveInfinity,
1547                        kFP64NegativeInfinity,
1548                        kFP64PositiveInfinity);
1549   FminFmaxDoubleHelper(snan,
1550                        0,
1551                        snan_processed,
1552                        snan_processed,
1553                        snan_processed,
1554                        snan_processed);
1555   FminFmaxDoubleHelper(0,
1556                        snan,
1557                        snan_processed,
1558                        snan_processed,
1559                        snan_processed,
1560                        snan_processed);
1561   FminFmaxDoubleHelper(qnan, 0, qnan_processed, qnan_processed, 0, 0);
1562   FminFmaxDoubleHelper(0, qnan, qnan_processed, qnan_processed, 0, 0);
1563   FminFmaxDoubleHelper(qnan,
1564                        snan,
1565                        snan_processed,
1566                        snan_processed,
1567                        snan_processed,
1568                        snan_processed);
1569   FminFmaxDoubleHelper(snan,
1570                        qnan,
1571                        snan_processed,
1572                        snan_processed,
1573                        snan_processed,
1574                        snan_processed);
1575 
1576   // Iterate over all combinations of inputs.
1577   double inputs[] = {DBL_MAX,
1578                      DBL_MIN,
1579                      1.0,
1580                      0.0,
1581                      -DBL_MAX,
1582                      -DBL_MIN,
1583                      -1.0,
1584                      -0.0,
1585                      kFP64PositiveInfinity,
1586                      kFP64NegativeInfinity,
1587                      kFP64QuietNaN,
1588                      kFP64SignallingNaN};
1589 
1590   const int count = sizeof(inputs) / sizeof(inputs[0]);
1591 
1592   for (int in = 0; in < count; in++) {
1593     double n = inputs[in];
1594     for (int im = 0; im < count; im++) {
1595       double m = inputs[im];
1596       FminFmaxDoubleHelper(n,
1597                            m,
1598                            MinMaxHelper(n, m, true),
1599                            MinMaxHelper(n, m, false),
1600                            MinMaxHelper(n, m, true, kFP64PositiveInfinity),
1601                            MinMaxHelper(n, m, false, kFP64NegativeInfinity));
1602     }
1603   }
1604 }
1605 
1606 
FminFmaxFloatHelper(float n,float m,float min,float max,float minnm,float maxnm)1607 static void FminFmaxFloatHelper(
1608     float n, float m, float min, float max, float minnm, float maxnm) {
1609   SETUP_WITH_FEATURES(CPUFeatures::kFP);
1610 
1611   START();
1612   __ Fmov(s0, n);
1613   __ Fmov(s1, m);
1614   __ Fmin(s28, s0, s1);
1615   __ Fmax(s29, s0, s1);
1616   __ Fminnm(s30, s0, s1);
1617   __ Fmaxnm(s31, s0, s1);
1618   END();
1619 
1620   if (CAN_RUN()) {
1621     RUN();
1622 
1623     ASSERT_EQUAL_FP32(min, s28);
1624     ASSERT_EQUAL_FP32(max, s29);
1625     ASSERT_EQUAL_FP32(minnm, s30);
1626     ASSERT_EQUAL_FP32(maxnm, s31);
1627   }
1628 }
1629 
1630 
TEST(fmax_fmin_s)1631 TEST(fmax_fmin_s) {
1632   // Use non-standard NaNs to check that the payload bits are preserved.
1633   float snan = RawbitsToFloat(0x7f951234);
1634   float qnan = RawbitsToFloat(0x7fea8765);
1635 
1636   float snan_processed = RawbitsToFloat(0x7fd51234);
1637   float qnan_processed = qnan;
1638 
1639   VIXL_ASSERT(IsSignallingNaN(snan));
1640   VIXL_ASSERT(IsQuietNaN(qnan));
1641   VIXL_ASSERT(IsQuietNaN(snan_processed));
1642   VIXL_ASSERT(IsQuietNaN(qnan_processed));
1643 
1644   // Bootstrap tests.
1645   FminFmaxFloatHelper(0, 0, 0, 0, 0, 0);
1646   FminFmaxFloatHelper(0, 1, 0, 1, 0, 1);
1647   FminFmaxFloatHelper(kFP32PositiveInfinity,
1648                       kFP32NegativeInfinity,
1649                       kFP32NegativeInfinity,
1650                       kFP32PositiveInfinity,
1651                       kFP32NegativeInfinity,
1652                       kFP32PositiveInfinity);
1653   FminFmaxFloatHelper(snan,
1654                       0,
1655                       snan_processed,
1656                       snan_processed,
1657                       snan_processed,
1658                       snan_processed);
1659   FminFmaxFloatHelper(0,
1660                       snan,
1661                       snan_processed,
1662                       snan_processed,
1663                       snan_processed,
1664                       snan_processed);
1665   FminFmaxFloatHelper(qnan, 0, qnan_processed, qnan_processed, 0, 0);
1666   FminFmaxFloatHelper(0, qnan, qnan_processed, qnan_processed, 0, 0);
1667   FminFmaxFloatHelper(qnan,
1668                       snan,
1669                       snan_processed,
1670                       snan_processed,
1671                       snan_processed,
1672                       snan_processed);
1673   FminFmaxFloatHelper(snan,
1674                       qnan,
1675                       snan_processed,
1676                       snan_processed,
1677                       snan_processed,
1678                       snan_processed);
1679 
1680   // Iterate over all combinations of inputs.
1681   float inputs[] = {FLT_MAX,
1682                     FLT_MIN,
1683                     1.0,
1684                     0.0,
1685                     -FLT_MAX,
1686                     -FLT_MIN,
1687                     -1.0,
1688                     -0.0,
1689                     kFP32PositiveInfinity,
1690                     kFP32NegativeInfinity,
1691                     kFP32QuietNaN,
1692                     kFP32SignallingNaN};
1693 
1694   const int count = sizeof(inputs) / sizeof(inputs[0]);
1695 
1696   for (int in = 0; in < count; in++) {
1697     float n = inputs[in];
1698     for (int im = 0; im < count; im++) {
1699       float m = inputs[im];
1700       FminFmaxFloatHelper(n,
1701                           m,
1702                           MinMaxHelper(n, m, true),
1703                           MinMaxHelper(n, m, false),
1704                           MinMaxHelper(n, m, true, kFP32PositiveInfinity),
1705                           MinMaxHelper(n, m, false, kFP32NegativeInfinity));
1706     }
1707   }
1708 }
1709 
TEST(fccmp)1710 TEST(fccmp) {
1711   SETUP_WITH_FEATURES(CPUFeatures::kFP);
1712 
1713   START();
1714   __ Fmov(s16, 0.0);
1715   __ Fmov(s17, 0.5);
1716   __ Fmov(d18, -0.5);
1717   __ Fmov(d19, -1.0);
1718   __ Mov(x20, 0);
1719   __ Mov(x21, 0x7ff0000000000001);  // Double precision NaN.
1720   __ Fmov(d21, x21);
1721   __ Mov(w22, 0x7f800001);  // Single precision NaN.
1722   __ Fmov(s22, w22);
1723 
1724   __ Cmp(x20, 0);
1725   __ Fccmp(s16, s16, NoFlag, eq);
1726   __ Mrs(x0, NZCV);
1727 
1728   __ Cmp(x20, 0);
1729   __ Fccmp(s16, s16, VFlag, ne);
1730   __ Mrs(x1, NZCV);
1731 
1732   __ Cmp(x20, 0);
1733   __ Fccmp(s16, s17, CFlag, ge);
1734   __ Mrs(x2, NZCV);
1735 
1736   __ Cmp(x20, 0);
1737   __ Fccmp(s16, s17, CVFlag, lt);
1738   __ Mrs(x3, NZCV);
1739 
1740   __ Cmp(x20, 0);
1741   __ Fccmp(d18, d18, ZFlag, le);
1742   __ Mrs(x4, NZCV);
1743 
1744   __ Cmp(x20, 0);
1745   __ Fccmp(d18, d18, ZVFlag, gt);
1746   __ Mrs(x5, NZCV);
1747 
1748   __ Cmp(x20, 0);
1749   __ Fccmp(d18, d19, ZCVFlag, ls);
1750   __ Mrs(x6, NZCV);
1751 
1752   __ Cmp(x20, 0);
1753   __ Fccmp(d18, d19, NFlag, hi);
1754   __ Mrs(x7, NZCV);
1755 
1756   // The Macro Assembler does not allow al or nv as condition.
1757   {
1758     ExactAssemblyScope scope(&masm, kInstructionSize);
1759     __ fccmp(s16, s16, NFlag, al);
1760   }
1761   __ Mrs(x8, NZCV);
1762 
1763   {
1764     ExactAssemblyScope scope(&masm, kInstructionSize);
1765     __ fccmp(d18, d18, NFlag, nv);
1766   }
1767   __ Mrs(x9, NZCV);
1768 
1769   __ Cmp(x20, 0);
1770   __ Fccmpe(s16, s16, NoFlag, eq);
1771   __ Mrs(x10, NZCV);
1772 
1773   __ Cmp(x20, 0);
1774   __ Fccmpe(d18, d19, ZCVFlag, ls);
1775   __ Mrs(x11, NZCV);
1776 
1777   __ Cmp(x20, 0);
1778   __ Fccmpe(d21, d21, NoFlag, eq);
1779   __ Mrs(x12, NZCV);
1780 
1781   __ Cmp(x20, 0);
1782   __ Fccmpe(s22, s22, NoFlag, eq);
1783   __ Mrs(x13, NZCV);
1784   END();
1785 
1786   if (CAN_RUN()) {
1787     RUN();
1788 
1789     ASSERT_EQUAL_32(ZCFlag, w0);
1790     ASSERT_EQUAL_32(VFlag, w1);
1791     ASSERT_EQUAL_32(NFlag, w2);
1792     ASSERT_EQUAL_32(CVFlag, w3);
1793     ASSERT_EQUAL_32(ZCFlag, w4);
1794     ASSERT_EQUAL_32(ZVFlag, w5);
1795     ASSERT_EQUAL_32(CFlag, w6);
1796     ASSERT_EQUAL_32(NFlag, w7);
1797     ASSERT_EQUAL_32(ZCFlag, w8);
1798     ASSERT_EQUAL_32(ZCFlag, w9);
1799     ASSERT_EQUAL_32(ZCFlag, w10);
1800     ASSERT_EQUAL_32(CFlag, w11);
1801     ASSERT_EQUAL_32(CVFlag, w12);
1802     ASSERT_EQUAL_32(CVFlag, w13);
1803   }
1804 }
1805 
1806 
TEST(fccmp_h)1807 TEST(fccmp_h) {
1808   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
1809 
1810   START();
1811   __ Fmov(h16, Float16(0.0));
1812   __ Fmov(h17, Float16(0.5));
1813   __ Mov(x20, 0);
1814   __ Fmov(h21, kFP16DefaultNaN);
1815 
1816   __ Cmp(x20, 0);
1817   __ Fccmp(h16, h16, NoFlag, eq);
1818   __ Mrs(x0, NZCV);
1819 
1820   __ Cmp(x20, 0);
1821   __ Fccmp(h16, h16, VFlag, ne);
1822   __ Mrs(x1, NZCV);
1823 
1824   __ Cmp(x20, 0);
1825   __ Fccmp(h16, h17, CFlag, ge);
1826   __ Mrs(x2, NZCV);
1827 
1828   __ Cmp(x20, 0);
1829   __ Fccmp(h16, h17, CVFlag, lt);
1830   __ Mrs(x3, NZCV);
1831 
1832   // The Macro Assembler does not allow al or nv as condition.
1833   {
1834     ExactAssemblyScope scope(&masm, kInstructionSize);
1835     __ fccmp(h16, h16, NFlag, al);
1836   }
1837   __ Mrs(x4, NZCV);
1838   {
1839     ExactAssemblyScope scope(&masm, kInstructionSize);
1840     __ fccmp(h16, h16, NFlag, nv);
1841   }
1842   __ Mrs(x5, NZCV);
1843 
1844   __ Cmp(x20, 0);
1845   __ Fccmpe(h16, h16, NoFlag, eq);
1846   __ Mrs(x6, NZCV);
1847 
1848   __ Cmp(x20, 0);
1849   __ Fccmpe(h16, h21, NoFlag, eq);
1850   __ Mrs(x7, NZCV);
1851 
1852   __ Cmp(x20, 0);
1853   __ Fccmpe(h21, h16, NoFlag, eq);
1854   __ Mrs(x8, NZCV);
1855 
1856   __ Cmp(x20, 0);
1857   __ Fccmpe(h21, h21, NoFlag, eq);
1858   __ Mrs(x9, NZCV);
1859   END();
1860 
1861   if (CAN_RUN()) {
1862     RUN();
1863     ASSERT_EQUAL_32(ZCFlag, w0);
1864     ASSERT_EQUAL_32(VFlag, w1);
1865     ASSERT_EQUAL_32(NFlag, w2);
1866     ASSERT_EQUAL_32(CVFlag, w3);
1867     ASSERT_EQUAL_32(ZCFlag, w4);
1868     ASSERT_EQUAL_32(ZCFlag, w5);
1869     ASSERT_EQUAL_32(ZCFlag, w6);
1870     ASSERT_EQUAL_32(CVFlag, w7);
1871     ASSERT_EQUAL_32(CVFlag, w8);
1872     ASSERT_EQUAL_32(CVFlag, w9);
1873   }
1874 }
1875 
1876 
TEST(fcmp)1877 TEST(fcmp) {
1878   SETUP_WITH_FEATURES(CPUFeatures::kFP);
1879 
1880   START();
1881 
1882   // Some of these tests require a floating-point scratch register assigned to
1883   // the macro assembler, but most do not.
1884   {
1885     UseScratchRegisterScope temps(&masm);
1886     temps.ExcludeAll();
1887     temps.Include(ip0, ip1);
1888 
1889     __ Fmov(s8, 0.0);
1890     __ Fmov(s9, 0.5);
1891     __ Mov(w18, 0x7f800001);  // Single precision NaN.
1892     __ Fmov(s18, w18);
1893 
1894     __ Fcmp(s8, s8);
1895     __ Mrs(x0, NZCV);
1896     __ Fcmp(s8, s9);
1897     __ Mrs(x1, NZCV);
1898     __ Fcmp(s9, s8);
1899     __ Mrs(x2, NZCV);
1900     __ Fcmp(s8, s18);
1901     __ Mrs(x3, NZCV);
1902     __ Fcmp(s18, s18);
1903     __ Mrs(x4, NZCV);
1904     __ Fcmp(s8, 0.0);
1905     __ Mrs(x5, NZCV);
1906     temps.Include(d0);
1907     __ Fcmp(s8, 255.0);
1908     temps.Exclude(d0);
1909     __ Mrs(x6, NZCV);
1910 
1911     __ Fmov(d19, 0.0);
1912     __ Fmov(d20, 0.5);
1913     __ Mov(x21, 0x7ff0000000000001);  // Double precision NaN.
1914     __ Fmov(d21, x21);
1915 
1916     __ Fcmp(d19, d19);
1917     __ Mrs(x10, NZCV);
1918     __ Fcmp(d19, d20);
1919     __ Mrs(x11, NZCV);
1920     __ Fcmp(d20, d19);
1921     __ Mrs(x12, NZCV);
1922     __ Fcmp(d19, d21);
1923     __ Mrs(x13, NZCV);
1924     __ Fcmp(d21, d21);
1925     __ Mrs(x14, NZCV);
1926     __ Fcmp(d19, 0.0);
1927     __ Mrs(x15, NZCV);
1928     temps.Include(d0);
1929     __ Fcmp(d19, 12.3456);
1930     temps.Exclude(d0);
1931     __ Mrs(x16, NZCV);
1932 
1933     __ Fcmpe(s8, s8);
1934     __ Mrs(x22, NZCV);
1935     __ Fcmpe(s8, 0.0);
1936     __ Mrs(x23, NZCV);
1937     __ Fcmpe(d19, d19);
1938     __ Mrs(x24, NZCV);
1939     __ Fcmpe(d19, 0.0);
1940     __ Mrs(x25, NZCV);
1941     __ Fcmpe(s18, s18);
1942     __ Mrs(x26, NZCV);
1943     __ Fcmpe(d21, d21);
1944     __ Mrs(x27, NZCV);
1945   }
1946 
1947   END();
1948 
1949   if (CAN_RUN()) {
1950     RUN();
1951 
1952     ASSERT_EQUAL_32(ZCFlag, w0);
1953     ASSERT_EQUAL_32(NFlag, w1);
1954     ASSERT_EQUAL_32(CFlag, w2);
1955     ASSERT_EQUAL_32(CVFlag, w3);
1956     ASSERT_EQUAL_32(CVFlag, w4);
1957     ASSERT_EQUAL_32(ZCFlag, w5);
1958     ASSERT_EQUAL_32(NFlag, w6);
1959     ASSERT_EQUAL_32(ZCFlag, w10);
1960     ASSERT_EQUAL_32(NFlag, w11);
1961     ASSERT_EQUAL_32(CFlag, w12);
1962     ASSERT_EQUAL_32(CVFlag, w13);
1963     ASSERT_EQUAL_32(CVFlag, w14);
1964     ASSERT_EQUAL_32(ZCFlag, w15);
1965     ASSERT_EQUAL_32(NFlag, w16);
1966     ASSERT_EQUAL_32(ZCFlag, w22);
1967     ASSERT_EQUAL_32(ZCFlag, w23);
1968     ASSERT_EQUAL_32(ZCFlag, w24);
1969     ASSERT_EQUAL_32(ZCFlag, w25);
1970     ASSERT_EQUAL_32(CVFlag, w26);
1971     ASSERT_EQUAL_32(CVFlag, w27);
1972   }
1973 }
1974 
1975 
TEST(fcmp_h)1976 TEST(fcmp_h) {
1977   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
1978 
1979   START();
1980 
1981   // Some of these tests require a floating-point scratch register assigned to
1982   // the macro assembler, but most do not.
1983   {
1984     UseScratchRegisterScope temps(&masm);
1985     temps.ExcludeAll();
1986     temps.Include(ip0, ip1);
1987 
1988     __ Fmov(h8, Float16(0.0));
1989     __ Fmov(h9, Float16(0.5));
1990     __ Fmov(h18, kFP16DefaultNaN);
1991 
1992     __ Fcmp(h8, h8);
1993     __ Mrs(x0, NZCV);
1994     __ Fcmp(h8, h9);
1995     __ Mrs(x1, NZCV);
1996     __ Fcmp(h9, h8);
1997     __ Mrs(x2, NZCV);
1998     __ Fcmp(h8, h18);
1999     __ Mrs(x3, NZCV);
2000     __ Fcmp(h18, h18);
2001     __ Mrs(x4, NZCV);
2002     __ Fcmp(h8, 0.0);
2003     __ Mrs(x5, NZCV);
2004     temps.Include(d0);
2005     __ Fcmp(h8, 255.0);
2006     temps.Exclude(d0);
2007     __ Mrs(x6, NZCV);
2008 
2009     __ Fcmpe(h8, h8);
2010     __ Mrs(x22, NZCV);
2011     __ Fcmpe(h8, 0.0);
2012     __ Mrs(x23, NZCV);
2013     __ Fcmpe(h8, h18);
2014     __ Mrs(x24, NZCV);
2015     __ Fcmpe(h18, h8);
2016     __ Mrs(x25, NZCV);
2017     __ Fcmpe(h18, h18);
2018     __ Mrs(x26, NZCV);
2019   }
2020 
2021   END();
2022 
2023   if (CAN_RUN()) {
2024     RUN();
2025     ASSERT_EQUAL_32(ZCFlag, w0);
2026     ASSERT_EQUAL_32(NFlag, w1);
2027     ASSERT_EQUAL_32(CFlag, w2);
2028     ASSERT_EQUAL_32(CVFlag, w3);
2029     ASSERT_EQUAL_32(CVFlag, w4);
2030     ASSERT_EQUAL_32(ZCFlag, w5);
2031     ASSERT_EQUAL_32(NFlag, w6);
2032     ASSERT_EQUAL_32(ZCFlag, w22);
2033     ASSERT_EQUAL_32(ZCFlag, w23);
2034     ASSERT_EQUAL_32(CVFlag, w24);
2035     ASSERT_EQUAL_32(CVFlag, w25);
2036     ASSERT_EQUAL_32(CVFlag, w26);
2037   }
2038 }
2039 
2040 
TEST(fcsel)2041 TEST(fcsel) {
2042   SETUP_WITH_FEATURES(CPUFeatures::kFP);
2043 
2044   START();
2045   __ Mov(x16, 0);
2046   __ Fmov(s16, 1.0);
2047   __ Fmov(s17, 2.0);
2048   __ Fmov(d18, 3.0);
2049   __ Fmov(d19, 4.0);
2050 
2051   __ Cmp(x16, 0);
2052   __ Fcsel(s0, s16, s17, eq);
2053   __ Fcsel(s1, s16, s17, ne);
2054   __ Fcsel(d2, d18, d19, eq);
2055   __ Fcsel(d3, d18, d19, ne);
2056   // The Macro Assembler does not allow al or nv as condition.
2057   {
2058     ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
2059     __ fcsel(s4, s16, s17, al);
2060     __ fcsel(d5, d18, d19, nv);
2061   }
2062   END();
2063 
2064   if (CAN_RUN()) {
2065     RUN();
2066 
2067     ASSERT_EQUAL_FP32(1.0, s0);
2068     ASSERT_EQUAL_FP32(2.0, s1);
2069     ASSERT_EQUAL_FP64(3.0, d2);
2070     ASSERT_EQUAL_FP64(4.0, d3);
2071     ASSERT_EQUAL_FP32(1.0, s4);
2072     ASSERT_EQUAL_FP64(3.0, d5);
2073   }
2074 }
2075 
2076 
TEST(fcsel_h)2077 TEST(fcsel_h) {
2078   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
2079 
2080   START();
2081   __ Mov(x16, 0);
2082   __ Fmov(h16, Float16(1.0));
2083   __ Fmov(h17, Float16(2.0));
2084 
2085   __ Cmp(x16, 0);
2086   __ Fcsel(h0, h16, h17, eq);
2087   __ Fcsel(h1, h16, h17, ne);
2088   // The Macro Assembler does not allow al or nv as condition.
2089   {
2090     ExactAssemblyScope scope(&masm, 2 * kInstructionSize);
2091     __ fcsel(h4, h16, h17, al);
2092     __ fcsel(h5, h16, h17, nv);
2093   }
2094   END();
2095 
2096   if (CAN_RUN()) {
2097     RUN();
2098     ASSERT_EQUAL_FP16(Float16(1.0), h0);
2099     ASSERT_EQUAL_FP16(Float16(2.0), h1);
2100     ASSERT_EQUAL_FP16(Float16(1.0), h4);
2101     ASSERT_EQUAL_FP16(Float16(1.0), h5);
2102   }
2103 }
2104 
2105 
TEST(fneg)2106 TEST(fneg) {
2107   SETUP_WITH_FEATURES(CPUFeatures::kFP);
2108 
2109   START();
2110   __ Fmov(s16, 1.0);
2111   __ Fmov(s17, 0.0);
2112   __ Fmov(s18, kFP32PositiveInfinity);
2113   __ Fmov(d19, 1.0);
2114   __ Fmov(d20, 0.0);
2115   __ Fmov(d21, kFP64PositiveInfinity);
2116 
2117   __ Fneg(s0, s16);
2118   __ Fneg(s1, s0);
2119   __ Fneg(s2, s17);
2120   __ Fneg(s3, s2);
2121   __ Fneg(s4, s18);
2122   __ Fneg(s5, s4);
2123   __ Fneg(d6, d19);
2124   __ Fneg(d7, d6);
2125   __ Fneg(d8, d20);
2126   __ Fneg(d9, d8);
2127   __ Fneg(d10, d21);
2128   __ Fneg(d11, d10);
2129   END();
2130 
2131   if (CAN_RUN()) {
2132     RUN();
2133 
2134     ASSERT_EQUAL_FP32(-1.0, s0);
2135     ASSERT_EQUAL_FP32(1.0, s1);
2136     ASSERT_EQUAL_FP32(-0.0, s2);
2137     ASSERT_EQUAL_FP32(0.0, s3);
2138     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s4);
2139     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
2140     ASSERT_EQUAL_FP64(-1.0, d6);
2141     ASSERT_EQUAL_FP64(1.0, d7);
2142     ASSERT_EQUAL_FP64(-0.0, d8);
2143     ASSERT_EQUAL_FP64(0.0, d9);
2144     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d10);
2145     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d11);
2146   }
2147 }
2148 
2149 
TEST(fabs)2150 TEST(fabs) {
2151   SETUP_WITH_FEATURES(CPUFeatures::kFP);
2152 
2153   START();
2154   __ Fmov(s16, -1.0);
2155   __ Fmov(s17, -0.0);
2156   __ Fmov(s18, kFP32NegativeInfinity);
2157   __ Fmov(d19, -1.0);
2158   __ Fmov(d20, -0.0);
2159   __ Fmov(d21, kFP64NegativeInfinity);
2160 
2161   __ Fabs(s0, s16);
2162   __ Fabs(s1, s0);
2163   __ Fabs(s2, s17);
2164   __ Fabs(s3, s18);
2165   __ Fabs(d4, d19);
2166   __ Fabs(d5, d4);
2167   __ Fabs(d6, d20);
2168   __ Fabs(d7, d21);
2169   END();
2170 
2171   if (CAN_RUN()) {
2172     RUN();
2173 
2174     ASSERT_EQUAL_FP32(1.0, s0);
2175     ASSERT_EQUAL_FP32(1.0, s1);
2176     ASSERT_EQUAL_FP32(0.0, s2);
2177     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s3);
2178     ASSERT_EQUAL_FP64(1.0, d4);
2179     ASSERT_EQUAL_FP64(1.0, d5);
2180     ASSERT_EQUAL_FP64(0.0, d6);
2181     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
2182   }
2183 }
2184 
2185 
TEST(fsqrt)2186 TEST(fsqrt) {
2187   SETUP_WITH_FEATURES(CPUFeatures::kFP);
2188 
2189   START();
2190   __ Fmov(s16, 0.0);
2191   __ Fmov(s17, 1.0);
2192   __ Fmov(s18, 0.25);
2193   __ Fmov(s19, 65536.0);
2194   __ Fmov(s20, -0.0);
2195   __ Fmov(s21, kFP32PositiveInfinity);
2196   __ Fmov(s22, -1.0);
2197   __ Fmov(d23, 0.0);
2198   __ Fmov(d24, 1.0);
2199   __ Fmov(d25, 0.25);
2200   __ Fmov(d26, 4294967296.0);
2201   __ Fmov(d27, -0.0);
2202   __ Fmov(d28, kFP64PositiveInfinity);
2203   __ Fmov(d29, -1.0);
2204 
2205   __ Fsqrt(s0, s16);
2206   __ Fsqrt(s1, s17);
2207   __ Fsqrt(s2, s18);
2208   __ Fsqrt(s3, s19);
2209   __ Fsqrt(s4, s20);
2210   __ Fsqrt(s5, s21);
2211   __ Fsqrt(s6, s22);
2212   __ Fsqrt(d7, d23);
2213   __ Fsqrt(d8, d24);
2214   __ Fsqrt(d9, d25);
2215   __ Fsqrt(d10, d26);
2216   __ Fsqrt(d11, d27);
2217   __ Fsqrt(d12, d28);
2218   __ Fsqrt(d13, d29);
2219   END();
2220 
2221   if (CAN_RUN()) {
2222     RUN();
2223 
2224     ASSERT_EQUAL_FP32(0.0, s0);
2225     ASSERT_EQUAL_FP32(1.0, s1);
2226     ASSERT_EQUAL_FP32(0.5, s2);
2227     ASSERT_EQUAL_FP32(256.0, s3);
2228     ASSERT_EQUAL_FP32(-0.0, s4);
2229     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s5);
2230     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s6);
2231     ASSERT_EQUAL_FP64(0.0, d7);
2232     ASSERT_EQUAL_FP64(1.0, d8);
2233     ASSERT_EQUAL_FP64(0.5, d9);
2234     ASSERT_EQUAL_FP64(65536.0, d10);
2235     ASSERT_EQUAL_FP64(-0.0, d11);
2236     ASSERT_EQUAL_FP64(kFP32PositiveInfinity, d12);
2237     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
2238   }
2239 }
2240 
TEST(frint32x_s)2241 TEST(frint32x_s) {
2242   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2243 
2244   START();
2245 
2246   __ Fmov(s13, 1.0);
2247   __ Fmov(s14, 1.1);
2248   __ Fmov(s15, 1.5);
2249   __ Fmov(s16, 1.9);
2250   __ Fmov(s17, 2.5);
2251   __ Fmov(s18, -1.5);
2252   __ Fmov(s19, -2.5);
2253   __ Fmov(s20, kFP32PositiveInfinity);
2254   __ Fmov(s21, kFP32NegativeInfinity);
2255   __ Fmov(s22, 0.0);
2256   __ Fmov(s23, -0.0);
2257   __ Fmov(s24, -0.2);
2258   __ Fmov(s25, kFP32DefaultNaN);
2259   __ Fmov(s26, INT32_MIN);
2260   __ Fmov(s27, INT32_MIN + 0x80);  // The next representable FP32.
2261   __ Fmov(s28, 0x80000000);
2262   __ Fmov(s29, 0x7fffff80);  // The largest int32_t representable as FP32.
2263   __ Fmov(s30, FLT_MIN);
2264   __ Fmov(s31, FLT_MAX);
2265 
2266   __ Frint32x(s0, s13);
2267   __ Frint32x(s1, s14);
2268   __ Frint32x(s2, s15);
2269   __ Frint32x(s3, s16);
2270   __ Frint32x(s4, s17);
2271   __ Frint32x(s5, s18);
2272   __ Frint32x(s6, s19);
2273   __ Frint32x(s7, s20);
2274   __ Frint32x(s8, s21);
2275   __ Frint32x(s9, s22);
2276   __ Frint32x(s10, s23);
2277   __ Frint32x(s11, s24);
2278   __ Frint32x(s12, s25);
2279   __ Frint32x(s13, s26);
2280   __ Frint32x(s14, s27);
2281   __ Frint32x(s15, s28);
2282   __ Frint32x(s16, s29);
2283   __ Frint32x(s17, s30);
2284   __ Frint32x(s18, s31);
2285 
2286   END();
2287 
2288   if (CAN_RUN()) {
2289     RUN();
2290 
2291     ASSERT_EQUAL_FP32(1.0, s0);
2292     ASSERT_EQUAL_FP32(1.0, s1);
2293     ASSERT_EQUAL_FP32(2.0, s2);
2294     ASSERT_EQUAL_FP32(2.0, s3);
2295     ASSERT_EQUAL_FP32(2.0, s4);
2296     ASSERT_EQUAL_FP32(-2.0, s5);
2297     ASSERT_EQUAL_FP32(-2.0, s6);
2298     ASSERT_EQUAL_FP32(INT32_MIN, s7);
2299     ASSERT_EQUAL_FP32(INT32_MIN, s8);
2300     ASSERT_EQUAL_FP32(0.0, s9);
2301     ASSERT_EQUAL_FP32(-0.0, s10);
2302     ASSERT_EQUAL_FP32(-0.0, s11);
2303     ASSERT_EQUAL_FP32(INT32_MIN, s12);  // NaN.
2304     ASSERT_EQUAL_FP32(INT32_MIN, s13);
2305     ASSERT_EQUAL_FP32(INT32_MIN + 0x80, s14);
2306     ASSERT_EQUAL_FP32(INT32_MIN, s15);  // Out of range.
2307     ASSERT_EQUAL_FP32(0x7fffff80, s16);
2308     ASSERT_EQUAL_FP32(0, s17);
2309     ASSERT_EQUAL_FP32(INT32_MIN, s18);
2310   }
2311 }
2312 
TEST(frint32x_d)2313 TEST(frint32x_d) {
2314   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2315 
2316   START();
2317 
2318   __ Fmov(d13, 1.0);
2319   __ Fmov(d14, 1.1);
2320   __ Fmov(d15, 1.5);
2321   __ Fmov(d16, 1.9);
2322   __ Fmov(d17, 2.5);
2323   __ Fmov(d18, -1.5);
2324   __ Fmov(d19, -2.5);
2325   __ Fmov(d20, kFP64PositiveInfinity);
2326   __ Fmov(d21, kFP64NegativeInfinity);
2327   __ Fmov(d22, 0.0);
2328   __ Fmov(d23, -0.0);
2329   __ Fmov(d24, -0.2);
2330   __ Fmov(d25, kFP64DefaultNaN);
2331   __ Fmov(d26, INT32_MIN);
2332   __ Fmov(d27, INT32_MIN + 1);
2333   __ Fmov(d28, INT32_MAX);
2334   __ Fmov(d29, INT32_MAX - 1);
2335   __ Fmov(d30, FLT_MIN);
2336   __ Fmov(d31, FLT_MAX);
2337 
2338   __ Frint32x(d0, d13);
2339   __ Frint32x(d1, d14);
2340   __ Frint32x(d2, d15);
2341   __ Frint32x(d3, d16);
2342   __ Frint32x(d4, d17);
2343   __ Frint32x(d5, d18);
2344   __ Frint32x(d6, d19);
2345   __ Frint32x(d7, d20);
2346   __ Frint32x(d8, d21);
2347   __ Frint32x(d9, d22);
2348   __ Frint32x(d10, d23);
2349   __ Frint32x(d11, d24);
2350   __ Frint32x(d12, d25);
2351   __ Frint32x(d13, d26);
2352   __ Frint32x(d14, d27);
2353   __ Frint32x(d15, d28);
2354   __ Frint32x(d16, d29);
2355   __ Frint32x(d17, d30);
2356   __ Frint32x(d18, d31);
2357 
2358   END();
2359 
2360   if (CAN_RUN()) {
2361     RUN();
2362 
2363     ASSERT_EQUAL_FP64(1.0, d0);
2364     ASSERT_EQUAL_FP64(1.0, d1);
2365     ASSERT_EQUAL_FP64(2.0, d2);
2366     ASSERT_EQUAL_FP64(2.0, d3);
2367     ASSERT_EQUAL_FP64(2.0, d4);
2368     ASSERT_EQUAL_FP64(-2.0, d5);
2369     ASSERT_EQUAL_FP64(-2.0, d6);
2370     ASSERT_EQUAL_FP64(INT32_MIN, d7);
2371     ASSERT_EQUAL_FP64(INT32_MIN, d8);
2372     ASSERT_EQUAL_FP64(0.0, d9);
2373     ASSERT_EQUAL_FP64(-0.0, d10);
2374     ASSERT_EQUAL_FP64(-0.0, d11);
2375     ASSERT_EQUAL_FP64(INT32_MIN, d12);
2376     ASSERT_EQUAL_FP64(INT32_MIN, d13);
2377     ASSERT_EQUAL_FP64(INT32_MIN + 1, d14);
2378     ASSERT_EQUAL_FP64(INT32_MAX, d15);
2379     ASSERT_EQUAL_FP64(INT32_MAX - 1, d16);
2380     ASSERT_EQUAL_FP64(0, d17);
2381     ASSERT_EQUAL_FP64(INT32_MIN, d18);
2382   }
2383 }
2384 
TEST(frint32z_s)2385 TEST(frint32z_s) {
2386   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2387 
2388   START();
2389 
2390   __ Fmov(s13, 1.0);
2391   __ Fmov(s14, 1.1);
2392   __ Fmov(s15, 1.5);
2393   __ Fmov(s16, 1.9);
2394   __ Fmov(s17, 2.5);
2395   __ Fmov(s18, -1.5);
2396   __ Fmov(s19, -2.5);
2397   __ Fmov(s20, kFP32PositiveInfinity);
2398   __ Fmov(s21, kFP32NegativeInfinity);
2399   __ Fmov(s22, 0.0);
2400   __ Fmov(s23, -0.0);
2401   __ Fmov(s24, -0.2);
2402   __ Fmov(s25, kFP32DefaultNaN);
2403   __ Fmov(s26, INT32_MIN);
2404   __ Fmov(s27, INT32_MIN + 0x80);  // The next representable FP32.
2405   __ Fmov(s28, 0x80000000);
2406   __ Fmov(s29, 0x7fffff80);  // The largest int32_t representable as FP32.
2407   __ Fmov(s30, FLT_MIN);
2408   __ Fmov(s31, FLT_MAX);
2409 
2410   __ Frint32z(s0, s13);
2411   __ Frint32z(s1, s14);
2412   __ Frint32z(s2, s15);
2413   __ Frint32z(s3, s16);
2414   __ Frint32z(s4, s17);
2415   __ Frint32z(s5, s18);
2416   __ Frint32z(s6, s19);
2417   __ Frint32z(s7, s20);
2418   __ Frint32z(s8, s21);
2419   __ Frint32z(s9, s22);
2420   __ Frint32z(s10, s23);
2421   __ Frint32z(s11, s24);
2422   __ Frint32z(s12, s25);
2423   __ Frint32z(s13, s26);
2424   __ Frint32z(s14, s27);
2425   __ Frint32z(s15, s28);
2426   __ Frint32z(s16, s29);
2427   __ Frint32z(s17, s30);
2428   __ Frint32z(s18, s31);
2429 
2430   END();
2431 
2432   if (CAN_RUN()) {
2433     RUN();
2434 
2435     ASSERT_EQUAL_FP32(1.0, s0);
2436     ASSERT_EQUAL_FP32(1.0, s1);
2437     ASSERT_EQUAL_FP32(1.0, s2);
2438     ASSERT_EQUAL_FP32(1.0, s3);
2439     ASSERT_EQUAL_FP32(2.0, s4);
2440     ASSERT_EQUAL_FP32(-1.0, s5);
2441     ASSERT_EQUAL_FP32(-2.0, s6);
2442     ASSERT_EQUAL_FP32(INT32_MIN, s7);
2443     ASSERT_EQUAL_FP32(INT32_MIN, s8);
2444     ASSERT_EQUAL_FP32(0.0, s9);
2445     ASSERT_EQUAL_FP32(-0.0, s10);
2446     ASSERT_EQUAL_FP32(-0.0, s11);
2447     ASSERT_EQUAL_FP32(INT32_MIN, s12);  // NaN.
2448     ASSERT_EQUAL_FP32(INT32_MIN, s13);
2449     ASSERT_EQUAL_FP32(INT32_MIN + 0x80, s14);
2450     ASSERT_EQUAL_FP32(INT32_MIN, s15);  // Out of range.
2451     ASSERT_EQUAL_FP32(0x7fffff80, s16);
2452     ASSERT_EQUAL_FP32(0, s17);
2453     ASSERT_EQUAL_FP32(INT32_MIN, s18);
2454   }
2455 }
2456 
TEST(frint32z_d)2457 TEST(frint32z_d) {
2458   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2459 
2460   START();
2461 
2462   __ Fmov(d13, 1.0);
2463   __ Fmov(d14, 1.1);
2464   __ Fmov(d15, 1.5);
2465   __ Fmov(d16, 1.9);
2466   __ Fmov(d17, 2.5);
2467   __ Fmov(d18, -1.5);
2468   __ Fmov(d19, -2.5);
2469   __ Fmov(d20, kFP64PositiveInfinity);
2470   __ Fmov(d21, kFP64NegativeInfinity);
2471   __ Fmov(d22, 0.0);
2472   __ Fmov(d23, -0.0);
2473   __ Fmov(d24, -0.2);
2474   __ Fmov(d25, kFP64DefaultNaN);
2475   __ Fmov(d26, INT32_MIN);
2476   __ Fmov(d27, INT32_MIN + 1);
2477   __ Fmov(d28, INT32_MAX);
2478   __ Fmov(d29, INT32_MAX - 1);
2479   __ Fmov(d30, FLT_MIN);
2480   __ Fmov(d31, FLT_MAX);
2481 
2482   __ Frint32z(d0, d13);
2483   __ Frint32z(d1, d14);
2484   __ Frint32z(d2, d15);
2485   __ Frint32z(d3, d16);
2486   __ Frint32z(d4, d17);
2487   __ Frint32z(d5, d18);
2488   __ Frint32z(d6, d19);
2489   __ Frint32z(d7, d20);
2490   __ Frint32z(d8, d21);
2491   __ Frint32z(d9, d22);
2492   __ Frint32z(d10, d23);
2493   __ Frint32z(d11, d24);
2494   __ Frint32z(d12, d25);
2495   __ Frint32z(d13, d26);
2496   __ Frint32z(d14, d27);
2497   __ Frint32z(d15, d28);
2498   __ Frint32z(d16, d29);
2499   __ Frint32z(d17, d30);
2500   __ Frint32z(d18, d31);
2501 
2502   END();
2503 
2504   if (CAN_RUN()) {
2505     RUN();
2506 
2507     ASSERT_EQUAL_FP64(1.0, d0);
2508     ASSERT_EQUAL_FP64(1.0, d1);
2509     ASSERT_EQUAL_FP64(1.0, d2);
2510     ASSERT_EQUAL_FP64(1.0, d3);
2511     ASSERT_EQUAL_FP64(2.0, d4);
2512     ASSERT_EQUAL_FP64(-1.0, d5);
2513     ASSERT_EQUAL_FP64(-2.0, d6);
2514     ASSERT_EQUAL_FP64(INT32_MIN, d7);
2515     ASSERT_EQUAL_FP64(INT32_MIN, d8);
2516     ASSERT_EQUAL_FP64(0.0, d9);
2517     ASSERT_EQUAL_FP64(-0.0, d10);
2518     ASSERT_EQUAL_FP64(-0.0, d11);
2519     ASSERT_EQUAL_FP64(INT32_MIN, d12);
2520     ASSERT_EQUAL_FP64(INT32_MIN, d13);
2521     ASSERT_EQUAL_FP64(INT32_MIN + 1, d14);
2522     ASSERT_EQUAL_FP64(INT32_MAX, d15);
2523     ASSERT_EQUAL_FP64(INT32_MAX - 1, d16);
2524     ASSERT_EQUAL_FP64(0, d17);
2525     ASSERT_EQUAL_FP64(INT32_MIN, d18);
2526   }
2527 }
2528 
TEST(frint64x_s)2529 TEST(frint64x_s) {
2530   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2531 
2532   START();
2533 
2534   __ Fmov(s13, 1.0);
2535   __ Fmov(s14, 1.1);
2536   __ Fmov(s15, 1.5);
2537   __ Fmov(s16, 1.9);
2538   __ Fmov(s17, 2.5);
2539   __ Fmov(s18, -1.5);
2540   __ Fmov(s19, -2.5);
2541   __ Fmov(s20, kFP64PositiveInfinity);
2542   __ Fmov(s21, kFP64NegativeInfinity);
2543   __ Fmov(s22, 0.0);
2544   __ Fmov(s23, -0.0);
2545   __ Fmov(s24, -0.2);
2546   __ Fmov(s25, kFP64DefaultNaN);
2547   __ Fmov(s26, INT64_MIN);
2548   __ Fmov(s27, INT64_MIN + 0x80'00000000);  // The next representable FP32.
2549   __ Fmov(s28, 0x80000000'00000000);
2550   // The largest int64_t representable as FP32.
2551   __ Fmov(s29, 0x7fffff80'00000000);
2552   __ Fmov(s30, FLT_MIN);
2553   __ Fmov(s31, FLT_MAX);
2554 
2555   __ Frint64x(s0, s13);
2556   __ Frint64x(s1, s14);
2557   __ Frint64x(s2, s15);
2558   __ Frint64x(s3, s16);
2559   __ Frint64x(s4, s17);
2560   __ Frint64x(s5, s18);
2561   __ Frint64x(s6, s19);
2562   __ Frint64x(s7, s20);
2563   __ Frint64x(s8, s21);
2564   __ Frint64x(s9, s22);
2565   __ Frint64x(s10, s23);
2566   __ Frint64x(s11, s24);
2567   __ Frint64x(s12, s25);
2568   __ Frint64x(s13, s26);
2569   __ Frint64x(s14, s27);
2570   __ Frint64x(s15, s28);
2571   __ Frint64x(s16, s29);
2572   __ Frint64x(s17, s30);
2573   __ Frint64x(s18, s31);
2574 
2575   END();
2576 
2577   if (CAN_RUN()) {
2578     RUN();
2579 
2580     ASSERT_EQUAL_FP32(1.0, s0);
2581     ASSERT_EQUAL_FP32(1.0, s1);
2582     ASSERT_EQUAL_FP32(2.0, s2);
2583     ASSERT_EQUAL_FP32(2.0, s3);
2584     ASSERT_EQUAL_FP32(2.0, s4);
2585     ASSERT_EQUAL_FP32(-2.0, s5);
2586     ASSERT_EQUAL_FP32(-2.0, s6);
2587     ASSERT_EQUAL_FP32(INT64_MIN, s7);
2588     ASSERT_EQUAL_FP32(INT64_MIN, s8);
2589     ASSERT_EQUAL_FP32(0.0, s9);
2590     ASSERT_EQUAL_FP32(-0.0, s10);
2591     ASSERT_EQUAL_FP32(-0.0, s11);
2592     ASSERT_EQUAL_FP32(INT64_MIN, s12);  // Nan.
2593     ASSERT_EQUAL_FP32(INT64_MIN, s13);
2594     ASSERT_EQUAL_FP32(INT64_MIN + 0x80'00000000, s14);
2595     ASSERT_EQUAL_FP32(INT64_MIN, s15);  // Out of range.
2596     ASSERT_EQUAL_FP32(0x7fffff80'00000000, s16);
2597     ASSERT_EQUAL_FP32(0, s17);
2598     ASSERT_EQUAL_FP32(INT64_MIN, s18);
2599   }
2600 }
2601 
TEST(frint64x_d)2602 TEST(frint64x_d) {
2603   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2604 
2605   START();
2606 
2607   __ Fmov(d13, 1.0);
2608   __ Fmov(d14, 1.1);
2609   __ Fmov(d15, 1.5);
2610   __ Fmov(d16, 1.9);
2611   __ Fmov(d17, 2.5);
2612   __ Fmov(d18, -1.5);
2613   __ Fmov(d19, -2.5);
2614   __ Fmov(d20, kFP64PositiveInfinity);
2615   __ Fmov(d21, kFP64NegativeInfinity);
2616   __ Fmov(d22, 0.0);
2617   __ Fmov(d23, -0.0);
2618   __ Fmov(d24, -0.2);
2619   __ Fmov(d25, kFP64DefaultNaN);
2620   __ Fmov(d26, INT64_MIN);
2621   __ Fmov(d27, INT64_MIN + 0x400);  // The next representable FP64.
2622   __ Fmov(d28, 0x80000000'00000000);
2623   // The largest int64_t representable as FP64.
2624   __ Fmov(d29, 0x7fffffff'fffffc00);
2625   __ Fmov(d30, FLT_MIN);
2626   __ Fmov(d31, FLT_MAX);
2627 
2628   __ Frint64x(d0, d13);
2629   __ Frint64x(d1, d14);
2630   __ Frint64x(d2, d15);
2631   __ Frint64x(d3, d16);
2632   __ Frint64x(d4, d17);
2633   __ Frint64x(d5, d18);
2634   __ Frint64x(d6, d19);
2635   __ Frint64x(d7, d20);
2636   __ Frint64x(d8, d21);
2637   __ Frint64x(d9, d22);
2638   __ Frint64x(d10, d23);
2639   __ Frint64x(d11, d24);
2640   __ Frint64x(d12, d25);
2641   __ Frint64x(d13, d26);
2642   __ Frint64x(d14, d27);
2643   __ Frint64x(d15, d28);
2644   __ Frint64x(d16, d29);
2645   __ Frint64x(d17, d30);
2646   __ Frint64x(d18, d31);
2647 
2648   END();
2649 
2650   if (CAN_RUN()) {
2651     RUN();
2652 
2653     ASSERT_EQUAL_FP64(1.0, d0);
2654     ASSERT_EQUAL_FP64(1.0, d1);
2655     ASSERT_EQUAL_FP64(2.0, d2);
2656     ASSERT_EQUAL_FP64(2.0, d3);
2657     ASSERT_EQUAL_FP64(2.0, d4);
2658     ASSERT_EQUAL_FP64(-2.0, d5);
2659     ASSERT_EQUAL_FP64(-2.0, d6);
2660     ASSERT_EQUAL_FP64(INT64_MIN, d7);
2661     ASSERT_EQUAL_FP64(INT64_MIN, d8);
2662     ASSERT_EQUAL_FP64(0.0, d9);
2663     ASSERT_EQUAL_FP64(-0.0, d10);
2664     ASSERT_EQUAL_FP64(-0.0, d11);
2665     ASSERT_EQUAL_FP64(INT64_MIN, d12);  // NaN.
2666     ASSERT_EQUAL_FP64(INT64_MIN, d13);
2667     ASSERT_EQUAL_FP64(INT64_MIN + 0x400, d14);
2668     ASSERT_EQUAL_FP64(INT64_MIN, d15);  // Out of range.
2669     ASSERT_EQUAL_FP64(0x7fffffff'fffffc00, d16);
2670     ASSERT_EQUAL_FP64(0, d17);
2671     ASSERT_EQUAL_FP64(INT64_MIN, d18);
2672   }
2673 }
2674 
TEST(frint64z_s)2675 TEST(frint64z_s) {
2676   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2677 
2678   START();
2679 
2680   __ Fmov(s13, 1.0);
2681   __ Fmov(s14, 1.1);
2682   __ Fmov(s15, 1.5);
2683   __ Fmov(s16, 1.9);
2684   __ Fmov(s17, 2.5);
2685   __ Fmov(s18, -1.5);
2686   __ Fmov(s19, -2.5);
2687   __ Fmov(s20, kFP64PositiveInfinity);
2688   __ Fmov(s21, kFP64NegativeInfinity);
2689   __ Fmov(s22, 0.0);
2690   __ Fmov(s23, -0.0);
2691   __ Fmov(s24, -0.2);
2692   __ Fmov(s25, kFP64DefaultNaN);
2693   __ Fmov(s26, INT64_MIN);
2694   __ Fmov(s27, INT64_MIN + 0x80'00000000);  // The next representable FP32.
2695   __ Fmov(s28, 0x80000000'00000000);
2696   // The largest int64_t representable as FP32.
2697   __ Fmov(s29, 0x7fffff80'00000000);
2698   __ Fmov(s30, FLT_MIN);
2699   __ Fmov(s31, FLT_MAX);
2700 
2701   __ Frint64z(s0, s13);
2702   __ Frint64z(s1, s14);
2703   __ Frint64z(s2, s15);
2704   __ Frint64z(s3, s16);
2705   __ Frint64z(s4, s17);
2706   __ Frint64z(s5, s18);
2707   __ Frint64z(s6, s19);
2708   __ Frint64z(s7, s20);
2709   __ Frint64z(s8, s21);
2710   __ Frint64z(s9, s22);
2711   __ Frint64z(s10, s23);
2712   __ Frint64z(s11, s24);
2713   __ Frint64z(s12, s25);
2714   __ Frint64z(s13, s26);
2715   __ Frint64z(s14, s27);
2716   __ Frint64z(s15, s28);
2717   __ Frint64z(s16, s29);
2718   __ Frint64z(s17, s30);
2719   __ Frint64z(s18, s31);
2720 
2721   END();
2722 
2723   if (CAN_RUN()) {
2724     RUN();
2725 
2726     ASSERT_EQUAL_FP32(1.0, s0);
2727     ASSERT_EQUAL_FP32(1.0, s1);
2728     ASSERT_EQUAL_FP32(1.0, s2);
2729     ASSERT_EQUAL_FP32(1.0, s3);
2730     ASSERT_EQUAL_FP32(2.0, s4);
2731     ASSERT_EQUAL_FP32(-1.0, s5);
2732     ASSERT_EQUAL_FP32(-2.0, s6);
2733     ASSERT_EQUAL_FP32(INT64_MIN, s7);
2734     ASSERT_EQUAL_FP32(INT64_MIN, s8);
2735     ASSERT_EQUAL_FP32(0.0, s9);
2736     ASSERT_EQUAL_FP32(-0.0, s10);
2737     ASSERT_EQUAL_FP32(-0.0, s11);
2738     ASSERT_EQUAL_FP32(INT64_MIN, s12);  // Nan.
2739     ASSERT_EQUAL_FP32(INT64_MIN, s13);
2740     ASSERT_EQUAL_FP32(INT64_MIN + 0x80'00000000, s14);
2741     ASSERT_EQUAL_FP32(INT64_MIN, s15);  // Out of range.
2742     ASSERT_EQUAL_FP32(0x7fffff80'00000000, s16);
2743     ASSERT_EQUAL_FP32(0, s17);
2744     ASSERT_EQUAL_FP32(INT64_MIN, s18);
2745   }
2746 }
2747 
TEST(frint64z_d)2748 TEST(frint64z_d) {
2749   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
2750 
2751   START();
2752 
2753   __ Fmov(d13, 1.0);
2754   __ Fmov(d14, 1.1);
2755   __ Fmov(d15, 1.5);
2756   __ Fmov(d16, 1.9);
2757   __ Fmov(d17, 2.5);
2758   __ Fmov(d18, -1.5);
2759   __ Fmov(d19, -2.5);
2760   __ Fmov(d20, kFP64PositiveInfinity);
2761   __ Fmov(d21, kFP64NegativeInfinity);
2762   __ Fmov(d22, 0.0);
2763   __ Fmov(d23, -0.0);
2764   __ Fmov(d24, -0.2);
2765   __ Fmov(d25, kFP64DefaultNaN);
2766   __ Fmov(d26, INT64_MIN);
2767   __ Fmov(d27, INT64_MIN + 0x400);  // The next representable FP64.
2768   __ Fmov(d28, 0x80000000'00000000);
2769   // The largest int64_t representable as FP64.
2770   __ Fmov(d29, 0x7fffffff'fffffc00);
2771   __ Fmov(d30, FLT_MIN);
2772   __ Fmov(d31, FLT_MAX);
2773 
2774   __ Frint64z(d0, d13);
2775   __ Frint64z(d1, d14);
2776   __ Frint64z(d2, d15);
2777   __ Frint64z(d3, d16);
2778   __ Frint64z(d4, d17);
2779   __ Frint64z(d5, d18);
2780   __ Frint64z(d6, d19);
2781   __ Frint64z(d7, d20);
2782   __ Frint64z(d8, d21);
2783   __ Frint64z(d9, d22);
2784   __ Frint64z(d10, d23);
2785   __ Frint64z(d11, d24);
2786   __ Frint64z(d12, d25);
2787   __ Frint64z(d13, d26);
2788   __ Frint64z(d14, d27);
2789   __ Frint64z(d15, d28);
2790   __ Frint64z(d16, d29);
2791   __ Frint64z(d17, d30);
2792   __ Frint64z(d18, d31);
2793 
2794   END();
2795 
2796   if (CAN_RUN()) {
2797     RUN();
2798 
2799     ASSERT_EQUAL_FP64(1.0, d0);
2800     ASSERT_EQUAL_FP64(1.0, d1);
2801     ASSERT_EQUAL_FP64(1.0, d2);
2802     ASSERT_EQUAL_FP64(1.0, d3);
2803     ASSERT_EQUAL_FP64(2.0, d4);
2804     ASSERT_EQUAL_FP64(-1.0, d5);
2805     ASSERT_EQUAL_FP64(-2.0, d6);
2806     ASSERT_EQUAL_FP64(INT64_MIN, d7);
2807     ASSERT_EQUAL_FP64(INT64_MIN, d8);
2808     ASSERT_EQUAL_FP64(0.0, d9);
2809     ASSERT_EQUAL_FP64(-0.0, d10);
2810     ASSERT_EQUAL_FP64(-0.0, d11);
2811     ASSERT_EQUAL_FP64(INT64_MIN, d12);  // NaN.
2812     ASSERT_EQUAL_FP64(INT64_MIN, d13);
2813     ASSERT_EQUAL_FP64(INT64_MIN + 0x400, d14);
2814     ASSERT_EQUAL_FP64(INT64_MIN, d15);  // Out of range.
2815     ASSERT_EQUAL_FP64(0x7fffffff'fffffc00, d16);
2816     ASSERT_EQUAL_FP64(0, d17);
2817     ASSERT_EQUAL_FP64(INT64_MIN, d18);
2818   }
2819 }
2820 
TEST(frinta)2821 TEST(frinta) {
2822   SETUP_WITH_FEATURES(CPUFeatures::kFP);
2823 
2824   START();
2825   __ Fmov(s16, 1.0);
2826   __ Fmov(s17, 1.1);
2827   __ Fmov(s18, 1.5);
2828   __ Fmov(s19, 1.9);
2829   __ Fmov(s20, 2.5);
2830   __ Fmov(s21, -1.5);
2831   __ Fmov(s22, -2.5);
2832   __ Fmov(s23, kFP32PositiveInfinity);
2833   __ Fmov(s24, kFP32NegativeInfinity);
2834   __ Fmov(s25, 0.0);
2835   __ Fmov(s26, -0.0);
2836   __ Fmov(s27, -0.2);
2837 
2838   __ Frinta(s0, s16);
2839   __ Frinta(s1, s17);
2840   __ Frinta(s2, s18);
2841   __ Frinta(s3, s19);
2842   __ Frinta(s4, s20);
2843   __ Frinta(s5, s21);
2844   __ Frinta(s6, s22);
2845   __ Frinta(s7, s23);
2846   __ Frinta(s8, s24);
2847   __ Frinta(s9, s25);
2848   __ Frinta(s10, s26);
2849   __ Frinta(s11, s27);
2850 
2851   __ Fmov(d16, 1.0);
2852   __ Fmov(d17, 1.1);
2853   __ Fmov(d18, 1.5);
2854   __ Fmov(d19, 1.9);
2855   __ Fmov(d20, 2.5);
2856   __ Fmov(d21, -1.5);
2857   __ Fmov(d22, -2.5);
2858   __ Fmov(d23, kFP32PositiveInfinity);
2859   __ Fmov(d24, kFP32NegativeInfinity);
2860   __ Fmov(d25, 0.0);
2861   __ Fmov(d26, -0.0);
2862   __ Fmov(d27, -0.2);
2863 
2864   __ Frinta(d12, d16);
2865   __ Frinta(d13, d17);
2866   __ Frinta(d14, d18);
2867   __ Frinta(d15, d19);
2868   __ Frinta(d16, d20);
2869   __ Frinta(d17, d21);
2870   __ Frinta(d18, d22);
2871   __ Frinta(d19, d23);
2872   __ Frinta(d20, d24);
2873   __ Frinta(d21, d25);
2874   __ Frinta(d22, d26);
2875   __ Frinta(d23, d27);
2876   END();
2877 
2878   if (CAN_RUN()) {
2879     RUN();
2880 
2881     ASSERT_EQUAL_FP32(1.0, s0);
2882     ASSERT_EQUAL_FP32(1.0, s1);
2883     ASSERT_EQUAL_FP32(2.0, s2);
2884     ASSERT_EQUAL_FP32(2.0, s3);
2885     ASSERT_EQUAL_FP32(3.0, s4);
2886     ASSERT_EQUAL_FP32(-2.0, s5);
2887     ASSERT_EQUAL_FP32(-3.0, s6);
2888     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
2889     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
2890     ASSERT_EQUAL_FP32(0.0, s9);
2891     ASSERT_EQUAL_FP32(-0.0, s10);
2892     ASSERT_EQUAL_FP32(-0.0, s11);
2893     ASSERT_EQUAL_FP64(1.0, d12);
2894     ASSERT_EQUAL_FP64(1.0, d13);
2895     ASSERT_EQUAL_FP64(2.0, d14);
2896     ASSERT_EQUAL_FP64(2.0, d15);
2897     ASSERT_EQUAL_FP64(3.0, d16);
2898     ASSERT_EQUAL_FP64(-2.0, d17);
2899     ASSERT_EQUAL_FP64(-3.0, d18);
2900     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
2901     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
2902     ASSERT_EQUAL_FP64(0.0, d21);
2903     ASSERT_EQUAL_FP64(-0.0, d22);
2904     ASSERT_EQUAL_FP64(-0.0, d23);
2905   }
2906 }
2907 
2908 
TEST(frinti)2909 TEST(frinti) {
2910   // VIXL only supports the round-to-nearest FPCR mode, so this test has the
2911   // same results as frintn.
2912   SETUP_WITH_FEATURES(CPUFeatures::kFP);
2913 
2914   START();
2915   __ Fmov(s16, 1.0);
2916   __ Fmov(s17, 1.1);
2917   __ Fmov(s18, 1.5);
2918   __ Fmov(s19, 1.9);
2919   __ Fmov(s20, 2.5);
2920   __ Fmov(s21, -1.5);
2921   __ Fmov(s22, -2.5);
2922   __ Fmov(s23, kFP32PositiveInfinity);
2923   __ Fmov(s24, kFP32NegativeInfinity);
2924   __ Fmov(s25, 0.0);
2925   __ Fmov(s26, -0.0);
2926   __ Fmov(s27, -0.2);
2927 
2928   __ Frinti(s0, s16);
2929   __ Frinti(s1, s17);
2930   __ Frinti(s2, s18);
2931   __ Frinti(s3, s19);
2932   __ Frinti(s4, s20);
2933   __ Frinti(s5, s21);
2934   __ Frinti(s6, s22);
2935   __ Frinti(s7, s23);
2936   __ Frinti(s8, s24);
2937   __ Frinti(s9, s25);
2938   __ Frinti(s10, s26);
2939   __ Frinti(s11, s27);
2940 
2941   __ Fmov(d16, 1.0);
2942   __ Fmov(d17, 1.1);
2943   __ Fmov(d18, 1.5);
2944   __ Fmov(d19, 1.9);
2945   __ Fmov(d20, 2.5);
2946   __ Fmov(d21, -1.5);
2947   __ Fmov(d22, -2.5);
2948   __ Fmov(d23, kFP32PositiveInfinity);
2949   __ Fmov(d24, kFP32NegativeInfinity);
2950   __ Fmov(d25, 0.0);
2951   __ Fmov(d26, -0.0);
2952   __ Fmov(d27, -0.2);
2953 
2954   __ Frinti(d12, d16);
2955   __ Frinti(d13, d17);
2956   __ Frinti(d14, d18);
2957   __ Frinti(d15, d19);
2958   __ Frinti(d16, d20);
2959   __ Frinti(d17, d21);
2960   __ Frinti(d18, d22);
2961   __ Frinti(d19, d23);
2962   __ Frinti(d20, d24);
2963   __ Frinti(d21, d25);
2964   __ Frinti(d22, d26);
2965   __ Frinti(d23, d27);
2966   END();
2967 
2968   if (CAN_RUN()) {
2969     RUN();
2970 
2971     ASSERT_EQUAL_FP32(1.0, s0);
2972     ASSERT_EQUAL_FP32(1.0, s1);
2973     ASSERT_EQUAL_FP32(2.0, s2);
2974     ASSERT_EQUAL_FP32(2.0, s3);
2975     ASSERT_EQUAL_FP32(2.0, s4);
2976     ASSERT_EQUAL_FP32(-2.0, s5);
2977     ASSERT_EQUAL_FP32(-2.0, s6);
2978     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
2979     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
2980     ASSERT_EQUAL_FP32(0.0, s9);
2981     ASSERT_EQUAL_FP32(-0.0, s10);
2982     ASSERT_EQUAL_FP32(-0.0, s11);
2983     ASSERT_EQUAL_FP64(1.0, d12);
2984     ASSERT_EQUAL_FP64(1.0, d13);
2985     ASSERT_EQUAL_FP64(2.0, d14);
2986     ASSERT_EQUAL_FP64(2.0, d15);
2987     ASSERT_EQUAL_FP64(2.0, d16);
2988     ASSERT_EQUAL_FP64(-2.0, d17);
2989     ASSERT_EQUAL_FP64(-2.0, d18);
2990     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
2991     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
2992     ASSERT_EQUAL_FP64(0.0, d21);
2993     ASSERT_EQUAL_FP64(-0.0, d22);
2994     ASSERT_EQUAL_FP64(-0.0, d23);
2995   }
2996 }
2997 
2998 
TEST(frintm)2999 TEST(frintm) {
3000   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3001 
3002   START();
3003   __ Fmov(s16, 1.0);
3004   __ Fmov(s17, 1.1);
3005   __ Fmov(s18, 1.5);
3006   __ Fmov(s19, 1.9);
3007   __ Fmov(s20, 2.5);
3008   __ Fmov(s21, -1.5);
3009   __ Fmov(s22, -2.5);
3010   __ Fmov(s23, kFP32PositiveInfinity);
3011   __ Fmov(s24, kFP32NegativeInfinity);
3012   __ Fmov(s25, 0.0);
3013   __ Fmov(s26, -0.0);
3014   __ Fmov(s27, -0.2);
3015 
3016   __ Frintm(s0, s16);
3017   __ Frintm(s1, s17);
3018   __ Frintm(s2, s18);
3019   __ Frintm(s3, s19);
3020   __ Frintm(s4, s20);
3021   __ Frintm(s5, s21);
3022   __ Frintm(s6, s22);
3023   __ Frintm(s7, s23);
3024   __ Frintm(s8, s24);
3025   __ Frintm(s9, s25);
3026   __ Frintm(s10, s26);
3027   __ Frintm(s11, s27);
3028 
3029   __ Fmov(d16, 1.0);
3030   __ Fmov(d17, 1.1);
3031   __ Fmov(d18, 1.5);
3032   __ Fmov(d19, 1.9);
3033   __ Fmov(d20, 2.5);
3034   __ Fmov(d21, -1.5);
3035   __ Fmov(d22, -2.5);
3036   __ Fmov(d23, kFP32PositiveInfinity);
3037   __ Fmov(d24, kFP32NegativeInfinity);
3038   __ Fmov(d25, 0.0);
3039   __ Fmov(d26, -0.0);
3040   __ Fmov(d27, -0.2);
3041 
3042   __ Frintm(d12, d16);
3043   __ Frintm(d13, d17);
3044   __ Frintm(d14, d18);
3045   __ Frintm(d15, d19);
3046   __ Frintm(d16, d20);
3047   __ Frintm(d17, d21);
3048   __ Frintm(d18, d22);
3049   __ Frintm(d19, d23);
3050   __ Frintm(d20, d24);
3051   __ Frintm(d21, d25);
3052   __ Frintm(d22, d26);
3053   __ Frintm(d23, d27);
3054   END();
3055 
3056   if (CAN_RUN()) {
3057     RUN();
3058 
3059     ASSERT_EQUAL_FP32(1.0, s0);
3060     ASSERT_EQUAL_FP32(1.0, s1);
3061     ASSERT_EQUAL_FP32(1.0, s2);
3062     ASSERT_EQUAL_FP32(1.0, s3);
3063     ASSERT_EQUAL_FP32(2.0, s4);
3064     ASSERT_EQUAL_FP32(-2.0, s5);
3065     ASSERT_EQUAL_FP32(-3.0, s6);
3066     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
3067     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
3068     ASSERT_EQUAL_FP32(0.0, s9);
3069     ASSERT_EQUAL_FP32(-0.0, s10);
3070     ASSERT_EQUAL_FP32(-1.0, s11);
3071     ASSERT_EQUAL_FP64(1.0, d12);
3072     ASSERT_EQUAL_FP64(1.0, d13);
3073     ASSERT_EQUAL_FP64(1.0, d14);
3074     ASSERT_EQUAL_FP64(1.0, d15);
3075     ASSERT_EQUAL_FP64(2.0, d16);
3076     ASSERT_EQUAL_FP64(-2.0, d17);
3077     ASSERT_EQUAL_FP64(-3.0, d18);
3078     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
3079     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
3080     ASSERT_EQUAL_FP64(0.0, d21);
3081     ASSERT_EQUAL_FP64(-0.0, d22);
3082     ASSERT_EQUAL_FP64(-1.0, d23);
3083   }
3084 }
3085 
3086 
TEST(frintn)3087 TEST(frintn) {
3088   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3089 
3090   START();
3091   __ Fmov(s16, 1.0);
3092   __ Fmov(s17, 1.1);
3093   __ Fmov(s18, 1.5);
3094   __ Fmov(s19, 1.9);
3095   __ Fmov(s20, 2.5);
3096   __ Fmov(s21, -1.5);
3097   __ Fmov(s22, -2.5);
3098   __ Fmov(s23, kFP32PositiveInfinity);
3099   __ Fmov(s24, kFP32NegativeInfinity);
3100   __ Fmov(s25, 0.0);
3101   __ Fmov(s26, -0.0);
3102   __ Fmov(s27, -0.2);
3103 
3104   __ Frintn(s0, s16);
3105   __ Frintn(s1, s17);
3106   __ Frintn(s2, s18);
3107   __ Frintn(s3, s19);
3108   __ Frintn(s4, s20);
3109   __ Frintn(s5, s21);
3110   __ Frintn(s6, s22);
3111   __ Frintn(s7, s23);
3112   __ Frintn(s8, s24);
3113   __ Frintn(s9, s25);
3114   __ Frintn(s10, s26);
3115   __ Frintn(s11, s27);
3116 
3117   __ Fmov(d16, 1.0);
3118   __ Fmov(d17, 1.1);
3119   __ Fmov(d18, 1.5);
3120   __ Fmov(d19, 1.9);
3121   __ Fmov(d20, 2.5);
3122   __ Fmov(d21, -1.5);
3123   __ Fmov(d22, -2.5);
3124   __ Fmov(d23, kFP32PositiveInfinity);
3125   __ Fmov(d24, kFP32NegativeInfinity);
3126   __ Fmov(d25, 0.0);
3127   __ Fmov(d26, -0.0);
3128   __ Fmov(d27, -0.2);
3129 
3130   __ Frintn(d12, d16);
3131   __ Frintn(d13, d17);
3132   __ Frintn(d14, d18);
3133   __ Frintn(d15, d19);
3134   __ Frintn(d16, d20);
3135   __ Frintn(d17, d21);
3136   __ Frintn(d18, d22);
3137   __ Frintn(d19, d23);
3138   __ Frintn(d20, d24);
3139   __ Frintn(d21, d25);
3140   __ Frintn(d22, d26);
3141   __ Frintn(d23, d27);
3142   END();
3143 
3144   if (CAN_RUN()) {
3145     RUN();
3146 
3147     ASSERT_EQUAL_FP32(1.0, s0);
3148     ASSERT_EQUAL_FP32(1.0, s1);
3149     ASSERT_EQUAL_FP32(2.0, s2);
3150     ASSERT_EQUAL_FP32(2.0, s3);
3151     ASSERT_EQUAL_FP32(2.0, s4);
3152     ASSERT_EQUAL_FP32(-2.0, s5);
3153     ASSERT_EQUAL_FP32(-2.0, s6);
3154     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
3155     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
3156     ASSERT_EQUAL_FP32(0.0, s9);
3157     ASSERT_EQUAL_FP32(-0.0, s10);
3158     ASSERT_EQUAL_FP32(-0.0, s11);
3159     ASSERT_EQUAL_FP64(1.0, d12);
3160     ASSERT_EQUAL_FP64(1.0, d13);
3161     ASSERT_EQUAL_FP64(2.0, d14);
3162     ASSERT_EQUAL_FP64(2.0, d15);
3163     ASSERT_EQUAL_FP64(2.0, d16);
3164     ASSERT_EQUAL_FP64(-2.0, d17);
3165     ASSERT_EQUAL_FP64(-2.0, d18);
3166     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
3167     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
3168     ASSERT_EQUAL_FP64(0.0, d21);
3169     ASSERT_EQUAL_FP64(-0.0, d22);
3170     ASSERT_EQUAL_FP64(-0.0, d23);
3171   }
3172 }
3173 
3174 
TEST(frintp)3175 TEST(frintp) {
3176   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3177 
3178   START();
3179   __ Fmov(s16, 1.0);
3180   __ Fmov(s17, 1.1);
3181   __ Fmov(s18, 1.5);
3182   __ Fmov(s19, 1.9);
3183   __ Fmov(s20, 2.5);
3184   __ Fmov(s21, -1.5);
3185   __ Fmov(s22, -2.5);
3186   __ Fmov(s23, kFP32PositiveInfinity);
3187   __ Fmov(s24, kFP32NegativeInfinity);
3188   __ Fmov(s25, 0.0);
3189   __ Fmov(s26, -0.0);
3190   __ Fmov(s27, -0.2);
3191 
3192   __ Frintp(s0, s16);
3193   __ Frintp(s1, s17);
3194   __ Frintp(s2, s18);
3195   __ Frintp(s3, s19);
3196   __ Frintp(s4, s20);
3197   __ Frintp(s5, s21);
3198   __ Frintp(s6, s22);
3199   __ Frintp(s7, s23);
3200   __ Frintp(s8, s24);
3201   __ Frintp(s9, s25);
3202   __ Frintp(s10, s26);
3203   __ Frintp(s11, s27);
3204 
3205   __ Fmov(d16, 1.0);
3206   __ Fmov(d17, 1.1);
3207   __ Fmov(d18, 1.5);
3208   __ Fmov(d19, 1.9);
3209   __ Fmov(d20, 2.5);
3210   __ Fmov(d21, -1.5);
3211   __ Fmov(d22, -2.5);
3212   __ Fmov(d23, kFP32PositiveInfinity);
3213   __ Fmov(d24, kFP32NegativeInfinity);
3214   __ Fmov(d25, 0.0);
3215   __ Fmov(d26, -0.0);
3216   __ Fmov(d27, -0.2);
3217 
3218   __ Frintp(d12, d16);
3219   __ Frintp(d13, d17);
3220   __ Frintp(d14, d18);
3221   __ Frintp(d15, d19);
3222   __ Frintp(d16, d20);
3223   __ Frintp(d17, d21);
3224   __ Frintp(d18, d22);
3225   __ Frintp(d19, d23);
3226   __ Frintp(d20, d24);
3227   __ Frintp(d21, d25);
3228   __ Frintp(d22, d26);
3229   __ Frintp(d23, d27);
3230   END();
3231 
3232   if (CAN_RUN()) {
3233     RUN();
3234 
3235     ASSERT_EQUAL_FP32(1.0, s0);
3236     ASSERT_EQUAL_FP32(2.0, s1);
3237     ASSERT_EQUAL_FP32(2.0, s2);
3238     ASSERT_EQUAL_FP32(2.0, s3);
3239     ASSERT_EQUAL_FP32(3.0, s4);
3240     ASSERT_EQUAL_FP32(-1.0, s5);
3241     ASSERT_EQUAL_FP32(-2.0, s6);
3242     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
3243     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
3244     ASSERT_EQUAL_FP32(0.0, s9);
3245     ASSERT_EQUAL_FP32(-0.0, s10);
3246     ASSERT_EQUAL_FP32(-0.0, s11);
3247     ASSERT_EQUAL_FP64(1.0, d12);
3248     ASSERT_EQUAL_FP64(2.0, d13);
3249     ASSERT_EQUAL_FP64(2.0, d14);
3250     ASSERT_EQUAL_FP64(2.0, d15);
3251     ASSERT_EQUAL_FP64(3.0, d16);
3252     ASSERT_EQUAL_FP64(-1.0, d17);
3253     ASSERT_EQUAL_FP64(-2.0, d18);
3254     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
3255     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
3256     ASSERT_EQUAL_FP64(0.0, d21);
3257     ASSERT_EQUAL_FP64(-0.0, d22);
3258     ASSERT_EQUAL_FP64(-0.0, d23);
3259   }
3260 }
3261 
3262 
TEST(frintx)3263 TEST(frintx) {
3264   // VIXL only supports the round-to-nearest FPCR mode, and it doesn't support
3265   // FP exceptions, so this test has the same results as frintn (and frinti).
3266   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3267 
3268   START();
3269   __ Fmov(s16, 1.0);
3270   __ Fmov(s17, 1.1);
3271   __ Fmov(s18, 1.5);
3272   __ Fmov(s19, 1.9);
3273   __ Fmov(s20, 2.5);
3274   __ Fmov(s21, -1.5);
3275   __ Fmov(s22, -2.5);
3276   __ Fmov(s23, kFP32PositiveInfinity);
3277   __ Fmov(s24, kFP32NegativeInfinity);
3278   __ Fmov(s25, 0.0);
3279   __ Fmov(s26, -0.0);
3280   __ Fmov(s27, -0.2);
3281 
3282   __ Frintx(s0, s16);
3283   __ Frintx(s1, s17);
3284   __ Frintx(s2, s18);
3285   __ Frintx(s3, s19);
3286   __ Frintx(s4, s20);
3287   __ Frintx(s5, s21);
3288   __ Frintx(s6, s22);
3289   __ Frintx(s7, s23);
3290   __ Frintx(s8, s24);
3291   __ Frintx(s9, s25);
3292   __ Frintx(s10, s26);
3293   __ Frintx(s11, s27);
3294 
3295   __ Fmov(d16, 1.0);
3296   __ Fmov(d17, 1.1);
3297   __ Fmov(d18, 1.5);
3298   __ Fmov(d19, 1.9);
3299   __ Fmov(d20, 2.5);
3300   __ Fmov(d21, -1.5);
3301   __ Fmov(d22, -2.5);
3302   __ Fmov(d23, kFP32PositiveInfinity);
3303   __ Fmov(d24, kFP32NegativeInfinity);
3304   __ Fmov(d25, 0.0);
3305   __ Fmov(d26, -0.0);
3306   __ Fmov(d27, -0.2);
3307 
3308   __ Frintx(d12, d16);
3309   __ Frintx(d13, d17);
3310   __ Frintx(d14, d18);
3311   __ Frintx(d15, d19);
3312   __ Frintx(d16, d20);
3313   __ Frintx(d17, d21);
3314   __ Frintx(d18, d22);
3315   __ Frintx(d19, d23);
3316   __ Frintx(d20, d24);
3317   __ Frintx(d21, d25);
3318   __ Frintx(d22, d26);
3319   __ Frintx(d23, d27);
3320   END();
3321 
3322   if (CAN_RUN()) {
3323     RUN();
3324 
3325     ASSERT_EQUAL_FP32(1.0, s0);
3326     ASSERT_EQUAL_FP32(1.0, s1);
3327     ASSERT_EQUAL_FP32(2.0, s2);
3328     ASSERT_EQUAL_FP32(2.0, s3);
3329     ASSERT_EQUAL_FP32(2.0, s4);
3330     ASSERT_EQUAL_FP32(-2.0, s5);
3331     ASSERT_EQUAL_FP32(-2.0, s6);
3332     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
3333     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
3334     ASSERT_EQUAL_FP32(0.0, s9);
3335     ASSERT_EQUAL_FP32(-0.0, s10);
3336     ASSERT_EQUAL_FP32(-0.0, s11);
3337     ASSERT_EQUAL_FP64(1.0, d12);
3338     ASSERT_EQUAL_FP64(1.0, d13);
3339     ASSERT_EQUAL_FP64(2.0, d14);
3340     ASSERT_EQUAL_FP64(2.0, d15);
3341     ASSERT_EQUAL_FP64(2.0, d16);
3342     ASSERT_EQUAL_FP64(-2.0, d17);
3343     ASSERT_EQUAL_FP64(-2.0, d18);
3344     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d19);
3345     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d20);
3346     ASSERT_EQUAL_FP64(0.0, d21);
3347     ASSERT_EQUAL_FP64(-0.0, d22);
3348     ASSERT_EQUAL_FP64(-0.0, d23);
3349   }
3350 }
3351 
3352 
TEST(frintz)3353 TEST(frintz) {
3354   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3355 
3356   START();
3357   __ Fmov(s16, 1.0);
3358   __ Fmov(s17, 1.1);
3359   __ Fmov(s18, 1.5);
3360   __ Fmov(s19, 1.9);
3361   __ Fmov(s20, 2.5);
3362   __ Fmov(s21, -1.5);
3363   __ Fmov(s22, -2.5);
3364   __ Fmov(s23, kFP32PositiveInfinity);
3365   __ Fmov(s24, kFP32NegativeInfinity);
3366   __ Fmov(s25, 0.0);
3367   __ Fmov(s26, -0.0);
3368 
3369   __ Frintz(s0, s16);
3370   __ Frintz(s1, s17);
3371   __ Frintz(s2, s18);
3372   __ Frintz(s3, s19);
3373   __ Frintz(s4, s20);
3374   __ Frintz(s5, s21);
3375   __ Frintz(s6, s22);
3376   __ Frintz(s7, s23);
3377   __ Frintz(s8, s24);
3378   __ Frintz(s9, s25);
3379   __ Frintz(s10, s26);
3380 
3381   __ Fmov(d16, 1.0);
3382   __ Fmov(d17, 1.1);
3383   __ Fmov(d18, 1.5);
3384   __ Fmov(d19, 1.9);
3385   __ Fmov(d20, 2.5);
3386   __ Fmov(d21, -1.5);
3387   __ Fmov(d22, -2.5);
3388   __ Fmov(d23, kFP32PositiveInfinity);
3389   __ Fmov(d24, kFP32NegativeInfinity);
3390   __ Fmov(d25, 0.0);
3391   __ Fmov(d26, -0.0);
3392 
3393   __ Frintz(d11, d16);
3394   __ Frintz(d12, d17);
3395   __ Frintz(d13, d18);
3396   __ Frintz(d14, d19);
3397   __ Frintz(d15, d20);
3398   __ Frintz(d16, d21);
3399   __ Frintz(d17, d22);
3400   __ Frintz(d18, d23);
3401   __ Frintz(d19, d24);
3402   __ Frintz(d20, d25);
3403   __ Frintz(d21, d26);
3404   END();
3405 
3406   if (CAN_RUN()) {
3407     RUN();
3408 
3409     ASSERT_EQUAL_FP32(1.0, s0);
3410     ASSERT_EQUAL_FP32(1.0, s1);
3411     ASSERT_EQUAL_FP32(1.0, s2);
3412     ASSERT_EQUAL_FP32(1.0, s3);
3413     ASSERT_EQUAL_FP32(2.0, s4);
3414     ASSERT_EQUAL_FP32(-1.0, s5);
3415     ASSERT_EQUAL_FP32(-2.0, s6);
3416     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
3417     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
3418     ASSERT_EQUAL_FP32(0.0, s9);
3419     ASSERT_EQUAL_FP32(-0.0, s10);
3420     ASSERT_EQUAL_FP64(1.0, d11);
3421     ASSERT_EQUAL_FP64(1.0, d12);
3422     ASSERT_EQUAL_FP64(1.0, d13);
3423     ASSERT_EQUAL_FP64(1.0, d14);
3424     ASSERT_EQUAL_FP64(2.0, d15);
3425     ASSERT_EQUAL_FP64(-1.0, d16);
3426     ASSERT_EQUAL_FP64(-2.0, d17);
3427     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d18);
3428     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d19);
3429     ASSERT_EQUAL_FP64(0.0, d20);
3430     ASSERT_EQUAL_FP64(-0.0, d21);
3431   }
3432 }
3433 
3434 
TEST(fcvt_ds)3435 TEST(fcvt_ds) {
3436   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3437 
3438   START();
3439   __ Fmov(s16, 1.0);
3440   __ Fmov(s17, 1.1);
3441   __ Fmov(s18, 1.5);
3442   __ Fmov(s19, 1.9);
3443   __ Fmov(s20, 2.5);
3444   __ Fmov(s21, -1.5);
3445   __ Fmov(s22, -2.5);
3446   __ Fmov(s23, kFP32PositiveInfinity);
3447   __ Fmov(s24, kFP32NegativeInfinity);
3448   __ Fmov(s25, 0.0);
3449   __ Fmov(s26, -0.0);
3450   __ Fmov(s27, FLT_MAX);
3451   __ Fmov(s28, FLT_MIN);
3452   __ Fmov(s29, RawbitsToFloat(0x7fc12345));  // Quiet NaN.
3453   __ Fmov(s30, RawbitsToFloat(0x7f812345));  // Signalling NaN.
3454 
3455   __ Fcvt(d0, s16);
3456   __ Fcvt(d1, s17);
3457   __ Fcvt(d2, s18);
3458   __ Fcvt(d3, s19);
3459   __ Fcvt(d4, s20);
3460   __ Fcvt(d5, s21);
3461   __ Fcvt(d6, s22);
3462   __ Fcvt(d7, s23);
3463   __ Fcvt(d8, s24);
3464   __ Fcvt(d9, s25);
3465   __ Fcvt(d10, s26);
3466   __ Fcvt(d11, s27);
3467   __ Fcvt(d12, s28);
3468   __ Fcvt(d13, s29);
3469   __ Fcvt(d14, s30);
3470   END();
3471 
3472   if (CAN_RUN()) {
3473     RUN();
3474 
3475     ASSERT_EQUAL_FP64(1.0f, d0);
3476     ASSERT_EQUAL_FP64(1.1f, d1);
3477     ASSERT_EQUAL_FP64(1.5f, d2);
3478     ASSERT_EQUAL_FP64(1.9f, d3);
3479     ASSERT_EQUAL_FP64(2.5f, d4);
3480     ASSERT_EQUAL_FP64(-1.5f, d5);
3481     ASSERT_EQUAL_FP64(-2.5f, d6);
3482     ASSERT_EQUAL_FP64(kFP64PositiveInfinity, d7);
3483     ASSERT_EQUAL_FP64(kFP64NegativeInfinity, d8);
3484     ASSERT_EQUAL_FP64(0.0f, d9);
3485     ASSERT_EQUAL_FP64(-0.0f, d10);
3486     ASSERT_EQUAL_FP64(FLT_MAX, d11);
3487     ASSERT_EQUAL_FP64(FLT_MIN, d12);
3488 
3489     // Check that the NaN payload is preserved according to Aarch64 conversion
3490     // rules:
3491     //  - The sign bit is preserved.
3492     //  - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
3493     //  - The remaining mantissa bits are copied until they run out.
3494     //  - The low-order bits that haven't already been assigned are set to 0.
3495     ASSERT_EQUAL_FP64(RawbitsToDouble(0x7ff82468a0000000), d13);
3496     ASSERT_EQUAL_FP64(RawbitsToDouble(0x7ff82468a0000000), d14);
3497   }
3498 }
3499 
3500 
TEST(fcvt_sd)3501 TEST(fcvt_sd) {
3502   // Test simple conversions here. Complex behaviour (such as rounding
3503   // specifics) are tested in the simulator tests.
3504 
3505   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3506 
3507   START();
3508   __ Fmov(d16, 1.0);
3509   __ Fmov(d17, 1.1);
3510   __ Fmov(d18, 1.5);
3511   __ Fmov(d19, 1.9);
3512   __ Fmov(d20, 2.5);
3513   __ Fmov(d21, -1.5);
3514   __ Fmov(d22, -2.5);
3515   __ Fmov(d23, kFP32PositiveInfinity);
3516   __ Fmov(d24, kFP32NegativeInfinity);
3517   __ Fmov(d25, 0.0);
3518   __ Fmov(d26, -0.0);
3519   __ Fmov(d27, FLT_MAX);
3520   __ Fmov(d28, FLT_MIN);
3521   __ Fmov(d29, RawbitsToDouble(0x7ff82468a0000000));  // Quiet NaN.
3522   __ Fmov(d30, RawbitsToDouble(0x7ff02468a0000000));  // Signalling NaN.
3523 
3524   __ Fcvt(s0, d16);
3525   __ Fcvt(s1, d17);
3526   __ Fcvt(s2, d18);
3527   __ Fcvt(s3, d19);
3528   __ Fcvt(s4, d20);
3529   __ Fcvt(s5, d21);
3530   __ Fcvt(s6, d22);
3531   __ Fcvt(s7, d23);
3532   __ Fcvt(s8, d24);
3533   __ Fcvt(s9, d25);
3534   __ Fcvt(s10, d26);
3535   __ Fcvt(s11, d27);
3536   __ Fcvt(s12, d28);
3537   __ Fcvt(s13, d29);
3538   __ Fcvt(s14, d30);
3539   END();
3540 
3541   if (CAN_RUN()) {
3542     RUN();
3543 
3544     ASSERT_EQUAL_FP32(1.0f, s0);
3545     ASSERT_EQUAL_FP32(1.1f, s1);
3546     ASSERT_EQUAL_FP32(1.5f, s2);
3547     ASSERT_EQUAL_FP32(1.9f, s3);
3548     ASSERT_EQUAL_FP32(2.5f, s4);
3549     ASSERT_EQUAL_FP32(-1.5f, s5);
3550     ASSERT_EQUAL_FP32(-2.5f, s6);
3551     ASSERT_EQUAL_FP32(kFP32PositiveInfinity, s7);
3552     ASSERT_EQUAL_FP32(kFP32NegativeInfinity, s8);
3553     ASSERT_EQUAL_FP32(0.0f, s9);
3554     ASSERT_EQUAL_FP32(-0.0f, s10);
3555     ASSERT_EQUAL_FP32(FLT_MAX, s11);
3556     ASSERT_EQUAL_FP32(FLT_MIN, s12);
3557 
3558     // Check that the NaN payload is preserved according to Aarch64 conversion
3559     // rules:
3560     //  - The sign bit is preserved.
3561     //  - The top bit of the mantissa is forced to 1 (making it a quiet NaN).
3562     //  - The remaining mantissa bits are copied until they run out.
3563     //  - The low-order bits that haven't already been assigned are set to 0.
3564     ASSERT_EQUAL_FP32(RawbitsToFloat(0x7fc12345), s13);
3565     ASSERT_EQUAL_FP32(RawbitsToFloat(0x7fc12345), s14);
3566   }
3567 }
3568 
3569 
TEST(fcvt_half)3570 TEST(fcvt_half) {
3571   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3572 
3573   START();
3574   Label done;
3575   {
3576     // Check all exact conversions from half to float and back.
3577     Label ok, fail;
3578     __ Mov(w0, 0);
3579     for (int i = 0; i < 0xffff; i += 3) {
3580       if ((i & 0x7c00) == 0x7c00) continue;
3581       __ Mov(w1, i);
3582       __ Fmov(s1, w1);
3583       __ Fcvt(s2, h1);
3584       __ Fcvt(h2, s2);
3585       __ Fmov(w2, s2);
3586       __ Cmp(w1, w2);
3587       __ B(&fail, ne);
3588     }
3589     __ B(&ok);
3590     __ Bind(&fail);
3591     __ Mov(w0, 1);
3592     __ B(&done);
3593     __ Bind(&ok);
3594   }
3595   {
3596     // Check all exact conversions from half to double and back.
3597     Label ok, fail;
3598     for (int i = 0; i < 0xffff; i += 3) {
3599       if ((i & 0x7c00) == 0x7c00) continue;
3600       __ Mov(w1, i);
3601       __ Fmov(s1, w1);
3602       __ Fcvt(d2, h1);
3603       __ Fcvt(h2, d2);
3604       __ Fmov(w2, s2);
3605       __ Cmp(w1, w2);
3606       __ B(&fail, ne);
3607     }
3608     __ B(&ok);
3609     __ Bind(&fail);
3610     __ Mov(w0, 2);
3611     __ Bind(&ok);
3612   }
3613   __ Bind(&done);
3614 
3615   // Check some other interesting values.
3616   __ Fmov(s0, kFP32PositiveInfinity);
3617   __ Fmov(s1, kFP32NegativeInfinity);
3618   __ Fmov(s2, 65504);       // Max half precision.
3619   __ Fmov(s3, 6.10352e-5);  // Min positive normal.
3620   __ Fmov(s4, 6.09756e-5);  // Max subnormal.
3621   __ Fmov(s5, 5.96046e-8);  // Min positive subnormal.
3622   __ Fmov(s6, 5e-9);        // Not representable -> zero.
3623   __ Fmov(s7, -0.0);
3624   __ Fcvt(h0, s0);
3625   __ Fcvt(h1, s1);
3626   __ Fcvt(h2, s2);
3627   __ Fcvt(h3, s3);
3628   __ Fcvt(h4, s4);
3629   __ Fcvt(h5, s5);
3630   __ Fcvt(h6, s6);
3631   __ Fcvt(h7, s7);
3632 
3633   __ Fmov(d20, kFP64PositiveInfinity);
3634   __ Fmov(d21, kFP64NegativeInfinity);
3635   __ Fmov(d22, 65504);       // Max half precision.
3636   __ Fmov(d23, 6.10352e-5);  // Min positive normal.
3637   __ Fmov(d24, 6.09756e-5);  // Max subnormal.
3638   __ Fmov(d25, 5.96046e-8);  // Min positive subnormal.
3639   __ Fmov(d26, 5e-9);        // Not representable -> zero.
3640   __ Fmov(d27, -0.0);
3641   __ Fcvt(h20, d20);
3642   __ Fcvt(h21, d21);
3643   __ Fcvt(h22, d22);
3644   __ Fcvt(h23, d23);
3645   __ Fcvt(h24, d24);
3646   __ Fcvt(h25, d25);
3647   __ Fcvt(h26, d26);
3648   __ Fcvt(h27, d27);
3649   END();
3650 
3651   if (CAN_RUN()) {
3652     RUN();
3653 
3654     ASSERT_EQUAL_32(0, w0);  // 1 => float failed, 2 => double failed.
3655     ASSERT_EQUAL_128(0, Float16ToRawbits(kFP16PositiveInfinity), q0);
3656     ASSERT_EQUAL_128(0, Float16ToRawbits(kFP16NegativeInfinity), q1);
3657     ASSERT_EQUAL_128(0, 0x7bff, q2);
3658     ASSERT_EQUAL_128(0, 0x0400, q3);
3659     ASSERT_EQUAL_128(0, 0x03ff, q4);
3660     ASSERT_EQUAL_128(0, 0x0001, q5);
3661     ASSERT_EQUAL_128(0, 0, q6);
3662     ASSERT_EQUAL_128(0, 0x8000, q7);
3663     ASSERT_EQUAL_128(0, Float16ToRawbits(kFP16PositiveInfinity), q20);
3664     ASSERT_EQUAL_128(0, Float16ToRawbits(kFP16NegativeInfinity), q21);
3665     ASSERT_EQUAL_128(0, 0x7bff, q22);
3666     ASSERT_EQUAL_128(0, 0x0400, q23);
3667     ASSERT_EQUAL_128(0, 0x03ff, q24);
3668     ASSERT_EQUAL_128(0, 0x0001, q25);
3669     ASSERT_EQUAL_128(0, 0, q26);
3670     ASSERT_EQUAL_128(0, 0x8000, q27);
3671   }
3672 }
3673 
3674 
TEST(fcvtas)3675 TEST(fcvtas) {
3676   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3677 
3678   START();
3679   __ Fmov(s0, 1.0);
3680   __ Fmov(s1, 1.1);
3681   __ Fmov(s2, 2.5);
3682   __ Fmov(s3, -2.5);
3683   __ Fmov(s4, kFP32PositiveInfinity);
3684   __ Fmov(s5, kFP32NegativeInfinity);
3685   __ Fmov(s6, 0x7fffff80);  // Largest float < INT32_MAX.
3686   __ Fneg(s7, s6);          // Smallest float > INT32_MIN.
3687   __ Fmov(d8, 1.0);
3688   __ Fmov(d9, 1.1);
3689   __ Fmov(d10, 2.5);
3690   __ Fmov(d11, -2.5);
3691   __ Fmov(d12, kFP64PositiveInfinity);
3692   __ Fmov(d13, kFP64NegativeInfinity);
3693   __ Fmov(d14, kWMaxInt - 1);
3694   __ Fmov(d15, kWMinInt + 1);
3695   __ Fmov(s17, 1.1);
3696   __ Fmov(s18, 2.5);
3697   __ Fmov(s19, -2.5);
3698   __ Fmov(s20, kFP32PositiveInfinity);
3699   __ Fmov(s21, kFP32NegativeInfinity);
3700   __ Fmov(s22, 0x7fffff8000000000);  // Largest float < INT64_MAX.
3701   __ Fneg(s23, s22);                 // Smallest float > INT64_MIN.
3702   __ Fmov(d24, 1.1);
3703   __ Fmov(d25, 2.5);
3704   __ Fmov(d26, -2.5);
3705   __ Fmov(d27, kFP64PositiveInfinity);
3706   __ Fmov(d28, kFP64NegativeInfinity);
3707   __ Fmov(d29, 0x7ffffffffffffc00);  // Largest double < INT64_MAX.
3708   __ Fneg(d30, d29);                 // Smallest double > INT64_MIN.
3709 
3710   __ Fcvtas(w0, s0);
3711   __ Fcvtas(w1, s1);
3712   __ Fcvtas(w2, s2);
3713   __ Fcvtas(w3, s3);
3714   __ Fcvtas(w4, s4);
3715   __ Fcvtas(w5, s5);
3716   __ Fcvtas(w6, s6);
3717   __ Fcvtas(w7, s7);
3718   __ Fcvtas(w8, d8);
3719   __ Fcvtas(w9, d9);
3720   __ Fcvtas(w10, d10);
3721   __ Fcvtas(w11, d11);
3722   __ Fcvtas(w12, d12);
3723   __ Fcvtas(w13, d13);
3724   __ Fcvtas(w14, d14);
3725   __ Fcvtas(w15, d15);
3726   __ Fcvtas(x17, s17);
3727   __ Fcvtas(x18, s18);
3728   __ Fcvtas(x19, s19);
3729   __ Fcvtas(x20, s20);
3730   __ Fcvtas(x21, s21);
3731   __ Fcvtas(x22, s22);
3732   __ Fcvtas(x23, s23);
3733   __ Fcvtas(x24, d24);
3734   __ Fcvtas(x25, d25);
3735   __ Fcvtas(x26, d26);
3736   __ Fcvtas(x27, d27);
3737   __ Fcvtas(x28, d28);
3738   __ Fcvtas(x29, d29);
3739   __ Fcvtas(x30, d30);
3740   END();
3741 
3742   if (CAN_RUN()) {
3743     RUN();
3744 
3745     ASSERT_EQUAL_64(1, x0);
3746     ASSERT_EQUAL_64(1, x1);
3747     ASSERT_EQUAL_64(3, x2);
3748     ASSERT_EQUAL_64(0xfffffffd, x3);
3749     ASSERT_EQUAL_64(0x7fffffff, x4);
3750     ASSERT_EQUAL_64(0x80000000, x5);
3751     ASSERT_EQUAL_64(0x7fffff80, x6);
3752     ASSERT_EQUAL_64(0x80000080, x7);
3753     ASSERT_EQUAL_64(1, x8);
3754     ASSERT_EQUAL_64(1, x9);
3755     ASSERT_EQUAL_64(3, x10);
3756     ASSERT_EQUAL_64(0xfffffffd, x11);
3757     ASSERT_EQUAL_64(0x7fffffff, x12);
3758     ASSERT_EQUAL_64(0x80000000, x13);
3759     ASSERT_EQUAL_64(0x7ffffffe, x14);
3760     ASSERT_EQUAL_64(0x80000001, x15);
3761     ASSERT_EQUAL_64(1, x17);
3762     ASSERT_EQUAL_64(3, x18);
3763     ASSERT_EQUAL_64(0xfffffffffffffffd, x19);
3764     ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
3765     ASSERT_EQUAL_64(0x8000000000000000, x21);
3766     ASSERT_EQUAL_64(0x7fffff8000000000, x22);
3767     ASSERT_EQUAL_64(0x8000008000000000, x23);
3768     ASSERT_EQUAL_64(1, x24);
3769     ASSERT_EQUAL_64(3, x25);
3770     ASSERT_EQUAL_64(0xfffffffffffffffd, x26);
3771     ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
3772     ASSERT_EQUAL_64(0x8000000000000000, x28);
3773     ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
3774     ASSERT_EQUAL_64(0x8000000000000400, x30);
3775   }
3776 }
3777 
3778 
TEST(fcvtau)3779 TEST(fcvtau) {
3780   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3781 
3782   START();
3783   __ Fmov(s0, 1.0);
3784   __ Fmov(s1, 1.1);
3785   __ Fmov(s2, 2.5);
3786   __ Fmov(s3, -2.5);
3787   __ Fmov(s4, kFP32PositiveInfinity);
3788   __ Fmov(s5, kFP32NegativeInfinity);
3789   __ Fmov(s6, 0xffffff00);  // Largest float < UINT32_MAX.
3790   __ Fmov(d8, 1.0);
3791   __ Fmov(d9, 1.1);
3792   __ Fmov(d10, 2.5);
3793   __ Fmov(d11, -2.5);
3794   __ Fmov(d12, kFP64PositiveInfinity);
3795   __ Fmov(d13, kFP64NegativeInfinity);
3796   __ Fmov(d14, 0xfffffffe);
3797   __ Fmov(s16, 1.0);
3798   __ Fmov(s17, 1.1);
3799   __ Fmov(s18, 2.5);
3800   __ Fmov(s19, -2.5);
3801   __ Fmov(s20, kFP32PositiveInfinity);
3802   __ Fmov(s21, kFP32NegativeInfinity);
3803   __ Fmov(s22, 0xffffff0000000000);  // Largest float < UINT64_MAX.
3804   __ Fmov(d24, 1.1);
3805   __ Fmov(d25, 2.5);
3806   __ Fmov(d26, -2.5);
3807   __ Fmov(d27, kFP64PositiveInfinity);
3808   __ Fmov(d28, kFP64NegativeInfinity);
3809   __ Fmov(d29, 0xfffffffffffff800);  // Largest double < UINT64_MAX.
3810   __ Fmov(s30, 0x100000000);
3811 
3812   __ Fcvtau(w0, s0);
3813   __ Fcvtau(w1, s1);
3814   __ Fcvtau(w2, s2);
3815   __ Fcvtau(w3, s3);
3816   __ Fcvtau(w4, s4);
3817   __ Fcvtau(w5, s5);
3818   __ Fcvtau(w6, s6);
3819   __ Fcvtau(w8, d8);
3820   __ Fcvtau(w9, d9);
3821   __ Fcvtau(w10, d10);
3822   __ Fcvtau(w11, d11);
3823   __ Fcvtau(w12, d12);
3824   __ Fcvtau(w13, d13);
3825   __ Fcvtau(w14, d14);
3826   __ Fcvtau(w15, d15);
3827   __ Fcvtau(x16, s16);
3828   __ Fcvtau(x17, s17);
3829   __ Fcvtau(x18, s18);
3830   __ Fcvtau(x19, s19);
3831   __ Fcvtau(x20, s20);
3832   __ Fcvtau(x21, s21);
3833   __ Fcvtau(x22, s22);
3834   __ Fcvtau(x24, d24);
3835   __ Fcvtau(x25, d25);
3836   __ Fcvtau(x26, d26);
3837   __ Fcvtau(x27, d27);
3838   __ Fcvtau(x28, d28);
3839   __ Fcvtau(x29, d29);
3840   __ Fcvtau(w30, s30);
3841   END();
3842 
3843   if (CAN_RUN()) {
3844     RUN();
3845 
3846     ASSERT_EQUAL_64(1, x0);
3847     ASSERT_EQUAL_64(1, x1);
3848     ASSERT_EQUAL_64(3, x2);
3849     ASSERT_EQUAL_64(0, x3);
3850     ASSERT_EQUAL_64(0xffffffff, x4);
3851     ASSERT_EQUAL_64(0, x5);
3852     ASSERT_EQUAL_64(0xffffff00, x6);
3853     ASSERT_EQUAL_64(1, x8);
3854     ASSERT_EQUAL_64(1, x9);
3855     ASSERT_EQUAL_64(3, x10);
3856     ASSERT_EQUAL_64(0, x11);
3857     ASSERT_EQUAL_64(0xffffffff, x12);
3858     ASSERT_EQUAL_64(0, x13);
3859     ASSERT_EQUAL_64(0xfffffffe, x14);
3860     ASSERT_EQUAL_64(1, x16);
3861     ASSERT_EQUAL_64(1, x17);
3862     ASSERT_EQUAL_64(3, x18);
3863     ASSERT_EQUAL_64(0, x19);
3864     ASSERT_EQUAL_64(0xffffffffffffffff, x20);
3865     ASSERT_EQUAL_64(0, x21);
3866     ASSERT_EQUAL_64(0xffffff0000000000, x22);
3867     ASSERT_EQUAL_64(1, x24);
3868     ASSERT_EQUAL_64(3, x25);
3869     ASSERT_EQUAL_64(0, x26);
3870     ASSERT_EQUAL_64(0xffffffffffffffff, x27);
3871     ASSERT_EQUAL_64(0, x28);
3872     ASSERT_EQUAL_64(0xfffffffffffff800, x29);
3873     ASSERT_EQUAL_64(0xffffffff, x30);
3874   }
3875 }
3876 
3877 
TEST(fcvtms)3878 TEST(fcvtms) {
3879   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3880 
3881   START();
3882   __ Fmov(s0, 1.0);
3883   __ Fmov(s1, 1.1);
3884   __ Fmov(s2, 1.5);
3885   __ Fmov(s3, -1.5);
3886   __ Fmov(s4, kFP32PositiveInfinity);
3887   __ Fmov(s5, kFP32NegativeInfinity);
3888   __ Fmov(s6, 0x7fffff80);  // Largest float < INT32_MAX.
3889   __ Fneg(s7, s6);          // Smallest float > INT32_MIN.
3890   __ Fmov(d8, 1.0);
3891   __ Fmov(d9, 1.1);
3892   __ Fmov(d10, 1.5);
3893   __ Fmov(d11, -1.5);
3894   __ Fmov(d12, kFP64PositiveInfinity);
3895   __ Fmov(d13, kFP64NegativeInfinity);
3896   __ Fmov(d14, kWMaxInt - 1);
3897   __ Fmov(d15, kWMinInt + 1);
3898   __ Fmov(s17, 1.1);
3899   __ Fmov(s18, 1.5);
3900   __ Fmov(s19, -1.5);
3901   __ Fmov(s20, kFP32PositiveInfinity);
3902   __ Fmov(s21, kFP32NegativeInfinity);
3903   __ Fmov(s22, 0x7fffff8000000000);  // Largest float < INT64_MAX.
3904   __ Fneg(s23, s22);                 // Smallest float > INT64_MIN.
3905   __ Fmov(d24, 1.1);
3906   __ Fmov(d25, 1.5);
3907   __ Fmov(d26, -1.5);
3908   __ Fmov(d27, kFP64PositiveInfinity);
3909   __ Fmov(d28, kFP64NegativeInfinity);
3910   __ Fmov(d29, 0x7ffffffffffffc00);  // Largest double < INT64_MAX.
3911   __ Fneg(d30, d29);                 // Smallest double > INT64_MIN.
3912 
3913   __ Fcvtms(w0, s0);
3914   __ Fcvtms(w1, s1);
3915   __ Fcvtms(w2, s2);
3916   __ Fcvtms(w3, s3);
3917   __ Fcvtms(w4, s4);
3918   __ Fcvtms(w5, s5);
3919   __ Fcvtms(w6, s6);
3920   __ Fcvtms(w7, s7);
3921   __ Fcvtms(w8, d8);
3922   __ Fcvtms(w9, d9);
3923   __ Fcvtms(w10, d10);
3924   __ Fcvtms(w11, d11);
3925   __ Fcvtms(w12, d12);
3926   __ Fcvtms(w13, d13);
3927   __ Fcvtms(w14, d14);
3928   __ Fcvtms(w15, d15);
3929   __ Fcvtms(x17, s17);
3930   __ Fcvtms(x18, s18);
3931   __ Fcvtms(x19, s19);
3932   __ Fcvtms(x20, s20);
3933   __ Fcvtms(x21, s21);
3934   __ Fcvtms(x22, s22);
3935   __ Fcvtms(x23, s23);
3936   __ Fcvtms(x24, d24);
3937   __ Fcvtms(x25, d25);
3938   __ Fcvtms(x26, d26);
3939   __ Fcvtms(x27, d27);
3940   __ Fcvtms(x28, d28);
3941   __ Fcvtms(x29, d29);
3942   __ Fcvtms(x30, d30);
3943   END();
3944 
3945   if (CAN_RUN()) {
3946     RUN();
3947 
3948     ASSERT_EQUAL_64(1, x0);
3949     ASSERT_EQUAL_64(1, x1);
3950     ASSERT_EQUAL_64(1, x2);
3951     ASSERT_EQUAL_64(0xfffffffe, x3);
3952     ASSERT_EQUAL_64(0x7fffffff, x4);
3953     ASSERT_EQUAL_64(0x80000000, x5);
3954     ASSERT_EQUAL_64(0x7fffff80, x6);
3955     ASSERT_EQUAL_64(0x80000080, x7);
3956     ASSERT_EQUAL_64(1, x8);
3957     ASSERT_EQUAL_64(1, x9);
3958     ASSERT_EQUAL_64(1, x10);
3959     ASSERT_EQUAL_64(0xfffffffe, x11);
3960     ASSERT_EQUAL_64(0x7fffffff, x12);
3961     ASSERT_EQUAL_64(0x80000000, x13);
3962     ASSERT_EQUAL_64(0x7ffffffe, x14);
3963     ASSERT_EQUAL_64(0x80000001, x15);
3964     ASSERT_EQUAL_64(1, x17);
3965     ASSERT_EQUAL_64(1, x18);
3966     ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
3967     ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
3968     ASSERT_EQUAL_64(0x8000000000000000, x21);
3969     ASSERT_EQUAL_64(0x7fffff8000000000, x22);
3970     ASSERT_EQUAL_64(0x8000008000000000, x23);
3971     ASSERT_EQUAL_64(1, x24);
3972     ASSERT_EQUAL_64(1, x25);
3973     ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
3974     ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
3975     ASSERT_EQUAL_64(0x8000000000000000, x28);
3976     ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
3977     ASSERT_EQUAL_64(0x8000000000000400, x30);
3978   }
3979 }
3980 
3981 
TEST(fcvtmu)3982 TEST(fcvtmu) {
3983   SETUP_WITH_FEATURES(CPUFeatures::kFP);
3984 
3985   START();
3986   __ Fmov(s0, 1.0);
3987   __ Fmov(s1, 1.1);
3988   __ Fmov(s2, 1.5);
3989   __ Fmov(s3, -1.5);
3990   __ Fmov(s4, kFP32PositiveInfinity);
3991   __ Fmov(s5, kFP32NegativeInfinity);
3992   __ Fmov(s6, 0x7fffff80);  // Largest float < INT32_MAX.
3993   __ Fneg(s7, s6);          // Smallest float > INT32_MIN.
3994   __ Fmov(d8, 1.0);
3995   __ Fmov(d9, 1.1);
3996   __ Fmov(d10, 1.5);
3997   __ Fmov(d11, -1.5);
3998   __ Fmov(d12, kFP64PositiveInfinity);
3999   __ Fmov(d13, kFP64NegativeInfinity);
4000   __ Fmov(d14, kWMaxInt - 1);
4001   __ Fmov(d15, kWMinInt + 1);
4002   __ Fmov(s17, 1.1);
4003   __ Fmov(s18, 1.5);
4004   __ Fmov(s19, -1.5);
4005   __ Fmov(s20, kFP32PositiveInfinity);
4006   __ Fmov(s21, kFP32NegativeInfinity);
4007   __ Fmov(s22, 0x7fffff8000000000);  // Largest float < INT64_MAX.
4008   __ Fneg(s23, s22);                 // Smallest float > INT64_MIN.
4009   __ Fmov(d24, 1.1);
4010   __ Fmov(d25, 1.5);
4011   __ Fmov(d26, -1.5);
4012   __ Fmov(d27, kFP64PositiveInfinity);
4013   __ Fmov(d28, kFP64NegativeInfinity);
4014   __ Fmov(d29, 0x7ffffffffffffc00);  // Largest double < INT64_MAX.
4015   __ Fneg(d30, d29);                 // Smallest double > INT64_MIN.
4016 
4017   __ Fcvtmu(w0, s0);
4018   __ Fcvtmu(w1, s1);
4019   __ Fcvtmu(w2, s2);
4020   __ Fcvtmu(w3, s3);
4021   __ Fcvtmu(w4, s4);
4022   __ Fcvtmu(w5, s5);
4023   __ Fcvtmu(w6, s6);
4024   __ Fcvtmu(w7, s7);
4025   __ Fcvtmu(w8, d8);
4026   __ Fcvtmu(w9, d9);
4027   __ Fcvtmu(w10, d10);
4028   __ Fcvtmu(w11, d11);
4029   __ Fcvtmu(w12, d12);
4030   __ Fcvtmu(w13, d13);
4031   __ Fcvtmu(w14, d14);
4032   __ Fcvtmu(x17, s17);
4033   __ Fcvtmu(x18, s18);
4034   __ Fcvtmu(x19, s19);
4035   __ Fcvtmu(x20, s20);
4036   __ Fcvtmu(x21, s21);
4037   __ Fcvtmu(x22, s22);
4038   __ Fcvtmu(x23, s23);
4039   __ Fcvtmu(x24, d24);
4040   __ Fcvtmu(x25, d25);
4041   __ Fcvtmu(x26, d26);
4042   __ Fcvtmu(x27, d27);
4043   __ Fcvtmu(x28, d28);
4044   __ Fcvtmu(x29, d29);
4045   __ Fcvtmu(x30, d30);
4046   END();
4047 
4048   if (CAN_RUN()) {
4049     RUN();
4050 
4051     ASSERT_EQUAL_64(1, x0);
4052     ASSERT_EQUAL_64(1, x1);
4053     ASSERT_EQUAL_64(1, x2);
4054     ASSERT_EQUAL_64(0, x3);
4055     ASSERT_EQUAL_64(0xffffffff, x4);
4056     ASSERT_EQUAL_64(0, x5);
4057     ASSERT_EQUAL_64(0x7fffff80, x6);
4058     ASSERT_EQUAL_64(0, x7);
4059     ASSERT_EQUAL_64(1, x8);
4060     ASSERT_EQUAL_64(1, x9);
4061     ASSERT_EQUAL_64(1, x10);
4062     ASSERT_EQUAL_64(0, x11);
4063     ASSERT_EQUAL_64(0xffffffff, x12);
4064     ASSERT_EQUAL_64(0, x13);
4065     ASSERT_EQUAL_64(0x7ffffffe, x14);
4066     ASSERT_EQUAL_64(1, x17);
4067     ASSERT_EQUAL_64(1, x18);
4068     ASSERT_EQUAL_64(0, x19);
4069     ASSERT_EQUAL_64(0xffffffffffffffff, x20);
4070     ASSERT_EQUAL_64(0, x21);
4071     ASSERT_EQUAL_64(0x7fffff8000000000, x22);
4072     ASSERT_EQUAL_64(0, x23);
4073     ASSERT_EQUAL_64(1, x24);
4074     ASSERT_EQUAL_64(1, x25);
4075     ASSERT_EQUAL_64(0, x26);
4076     ASSERT_EQUAL_64(0xffffffffffffffff, x27);
4077     ASSERT_EQUAL_64(0, x28);
4078     ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
4079     ASSERT_EQUAL_64(0, x30);
4080   }
4081 }
4082 
4083 
TEST(fcvtns)4084 TEST(fcvtns) {
4085   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4086 
4087   START();
4088   __ Fmov(s0, 1.0);
4089   __ Fmov(s1, 1.1);
4090   __ Fmov(s2, 1.5);
4091   __ Fmov(s3, -1.5);
4092   __ Fmov(s4, kFP32PositiveInfinity);
4093   __ Fmov(s5, kFP32NegativeInfinity);
4094   __ Fmov(s6, 0x7fffff80);  // Largest float < INT32_MAX.
4095   __ Fneg(s7, s6);          // Smallest float > INT32_MIN.
4096   __ Fmov(d8, 1.0);
4097   __ Fmov(d9, 1.1);
4098   __ Fmov(d10, 1.5);
4099   __ Fmov(d11, -1.5);
4100   __ Fmov(d12, kFP64PositiveInfinity);
4101   __ Fmov(d13, kFP64NegativeInfinity);
4102   __ Fmov(d14, kWMaxInt - 1);
4103   __ Fmov(d15, kWMinInt + 1);
4104   __ Fmov(s17, 1.1);
4105   __ Fmov(s18, 1.5);
4106   __ Fmov(s19, -1.5);
4107   __ Fmov(s20, kFP32PositiveInfinity);
4108   __ Fmov(s21, kFP32NegativeInfinity);
4109   __ Fmov(s22, 0x7fffff8000000000);  // Largest float < INT64_MAX.
4110   __ Fneg(s23, s22);                 // Smallest float > INT64_MIN.
4111   __ Fmov(d24, 1.1);
4112   __ Fmov(d25, 1.5);
4113   __ Fmov(d26, -1.5);
4114   __ Fmov(d27, kFP64PositiveInfinity);
4115   __ Fmov(d28, kFP64NegativeInfinity);
4116   __ Fmov(d29, 0x7ffffffffffffc00);  // Largest double < INT64_MAX.
4117   __ Fneg(d30, d29);                 // Smallest double > INT64_MIN.
4118 
4119   __ Fcvtns(w0, s0);
4120   __ Fcvtns(w1, s1);
4121   __ Fcvtns(w2, s2);
4122   __ Fcvtns(w3, s3);
4123   __ Fcvtns(w4, s4);
4124   __ Fcvtns(w5, s5);
4125   __ Fcvtns(w6, s6);
4126   __ Fcvtns(w7, s7);
4127   __ Fcvtns(w8, d8);
4128   __ Fcvtns(w9, d9);
4129   __ Fcvtns(w10, d10);
4130   __ Fcvtns(w11, d11);
4131   __ Fcvtns(w12, d12);
4132   __ Fcvtns(w13, d13);
4133   __ Fcvtns(w14, d14);
4134   __ Fcvtns(w15, d15);
4135   __ Fcvtns(x17, s17);
4136   __ Fcvtns(x18, s18);
4137   __ Fcvtns(x19, s19);
4138   __ Fcvtns(x20, s20);
4139   __ Fcvtns(x21, s21);
4140   __ Fcvtns(x22, s22);
4141   __ Fcvtns(x23, s23);
4142   __ Fcvtns(x24, d24);
4143   __ Fcvtns(x25, d25);
4144   __ Fcvtns(x26, d26);
4145   __ Fcvtns(x27, d27);
4146   __ Fcvtns(x28, d28);
4147   __ Fcvtns(x29, d29);
4148   __ Fcvtns(x30, d30);
4149   END();
4150 
4151   if (CAN_RUN()) {
4152     RUN();
4153 
4154     ASSERT_EQUAL_64(1, x0);
4155     ASSERT_EQUAL_64(1, x1);
4156     ASSERT_EQUAL_64(2, x2);
4157     ASSERT_EQUAL_64(0xfffffffe, x3);
4158     ASSERT_EQUAL_64(0x7fffffff, x4);
4159     ASSERT_EQUAL_64(0x80000000, x5);
4160     ASSERT_EQUAL_64(0x7fffff80, x6);
4161     ASSERT_EQUAL_64(0x80000080, x7);
4162     ASSERT_EQUAL_64(1, x8);
4163     ASSERT_EQUAL_64(1, x9);
4164     ASSERT_EQUAL_64(2, x10);
4165     ASSERT_EQUAL_64(0xfffffffe, x11);
4166     ASSERT_EQUAL_64(0x7fffffff, x12);
4167     ASSERT_EQUAL_64(0x80000000, x13);
4168     ASSERT_EQUAL_64(0x7ffffffe, x14);
4169     ASSERT_EQUAL_64(0x80000001, x15);
4170     ASSERT_EQUAL_64(1, x17);
4171     ASSERT_EQUAL_64(2, x18);
4172     ASSERT_EQUAL_64(0xfffffffffffffffe, x19);
4173     ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
4174     ASSERT_EQUAL_64(0x8000000000000000, x21);
4175     ASSERT_EQUAL_64(0x7fffff8000000000, x22);
4176     ASSERT_EQUAL_64(0x8000008000000000, x23);
4177     ASSERT_EQUAL_64(1, x24);
4178     ASSERT_EQUAL_64(2, x25);
4179     ASSERT_EQUAL_64(0xfffffffffffffffe, x26);
4180     ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
4181     ASSERT_EQUAL_64(0x8000000000000000, x28);
4182     ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
4183     ASSERT_EQUAL_64(0x8000000000000400, x30);
4184   }
4185 }
4186 
4187 
TEST(fcvtnu)4188 TEST(fcvtnu) {
4189   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4190 
4191   START();
4192   __ Fmov(s0, 1.0);
4193   __ Fmov(s1, 1.1);
4194   __ Fmov(s2, 1.5);
4195   __ Fmov(s3, -1.5);
4196   __ Fmov(s4, kFP32PositiveInfinity);
4197   __ Fmov(s5, kFP32NegativeInfinity);
4198   __ Fmov(s6, 0xffffff00);  // Largest float < UINT32_MAX.
4199   __ Fmov(d8, 1.0);
4200   __ Fmov(d9, 1.1);
4201   __ Fmov(d10, 1.5);
4202   __ Fmov(d11, -1.5);
4203   __ Fmov(d12, kFP64PositiveInfinity);
4204   __ Fmov(d13, kFP64NegativeInfinity);
4205   __ Fmov(d14, 0xfffffffe);
4206   __ Fmov(s16, 1.0);
4207   __ Fmov(s17, 1.1);
4208   __ Fmov(s18, 1.5);
4209   __ Fmov(s19, -1.5);
4210   __ Fmov(s20, kFP32PositiveInfinity);
4211   __ Fmov(s21, kFP32NegativeInfinity);
4212   __ Fmov(s22, 0xffffff0000000000);  // Largest float < UINT64_MAX.
4213   __ Fmov(d24, 1.1);
4214   __ Fmov(d25, 1.5);
4215   __ Fmov(d26, -1.5);
4216   __ Fmov(d27, kFP64PositiveInfinity);
4217   __ Fmov(d28, kFP64NegativeInfinity);
4218   __ Fmov(d29, 0xfffffffffffff800);  // Largest double < UINT64_MAX.
4219   __ Fmov(s30, 0x100000000);
4220 
4221   __ Fcvtnu(w0, s0);
4222   __ Fcvtnu(w1, s1);
4223   __ Fcvtnu(w2, s2);
4224   __ Fcvtnu(w3, s3);
4225   __ Fcvtnu(w4, s4);
4226   __ Fcvtnu(w5, s5);
4227   __ Fcvtnu(w6, s6);
4228   __ Fcvtnu(w8, d8);
4229   __ Fcvtnu(w9, d9);
4230   __ Fcvtnu(w10, d10);
4231   __ Fcvtnu(w11, d11);
4232   __ Fcvtnu(w12, d12);
4233   __ Fcvtnu(w13, d13);
4234   __ Fcvtnu(w14, d14);
4235   __ Fcvtnu(w15, d15);
4236   __ Fcvtnu(x16, s16);
4237   __ Fcvtnu(x17, s17);
4238   __ Fcvtnu(x18, s18);
4239   __ Fcvtnu(x19, s19);
4240   __ Fcvtnu(x20, s20);
4241   __ Fcvtnu(x21, s21);
4242   __ Fcvtnu(x22, s22);
4243   __ Fcvtnu(x24, d24);
4244   __ Fcvtnu(x25, d25);
4245   __ Fcvtnu(x26, d26);
4246   __ Fcvtnu(x27, d27);
4247   __ Fcvtnu(x28, d28);
4248   __ Fcvtnu(x29, d29);
4249   __ Fcvtnu(w30, s30);
4250   END();
4251 
4252   if (CAN_RUN()) {
4253     RUN();
4254 
4255     ASSERT_EQUAL_64(1, x0);
4256     ASSERT_EQUAL_64(1, x1);
4257     ASSERT_EQUAL_64(2, x2);
4258     ASSERT_EQUAL_64(0, x3);
4259     ASSERT_EQUAL_64(0xffffffff, x4);
4260     ASSERT_EQUAL_64(0, x5);
4261     ASSERT_EQUAL_64(0xffffff00, x6);
4262     ASSERT_EQUAL_64(1, x8);
4263     ASSERT_EQUAL_64(1, x9);
4264     ASSERT_EQUAL_64(2, x10);
4265     ASSERT_EQUAL_64(0, x11);
4266     ASSERT_EQUAL_64(0xffffffff, x12);
4267     ASSERT_EQUAL_64(0, x13);
4268     ASSERT_EQUAL_64(0xfffffffe, x14);
4269     ASSERT_EQUAL_64(1, x16);
4270     ASSERT_EQUAL_64(1, x17);
4271     ASSERT_EQUAL_64(2, x18);
4272     ASSERT_EQUAL_64(0, x19);
4273     ASSERT_EQUAL_64(0xffffffffffffffff, x20);
4274     ASSERT_EQUAL_64(0, x21);
4275     ASSERT_EQUAL_64(0xffffff0000000000, x22);
4276     ASSERT_EQUAL_64(1, x24);
4277     ASSERT_EQUAL_64(2, x25);
4278     ASSERT_EQUAL_64(0, x26);
4279     ASSERT_EQUAL_64(0xffffffffffffffff, x27);
4280     ASSERT_EQUAL_64(0, x28);
4281     ASSERT_EQUAL_64(0xfffffffffffff800, x29);
4282     ASSERT_EQUAL_64(0xffffffff, x30);
4283   }
4284 }
4285 
4286 
TEST(fcvtzs)4287 TEST(fcvtzs) {
4288   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4289 
4290   START();
4291   __ Fmov(s0, 1.0);
4292   __ Fmov(s1, 1.1);
4293   __ Fmov(s2, 1.5);
4294   __ Fmov(s3, -1.5);
4295   __ Fmov(s4, kFP32PositiveInfinity);
4296   __ Fmov(s5, kFP32NegativeInfinity);
4297   __ Fmov(s6, 0x7fffff80);  // Largest float < INT32_MAX.
4298   __ Fneg(s7, s6);          // Smallest float > INT32_MIN.
4299   __ Fmov(d8, 1.0);
4300   __ Fmov(d9, 1.1);
4301   __ Fmov(d10, 1.5);
4302   __ Fmov(d11, -1.5);
4303   __ Fmov(d12, kFP64PositiveInfinity);
4304   __ Fmov(d13, kFP64NegativeInfinity);
4305   __ Fmov(d14, kWMaxInt - 1);
4306   __ Fmov(d15, kWMinInt + 1);
4307   __ Fmov(s17, 1.1);
4308   __ Fmov(s18, 1.5);
4309   __ Fmov(s19, -1.5);
4310   __ Fmov(s20, kFP32PositiveInfinity);
4311   __ Fmov(s21, kFP32NegativeInfinity);
4312   __ Fmov(s22, 0x7fffff8000000000);  // Largest float < INT64_MAX.
4313   __ Fneg(s23, s22);                 // Smallest float > INT64_MIN.
4314   __ Fmov(d24, 1.1);
4315   __ Fmov(d25, 1.5);
4316   __ Fmov(d26, -1.5);
4317   __ Fmov(d27, kFP64PositiveInfinity);
4318   __ Fmov(d28, kFP64NegativeInfinity);
4319   __ Fmov(d29, 0x7ffffffffffffc00);  // Largest double < INT64_MAX.
4320   __ Fneg(d30, d29);                 // Smallest double > INT64_MIN.
4321 
4322   __ Fcvtzs(w0, s0);
4323   __ Fcvtzs(w1, s1);
4324   __ Fcvtzs(w2, s2);
4325   __ Fcvtzs(w3, s3);
4326   __ Fcvtzs(w4, s4);
4327   __ Fcvtzs(w5, s5);
4328   __ Fcvtzs(w6, s6);
4329   __ Fcvtzs(w7, s7);
4330   __ Fcvtzs(w8, d8);
4331   __ Fcvtzs(w9, d9);
4332   __ Fcvtzs(w10, d10);
4333   __ Fcvtzs(w11, d11);
4334   __ Fcvtzs(w12, d12);
4335   __ Fcvtzs(w13, d13);
4336   __ Fcvtzs(w14, d14);
4337   __ Fcvtzs(w15, d15);
4338   __ Fcvtzs(x17, s17);
4339   __ Fcvtzs(x18, s18);
4340   __ Fcvtzs(x19, s19);
4341   __ Fcvtzs(x20, s20);
4342   __ Fcvtzs(x21, s21);
4343   __ Fcvtzs(x22, s22);
4344   __ Fcvtzs(x23, s23);
4345   __ Fcvtzs(x24, d24);
4346   __ Fcvtzs(x25, d25);
4347   __ Fcvtzs(x26, d26);
4348   __ Fcvtzs(x27, d27);
4349   __ Fcvtzs(x28, d28);
4350   __ Fcvtzs(x29, d29);
4351   __ Fcvtzs(x30, d30);
4352   END();
4353 
4354   if (CAN_RUN()) {
4355     RUN();
4356 
4357     ASSERT_EQUAL_64(1, x0);
4358     ASSERT_EQUAL_64(1, x1);
4359     ASSERT_EQUAL_64(1, x2);
4360     ASSERT_EQUAL_64(0xffffffff, x3);
4361     ASSERT_EQUAL_64(0x7fffffff, x4);
4362     ASSERT_EQUAL_64(0x80000000, x5);
4363     ASSERT_EQUAL_64(0x7fffff80, x6);
4364     ASSERT_EQUAL_64(0x80000080, x7);
4365     ASSERT_EQUAL_64(1, x8);
4366     ASSERT_EQUAL_64(1, x9);
4367     ASSERT_EQUAL_64(1, x10);
4368     ASSERT_EQUAL_64(0xffffffff, x11);
4369     ASSERT_EQUAL_64(0x7fffffff, x12);
4370     ASSERT_EQUAL_64(0x80000000, x13);
4371     ASSERT_EQUAL_64(0x7ffffffe, x14);
4372     ASSERT_EQUAL_64(0x80000001, x15);
4373     ASSERT_EQUAL_64(1, x17);
4374     ASSERT_EQUAL_64(1, x18);
4375     ASSERT_EQUAL_64(0xffffffffffffffff, x19);
4376     ASSERT_EQUAL_64(0x7fffffffffffffff, x20);
4377     ASSERT_EQUAL_64(0x8000000000000000, x21);
4378     ASSERT_EQUAL_64(0x7fffff8000000000, x22);
4379     ASSERT_EQUAL_64(0x8000008000000000, x23);
4380     ASSERT_EQUAL_64(1, x24);
4381     ASSERT_EQUAL_64(1, x25);
4382     ASSERT_EQUAL_64(0xffffffffffffffff, x26);
4383     ASSERT_EQUAL_64(0x7fffffffffffffff, x27);
4384     ASSERT_EQUAL_64(0x8000000000000000, x28);
4385     ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
4386     ASSERT_EQUAL_64(0x8000000000000400, x30);
4387   }
4388 }
4389 
FjcvtzsHelper(uint64_t value,uint64_t expected,uint32_t expected_z)4390 void FjcvtzsHelper(uint64_t value, uint64_t expected, uint32_t expected_z) {
4391   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kJSCVT);
4392   START();
4393   __ Fmov(d0, RawbitsToDouble(value));
4394   __ Fjcvtzs(w0, d0);
4395   __ Mrs(x1, NZCV);
4396   END();
4397 
4398   if (CAN_RUN()) {
4399     RUN();
4400     ASSERT_EQUAL_64(expected, x0);
4401     ASSERT_EQUAL_32(expected_z, w1);
4402   }
4403 }
4404 
TEST(fjcvtzs)4405 TEST(fjcvtzs) {
4406   /* Simple values. */
4407   FjcvtzsHelper(0x0000000000000000, 0, ZFlag);   // 0.0
4408   FjcvtzsHelper(0x0010000000000000, 0, NoFlag);  // The smallest normal value.
4409   FjcvtzsHelper(0x3fdfffffffffffff, 0, NoFlag);  // The value just below 0.5.
4410   FjcvtzsHelper(0x3fe0000000000000, 0, NoFlag);  // 0.5
4411   FjcvtzsHelper(0x3fe0000000000001, 0, NoFlag);  // The value just above 0.5.
4412   FjcvtzsHelper(0x3fefffffffffffff, 0, NoFlag);  // The value just below 1.0.
4413   FjcvtzsHelper(0x3ff0000000000000, 1, ZFlag);   // 1.0
4414   FjcvtzsHelper(0x3ff0000000000001, 1, NoFlag);  // The value just above 1.0.
4415   FjcvtzsHelper(0x3ff8000000000000, 1, NoFlag);  // 1.5
4416   FjcvtzsHelper(0x4024000000000000, 10, ZFlag);  // 10
4417   FjcvtzsHelper(0x7fefffffffffffff, 0, NoFlag);  // The largest finite value.
4418 
4419   /* Infinity. */
4420   FjcvtzsHelper(0x7ff0000000000000, 0, NoFlag);
4421 
4422   /* NaNs. */
4423   /*  - Quiet NaNs */
4424   FjcvtzsHelper(0x7ff923456789abcd, 0, NoFlag);
4425   FjcvtzsHelper(0x7ff8000000000000, 0, NoFlag);
4426   /*  - Signalling NaNs */
4427   FjcvtzsHelper(0x7ff123456789abcd, 0, NoFlag);
4428   FjcvtzsHelper(0x7ff0000000000001, 0, NoFlag);
4429 
4430   /* Subnormals. */
4431   /*  - A recognisable bit pattern. */
4432   FjcvtzsHelper(0x000123456789abcd, 0, NoFlag);
4433   /*  - The largest subnormal value. */
4434   FjcvtzsHelper(0x000fffffffffffff, 0, NoFlag);
4435   /*  - The smallest subnormal value. */
4436   FjcvtzsHelper(0x0000000000000001, 0, NoFlag);
4437 
4438   /* The same values again, but negated. */
4439   FjcvtzsHelper(0x8000000000000000, 0, NoFlag);
4440   FjcvtzsHelper(0x8010000000000000, 0, NoFlag);
4441   FjcvtzsHelper(0xbfdfffffffffffff, 0, NoFlag);
4442   FjcvtzsHelper(0xbfe0000000000000, 0, NoFlag);
4443   FjcvtzsHelper(0xbfe0000000000001, 0, NoFlag);
4444   FjcvtzsHelper(0xbfefffffffffffff, 0, NoFlag);
4445   FjcvtzsHelper(0xbff0000000000000, 0xffffffff, ZFlag);
4446   FjcvtzsHelper(0xbff0000000000001, 0xffffffff, NoFlag);
4447   FjcvtzsHelper(0xbff8000000000000, 0xffffffff, NoFlag);
4448   FjcvtzsHelper(0xc024000000000000, 0xfffffff6, ZFlag);
4449   FjcvtzsHelper(0xffefffffffffffff, 0, NoFlag);
4450   FjcvtzsHelper(0xfff0000000000000, 0, NoFlag);
4451   FjcvtzsHelper(0xfff923456789abcd, 0, NoFlag);
4452   FjcvtzsHelper(0xfff8000000000000, 0, NoFlag);
4453   FjcvtzsHelper(0xfff123456789abcd, 0, NoFlag);
4454   FjcvtzsHelper(0xfff0000000000001, 0, NoFlag);
4455   FjcvtzsHelper(0x800123456789abcd, 0, NoFlag);
4456   FjcvtzsHelper(0x800fffffffffffff, 0, NoFlag);
4457   FjcvtzsHelper(0x8000000000000001, 0, NoFlag);
4458 
4459   // Test floating-point numbers of every possible exponent, most of the
4460   // expected values are zero but there is a range of exponents where the
4461   // results are shifted parts of this mantissa.
4462   uint64_t mantissa = 0x0001234567890abc;
4463 
4464   // Between an exponent of 0 and 52, only some of the top bits of the
4465   // mantissa are above the decimal position of doubles so the mantissa is
4466   // shifted to the right down to just those top bits. Above 52, all bits
4467   // of the mantissa are shifted left above the decimal position until it
4468   // reaches 52 + 64 where all the bits are shifted out of the range of 64-bit
4469   // integers.
4470   int first_exp_boundary = 52;
4471   int second_exp_boundary = first_exp_boundary + 64;
4472   for (int exponent = 0; exponent < 2048; exponent += 8) {
4473     int e = exponent - 1023;
4474 
4475     uint64_t expected = 0;
4476     if (e < 0) {
4477       expected = 0;
4478     } else if (e <= first_exp_boundary) {
4479       expected = (UINT64_C(1) << e) | (mantissa >> (52 - e));
4480       expected &= 0xffffffff;
4481     } else if (e < second_exp_boundary) {
4482       expected = (mantissa << (e - 52)) & 0xffffffff;
4483     } else {
4484       expected = 0;
4485     }
4486 
4487     uint64_t value = (static_cast<uint64_t>(exponent) << 52) | mantissa;
4488     FjcvtzsHelper(value, expected, NoFlag);
4489     FjcvtzsHelper(value | kDSignMask, (-expected) & 0xffffffff, NoFlag);
4490   }
4491 }
4492 
TEST(fcvtzu)4493 TEST(fcvtzu) {
4494   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4495 
4496   START();
4497   __ Fmov(s0, 1.0);
4498   __ Fmov(s1, 1.1);
4499   __ Fmov(s2, 1.5);
4500   __ Fmov(s3, -1.5);
4501   __ Fmov(s4, kFP32PositiveInfinity);
4502   __ Fmov(s5, kFP32NegativeInfinity);
4503   __ Fmov(s6, 0x7fffff80);  // Largest float < INT32_MAX.
4504   __ Fneg(s7, s6);          // Smallest float > INT32_MIN.
4505   __ Fmov(d8, 1.0);
4506   __ Fmov(d9, 1.1);
4507   __ Fmov(d10, 1.5);
4508   __ Fmov(d11, -1.5);
4509   __ Fmov(d12, kFP64PositiveInfinity);
4510   __ Fmov(d13, kFP64NegativeInfinity);
4511   __ Fmov(d14, kWMaxInt - 1);
4512   __ Fmov(d15, kWMinInt + 1);
4513   __ Fmov(s17, 1.1);
4514   __ Fmov(s18, 1.5);
4515   __ Fmov(s19, -1.5);
4516   __ Fmov(s20, kFP32PositiveInfinity);
4517   __ Fmov(s21, kFP32NegativeInfinity);
4518   __ Fmov(s22, 0x7fffff8000000000);  // Largest float < INT64_MAX.
4519   __ Fneg(s23, s22);                 // Smallest float > INT64_MIN.
4520   __ Fmov(d24, 1.1);
4521   __ Fmov(d25, 1.5);
4522   __ Fmov(d26, -1.5);
4523   __ Fmov(d27, kFP64PositiveInfinity);
4524   __ Fmov(d28, kFP64NegativeInfinity);
4525   __ Fmov(d29, 0x7ffffffffffffc00);  // Largest double < INT64_MAX.
4526   __ Fneg(d30, d29);                 // Smallest double > INT64_MIN.
4527 
4528   __ Fcvtzu(w0, s0);
4529   __ Fcvtzu(w1, s1);
4530   __ Fcvtzu(w2, s2);
4531   __ Fcvtzu(w3, s3);
4532   __ Fcvtzu(w4, s4);
4533   __ Fcvtzu(w5, s5);
4534   __ Fcvtzu(w6, s6);
4535   __ Fcvtzu(w7, s7);
4536   __ Fcvtzu(w8, d8);
4537   __ Fcvtzu(w9, d9);
4538   __ Fcvtzu(w10, d10);
4539   __ Fcvtzu(w11, d11);
4540   __ Fcvtzu(w12, d12);
4541   __ Fcvtzu(w13, d13);
4542   __ Fcvtzu(w14, d14);
4543   __ Fcvtzu(x17, s17);
4544   __ Fcvtzu(x18, s18);
4545   __ Fcvtzu(x19, s19);
4546   __ Fcvtzu(x20, s20);
4547   __ Fcvtzu(x21, s21);
4548   __ Fcvtzu(x22, s22);
4549   __ Fcvtzu(x23, s23);
4550   __ Fcvtzu(x24, d24);
4551   __ Fcvtzu(x25, d25);
4552   __ Fcvtzu(x26, d26);
4553   __ Fcvtzu(x27, d27);
4554   __ Fcvtzu(x28, d28);
4555   __ Fcvtzu(x29, d29);
4556   __ Fcvtzu(x30, d30);
4557   END();
4558 
4559   if (CAN_RUN()) {
4560     RUN();
4561 
4562     ASSERT_EQUAL_64(1, x0);
4563     ASSERT_EQUAL_64(1, x1);
4564     ASSERT_EQUAL_64(1, x2);
4565     ASSERT_EQUAL_64(0, x3);
4566     ASSERT_EQUAL_64(0xffffffff, x4);
4567     ASSERT_EQUAL_64(0, x5);
4568     ASSERT_EQUAL_64(0x7fffff80, x6);
4569     ASSERT_EQUAL_64(0, x7);
4570     ASSERT_EQUAL_64(1, x8);
4571     ASSERT_EQUAL_64(1, x9);
4572     ASSERT_EQUAL_64(1, x10);
4573     ASSERT_EQUAL_64(0, x11);
4574     ASSERT_EQUAL_64(0xffffffff, x12);
4575     ASSERT_EQUAL_64(0, x13);
4576     ASSERT_EQUAL_64(0x7ffffffe, x14);
4577     ASSERT_EQUAL_64(1, x17);
4578     ASSERT_EQUAL_64(1, x18);
4579     ASSERT_EQUAL_64(0, x19);
4580     ASSERT_EQUAL_64(0xffffffffffffffff, x20);
4581     ASSERT_EQUAL_64(0, x21);
4582     ASSERT_EQUAL_64(0x7fffff8000000000, x22);
4583     ASSERT_EQUAL_64(0, x23);
4584     ASSERT_EQUAL_64(1, x24);
4585     ASSERT_EQUAL_64(1, x25);
4586     ASSERT_EQUAL_64(0, x26);
4587     ASSERT_EQUAL_64(0xffffffffffffffff, x27);
4588     ASSERT_EQUAL_64(0, x28);
4589     ASSERT_EQUAL_64(0x7ffffffffffffc00, x29);
4590     ASSERT_EQUAL_64(0, x30);
4591   }
4592 }
4593 
4594 // Test that scvtf and ucvtf can convert the 64-bit input into the expected
4595 // value. All possible values of 'fbits' are tested. The expected value is
4596 // modified accordingly in each case.
4597 //
4598 // The expected value is specified as the bit encoding of the expected double
4599 // produced by scvtf (expected_scvtf_bits) as well as ucvtf
4600 // (expected_ucvtf_bits).
4601 //
4602 // Where the input value is representable by int32_t or uint32_t, conversions
4603 // from W registers will also be tested.
TestUScvtfHelper(uint64_t in,uint64_t expected_scvtf_bits,uint64_t expected_ucvtf_bits)4604 static void TestUScvtfHelper(uint64_t in,
4605                              uint64_t expected_scvtf_bits,
4606                              uint64_t expected_ucvtf_bits) {
4607   uint64_t u64 = in;
4608   uint32_t u32 = u64 & 0xffffffff;
4609   int64_t s64 = static_cast<int64_t>(in);
4610   int32_t s32 = s64 & 0x7fffffff;
4611 
4612   bool cvtf_s32 = (s64 == s32);
4613   bool cvtf_u32 = (u64 == u32);
4614 
4615   double results_scvtf_x[65];
4616   double results_ucvtf_x[65];
4617   double results_scvtf_w[33];
4618   double results_ucvtf_w[33];
4619 
4620   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4621 
4622   START();
4623 
4624   __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
4625   __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
4626   __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
4627   __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
4628 
4629   __ Mov(x10, s64);
4630 
4631   // Corrupt the top word, in case it is accidentally used during W-register
4632   // conversions.
4633   __ Mov(x11, 0x5555555555555555);
4634   __ Bfi(x11, x10, 0, kWRegSize);
4635 
4636   // Test integer conversions.
4637   __ Scvtf(d0, x10);
4638   __ Ucvtf(d1, x10);
4639   __ Scvtf(d2, w11);
4640   __ Ucvtf(d3, w11);
4641   __ Str(d0, MemOperand(x0));
4642   __ Str(d1, MemOperand(x1));
4643   __ Str(d2, MemOperand(x2));
4644   __ Str(d3, MemOperand(x3));
4645 
4646   // Test all possible values of fbits.
4647   for (int fbits = 1; fbits <= 32; fbits++) {
4648     __ Scvtf(d0, x10, fbits);
4649     __ Ucvtf(d1, x10, fbits);
4650     __ Scvtf(d2, w11, fbits);
4651     __ Ucvtf(d3, w11, fbits);
4652     __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
4653     __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
4654     __ Str(d2, MemOperand(x2, fbits * kDRegSizeInBytes));
4655     __ Str(d3, MemOperand(x3, fbits * kDRegSizeInBytes));
4656   }
4657 
4658   // Conversions from W registers can only handle fbits values <= 32, so just
4659   // test conversions from X registers for 32 < fbits <= 64.
4660   for (int fbits = 33; fbits <= 64; fbits++) {
4661     __ Scvtf(d0, x10, fbits);
4662     __ Ucvtf(d1, x10, fbits);
4663     __ Str(d0, MemOperand(x0, fbits * kDRegSizeInBytes));
4664     __ Str(d1, MemOperand(x1, fbits * kDRegSizeInBytes));
4665   }
4666 
4667   END();
4668   if (CAN_RUN()) {
4669     RUN();
4670 
4671     // Check the results.
4672     double expected_scvtf_base = RawbitsToDouble(expected_scvtf_bits);
4673     double expected_ucvtf_base = RawbitsToDouble(expected_ucvtf_bits);
4674 
4675     for (int fbits = 0; fbits <= 32; fbits++) {
4676       double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
4677       double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
4678       ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
4679       ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
4680       if (cvtf_s32) ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_w[fbits]);
4681       if (cvtf_u32) ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_w[fbits]);
4682     }
4683     for (int fbits = 33; fbits <= 64; fbits++) {
4684       double expected_scvtf = expected_scvtf_base / std::pow(2, fbits);
4685       double expected_ucvtf = expected_ucvtf_base / std::pow(2, fbits);
4686       ASSERT_EQUAL_FP64(expected_scvtf, results_scvtf_x[fbits]);
4687       ASSERT_EQUAL_FP64(expected_ucvtf, results_ucvtf_x[fbits]);
4688     }
4689   }
4690 }
4691 
4692 
TEST(scvtf_ucvtf_double)4693 TEST(scvtf_ucvtf_double) {
4694   // Simple conversions of positive numbers which require no rounding; the
4695   // results should not depened on the rounding mode, and ucvtf and scvtf should
4696   // produce the same result.
4697   TestUScvtfHelper(0x0000000000000000, 0x0000000000000000, 0x0000000000000000);
4698   TestUScvtfHelper(0x0000000000000001, 0x3ff0000000000000, 0x3ff0000000000000);
4699   TestUScvtfHelper(0x0000000040000000, 0x41d0000000000000, 0x41d0000000000000);
4700   TestUScvtfHelper(0x0000000100000000, 0x41f0000000000000, 0x41f0000000000000);
4701   TestUScvtfHelper(0x4000000000000000, 0x43d0000000000000, 0x43d0000000000000);
4702   // Test mantissa extremities.
4703   TestUScvtfHelper(0x4000000000000400, 0x43d0000000000001, 0x43d0000000000001);
4704   // The largest int32_t that fits in a double.
4705   TestUScvtfHelper(0x000000007fffffff, 0x41dfffffffc00000, 0x41dfffffffc00000);
4706   // Values that would be negative if treated as an int32_t.
4707   TestUScvtfHelper(0x00000000ffffffff, 0x41efffffffe00000, 0x41efffffffe00000);
4708   TestUScvtfHelper(0x0000000080000000, 0x41e0000000000000, 0x41e0000000000000);
4709   TestUScvtfHelper(0x0000000080000001, 0x41e0000000200000, 0x41e0000000200000);
4710   // The largest int64_t that fits in a double.
4711   TestUScvtfHelper(0x7ffffffffffffc00, 0x43dfffffffffffff, 0x43dfffffffffffff);
4712   // Check for bit pattern reproduction.
4713   TestUScvtfHelper(0x0123456789abcde0, 0x43723456789abcde, 0x43723456789abcde);
4714   TestUScvtfHelper(0x0000000012345678, 0x41b2345678000000, 0x41b2345678000000);
4715 
4716   // Simple conversions of negative int64_t values. These require no rounding,
4717   // and the results should not depend on the rounding mode.
4718   TestUScvtfHelper(0xffffffffc0000000, 0xc1d0000000000000, 0x43effffffff80000);
4719   TestUScvtfHelper(0xffffffff00000000, 0xc1f0000000000000, 0x43efffffffe00000);
4720   TestUScvtfHelper(0xc000000000000000, 0xc3d0000000000000, 0x43e8000000000000);
4721 
4722   // Conversions which require rounding.
4723   TestUScvtfHelper(0x1000000000000000, 0x43b0000000000000, 0x43b0000000000000);
4724   TestUScvtfHelper(0x1000000000000001, 0x43b0000000000000, 0x43b0000000000000);
4725   TestUScvtfHelper(0x1000000000000080, 0x43b0000000000000, 0x43b0000000000000);
4726   TestUScvtfHelper(0x1000000000000081, 0x43b0000000000001, 0x43b0000000000001);
4727   TestUScvtfHelper(0x1000000000000100, 0x43b0000000000001, 0x43b0000000000001);
4728   TestUScvtfHelper(0x1000000000000101, 0x43b0000000000001, 0x43b0000000000001);
4729   TestUScvtfHelper(0x1000000000000180, 0x43b0000000000002, 0x43b0000000000002);
4730   TestUScvtfHelper(0x1000000000000181, 0x43b0000000000002, 0x43b0000000000002);
4731   TestUScvtfHelper(0x1000000000000200, 0x43b0000000000002, 0x43b0000000000002);
4732   TestUScvtfHelper(0x1000000000000201, 0x43b0000000000002, 0x43b0000000000002);
4733   TestUScvtfHelper(0x1000000000000280, 0x43b0000000000002, 0x43b0000000000002);
4734   TestUScvtfHelper(0x1000000000000281, 0x43b0000000000003, 0x43b0000000000003);
4735   TestUScvtfHelper(0x1000000000000300, 0x43b0000000000003, 0x43b0000000000003);
4736   // Check rounding of negative int64_t values (and large uint64_t values).
4737   TestUScvtfHelper(0x8000000000000000, 0xc3e0000000000000, 0x43e0000000000000);
4738   TestUScvtfHelper(0x8000000000000001, 0xc3e0000000000000, 0x43e0000000000000);
4739   TestUScvtfHelper(0x8000000000000200, 0xc3e0000000000000, 0x43e0000000000000);
4740   TestUScvtfHelper(0x8000000000000201, 0xc3dfffffffffffff, 0x43e0000000000000);
4741   TestUScvtfHelper(0x8000000000000400, 0xc3dfffffffffffff, 0x43e0000000000000);
4742   TestUScvtfHelper(0x8000000000000401, 0xc3dfffffffffffff, 0x43e0000000000001);
4743   TestUScvtfHelper(0x8000000000000600, 0xc3dffffffffffffe, 0x43e0000000000001);
4744   TestUScvtfHelper(0x8000000000000601, 0xc3dffffffffffffe, 0x43e0000000000001);
4745   TestUScvtfHelper(0x8000000000000800, 0xc3dffffffffffffe, 0x43e0000000000001);
4746   TestUScvtfHelper(0x8000000000000801, 0xc3dffffffffffffe, 0x43e0000000000001);
4747   TestUScvtfHelper(0x8000000000000a00, 0xc3dffffffffffffe, 0x43e0000000000001);
4748   TestUScvtfHelper(0x8000000000000a01, 0xc3dffffffffffffd, 0x43e0000000000001);
4749   TestUScvtfHelper(0x8000000000000c00, 0xc3dffffffffffffd, 0x43e0000000000002);
4750   // Round up to produce a result that's too big for the input to represent.
4751   TestUScvtfHelper(0x7ffffffffffffe00, 0x43e0000000000000, 0x43e0000000000000);
4752   TestUScvtfHelper(0x7fffffffffffffff, 0x43e0000000000000, 0x43e0000000000000);
4753   TestUScvtfHelper(0xfffffffffffffc00, 0xc090000000000000, 0x43f0000000000000);
4754   TestUScvtfHelper(0xffffffffffffffff, 0xbff0000000000000, 0x43f0000000000000);
4755 }
4756 
4757 
4758 // The same as TestUScvtfHelper, but convert to floats.
TestUScvtf32Helper(uint64_t in,uint32_t expected_scvtf_bits,uint32_t expected_ucvtf_bits)4759 static void TestUScvtf32Helper(uint64_t in,
4760                                uint32_t expected_scvtf_bits,
4761                                uint32_t expected_ucvtf_bits) {
4762   uint64_t u64 = in;
4763   uint32_t u32 = u64 & 0xffffffff;
4764   int64_t s64 = static_cast<int64_t>(in);
4765   int32_t s32 = s64 & 0x7fffffff;
4766 
4767   bool cvtf_s32 = (s64 == s32);
4768   bool cvtf_u32 = (u64 == u32);
4769 
4770   float results_scvtf_x[65];
4771   float results_ucvtf_x[65];
4772   float results_scvtf_w[33];
4773   float results_ucvtf_w[33];
4774 
4775   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4776 
4777   START();
4778 
4779   __ Mov(x0, reinterpret_cast<uintptr_t>(results_scvtf_x));
4780   __ Mov(x1, reinterpret_cast<uintptr_t>(results_ucvtf_x));
4781   __ Mov(x2, reinterpret_cast<uintptr_t>(results_scvtf_w));
4782   __ Mov(x3, reinterpret_cast<uintptr_t>(results_ucvtf_w));
4783 
4784   __ Mov(x10, s64);
4785 
4786   // Corrupt the top word, in case it is accidentally used during W-register
4787   // conversions.
4788   __ Mov(x11, 0x5555555555555555);
4789   __ Bfi(x11, x10, 0, kWRegSize);
4790 
4791   // Test integer conversions.
4792   __ Scvtf(s0, x10);
4793   __ Ucvtf(s1, x10);
4794   __ Scvtf(s2, w11);
4795   __ Ucvtf(s3, w11);
4796   __ Str(s0, MemOperand(x0));
4797   __ Str(s1, MemOperand(x1));
4798   __ Str(s2, MemOperand(x2));
4799   __ Str(s3, MemOperand(x3));
4800 
4801   // Test all possible values of fbits.
4802   for (int fbits = 1; fbits <= 32; fbits++) {
4803     __ Scvtf(s0, x10, fbits);
4804     __ Ucvtf(s1, x10, fbits);
4805     __ Scvtf(s2, w11, fbits);
4806     __ Ucvtf(s3, w11, fbits);
4807     __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
4808     __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
4809     __ Str(s2, MemOperand(x2, fbits * kSRegSizeInBytes));
4810     __ Str(s3, MemOperand(x3, fbits * kSRegSizeInBytes));
4811   }
4812 
4813   // Conversions from W registers can only handle fbits values <= 32, so just
4814   // test conversions from X registers for 32 < fbits <= 64.
4815   for (int fbits = 33; fbits <= 64; fbits++) {
4816     __ Scvtf(s0, x10, fbits);
4817     __ Ucvtf(s1, x10, fbits);
4818     __ Str(s0, MemOperand(x0, fbits * kSRegSizeInBytes));
4819     __ Str(s1, MemOperand(x1, fbits * kSRegSizeInBytes));
4820   }
4821 
4822   END();
4823   if (CAN_RUN()) {
4824     RUN();
4825 
4826     // Check the results.
4827     float expected_scvtf_base = RawbitsToFloat(expected_scvtf_bits);
4828     float expected_ucvtf_base = RawbitsToFloat(expected_ucvtf_bits);
4829 
4830     for (int fbits = 0; fbits <= 32; fbits++) {
4831       float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
4832       float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
4833       ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
4834       ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
4835       if (cvtf_s32) ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_w[fbits]);
4836       if (cvtf_u32) ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_w[fbits]);
4837     }
4838     for (int fbits = 33; fbits <= 64; fbits++) {
4839       float expected_scvtf = expected_scvtf_base / std::pow(2.0f, fbits);
4840       float expected_ucvtf = expected_ucvtf_base / std::pow(2.0f, fbits);
4841       ASSERT_EQUAL_FP32(expected_scvtf, results_scvtf_x[fbits]);
4842       ASSERT_EQUAL_FP32(expected_ucvtf, results_ucvtf_x[fbits]);
4843     }
4844   }
4845 }
4846 
4847 
TEST(scvtf_ucvtf_float)4848 TEST(scvtf_ucvtf_float) {
4849   // Simple conversions of positive numbers which require no rounding; the
4850   // results should not depened on the rounding mode, and ucvtf and scvtf should
4851   // produce the same result.
4852   TestUScvtf32Helper(0x0000000000000000, 0x00000000, 0x00000000);
4853   TestUScvtf32Helper(0x0000000000000001, 0x3f800000, 0x3f800000);
4854   TestUScvtf32Helper(0x0000000040000000, 0x4e800000, 0x4e800000);
4855   TestUScvtf32Helper(0x0000000100000000, 0x4f800000, 0x4f800000);
4856   TestUScvtf32Helper(0x4000000000000000, 0x5e800000, 0x5e800000);
4857   // Test mantissa extremities.
4858   TestUScvtf32Helper(0x0000000000800001, 0x4b000001, 0x4b000001);
4859   TestUScvtf32Helper(0x4000008000000000, 0x5e800001, 0x5e800001);
4860   // The largest int32_t that fits in a float.
4861   TestUScvtf32Helper(0x000000007fffff80, 0x4effffff, 0x4effffff);
4862   // Values that would be negative if treated as an int32_t.
4863   TestUScvtf32Helper(0x00000000ffffff00, 0x4f7fffff, 0x4f7fffff);
4864   TestUScvtf32Helper(0x0000000080000000, 0x4f000000, 0x4f000000);
4865   TestUScvtf32Helper(0x0000000080000100, 0x4f000001, 0x4f000001);
4866   // The largest int64_t that fits in a float.
4867   TestUScvtf32Helper(0x7fffff8000000000, 0x5effffff, 0x5effffff);
4868   // Check for bit pattern reproduction.
4869   TestUScvtf32Helper(0x0000000000876543, 0x4b076543, 0x4b076543);
4870 
4871   // Simple conversions of negative int64_t values. These require no rounding,
4872   // and the results should not depend on the rounding mode.
4873   TestUScvtf32Helper(0xfffffc0000000000, 0xd4800000, 0x5f7ffffc);
4874   TestUScvtf32Helper(0xc000000000000000, 0xde800000, 0x5f400000);
4875 
4876   // Conversions which require rounding.
4877   TestUScvtf32Helper(0x0000800000000000, 0x57000000, 0x57000000);
4878   TestUScvtf32Helper(0x0000800000000001, 0x57000000, 0x57000000);
4879   TestUScvtf32Helper(0x0000800000800000, 0x57000000, 0x57000000);
4880   TestUScvtf32Helper(0x0000800000800001, 0x57000001, 0x57000001);
4881   TestUScvtf32Helper(0x0000800001000000, 0x57000001, 0x57000001);
4882   TestUScvtf32Helper(0x0000800001000001, 0x57000001, 0x57000001);
4883   TestUScvtf32Helper(0x0000800001800000, 0x57000002, 0x57000002);
4884   TestUScvtf32Helper(0x0000800001800001, 0x57000002, 0x57000002);
4885   TestUScvtf32Helper(0x0000800002000000, 0x57000002, 0x57000002);
4886   TestUScvtf32Helper(0x0000800002000001, 0x57000002, 0x57000002);
4887   TestUScvtf32Helper(0x0000800002800000, 0x57000002, 0x57000002);
4888   TestUScvtf32Helper(0x0000800002800001, 0x57000003, 0x57000003);
4889   TestUScvtf32Helper(0x0000800003000000, 0x57000003, 0x57000003);
4890   // Check rounding of negative int64_t values (and large uint64_t values).
4891   TestUScvtf32Helper(0x8000000000000000, 0xdf000000, 0x5f000000);
4892   TestUScvtf32Helper(0x8000000000000001, 0xdf000000, 0x5f000000);
4893   TestUScvtf32Helper(0x8000004000000000, 0xdf000000, 0x5f000000);
4894   TestUScvtf32Helper(0x8000004000000001, 0xdeffffff, 0x5f000000);
4895   TestUScvtf32Helper(0x8000008000000000, 0xdeffffff, 0x5f000000);
4896   TestUScvtf32Helper(0x8000008000000001, 0xdeffffff, 0x5f000001);
4897   TestUScvtf32Helper(0x800000c000000000, 0xdefffffe, 0x5f000001);
4898   TestUScvtf32Helper(0x800000c000000001, 0xdefffffe, 0x5f000001);
4899   TestUScvtf32Helper(0x8000010000000000, 0xdefffffe, 0x5f000001);
4900   TestUScvtf32Helper(0x8000010000000001, 0xdefffffe, 0x5f000001);
4901   TestUScvtf32Helper(0x8000014000000000, 0xdefffffe, 0x5f000001);
4902   TestUScvtf32Helper(0x8000014000000001, 0xdefffffd, 0x5f000001);
4903   TestUScvtf32Helper(0x8000018000000000, 0xdefffffd, 0x5f000002);
4904   // Round up to produce a result that's too big for the input to represent.
4905   TestUScvtf32Helper(0x000000007fffffc0, 0x4f000000, 0x4f000000);
4906   TestUScvtf32Helper(0x000000007fffffff, 0x4f000000, 0x4f000000);
4907   TestUScvtf32Helper(0x00000000ffffff80, 0x4f800000, 0x4f800000);
4908   TestUScvtf32Helper(0x00000000ffffffff, 0x4f800000, 0x4f800000);
4909   TestUScvtf32Helper(0x7fffffc000000000, 0x5f000000, 0x5f000000);
4910   TestUScvtf32Helper(0x7fffffffffffffff, 0x5f000000, 0x5f000000);
4911   TestUScvtf32Helper(0xffffff8000000000, 0xd3000000, 0x5f800000);
4912   TestUScvtf32Helper(0xffffffffffffffff, 0xbf800000, 0x5f800000);
4913 }
4914 
TEST(process_nan_double)4915 TEST(process_nan_double) {
4916   // Make sure that NaN propagation works correctly.
4917   double sn = RawbitsToDouble(0x7ff5555511111111);
4918   double qn = RawbitsToDouble(0x7ffaaaaa11111111);
4919   VIXL_ASSERT(IsSignallingNaN(sn));
4920   VIXL_ASSERT(IsQuietNaN(qn));
4921 
4922   // The input NaNs after passing through ProcessNaN.
4923   double sn_proc = RawbitsToDouble(0x7ffd555511111111);
4924   double qn_proc = qn;
4925   VIXL_ASSERT(IsQuietNaN(sn_proc));
4926   VIXL_ASSERT(IsQuietNaN(qn_proc));
4927 
4928   SETUP_WITH_FEATURES(CPUFeatures::kFP);
4929 
4930   START();
4931 
4932   // Execute a number of instructions which all use ProcessNaN, and check that
4933   // they all handle the NaN correctly.
4934   __ Fmov(d0, sn);
4935   __ Fmov(d10, qn);
4936 
4937   // Operations that always propagate NaNs unchanged, even signalling NaNs.
4938   //   - Signalling NaN
4939   __ Fmov(d1, d0);
4940   __ Fabs(d2, d0);
4941   __ Fneg(d3, d0);
4942   //   - Quiet NaN
4943   __ Fmov(d11, d10);
4944   __ Fabs(d12, d10);
4945   __ Fneg(d13, d10);
4946 
4947   // Operations that use ProcessNaN.
4948   //   - Signalling NaN
4949   __ Fsqrt(d4, d0);
4950   __ Frinta(d5, d0);
4951   __ Frintn(d6, d0);
4952   __ Frintz(d7, d0);
4953   //   - Quiet NaN
4954   __ Fsqrt(d14, d10);
4955   __ Frinta(d15, d10);
4956   __ Frintn(d16, d10);
4957   __ Frintz(d17, d10);
4958 
4959   // The behaviour of fcvt is checked in TEST(fcvt_sd).
4960 
4961   END();
4962   if (CAN_RUN()) {
4963     RUN();
4964 
4965     uint64_t qn_raw = DoubleToRawbits(qn);
4966     uint64_t sn_raw = DoubleToRawbits(sn);
4967 
4968     //   - Signalling NaN
4969     ASSERT_EQUAL_FP64(sn, d1);
4970     ASSERT_EQUAL_FP64(RawbitsToDouble(sn_raw & ~kDSignMask), d2);
4971     ASSERT_EQUAL_FP64(RawbitsToDouble(sn_raw ^ kDSignMask), d3);
4972     //   - Quiet NaN
4973     ASSERT_EQUAL_FP64(qn, d11);
4974     ASSERT_EQUAL_FP64(RawbitsToDouble(qn_raw & ~kDSignMask), d12);
4975     ASSERT_EQUAL_FP64(RawbitsToDouble(qn_raw ^ kDSignMask), d13);
4976 
4977     //   - Signalling NaN
4978     ASSERT_EQUAL_FP64(sn_proc, d4);
4979     ASSERT_EQUAL_FP64(sn_proc, d5);
4980     ASSERT_EQUAL_FP64(sn_proc, d6);
4981     ASSERT_EQUAL_FP64(sn_proc, d7);
4982     //   - Quiet NaN
4983     ASSERT_EQUAL_FP64(qn_proc, d14);
4984     ASSERT_EQUAL_FP64(qn_proc, d15);
4985     ASSERT_EQUAL_FP64(qn_proc, d16);
4986     ASSERT_EQUAL_FP64(qn_proc, d17);
4987   }
4988 }
4989 
4990 
TEST(process_nan_float)4991 TEST(process_nan_float) {
4992   // Make sure that NaN propagation works correctly.
4993   float sn = RawbitsToFloat(0x7f951111);
4994   float qn = RawbitsToFloat(0x7fea1111);
4995   VIXL_ASSERT(IsSignallingNaN(sn));
4996   VIXL_ASSERT(IsQuietNaN(qn));
4997 
4998   // The input NaNs after passing through ProcessNaN.
4999   float sn_proc = RawbitsToFloat(0x7fd51111);
5000   float qn_proc = qn;
5001   VIXL_ASSERT(IsQuietNaN(sn_proc));
5002   VIXL_ASSERT(IsQuietNaN(qn_proc));
5003 
5004   SETUP_WITH_FEATURES(CPUFeatures::kFP);
5005 
5006   START();
5007 
5008   // Execute a number of instructions which all use ProcessNaN, and check that
5009   // they all handle the NaN correctly.
5010   __ Fmov(s0, sn);
5011   __ Fmov(s10, qn);
5012 
5013   // Operations that always propagate NaNs unchanged, even signalling NaNs.
5014   //   - Signalling NaN
5015   __ Fmov(s1, s0);
5016   __ Fabs(s2, s0);
5017   __ Fneg(s3, s0);
5018   //   - Quiet NaN
5019   __ Fmov(s11, s10);
5020   __ Fabs(s12, s10);
5021   __ Fneg(s13, s10);
5022 
5023   // Operations that use ProcessNaN.
5024   //   - Signalling NaN
5025   __ Fsqrt(s4, s0);
5026   __ Frinta(s5, s0);
5027   __ Frintn(s6, s0);
5028   __ Frintz(s7, s0);
5029   //   - Quiet NaN
5030   __ Fsqrt(s14, s10);
5031   __ Frinta(s15, s10);
5032   __ Frintn(s16, s10);
5033   __ Frintz(s17, s10);
5034 
5035   // The behaviour of fcvt is checked in TEST(fcvt_sd).
5036 
5037   END();
5038   if (CAN_RUN()) {
5039     RUN();
5040 
5041     uint32_t qn_raw = FloatToRawbits(qn);
5042     uint32_t sn_raw = FloatToRawbits(sn);
5043 
5044     //   - Signalling NaN
5045     ASSERT_EQUAL_FP32(sn, s1);
5046     ASSERT_EQUAL_FP32(RawbitsToFloat(sn_raw & ~kSSignMask), s2);
5047     ASSERT_EQUAL_FP32(RawbitsToFloat(sn_raw ^ kSSignMask), s3);
5048     //   - Quiet NaN
5049     ASSERT_EQUAL_FP32(qn, s11);
5050     ASSERT_EQUAL_FP32(RawbitsToFloat(qn_raw & ~kSSignMask), s12);
5051     ASSERT_EQUAL_FP32(RawbitsToFloat(qn_raw ^ kSSignMask), s13);
5052 
5053     //   - Signalling NaN
5054     ASSERT_EQUAL_FP32(sn_proc, s4);
5055     ASSERT_EQUAL_FP32(sn_proc, s5);
5056     ASSERT_EQUAL_FP32(sn_proc, s6);
5057     ASSERT_EQUAL_FP32(sn_proc, s7);
5058     //   - Quiet NaN
5059     ASSERT_EQUAL_FP32(qn_proc, s14);
5060     ASSERT_EQUAL_FP32(qn_proc, s15);
5061     ASSERT_EQUAL_FP32(qn_proc, s16);
5062     ASSERT_EQUAL_FP32(qn_proc, s17);
5063   }
5064 }
5065 
5066 // TODO: TEST(process_nan_half) {}
5067 
ProcessNaNsHelper(double n,double m,double expected)5068 static void ProcessNaNsHelper(double n, double m, double expected) {
5069   VIXL_ASSERT(IsNaN(n) || IsNaN(m));
5070   VIXL_ASSERT(IsNaN(expected));
5071 
5072   SETUP_WITH_FEATURES(CPUFeatures::kFP);
5073 
5074   START();
5075 
5076   // Execute a number of instructions which all use ProcessNaNs, and check that
5077   // they all propagate NaNs correctly.
5078   __ Fmov(d0, n);
5079   __ Fmov(d1, m);
5080 
5081   __ Fadd(d2, d0, d1);
5082   __ Fsub(d3, d0, d1);
5083   __ Fmul(d4, d0, d1);
5084   __ Fdiv(d5, d0, d1);
5085   __ Fmax(d6, d0, d1);
5086   __ Fmin(d7, d0, d1);
5087 
5088   END();
5089   if (CAN_RUN()) {
5090     RUN();
5091 
5092     ASSERT_EQUAL_FP64(expected, d2);
5093     ASSERT_EQUAL_FP64(expected, d3);
5094     ASSERT_EQUAL_FP64(expected, d4);
5095     ASSERT_EQUAL_FP64(expected, d5);
5096     ASSERT_EQUAL_FP64(expected, d6);
5097     ASSERT_EQUAL_FP64(expected, d7);
5098   }
5099 }
5100 
5101 
TEST(process_nans_double)5102 TEST(process_nans_double) {
5103   // Make sure that NaN propagation works correctly.
5104   double sn = RawbitsToDouble(0x7ff5555511111111);
5105   double sm = RawbitsToDouble(0x7ff5555522222222);
5106   double qn = RawbitsToDouble(0x7ffaaaaa11111111);
5107   double qm = RawbitsToDouble(0x7ffaaaaa22222222);
5108   VIXL_ASSERT(IsSignallingNaN(sn));
5109   VIXL_ASSERT(IsSignallingNaN(sm));
5110   VIXL_ASSERT(IsQuietNaN(qn));
5111   VIXL_ASSERT(IsQuietNaN(qm));
5112 
5113   // The input NaNs after passing through ProcessNaN.
5114   double sn_proc = RawbitsToDouble(0x7ffd555511111111);
5115   double sm_proc = RawbitsToDouble(0x7ffd555522222222);
5116   double qn_proc = qn;
5117   double qm_proc = qm;
5118   VIXL_ASSERT(IsQuietNaN(sn_proc));
5119   VIXL_ASSERT(IsQuietNaN(sm_proc));
5120   VIXL_ASSERT(IsQuietNaN(qn_proc));
5121   VIXL_ASSERT(IsQuietNaN(qm_proc));
5122 
5123   // Quiet NaNs are propagated.
5124   ProcessNaNsHelper(qn, 0, qn_proc);
5125   ProcessNaNsHelper(0, qm, qm_proc);
5126   ProcessNaNsHelper(qn, qm, qn_proc);
5127 
5128   // Signalling NaNs are propagated, and made quiet.
5129   ProcessNaNsHelper(sn, 0, sn_proc);
5130   ProcessNaNsHelper(0, sm, sm_proc);
5131   ProcessNaNsHelper(sn, sm, sn_proc);
5132 
5133   // Signalling NaNs take precedence over quiet NaNs.
5134   ProcessNaNsHelper(sn, qm, sn_proc);
5135   ProcessNaNsHelper(qn, sm, sm_proc);
5136   ProcessNaNsHelper(sn, sm, sn_proc);
5137 }
5138 
5139 
ProcessNaNsHelper(float n,float m,float expected)5140 static void ProcessNaNsHelper(float n, float m, float expected) {
5141   VIXL_ASSERT(IsNaN(n) || IsNaN(m));
5142   VIXL_ASSERT(IsNaN(expected));
5143 
5144   SETUP_WITH_FEATURES(CPUFeatures::kFP);
5145 
5146   START();
5147 
5148   // Execute a number of instructions which all use ProcessNaNs, and check that
5149   // they all propagate NaNs correctly.
5150   __ Fmov(s0, n);
5151   __ Fmov(s1, m);
5152 
5153   __ Fadd(s2, s0, s1);
5154   __ Fsub(s3, s0, s1);
5155   __ Fmul(s4, s0, s1);
5156   __ Fdiv(s5, s0, s1);
5157   __ Fmax(s6, s0, s1);
5158   __ Fmin(s7, s0, s1);
5159 
5160   END();
5161   if (CAN_RUN()) {
5162     RUN();
5163 
5164     ASSERT_EQUAL_FP32(expected, s2);
5165     ASSERT_EQUAL_FP32(expected, s3);
5166     ASSERT_EQUAL_FP32(expected, s4);
5167     ASSERT_EQUAL_FP32(expected, s5);
5168     ASSERT_EQUAL_FP32(expected, s6);
5169     ASSERT_EQUAL_FP32(expected, s7);
5170   }
5171 }
5172 
5173 
TEST(process_nans_float)5174 TEST(process_nans_float) {
5175   // Make sure that NaN propagation works correctly.
5176   float sn = RawbitsToFloat(0x7f951111);
5177   float sm = RawbitsToFloat(0x7f952222);
5178   float qn = RawbitsToFloat(0x7fea1111);
5179   float qm = RawbitsToFloat(0x7fea2222);
5180   VIXL_ASSERT(IsSignallingNaN(sn));
5181   VIXL_ASSERT(IsSignallingNaN(sm));
5182   VIXL_ASSERT(IsQuietNaN(qn));
5183   VIXL_ASSERT(IsQuietNaN(qm));
5184 
5185   // The input NaNs after passing through ProcessNaN.
5186   float sn_proc = RawbitsToFloat(0x7fd51111);
5187   float sm_proc = RawbitsToFloat(0x7fd52222);
5188   float qn_proc = qn;
5189   float qm_proc = qm;
5190   VIXL_ASSERT(IsQuietNaN(sn_proc));
5191   VIXL_ASSERT(IsQuietNaN(sm_proc));
5192   VIXL_ASSERT(IsQuietNaN(qn_proc));
5193   VIXL_ASSERT(IsQuietNaN(qm_proc));
5194 
5195   // Quiet NaNs are propagated.
5196   ProcessNaNsHelper(qn, 0, qn_proc);
5197   ProcessNaNsHelper(0, qm, qm_proc);
5198   ProcessNaNsHelper(qn, qm, qn_proc);
5199 
5200   // Signalling NaNs are propagated, and made quiet.
5201   ProcessNaNsHelper(sn, 0, sn_proc);
5202   ProcessNaNsHelper(0, sm, sm_proc);
5203   ProcessNaNsHelper(sn, sm, sn_proc);
5204 
5205   // Signalling NaNs take precedence over quiet NaNs.
5206   ProcessNaNsHelper(sn, qm, sn_proc);
5207   ProcessNaNsHelper(qn, sm, sm_proc);
5208   ProcessNaNsHelper(sn, sm, sn_proc);
5209 }
5210 
5211 
ProcessNaNsHelper(Float16 n,Float16 m,Float16 expected)5212 static void ProcessNaNsHelper(Float16 n, Float16 m, Float16 expected) {
5213   VIXL_ASSERT(IsNaN(n) || IsNaN(m));
5214   VIXL_ASSERT(IsNaN(expected));
5215 
5216   SETUP_WITH_FEATURES(CPUFeatures::kFP, CPUFeatures::kFPHalf);
5217 
5218   START();
5219 
5220   // Execute a number of instructions which all use ProcessNaNs, and check that
5221   // they all propagate NaNs correctly.
5222   __ Fmov(h0, n);
5223   __ Fmov(h1, m);
5224 
5225   __ Fadd(h2, h0, h1);
5226   __ Fsub(h3, h0, h1);
5227   __ Fmul(h4, h0, h1);
5228   __ Fdiv(h5, h0, h1);
5229   __ Fmax(h6, h0, h1);
5230   __ Fmin(h7, h0, h1);
5231 
5232   END();
5233 
5234   if (CAN_RUN()) {
5235     RUN();
5236     ASSERT_EQUAL_FP16(expected, h2);
5237     ASSERT_EQUAL_FP16(expected, h3);
5238     ASSERT_EQUAL_FP16(expected, h4);
5239     ASSERT_EQUAL_FP16(expected, h5);
5240     ASSERT_EQUAL_FP16(expected, h6);
5241     ASSERT_EQUAL_FP16(expected, h7);
5242   }
5243 }
5244 
5245 
TEST(process_nans_half)5246 TEST(process_nans_half) {
5247   // Make sure that NaN propagation works correctly.
5248   Float16 sn(RawbitsToFloat16(0x7c11));
5249   Float16 sm(RawbitsToFloat16(0xfc22));
5250   Float16 qn(RawbitsToFloat16(0x7e33));
5251   Float16 qm(RawbitsToFloat16(0xfe44));
5252   VIXL_ASSERT(IsSignallingNaN(sn));
5253   VIXL_ASSERT(IsSignallingNaN(sm));
5254   VIXL_ASSERT(IsQuietNaN(qn));
5255   VIXL_ASSERT(IsQuietNaN(qm));
5256 
5257   // The input NaNs after passing through ProcessNaN.
5258   Float16 sn_proc(RawbitsToFloat16(0x7e11));
5259   Float16 sm_proc(RawbitsToFloat16(0xfe22));
5260   Float16 qn_proc = qn;
5261   Float16 qm_proc = qm;
5262   VIXL_ASSERT(IsQuietNaN(sn_proc));
5263   VIXL_ASSERT(IsQuietNaN(sm_proc));
5264   VIXL_ASSERT(IsQuietNaN(qn_proc));
5265   VIXL_ASSERT(IsQuietNaN(qm_proc));
5266 
5267   // Quiet NaNs are propagated.
5268   ProcessNaNsHelper(qn, Float16(), qn_proc);
5269   ProcessNaNsHelper(Float16(), qm, qm_proc);
5270   ProcessNaNsHelper(qn, qm, qn_proc);
5271 
5272   // Signalling NaNs are propagated, and made quiet.
5273   ProcessNaNsHelper(sn, Float16(), sn_proc);
5274   ProcessNaNsHelper(Float16(), sm, sm_proc);
5275   ProcessNaNsHelper(sn, sm, sn_proc);
5276 
5277   // Signalling NaNs take precedence over quiet NaNs.
5278   ProcessNaNsHelper(sn, qm, sn_proc);
5279   ProcessNaNsHelper(qn, sm, sm_proc);
5280   ProcessNaNsHelper(sn, sm, sn_proc);
5281 }
5282 
5283 
DefaultNaNHelper(float n,float m,float a)5284 static void DefaultNaNHelper(float n, float m, float a) {
5285   VIXL_ASSERT(IsNaN(n) || IsNaN(m) || IsNaN(a));
5286 
5287   bool test_1op = IsNaN(n);
5288   bool test_2op = IsNaN(n) || IsNaN(m);
5289 
5290   SETUP_WITH_FEATURES(CPUFeatures::kFP);
5291   START();
5292 
5293   // Enable Default-NaN mode in the FPCR.
5294   __ Mrs(x0, FPCR);
5295   __ Orr(x1, x0, DN_mask);
5296   __ Msr(FPCR, x1);
5297 
5298   // Execute a number of instructions which all use ProcessNaNs, and check that
5299   // they all produce the default NaN.
5300   __ Fmov(s0, n);
5301   __ Fmov(s1, m);
5302   __ Fmov(s2, a);
5303 
5304   if (test_1op) {
5305     // Operations that always propagate NaNs unchanged, even signalling NaNs.
5306     __ Fmov(s10, s0);
5307     __ Fabs(s11, s0);
5308     __ Fneg(s12, s0);
5309 
5310     // Operations that use ProcessNaN.
5311     __ Fsqrt(s13, s0);
5312     __ Frinta(s14, s0);
5313     __ Frintn(s15, s0);
5314     __ Frintz(s16, s0);
5315 
5316     // Fcvt usually has special NaN handling, but it respects default-NaN mode.
5317     __ Fcvt(d17, s0);
5318   }
5319 
5320   if (test_2op) {
5321     __ Fadd(s18, s0, s1);
5322     __ Fsub(s19, s0, s1);
5323     __ Fmul(s20, s0, s1);
5324     __ Fdiv(s21, s0, s1);
5325     __ Fmax(s22, s0, s1);
5326     __ Fmin(s23, s0, s1);
5327   }
5328 
5329   __ Fmadd(s24, s0, s1, s2);
5330   __ Fmsub(s25, s0, s1, s2);
5331   __ Fnmadd(s26, s0, s1, s2);
5332   __ Fnmsub(s27, s0, s1, s2);
5333 
5334   // Restore FPCR.
5335   __ Msr(FPCR, x0);
5336 
5337   END();
5338   if (CAN_RUN()) {
5339     RUN();
5340 
5341     if (test_1op) {
5342       uint32_t n_raw = FloatToRawbits(n);
5343       ASSERT_EQUAL_FP32(n, s10);
5344       ASSERT_EQUAL_FP32(RawbitsToFloat(n_raw & ~kSSignMask), s11);
5345       ASSERT_EQUAL_FP32(RawbitsToFloat(n_raw ^ kSSignMask), s12);
5346       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s13);
5347       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s14);
5348       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s15);
5349       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s16);
5350       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d17);
5351     }
5352 
5353     if (test_2op) {
5354       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s18);
5355       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s19);
5356       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s20);
5357       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s21);
5358       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s22);
5359       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s23);
5360     }
5361 
5362     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s24);
5363     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s25);
5364     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s26);
5365     ASSERT_EQUAL_FP32(kFP32DefaultNaN, s27);
5366   }
5367 }
5368 
5369 
TEST(default_nan_float)5370 TEST(default_nan_float) {
5371   float sn = RawbitsToFloat(0x7f951111);
5372   float sm = RawbitsToFloat(0x7f952222);
5373   float sa = RawbitsToFloat(0x7f95aaaa);
5374   float qn = RawbitsToFloat(0x7fea1111);
5375   float qm = RawbitsToFloat(0x7fea2222);
5376   float qa = RawbitsToFloat(0x7feaaaaa);
5377   VIXL_ASSERT(IsSignallingNaN(sn));
5378   VIXL_ASSERT(IsSignallingNaN(sm));
5379   VIXL_ASSERT(IsSignallingNaN(sa));
5380   VIXL_ASSERT(IsQuietNaN(qn));
5381   VIXL_ASSERT(IsQuietNaN(qm));
5382   VIXL_ASSERT(IsQuietNaN(qa));
5383 
5384   //   - Signalling NaNs
5385   DefaultNaNHelper(sn, 0.0f, 0.0f);
5386   DefaultNaNHelper(0.0f, sm, 0.0f);
5387   DefaultNaNHelper(0.0f, 0.0f, sa);
5388   DefaultNaNHelper(sn, sm, 0.0f);
5389   DefaultNaNHelper(0.0f, sm, sa);
5390   DefaultNaNHelper(sn, 0.0f, sa);
5391   DefaultNaNHelper(sn, sm, sa);
5392   //   - Quiet NaNs
5393   DefaultNaNHelper(qn, 0.0f, 0.0f);
5394   DefaultNaNHelper(0.0f, qm, 0.0f);
5395   DefaultNaNHelper(0.0f, 0.0f, qa);
5396   DefaultNaNHelper(qn, qm, 0.0f);
5397   DefaultNaNHelper(0.0f, qm, qa);
5398   DefaultNaNHelper(qn, 0.0f, qa);
5399   DefaultNaNHelper(qn, qm, qa);
5400   //   - Mixed NaNs
5401   DefaultNaNHelper(qn, sm, sa);
5402   DefaultNaNHelper(sn, qm, sa);
5403   DefaultNaNHelper(sn, sm, qa);
5404   DefaultNaNHelper(qn, qm, sa);
5405   DefaultNaNHelper(sn, qm, qa);
5406   DefaultNaNHelper(qn, sm, qa);
5407   DefaultNaNHelper(qn, qm, qa);
5408 }
5409 
5410 
DefaultNaNHelper(double n,double m,double a)5411 static void DefaultNaNHelper(double n, double m, double a) {
5412   VIXL_ASSERT(IsNaN(n) || IsNaN(m) || IsNaN(a));
5413 
5414   bool test_1op = IsNaN(n);
5415   bool test_2op = IsNaN(n) || IsNaN(m);
5416 
5417   SETUP_WITH_FEATURES(CPUFeatures::kFP);
5418 
5419   START();
5420 
5421   // Enable Default-NaN mode in the FPCR.
5422   __ Mrs(x0, FPCR);
5423   __ Orr(x1, x0, DN_mask);
5424   __ Msr(FPCR, x1);
5425 
5426   // Execute a number of instructions which all use ProcessNaNs, and check that
5427   // they all produce the default NaN.
5428   __ Fmov(d0, n);
5429   __ Fmov(d1, m);
5430   __ Fmov(d2, a);
5431 
5432   if (test_1op) {
5433     // Operations that always propagate NaNs unchanged, even signalling NaNs.
5434     __ Fmov(d10, d0);
5435     __ Fabs(d11, d0);
5436     __ Fneg(d12, d0);
5437 
5438     // Operations that use ProcessNaN.
5439     __ Fsqrt(d13, d0);
5440     __ Frinta(d14, d0);
5441     __ Frintn(d15, d0);
5442     __ Frintz(d16, d0);
5443 
5444     // Fcvt usually has special NaN handling, but it respects default-NaN mode.
5445     __ Fcvt(s17, d0);
5446   }
5447 
5448   if (test_2op) {
5449     __ Fadd(d18, d0, d1);
5450     __ Fsub(d19, d0, d1);
5451     __ Fmul(d20, d0, d1);
5452     __ Fdiv(d21, d0, d1);
5453     __ Fmax(d22, d0, d1);
5454     __ Fmin(d23, d0, d1);
5455   }
5456 
5457   __ Fmadd(d24, d0, d1, d2);
5458   __ Fmsub(d25, d0, d1, d2);
5459   __ Fnmadd(d26, d0, d1, d2);
5460   __ Fnmsub(d27, d0, d1, d2);
5461 
5462   // Restore FPCR.
5463   __ Msr(FPCR, x0);
5464 
5465   END();
5466   if (CAN_RUN()) {
5467     RUN();
5468 
5469     if (test_1op) {
5470       uint64_t n_raw = DoubleToRawbits(n);
5471       ASSERT_EQUAL_FP64(n, d10);
5472       ASSERT_EQUAL_FP64(RawbitsToDouble(n_raw & ~kDSignMask), d11);
5473       ASSERT_EQUAL_FP64(RawbitsToDouble(n_raw ^ kDSignMask), d12);
5474       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d13);
5475       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d14);
5476       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d15);
5477       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d16);
5478       ASSERT_EQUAL_FP32(kFP32DefaultNaN, s17);
5479     }
5480 
5481     if (test_2op) {
5482       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d18);
5483       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d19);
5484       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d20);
5485       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d21);
5486       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d22);
5487       ASSERT_EQUAL_FP64(kFP64DefaultNaN, d23);
5488     }
5489 
5490     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d24);
5491     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d25);
5492     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d26);
5493     ASSERT_EQUAL_FP64(kFP64DefaultNaN, d27);
5494   }
5495 }
5496 
5497 
TEST(default_nan_double)5498 TEST(default_nan_double) {
5499   double sn = RawbitsToDouble(0x7ff5555511111111);
5500   double sm = RawbitsToDouble(0x7ff5555522222222);
5501   double sa = RawbitsToDouble(0x7ff55555aaaaaaaa);
5502   double qn = RawbitsToDouble(0x7ffaaaaa11111111);
5503   double qm = RawbitsToDouble(0x7ffaaaaa22222222);
5504   double qa = RawbitsToDouble(0x7ffaaaaaaaaaaaaa);
5505   VIXL_ASSERT(IsSignallingNaN(sn));
5506   VIXL_ASSERT(IsSignallingNaN(sm));
5507   VIXL_ASSERT(IsSignallingNaN(sa));
5508   VIXL_ASSERT(IsQuietNaN(qn));
5509   VIXL_ASSERT(IsQuietNaN(qm));
5510   VIXL_ASSERT(IsQuietNaN(qa));
5511 
5512   //   - Signalling NaNs
5513   DefaultNaNHelper(sn, 0.0, 0.0);
5514   DefaultNaNHelper(0.0, sm, 0.0);
5515   DefaultNaNHelper(0.0, 0.0, sa);
5516   DefaultNaNHelper(sn, sm, 0.0);
5517   DefaultNaNHelper(0.0, sm, sa);
5518   DefaultNaNHelper(sn, 0.0, sa);
5519   DefaultNaNHelper(sn, sm, sa);
5520   //   - Quiet NaNs
5521   DefaultNaNHelper(qn, 0.0, 0.0);
5522   DefaultNaNHelper(0.0, qm, 0.0);
5523   DefaultNaNHelper(0.0, 0.0, qa);
5524   DefaultNaNHelper(qn, qm, 0.0);
5525   DefaultNaNHelper(0.0, qm, qa);
5526   DefaultNaNHelper(qn, 0.0, qa);
5527   DefaultNaNHelper(qn, qm, qa);
5528   //   - Mixed NaNs
5529   DefaultNaNHelper(qn, sm, sa);
5530   DefaultNaNHelper(sn, qm, sa);
5531   DefaultNaNHelper(sn, sm, qa);
5532   DefaultNaNHelper(qn, qm, sa);
5533   DefaultNaNHelper(sn, qm, qa);
5534   DefaultNaNHelper(qn, sm, qa);
5535   DefaultNaNHelper(qn, qm, qa);
5536 }
5537 
5538 }  // namespace aarch64
5539 }  // namespace vixl
5540