PageRenderTime 65ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/backend/evalu8.c

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