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