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