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