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