1#define ASSERT(EXPRESSION) \ 2do { \ 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 26static int flags; 27 28int8 29syst_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 72sim_fpu_round rounding_mode; 73 74void 75syst_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 95float32 96syst_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 106float64 107syst_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 116int32 117syst_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 126float64 127syst_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 137float32 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 162float32 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 186float32 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 213float32 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 227float32 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 249flag 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 260flag 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 271flag 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 282flag 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 293flag 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 304flag 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 315int32 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 324float32 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 343float64 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 369float64 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 395float64 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 422float64 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 449float64 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 473flag 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 484flag 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 495flag 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 506flag 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 517flag 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 528flag 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