PageRenderTime 63ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/dev/dmd2/src/dmd/backend/evalu8.c

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