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