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