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