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