PageRenderTime 66ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/backend/evalu8.c

https://github.com/revellian/dmd
C | 2067 lines | 1891 code | 86 blank | 90 comment | 247 complexity | b4ec17752d349e625e283357d9cab577 MD5 | raw file
Possible License(s): AGPL-1.0

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-2011 by Digital Mars
  3. // All Rights Reserved
  4. // http://www.digitalmars.com
  5. // Written by Walter Bright
  6. /*
  7. * This source file is made available for personal use
  8. * only. The license is in /dmd/src/dmd/backendlicense.txt
  9. * or /dm/src/dmd/backendlicense.txt
  10. * For any other uses, please contact Digital Mars.
  11. */
  12. #if !SPP
  13. #include <math.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <float.h>
  18. #include <time.h>
  19. #if !defined(__OpenBSD__)
  20. // Mysteriously missing from OpenBSD
  21. #include <fenv.h>
  22. #endif
  23. #if __DMC__
  24. #include <fp.h>
  25. #endif
  26. #if __FreeBSD__ || __OpenBSD__
  27. #define fmodl fmod
  28. #endif
  29. #include "cc.h"
  30. #include "oper.h" /* OPxxxx definitions */
  31. #include "global.h"
  32. #include "el.h"
  33. #include "type.h"
  34. #if SCPP
  35. #include "parser.h"
  36. #include "cpp.h"
  37. #endif
  38. static char __file__[] = __FILE__; /* for tassert.h */
  39. #include "tassert.h"
  40. extern void error(const char *filename, unsigned linnum, const char *format, ...);
  41. #if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
  42. int _status87()
  43. {
  44. return fetestexcept(FE_ALL_EXCEPT);
  45. }
  46. void _clear87()
  47. {
  48. feclearexcept(FE_ALL_EXCEPT);
  49. }
  50. #endif
  51. CEXTERN elem * evalu8(elem *);
  52. /* When this !=0, we do constant folding on floating point constants
  53. * even if they raise overflow, underflow, invalid, etc. exceptions.
  54. */
  55. static int ignore_exceptions;
  56. /* When this is !=0, we try to fold out OPsizeof expressions.
  57. */
  58. static int resolve_sizeof;
  59. /************************************
  60. * Helper to do % for long doubles.
  61. */
  62. #if __DMC__
  63. long double _modulo(long double x, long double y)
  64. { short sw;
  65. __asm
  66. {
  67. fld tbyte ptr y
  68. fld tbyte ptr x // ST = x, ST1 = y
  69. FM1: // We don't use fprem1 because for some inexplicable
  70. // reason we get -5 when we do _modulo(15, 10)
  71. fprem // ST = ST % ST1
  72. fstsw word ptr sw
  73. fwait
  74. mov AH,byte ptr sw+1 // get msb of status word in AH
  75. sahf // transfer to flags
  76. jp FM1 // continue till ST < ST1
  77. fstp ST(1) // leave remainder on stack
  78. }
  79. }
  80. #endif
  81. /**********************
  82. * Return boolean result of constant elem.
  83. */
  84. HINT boolres(elem *e)
  85. { int b;
  86. //printf("boolres()\n");
  87. //elem_print(e);
  88. elem_debug(e);
  89. // assert((_status87() & 0x3800) == 0);
  90. switch (e->Eoper)
  91. {
  92. case OPrelconst:
  93. case OPstring:
  94. return TRUE;
  95. #if SCPP
  96. case OPvar:
  97. assert(CPP && PARSER);
  98. el_toconst(e);
  99. assert(e->Eoper == OPconst);
  100. #endif
  101. case OPconst:
  102. switch (tybasic(typemask(e)))
  103. { case TYchar:
  104. case TYuchar:
  105. case TYschar:
  106. case TYchar16:
  107. case TYshort:
  108. case TYushort:
  109. case TYint:
  110. case TYuint:
  111. case TYbool:
  112. case TYwchar_t:
  113. case TYenum:
  114. #if !MARS
  115. case TYmemptr:
  116. #endif
  117. case TYlong:
  118. case TYulong:
  119. case TYdchar:
  120. case TYllong:
  121. case TYullong:
  122. #if JHANDLE
  123. case TYjhandle:
  124. #endif
  125. #if TARGET_SEGMENTED
  126. case TYsptr:
  127. case TYcptr:
  128. case TYhptr:
  129. case TYfptr:
  130. case TYvptr:
  131. #endif
  132. case TYnptr:
  133. b = el_tolong(e) != 0;
  134. break;
  135. case TYfloat:
  136. case TYifloat:
  137. case TYdouble:
  138. case TYidouble:
  139. case TYdouble_alias:
  140. case TYildouble:
  141. case TYldouble:
  142. { targ_ldouble ld = el_toldouble(e);
  143. if (isnan((double)ld))
  144. b = 1;
  145. else
  146. b = (ld != 0);
  147. break;
  148. }
  149. case TYcfloat:
  150. if (isnan(e->EV.Vcfloat.re) || isnan(e->EV.Vcfloat.im))
  151. b = 1;
  152. else
  153. b = e->EV.Vcfloat.re != 0 || e->EV.Vcfloat.im != 0;
  154. break;
  155. case TYcdouble:
  156. if (isnan(e->EV.Vcdouble.re) || isnan(e->EV.Vcdouble.im))
  157. b = 1;
  158. else
  159. b = e->EV.Vcdouble.re != 0 || e->EV.Vcdouble.im != 0;
  160. break;
  161. case TYcldouble:
  162. if (isnan(e->EV.Vcldouble.re) || isnan(e->EV.Vcldouble.im))
  163. b = 1;
  164. else
  165. b = e->EV.Vcldouble.re != 0 || e->EV.Vcldouble.im != 0;
  166. break;
  167. case TYstruct: // happens on syntax error of (struct x)0
  168. #if SCPP
  169. assert(errcnt);
  170. #else
  171. assert(0);
  172. #endif
  173. case TYvoid: /* happens if we get syntax errors or
  174. on RHS of && || expressions */
  175. b = 0;
  176. break;
  177. case TYcent:
  178. case TYucent:
  179. b = e->EV.Vcent.lsw || e->EV.Vcent.msw;
  180. break;
  181. default:
  182. #ifdef DEBUG
  183. WRTYxx(typemask(e));
  184. #endif
  185. assert(0);
  186. }
  187. break;
  188. default:
  189. assert(0);
  190. }
  191. return b;
  192. }
  193. /***************************
  194. * Return TRUE if expression will always evaluate to TRUE.
  195. */
  196. HINT iftrue(elem *e)
  197. {
  198. while (1)
  199. {
  200. assert(e);
  201. elem_debug(e);
  202. switch (e->Eoper)
  203. { case OPcomma:
  204. case OPinfo:
  205. e = e->E2;
  206. break;
  207. case OPrelconst:
  208. case OPconst:
  209. case OPstring:
  210. return boolres(e);
  211. default:
  212. return FALSE;
  213. }
  214. }
  215. }
  216. /***************************
  217. * Return TRUE if expression will always evaluate to FALSE.
  218. */
  219. HINT iffalse(elem *e)
  220. {
  221. while (1)
  222. { assert(e);
  223. elem_debug(e);
  224. switch (e->Eoper)
  225. { case OPcomma:
  226. case OPinfo:
  227. e = e->E2;
  228. break;
  229. case OPconst:
  230. return !boolres(e);
  231. //case OPstring:
  232. //case OPrelconst:
  233. default:
  234. return FALSE;
  235. }
  236. }
  237. }
  238. /******************************
  239. * Constant fold expression tree.
  240. * Calculate &symbol and &*e1 if we can.
  241. */
  242. #if SCPP
  243. elem *poptelem2(elem *e)
  244. {
  245. // Same as poptelem(), but we ignore floating point exceptions
  246. ignore_exceptions++;
  247. e = poptelem(e);
  248. ignore_exceptions--;
  249. return e;
  250. }
  251. elem *poptelem3(elem *e)
  252. {
  253. resolve_sizeof++;
  254. e = poptelem(e);
  255. resolve_sizeof--;
  256. return e;
  257. }
  258. elem *poptelem4(elem *e)
  259. {
  260. resolve_sizeof++;
  261. ignore_exceptions++;
  262. e = poptelem(e);
  263. ignore_exceptions--;
  264. resolve_sizeof--;
  265. return e;
  266. }
  267. elem *poptelem(elem *e)
  268. {
  269. elem *e1,*e2;
  270. unsigned op;
  271. //dbg_printf("poptelem(e = %p)\n", e); elem_print(e);
  272. #ifdef DEBUG
  273. assert(PARSER);
  274. assert(e && e->ET);
  275. if (controlc_saw)
  276. exit(1);
  277. // static int xxx; if (++xxx == 1000) *(char *)0 = 0;
  278. #endif
  279. elem_debug(e);
  280. type_debug(e->ET);
  281. op = e->Eoper;
  282. #ifdef DEBUG
  283. if (OTunary(op))
  284. assert(!e->E2 || op == OPinfo);
  285. #endif
  286. switch (op)
  287. {
  288. case OPvar:
  289. if (CPP && e->EV.sp.Vsym->Sflags & SFLvalue)
  290. el_toconst(e);
  291. break;
  292. case OPsizeof:
  293. if (resolve_sizeof)
  294. {
  295. e->Eoper = OPconst;
  296. e->EV.Vlong = type_size(e->EV.sp.Vsym->Stype);
  297. }
  298. break;
  299. case OPconst:
  300. case OPrelconst:
  301. case OPstring:
  302. break;
  303. case OPaddr:
  304. e1 = e->E1;
  305. if (e1->Eoper == OPvar)
  306. goto L3;
  307. e->E1 = e1 = poptelem(e1);
  308. if (e1->Eoper == OPind) /* if &*exp */
  309. { type *t;
  310. L6:
  311. t = e->ET;
  312. e1->E1 = cast(e1->E1,t);
  313. e = selecte1(selecte1(e,t),t);
  314. }
  315. else if (e1->Eoper == OPvar)
  316. { /* convert &var to relconst */
  317. L3:
  318. e = selecte1(e,e->ET);
  319. e->Eoper = OPrelconst;
  320. #if 1
  321. // If this is an address of a function template,
  322. // try to expand the template if it's got an explicit
  323. // parameter list.
  324. if (e->PEFflags & PEFtemplate_id)
  325. { symbol *s;
  326. s = e->EV.sp.Vsym;
  327. s = cpp_lookformatch(s, NULL, NULL,NULL,NULL,NULL,
  328. e->EV.sp.spu.Vtal, 1|8, NULL, NULL);
  329. if (s)
  330. {
  331. e->EV.sp.Vsym = s;
  332. param_free(&e->EV.sp.spu.Vtal);
  333. e->PEFflags &= ~PEFtemplate_id;
  334. type_settype(&e->ET, newpointer(s->Stype));
  335. }
  336. }
  337. #endif
  338. }
  339. break;
  340. case OPind:
  341. e->E1 = e1 = poptelem(e->E1);
  342. #if TX86
  343. if (e1->Eoper == OPrelconst)
  344. { /* convert *(&var) to var */
  345. e = selecte1(e,e->ET);
  346. e->Eoper = OPvar;
  347. }
  348. #else
  349. if (e1->Eoper == OPrelconst)
  350. {
  351. unsigned to_sz = tysize(tym_conv(e->ET));
  352. unsigned frm_sz = tysize(tym_conv(e1->ET));
  353. if (tyfunc(tybasic(e->ET->Tty)))
  354. to_sz = LONGSIZE;
  355. else if (tybasic(e->ET->Tty) == TYstruct || tybasic(e->ET->Tty) == TYarray)
  356. {
  357. to_sz = LONGSIZE;
  358. e1->ET = e->ET;
  359. }
  360. if(to_sz == frm_sz)
  361. { /* convert *(&var) to var */
  362. doit:
  363. e = selecte1(e,e->ET);
  364. e->Eoper = OPvar;
  365. }
  366. else /* handle the most common cases for now */
  367. { unsigned offset = e1->Eoffset;
  368. switch(to_sz)
  369. {
  370. case SHORTSIZE:
  371. if (frm_sz == LONGSIZE && (offset%LONGSIZE) == SHORTSIZE)
  372. goto doit;
  373. break;
  374. case CHARSIZE:
  375. if (frm_sz == LONGSIZE &&
  376. offset%(LONGSIZE-CHARSIZE) == CHARSIZE)
  377. goto doit;
  378. if (frm_sz == SHORTSIZE && offset&1)
  379. goto doit;
  380. break;
  381. }
  382. }
  383. }
  384. #endif
  385. break;
  386. #if TX86
  387. case OPnp_fp:
  388. e->E1 = e1 = poptelem(e->E1);
  389. // If casting a non-NULL constant pointer
  390. if (e1->Eoper == OPconst && el_tolong(e1) != 0)
  391. break;
  392. goto L5;
  393. case OPoffset:
  394. e->E1 = e1 = poptelem(e->E1);
  395. if (e1->Eoper == OPnp_fp)
  396. goto L6;
  397. goto L5;
  398. #endif
  399. case OP32_16:
  400. e->E1 = e1 = poptelem(e->E1);
  401. L5:
  402. if (e1->Eoper == OPrelconst || e1->Eoper == OPstring)
  403. e = selecte1(e,e->ET);
  404. else
  405. goto eval;
  406. break;
  407. case OPandand:
  408. e->E1 = e1 = poptelem(e->E1);
  409. if (iffalse(e1))
  410. goto L2;
  411. else
  412. goto def;
  413. case OPoror:
  414. e->E1 = e1 = poptelem(e->E1);
  415. if (iftrue(e1))
  416. {
  417. L2: el_free(e->E2);
  418. e->E2 = NULL;
  419. e->Eoper = OPbool;
  420. e = poptelem(e);
  421. }
  422. else
  423. goto def;
  424. break;
  425. case OPcond:
  426. e->E1 = e1 = poptelem(e->E1);
  427. if (e1->Eoper == OPconst)
  428. {
  429. e2 = e->E2;
  430. type_free(e->ET);
  431. if (boolres(e1))
  432. { el_copy(e,e2->E1);
  433. e2->E1->Eoper = OPunde;
  434. e2->E1->ET = NULL;
  435. e2->E1->E1 = NULL;
  436. e2->E1->E2 = NULL;
  437. el_free(e2->E1);
  438. e2->E1 = NULL;
  439. }
  440. else
  441. { el_copy(e,e2->E2);
  442. e2->E2->Eoper = OPunde;
  443. e2->E2->ET = NULL;
  444. e2->E2->E1 = NULL;
  445. e2->E2->E2 = NULL;
  446. el_free(e2->E2);
  447. e2->E2 = NULL;
  448. }
  449. el_free(e2);
  450. el_free(e1);
  451. e = poptelem(e);
  452. }
  453. else
  454. goto def;
  455. break;
  456. case OPadd:
  457. e->E1 = e1 = poptelem(e->E1);
  458. e->E2 = e2 = poptelem(e->E2);
  459. if (e1->Eoper == OPconst)
  460. { /* swap leaves */
  461. e->E1 = e2;
  462. e2 = e->E2 = e1;
  463. e1 = e->E1;
  464. }
  465. goto L4;
  466. case OPmin:
  467. e->E1 = e1 = poptelem(e->E1);
  468. e->E2 = e2 = poptelem(e->E2);
  469. L4:
  470. if (e1->Eoper == OPrelconst || e1->Eoper == OPstring)
  471. {
  472. if (e2->Eoper == OPconst)
  473. { targ_int i = e2->EV.Vint;
  474. #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
  475. if (i && e1->EV.sp.Vsym->Sfl == FLgot)
  476. break;
  477. #endif
  478. if (e->Eoper == OPmin)
  479. i = -i;
  480. e1->EV.sp.Voffset += i;
  481. e = selecte1(e,e->ET);
  482. break;
  483. }
  484. }
  485. goto eval;
  486. default:
  487. if (OTleaf(op))
  488. goto ret;
  489. e->E1 = poptelem(e->E1);
  490. def:
  491. if (OTbinary(op)) // if binary node
  492. {
  493. e->E2 = poptelem(e->E2);
  494. }
  495. eval:
  496. e = evalu8(e);
  497. break;
  498. }
  499. ret:
  500. return e;
  501. }
  502. /********************
  503. * Select E1 leaf of e, and give it type t.
  504. */
  505. elem *selecte1(elem *e,type *t)
  506. { elem *e1;
  507. elem_debug(e);
  508. assert(EOP(e));
  509. e1 = e->E1;
  510. el_settype(e1,t);
  511. e->E1 = NULL;
  512. el_free(e);
  513. return e1;
  514. }
  515. #endif
  516. /******************************
  517. * Evaluate a node with only constants as leaves.
  518. * Return with the result.
  519. */
  520. elem * evalu8(elem *e)
  521. { elem *e1,*e2;
  522. tym_t tym,tym2,uns;
  523. unsigned op;
  524. targ_int i1,i2;
  525. int i;
  526. targ_llong l1,l2;
  527. targ_ldouble d1,d2;
  528. elem esave;
  529. // assert((_status87() & 0x3800) == 0);
  530. assert(e && EOP(e));
  531. op = e->Eoper;
  532. elem_debug(e);
  533. e1 = e->E1;
  534. //printf("evalu8(): "); elem_print(e);
  535. elem_debug(e1);
  536. if (e1->Eoper == OPconst)
  537. {
  538. tym2 = 0;
  539. e2 = NULL;
  540. if (EBIN(e))
  541. { e2 = e->E2;
  542. elem_debug(e2);
  543. if (e2->Eoper == OPconst)
  544. {
  545. i2 = l2 = el_tolong(e2);
  546. d2 = el_toldouble(e2);
  547. }
  548. else
  549. return e;
  550. tym2 = tybasic(typemask(e2));
  551. }
  552. else
  553. {
  554. tym2 = 0;
  555. e2 = NULL;
  556. i2 = 0; // not used, but static analyzer complains
  557. l2 = 0; // "
  558. d2 = 0; // "
  559. }
  560. i1 = l1 = el_tolong(e1);
  561. d1 = el_toldouble(e1);
  562. tym = tybasic(typemask(e1)); /* type of op is type of left child */
  563. #if TX86 && SCPP
  564. // Huge pointers are always evaluated at runtime
  565. if (tym == TYhptr && (l1 != 0 || l2 != 0))
  566. return e;
  567. #endif
  568. esave = *e;
  569. #if !__OpenBSD__
  570. _clear87();
  571. #endif
  572. }
  573. else
  574. return e;
  575. /* if left or right leaf is unsigned, this is an unsigned operation */
  576. uns = tyuns(tym) | tyuns(tym2);
  577. /*elem_print(e);*/
  578. /*dbg_printf("x%lx ",l1); WROP(op); dbg_printf("x%lx = ",l2);*/
  579. #if 0
  580. if (0 && e2)
  581. {
  582. dbg_printf("d1 = %Lg, d2 = %Lg, op = %d, OPne = %d, tym = x%lx\n",d1,d2,op,OPne,tym);
  583. dbg_printf("tym1 = x%lx, tym2 = x%lx, e2 = %g\n",tym,tym2,e2->EV.Vdouble);
  584. union eve u;
  585. dbg_printf("d1 = x%16llx\n", (u.Vldouble = d1, u.Vullong));
  586. dbg_printf("d2 = x%16llx\n", (u.Vldouble = d2, u.Vullong));
  587. }
  588. #endif
  589. i = 0;
  590. switch (op)
  591. {
  592. case OPadd:
  593. switch (tym)
  594. {
  595. case TYfloat:
  596. switch (tym2)
  597. {
  598. case TYfloat:
  599. e->EV.Vfloat = e1->EV.Vfloat + e2->EV.Vfloat;
  600. break;
  601. case TYifloat:
  602. e->EV.Vcfloat.re = e1->EV.Vfloat;
  603. e->EV.Vcfloat.im = e2->EV.Vfloat;
  604. break;
  605. case TYcfloat:
  606. e->EV.Vcfloat.re = e1->EV.Vfloat + e2->EV.Vcfloat.re;
  607. e->EV.Vcfloat.im = 0 + e2->EV.Vcfloat.im;
  608. break;
  609. default:
  610. assert(0);
  611. }
  612. break;
  613. case TYdouble:
  614. case TYdouble_alias:
  615. switch (tym2)
  616. {
  617. case TYdouble:
  618. case TYdouble_alias:
  619. e->EV.Vdouble = e1->EV.Vdouble + e2->EV.Vdouble;
  620. break;
  621. case TYidouble:
  622. e->EV.Vcdouble.re = e1->EV.Vdouble;
  623. e->EV.Vcdouble.im = e2->EV.Vdouble;
  624. break;
  625. case TYcdouble:
  626. e->EV.Vcdouble.re = e1->EV.Vdouble + e2->EV.Vcdouble.re;
  627. e->EV.Vcdouble.im = 0 + e2->EV.Vcdouble.im;
  628. break;
  629. default:
  630. assert(0);
  631. }
  632. break;
  633. case TYldouble:
  634. switch (tym2)
  635. {
  636. case TYldouble:
  637. e->EV.Vldouble = d1 + d2;
  638. break;
  639. case TYildouble:
  640. e->EV.Vcldouble.re = d1;
  641. e->EV.Vcldouble.im = d2;
  642. break;
  643. case TYcldouble:
  644. e->EV.Vcldouble.re = d1 + e2->EV.Vcldouble.re;
  645. e->EV.Vcldouble.im = 0 + e2->EV.Vcldouble.im;
  646. break;
  647. default:
  648. assert(0);
  649. }
  650. break;
  651. case TYifloat:
  652. switch (tym2)
  653. {
  654. case TYfloat:
  655. e->EV.Vcfloat.re = e2->EV.Vfloat;
  656. e->EV.Vcfloat.im = e1->EV.Vfloat;
  657. break;
  658. case TYifloat:
  659. e->EV.Vfloat = e1->EV.Vfloat + e2->EV.Vfloat;
  660. break;
  661. case TYcfloat:
  662. e->EV.Vcfloat.re = 0 + e2->EV.Vcfloat.re;
  663. e->EV.Vcfloat.im = e1->EV.Vfloat + e2->EV.Vcfloat.im;
  664. break;
  665. default:
  666. assert(0);
  667. }
  668. break;
  669. case TYidouble:
  670. switch (tym2)
  671. {
  672. case TYdouble:
  673. e->EV.Vcdouble.re = e2->EV.Vdouble;
  674. e->EV.Vcdouble.im = e1->EV.Vdouble;
  675. break;
  676. case TYidouble:
  677. e->EV.Vdouble = e1->EV.Vdouble + e2->EV.Vdouble;
  678. break;
  679. case TYcdouble:
  680. e->EV.Vcdouble.re = 0 + e2->EV.Vcdouble.re;
  681. e->EV.Vcdouble.im = e1->EV.Vdouble + e2->EV.Vcdouble.im;
  682. break;
  683. default:
  684. assert(0);
  685. }
  686. break;
  687. case TYildouble:
  688. switch (tym2)
  689. {
  690. case TYldouble:
  691. e->EV.Vcldouble.re = d2;
  692. e->EV.Vcldouble.im = d1;
  693. break;
  694. case TYildouble:
  695. e->EV.Vldouble = d1 + d2;
  696. break;
  697. case TYcldouble:
  698. e->EV.Vcldouble.re = 0 + e2->EV.Vcldouble.re;
  699. e->EV.Vcldouble.im = d1 + e2->EV.Vcldouble.im;
  700. break;
  701. default:
  702. assert(0);
  703. }
  704. break;
  705. case TYcfloat:
  706. switch (tym2)
  707. {
  708. case TYfloat:
  709. e->EV.Vcfloat.re = e1->EV.Vcfloat.re + e2->EV.Vfloat;
  710. e->EV.Vcfloat.im = e1->EV.Vcfloat.im;
  711. break;
  712. case TYifloat:
  713. e->EV.Vcfloat.re = e1->EV.Vcfloat.re;
  714. e->EV.Vcfloat.im = e1->EV.Vcfloat.im + e2->EV.Vfloat;
  715. break;
  716. case TYcfloat:
  717. e->EV.Vcfloat.re = e1->EV.Vcfloat.re + e2->EV.Vcfloat.re;
  718. e->EV.Vcfloat.im = e1->EV.Vcfloat.im + e2->EV.Vcfloat.im;
  719. break;
  720. default:
  721. assert(0);
  722. }
  723. break;
  724. case TYcdouble:
  725. switch (tym2)
  726. {
  727. case TYdouble:
  728. e->EV.Vcdouble.re = e1->EV.Vcdouble.re + e2->EV.Vdouble;
  729. e->EV.Vcdouble.im = e1->EV.Vcdouble.im;
  730. break;
  731. case TYidouble:
  732. e->EV.Vcdouble.re = e1->EV.Vcdouble.re;
  733. e->EV.Vcdouble.im = e1->EV.Vcdouble.im + e2->EV.Vdouble;
  734. break;
  735. case TYcdouble:
  736. e->EV.Vcdouble.re = e1->EV.Vcdouble.re + e2->EV.Vcdouble.re;
  737. e->EV.Vcdouble.im = e1->EV.Vcdouble.im + e2->EV.Vcdouble.im;
  738. break;
  739. default:
  740. assert(0);
  741. }
  742. break;
  743. case TYcldouble:
  744. switch (tym2)
  745. {
  746. case TYldouble:
  747. e->EV.Vcldouble.re = e1->EV.Vcldouble.re + d2;
  748. e->EV.Vcldouble.im = e1->EV.Vcldouble.im;
  749. break;
  750. case TYildouble:
  751. e->EV.Vcldouble.re = e1->EV.Vcldouble.re;
  752. e->EV.Vcldouble.im = e1->EV.Vcldouble.im + d2;
  753. break;
  754. case TYcldouble:
  755. e->EV.Vcldouble.re = e1->EV.Vcldouble.re + e2->EV.Vcldouble.re;
  756. e->EV.Vcldouble.im = e1->EV.Vcldouble.im + e2->EV.Vcldouble.im;
  757. break;
  758. default:
  759. assert(0);
  760. }
  761. break;
  762. default:
  763. #if TX86
  764. if (intsize == 2)
  765. { if (tyfv(tym))
  766. e->EV.Vlong = (l1 & 0xFFFF0000) |
  767. (targ_ushort) ((targ_ushort) l1 + i2);
  768. else if (tyfv(tym2))
  769. e->EV.Vlong = (l2 & 0xFFFF0000) |
  770. (targ_ushort) (i1 + (targ_ushort) l2);
  771. else if (tyintegral(tym) || typtr(tym))
  772. e->EV.Vllong = l1 + l2;
  773. else
  774. assert(0);
  775. }
  776. else
  777. #endif
  778. if (tyintegral(tym) || typtr(tym))
  779. e->EV.Vllong = l1 + l2;
  780. else
  781. assert(0);
  782. break;
  783. }
  784. break;
  785. case OPmin:
  786. switch (tym)
  787. {
  788. case TYfloat:
  789. switch (tym2)
  790. {
  791. case TYfloat:
  792. e->EV.Vfloat = e1->EV.Vfloat - e2->EV.Vfloat;
  793. break;
  794. case TYifloat:
  795. e->EV.Vcfloat.re = e1->EV.Vfloat;
  796. e->EV.Vcfloat.im = -e2->EV.Vfloat;
  797. break;
  798. case TYcfloat:
  799. e->EV.Vcfloat.re = e1->EV.Vfloat - e2->EV.Vcfloat.re;
  800. e->EV.Vcfloat.im = 0 - e2->EV.Vcfloat.im;
  801. break;
  802. default:
  803. assert(0);
  804. }
  805. break;
  806. case TYdouble:
  807. case TYdouble_alias:
  808. switch (tym2)
  809. {
  810. case TYdouble:
  811. case TYdouble_alias:
  812. e->EV.Vdouble = e1->EV.Vdouble - e2->EV.Vdouble;
  813. break;
  814. case TYidouble:
  815. e->EV.Vcdouble.re = e1->EV.Vdouble;
  816. e->EV.Vcdouble.im = -e2->EV.Vdouble;
  817. break;
  818. case TYcdouble:
  819. e->EV.Vcdouble.re = e1->EV.Vdouble - e2->EV.Vcdouble.re;
  820. e->EV.Vcdouble.im = 0 - e2->EV.Vcdouble.im;
  821. break;
  822. default:
  823. assert(0);
  824. }
  825. break;
  826. case TYldouble:
  827. switch (tym2)
  828. {
  829. case TYldouble:
  830. e->EV.Vldouble = d1 - d2;
  831. break;
  832. case TYildouble:
  833. e->EV.Vcldouble.re = d1;
  834. e->EV.Vcldouble.im = -d2;
  835. break;
  836. case TYcldouble:
  837. e->EV.Vcldouble.re = d1 - e2->EV.Vcldouble.re;
  838. e->EV.Vcldouble.im = 0 - e2->EV.Vcldouble.im;
  839. break;
  840. default:
  841. assert(0);
  842. }
  843. break;
  844. case TYifloat:
  845. switch (tym2)
  846. {
  847. case TYfloat:
  848. e->EV.Vcfloat.re = -e2->EV.Vfloat;
  849. e->EV.Vcfloat.im = e1->EV.Vfloat;
  850. break;
  851. case TYifloat:
  852. e->EV.Vfloat = e1->EV.Vfloat - e2->EV.Vfloat;
  853. break;
  854. case TYcfloat:
  855. e->EV.Vcfloat.re = 0 - e2->EV.Vcfloat.re;
  856. e->EV.Vcfloat.im = e1->EV.Vfloat - e2->EV.Vcfloat.im;
  857. break;
  858. default:
  859. assert(0);
  860. }
  861. break;
  862. case TYidouble:
  863. switch (tym2)
  864. {
  865. case TYdouble:
  866. e->EV.Vcdouble.re = -e2->EV.Vdouble;
  867. e->EV.Vcdouble.im = e1->EV.Vdouble;
  868. break;
  869. case TYidouble:
  870. e->EV.Vdouble = e1->EV.Vdouble - e2->EV.Vdouble;
  871. break;
  872. case TYcdouble:
  873. e->EV.Vcdouble.re = 0 - e2->EV.Vcdouble.re;
  874. e->EV.Vcdouble.im = e1->EV.Vdouble - e2->EV.Vcdouble.im;
  875. break;
  876. default:
  877. assert(0);
  878. }
  879. break;
  880. case TYildouble:
  881. switch (tym2)
  882. {
  883. case TYldouble:
  884. e->EV.Vcldouble.re = -d2;
  885. e->EV.Vcldouble.im = d1;
  886. break;
  887. case TYildouble:
  888. e->EV.Vldouble = d1 - d2;
  889. break;
  890. case TYcldouble:
  891. e->EV.Vcldouble.re = 0 - e2->EV.Vcldouble.re;
  892. e->EV.Vcldouble.im = d1 - e2->EV.Vcldouble.im;
  893. break;
  894. default:
  895. assert(0);
  896. }
  897. break;
  898. case TYcfloat:
  899. switch (tym2)
  900. {
  901. case TYfloat:
  902. e->EV.Vcfloat.re = e1->EV.Vcfloat.re - e2->EV.Vfloat;
  903. e->EV.Vcfloat.im = e1->EV.Vcfloat.im;
  904. break;
  905. case TYifloat:
  906. e->EV.Vcfloat.re = e1->EV.Vcfloat.re;
  907. e->EV.Vcfloat.im = e1->EV.Vcfloat.im - e2->EV.Vfloat;
  908. break;
  909. case TYcfloat:
  910. e->EV.Vcfloat.re = e1->EV.Vcfloat.re - e2->EV.Vcfloat.re;
  911. e->EV.Vcfloat.im = e1->EV.Vcfloat.im - e2->EV.Vcfloat.im;
  912. break;
  913. default:
  914. assert(0);
  915. }
  916. break;
  917. case TYcdouble:
  918. switch (tym2)
  919. {
  920. case TYdouble:
  921. e->EV.Vcdouble.re = e1->EV.Vcdouble.re - e2->EV.Vdouble;
  922. e->EV.Vcdouble.im = e1->EV.Vcdouble.im;
  923. break;
  924. case TYidouble:
  925. e->EV.Vcdouble.re = e1->EV.Vcdouble.re;
  926. e->EV.Vcdouble.im = e1->EV.Vcdouble.im - e2->EV.Vdouble;
  927. break;
  928. case TYcdouble:
  929. e->EV.Vcdouble.re = e1->EV.Vcdouble.re - e2->EV.Vcdouble.re;
  930. e->EV.Vcdouble.im = e1->EV.Vcdouble.im - e2->EV.Vcdouble.im;
  931. break;
  932. default:
  933. assert(0);
  934. }
  935. break;
  936. case TYcldouble:
  937. switch (tym2)
  938. {
  939. case TYldouble:
  940. e->EV.Vcldouble.re = e1->EV.Vcldouble.re - d2;
  941. e->EV.Vcldouble.im = e1->EV.Vcldouble.im;
  942. break;
  943. case TYildouble:
  944. e->EV.Vcldouble.re = e1->EV.Vcldouble.re;
  945. e->EV.Vcldouble.im = e1->EV.Vcldouble.im - d2;
  946. break;
  947. case TYcldouble:
  948. e->EV.Vcldouble.re = e1->EV.Vcldouble.re - e2->EV.Vcldouble.re;
  949. e->EV.Vcldouble.im = e1->EV.Vcldouble.im - e2->EV.Vcldouble.im;
  950. break;
  951. default:
  952. assert(0);
  953. }
  954. break;
  955. default:
  956. #if TX86
  957. if (intsize == 2 &&
  958. tyfv(tym) && tysize[tym2] == 2)
  959. e->EV.Vllong = (l1 & 0xFFFF0000) |
  960. (targ_ushort) ((targ_ushort) l1 - i2);
  961. else
  962. #endif
  963. if (tyintegral(tym) || typtr(tym))
  964. e->EV.Vllong = l1 - l2;
  965. else
  966. assert(0);
  967. break;
  968. }
  969. break;
  970. case OPmul:
  971. if (tyintegral(tym) || typtr(tym))
  972. e->EV.Vllong = l1 * l2;
  973. else
  974. { switch (tym)
  975. {
  976. case TYfloat:
  977. switch (tym2)
  978. {
  979. case TYfloat:
  980. case TYifloat:
  981. e->EV.Vfloat = e1->EV.Vfloat * e2->EV.Vfloat;
  982. break;
  983. case TYcfloat:
  984. e->EV.Vcfloat.re = e1->EV.Vfloat * e2->EV.Vcfloat.re;
  985. e->EV.Vcfloat.im = e1->EV.Vfloat * e2->EV.Vcfloat.im;
  986. break;
  987. default:
  988. assert(0);
  989. }
  990. break;
  991. case TYdouble:
  992. case TYdouble_alias:
  993. switch (tym2)
  994. {
  995. case TYdouble:
  996. case TYdouble_alias:
  997. case TYidouble:
  998. e->EV.Vdouble = e1->EV.Vdouble * e2->EV.Vdouble;
  999. break;
  1000. case TYcdouble:
  1001. e->EV.Vcdouble.re = e1->EV.Vdouble * e2->EV.Vcdouble.re;
  1002. e->EV.Vcdouble.im = e1->EV.Vdouble * e2->EV.Vcdouble.im;
  1003. break;
  1004. default:
  1005. assert(0);
  1006. }
  1007. break;
  1008. case TYldouble:
  1009. switch (tym2)
  1010. {
  1011. case TYldouble:
  1012. case TYildouble:
  1013. e->EV.Vldouble = d1 * d2;
  1014. break;
  1015. case TYcldouble:
  1016. e->EV.Vcldouble.re = d1 * e2->EV.Vcldouble.re;
  1017. e->EV.Vcldouble.im = d1 * e2->EV.Vcldouble.im;
  1018. break;
  1019. default:
  1020. assert(0);
  1021. }
  1022. break;
  1023. case TYifloat:
  1024. switch (tym2)
  1025. {
  1026. case TYfloat:
  1027. e->EV.Vfloat = e1->EV.Vfloat * e2->EV.Vfloat;
  1028. break;
  1029. case TYifloat:
  1030. e->EV.Vfloat = -e1->EV.Vfloat * e2->EV.Vfloat;
  1031. break;
  1032. case TYcfloat:
  1033. e->EV.Vcfloat.re = -e1->EV.Vfloat * e2->EV.Vcfloat.im;
  1034. e->EV.Vcfloat.im = e1->EV.Vfloat * e2->EV.Vcfloat.re;
  1035. break;
  1036. default:
  1037. assert(0);
  1038. }
  1039. break;
  1040. case TYidouble:
  1041. switch (tym2)
  1042. {
  1043. case TYdouble:
  1044. e->EV.Vdouble = e1->EV.Vdouble * e2->EV.Vdouble;
  1045. break;
  1046. case TYidouble:
  1047. e->EV.Vdouble = -e1->EV.Vdouble * e2->EV.Vdouble;
  1048. break;
  1049. case TYcdouble:
  1050. e->EV.Vcdouble.re = -e1->EV.Vdouble * e2->EV.Vcdouble.im;
  1051. e->EV.Vcdouble.im = e1->EV.Vdouble * e2->EV.Vcdouble.re;
  1052. break;
  1053. default:
  1054. assert(0);
  1055. }
  1056. break;
  1057. case TYildouble:
  1058. switch (tym2)
  1059. {
  1060. case TYldouble:
  1061. e->EV.Vldouble = d1 * d2;
  1062. break;
  1063. case TYildouble:
  1064. e->EV.Vldouble = -d1 * d2;
  1065. break;
  1066. case TYcldouble:
  1067. e->EV.Vcldouble.re = -d1 * e2->EV.Vcldouble.im;
  1068. e->EV.Vcldouble.im = d1 * e2->EV.Vcldouble.re;
  1069. break;
  1070. default:
  1071. assert(0);
  1072. }
  1073. break;
  1074. case TYcfloat:
  1075. switch (tym2)
  1076. {
  1077. case TYfloat:
  1078. e->EV.Vcfloat.re = e1->EV.Vcfloat.re * e2->EV.Vfloat;
  1079. e->EV.Vcfloat.im = e1->EV.Vcfloat.im * e2->EV.Vfloat;
  1080. break;
  1081. case TYifloat:
  1082. e->EV.Vcfloat.re = -e1->EV.Vcfloat.im * e2->EV.Vfloat;
  1083. e->EV.Vcfloat.im = e1->EV.Vcfloat.re * e2->EV.Vfloat;
  1084. break;
  1085. case TYcfloat:
  1086. e->EV.Vcfloat = Complex_f::mul(e1->EV.Vcfloat, e2->EV.Vcfloat);
  1087. break;
  1088. default:
  1089. assert(0);
  1090. }
  1091. break;
  1092. case TYcdouble:
  1093. switch (tym2)
  1094. {
  1095. case TYdouble:
  1096. e->EV.Vcdouble.re = e1->EV.Vcdouble.re * e2->EV.Vdouble;
  1097. e->EV.Vcdouble.im = e1->EV.Vcdouble.im * e2->EV.Vdouble;
  1098. break;
  1099. case TYidouble:
  1100. e->EV.Vcdouble.re = -e1->EV.Vcdouble.im * e2->EV.Vdouble;
  1101. e->EV.Vcdouble.im = e1->EV.Vcdouble.re * e2->EV.Vdouble;
  1102. break;
  1103. case TYcdouble:
  1104. e->EV.Vcdouble = Complex_d::mul(e1->EV.Vcdouble, e2->EV.Vcdouble);
  1105. break;
  1106. default:
  1107. assert(0);
  1108. }
  1109. break;
  1110. case TYcldouble:
  1111. switch (tym2)
  1112. {
  1113. case TYldouble:
  1114. e->EV.Vcldouble.re = e1->EV.Vcldouble.re * d2;
  1115. e->EV.Vcldouble.im = e1->EV.Vcldouble.im * d2;
  1116. break;
  1117. case TYildouble:
  1118. e->EV.Vcldouble.re = -e1->EV.Vcldouble.im * d2;
  1119. e->EV.Vcldouble.im = e1->EV.Vcldouble.re * d2;
  1120. break;
  1121. case TYcldouble:
  1122. e->EV.Vcldouble = Complex_ld::mul(e1->EV.Vcldouble, e2->EV.Vcldouble);
  1123. break;
  1124. default:
  1125. assert(0);
  1126. }
  1127. break;
  1128. default:
  1129. #ifdef DEBUG
  1130. dbg_printf("tym = x%x\n",tym);
  1131. elem_print(e);
  1132. #endif
  1133. assert(0);
  1134. }
  1135. }
  1136. break;
  1137. case OPdiv:
  1138. if (!boolres(e2)) // divide by 0
  1139. {
  1140. #if SCPP
  1141. if (!tyfloating(tym))
  1142. #endif
  1143. goto div0;
  1144. }
  1145. if (uns)
  1146. e->EV.Vullong = ((targ_ullong) l1) / ((targ_ullong) l2);
  1147. else
  1148. { switch (tym)
  1149. {
  1150. case TYfloat:
  1151. switch (tym2)
  1152. {
  1153. case TYfloat:
  1154. e->EV.Vfloat = e1->EV.Vfloat / e2->EV.Vfloat;
  1155. break;
  1156. case TYifloat:
  1157. e->EV.Vfloat = -e1->EV.Vfloat / e2->EV.Vfloat;
  1158. break;
  1159. case TYcfloat:
  1160. e->EV.Vcfloat.re = d1;
  1161. e->EV.Vcfloat.im = 0;
  1162. e->EV.Vcfloat = Complex_f::div(e->EV.Vcfloat, e2->EV.Vcfloat);
  1163. break;
  1164. default:
  1165. assert(0);
  1166. }
  1167. break;
  1168. case TYdouble:
  1169. case TYdouble_alias:
  1170. switch (tym2)
  1171. {
  1172. case TYdouble:
  1173. case TYdouble_alias:
  1174. e->EV.Vdouble = e1->EV.Vdouble / e2->EV.Vdouble;
  1175. break;
  1176. case TYidouble:
  1177. e->EV.Vdouble = -e1->EV.Vdouble / e2->EV.Vdouble;
  1178. break;
  1179. case TYcdouble:
  1180. e->EV.Vcdouble.re = d1;
  1181. e->EV.Vcdouble.im = 0;
  1182. e->EV.Vcdouble = Complex_d::div(e->EV.Vcdouble, e2->EV.Vcdouble);
  1183. break;
  1184. default:
  1185. assert(0);
  1186. }
  1187. break;
  1188. case TYldouble:
  1189. switch (tym2)
  1190. {
  1191. case TYldouble:
  1192. e->EV.Vldouble = d1 / d2;
  1193. break;
  1194. case TYildouble:
  1195. e->EV.Vldouble = -d1 / d2;
  1196. break;
  1197. case TYcldouble:
  1198. e->EV.Vcldouble.re = d1;
  1199. e->EV.Vcldouble.im = 0;
  1200. e->EV.Vcldouble = Complex_ld::div(e->EV.Vcldouble, e2->EV.Vcldouble);
  1201. break;
  1202. default:
  1203. assert(0);
  1204. }
  1205. break;
  1206. case TYifloat:
  1207. switch (tym2)
  1208. {
  1209. case TYfloat:
  1210. case TYifloat:
  1211. e->EV.Vfloat = e1->EV.Vfloat / e2->EV.Vfloat;
  1212. break;
  1213. case TYcfloat:
  1214. e->EV.Vcfloat.re = 0;
  1215. e->EV.Vcfloat.im = e1->EV.Vfloat;
  1216. e->EV.Vcfloat = Complex_f::div(e->EV.Vcfloat, e2->EV.Vcfloat);
  1217. break;
  1218. default:
  1219. assert(0);
  1220. }
  1221. break;
  1222. case TYidouble:
  1223. switch (tym2)
  1224. {
  1225. case TYdouble:
  1226. case TYidouble:
  1227. e->EV.Vdouble = e1->EV.Vdouble / e2->EV.Vdouble;
  1228. break;
  1229. case TYcdouble:
  1230. e->EV.Vcdouble.re = 0;
  1231. e->EV.Vcdouble.im = e1->EV.Vdouble;
  1232. e->EV.Vcdouble = Complex_d::div(e->EV.Vcdouble, e2->EV.Vcdouble);
  1233. break;
  1234. default:
  1235. assert(0);
  1236. }
  1237. break;
  1238. case TYildouble:
  1239. switch (tym2)
  1240. {
  1241. case TYldouble:
  1242. case TYildouble:
  1243. e->EV.Vldouble = d1 / d2;
  1244. break;
  1245. case TYcldouble:
  1246. e->EV.Vcldouble.re = 0;
  1247. e->EV.Vcldouble.im = d1;
  1248. e->EV.Vcldouble = Complex_ld::div(e->EV.Vcldouble, e2->EV.Vcldouble);
  1249. break;
  1250. default:
  1251. assert(0);
  1252. }
  1253. break;
  1254. case TYcfloat:
  1255. switch (tym2)
  1256. {
  1257. case TYfloat:
  1258. e->EV.Vcfloat.re = e1->EV.Vcfloat.re / e2->EV.Vfloat;
  1259. e->EV.Vcfloat.im = e1->EV.Vcfloat.im / e2->EV.Vfloat;
  1260. break;
  1261. case TYifloat:
  1262. e->EV.Vcfloat.re = e1->EV.Vcfloat.im / e2->EV.Vfloat;
  1263. e->EV.Vcfloat.im = -e1->EV.Vcfloat.re / e2->EV.Vfloat;
  1264. break;
  1265. case TYcfloat:
  1266. e->EV.Vcfloat = Complex_f::div(e1->EV.Vcfloat, e2->EV.Vcfloat);
  1267. break;
  1268. default:
  1269. assert(0);
  1270. }
  1271. break;
  1272. case TYcdouble:
  1273. switch (tym2)
  1274. {
  1275. case TYdouble:
  1276. e->EV.Vcdouble.re = e1->EV.Vcdouble.re / e2->EV.Vdouble;
  1277. e->EV.Vcdouble.im = e1->EV.Vcdouble.im / e2->EV.Vdouble;
  1278. break;
  1279. case TYidouble:
  1280. e->EV.Vcdouble.re = e1->EV.Vcdouble.im / e2->EV.Vdouble;
  1281. e->EV.Vcdouble.im = -e1->EV.Vcdouble.re / e2->EV.Vdouble;
  1282. break;
  1283. case TYcdouble:
  1284. e->EV.Vcdouble = Complex_d::div(e1->EV.Vcdouble, e2->EV.Vcdouble);
  1285. break;
  1286. default:
  1287. assert(0);
  1288. }
  1289. break;
  1290. case TYcldouble:
  1291. switch (tym2)
  1292. {
  1293. case TYldouble:
  1294. e->EV.Vcldouble.re = e1->EV.Vcldouble.re / d2;
  1295. e->EV.Vcldouble.im = e1->EV.Vcldouble.im / d2;
  1296. break;
  1297. case TYildouble:
  1298. e->EV.Vcldouble.re = e1->EV.Vcldouble.im / d2;
  1299. e->EV.Vcldouble.im = -e1->EV.Vcldouble.re / d2;
  1300. break;
  1301. case TYcldouble:
  1302. e->EV.Vcldouble = Complex_ld::div(e1->EV.Vcldouble, e2->EV.Vcldouble);
  1303. break;
  1304. default:
  1305. assert(0);
  1306. }
  1307. break;
  1308. default:
  1309. e->EV.Vllong = l1 / l2;
  1310. break;
  1311. }
  1312. }
  1313. break;
  1314. case OPmod:
  1315. if (!boolres(e2))
  1316. {
  1317. div0:
  1318. #if SCPP
  1319. synerr(EM_divby0);
  1320. #else // MARS
  1321. //error(e->Esrcpos.Sfilename, e->Esrcpos.Slinnum, "divide by zero");
  1322. #endif
  1323. break;
  1324. }
  1325. if (uns)
  1326. e->EV.Vullong = ((targ_ullong) l1) % ((targ_ullong) l2);
  1327. else
  1328. {
  1329. // BUG: what do we do for imaginary, complex?
  1330. switch (tym)
  1331. { case TYdouble:
  1332. case TYidouble:
  1333. case TYdouble_alias:
  1334. e->EV.Vdouble = fmod(e1->EV.Vdouble,e2->EV.Vdouble);
  1335. break;
  1336. case TYfloat:
  1337. case TYifloat:
  1338. e->EV.Vfloat = fmodf(e1->EV.Vfloat,e2->EV.Vfloat);
  1339. break;
  1340. case TYldouble:
  1341. case TYildouble:
  1342. #if __DMC__
  1343. e->EV.Vldouble = _modulo(d1, d2);
  1344. #else
  1345. e->EV.Vldouble = fmodl(d1, d2);
  1346. #endif
  1347. break;
  1348. case TYcfloat:
  1349. switch (tym2)
  1350. {
  1351. case TYfloat:
  1352. case TYifloat:
  1353. e->EV.Vcfloat.re = fmodf(e1->EV.Vcfloat.re, e2->EV.Vfloat);
  1354. e->EV.Vcfloat.im = fmodf(e1->EV.Vcfloat.im, e2->EV.Vfloat);
  1355. break;
  1356. default:
  1357. assert(0);
  1358. }
  1359. break;
  1360. case TYcdouble:
  1361. switch (tym2)
  1362. {
  1363. case TYdouble:
  1364. case TYidouble:
  1365. e->EV.Vcdouble.re = fmod(e1->EV.Vcdouble.re, e2->EV.Vdouble);
  1366. e->EV.Vcdouble.im = fmod(e1->EV.Vcdouble.im, e2->EV.Vdouble);
  1367. break;
  1368. default:
  1369. assert(0);
  1370. }
  1371. break;
  1372. case TYcldouble:
  1373. switch (tym2)
  1374. {
  1375. case TYldouble:
  1376. case TYildouble:
  1377. #if __DMC__
  1378. e->EV.Vcldouble.re = _modulo(e1->EV.Vcldouble.re, d2);
  1379. e->EV.Vcldouble.im = _modulo(e1->EV.Vcldouble.im, d2);
  1380. #else
  1381. e->EV.Vcldouble.re = fmodl(e1->EV.Vcldouble.re, d2);
  1382. e->EV.Vcldouble.im = fmodl(e1->EV.Vcldouble.im, d2);
  1383. #endif
  1384. break;
  1385. default:
  1386. assert(0);
  1387. }
  1388. break;
  1389. default:
  1390. e->EV.Vllong = l1 % l2;
  1391. break;
  1392. }
  1393. }
  1394. break;
  1395. case OPremquo:
  1396. {
  1397. targ_llong rem, quo;
  1398. if (!boolres(e2))
  1399. goto div0;
  1400. if (uns)
  1401. {
  1402. rem = ((targ_ullong) l1) % ((targ_ullong) l2);
  1403. quo = ((targ_ullong) l1) / ((targ_ullong) l2);
  1404. }
  1405. else
  1406. {
  1407. rem = l1 % l2;

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