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