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