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