PageRenderTime 103ms CodeModel.GetById 48ms RepoModel.GetById 7ms 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

Large files files are truncated, but you can click here to view the full file

  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);

Large files files are truncated, but you can click here to view the full file