1 #define ASSERT(EXPRESSION) \ 2 do { \ 3 if (!(EXPRESSION)) { \ 4 fprintf (stderr, "%s:%d: assertion failed - %s\n", \ 5 __FILE__, __LINE__, #EXPRESSION); \ 6 abort (); \ 7 } \ 8 } while (0) 9 10 #define SIM_BITS_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE) 11 12 #include "milieu.h" 13 #include "softfloat.h" 14 #include "systfloat.h" 15 #include "systmodes.h" 16 17 /* #define SIM_FPU_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE) */ 18 19 20 #include "sim-bits.h" 21 #include "sim-fpu.h" 22 #include "sim-fpu.c" 23 24 25 26 static int flags; 27 28 int8 29 syst_float_flags_clear () 30 { 31 int old_flags = 0; 32 int i = 1; 33 while (flags >= i) 34 { 35 switch ((sim_fpu_status) (flags & i)) 36 { 37 case sim_fpu_status_denorm: 38 break; 39 case sim_fpu_status_invalid_snan: 40 case sim_fpu_status_invalid_qnan: 41 case sim_fpu_status_invalid_isi: 42 case sim_fpu_status_invalid_idi: 43 case sim_fpu_status_invalid_zdz: 44 case sim_fpu_status_invalid_imz: 45 case sim_fpu_status_invalid_cvi: 46 case sim_fpu_status_invalid_cmp: 47 case sim_fpu_status_invalid_sqrt: 48 old_flags |= float_flag_invalid; /* v */ 49 break; 50 case sim_fpu_status_inexact: 51 old_flags |= float_flag_inexact; /* x */ 52 break; 53 case sim_fpu_status_overflow: 54 old_flags |= float_flag_overflow; /* o */ 55 break; 56 case sim_fpu_status_underflow: 57 old_flags |= float_flag_underflow; /* u */ 58 break; 59 case sim_fpu_status_invalid_div0: 60 old_flags |= float_flag_divbyzero; /* z */ 61 break; 62 case sim_fpu_status_rounded: 63 break; 64 } 65 i <<= 1; 66 } 67 flags = 0; 68 return old_flags; 69 } 70 71 72 sim_fpu_round rounding_mode; 73 74 void 75 syst_float_set_rounding_mode(int8 mode) 76 { 77 switch (mode) 78 { 79 case float_round_nearest_even: 80 rounding_mode = sim_fpu_round_near; 81 break; 82 case float_round_down: 83 rounding_mode = sim_fpu_round_down; 84 break; 85 case float_round_up: 86 rounding_mode = sim_fpu_round_up; 87 break; 88 case float_round_to_zero: 89 rounding_mode = sim_fpu_round_zero; 90 break; 91 } 92 } 93 94 95 float32 96 syst_int32_to_float32(int32 a) 97 { 98 float32 z; 99 sim_fpu s; 100 flags |= sim_fpu_i32to (&s, a, rounding_mode); 101 flags |= sim_fpu_round_32 (&s, rounding_mode, 0); 102 sim_fpu_to32 (&z, &s); 103 return z; 104 } 105 106 float64 107 syst_int32_to_float64( int32 a ) 108 { 109 float64 z; 110 sim_fpu s; 111 flags |= sim_fpu_i32to (&s, a, rounding_mode); 112 sim_fpu_to64 (&z, &s); 113 return z; 114 } 115 116 int32 117 syst_float32_to_int32_round_to_zero( float32 a ) 118 { 119 int32 z; 120 sim_fpu s; 121 sim_fpu_32to (&s, a); 122 flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero); 123 return z; 124 } 125 126 float64 127 syst_float32_to_float64 (float32 a) 128 { 129 float64 z; 130 sim_fpu s; 131 sim_fpu_32to (&s, a); 132 flags |= sim_fpu_round_64 (&s, rounding_mode, 0); 133 sim_fpu_to64 (&z, &s); 134 return z; 135 } 136 137 float32 syst_float32_add( float32 a, float32 b ) 138 { 139 float32 z; 140 sim_fpu A; 141 sim_fpu B; 142 sim_fpu ans; 143 sim_fpu_32to (&A, a); 144 sim_fpu_32to (&B, b); 145 #if 0 146 fprintf (stdout, "\n "); 147 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 148 fprintf (stdout, "\n+ "); 149 sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); 150 fprintf (stdout, "\n= "); 151 #endif 152 flags |= sim_fpu_add (&ans, &A, &B); 153 flags |= sim_fpu_round_32 (&ans, rounding_mode, 0); 154 #if 0 155 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 156 fprintf (stdout, "\n"); 157 #endif 158 sim_fpu_to32 (&z, &ans); 159 return z; 160 } 161 162 float32 syst_float32_sub( float32 a, float32 b ) 163 { 164 float32 z; 165 sim_fpu A; 166 sim_fpu B; 167 sim_fpu ans; 168 sim_fpu_32to (&A, a); 169 sim_fpu_32to (&B, b); 170 #if 0 171 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 172 fprintf (stdout, " + "); 173 sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); 174 fprintf (stdout, " = "); 175 #endif 176 flags |= sim_fpu_sub (&ans, &A, &B); 177 flags |= sim_fpu_round_32 (&ans, rounding_mode, 0); 178 #if 0 179 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 180 fprintf (stdout, "\n"); 181 #endif 182 sim_fpu_to32 (&z, &ans); 183 return z; 184 } 185 186 float32 syst_float32_mul( float32 a, float32 b ) 187 { 188 float32 z; 189 sim_fpu A; 190 sim_fpu B; 191 sim_fpu ans; 192 sim_fpu_32to (&A, a); 193 sim_fpu_32to (&B, b); 194 #if 0 195 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 196 fprintf (stdout, " + "); 197 sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); 198 fprintf (stdout, " = "); 199 #endif 200 flags |= sim_fpu_mul (&ans, &A, &B); 201 #if 0 202 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 203 #endif 204 flags |= sim_fpu_round_32 (&ans, rounding_mode, 0); 205 #if 0 206 sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout); 207 fprintf (stdout, "\n"); 208 #endif 209 sim_fpu_to32 (&z, &ans); 210 return z; 211 } 212 213 float32 syst_float32_div( float32 a, float32 b ) 214 { 215 float32 z; 216 sim_fpu A; 217 sim_fpu B; 218 sim_fpu ans; 219 sim_fpu_32to (&A, a); 220 sim_fpu_32to (&B, b); 221 flags |= sim_fpu_div (&ans, &A, &B); 222 flags |= sim_fpu_round_32 (&ans, rounding_mode, 0); 223 sim_fpu_to32 (&z, &ans); 224 return z; 225 } 226 227 float32 syst_float32_sqrt( float32 a ) 228 { 229 float32 z; 230 sim_fpu A; 231 sim_fpu ans; 232 sim_fpu_32to (&A, a); 233 #if 0 234 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 235 fprintf (stdout, " sqrt> "); 236 #endif 237 flags |= sim_fpu_sqrt (&ans, &A); 238 #if 0 239 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 240 #endif 241 flags |= sim_fpu_round_32 (&ans, rounding_mode, 0); 242 #if 0 243 fprintf (stdout, " (%x)\n", flags); 244 #endif 245 sim_fpu_to32 (&z, &ans); 246 return z; 247 } 248 249 flag syst_float32_eq( float32 a, float32 b ) 250 { 251 sim_fpu A; 252 sim_fpu B; 253 int is; 254 sim_fpu_32to (&A, a); 255 sim_fpu_32to (&B, b); 256 flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan); 257 return is; 258 } 259 260 flag syst_float32_eq_signaling( float32 a, float32 b ) 261 { 262 sim_fpu A; 263 sim_fpu B; 264 int is; 265 sim_fpu_32to (&A, a); 266 sim_fpu_32to (&B, b); 267 flags |= sim_fpu_eq (&is, &A, &B); 268 return is; 269 } 270 271 flag syst_float32_le( float32 a, float32 b ) 272 { 273 sim_fpu A; 274 sim_fpu B; 275 int is; 276 sim_fpu_32to (&A, a); 277 sim_fpu_32to (&B, b); 278 flags |= sim_fpu_le (&is, &A, &B); 279 return is; 280 } 281 282 flag syst_float32_le_quiet( float32 a, float32 b ) 283 { 284 sim_fpu A; 285 sim_fpu B; 286 int is; 287 sim_fpu_32to (&A, a); 288 sim_fpu_32to (&B, b); 289 flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan); 290 return is; 291 } 292 293 flag syst_float32_lt( float32 a, float32 b ) 294 { 295 sim_fpu A; 296 sim_fpu B; 297 int is; 298 sim_fpu_32to (&A, a); 299 sim_fpu_32to (&B, b); 300 flags |= sim_fpu_lt (&is, &A, &B); 301 return is; 302 } 303 304 flag syst_float32_lt_quiet( float32 a, float32 b ) 305 { 306 sim_fpu A; 307 sim_fpu B; 308 int is; 309 sim_fpu_32to (&A, a); 310 sim_fpu_32to (&B, b); 311 flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan); 312 return is; 313 } 314 315 int32 syst_float64_to_int32_round_to_zero( float64 a ) 316 { 317 int32 z; 318 sim_fpu s; 319 sim_fpu_64to (&s, a); 320 flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero); 321 return z; 322 } 323 324 float32 syst_float64_to_float32( float64 a ) 325 { 326 float32 z; 327 sim_fpu s; 328 sim_fpu_64to (&s, a); 329 #if 0 330 sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout); 331 fprintf (stdout, " -> "); 332 #endif 333 flags |= sim_fpu_round_32 (&s, rounding_mode, 0); 334 #if 0 335 sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout); 336 sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout); 337 printf ("\n"); 338 #endif 339 sim_fpu_to32 (&z, &s); 340 return z; 341 } 342 343 float64 syst_float64_add( float64 a, float64 b ) 344 { 345 float64 z; 346 sim_fpu A; 347 sim_fpu B; 348 sim_fpu ans; 349 sim_fpu_64to (&A, a); 350 sim_fpu_64to (&B, b); 351 #if 0 352 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 353 fprintf (stdout, " + "); 354 sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); 355 fprintf (stdout, " = "); 356 #endif 357 flags |= sim_fpu_add (&ans, &A, &B); 358 #if 0 359 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 360 #endif 361 flags |= sim_fpu_round_64 (&ans, rounding_mode, 0); 362 #if 0 363 fprintf (stdout, " (%x)\n", flags); 364 #endif 365 sim_fpu_to64 (&z, &ans); 366 return z; 367 } 368 369 float64 syst_float64_sub( float64 a, float64 b ) 370 { 371 float64 z; 372 sim_fpu A; 373 sim_fpu B; 374 sim_fpu ans; 375 sim_fpu_64to (&A, a); 376 sim_fpu_64to (&B, b); 377 #if 0 378 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 379 fprintf (stdout, " + "); 380 sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); 381 fprintf (stdout, " = "); 382 #endif 383 flags |= sim_fpu_sub (&ans, &A, &B); 384 #if 0 385 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 386 #endif 387 flags |= sim_fpu_round_64 (&ans, rounding_mode, 0); 388 #if 0 389 fprintf (stdout, " (%x)\n", flags); 390 #endif 391 sim_fpu_to64 (&z, &ans); 392 return z; 393 } 394 395 float64 syst_float64_mul( float64 a, float64 b ) 396 { 397 float64 z; 398 sim_fpu A; 399 sim_fpu B; 400 sim_fpu ans; 401 sim_fpu_64to (&A, a); 402 sim_fpu_64to (&B, b); 403 #if 0 404 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 405 fprintf (stdout, " * "); 406 sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); 407 fprintf (stdout, " = "); 408 #endif 409 flags |= sim_fpu_mul (&ans, &A, &B); 410 #if 0 411 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 412 #endif 413 flags |= sim_fpu_round_64 (&ans, rounding_mode, 0); 414 #if 0 415 sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout); 416 fprintf (stdout, "\n"); 417 #endif 418 sim_fpu_to64 (&z, &ans); 419 return z; 420 } 421 422 float64 syst_float64_div( float64 a, float64 b ) 423 { 424 float64 z; 425 sim_fpu A; 426 sim_fpu B; 427 sim_fpu ans; 428 sim_fpu_64to (&A, a); 429 sim_fpu_64to (&B, b); 430 #if 0 431 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 432 fprintf (stdout, " + "); 433 sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); 434 fprintf (stdout, " = "); 435 #endif 436 flags |= sim_fpu_div (&ans, &A, &B); 437 #if 0 438 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 439 #endif 440 flags |= sim_fpu_round_64 (&ans, rounding_mode, 0); 441 #if 0 442 sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout); 443 fprintf (stdout, "\n"); 444 #endif 445 sim_fpu_to64 (&z, &ans); 446 return z; 447 } 448 449 float64 syst_float64_sqrt( float64 a ) 450 { 451 float64 z; 452 sim_fpu A; 453 sim_fpu ans; 454 sim_fpu_64to (&A, a); 455 #if 0 456 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); 457 printf (" sqrt> "); 458 printf ("\n"); 459 #endif 460 flags |= sim_fpu_sqrt (&ans, &A); 461 #if 0 462 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); 463 #endif 464 flags |= sim_fpu_round_64 (&ans, rounding_mode, 0); 465 #if 0 466 sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout); 467 fprintf (stdout, "\n"); 468 #endif 469 sim_fpu_to64 (&z, &ans); 470 return z; 471 } 472 473 flag syst_float64_eq( float64 a, float64 b ) 474 { 475 sim_fpu A; 476 sim_fpu B; 477 int is; 478 sim_fpu_64to (&A, a); 479 sim_fpu_64to (&B, b); 480 flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan); 481 return is; 482 } 483 484 flag syst_float64_eq_signaling( float64 a, float64 b ) 485 { 486 sim_fpu A; 487 sim_fpu B; 488 int is; 489 sim_fpu_64to (&A, a); 490 sim_fpu_64to (&B, b); 491 flags |= sim_fpu_eq (&is, &A, &B); 492 return is; 493 } 494 495 flag syst_float64_le( float64 a, float64 b ) 496 { 497 sim_fpu A; 498 sim_fpu B; 499 int is; 500 sim_fpu_64to (&A, a); 501 sim_fpu_64to (&B, b); 502 flags |= sim_fpu_le (&is, &A, &B); 503 return is; 504 } 505 506 flag syst_float64_le_quiet( float64 a, float64 b ) 507 { 508 sim_fpu A; 509 sim_fpu B; 510 int is; 511 sim_fpu_64to (&A, a); 512 sim_fpu_64to (&B, b); 513 flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan); 514 return is; 515 } 516 517 flag syst_float64_lt( float64 a, float64 b ) 518 { 519 sim_fpu A; 520 sim_fpu B; 521 int is; 522 sim_fpu_64to (&A, a); 523 sim_fpu_64to (&B, b); 524 flags |= sim_fpu_lt (&is, &A, &B); 525 return is; 526 } 527 528 flag syst_float64_lt_quiet( float64 a, float64 b ) 529 { 530 sim_fpu A; 531 sim_fpu B; 532 int is; 533 sim_fpu_64to (&A, a); 534 sim_fpu_64to (&B, b); 535 flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan); 536 return is; 537 } 538 539