PageRenderTime 52ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/src/backend/evalu8.c

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