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