1 1.1 christos /* Accurate fp support for CGEN-based simulators. 2 1.1 christos Copyright (C) 1999 Cygnus Solutions. 3 1.1 christos 4 1.1 christos This implemention assumes: 5 1.1 christos typedef USI SF; 6 1.1 christos typedef UDI DF; 7 1.1 christos 8 1.1 christos TODO: 9 1.1 christos - lazy encoding/decoding 10 1.1 christos - checking return code (say by callback) 11 1.1 christos - proper rounding 12 1.1 christos */ 13 1.1 christos 14 1.1.1.4 christos /* This must come before any other includes. */ 15 1.1.1.4 christos #include "defs.h" 16 1.1.1.4 christos 17 1.1 christos #include "sim-main.h" 18 1.1 christos #include "sim-fpu.h" 19 1.1 christos 20 1.1 christos /* SF mode support */ 21 1.1 christos 22 1.1 christos static SF 23 1.1 christos addsf (CGEN_FPU* fpu, SF x, SF y) 24 1.1 christos { 25 1.1 christos sim_fpu op1; 26 1.1 christos sim_fpu op2; 27 1.1 christos sim_fpu ans; 28 1.1.1.4 christos uint32_t res; 29 1.1 christos sim_fpu_status status; 30 1.1 christos 31 1.1 christos sim_fpu_32to (&op1, x); 32 1.1 christos sim_fpu_32to (&op2, y); 33 1.1 christos status = sim_fpu_add (&ans, &op1, &op2); 34 1.1 christos if (status != 0) 35 1.1 christos (*fpu->ops->error) (fpu, status); 36 1.1 christos sim_fpu_to32 (&res, &ans); 37 1.1 christos 38 1.1 christos return res; 39 1.1 christos } 40 1.1 christos 41 1.1 christos static SF 42 1.1 christos subsf (CGEN_FPU* fpu, SF x, SF y) 43 1.1 christos { 44 1.1 christos sim_fpu op1; 45 1.1 christos sim_fpu op2; 46 1.1 christos sim_fpu ans; 47 1.1.1.4 christos uint32_t res; 48 1.1 christos sim_fpu_status status; 49 1.1 christos 50 1.1 christos sim_fpu_32to (&op1, x); 51 1.1 christos sim_fpu_32to (&op2, y); 52 1.1 christos status = sim_fpu_sub (&ans, &op1, &op2); 53 1.1 christos if (status != 0) 54 1.1 christos (*fpu->ops->error) (fpu, status); 55 1.1 christos sim_fpu_to32 (&res, &ans); 56 1.1 christos 57 1.1 christos return res; 58 1.1 christos } 59 1.1 christos 60 1.1 christos static SF 61 1.1 christos mulsf (CGEN_FPU* fpu, SF x, SF y) 62 1.1 christos { 63 1.1 christos sim_fpu op1; 64 1.1 christos sim_fpu op2; 65 1.1 christos sim_fpu ans; 66 1.1.1.4 christos uint32_t res; 67 1.1 christos sim_fpu_status status; 68 1.1 christos 69 1.1 christos sim_fpu_32to (&op1, x); 70 1.1 christos sim_fpu_32to (&op2, y); 71 1.1 christos status = sim_fpu_mul (&ans, &op1, &op2); 72 1.1 christos if (status != 0) 73 1.1 christos (*fpu->ops->error) (fpu, status); 74 1.1 christos sim_fpu_to32 (&res, &ans); 75 1.1 christos 76 1.1 christos return res; 77 1.1 christos } 78 1.1 christos 79 1.1 christos static SF 80 1.1 christos divsf (CGEN_FPU* fpu, SF x, SF y) 81 1.1 christos { 82 1.1 christos sim_fpu op1; 83 1.1 christos sim_fpu op2; 84 1.1 christos sim_fpu ans; 85 1.1.1.4 christos uint32_t res; 86 1.1 christos sim_fpu_status status; 87 1.1 christos 88 1.1 christos sim_fpu_32to (&op1, x); 89 1.1 christos sim_fpu_32to (&op2, y); 90 1.1 christos status = sim_fpu_div (&ans, &op1, &op2); 91 1.1 christos if (status != 0) 92 1.1 christos (*fpu->ops->error) (fpu, status); 93 1.1 christos sim_fpu_to32 (&res, &ans); 94 1.1 christos 95 1.1 christos return res; 96 1.1 christos } 97 1.1 christos 98 1.1 christos static SF 99 1.1.1.2 christos remsf (CGEN_FPU* fpu, SF x, SF y) 100 1.1.1.2 christos { 101 1.1.1.2 christos sim_fpu op1; 102 1.1.1.2 christos sim_fpu op2; 103 1.1.1.2 christos sim_fpu ans; 104 1.1.1.4 christos uint32_t res; 105 1.1.1.2 christos sim_fpu_status status; 106 1.1.1.2 christos 107 1.1.1.2 christos sim_fpu_32to (&op1, x); 108 1.1.1.2 christos sim_fpu_32to (&op2, y); 109 1.1.1.2 christos status = sim_fpu_rem (&ans, &op1, &op2); 110 1.1.1.2 christos if (status != 0) 111 1.1.1.2 christos (*fpu->ops->error) (fpu, status); 112 1.1.1.2 christos sim_fpu_to32 (&res, &ans); 113 1.1.1.2 christos 114 1.1.1.2 christos return res; 115 1.1.1.2 christos } 116 1.1.1.2 christos 117 1.1.1.2 christos static SF 118 1.1 christos negsf (CGEN_FPU* fpu, SF x) 119 1.1 christos { 120 1.1 christos sim_fpu op1; 121 1.1 christos sim_fpu ans; 122 1.1.1.4 christos uint32_t res; 123 1.1 christos sim_fpu_status status; 124 1.1 christos 125 1.1 christos sim_fpu_32to (&op1, x); 126 1.1 christos status = sim_fpu_neg (&ans, &op1); 127 1.1 christos if (status != 0) 128 1.1 christos (*fpu->ops->error) (fpu, status); 129 1.1 christos sim_fpu_to32 (&res, &ans); 130 1.1 christos 131 1.1 christos return res; 132 1.1 christos } 133 1.1 christos 134 1.1 christos static SF 135 1.1 christos abssf (CGEN_FPU* fpu, SF x) 136 1.1 christos { 137 1.1 christos sim_fpu op1; 138 1.1 christos sim_fpu ans; 139 1.1.1.4 christos uint32_t res; 140 1.1 christos sim_fpu_status status; 141 1.1 christos 142 1.1 christos sim_fpu_32to (&op1, x); 143 1.1 christos status = sim_fpu_abs (&ans, &op1); 144 1.1 christos if (status != 0) 145 1.1 christos (*fpu->ops->error) (fpu, status); 146 1.1 christos sim_fpu_to32 (&res, &ans); 147 1.1 christos 148 1.1 christos return res; 149 1.1 christos } 150 1.1 christos 151 1.1 christos static SF 152 1.1 christos sqrtsf (CGEN_FPU* fpu, SF x) 153 1.1 christos { 154 1.1 christos sim_fpu op1; 155 1.1 christos sim_fpu ans; 156 1.1.1.4 christos uint32_t res; 157 1.1 christos sim_fpu_status status; 158 1.1 christos 159 1.1 christos sim_fpu_32to (&op1, x); 160 1.1 christos status = sim_fpu_sqrt (&ans, &op1); 161 1.1 christos if (status != 0) 162 1.1 christos (*fpu->ops->error) (fpu, status); 163 1.1 christos sim_fpu_to32 (&res, &ans); 164 1.1 christos 165 1.1 christos return res; 166 1.1 christos } 167 1.1 christos 168 1.1 christos static SF 169 1.1 christos invsf (CGEN_FPU* fpu, SF x) 170 1.1 christos { 171 1.1 christos sim_fpu op1; 172 1.1 christos sim_fpu ans; 173 1.1.1.4 christos uint32_t res; 174 1.1 christos sim_fpu_status status; 175 1.1 christos 176 1.1 christos sim_fpu_32to (&op1, x); 177 1.1 christos status = sim_fpu_inv (&ans, &op1); 178 1.1 christos if (status != 0) 179 1.1 christos (*fpu->ops->error) (fpu, status); 180 1.1 christos sim_fpu_to32 (&res, &ans); 181 1.1 christos 182 1.1 christos return res; 183 1.1 christos } 184 1.1 christos 185 1.1 christos static SF 186 1.1 christos minsf (CGEN_FPU* fpu, SF x, SF y) 187 1.1 christos { 188 1.1 christos sim_fpu op1; 189 1.1 christos sim_fpu op2; 190 1.1 christos sim_fpu ans; 191 1.1.1.4 christos uint32_t res; 192 1.1 christos sim_fpu_status status; 193 1.1 christos 194 1.1 christos sim_fpu_32to (&op1, x); 195 1.1 christos sim_fpu_32to (&op2, y); 196 1.1 christos status = sim_fpu_min (&ans, &op1, &op2); 197 1.1 christos if (status != 0) 198 1.1 christos (*fpu->ops->error) (fpu, status); 199 1.1 christos sim_fpu_to32 (&res, &ans); 200 1.1 christos 201 1.1 christos return res; 202 1.1 christos } 203 1.1 christos 204 1.1 christos static SF 205 1.1 christos maxsf (CGEN_FPU* fpu, SF x, SF y) 206 1.1 christos { 207 1.1 christos sim_fpu op1; 208 1.1 christos sim_fpu op2; 209 1.1 christos sim_fpu ans; 210 1.1.1.4 christos uint32_t res; 211 1.1 christos sim_fpu_status status; 212 1.1 christos 213 1.1 christos sim_fpu_32to (&op1, x); 214 1.1 christos sim_fpu_32to (&op2, y); 215 1.1 christos status = sim_fpu_max (&ans, &op1, &op2); 216 1.1 christos if (status != 0) 217 1.1 christos (*fpu->ops->error) (fpu, status); 218 1.1 christos sim_fpu_to32 (&res, &ans); 219 1.1 christos 220 1.1 christos return res; 221 1.1 christos } 222 1.1 christos 223 1.1 christos static CGEN_FP_CMP 224 1.1 christos cmpsf (CGEN_FPU* fpu, SF x, SF y) 225 1.1 christos { 226 1.1 christos sim_fpu op1; 227 1.1 christos sim_fpu op2; 228 1.1 christos 229 1.1 christos sim_fpu_32to (&op1, x); 230 1.1 christos sim_fpu_32to (&op2, y); 231 1.1 christos 232 1.1 christos if (sim_fpu_is_nan (&op1) 233 1.1 christos || sim_fpu_is_nan (&op2)) 234 1.1 christos return FP_CMP_NAN; 235 1.1 christos 236 1.1 christos if (x < y) 237 1.1 christos return FP_CMP_LT; 238 1.1 christos if (x > y) 239 1.1 christos return FP_CMP_GT; 240 1.1 christos return FP_CMP_EQ; 241 1.1 christos } 242 1.1 christos 243 1.1 christos static int 244 1.1 christos eqsf (CGEN_FPU* fpu, SF x, SF y) 245 1.1 christos { 246 1.1 christos sim_fpu op1; 247 1.1 christos sim_fpu op2; 248 1.1 christos 249 1.1 christos sim_fpu_32to (&op1, x); 250 1.1 christos sim_fpu_32to (&op2, y); 251 1.1 christos return sim_fpu_is_eq (&op1, &op2); 252 1.1 christos } 253 1.1 christos 254 1.1 christos static int 255 1.1 christos nesf (CGEN_FPU* fpu, SF x, SF y) 256 1.1 christos { 257 1.1 christos sim_fpu op1; 258 1.1 christos sim_fpu op2; 259 1.1 christos 260 1.1 christos sim_fpu_32to (&op1, x); 261 1.1 christos sim_fpu_32to (&op2, y); 262 1.1 christos return sim_fpu_is_ne (&op1, &op2); 263 1.1 christos } 264 1.1 christos 265 1.1 christos static int 266 1.1 christos ltsf (CGEN_FPU* fpu, SF x, SF y) 267 1.1 christos { 268 1.1 christos sim_fpu op1; 269 1.1 christos sim_fpu op2; 270 1.1 christos 271 1.1 christos sim_fpu_32to (&op1, x); 272 1.1 christos sim_fpu_32to (&op2, y); 273 1.1 christos return sim_fpu_is_lt (&op1, &op2); 274 1.1 christos } 275 1.1 christos 276 1.1 christos static int 277 1.1 christos lesf (CGEN_FPU* fpu, SF x, SF y) 278 1.1 christos { 279 1.1 christos sim_fpu op1; 280 1.1 christos sim_fpu op2; 281 1.1 christos 282 1.1 christos sim_fpu_32to (&op1, x); 283 1.1 christos sim_fpu_32to (&op2, y); 284 1.1 christos return sim_fpu_is_le (&op1, &op2); 285 1.1 christos } 286 1.1 christos 287 1.1 christos static int 288 1.1 christos gtsf (CGEN_FPU* fpu, SF x, SF y) 289 1.1 christos { 290 1.1 christos sim_fpu op1; 291 1.1 christos sim_fpu op2; 292 1.1 christos 293 1.1 christos sim_fpu_32to (&op1, x); 294 1.1 christos sim_fpu_32to (&op2, y); 295 1.1 christos return sim_fpu_is_gt (&op1, &op2); 296 1.1 christos } 297 1.1 christos 298 1.1 christos static int 299 1.1 christos gesf (CGEN_FPU* fpu, SF x, SF y) 300 1.1 christos { 301 1.1 christos sim_fpu op1; 302 1.1 christos sim_fpu op2; 303 1.1 christos 304 1.1 christos sim_fpu_32to (&op1, x); 305 1.1 christos sim_fpu_32to (&op2, y); 306 1.1 christos return sim_fpu_is_ge (&op1, &op2); 307 1.1 christos } 308 1.1 christos 309 1.1.1.3 christos static int 310 1.1.1.3 christos unorderedsf (CGEN_FPU* fpu, SF x, SF y) 311 1.1.1.3 christos { 312 1.1.1.3 christos sim_fpu op1; 313 1.1.1.3 christos sim_fpu op2; 314 1.1.1.3 christos 315 1.1.1.3 christos sim_fpu_32to (&op1, x); 316 1.1.1.3 christos sim_fpu_32to (&op2, y); 317 1.1.1.3 christos return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2); 318 1.1.1.3 christos } 319 1.1.1.3 christos 320 1.1.1.3 christos 321 1.1 christos static DF 322 1.1 christos fextsfdf (CGEN_FPU* fpu, int how UNUSED, SF x) 323 1.1 christos { 324 1.1 christos sim_fpu op1; 325 1.1.1.4 christos uint64_t res; 326 1.1 christos 327 1.1 christos sim_fpu_32to (&op1, x); 328 1.1 christos sim_fpu_to64 (&res, &op1); 329 1.1 christos 330 1.1 christos return res; 331 1.1 christos } 332 1.1 christos 333 1.1 christos static SF 334 1.1 christos ftruncdfsf (CGEN_FPU* fpu, int how UNUSED, DF x) 335 1.1 christos { 336 1.1 christos sim_fpu op1; 337 1.1.1.4 christos uint32_t res; 338 1.1 christos 339 1.1 christos sim_fpu_64to (&op1, x); 340 1.1 christos sim_fpu_to32 (&res, &op1); 341 1.1 christos 342 1.1 christos return res; 343 1.1 christos } 344 1.1 christos 345 1.1 christos static SF 346 1.1 christos floatsisf (CGEN_FPU* fpu, int how UNUSED, SI x) 347 1.1 christos { 348 1.1 christos sim_fpu ans; 349 1.1.1.4 christos uint32_t res; 350 1.1 christos 351 1.1 christos sim_fpu_i32to (&ans, x, sim_fpu_round_near); 352 1.1 christos sim_fpu_to32 (&res, &ans); 353 1.1 christos return res; 354 1.1 christos } 355 1.1 christos 356 1.1 christos static DF 357 1.1 christos floatsidf (CGEN_FPU* fpu, int how UNUSED, SI x) 358 1.1 christos { 359 1.1 christos sim_fpu ans; 360 1.1.1.4 christos uint64_t res; 361 1.1 christos 362 1.1 christos sim_fpu_i32to (&ans, x, sim_fpu_round_near); 363 1.1 christos sim_fpu_to64 (&res, &ans); 364 1.1 christos return res; 365 1.1 christos } 366 1.1 christos 367 1.1.1.3 christos static DF 368 1.1.1.3 christos floatdidf (CGEN_FPU* fpu, int how UNUSED, DI x) 369 1.1.1.3 christos { 370 1.1.1.3 christos sim_fpu ans; 371 1.1.1.4 christos uint64_t res; 372 1.1.1.3 christos 373 1.1.1.3 christos sim_fpu_i64to (&ans, x, sim_fpu_round_near); 374 1.1.1.3 christos sim_fpu_to64 (&res, &ans); 375 1.1.1.3 christos return res; 376 1.1.1.3 christos } 377 1.1.1.3 christos 378 1.1 christos static SF 379 1.1 christos ufloatsisf (CGEN_FPU* fpu, int how UNUSED, USI x) 380 1.1 christos { 381 1.1 christos sim_fpu ans; 382 1.1.1.4 christos uint32_t res; 383 1.1 christos 384 1.1 christos sim_fpu_u32to (&ans, x, sim_fpu_round_near); 385 1.1 christos sim_fpu_to32 (&res, &ans); 386 1.1 christos return res; 387 1.1 christos } 388 1.1 christos 389 1.1 christos static SI 390 1.1 christos fixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x) 391 1.1 christos { 392 1.1 christos sim_fpu op1; 393 1.1.1.4 christos int32_t res; 394 1.1 christos 395 1.1 christos sim_fpu_32to (&op1, x); 396 1.1 christos sim_fpu_to32i (&res, &op1, sim_fpu_round_near); 397 1.1 christos return res; 398 1.1 christos } 399 1.1 christos 400 1.1 christos static SI 401 1.1 christos fixdfsi (CGEN_FPU* fpu, int how UNUSED, DF x) 402 1.1 christos { 403 1.1 christos sim_fpu op1; 404 1.1.1.4 christos int32_t res; 405 1.1 christos 406 1.1 christos sim_fpu_64to (&op1, x); 407 1.1 christos sim_fpu_to32i (&res, &op1, sim_fpu_round_near); 408 1.1 christos return res; 409 1.1 christos } 410 1.1 christos 411 1.1.1.3 christos static DI 412 1.1.1.3 christos fixdfdi (CGEN_FPU* fpu, int how UNUSED, DF x) 413 1.1.1.3 christos { 414 1.1.1.3 christos sim_fpu op1; 415 1.1.1.4 christos int64_t res; 416 1.1.1.3 christos 417 1.1.1.3 christos sim_fpu_64to (&op1, x); 418 1.1.1.3 christos sim_fpu_to64i (&res, &op1, sim_fpu_round_near); 419 1.1.1.3 christos return res; 420 1.1.1.3 christos } 421 1.1.1.3 christos 422 1.1 christos static USI 423 1.1 christos ufixsfsi (CGEN_FPU* fpu, int how UNUSED, SF x) 424 1.1 christos { 425 1.1 christos sim_fpu op1; 426 1.1.1.4 christos uint32_t res; 427 1.1 christos 428 1.1 christos sim_fpu_32to (&op1, x); 429 1.1 christos sim_fpu_to32u (&res, &op1, sim_fpu_round_near); 430 1.1 christos return res; 431 1.1 christos } 432 1.1 christos 433 1.1 christos /* DF mode support */ 435 1.1 christos 436 1.1 christos static DF 437 1.1 christos adddf (CGEN_FPU* fpu, DF x, DF y) 438 1.1 christos { 439 1.1 christos sim_fpu op1; 440 1.1 christos sim_fpu op2; 441 1.1.1.4 christos sim_fpu ans; 442 1.1 christos uint64_t res; 443 1.1 christos sim_fpu_status status; 444 1.1 christos 445 1.1 christos sim_fpu_64to (&op1, x); 446 1.1 christos sim_fpu_64to (&op2, y); 447 1.1 christos status = sim_fpu_add (&ans, &op1, &op2); 448 1.1 christos if (status != 0) 449 1.1 christos (*fpu->ops->error) (fpu, status); 450 1.1 christos sim_fpu_to64 (&res, &ans); 451 1.1 christos 452 1.1 christos return res; 453 1.1 christos } 454 1.1 christos 455 1.1 christos static DF 456 1.1 christos subdf (CGEN_FPU* fpu, DF x, DF y) 457 1.1 christos { 458 1.1 christos sim_fpu op1; 459 1.1 christos sim_fpu op2; 460 1.1.1.4 christos sim_fpu ans; 461 1.1 christos uint64_t res; 462 1.1 christos sim_fpu_status status; 463 1.1 christos 464 1.1 christos sim_fpu_64to (&op1, x); 465 1.1 christos sim_fpu_64to (&op2, y); 466 1.1 christos status = sim_fpu_sub (&ans, &op1, &op2); 467 1.1 christos if (status != 0) 468 1.1 christos (*fpu->ops->error) (fpu, status); 469 1.1 christos sim_fpu_to64 (&res, &ans); 470 1.1 christos 471 1.1 christos return res; 472 1.1 christos } 473 1.1 christos 474 1.1 christos static DF 475 1.1 christos muldf (CGEN_FPU* fpu, DF x, DF y) 476 1.1 christos { 477 1.1 christos sim_fpu op1; 478 1.1 christos sim_fpu op2; 479 1.1.1.4 christos sim_fpu ans; 480 1.1 christos uint64_t res; 481 1.1 christos sim_fpu_status status; 482 1.1 christos 483 1.1 christos sim_fpu_64to (&op1, x); 484 1.1 christos sim_fpu_64to (&op2, y); 485 1.1 christos status = sim_fpu_mul (&ans, &op1, &op2); 486 1.1 christos if (status != 0) 487 1.1 christos (*fpu->ops->error) (fpu, status); 488 1.1 christos sim_fpu_to64 (&res, &ans); 489 1.1 christos 490 1.1 christos return res; 491 1.1 christos } 492 1.1 christos 493 1.1 christos static DF 494 1.1 christos divdf (CGEN_FPU* fpu, DF x, DF y) 495 1.1 christos { 496 1.1 christos sim_fpu op1; 497 1.1 christos sim_fpu op2; 498 1.1.1.4 christos sim_fpu ans; 499 1.1 christos uint64_t res; 500 1.1 christos sim_fpu_status status; 501 1.1 christos 502 1.1 christos sim_fpu_64to (&op1, x); 503 1.1 christos sim_fpu_64to (&op2, y); 504 1.1 christos status = sim_fpu_div (&ans, &op1, &op2); 505 1.1 christos if (status != 0) 506 1.1 christos (*fpu->ops->error) (fpu, status); 507 1.1 christos sim_fpu_to64 (&res, &ans); 508 1.1 christos 509 1.1 christos return res; 510 1.1 christos } 511 1.1 christos 512 1.1.1.2 christos static DF 513 1.1.1.2 christos remdf (CGEN_FPU* fpu, DF x, DF y) 514 1.1.1.2 christos { 515 1.1.1.2 christos sim_fpu op1; 516 1.1.1.2 christos sim_fpu op2; 517 1.1.1.4 christos sim_fpu ans; 518 1.1.1.2 christos uint64_t res; 519 1.1.1.2 christos sim_fpu_status status; 520 1.1.1.2 christos 521 1.1.1.2 christos sim_fpu_64to (&op1, x); 522 1.1.1.2 christos sim_fpu_64to (&op2, y); 523 1.1.1.2 christos status = sim_fpu_rem (&ans, &op1, &op2); 524 1.1.1.2 christos if (status != 0) 525 1.1.1.2 christos (*fpu->ops->error) (fpu, status); 526 1.1.1.2 christos sim_fpu_to64(&res, &ans); 527 1.1.1.2 christos 528 1.1.1.2 christos return res; 529 1.1.1.2 christos } 530 1.1.1.2 christos 531 1.1 christos static DF 532 1.1 christos negdf (CGEN_FPU* fpu, DF x) 533 1.1 christos { 534 1.1 christos sim_fpu op1; 535 1.1.1.4 christos sim_fpu ans; 536 1.1 christos uint64_t res; 537 1.1 christos sim_fpu_status status; 538 1.1 christos 539 1.1 christos sim_fpu_64to (&op1, x); 540 1.1 christos status = sim_fpu_neg (&ans, &op1); 541 1.1 christos if (status != 0) 542 1.1 christos (*fpu->ops->error) (fpu, status); 543 1.1 christos sim_fpu_to64 (&res, &ans); 544 1.1 christos 545 1.1 christos return res; 546 1.1 christos } 547 1.1 christos 548 1.1 christos static DF 549 1.1 christos absdf (CGEN_FPU* fpu, DF x) 550 1.1 christos { 551 1.1 christos sim_fpu op1; 552 1.1.1.4 christos sim_fpu ans; 553 1.1 christos uint64_t res; 554 1.1 christos sim_fpu_status status; 555 1.1 christos 556 1.1 christos sim_fpu_64to (&op1, x); 557 1.1 christos status = sim_fpu_abs (&ans, &op1); 558 1.1 christos if (status != 0) 559 1.1 christos (*fpu->ops->error) (fpu, status); 560 1.1 christos sim_fpu_to64 (&res, &ans); 561 1.1 christos 562 1.1 christos return res; 563 1.1 christos } 564 1.1 christos 565 1.1 christos static DF 566 1.1 christos sqrtdf (CGEN_FPU* fpu, DF x) 567 1.1 christos { 568 1.1 christos sim_fpu op1; 569 1.1.1.4 christos sim_fpu ans; 570 1.1 christos uint64_t res; 571 1.1 christos sim_fpu_status status; 572 1.1 christos 573 1.1 christos sim_fpu_64to (&op1, x); 574 1.1 christos status = sim_fpu_sqrt (&ans, &op1); 575 1.1 christos if (status != 0) 576 1.1 christos (*fpu->ops->error) (fpu, status); 577 1.1 christos sim_fpu_to64 (&res, &ans); 578 1.1 christos 579 1.1 christos return res; 580 1.1 christos } 581 1.1 christos 582 1.1 christos static DF 583 1.1 christos invdf (CGEN_FPU* fpu, DF x) 584 1.1 christos { 585 1.1 christos sim_fpu op1; 586 1.1.1.4 christos sim_fpu ans; 587 1.1 christos uint64_t res; 588 1.1 christos sim_fpu_status status; 589 1.1 christos 590 1.1 christos sim_fpu_64to (&op1, x); 591 1.1 christos status = sim_fpu_inv (&ans, &op1); 592 1.1 christos if (status != 0) 593 1.1 christos (*fpu->ops->error) (fpu, status); 594 1.1 christos sim_fpu_to64 (&res, &ans); 595 1.1 christos 596 1.1 christos return res; 597 1.1 christos } 598 1.1 christos 599 1.1 christos static DF 600 1.1 christos mindf (CGEN_FPU* fpu, DF x, DF y) 601 1.1 christos { 602 1.1 christos sim_fpu op1; 603 1.1 christos sim_fpu op2; 604 1.1.1.4 christos sim_fpu ans; 605 1.1 christos uint64_t res; 606 1.1 christos sim_fpu_status status; 607 1.1 christos 608 1.1 christos sim_fpu_64to (&op1, x); 609 1.1 christos sim_fpu_64to (&op2, y); 610 1.1 christos status = sim_fpu_min (&ans, &op1, &op2); 611 1.1 christos if (status != 0) 612 1.1 christos (*fpu->ops->error) (fpu, status); 613 1.1 christos sim_fpu_to64 (&res, &ans); 614 1.1 christos 615 1.1 christos return res; 616 1.1 christos } 617 1.1 christos 618 1.1 christos static DF 619 1.1 christos maxdf (CGEN_FPU* fpu, DF x, DF y) 620 1.1 christos { 621 1.1 christos sim_fpu op1; 622 1.1 christos sim_fpu op2; 623 1.1.1.4 christos sim_fpu ans; 624 1.1 christos uint64_t res; 625 1.1 christos sim_fpu_status status; 626 1.1 christos 627 1.1 christos sim_fpu_64to (&op1, x); 628 1.1 christos sim_fpu_64to (&op2, y); 629 1.1 christos status = sim_fpu_max (&ans, &op1, &op2); 630 1.1 christos if (status != 0) 631 1.1 christos (*fpu->ops->error) (fpu, status); 632 1.1 christos sim_fpu_to64 (&res, &ans); 633 1.1 christos 634 1.1 christos return res; 635 1.1 christos } 636 1.1 christos 637 1.1 christos static CGEN_FP_CMP 638 1.1 christos cmpdf (CGEN_FPU* fpu, DF x, DF y) 639 1.1 christos { 640 1.1 christos sim_fpu op1; 641 1.1 christos sim_fpu op2; 642 1.1 christos 643 1.1 christos sim_fpu_64to (&op1, x); 644 1.1 christos sim_fpu_64to (&op2, y); 645 1.1 christos 646 1.1 christos if (sim_fpu_is_nan (&op1) 647 1.1 christos || sim_fpu_is_nan (&op2)) 648 1.1 christos return FP_CMP_NAN; 649 1.1 christos 650 1.1 christos if (x < y) 651 1.1 christos return FP_CMP_LT; 652 1.1 christos if (x > y) 653 1.1 christos return FP_CMP_GT; 654 1.1 christos return FP_CMP_EQ; 655 1.1 christos } 656 1.1 christos 657 1.1 christos static int 658 1.1 christos eqdf (CGEN_FPU* fpu, DF x, DF y) 659 1.1 christos { 660 1.1 christos sim_fpu op1; 661 1.1 christos sim_fpu op2; 662 1.1 christos 663 1.1 christos sim_fpu_64to (&op1, x); 664 1.1 christos sim_fpu_64to (&op2, y); 665 1.1 christos return sim_fpu_is_eq (&op1, &op2); 666 1.1 christos } 667 1.1 christos 668 1.1 christos static int 669 1.1 christos nedf (CGEN_FPU* fpu, DF x, DF y) 670 1.1 christos { 671 1.1 christos sim_fpu op1; 672 1.1 christos sim_fpu op2; 673 1.1 christos 674 1.1 christos sim_fpu_64to (&op1, x); 675 1.1 christos sim_fpu_64to (&op2, y); 676 1.1 christos return sim_fpu_is_ne (&op1, &op2); 677 1.1 christos } 678 1.1 christos 679 1.1 christos static int 680 1.1 christos ltdf (CGEN_FPU* fpu, DF x, DF y) 681 1.1 christos { 682 1.1 christos sim_fpu op1; 683 1.1 christos sim_fpu op2; 684 1.1 christos 685 1.1 christos sim_fpu_64to (&op1, x); 686 1.1 christos sim_fpu_64to (&op2, y); 687 1.1 christos return sim_fpu_is_lt (&op1, &op2); 688 1.1 christos } 689 1.1 christos 690 1.1 christos static int 691 1.1 christos ledf (CGEN_FPU* fpu, DF x, DF y) 692 1.1 christos { 693 1.1 christos sim_fpu op1; 694 1.1 christos sim_fpu op2; 695 1.1 christos 696 1.1 christos sim_fpu_64to (&op1, x); 697 1.1 christos sim_fpu_64to (&op2, y); 698 1.1 christos return sim_fpu_is_le (&op1, &op2); 699 1.1 christos } 700 1.1 christos 701 1.1 christos static int 702 1.1 christos gtdf (CGEN_FPU* fpu, DF x, DF y) 703 1.1 christos { 704 1.1 christos sim_fpu op1; 705 1.1 christos sim_fpu op2; 706 1.1 christos 707 1.1 christos sim_fpu_64to (&op1, x); 708 1.1 christos sim_fpu_64to (&op2, y); 709 1.1 christos return sim_fpu_is_gt (&op1, &op2); 710 1.1 christos } 711 1.1 christos 712 1.1 christos static int 713 1.1 christos gedf (CGEN_FPU* fpu, DF x, DF y) 714 1.1 christos { 715 1.1 christos sim_fpu op1; 716 1.1 christos sim_fpu op2; 717 1.1 christos 718 1.1 christos sim_fpu_64to (&op1, x); 719 1.1 christos sim_fpu_64to (&op2, y); 720 1.1 christos return sim_fpu_is_ge (&op1, &op2); 721 1.1.1.3 christos } 722 1.1.1.3 christos 723 1.1.1.3 christos static int 724 1.1.1.3 christos unordereddf (CGEN_FPU* fpu, DF x, DF y) 725 1.1.1.3 christos { 726 1.1.1.3 christos sim_fpu op1; 727 1.1.1.3 christos sim_fpu op2; 728 1.1.1.3 christos 729 1.1.1.3 christos sim_fpu_64to (&op1, x); 730 1.1.1.3 christos sim_fpu_64to (&op2, y); 731 1.1.1.3 christos return sim_fpu_is_nan (&op1) || sim_fpu_is_nan (&op2); 732 1.1 christos } 733 1.1 christos 734 1.1 christos /* Initialize FP_OPS to use accurate library. */ 736 1.1 christos 737 1.1 christos void 738 1.1 christos cgen_init_accurate_fpu (SIM_CPU* cpu, CGEN_FPU* fpu, CGEN_FPU_ERROR_FN* error) 739 1.1 christos { 740 1.1 christos CGEN_FP_OPS* o; 741 1.1 christos 742 1.1 christos fpu->owner = cpu; 743 1.1 christos /* ??? small memory leak, not freed by sim_close */ 744 1.1 christos fpu->ops = (CGEN_FP_OPS*) xmalloc (sizeof (CGEN_FP_OPS)); 745 1.1 christos 746 1.1 christos o = fpu->ops; 747 1.1 christos memset (o, 0, sizeof (*o)); 748 1.1 christos 749 1.1 christos o->error = error; 750 1.1 christos 751 1.1 christos o->addsf = addsf; 752 1.1 christos o->subsf = subsf; 753 1.1.1.2 christos o->mulsf = mulsf; 754 1.1 christos o->divsf = divsf; 755 1.1 christos o->remsf = remsf; 756 1.1 christos o->negsf = negsf; 757 1.1 christos o->abssf = abssf; 758 1.1 christos o->sqrtsf = sqrtsf; 759 1.1 christos o->invsf = invsf; 760 1.1 christos o->minsf = minsf; 761 1.1 christos o->maxsf = maxsf; 762 1.1 christos o->cmpsf = cmpsf; 763 1.1 christos o->eqsf = eqsf; 764 1.1 christos o->nesf = nesf; 765 1.1 christos o->ltsf = ltsf; 766 1.1 christos o->lesf = lesf; 767 1.1.1.3 christos o->gtsf = gtsf; 768 1.1 christos o->gesf = gesf; 769 1.1 christos o->unorderedsf = unorderedsf; 770 1.1 christos 771 1.1 christos o->adddf = adddf; 772 1.1 christos o->subdf = subdf; 773 1.1.1.2 christos o->muldf = muldf; 774 1.1 christos o->divdf = divdf; 775 1.1 christos o->remdf = remdf; 776 1.1 christos o->negdf = negdf; 777 1.1 christos o->absdf = absdf; 778 1.1 christos o->sqrtdf = sqrtdf; 779 1.1 christos o->invdf = invdf; 780 1.1 christos o->mindf = mindf; 781 1.1 christos o->maxdf = maxdf; 782 1.1 christos o->cmpdf = cmpdf; 783 1.1 christos o->eqdf = eqdf; 784 1.1 christos o->nedf = nedf; 785 1.1 christos o->ltdf = ltdf; 786 1.1 christos o->ledf = ledf; 787 1.1.1.3 christos o->gtdf = gtdf; 788 1.1 christos o->gedf = gedf; 789 1.1 christos o->unordereddf = unordereddf; 790 1.1 christos o->fextsfdf = fextsfdf; 791 1.1 christos o->ftruncdfsf = ftruncdfsf; 792 1.1.1.3 christos o->floatsisf = floatsisf; 793 1.1 christos o->floatsidf = floatsidf; 794 1.1 christos o->floatdidf = floatdidf; 795 1.1 christos o->ufloatsisf = ufloatsisf; 796 1.1.1.3 christos o->fixsfsi = fixsfsi; 797 1.1 christos o->fixdfsi = fixdfsi; 798 1.1 christos o->fixdfdi = fixdfdi; 799 o->ufixsfsi = ufixsfsi; 800 } 801