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