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