1/* 2 * Copyright (c) 2016 The University of Virginia 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Alec Roelke 29 */ 30 31#include <cstdint> 32#include <limits> 33 34#include "insttest.h" 35#include "rv64d.h" 36#include "rv64f.h" 37 38int main() 39{ 40 using namespace std; 41 using namespace insttest; 42 43 // Memory (FLD, FSD) 44 expect<double>(3.1415926, []{return D::load(3.1415926);}, "fld"); 45 expect<double>(1.61803398875, []{return D::store(1.61803398875);}, "fsd"); 46 47 // FMADD.D 48 expect<double>(D::number(0x4019FD5AED13B1CEULL), 49 []{return D::fmadd_d(3.1415926, 1.61803398875,1.41421356237);}, 50 "fmadd.d"); 51 expect<bool>(true, []{ 52 double fd = D::fmadd_d(numeric_limits<double>::quiet_NaN(), 3.14, 53 1.816); 54 return D::isquietnan(fd); 55 }, "fmadd.d, quiet NaN"); 56 expect<bool>(true, []{ 57 double fd = D::fmadd_d(3.14, 58 numeric_limits<double>::signaling_NaN(), 1.816); 59 return D::isquietnan(fd); 60 }, "fmadd.d, signaling NaN"); 61 expect<double>(numeric_limits<double>::infinity(), 62 []{return D::fmadd_d(3.14, numeric_limits<double>::infinity(),1.414);}, 63 "fmadd.d, infinity"); 64 expect<double>(-numeric_limits<double>::infinity(), 65 []{return D::fmadd_d(3.14,-numeric_limits<double>::infinity(),1.414);}, 66 "fmadd.d, -infinity"); 67 68 // FMSUB.D 69 expect<double>(D::number(0x400d5A1773A85E43ULL), 70 []{return D::fmsub_d(3.1415926, 1.61803398875, 1.41421356237);}, 71 "fmsub.d"); 72 expect<bool>(true, []{ 73 double fd = D::fmsub_d(3.14, numeric_limits<double>::quiet_NaN(), 74 1.414); 75 return D::isquietnan(fd); 76 }, "fmsub.d, quiet NaN"); 77 expect<bool>(true, []{ 78 double fd = D::fmsub_d(3.14, 1.816, 79 numeric_limits<double>::signaling_NaN()); 80 return D::isquietnan(fd); 81 }, "fmsub.d, signaling NaN"); 82 expect<double>(numeric_limits<double>::infinity(), 83 []{return D::fmsub_d(numeric_limits<double>::infinity(), 1.816, 84 1.414);}, 85 "fmsub.d, infinity"); 86 expect<double>(-numeric_limits<double>::infinity(), 87 []{return D::fmsub_d(3.14, -numeric_limits<double>::infinity(), 88 1.414);}, 89 "fmsub.d, -infinity"); 90 expect<double>(-numeric_limits<double>::infinity(), 91 []{return D::fmsub_d(3.14, 1.816, 92 numeric_limits<double>::infinity());}, 93 "fmsub.d, subtract infinity"); 94 95 // FNMSUB.D 96 expect<double>(D::number(0xC00D5A1773A85E43ULL), 97 []{return D::fnmsub_d(3.1415926, 1.61803398875, 1.41421356237);}, 98 "fnmsub.d"); 99 expect<bool>(true, []{ 100 double fd = D::fnmsub_d(3.14, 1.816, 101 numeric_limits<double>::quiet_NaN()); 102 return D::isquietnan(fd); 103 }, "fnmsub.d, quiet NaN"); 104 expect<bool>(true, []{ 105 double fd = D::fnmsub_d(numeric_limits<double>::signaling_NaN(), 106 1.816, 1.414); 107 return D::isquietnan(fd); 108 }, "fnmsub.d, signaling NaN"); 109 expect<double>(-numeric_limits<double>::infinity(), 110 []{return D::fnmsub_d(numeric_limits<double>::infinity(), 1.816, 111 1.414);}, 112 "fnmsub.d, infinity"); 113 expect<double>(numeric_limits<double>::infinity(), 114 []{return D::fnmsub_d(3.14, -numeric_limits<double>::infinity(), 115 1.414);}, 116 "fnmsub.d, -infinity"); 117 expect<double>(numeric_limits<double>::infinity(), 118 []{return D::fnmsub_d(3.14, 1.816, 119 numeric_limits<double>::infinity());}, 120 "fnmsub.d, subtract infinity"); 121 122 // FNMADD.D 123 expect<double>(D::number(0xC019FD5AED13B1CEULL), 124 []{return D::fnmadd_d(3.1415926, 1.61803398875, 1.41421356237);}, 125 "fnmadd.d"); 126 expect<bool>(true, []{ 127 double fd = D::fnmadd_d(numeric_limits<double>::quiet_NaN(), 3.14, 128 1.816); 129 return D::isquietnan(fd); 130 }, "fnmadd.d, quiet NaN"); 131 expect<bool>(true, []{ 132 double fd = D::fnmadd_d(3.14, 133 numeric_limits<double>::signaling_NaN(), 1.816); 134 return D::isquietnan(fd); 135 }, "fnmadd.d, signaling NaN"); 136 expect<double>(-numeric_limits<double>::infinity(), 137 []{return D::fnmadd_d(3.14, numeric_limits<double>::infinity(), 138 1.414);}, 139 "fnmadd.d, infinity"); 140 expect<double>(numeric_limits<double>::infinity(), 141 []{return D::fnmadd_d(3.14, -numeric_limits<double>::infinity(), 142 1.414);}, 143 "fnmadd.d, -infinity"); 144 145 // FADD.D 146 expect<double>(D::number(0x4012392540292D7CULL), 147 []{return D::fadd_d(3.1415926, 1.41421356237);}, "fadd.d"); 148 expect<bool>(true, []{ 149 double fd = D::fadd_d(numeric_limits<double>::quiet_NaN(), 1.414); 150 return D::isquietnan(fd); 151 }, "fadd.d, quiet NaN"); 152 expect<bool>(true, []{ 153 double fd = D::fadd_d(3.14, 154 numeric_limits<double>::signaling_NaN()); 155 return D::isquietnan(fd); 156 }, "fadd.d, signaling NaN"); 157 expect<double>(numeric_limits<double>::infinity(), 158 []{return D::fadd_d(3.14, numeric_limits<double>::infinity());}, 159 "fadd.d, infinity"); 160 expect<double>(-numeric_limits<double>::infinity(), 161 []{return D::fadd_d(-numeric_limits<double>::infinity(), 1.816);}, 162 "fadd.d, -infinity"); 163 164 // FSUB.D 165 expect<double>(D::number(0xBFFBA35833AB7AAEULL), 166 []{return D::fsub_d(1.4142135623, 3.1415926);}, "fsub.d"); 167 expect<bool>(true, []{ 168 double fd = D::fsub_d(numeric_limits<double>::quiet_NaN(), 1.414); 169 return D::isquietnan(fd); 170 }, "fsub.d, quiet NaN"); 171 expect<bool>(true, []{ 172 double fd = D::fsub_d(3.14, 173 numeric_limits<double>::signaling_NaN()); 174 return D::isquietnan(fd); 175 }, "fsub.d, signaling NaN"); 176 expect<double>(numeric_limits<double>::infinity(), 177 []{return D::fsub_d(numeric_limits<double>::infinity(), 3.14);}, 178 "fsub.d, infinity"); 179 expect<double>(-numeric_limits<double>::infinity(), 180 []{return D::fsub_d(-numeric_limits<double>::infinity(), 3.14);}, 181 "fsub.d, -infinity"); 182 expect<double>(-numeric_limits<double>::infinity(), 183 []{return D::fsub_d(1.414, numeric_limits<double>::infinity());}, 184 "fsub.d, subtract infinity"); 185 186 // FMUL.D 187 expect<double>(D::number(0x40024E53B708ED9AULL), 188 []{return D::fmul_d(1.61803398875, 1.4142135623);}, "fmul.d"); 189 expect<bool>(true, []{ 190 double fd = D::fmul_d(numeric_limits<double>::quiet_NaN(), 1.414); 191 return D::isquietnan(fd); 192 }, "fmul.d, quiet NaN"); 193 expect<bool>(true, []{ 194 double fd = D::fmul_d(1.816, 195 numeric_limits<double>::signaling_NaN()); 196 return D::isquietnan(fd); 197 }, "fmul.d, signaling NaN"); 198 expect<double>(numeric_limits<double>::infinity(), 199 []{return D::fmul_d(numeric_limits<double>::infinity(), 2.718);}, 200 "fmul.d, infinity"); 201 expect<double>(-numeric_limits<double>::infinity(), 202 []{return D::fmul_d(2.5966, -numeric_limits<double>::infinity());}, 203 "fmul.d, -infinity"); 204 expect<bool>(true, []{ 205 double fd = D::fmul_d(0.0, numeric_limits<double>::infinity()); 206 return D::isquietnan(fd); 207 }, "fmul.d, 0*infinity"); 208 expect<double>(numeric_limits<double>::infinity(), 209 []{return D::fmul_d(numeric_limits<double>::max(), 2.0);}, 210 "fmul.d, overflow"); 211 expect<double>(0.0, 212 []{return D::fmul_d(numeric_limits<double>::min(), 213 numeric_limits<double>::min());}, 214 "fmul.d, underflow"); 215 216 // FDIV.D 217 expect<double>(2.5, []{return D::fdiv_d(10.0, 4.0);}, "fdiv.d"); 218 expect<bool>(true, []{ 219 double fd = D::fdiv_d(numeric_limits<double>::quiet_NaN(), 4.0); 220 return D::isquietnan(fd); 221 }, "fdiv.d, quiet NaN"); 222 expect<bool>(true, []{ 223 double fd = D::fdiv_d(10.0, 224 numeric_limits<double>::signaling_NaN()); 225 return D::isquietnan(fd); 226 }, "fdiv.d, signaling NaN"); 227 expect<double>(numeric_limits<double>::infinity(), 228 []{return D::fdiv_d(10.0, 0.0);}, "fdiv.d/0"); 229 expect<double>(0.0, 230 []{return D::fdiv_d(10.0, numeric_limits<double>::infinity());}, 231 "fdiv.d/infinity"); 232 expect<bool>(true, []{ 233 double fd = D::fdiv_d(numeric_limits<double>::infinity(), 234 numeric_limits<double>::infinity()); 235 return D::isquietnan(fd); 236 }, "fdiv.d, infinity/infinity"); 237 expect<bool>(true, []{ 238 double fd = D::fdiv_d(0.0, 0.0); 239 return D::isquietnan(fd); 240 }, "fdiv.d, 0/0"); 241 expect<double>(numeric_limits<double>::infinity(), 242 []{return D::fdiv_d(numeric_limits<double>::infinity(), 0.0);}, 243 "fdiv.d, infinity/0"); 244 expect<double>(0.0, 245 []{return D::fdiv_d(0.0, numeric_limits<double>::infinity());}, 246 "fdiv.d, 0/infinity"); 247 expect<double>(0.0, 248 []{return D::fdiv_d(numeric_limits<double>::min(), 249 numeric_limits<double>::max());}, 250 "fdiv.d, underflow"); 251 expect<double>(numeric_limits<double>::infinity(), 252 []{return D::fdiv_d(numeric_limits<double>::max(), 253 numeric_limits<double>::min());}, 254 "fdiv.d, overflow"); 255 256 // FSQRT.D 257 expect<double>(1e154, []{return D::fsqrt_d(1e308);}, "fsqrt.d"); 258 expect<bool>(true, []{ 259 double fd = D::fsqrt_d(-1.0); 260 return D::isquietnan(fd); 261 }, "fsqrt.d, NaN"); 262 expect<bool>(true, []{ 263 double fd = D::fsqrt_d(numeric_limits<double>::quiet_NaN()); 264 return D::isquietnan(fd); 265 }, "fsqrt.d, quiet NaN"); 266 expect<bool>(true, []{ 267 double fd = D::fsqrt_d(numeric_limits<double>::signaling_NaN()); 268 return D::isquietnan(fd); 269 }, "fsqrt.d, signaling NaN"); 270 expect<double>(numeric_limits<double>::infinity(), 271 []{return D::fsqrt_d(numeric_limits<double>::infinity());}, 272 "fsqrt.d, infinity"); 273 274 // FSGNJ.D 275 expect<double>(1.0, []{return D::fsgnj_d(1.0, 25.0);}, "fsgnj.d, ++"); 276 expect<double>(-1.0, []{return D::fsgnj_d(1.0, -25.0);}, "fsgnj.d, +-"); 277 expect<double>(1.0, []{return D::fsgnj_d(-1.0, 25.0);}, "fsgnj.d, -+"); 278 expect<double>(-1.0, []{return D::fsgnj_d(-1.0, -25.0);}, "fsgnj.d, --"); 279 expect<bool>(true, []{ 280 double fd = D::fsgnj_d(numeric_limits<double>::quiet_NaN(), -4.0); 281 return D::isquietnan(fd); 282 }, "fsgnj.d, quiet NaN"); 283 expect<bool>(true, []{ 284 double fd = D::fsgnj_d(numeric_limits<double>::signaling_NaN(), 285 -4.0); 286 return D::issignalingnan(fd); 287 }, "fsgnj.d, signaling NaN"); 288 expect<double>(4.0, 289 []{return D::fsgnj_d(4.0, numeric_limits<double>::quiet_NaN());}, 290 "fsgnj.d, inject NaN"); 291 expect<double>(-4.0, 292 []{return D::fsgnj_d(4.0, -numeric_limits<double>::quiet_NaN());}, 293 "fsgnj.d, inject -NaN"); 294 295 // FSGNJN.D 296 expect<double>(-1.0, []{return D::fsgnjn_d(1.0, 25.0);}, "fsgnjn.d, ++"); 297 expect<double>(1.0, []{return D::fsgnjn_d(1.0, -25.0);}, "fsgnjn.d, +-"); 298 expect<double>(-1.0, []{return D::fsgnjn_d(-1.0, 25.0);}, "fsgnjn.d, -+"); 299 expect<double>(1.0, []{return D::fsgnjn_d(-1.0, -25.0);}, "fsgnjn.d, --"); 300 expect<bool>(true, []{ 301 double fd = D::fsgnjn_d(numeric_limits<double>::quiet_NaN(), -4.0); 302 return D::isquietnan(fd); 303 }, "fsgnjn.d, quiet NaN"); 304 expect<bool>(true, []{ 305 double fd = D::fsgnjn_d(numeric_limits<double>::signaling_NaN(), 306 -4.0); 307 return D::issignalingnan(fd); 308 }, "fsgnjn.d, signaling NaN"); 309 expect<double>(-4.0, 310 []{return D::fsgnjn_d(4.0, numeric_limits<double>::quiet_NaN());}, 311 "fsgnjn.d, inject NaN"); 312 expect<double>(4.0, 313 []{return D::fsgnjn_d(4.0, -numeric_limits<double>::quiet_NaN());}, 314 "fsgnjn.d, inject NaN"); 315 316 // FSGNJX.D 317 expect<double>(1.0, []{return D::fsgnjx_d(1.0, 25.0);}, "fsgnjx.d, ++"); 318 expect<double>(-1.0, []{return D::fsgnjx_d(1.0, -25.0);}, "fsgnjx.d, +-"); 319 expect<double>(-1.0, []{return D::fsgnjx_d(-1.0, 25.0);}, "fsgnjx.d, -+"); 320 expect<double>(1.0, []{return D::fsgnjx_d(-1.0, -25.0);}, "fsgnjx.d, --"); 321 expect<bool>(true, []{ 322 double fd = D::fsgnjx_d(numeric_limits<double>::quiet_NaN(), -4.0); 323 return D::isquietnan(fd); 324 }, "fsgnjx.d, quiet NaN"); 325 expect<bool>(true, []{ 326 double fd = D::fsgnjx_d(numeric_limits<double>::signaling_NaN(), 327 -4.0); 328 return D::issignalingnan(fd); 329 }, "fsgnjx.d, signaling NaN"); 330 expect<double>(4.0, 331 []{return D::fsgnjx_d(4.0, numeric_limits<double>::quiet_NaN());}, 332 "fsgnjx.d, inject NaN"); 333 expect<double>(-4.0, 334 []{return D::fsgnjx_d(4.0, -numeric_limits<double>::quiet_NaN());}, 335 "fsgnjx.d, inject NaN"); 336 337 // FMIN.D 338 expect<double>(2.718, []{return D::fmin_d(3.14, 2.718);}, "fmin.d"); 339 expect<double>(-numeric_limits<double>::infinity(), 340 []{return D::fmin_d(-numeric_limits<double>::infinity(), 341 numeric_limits<double>::min());}, 342 "fmin.d, -infinity"); 343 expect<double>(numeric_limits<double>::max(), 344 []{return D::fmin_d(numeric_limits<double>::infinity(), 345 numeric_limits<double>::max());}, 346 "fmin.d, infinity"); 347 expect<double>(-1.414, 348 []{return D::fmin_d(numeric_limits<double>::quiet_NaN(), -1.414);}, 349 "fmin.d, quiet NaN first"); 350 expect<double>(2.718, 351 []{return D::fmin_d(2.718, numeric_limits<double>::quiet_NaN());}, 352 "fmin.d, quiet NaN second"); 353 expect<bool>(true, []{ 354 double fd = D::fmin_d(numeric_limits<double>::quiet_NaN(), 355 numeric_limits<double>::quiet_NaN()); 356 return D::isquietnan(fd); 357 }, "fmin.d, quiet NaN both"); 358 expect<double>(3.14, 359 []{return D::fmin_d(numeric_limits<double>::signaling_NaN(), 360 3.14);}, 361 "fmin.d, signaling NaN first"); 362 expect<double>(1.816, 363 []{return D::fmin_d(1.816, 364 numeric_limits<double>::signaling_NaN());}, 365 "fmin.d, signaling NaN second"); 366 expect<bool>(true, []{ 367 double fd = D::fmin_d(numeric_limits<double>::signaling_NaN(), 368 numeric_limits<double>::signaling_NaN()); 369 return D::issignalingnan(fd); 370 }, "fmin.d, signaling NaN both"); 371 372 // FMAX.D 373 expect<double>(3.14, []{return D::fmax_d(3.14, 2.718);}, "fmax.d"); 374 expect<double>(numeric_limits<double>::min(), 375 []{return D::fmax_d(-numeric_limits<double>::infinity(), 376 numeric_limits<double>::min());}, 377 "fmax.d, -infinity"); 378 expect<double>(numeric_limits<double>::infinity(), 379 []{return D::fmax_d(numeric_limits<double>::infinity(), 380 numeric_limits<double>::max());}, 381 "fmax.d, infinity"); 382 expect<double>(-1.414, 383 []{return D::fmax_d(numeric_limits<double>::quiet_NaN(), -1.414);}, 384 "fmax.d, quiet NaN first"); 385 expect<double>(2.718, 386 []{return D::fmax_d(2.718, numeric_limits<double>::quiet_NaN());}, 387 "fmax.d, quiet NaN second"); 388 expect<bool>(true, []{ 389 double fd = D::fmax_d(numeric_limits<double>::quiet_NaN(), 390 numeric_limits<double>::quiet_NaN()); 391 return D::isquietnan(fd); 392 }, "fmax.d, quiet NaN both"); 393 expect<double>(3.14, 394 []{return D::fmax_d(numeric_limits<double>::signaling_NaN(), 395 3.14);}, 396 "fmax.d, signaling NaN first"); 397 expect<double>(1.816, 398 []{return D::fmax_d(1.816, 399 numeric_limits<double>::signaling_NaN());}, 400 "fmax.d, signaling NaN second"); 401 expect<bool>(true, []{ 402 double fd = D::fmax_d(numeric_limits<double>::signaling_NaN(), 403 numeric_limits<double>::signaling_NaN()); 404 return D::issignalingnan(fd); 405 }, "fmax.d, signaling NaN both"); 406 407 // FCVT.S.D 408 expect<float>(4.0, []{return D::fcvt_s_d(4.0);}, "fcvt.s.d"); 409 expect<bool>(true, []{ 410 float fd = D::fcvt_s_d(numeric_limits<double>::quiet_NaN()); 411 return F::isquietnan(fd); 412 }, "fcvt.s.d, quiet NaN"); 413 expect<bool>(true, []{ 414 float fd = D::fcvt_s_d(numeric_limits<double>::signaling_NaN()); 415 return F::isquietnan(fd); 416 }, "fcvt.s.d, signaling NaN"); 417 expect<float>(numeric_limits<float>::infinity(), 418 []{return D::fcvt_s_d(numeric_limits<double>::infinity());}, 419 "fcvt.s.d, infinity"); 420 expect<float>(numeric_limits<float>::infinity(), 421 []{return D::fcvt_s_d(numeric_limits<double>::max());}, 422 "fcvt.s.d, overflow"); 423 expect<float>(0.0, []{return D::fcvt_s_d(numeric_limits<double>::min());}, 424 "fcvt.s.d, underflow"); 425 426 // FCVT.D.S 427 expect<double>(D::number(0x4005BE76C0000000), 428 []{return D::fcvt_d_s(2.718);}, "fcvt.d.s"); 429 expect<bool>(true, []{ 430 double fd = D::fcvt_d_s(numeric_limits<float>::quiet_NaN()); 431 return D::isquietnan(fd); 432 }, "fcvt.d.s, quiet NaN"); 433 expect<bool>(true, []{ 434 double fd = D::fcvt_d_s(numeric_limits<float>::signaling_NaN()); 435 return D::isquietnan(fd); 436 }, "fcvt.d.s, signaling NaN"); 437 expect<double>(numeric_limits<double>::infinity(), 438 []{return D::fcvt_d_s(numeric_limits<float>::infinity());}, 439 "fcvt.d.s, infinity"); 440 441 // FEQ.D 442 expect<bool>(true, []{return D::feq_d(1.414, 1.414);}, "feq.d, equal"); 443 expect<bool>(false,[]{return D::feq_d(2.718, 1.816);}, "feq.d, not equal"); 444 expect<bool>(true, []{return D::feq_d(0.0, -0.0);}, "feq.d, 0 == -0"); 445 expect<bool>(false, 446 []{return D::feq_d(numeric_limits<double>::quiet_NaN(), -1.0);}, 447 "feq.d, quiet NaN first"); 448 expect<bool>(false, 449 []{return D::feq_d(2.0, numeric_limits<double>::quiet_NaN());}, 450 "feq.d, quiet NaN second"); 451 expect<bool>(false, 452 []{return D::feq_d(numeric_limits<double>::quiet_NaN(), 453 numeric_limits<double>::quiet_NaN());}, 454 "feq.d, quiet NaN both"); 455 expect<bool>(false, 456 []{return D::feq_d(numeric_limits<double>::signaling_NaN(),-1.0);}, 457 "feq.d, signaling NaN first"); 458 expect<bool>(false, 459 []{return D::feq_d(2.0, numeric_limits<double>::signaling_NaN());}, 460 "feq.d, signaling NaN second"); 461 expect<bool>(false, 462 []{return D::feq_d(numeric_limits<double>::signaling_NaN(), 463 numeric_limits<double>::signaling_NaN());}, 464 "feq.d, signaling NaN both"); 465 466 // FLT.D 467 expect<bool>(false, []{return D::flt_d(1.414, 1.414);}, "flt.d, equal"); 468 expect<bool>(true, []{return D::flt_d(1.816, 2.718);}, "flt.d, less"); 469 expect<bool>(false, []{return D::flt_d(2.718, 1.816);}, "flt.d, greater"); 470 expect<bool>(false, 471 []{return D::flt_d(numeric_limits<double>::quiet_NaN(), -1.0);}, 472 "flt.d, quiet NaN first"); 473 expect<bool>(false, 474 []{return D::flt_d(2.0, numeric_limits<double>::quiet_NaN());}, 475 "flt.d, quiet NaN second"); 476 expect<bool>(false, 477 []{return D::flt_d(numeric_limits<double>::quiet_NaN(), 478 numeric_limits<double>::quiet_NaN());}, 479 "flt.d, quiet NaN both"); 480 expect<bool>(false, 481 []{return D::flt_d(numeric_limits<double>::signaling_NaN(),-1.0);}, 482 "flt.d, signaling NaN first"); 483 expect<bool>(false, 484 []{return D::flt_d(2.0, numeric_limits<double>::signaling_NaN());}, 485 "flt.d, signaling NaN second"); 486 expect<bool>(false, 487 []{return D::flt_d(numeric_limits<double>::signaling_NaN(), 488 numeric_limits<double>::signaling_NaN());}, 489 "flt.d, signaling NaN both"); 490 491 // FLE.D 492 expect<bool>(true, []{return D::fle_d(1.414, 1.414);}, "fle.d, equal"); 493 expect<bool>(true, []{return D::fle_d(1.816, 2.718);}, "fle.d, less"); 494 expect<bool>(false, []{return D::fle_d(2.718, 1.816);}, "fle.d, greater"); 495 expect<bool>(true, []{return D::fle_d(0.0, -0.0);}, "fle.d, 0 == -0"); 496 expect<bool>(false, 497 []{return D::fle_d(numeric_limits<double>::quiet_NaN(), -1.0);}, 498 "fle.d, quiet NaN first"); 499 expect<bool>(false, 500 []{return D::fle_d(2.0, numeric_limits<double>::quiet_NaN());}, 501 "fle.d, quiet NaN second"); 502 expect<bool>(false, 503 []{return D::fle_d(numeric_limits<double>::quiet_NaN(), 504 numeric_limits<double>::quiet_NaN());}, 505 "fle.d, quiet NaN both"); 506 expect<bool>(false, 507 []{return D::fle_d(numeric_limits<double>::signaling_NaN(),-1.0);}, 508 "fle.d, signaling NaN first"); 509 expect<bool>(false, 510 []{return D::fle_d(2.0, numeric_limits<double>::signaling_NaN());}, 511 "fle.d, signaling NaN second"); 512 expect<bool>(false, 513 []{return D::fle_d(numeric_limits<double>::signaling_NaN(), 514 numeric_limits<double>::signaling_NaN());}, 515 "fle.d, signaling NaN both"); 516 517 // FCLASS.D 518 expect<uint64_t>(0x1, 519 []{return D::fclass_d(-numeric_limits<double>::infinity());}, 520 "fclass.d, -infinity"); 521 expect<uint64_t>(0x2, 522 []{return D::fclass_d(-3.14);}, "fclass.d, -normal"); 523 expect<uint64_t>(0x4, 524 []{return D::fclass_d(D::number(0x800FFFFFFFFFFFFFULL));}, 525 "fclass.d, -subnormal"); 526 expect<uint64_t>(0x8, []{return D::fclass_d(-0.0);}, "fclass.d, -0.0"); 527 expect<uint64_t>(0x10, []{return D::fclass_d(0.0);}, "fclass.d, 0.0"); 528 expect<uint64_t>(0x20, 529 []{return D::fclass_d(D::number(0x000FFFFFFFFFFFFFULL));}, 530 "fclass.d, subnormal"); 531 expect<uint64_t>(0x40, []{return D::fclass_d(1.816);}, "fclass.d, normal"); 532 expect<uint64_t>(0x80, 533 []{return D::fclass_d(numeric_limits<double>::infinity());}, 534 "fclass.d, infinity"); 535 expect<uint64_t>(0x100, 536 []{return D::fclass_d(numeric_limits<double>::signaling_NaN());}, 537 "fclass.d, signaling NaN"); 538 expect<uint64_t>(0x200, 539 []{return D::fclass_d(numeric_limits<double>::quiet_NaN());}, 540 "fclass.s, quiet NaN"); 541 542 // FCVT.W.D 543 expect<int64_t>(256, []{return D::fcvt_w_d(256.3);}, 544 "fcvt.w.d, truncate positive"); 545 expect<int64_t>(-256, []{return D::fcvt_w_d(-256.2);}, 546 "fcvt.w.d, truncate negative"); 547 expect<int64_t>(0, []{return D::fcvt_w_d(0.0);}, "fcvt.w.d, 0.0"); 548 expect<int64_t>(0, []{return D::fcvt_w_d(-0.0);}, "fcvt.w.d, -0.0"); 549 expect<int64_t>(numeric_limits<int32_t>::max(), 550 []{return D::fcvt_w_d(numeric_limits<double>::max());}, 551 "fcvt.w.d, overflow"); 552 expect<int64_t>(0, []{return D::fcvt_w_d(numeric_limits<double>::min());}, 553 "fcvt.w.d, underflow"); 554 expect<int64_t>(numeric_limits<int32_t>::max(), 555 []{return D::fcvt_w_d(numeric_limits<double>::infinity());}, 556 "fcvt.w.d, infinity"); 557 expect<int64_t>(numeric_limits<int32_t>::min(), 558 []{return D::fcvt_w_d(-numeric_limits<double>::infinity());}, 559 "fcvt.w.d, -infinity"); 560 expect<int64_t>(numeric_limits<int32_t>::max(), 561 []{return D::fcvt_w_d(numeric_limits<double>::quiet_NaN());}, 562 "fcvt.w.d, quiet NaN"); 563 expect<int64_t>(numeric_limits<int32_t>::max(), 564 []{return D::fcvt_w_d(-numeric_limits<double>::quiet_NaN());}, 565 "fcvt.w.d, quiet -NaN"); 566 expect<int64_t>(numeric_limits<int32_t>::max(), 567 []{return D::fcvt_w_d(numeric_limits<double>::signaling_NaN());}, 568 "fcvt.w.d, signaling NaN"); 569 570 // FCVT.WU.D 571 expect<uint64_t>(256, []{return D::fcvt_wu_d(256.3);}, 572 "fcvt.wu.d, truncate positive"); 573 expect<uint64_t>(0, []{return D::fcvt_wu_d(-256.2);}, 574 "fcvt.wu.d, truncate negative"); 575 expect<uint64_t>(0, []{return D::fcvt_wu_d(0.0);}, "fcvt.wu.d, 0.0"); 576 expect<uint64_t>(0, []{return D::fcvt_wu_d(-0.0);}, "fcvt.wu.d, -0.0"); 577 expect<uint64_t>(numeric_limits<uint64_t>::max(), 578 []{return D::fcvt_wu_d(numeric_limits<double>::max());}, 579 "fcvt.wu.d, overflow"); 580 expect<uint64_t>(0,[]{return D::fcvt_wu_d(numeric_limits<double>::min());}, 581 "fcvt.wu.d, underflow"); 582 expect<uint64_t>(numeric_limits<uint64_t>::max(), 583 []{return D::fcvt_wu_d(numeric_limits<double>::infinity());}, 584 "fcvt.wu.d, infinity"); 585 expect<uint64_t>(0, 586 []{return D::fcvt_wu_d(-numeric_limits<double>::infinity());}, 587 "fcvt.wu.d, -infinity"); 588 expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL, 589 []{return D::fcvt_wu_d(numeric_limits<double>::quiet_NaN());}, 590 "fcvt.wu.d, quiet NaN"); 591 expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL, 592 []{return D::fcvt_wu_d(-numeric_limits<double>::quiet_NaN());}, 593 "fcvt.wu.d, quiet -NaN"); 594 expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL, 595 []{return D::fcvt_wu_d(numeric_limits<double>::signaling_NaN());}, 596 "fcvt.wu.d, signaling NaN"); 597 598 // FCVT.D.W 599 expect<double>(0.0, []{return D::fcvt_d_w(0);}, "fcvt.d.w, 0"); 600 expect<double>(-2147483648.0, 601 []{return D::fcvt_d_w(numeric_limits<int32_t>::min());}, 602 "fcvt.d.w, negative"); 603 expect<double>(255.0, []{return D::fcvt_d_w(0xFFFFFFFF000000FFLL);}, 604 "fcvt.d.w, truncate"); 605 606 // FCVT.D.WU 607 expect<double>(0.0, []{return D::fcvt_d_wu(0);}, "fcvt.d.wu, 0"); 608 expect<double>(2147483648.0, 609 []{return D::fcvt_d_wu(numeric_limits<int32_t>::min());}, 610 "fcvt.d.wu"); 611 expect<double>(255.0, 612 []{return D::fcvt_d_wu(0xFFFFFFFF000000FFLL);}, 613 "fcvt.d.wu, truncate"); 614 615 // FCVT.L.D 616 expect<int64_t>(256, []{return D::fcvt_l_d(256.3);}, 617 "fcvt.l.d, truncate positive"); 618 expect<int64_t>(-256, []{return D::fcvt_l_d(-256.2);}, 619 "fcvt.l.d, truncate negative"); 620 expect<int64_t>(0, []{return D::fcvt_l_d(0.0);}, "fcvt.l.d, 0.0"); 621 expect<int64_t>(0, []{return D::fcvt_l_d(-0.0);}, "fcvt.l.d, -0.0"); 622 expect<int64_t>(-8589934592LL, []{return D::fcvt_l_d(-8589934592.0);}, 623 "fcvt.l.d, 32-bit overflow"); 624 expect<int64_t>(numeric_limits<int64_t>::max(), 625 []{return D::fcvt_l_d(numeric_limits<double>::max());}, 626 "fcvt.l.d, overflow"); 627 expect<int64_t>(0, []{return D::fcvt_l_d(numeric_limits<double>::min());}, 628 "fcvt.l.d, underflow"); 629 expect<int64_t>(numeric_limits<int64_t>::max(), 630 []{return D::fcvt_l_d(numeric_limits<double>::infinity());}, 631 "fcvt.l.d, infinity"); 632 expect<int64_t>(numeric_limits<int64_t>::min(), 633 []{return D::fcvt_l_d(-numeric_limits<double>::infinity());}, 634 "fcvt.l.d, -infinity"); 635 expect<int64_t>(numeric_limits<int64_t>::max(), 636 []{return D::fcvt_l_d(numeric_limits<double>::quiet_NaN());}, 637 "fcvt.l.d, quiet NaN"); 638 expect<int64_t>(numeric_limits<int64_t>::max(), 639 []{return D::fcvt_l_d(-numeric_limits<double>::quiet_NaN());}, 640 "fcvt.l.d, quiet -NaN"); 641 expect<int64_t>(numeric_limits<int64_t>::max(), 642 []{return D::fcvt_l_d(numeric_limits<double>::signaling_NaN());}, 643 "fcvt.l.d, signaling NaN"); 644 645 // FCVT.LU.D 646 expect<uint64_t>(256, []{return D::fcvt_lu_d(256.3);}, 647 "fcvt.lu.d, truncate positive"); 648 expect<uint64_t>(0, []{return D::fcvt_lu_d(-256.2);}, 649 "fcvt.lu.d, truncate negative"); 650 expect<uint64_t>(0, []{return D::fcvt_lu_d(0.0);}, "fcvt.lu.d, 0.0"); 651 expect<uint64_t>(0, []{return D::fcvt_lu_d(-0.0);}, "fcvt.lu.d, -0.0"); 652 expect<uint64_t>(8589934592LL, []{return D::fcvt_lu_d(8589934592.0);}, 653 "fcvt.lu.d, 32-bit overflow"); 654 expect<uint64_t>(numeric_limits<uint64_t>::max(), 655 []{return D::fcvt_lu_d(numeric_limits<double>::max());}, 656 "fcvt.lu.d, overflow"); 657 expect<uint64_t>(0,[]{return D::fcvt_lu_d(numeric_limits<double>::min());}, 658 "fcvt.lu.d, underflow"); 659 expect<uint64_t>(numeric_limits<uint64_t>::max(), 660 []{return D::fcvt_lu_d(numeric_limits<double>::infinity());}, 661 "fcvt.lu.d, infinity"); 662 expect<uint64_t>(0, 663 []{return D::fcvt_lu_d(-numeric_limits<double>::infinity());}, 664 "fcvt.lu.d, -infinity"); 665 expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL, 666 []{return D::fcvt_lu_d(numeric_limits<double>::quiet_NaN());}, 667 "fcvt.lu.d, quiet NaN"); 668 expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL, 669 []{return D::fcvt_lu_d(-numeric_limits<double>::quiet_NaN());}, 670 "fcvt.lu.d, quiet -NaN"); 671 expect<uint64_t>(0xFFFFFFFFFFFFFFFFULL, 672 []{return D::fcvt_lu_d(numeric_limits<double>::signaling_NaN());}, 673 "fcvt.lu.d, signaling NaN"); 674 675 // FMV.X.D 676 expect<uint64_t>(0x40091EB851EB851FULL, []{return D::fmv_x_d(3.14);}, 677 "fmv.x.d, positive"); 678 expect<uint64_t>(0xC0091EB851EB851FULL, []{return D::fmv_x_d(-3.14);}, 679 "fmv.x.d, negative"); 680 expect<uint64_t>(0x0000000000000000ULL, []{return D::fmv_x_d(0.0);}, 681 "fmv.x.d, 0.0"); 682 expect<uint64_t>(0x8000000000000000ULL, []{return D::fmv_x_d(-0.0);}, 683 "fmv.x.d, -0.0"); 684 685 // FCVT.D.L 686 expect<double>(0.0, []{return D::fcvt_d_l(0);}, "fcvt.d.l, 0"); 687 expect<double>(D::number(0xC3E0000000000000), 688 []{return D::fcvt_d_l(numeric_limits<int64_t>::min());}, 689 "fcvt.d.l, negative"); 690 expect<double>(D::number(0xC1EFFFFFE0200000), 691 []{return D::fcvt_d_l(0xFFFFFFFF000000FFLL);}, 692 "fcvt.d.l, 32-bit truncate"); 693 694 // FCVT.D.LU 695 expect<double>(0.0, []{return D::fcvt_d_lu(0);}, "fcvt.d.lu, 0"); 696 expect<double>(D::number(0x43E0000000000000), 697 []{return D::fcvt_d_lu(numeric_limits<int64_t>::min());}, 698 "fcvt.d.lu"); 699 expect<double>(D::number(0x43EFFFFFFFE00000), 700 []{return D::fcvt_d_lu(0xFFFFFFFF000000FFLL);}, 701 "fcvt.d.lu, 32-bit truncate"); 702 703 // FMV.D.X 704 expect<double>(-numeric_limits<float>::infinity(), 705 []{return D::fmv_d_x(0xFFF0000000000000ULL);}, "fmv.d.x"); 706 707 return 0; 708} 709