1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (C) 1985-1998 by Symantec 6 * Copyright (C) 2000-2020 by The D Language Foundation, All Rights Reserved 7 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 8 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 9 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/evalu8.d, backend/evalu8.d) 10 */ 11 12 module dmd.backend.evalu8; 13 14 version (SPP) 15 { 16 } 17 else 18 { 19 20 import core.stdc.math; 21 import core.stdc.stdio; 22 import core.stdc.stdlib; 23 import core.stdc..string; 24 static import core.bitop; 25 26 //#if _MSC_VER 27 //#define isnan _isnan 28 //#endif 29 30 import dmd.backend.bcomplex; 31 import dmd.backend.cc; 32 import dmd.backend.cdef; 33 import dmd.backend.oper; 34 import dmd.backend.global; 35 import dmd.backend.el; 36 import dmd.backend.ty; 37 import dmd.backend.type; 38 39 version (SCPP) 40 { 41 import msgs2; 42 import parser; 43 import scopeh; 44 } 45 46 extern (C++): 47 48 nothrow: 49 50 version (MARS) 51 import dmd.backend.errors; 52 53 // fp.c 54 int testFE(); 55 void clearFE(); 56 int statusFE(); 57 bool have_float_except(); 58 59 60 /********************** 61 * Return boolean result of constant elem. 62 */ 63 64 int boolres(elem *e) 65 { int b; 66 67 //printf("boolres()\n"); 68 //elem_print(e); 69 elem_debug(e); 70 assert((statusFE() & 0x3800) == 0); 71 switch (e.Eoper) 72 { 73 case OPrelconst: 74 case OPstring: 75 return true; 76 77 version (SCPP) 78 { 79 case OPvar: 80 assert(CPP && PARSER); 81 el_toconst(e); 82 assert(e.Eoper == OPconst); 83 goto case OPconst; 84 } 85 case OPconst: 86 switch (tybasic(typemask(e))) 87 { case TYchar: 88 case TYuchar: 89 case TYschar: 90 case TYchar16: 91 case TYshort: 92 case TYushort: 93 case TYint: 94 case TYuint: 95 case TYbool: 96 case TYwchar_t: 97 case TYenum: 98 case TYmemptr: 99 case TYlong: 100 case TYulong: 101 case TYdchar: 102 case TYllong: 103 case TYullong: 104 case TYsptr: 105 case TYcptr: 106 case TYhptr: 107 case TYfptr: 108 case TYvptr: 109 case TYnptr: 110 case TYimmutPtr: 111 case TYsharePtr: 112 case TYrestrictPtr: 113 case TYfgPtr: 114 b = el_tolong(e) != 0; 115 break; 116 case TYnref: // reference can't be converted to bool 117 assert(0); 118 119 case TYfloat: 120 case TYifloat: 121 case TYdouble: 122 case TYidouble: 123 case TYdouble_alias: 124 case TYildouble: 125 case TYldouble: 126 { targ_ldouble ld = el_toldoubled(e); 127 128 if (isnan(ld)) 129 b = 1; 130 else 131 b = (ld != 0); 132 break; 133 } 134 case TYcfloat: 135 if (isnan(e.EV.Vcfloat.re) || isnan(e.EV.Vcfloat.im)) 136 b = 1; 137 else 138 b = e.EV.Vcfloat.re != 0 || e.EV.Vcfloat.im != 0; 139 break; 140 case TYcdouble: 141 case TYdouble2: 142 if (isnan(e.EV.Vcdouble.re) || isnan(e.EV.Vcdouble.im)) 143 b = 1; 144 else 145 b = e.EV.Vcdouble.re != 0 || e.EV.Vcdouble.im != 0; 146 break; 147 case TYcldouble: 148 if (isnan(e.EV.Vcldouble.re) || isnan(e.EV.Vcldouble.im)) 149 b = 1; 150 else 151 b = e.EV.Vcldouble.re != 0 || e.EV.Vcldouble.im != 0; 152 break; 153 154 case TYstruct: // happens on syntax error of (struct x)0 155 version (SCPP) 156 { 157 assert(errcnt); 158 goto case TYvoid; 159 } 160 else 161 assert(0); 162 163 case TYvoid: /* happens if we get syntax errors or 164 on RHS of && || expressions */ 165 b = 0; 166 break; 167 168 case TYcent: 169 case TYucent: 170 case TYschar16: 171 case TYuchar16: 172 case TYshort8: 173 case TYushort8: 174 case TYlong4: 175 case TYulong4: 176 case TYllong2: 177 case TYullong2: 178 b = e.EV.Vcent.lsw || e.EV.Vcent.msw; 179 break; 180 181 case TYfloat4: 182 { b = 0; 183 foreach (f; e.EV.Vfloat4) 184 { 185 if (f != 0) 186 { b = 1; 187 break; 188 } 189 } 190 break; 191 } 192 193 case TYschar32: 194 case TYuchar32: 195 case TYshort16: 196 case TYushort16: 197 case TYlong8: 198 case TYulong8: 199 case TYllong4: 200 case TYullong4: 201 b = 0; 202 foreach (elem; e.EV.Vulong8) 203 b |= elem != 0; 204 break; 205 206 case TYfloat8: 207 b = 0; 208 foreach (f; e.EV.Vfloat8) 209 { 210 if (f != 0) 211 { b = 1; 212 break; 213 } 214 } 215 break; 216 217 case TYdouble4: 218 b = 0; 219 foreach (f; e.EV.Vdouble4) 220 { 221 if (f != 0) 222 { b = 1; 223 break; 224 } 225 } 226 break; 227 228 default: 229 break; // can be the result of other errors 230 } 231 break; 232 default: 233 assert(0); 234 } 235 return b; 236 } 237 238 239 /*************************** 240 * Return true if expression will always evaluate to true. 241 */ 242 243 int iftrue(elem *e) 244 { 245 while (1) 246 { 247 assert(e); 248 elem_debug(e); 249 switch (e.Eoper) 250 { case OPcomma: 251 case OPinfo: 252 e = e.EV.E2; 253 break; 254 case OPrelconst: 255 case OPconst: 256 case OPstring: 257 return boolres(e); 258 default: 259 return false; 260 } 261 } 262 } 263 264 /*************************** 265 * Return true if expression will always evaluate to false. 266 */ 267 268 int iffalse(elem *e) 269 { 270 while (1) 271 { assert(e); 272 elem_debug(e); 273 switch (e.Eoper) 274 { case OPcomma: 275 case OPinfo: 276 e = e.EV.E2; 277 break; 278 case OPconst: 279 return !boolres(e); 280 //case OPstring: 281 //case OPrelconst: 282 default: 283 return false; 284 } 285 } 286 } 287 288 289 /****************************** 290 * Evaluate a node with only constants as leaves. 291 * Return with the result. 292 */ 293 294 elem * evalu8(elem *e, goal_t goal) 295 { 296 elem* e1; 297 elem* e2; 298 tym_t tym,tym2,uns; 299 uint op; 300 targ_int i1,i2; 301 targ_llong l1,l2; 302 targ_ldouble d1,d2; 303 elem esave = void; 304 305 static bool unordered(T)(T d1, T d2) { return isnan(d1) || isnan(d2); } 306 307 assert((statusFE() & 0x3800) == 0); 308 assert(e && !OTleaf(e.Eoper)); 309 op = e.Eoper; 310 elem_debug(e); 311 e1 = e.EV.E1; 312 313 //printf("evalu8(): "); elem_print(e); 314 elem_debug(e1); 315 if (e1.Eoper == OPconst && !tyvector(e1.Ety)) 316 { 317 tym2 = 0; 318 e2 = null; 319 if (OTbinary(e.Eoper)) 320 { e2 = e.EV.E2; 321 elem_debug(e2); 322 if (e2.Eoper == OPconst && !tyvector(e2.Ety)) 323 { 324 i2 = cast(targ_int)(l2 = el_tolong(e2)); 325 d2 = el_toldoubled(e2); 326 } 327 else 328 return e; 329 tym2 = tybasic(typemask(e2)); 330 } 331 else 332 { 333 tym2 = 0; 334 e2 = null; 335 i2 = 0; // not used, but static analyzer complains 336 l2 = 0; // " 337 d2 = 0; // " 338 } 339 i1 = cast(targ_int)(l1 = el_tolong(e1)); 340 d1 = el_toldoubled(e1); 341 tym = tybasic(typemask(e1)); /* type of op is type of left child */ 342 343 // Huge pointers are always evaluated at runtime 344 if (tym == TYhptr && (l1 != 0 || l2 != 0)) 345 return e; 346 347 esave = *e; 348 clearFE(); 349 } 350 else 351 return e; 352 353 /* if left or right leaf is unsigned, this is an unsigned operation */ 354 uns = tyuns(tym) | tyuns(tym2); 355 356 /*elem_print(e);*/ 357 /*dbg_printf("x%lx ",l1); WROP(op); dbg_printf("x%lx = ",l2);*/ 358 static if (0) 359 { 360 if (0 && e2) 361 { 362 debug printf("d1 = %Lg, d2 = %Lg, op = %d, OPne = %d, tym = x%lx\n",d1,d2,op,OPne,tym); 363 debug printf("tym1 = x%lx, tym2 = x%lx, e2 = %g\n",tym,tym2,e2.EV.Vdouble); 364 365 eve u; 366 debug printf("d1 = x%16llx\n", (u.Vldouble = d1, u.Vullong)); 367 debug printf("d2 = x%16llx\n", (u.Vldouble = d2, u.Vullong)); 368 } 369 } 370 switch (op) 371 { 372 case OPadd: 373 switch (tym) 374 { 375 case TYfloat: 376 switch (tym2) 377 { 378 case TYfloat: 379 e.EV.Vfloat = e1.EV.Vfloat + e2.EV.Vfloat; 380 break; 381 case TYifloat: 382 e.EV.Vcfloat.re = e1.EV.Vfloat; 383 e.EV.Vcfloat.im = e2.EV.Vfloat; 384 break; 385 case TYcfloat: 386 e.EV.Vcfloat.re = e1.EV.Vfloat + e2.EV.Vcfloat.re; 387 e.EV.Vcfloat.im = 0 + e2.EV.Vcfloat.im; 388 break; 389 default: 390 assert(0); 391 } 392 break; 393 case TYdouble: 394 case TYdouble_alias: 395 switch (tym2) 396 { 397 case TYdouble: 398 case TYdouble_alias: 399 e.EV.Vdouble = e1.EV.Vdouble + e2.EV.Vdouble; 400 break; 401 case TYidouble: 402 e.EV.Vcdouble.re = e1.EV.Vdouble; 403 e.EV.Vcdouble.im = e2.EV.Vdouble; 404 break; 405 case TYcdouble: 406 e.EV.Vcdouble.re = e1.EV.Vdouble + e2.EV.Vcdouble.re; 407 e.EV.Vcdouble.im = 0 + e2.EV.Vcdouble.im; 408 break; 409 default: 410 assert(0); 411 } 412 break; 413 case TYldouble: 414 switch (tym2) 415 { 416 case TYldouble: 417 e.EV.Vldouble = d1 + d2; 418 break; 419 case TYildouble: 420 e.EV.Vcldouble.re = d1; 421 e.EV.Vcldouble.im = d2; 422 break; 423 case TYcldouble: 424 e.EV.Vcldouble.re = d1 + e2.EV.Vcldouble.re; 425 e.EV.Vcldouble.im = 0 + e2.EV.Vcldouble.im; 426 break; 427 default: 428 assert(0); 429 } 430 break; 431 case TYifloat: 432 switch (tym2) 433 { 434 case TYfloat: 435 e.EV.Vcfloat.re = e2.EV.Vfloat; 436 e.EV.Vcfloat.im = e1.EV.Vfloat; 437 break; 438 case TYifloat: 439 e.EV.Vfloat = e1.EV.Vfloat + e2.EV.Vfloat; 440 break; 441 case TYcfloat: 442 e.EV.Vcfloat.re = 0 + e2.EV.Vcfloat.re; 443 e.EV.Vcfloat.im = e1.EV.Vfloat + e2.EV.Vcfloat.im; 444 break; 445 default: 446 assert(0); 447 } 448 break; 449 case TYidouble: 450 switch (tym2) 451 { 452 case TYdouble: 453 e.EV.Vcdouble.re = e2.EV.Vdouble; 454 e.EV.Vcdouble.im = e1.EV.Vdouble; 455 break; 456 case TYidouble: 457 e.EV.Vdouble = e1.EV.Vdouble + e2.EV.Vdouble; 458 break; 459 case TYcdouble: 460 e.EV.Vcdouble.re = 0 + e2.EV.Vcdouble.re; 461 e.EV.Vcdouble.im = e1.EV.Vdouble + e2.EV.Vcdouble.im; 462 break; 463 default: 464 assert(0); 465 } 466 break; 467 case TYildouble: 468 switch (tym2) 469 { 470 case TYldouble: 471 e.EV.Vcldouble.re = d2; 472 e.EV.Vcldouble.im = d1; 473 break; 474 case TYildouble: 475 e.EV.Vldouble = d1 + d2; 476 break; 477 case TYcldouble: 478 e.EV.Vcldouble.re = 0 + e2.EV.Vcldouble.re; 479 e.EV.Vcldouble.im = d1 + e2.EV.Vcldouble.im; 480 break; 481 default: 482 assert(0); 483 } 484 break; 485 case TYcfloat: 486 switch (tym2) 487 { 488 case TYfloat: 489 e.EV.Vcfloat.re = e1.EV.Vcfloat.re + e2.EV.Vfloat; 490 e.EV.Vcfloat.im = e1.EV.Vcfloat.im; 491 break; 492 case TYifloat: 493 e.EV.Vcfloat.re = e1.EV.Vcfloat.re; 494 e.EV.Vcfloat.im = e1.EV.Vcfloat.im + e2.EV.Vfloat; 495 break; 496 case TYcfloat: 497 e.EV.Vcfloat.re = e1.EV.Vcfloat.re + e2.EV.Vcfloat.re; 498 e.EV.Vcfloat.im = e1.EV.Vcfloat.im + e2.EV.Vcfloat.im; 499 break; 500 default: 501 assert(0); 502 } 503 break; 504 case TYcdouble: 505 switch (tym2) 506 { 507 case TYdouble: 508 e.EV.Vcdouble.re = e1.EV.Vcdouble.re + e2.EV.Vdouble; 509 e.EV.Vcdouble.im = e1.EV.Vcdouble.im; 510 break; 511 case TYidouble: 512 e.EV.Vcdouble.re = e1.EV.Vcdouble.re; 513 e.EV.Vcdouble.im = e1.EV.Vcdouble.im + e2.EV.Vdouble; 514 break; 515 case TYcdouble: 516 e.EV.Vcdouble.re = e1.EV.Vcdouble.re + e2.EV.Vcdouble.re; 517 e.EV.Vcdouble.im = e1.EV.Vcdouble.im + e2.EV.Vcdouble.im; 518 break; 519 default: 520 assert(0); 521 } 522 break; 523 case TYcldouble: 524 switch (tym2) 525 { 526 case TYldouble: 527 e.EV.Vcldouble.re = e1.EV.Vcldouble.re + d2; 528 e.EV.Vcldouble.im = e1.EV.Vcldouble.im; 529 break; 530 case TYildouble: 531 e.EV.Vcldouble.re = e1.EV.Vcldouble.re; 532 e.EV.Vcldouble.im = e1.EV.Vcldouble.im + d2; 533 break; 534 case TYcldouble: 535 e.EV.Vcldouble.re = e1.EV.Vcldouble.re + e2.EV.Vcldouble.re; 536 e.EV.Vcldouble.im = e1.EV.Vcldouble.im + e2.EV.Vcldouble.im; 537 break; 538 default: 539 assert(0); 540 } 541 break; 542 543 default: 544 if (_tysize[TYint] == 2) 545 { if (tyfv(tym)) 546 e.EV.Vlong = cast(targ_long)((l1 & 0xFFFF0000) | 547 cast(targ_ushort) (cast(targ_ushort) l1 + i2)); 548 else if (tyfv(tym2)) 549 e.EV.Vlong = cast(targ_long)((l2 & 0xFFFF0000) | 550 cast(targ_ushort) (i1 + cast(targ_ushort) l2)); 551 else if (tyintegral(tym) || typtr(tym)) 552 e.EV.Vllong = l1 + l2; 553 else 554 assert(0); 555 } 556 else if (tyintegral(tym) || typtr(tym)) 557 e.EV.Vllong = l1 + l2; 558 else 559 assert(0); 560 break; 561 } 562 break; 563 564 case OPmin: 565 switch (tym) 566 { 567 case TYfloat: 568 switch (tym2) 569 { 570 case TYfloat: 571 e.EV.Vfloat = e1.EV.Vfloat - e2.EV.Vfloat; 572 break; 573 case TYifloat: 574 e.EV.Vcfloat.re = e1.EV.Vfloat; 575 e.EV.Vcfloat.im = -e2.EV.Vfloat; 576 break; 577 case TYcfloat: 578 e.EV.Vcfloat.re = e1.EV.Vfloat - e2.EV.Vcfloat.re; 579 e.EV.Vcfloat.im = 0 - e2.EV.Vcfloat.im; 580 break; 581 default: 582 assert(0); 583 } 584 break; 585 case TYdouble: 586 case TYdouble_alias: 587 switch (tym2) 588 { 589 case TYdouble: 590 case TYdouble_alias: 591 e.EV.Vdouble = e1.EV.Vdouble - e2.EV.Vdouble; 592 break; 593 case TYidouble: 594 e.EV.Vcdouble.re = e1.EV.Vdouble; 595 e.EV.Vcdouble.im = -e2.EV.Vdouble; 596 break; 597 case TYcdouble: 598 e.EV.Vcdouble.re = e1.EV.Vdouble - e2.EV.Vcdouble.re; 599 e.EV.Vcdouble.im = 0 - e2.EV.Vcdouble.im; 600 break; 601 default: 602 assert(0); 603 } 604 break; 605 case TYldouble: 606 switch (tym2) 607 { 608 case TYldouble: 609 e.EV.Vldouble = d1 - d2; 610 break; 611 case TYildouble: 612 e.EV.Vcldouble.re = d1; 613 e.EV.Vcldouble.im = -d2; 614 break; 615 case TYcldouble: 616 e.EV.Vcldouble.re = d1 - e2.EV.Vcldouble.re; 617 e.EV.Vcldouble.im = 0 - e2.EV.Vcldouble.im; 618 break; 619 default: 620 assert(0); 621 } 622 break; 623 case TYifloat: 624 switch (tym2) 625 { 626 case TYfloat: 627 e.EV.Vcfloat.re = -e2.EV.Vfloat; 628 e.EV.Vcfloat.im = e1.EV.Vfloat; 629 break; 630 case TYifloat: 631 e.EV.Vfloat = e1.EV.Vfloat - e2.EV.Vfloat; 632 break; 633 case TYcfloat: 634 e.EV.Vcfloat.re = 0 - e2.EV.Vcfloat.re; 635 e.EV.Vcfloat.im = e1.EV.Vfloat - e2.EV.Vcfloat.im; 636 break; 637 default: 638 assert(0); 639 } 640 break; 641 case TYidouble: 642 switch (tym2) 643 { 644 case TYdouble: 645 e.EV.Vcdouble.re = -e2.EV.Vdouble; 646 e.EV.Vcdouble.im = e1.EV.Vdouble; 647 break; 648 case TYidouble: 649 e.EV.Vdouble = e1.EV.Vdouble - e2.EV.Vdouble; 650 break; 651 case TYcdouble: 652 e.EV.Vcdouble.re = 0 - e2.EV.Vcdouble.re; 653 e.EV.Vcdouble.im = e1.EV.Vdouble - e2.EV.Vcdouble.im; 654 break; 655 default: 656 assert(0); 657 } 658 break; 659 case TYildouble: 660 switch (tym2) 661 { 662 case TYldouble: 663 e.EV.Vcldouble.re = -d2; 664 e.EV.Vcldouble.im = d1; 665 break; 666 case TYildouble: 667 e.EV.Vldouble = d1 - d2; 668 break; 669 case TYcldouble: 670 e.EV.Vcldouble.re = 0 - e2.EV.Vcldouble.re; 671 e.EV.Vcldouble.im = d1 - e2.EV.Vcldouble.im; 672 break; 673 default: 674 assert(0); 675 } 676 break; 677 case TYcfloat: 678 switch (tym2) 679 { 680 case TYfloat: 681 e.EV.Vcfloat.re = e1.EV.Vcfloat.re - e2.EV.Vfloat; 682 e.EV.Vcfloat.im = e1.EV.Vcfloat.im; 683 break; 684 case TYifloat: 685 e.EV.Vcfloat.re = e1.EV.Vcfloat.re; 686 e.EV.Vcfloat.im = e1.EV.Vcfloat.im - e2.EV.Vfloat; 687 break; 688 case TYcfloat: 689 e.EV.Vcfloat.re = e1.EV.Vcfloat.re - e2.EV.Vcfloat.re; 690 e.EV.Vcfloat.im = e1.EV.Vcfloat.im - e2.EV.Vcfloat.im; 691 break; 692 default: 693 assert(0); 694 } 695 break; 696 case TYcdouble: 697 switch (tym2) 698 { 699 case TYdouble: 700 e.EV.Vcdouble.re = e1.EV.Vcdouble.re - e2.EV.Vdouble; 701 e.EV.Vcdouble.im = e1.EV.Vcdouble.im; 702 break; 703 case TYidouble: 704 e.EV.Vcdouble.re = e1.EV.Vcdouble.re; 705 e.EV.Vcdouble.im = e1.EV.Vcdouble.im - e2.EV.Vdouble; 706 break; 707 case TYcdouble: 708 e.EV.Vcdouble.re = e1.EV.Vcdouble.re - e2.EV.Vcdouble.re; 709 e.EV.Vcdouble.im = e1.EV.Vcdouble.im - e2.EV.Vcdouble.im; 710 break; 711 default: 712 assert(0); 713 } 714 break; 715 case TYcldouble: 716 switch (tym2) 717 { 718 case TYldouble: 719 e.EV.Vcldouble.re = e1.EV.Vcldouble.re - d2; 720 e.EV.Vcldouble.im = e1.EV.Vcldouble.im; 721 break; 722 case TYildouble: 723 e.EV.Vcldouble.re = e1.EV.Vcldouble.re; 724 e.EV.Vcldouble.im = e1.EV.Vcldouble.im - d2; 725 break; 726 case TYcldouble: 727 e.EV.Vcldouble.re = e1.EV.Vcldouble.re - e2.EV.Vcldouble.re; 728 e.EV.Vcldouble.im = e1.EV.Vcldouble.im - e2.EV.Vcldouble.im; 729 break; 730 default: 731 assert(0); 732 } 733 break; 734 735 default: 736 if (_tysize[TYint] == 2 && 737 tyfv(tym) && _tysize[tym2] == 2) 738 e.EV.Vllong = (l1 & 0xFFFF0000) | 739 cast(targ_ushort) (cast(targ_ushort) l1 - i2); 740 else if (tyintegral(tym) || typtr(tym)) 741 e.EV.Vllong = l1 - l2; 742 else 743 assert(0); 744 break; 745 } 746 break; 747 case OPmul: 748 if (tyintegral(tym) || typtr(tym)) 749 e.EV.Vllong = l1 * l2; 750 else 751 { switch (tym) 752 { 753 case TYfloat: 754 switch (tym2) 755 { 756 case TYfloat: 757 case TYifloat: 758 e.EV.Vfloat = e1.EV.Vfloat * e2.EV.Vfloat; 759 break; 760 case TYcfloat: 761 e.EV.Vcfloat.re = e1.EV.Vfloat * e2.EV.Vcfloat.re; 762 e.EV.Vcfloat.im = e1.EV.Vfloat * e2.EV.Vcfloat.im; 763 break; 764 default: 765 assert(0); 766 } 767 break; 768 case TYdouble: 769 case TYdouble_alias: 770 switch (tym2) 771 { 772 case TYdouble: 773 case TYdouble_alias: 774 case TYidouble: 775 e.EV.Vdouble = e1.EV.Vdouble * e2.EV.Vdouble; 776 break; 777 case TYcdouble: 778 e.EV.Vcdouble.re = e1.EV.Vdouble * e2.EV.Vcdouble.re; 779 e.EV.Vcdouble.im = e1.EV.Vdouble * e2.EV.Vcdouble.im; 780 break; 781 default: 782 assert(0); 783 } 784 break; 785 case TYldouble: 786 switch (tym2) 787 { 788 case TYldouble: 789 case TYildouble: 790 e.EV.Vldouble = d1 * d2; 791 break; 792 case TYcldouble: 793 e.EV.Vcldouble.re = d1 * e2.EV.Vcldouble.re; 794 e.EV.Vcldouble.im = d1 * e2.EV.Vcldouble.im; 795 break; 796 default: 797 assert(0); 798 } 799 break; 800 case TYifloat: 801 switch (tym2) 802 { 803 case TYfloat: 804 e.EV.Vfloat = e1.EV.Vfloat * e2.EV.Vfloat; 805 break; 806 case TYifloat: 807 e.EV.Vfloat = -e1.EV.Vfloat * e2.EV.Vfloat; 808 break; 809 case TYcfloat: 810 e.EV.Vcfloat.re = -e1.EV.Vfloat * e2.EV.Vcfloat.im; 811 e.EV.Vcfloat.im = e1.EV.Vfloat * e2.EV.Vcfloat.re; 812 break; 813 default: 814 assert(0); 815 } 816 break; 817 case TYidouble: 818 switch (tym2) 819 { 820 case TYdouble: 821 e.EV.Vdouble = e1.EV.Vdouble * e2.EV.Vdouble; 822 break; 823 case TYidouble: 824 e.EV.Vdouble = -e1.EV.Vdouble * e2.EV.Vdouble; 825 break; 826 case TYcdouble: 827 e.EV.Vcdouble.re = -e1.EV.Vdouble * e2.EV.Vcdouble.im; 828 e.EV.Vcdouble.im = e1.EV.Vdouble * e2.EV.Vcdouble.re; 829 break; 830 default: 831 assert(0); 832 } 833 break; 834 case TYildouble: 835 switch (tym2) 836 { 837 case TYldouble: 838 e.EV.Vldouble = d1 * d2; 839 break; 840 case TYildouble: 841 e.EV.Vldouble = -d1 * d2; 842 break; 843 case TYcldouble: 844 e.EV.Vcldouble.re = -d1 * e2.EV.Vcldouble.im; 845 e.EV.Vcldouble.im = d1 * e2.EV.Vcldouble.re; 846 break; 847 default: 848 assert(0); 849 } 850 break; 851 case TYcfloat: 852 switch (tym2) 853 { 854 case TYfloat: 855 e.EV.Vcfloat.re = e1.EV.Vcfloat.re * e2.EV.Vfloat; 856 e.EV.Vcfloat.im = e1.EV.Vcfloat.im * e2.EV.Vfloat; 857 break; 858 case TYifloat: 859 e.EV.Vcfloat.re = -e1.EV.Vcfloat.im * e2.EV.Vfloat; 860 e.EV.Vcfloat.im = e1.EV.Vcfloat.re * e2.EV.Vfloat; 861 break; 862 case TYcfloat: 863 e.EV.Vcfloat = Complex_f.mul(e1.EV.Vcfloat, e2.EV.Vcfloat); 864 break; 865 default: 866 assert(0); 867 } 868 break; 869 case TYcdouble: 870 switch (tym2) 871 { 872 case TYdouble: 873 e.EV.Vcdouble.re = e1.EV.Vcdouble.re * e2.EV.Vdouble; 874 e.EV.Vcdouble.im = e1.EV.Vcdouble.im * e2.EV.Vdouble; 875 break; 876 case TYidouble: 877 e.EV.Vcdouble.re = -e1.EV.Vcdouble.im * e2.EV.Vdouble; 878 e.EV.Vcdouble.im = e1.EV.Vcdouble.re * e2.EV.Vdouble; 879 break; 880 case TYcdouble: 881 e.EV.Vcdouble = Complex_d.mul(e1.EV.Vcdouble, e2.EV.Vcdouble); 882 break; 883 default: 884 assert(0); 885 } 886 break; 887 case TYcldouble: 888 switch (tym2) 889 { 890 case TYldouble: 891 e.EV.Vcldouble.re = e1.EV.Vcldouble.re * d2; 892 e.EV.Vcldouble.im = e1.EV.Vcldouble.im * d2; 893 break; 894 case TYildouble: 895 e.EV.Vcldouble.re = -e1.EV.Vcldouble.im * d2; 896 e.EV.Vcldouble.im = e1.EV.Vcldouble.re * d2; 897 break; 898 case TYcldouble: 899 e.EV.Vcldouble = Complex_ld.mul(e1.EV.Vcldouble, e2.EV.Vcldouble); 900 break; 901 default: 902 assert(0); 903 } 904 break; 905 default: 906 debug printf("tym = x%x\n",tym); 907 debug elem_print(e); 908 assert(0); 909 } 910 } 911 break; 912 case OPdiv: 913 if (!boolres(e2)) // divide by 0 914 { 915 if (!tyfloating(tym)) 916 goto div0; 917 } 918 if (uns) 919 e.EV.Vullong = (cast(targ_ullong) l1) / (cast(targ_ullong) l2); 920 else 921 { switch (tym) 922 { 923 case TYfloat: 924 switch (tym2) 925 { 926 case TYfloat: 927 e.EV.Vfloat = e1.EV.Vfloat / e2.EV.Vfloat; 928 break; 929 case TYifloat: 930 e.EV.Vfloat = -e1.EV.Vfloat / e2.EV.Vfloat; 931 break; 932 case TYcfloat: 933 e.EV.Vcfloat.re = cast(float)d1; 934 e.EV.Vcfloat.im = 0; 935 e.EV.Vcfloat = Complex_f.div(e.EV.Vcfloat, e2.EV.Vcfloat); 936 break; 937 default: 938 assert(0); 939 } 940 break; 941 case TYdouble: 942 case TYdouble_alias: 943 switch (tym2) 944 { 945 case TYdouble: 946 case TYdouble_alias: 947 e.EV.Vdouble = e1.EV.Vdouble / e2.EV.Vdouble; 948 break; 949 case TYidouble: 950 e.EV.Vdouble = -e1.EV.Vdouble / e2.EV.Vdouble; 951 break; 952 case TYcdouble: 953 e.EV.Vcdouble.re = cast(double)d1; 954 e.EV.Vcdouble.im = 0; 955 e.EV.Vcdouble = Complex_d.div(e.EV.Vcdouble, e2.EV.Vcdouble); 956 break; 957 default: 958 assert(0); 959 } 960 break; 961 case TYldouble: 962 switch (tym2) 963 { 964 case TYldouble: 965 e.EV.Vldouble = d1 / d2; 966 break; 967 case TYildouble: 968 e.EV.Vldouble = -d1 / d2; 969 break; 970 case TYcldouble: 971 e.EV.Vcldouble.re = d1; 972 e.EV.Vcldouble.im = 0; 973 e.EV.Vcldouble = Complex_ld.div(e.EV.Vcldouble, e2.EV.Vcldouble); 974 break; 975 default: 976 assert(0); 977 } 978 break; 979 case TYifloat: 980 switch (tym2) 981 { 982 case TYfloat: 983 case TYifloat: 984 e.EV.Vfloat = e1.EV.Vfloat / e2.EV.Vfloat; 985 break; 986 case TYcfloat: 987 e.EV.Vcfloat.re = 0; 988 e.EV.Vcfloat.im = e1.EV.Vfloat; 989 e.EV.Vcfloat = Complex_f.div(e.EV.Vcfloat, e2.EV.Vcfloat); 990 break; 991 default: 992 assert(0); 993 } 994 break; 995 case TYidouble: 996 switch (tym2) 997 { 998 case TYdouble: 999 case TYidouble: 1000 e.EV.Vdouble = e1.EV.Vdouble / e2.EV.Vdouble; 1001 break; 1002 case TYcdouble: 1003 e.EV.Vcdouble.re = 0; 1004 e.EV.Vcdouble.im = e1.EV.Vdouble; 1005 e.EV.Vcdouble = Complex_d.div(e.EV.Vcdouble, e2.EV.Vcdouble); 1006 break; 1007 default: 1008 assert(0); 1009 } 1010 break; 1011 case TYildouble: 1012 switch (tym2) 1013 { 1014 case TYldouble: 1015 case TYildouble: 1016 e.EV.Vldouble = d1 / d2; 1017 break; 1018 case TYcldouble: 1019 e.EV.Vcldouble.re = 0; 1020 e.EV.Vcldouble.im = d1; 1021 e.EV.Vcldouble = Complex_ld.div(e.EV.Vcldouble, e2.EV.Vcldouble); 1022 break; 1023 default: 1024 assert(0); 1025 } 1026 break; 1027 case TYcfloat: 1028 switch (tym2) 1029 { 1030 case TYfloat: 1031 e.EV.Vcfloat.re = e1.EV.Vcfloat.re / e2.EV.Vfloat; 1032 e.EV.Vcfloat.im = e1.EV.Vcfloat.im / e2.EV.Vfloat; 1033 break; 1034 case TYifloat: 1035 e.EV.Vcfloat.re = e1.EV.Vcfloat.im / e2.EV.Vfloat; 1036 e.EV.Vcfloat.im = -e1.EV.Vcfloat.re / e2.EV.Vfloat; 1037 break; 1038 case TYcfloat: 1039 e.EV.Vcfloat = Complex_f.div(e1.EV.Vcfloat, e2.EV.Vcfloat); 1040 break; 1041 default: 1042 assert(0); 1043 } 1044 break; 1045 case TYcdouble: 1046 switch (tym2) 1047 { 1048 case TYdouble: 1049 e.EV.Vcdouble.re = e1.EV.Vcdouble.re / e2.EV.Vdouble; 1050 e.EV.Vcdouble.im = e1.EV.Vcdouble.im / e2.EV.Vdouble; 1051 break; 1052 case TYidouble: 1053 e.EV.Vcdouble.re = e1.EV.Vcdouble.im / e2.EV.Vdouble; 1054 e.EV.Vcdouble.im = -e1.EV.Vcdouble.re / e2.EV.Vdouble; 1055 break; 1056 case TYcdouble: 1057 e.EV.Vcdouble = Complex_d.div(e1.EV.Vcdouble, e2.EV.Vcdouble); 1058 break; 1059 default: 1060 assert(0); 1061 } 1062 break; 1063 case TYcldouble: 1064 switch (tym2) 1065 { 1066 case TYldouble: 1067 e.EV.Vcldouble.re = e1.EV.Vcldouble.re / d2; 1068 e.EV.Vcldouble.im = e1.EV.Vcldouble.im / d2; 1069 break; 1070 case TYildouble: 1071 e.EV.Vcldouble.re = e1.EV.Vcldouble.im / d2; 1072 e.EV.Vcldouble.im = -e1.EV.Vcldouble.re / d2; 1073 break; 1074 case TYcldouble: 1075 e.EV.Vcldouble = Complex_ld.div(e1.EV.Vcldouble, e2.EV.Vcldouble); 1076 break; 1077 default: 1078 assert(0); 1079 } 1080 break; 1081 default: 1082 e.EV.Vllong = l1 / l2; 1083 break; 1084 } 1085 } 1086 break; 1087 case OPmod: 1088 version (MARS) 1089 { 1090 if (!tyfloating(tym)) 1091 { 1092 if (!boolres(e2)) 1093 { 1094 div0: 1095 error(e.Esrcpos.Sfilename, e.Esrcpos.Slinnum, e.Esrcpos.Scharnum, "divide by zero"); 1096 break; 1097 } 1098 } 1099 } 1100 else 1101 { 1102 if (1) 1103 { 1104 if (!boolres(e2)) 1105 { 1106 div0: 1107 version (SCPP) 1108 synerr(EM_divby0); 1109 break; 1110 } 1111 } 1112 } 1113 if (uns) 1114 e.EV.Vullong = (cast(targ_ullong) l1) % (cast(targ_ullong) l2); 1115 else 1116 { 1117 // BUG: what do we do for imaginary, complex? 1118 switch (tym) 1119 { case TYdouble: 1120 case TYidouble: 1121 case TYdouble_alias: 1122 e.EV.Vdouble = fmod(e1.EV.Vdouble,e2.EV.Vdouble); 1123 break; 1124 case TYfloat: 1125 case TYifloat: 1126 e.EV.Vfloat = fmodf(e1.EV.Vfloat,e2.EV.Vfloat); 1127 break; 1128 case TYldouble: 1129 case TYildouble: 1130 e.EV.Vldouble = _modulo(d1, d2); 1131 break; 1132 case TYcfloat: 1133 switch (tym2) 1134 { 1135 case TYfloat: 1136 case TYifloat: 1137 e.EV.Vcfloat.re = fmodf(e1.EV.Vcfloat.re, e2.EV.Vfloat); 1138 e.EV.Vcfloat.im = fmodf(e1.EV.Vcfloat.im, e2.EV.Vfloat); 1139 break; 1140 default: 1141 assert(0); 1142 } 1143 break; 1144 case TYcdouble: 1145 switch (tym2) 1146 { 1147 case TYdouble: 1148 case TYidouble: 1149 e.EV.Vcdouble.re = fmod(e1.EV.Vcdouble.re, e2.EV.Vdouble); 1150 e.EV.Vcdouble.im = fmod(e1.EV.Vcdouble.im, e2.EV.Vdouble); 1151 break; 1152 default: 1153 assert(0); 1154 } 1155 break; 1156 case TYcldouble: 1157 switch (tym2) 1158 { 1159 case TYldouble: 1160 case TYildouble: 1161 e.EV.Vcldouble.re = _modulo(e1.EV.Vcldouble.re, d2); 1162 e.EV.Vcldouble.im = _modulo(e1.EV.Vcldouble.im, d2); 1163 break; 1164 default: 1165 assert(0); 1166 } 1167 break; 1168 default: 1169 e.EV.Vllong = l1 % l2; 1170 break; 1171 } 1172 } 1173 break; 1174 case OPremquo: 1175 { 1176 targ_llong rem, quo; 1177 1178 assert(!tyfloating(tym)); 1179 if (!boolres(e2)) 1180 goto div0; 1181 if (uns) 1182 { 1183 rem = (cast(targ_ullong) l1) % (cast(targ_ullong) l2); 1184 quo = (cast(targ_ullong) l1) / (cast(targ_ullong) l2); 1185 } 1186 else 1187 { 1188 rem = l1 % l2; 1189 quo = l1 / l2; 1190 } 1191 switch (tysize(tym)) 1192 { 1193 case 2: 1194 e.EV.Vllong = (rem << 16) | (quo & 0xFFFF); 1195 break; 1196 case 4: 1197 e.EV.Vllong = (rem << 32) | (quo & 0xFFFFFFFF); 1198 break; 1199 case 8: 1200 e.EV.Vcent.lsw = quo; 1201 e.EV.Vcent.msw = rem; 1202 break; 1203 default: 1204 assert(0); 1205 } 1206 break; 1207 } 1208 case OPand: 1209 e.EV.Vllong = l1 & l2; 1210 break; 1211 case OPor: 1212 e.EV.Vllong = l1 | l2; 1213 break; 1214 case OPxor: 1215 e.EV.Vllong = l1 ^ l2; 1216 break; 1217 case OPnot: 1218 e.EV.Vint = boolres(e1) ^ true; 1219 break; 1220 case OPcom: 1221 e.EV.Vllong = ~l1; 1222 break; 1223 case OPcomma: 1224 e.EV = e2.EV; 1225 break; 1226 case OPoror: 1227 e.EV.Vint = boolres(e1) || boolres(e2); 1228 break; 1229 case OPandand: 1230 e.EV.Vint = boolres(e1) && boolres(e2); 1231 break; 1232 case OPshl: 1233 if (cast(targ_ullong) i2 < targ_ullong.sizeof * 8) 1234 e.EV.Vllong = l1 << i2; 1235 else 1236 e.EV.Vllong = 0; 1237 break; 1238 case OPshr: 1239 if (cast(targ_ullong) i2 > targ_ullong.sizeof * 8) 1240 i2 = targ_ullong.sizeof * 8; 1241 version (SCPP) 1242 { 1243 if (tyuns(tym)) 1244 { //printf("unsigned\n"); 1245 e.EV.Vullong = (cast(targ_ullong) l1) >> i2; 1246 } 1247 else 1248 { //printf("signed\n"); 1249 e.EV.Vllong = l1 >> i2; 1250 } 1251 } 1252 version (MARS) 1253 { 1254 // Always unsigned 1255 e.EV.Vullong = (cast(targ_ullong) l1) >> i2; 1256 } 1257 break; 1258 1259 case OPbtst: 1260 if (cast(targ_ullong) i2 > targ_ullong.sizeof * 8) 1261 i2 = targ_ullong.sizeof * 8; 1262 e.EV.Vullong = ((cast(targ_ullong) l1) >> i2) & 1; 1263 break; 1264 1265 version (MARS) 1266 { 1267 case OPashr: 1268 if (cast(targ_ullong) i2 > targ_ullong.sizeof * 8) 1269 i2 = targ_ullong.sizeof * 8; 1270 // Always signed 1271 e.EV.Vllong = l1 >> i2; 1272 break; 1273 } 1274 1275 case OPpair: 1276 switch (tysize(e.Ety)) 1277 { 1278 case 4: 1279 e.EV.Vlong = (i2 << 16) | (i1 & 0xFFFF); 1280 break; 1281 case 8: 1282 if (tyfloating(tym)) 1283 { 1284 e.EV.Vcfloat.re = cast(float)d1; 1285 e.EV.Vcfloat.im = cast(float)d2; 1286 } 1287 else 1288 e.EV.Vllong = (l2 << 32) | (l1 & 0xFFFFFFFF); 1289 break; 1290 case 16: 1291 if (tyfloating(tym)) 1292 { 1293 e.EV.Vcdouble.re = cast(double)d1; 1294 e.EV.Vcdouble.im = cast(double)d2; 1295 } 1296 else 1297 { 1298 e.EV.Vcent.lsw = l1; 1299 e.EV.Vcent.msw = l2; 1300 } 1301 break; 1302 1303 case -1: // can happen for TYstruct 1304 return e; // don't const fold it 1305 1306 default: 1307 if (tyfloating(tym)) 1308 { 1309 e.EV.Vcldouble.re = d1; 1310 e.EV.Vcldouble.im = d2; 1311 } 1312 else 1313 { 1314 elem_print(e); 1315 assert(0); 1316 } 1317 break; 1318 } 1319 break; 1320 1321 case OPrpair: 1322 switch (tysize(e.Ety)) 1323 { 1324 case 4: 1325 e.EV.Vlong = (i1 << 16) | (i2 & 0xFFFF); 1326 break; 1327 case 8: 1328 e.EV.Vllong = (l1 << 32) | (l2 & 0xFFFFFFFF); 1329 if (tyfloating(tym)) 1330 { 1331 e.EV.Vcfloat.re = cast(float)d2; 1332 e.EV.Vcfloat.im = cast(float)d1; 1333 } 1334 else 1335 e.EV.Vllong = (l1 << 32) | (l2 & 0xFFFFFFFF); 1336 break; 1337 case 16: 1338 if (tyfloating(tym)) 1339 { 1340 e.EV.Vcdouble.re = cast(double)d2; 1341 e.EV.Vcdouble.im = cast(double)d1; 1342 } 1343 else 1344 { 1345 e.EV.Vcent.lsw = l2; 1346 e.EV.Vcent.msw = l1; 1347 } 1348 break; 1349 default: 1350 if (tyfloating(tym)) 1351 { 1352 e.EV.Vcldouble.re = d2; 1353 e.EV.Vcldouble.im = d1; 1354 } 1355 else 1356 { 1357 assert(0); 1358 } 1359 break; 1360 } 1361 break; 1362 1363 case OPneg: 1364 // Avoid converting NANS to NAN 1365 memcpy(&e.EV.Vcldouble,&e1.EV.Vcldouble,e.EV.Vcldouble.sizeof); 1366 switch (tym) 1367 { case TYdouble: 1368 case TYidouble: 1369 case TYdouble_alias: 1370 e.EV.Vdouble = -e.EV.Vdouble; 1371 break; 1372 case TYfloat: 1373 case TYifloat: 1374 e.EV.Vfloat = -e.EV.Vfloat; 1375 break; 1376 case TYldouble: 1377 case TYildouble: 1378 e.EV.Vldouble = -e.EV.Vldouble; 1379 break; 1380 case TYcfloat: 1381 e.EV.Vcfloat.re = -e.EV.Vcfloat.re; 1382 e.EV.Vcfloat.im = -e.EV.Vcfloat.im; 1383 break; 1384 case TYcdouble: 1385 e.EV.Vcdouble.re = -e.EV.Vcdouble.re; 1386 e.EV.Vcdouble.im = -e.EV.Vcdouble.im; 1387 break; 1388 case TYcldouble: 1389 e.EV.Vcldouble.re = -e.EV.Vcldouble.re; 1390 e.EV.Vcldouble.im = -e.EV.Vcldouble.im; 1391 break; 1392 default: 1393 e.EV.Vllong = -l1; 1394 break; 1395 } 1396 break; 1397 case OPabs: 1398 switch (tym) 1399 { 1400 case TYdouble: 1401 case TYidouble: 1402 case TYdouble_alias: 1403 e.EV.Vdouble = fabs(e1.EV.Vdouble); 1404 break; 1405 case TYfloat: 1406 case TYifloat: 1407 version (DigitalMars) 1408 e.EV.Vfloat = fabsf(e1.EV.Vfloat); 1409 else 1410 e.EV.Vfloat = fabs(e1.EV.Vfloat); 1411 1412 break; 1413 case TYldouble: 1414 case TYildouble: 1415 e.EV.Vldouble = fabsl(d1); 1416 break; 1417 case TYcfloat: 1418 e.EV.Vfloat = cast(float)Complex_f.abs(e1.EV.Vcfloat); 1419 break; 1420 case TYcdouble: 1421 e.EV.Vdouble = cast(double)Complex_d.abs(e1.EV.Vcdouble); 1422 break; 1423 case TYcldouble: 1424 e.EV.Vldouble = Complex_ld.abs(e1.EV.Vcldouble); 1425 break; 1426 default: 1427 e.EV.Vllong = l1 < 0 ? -l1 : l1; 1428 break; 1429 } 1430 break; 1431 1432 case OPsqrt: 1433 case OPsin: 1434 case OPcos: 1435 case OPrndtol: 1436 case OPrint: 1437 return e; 1438 1439 case OPngt: 1440 case OPgt: 1441 if (!tyfloating(tym)) 1442 goto Lnle; 1443 e.EV.Vint = (op == OPngt) ^ (d1 > d2); 1444 break; 1445 1446 case OPnle: 1447 Lnle: 1448 case OPle: 1449 { 1450 int b; 1451 if (uns) 1452 { 1453 b = cast(int)((cast(targ_ullong) l1) <= (cast(targ_ullong) l2)); 1454 } 1455 else 1456 { 1457 if (tyfloating(tym)) 1458 b = cast(int)(!unordered(d1, d2) && d1 <= d2); 1459 else 1460 b = cast(int)(l1 <= l2); 1461 } 1462 e.EV.Vint = (op != OPle) ^ b; 1463 break; 1464 } 1465 1466 case OPnge: 1467 case OPge: 1468 if (!tyfloating(tym)) 1469 goto Lnlt; 1470 e.EV.Vint = (op == OPnge) ^ (!unordered(d1, d2) && d1 >= d2); 1471 break; 1472 1473 case OPnlt: 1474 Lnlt: 1475 case OPlt: 1476 { 1477 int b; 1478 if (uns) 1479 { 1480 b = cast(int)((cast(targ_ullong) l1) < (cast(targ_ullong) l2)); 1481 } 1482 else 1483 { 1484 if (tyfloating(tym)) 1485 b = cast(int)(!unordered(d1, d2) && d1 < d2); 1486 else 1487 b = cast(int)(l1 < l2); 1488 } 1489 e.EV.Vint = (op != OPlt) ^ b; 1490 break; 1491 } 1492 1493 case OPne: 1494 case OPeqeq: 1495 { 1496 int b; 1497 if (tyfloating(tym)) 1498 { 1499 switch (tybasic(tym)) 1500 { 1501 case TYcfloat: 1502 if (isnan(e1.EV.Vcfloat.re) || isnan(e1.EV.Vcfloat.im) || 1503 isnan(e2.EV.Vcfloat.re) || isnan(e2.EV.Vcfloat.im)) 1504 b = 0; 1505 else 1506 b = cast(int)((e1.EV.Vcfloat.re == e2.EV.Vcfloat.re) && 1507 (e1.EV.Vcfloat.im == e2.EV.Vcfloat.im)); 1508 break; 1509 case TYcdouble: 1510 if (isnan(e1.EV.Vcdouble.re) || isnan(e1.EV.Vcdouble.im) || 1511 isnan(e2.EV.Vcdouble.re) || isnan(e2.EV.Vcdouble.im)) 1512 b = 0; 1513 else 1514 b = cast(int)((e1.EV.Vcdouble.re == e2.EV.Vcdouble.re) && 1515 (e1.EV.Vcdouble.im == e2.EV.Vcdouble.im)); 1516 break; 1517 case TYcldouble: 1518 if (isnan(e1.EV.Vcldouble.re) || isnan(e1.EV.Vcldouble.im) || 1519 isnan(e2.EV.Vcldouble.re) || isnan(e2.EV.Vcldouble.im)) 1520 b = 0; 1521 else 1522 b = cast(int)((e1.EV.Vcldouble.re == e2.EV.Vcldouble.re) && 1523 (e1.EV.Vcldouble.im == e2.EV.Vcldouble.im)); 1524 break; 1525 default: 1526 b = cast(int)(d1 == d2); 1527 break; 1528 } 1529 //printf("%Lg + %Lgi, %Lg + %Lgi\n", e1.EV.Vcldouble.re, e1.EV.Vcldouble.im, e2.EV.Vcldouble.re, e2.EV.Vcldouble.im); 1530 } 1531 else 1532 b = cast(int)(l1 == l2); 1533 e.EV.Vint = (op == OPne) ^ b; 1534 break; 1535 } 1536 1537 case OPord: 1538 case OPunord: 1539 // BUG: complex numbers 1540 e.EV.Vint = (op == OPord) ^ (unordered(d1, d2)); // !<>= 1541 break; 1542 1543 case OPnlg: 1544 case OPlg: 1545 // BUG: complex numbers 1546 e.EV.Vint = (op == OPnlg) ^ (!unordered(d1, d2) && d1 != d2); // <> 1547 break; 1548 1549 case OPnleg: 1550 case OPleg: 1551 // BUG: complex numbers 1552 e.EV.Vint = (op == OPnleg) ^ (!unordered(d1, d2)); // <>= 1553 break; 1554 1555 case OPnule: 1556 case OPule: 1557 // BUG: complex numbers 1558 e.EV.Vint = (op == OPnule) ^ (unordered(d1, d2) || d1 <= d2); // !> 1559 break; 1560 1561 case OPnul: 1562 case OPul: 1563 // BUG: complex numbers 1564 e.EV.Vint = (op == OPnul) ^ (unordered(d1, d2) || d1 < d2); // !>= 1565 break; 1566 1567 case OPnuge: 1568 case OPuge: 1569 // BUG: complex numbers 1570 e.EV.Vint = (op == OPnuge) ^ (unordered(d1, d2) || d1 >= d2); // !< 1571 break; 1572 1573 case OPnug: 1574 case OPug: 1575 // BUG: complex numbers 1576 e.EV.Vint = (op == OPnug) ^ (unordered(d1, d2) || d1 > d2); // !<= 1577 break; 1578 1579 case OPnue: 1580 case OPue: 1581 // BUG: complex numbers 1582 e.EV.Vint = (op == OPnue) ^ (unordered(d1, d2) || d1 == d2); // !<> 1583 break; 1584 1585 case OPs16_32: 1586 e.EV.Vlong = cast(targ_short) i1; 1587 break; 1588 case OPnp_fp: 1589 case OPu16_32: 1590 e.EV.Vulong = cast(targ_ushort) i1; 1591 break; 1592 case OPd_u32: 1593 e.EV.Vulong = cast(targ_ulong)d1; 1594 //printf("OPd_u32: dbl = %g, ulng = x%lx\n",d1,e.EV.Vulong); 1595 break; 1596 case OPd_s32: 1597 e.EV.Vlong = cast(targ_long)d1; 1598 break; 1599 case OPu32_d: 1600 e.EV.Vdouble = cast(uint) l1; 1601 break; 1602 case OPs32_d: 1603 e.EV.Vdouble = cast(int) l1; 1604 break; 1605 case OPd_s16: 1606 e.EV.Vint = cast(targ_int)d1; 1607 break; 1608 case OPs16_d: 1609 e.EV.Vdouble = cast(targ_short) i1; 1610 break; 1611 case OPd_u16: 1612 e.EV.Vushort = cast(targ_ushort)d1; 1613 break; 1614 case OPu16_d: 1615 e.EV.Vdouble = cast(targ_ushort) i1; 1616 break; 1617 case OPd_s64: 1618 e.EV.Vllong = cast(targ_llong)d1; 1619 break; 1620 case OPd_u64: 1621 case OPld_u64: 1622 e.EV.Vullong = cast(targ_ullong)d1; 1623 break; 1624 case OPs64_d: 1625 e.EV.Vdouble = l1; 1626 break; 1627 case OPu64_d: 1628 e.EV.Vdouble = cast(targ_ullong) l1; 1629 break; 1630 case OPd_f: 1631 assert((statusFE() & 0x3800) == 0); 1632 e.EV.Vfloat = e1.EV.Vdouble; 1633 if (tycomplex(tym)) 1634 e.EV.Vcfloat.im = e1.EV.Vcdouble.im; 1635 assert((statusFE() & 0x3800) == 0); 1636 break; 1637 case OPf_d: 1638 e.EV.Vdouble = e1.EV.Vfloat; 1639 if (tycomplex(tym)) 1640 e.EV.Vcdouble.im = e1.EV.Vcfloat.im; 1641 break; 1642 case OPd_ld: 1643 e.EV.Vldouble = e1.EV.Vdouble; 1644 if (tycomplex(tym)) 1645 e.EV.Vcldouble.im = e1.EV.Vcdouble.im; 1646 break; 1647 case OPld_d: 1648 e.EV.Vdouble = cast(double)e1.EV.Vldouble; 1649 if (tycomplex(tym)) 1650 e.EV.Vcdouble.im = cast(double)e1.EV.Vcldouble.im; 1651 break; 1652 case OPc_r: 1653 e.EV = e1.EV; 1654 break; 1655 case OPc_i: 1656 switch (tym) 1657 { 1658 case TYcfloat: 1659 e.EV.Vfloat = e1.EV.Vcfloat.im; 1660 break; 1661 case TYcdouble: 1662 e.EV.Vdouble = e1.EV.Vcdouble.im; 1663 break; 1664 case TYcldouble: 1665 e.EV.Vldouble = e1.EV.Vcldouble.im; 1666 break; 1667 default: 1668 assert(0); 1669 } 1670 break; 1671 case OPs8_16: 1672 e.EV.Vint = cast(targ_schar) i1; 1673 break; 1674 case OPu8_16: 1675 e.EV.Vint = i1 & 0xFF; 1676 break; 1677 case OP16_8: 1678 e.EV.Vint = i1; 1679 break; 1680 case OPbool: 1681 e.EV.Vint = boolres(e1); 1682 break; 1683 case OP32_16: 1684 case OPoffset: 1685 e.EV.Vint = cast(targ_int)l1; 1686 break; 1687 1688 case OP64_32: 1689 e.EV.Vlong = cast(targ_long)l1; 1690 break; 1691 case OPs32_64: 1692 e.EV.Vllong = cast(targ_long) l1; 1693 break; 1694 case OPu32_64: 1695 e.EV.Vllong = cast(targ_ulong) l1; 1696 break; 1697 1698 case OP128_64: 1699 e.EV.Vllong = e1.EV.Vcent.lsw; 1700 break; 1701 case OPs64_128: 1702 e.EV.Vcent.lsw = e1.EV.Vllong; 1703 e.EV.Vcent.msw = 0; 1704 if (cast(targ_llong)e.EV.Vcent.lsw < 0) 1705 e.EV.Vcent.msw = ~cast(targ_ullong)0; 1706 break; 1707 case OPu64_128: 1708 e.EV.Vcent.lsw = e1.EV.Vullong; 1709 e.EV.Vcent.msw = 0; 1710 break; 1711 1712 case OPmsw: 1713 switch (tysize(tym)) 1714 { 1715 case 4: 1716 e.EV.Vllong = (l1 >> 16) & 0xFFFF; 1717 break; 1718 case 8: 1719 e.EV.Vllong = (l1 >> 32) & 0xFFFFFFFF; 1720 break; 1721 case 16: 1722 e.EV.Vllong = e1.EV.Vcent.msw; 1723 break; 1724 default: 1725 assert(0); 1726 } 1727 break; 1728 case OPb_8: 1729 e.EV.Vlong = i1 & 1; 1730 break; 1731 case OPbswap: 1732 e.EV.Vint = core.bitop.bswap(cast(uint) i1); 1733 break; 1734 1735 case OPpopcnt: 1736 { 1737 // Eliminate any unwanted sign extension 1738 switch (tysize(tym)) 1739 { 1740 case 1: l1 &= 0xFF; break; 1741 case 2: l1 &= 0xFFFF; break; 1742 case 4: l1 &= 0xFFFFFFFF; break; 1743 case 8: break; 1744 default: assert(0); 1745 } 1746 e.EV.Vllong = core.bitop.popcnt(cast(ulong) l1); 1747 break; 1748 } 1749 1750 case OProl: 1751 case OPror: 1752 { uint n = i2; 1753 if (op == OPror) 1754 n = -n; 1755 switch (tysize(tym)) 1756 { 1757 case 1: 1758 n &= 7; 1759 e.EV.Vuchar = cast(ubyte)((i1 << n) | ((i1 & 0xFF) >> (8 - n))); 1760 break; 1761 case 2: 1762 n &= 0xF; 1763 e.EV.Vushort = cast(targ_ushort)((i1 << n) | ((i1 & 0xFFFF) >> (16 - n))); 1764 break; 1765 case 4: 1766 n &= 0x1F; 1767 e.EV.Vulong = cast(targ_ulong)((i1 << n) | ((i1 & 0xFFFFFFFF) >> (32 - n))); 1768 break; 1769 case 8: 1770 n &= 0x3F; 1771 e.EV.Vullong = cast(targ_ullong)((l1 << n) | ((l1 & 0xFFFFFFFFFFFFFFFFL) >> (64 - n))); 1772 break; 1773 //case 16: 1774 default: 1775 assert(0); 1776 } 1777 break; 1778 } 1779 case OPind: 1780 static if (0) // && MARS 1781 { 1782 /* The problem with this is that although the only reaching definition 1783 * of the variable is null, it still may never get executed, as in: 1784 * int* p = null; if (p) *p = 3; 1785 * and the error will be spurious. 1786 */ 1787 if (l1 >= 0 && l1 < 4096) 1788 { 1789 error(e.Esrcpos.Sfilename, e.Esrcpos.Slinnum, e.Esrcpos.Scharnum, 1790 "dereference of null pointer"); 1791 e.EV.E1.EV.Vlong = 4096; // suppress redundant messages 1792 } 1793 } 1794 return e; 1795 1796 case OPvecfill: 1797 switch (tybasic(e.Ety)) 1798 { 1799 // 16 byte vectors 1800 case TYfloat4: 1801 foreach (ref lhsElem; e.EV.Vfloat4) 1802 lhsElem = e1.EV.Vfloat; 1803 break; 1804 case TYdouble2: 1805 foreach (ref lhsElem; e.EV.Vdouble2) 1806 lhsElem = e1.EV.Vdouble; 1807 break; 1808 case TYschar16: 1809 case TYuchar16: 1810 foreach (ref lhsElem; e.EV.Vuchar16) 1811 lhsElem = cast(targ_uchar)i1; 1812 break; 1813 case TYshort8: 1814 case TYushort8: 1815 foreach (ref lhsElem; e.EV.Vushort8) 1816 lhsElem = cast(targ_ushort)i1; 1817 break; 1818 case TYlong4: 1819 case TYulong4: 1820 foreach (ref lhsElem; e.EV.Vulong4) 1821 lhsElem = cast(targ_ulong)i1; 1822 break; 1823 case TYllong2: 1824 case TYullong2: 1825 foreach (ref lhsElem; e.EV.Vullong2) 1826 lhsElem = cast(targ_ullong)l1; 1827 break; 1828 1829 // 32 byte vectors 1830 case TYfloat8: 1831 foreach (ref lhsElem; e.EV.Vfloat8) 1832 lhsElem = e1.EV.Vfloat; 1833 break; 1834 case TYdouble4: 1835 foreach (ref lhsElem; e.EV.Vdouble4) 1836 lhsElem = e1.EV.Vdouble; 1837 break; 1838 case TYschar32: 1839 case TYuchar32: 1840 foreach (ref lhsElem; e.EV.Vuchar32) 1841 lhsElem = cast(targ_uchar)i1; 1842 break; 1843 case TYshort16: 1844 case TYushort16: 1845 foreach (ref lhsElem; e.EV.Vushort16) 1846 lhsElem = cast(targ_ushort)i1; 1847 break; 1848 case TYlong8: 1849 case TYulong8: 1850 foreach (ref lhsElem; e.EV.Vulong8) 1851 lhsElem = cast(targ_ulong)i1; 1852 break; 1853 case TYllong4: 1854 case TYullong4: 1855 foreach (ref lhsElem; e.EV.Vullong4) 1856 lhsElem = cast(targ_ullong)l1; 1857 break; 1858 1859 default: 1860 assert(0); 1861 } 1862 break; 1863 1864 default: 1865 return e; 1866 } 1867 1868 int flags; 1869 1870 if (!(goal & GOALignore_exceptions) && 1871 (config.flags4 & CFG4fastfloat) == 0 && testFE() && 1872 (have_float_except() || tyfloating(tym) || tyfloating(tybasic(typemask(e)))) 1873 ) 1874 { 1875 // Exceptions happened. Do not fold the constants. 1876 *e = esave; 1877 return e; 1878 } 1879 else 1880 { 1881 version (SCPP) 1882 { 1883 if ((flags = statusFE()) & 0x3F) 1884 { // Should also give diagnostic warning for: 1885 // overflow, underflow, denormal, invalid 1886 if (flags & 0x04) 1887 warerr(WM.WM_divby0); 1888 // else if (flags & 0x08) // overflow 1889 // warerr(WM.WM_badnumber); 1890 } 1891 } 1892 } 1893 1894 /*debug printf("result = x%lx\n",e.EV.Vlong);*/ 1895 e.Eoper = OPconst; 1896 el_free(e1); 1897 if (e2) 1898 el_free(e2); 1899 //printf("2: %x\n", statusFE()); 1900 assert((statusFE() & 0x3800) == 0); 1901 //printf("evalu8() returns: "); elem_print(e); 1902 return e; 1903 } 1904 1905 /****************************** 1906 * This is the same as the one in el.c, but uses native D reals 1907 * instead of the soft long double ones. 1908 */ 1909 1910 extern (D) targ_ldouble el_toldoubled(elem *e) 1911 { 1912 targ_ldouble result; 1913 1914 elem_debug(e); 1915 assert(e.Eoper == OPconst); 1916 switch (tybasic(typemask(e))) 1917 { 1918 case TYfloat: 1919 case TYifloat: 1920 result = e.EV.Vfloat; 1921 break; 1922 case TYdouble: 1923 case TYidouble: 1924 case TYdouble_alias: 1925 result = e.EV.Vdouble; 1926 break; 1927 case TYldouble: 1928 case TYildouble: 1929 result = e.EV.Vldouble; 1930 break; 1931 default: 1932 result = 0; 1933 break; 1934 } 1935 return result; 1936 } 1937 1938 /*************************************** 1939 * Copy of _modulo from fp.c. Here to help with linking problems. 1940 */ 1941 version (CRuntime_Microsoft) 1942 { 1943 extern (D) private targ_ldouble _modulo(targ_ldouble x, targ_ldouble y) 1944 { 1945 return cast(targ_ldouble)fmodl(cast(real)x, cast(real)y); 1946 } 1947 import core.stdc.math : isnan; 1948 static if (!is(targ_ldouble == real)) 1949 extern (D) private int isnan(targ_ldouble x) 1950 { 1951 return isnan(cast(real)x); 1952 } 1953 import core.stdc.math : fabsl; 1954 import dmd.root.longdouble : fabsl; // needed if longdouble is longdouble_soft 1955 } 1956 else 1957 { 1958 targ_ldouble _modulo(targ_ldouble x, targ_ldouble y); 1959 } 1960 }