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
44namespace vixl {
45namespace aarch64 {
46
47TEST(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
89TEST(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
130TEST(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
159TEST(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
187TEST(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
235TEST(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
282template <typename T>
283void 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
314TEST(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
321TEST(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
327TEST(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
376TEST(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
432TEST(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
488TEST(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
524TEST(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
580TEST(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
614TEST(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
671TEST(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
706TEST(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
741static 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
772TEST(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
823static 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
854TEST(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
905TEST(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
1117TEST(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
1329TEST(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
1386TEST(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
1420static 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
1461static 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
1502static 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
1526TEST(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
1606static 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
1630TEST(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
1709TEST(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
1806TEST(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
1876TEST(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
1975TEST(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
2040TEST(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
2076TEST(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
2105TEST(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
2149TEST(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
2185TEST(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
2240TEST(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
2312TEST(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
2384TEST(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
2456TEST(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
2528TEST(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
2601TEST(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
2674TEST(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
2747TEST(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
2820TEST(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
2908TEST(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
2998TEST(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
3086TEST(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
3174TEST(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
3262TEST(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
3352TEST(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
3434TEST(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
3500TEST(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
3569TEST(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
3674TEST(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
3778TEST(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
3877TEST(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
3981TEST(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
4083TEST(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
4187TEST(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
4286TEST(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
4389void 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
4404TEST(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
4492TEST(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.
4603static 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
4692TEST(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.
4758static 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
4847TEST(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
4914TEST(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
4990TEST(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
5067static 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
5101TEST(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
5139static 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
5173TEST(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
5211static 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
5245TEST(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
5283static 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
5369TEST(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
5410static 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
5497TEST(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