Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1276 lines
27 KiB

  1. /* asmchksp.c -- microsoft 80x86 assembler
  2. **
  3. ** microsoft (r) macro assembler
  4. ** copyright (c) microsoft corp 1986. all rights reserved
  5. **
  6. ** randy nevin
  7. **
  8. ** 10/90 - Quick conversion to 32 bit by Jeff Spencer
  9. */
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <float.h>
  13. #include <stdlib.h>
  14. #include <math.h>
  15. #include <errno.h>
  16. #include "asm86.h"
  17. #include "asmfcn.h"
  18. #include "asmctype.h"
  19. #include "asmexpr.h"
  20. #include "asmopcod.h"
  21. extern UCHAR opprec [];
  22. VOID CODESIZE setdispmode(struct ar *);
  23. SHORT CODESIZE simpleExpr (struct ar *);
  24. char fValidSym;
  25. /*** createsym - make item entry for symbol
  26. *
  27. * createsym (itemkind, p);
  28. *
  29. * Entry itemkind = kind of item
  30. * itemsub =
  31. * *p = activation record
  32. * Exit
  33. * Returns
  34. * Calls
  35. * Note If symbol, look further to see if EQU, record name
  36. * and do appropriate thing.
  37. */
  38. VOID PASCAL CODESIZE createsym (
  39. ){
  40. register struct psop *pso; /* parse stack operand structure */
  41. register SYMBOL FARSYM *symp = symptr;
  42. char aliasAttr = (char) 0xFF;
  43. struct dscrec *itemptrT;
  44. pso = &(itemptr->dsckind.opnd);
  45. if (!symp) {
  46. undefined:
  47. pso->dflag = UNDEFINED;
  48. pso->dtype = M_CODE | M_FORTYPE;
  49. return;
  50. }
  51. if (symp->symkind == EQU &&
  52. symp->symu.equ.equtyp == ALIAS) {
  53. aliasAttr = symptr->attr;
  54. symptr = symp = chasealias (symp);
  55. if (!symp)
  56. goto undefined;
  57. }
  58. else if (symp->symkind == REC && (PEEKC () == '<')) {
  59. itemptrT = itemptr;
  60. pso->doffset = recordparse ();
  61. itemptr = itemptrT;
  62. return;
  63. }
  64. /* Assume symbol is defined */
  65. if (M_XTERN & symp->attr)
  66. pso->dflag = XTERNAL;
  67. else if (!(M_DEFINED & symp->attr)) {
  68. /* Cause error if undefined */
  69. pso->dflag = UNDEFINED;
  70. errorn (E_SND);
  71. }
  72. else if (!(M_BACKREF & (symp->attr & aliasAttr)))
  73. pso->dflag = FORREF;
  74. else
  75. pso->dflag = KNOWN;
  76. if (M_MULTDEFINED & symp->attr)
  77. errorc (E_RMD);
  78. pso->dsize = symp->symtype;
  79. pso->dlength = symp->length;
  80. pso->doffset = symp->offset;
  81. pso->dcontext = (SYMBOL FARSYM *)NULL;
  82. if ((symp->symkind == EQU) && (symp->symu.equ.equtyp == EXPR)) {
  83. pso->dsign = symp->symu.equ.equrec.expr.esign;
  84. pso->dcontext = symp->symu.equ.equrec.expr.eassume;
  85. }
  86. if (1 << symp->symkind & (M_CLABEL | M_PROC))
  87. if (isCodeLabel(symp) && emittext)
  88. pso->dcontext = symp->symu.clabel.csassume;
  89. if (1 << symp->symkind & (M_REGISTER | M_GROUP | M_SEGMENT))
  90. pso->dsegment = symp;
  91. else
  92. pso->dsegment = symp->symsegptr;
  93. if ((M_XTERN & symp->attr) || (1 << symp->symkind & (M_REC | M_RECFIELD)))
  94. pso->dextptr = symp;
  95. pso->dtype = xltsymtoresult[symp->symkind];
  96. if (symp->symkind == CLABEL ||
  97. symp->symkind == EQU && pso->dsegment)
  98. if (isCodeLabel(symp))
  99. pso->dtype = M_CODE;
  100. else
  101. pso->dtype = M_DATA;
  102. if (!(M_BACKREF & (symp->attr & aliasAttr)))
  103. pso->dtype |= M_FORTYPE;
  104. if ((pso->dtype == xltsymtoresult[REGISTER]) &&
  105. (symp->symu.regsym.regtype == STKREG)) {
  106. /* 8087 support */
  107. flteval ();
  108. }
  109. }
  110. /*** evalalpha - evaluate alpha
  111. *
  112. * type = evalpha (p);
  113. *
  114. * Entry p = pointer to parser activation record
  115. * Exit alpha item added to parse stack
  116. * Returns type of item added to parse stack
  117. * Calls
  118. */
  119. UCHAR PASCAL CODESIZE
  120. evalalpha (
  121. register struct ar *p
  122. ){
  123. register struct psop *pso; /* parse stack operand entry */
  124. if (! fValidSym)
  125. getatom ();
  126. if (fValidSym == 2 || symsearch ()){
  127. fValidSym = 0;
  128. if (symptr->symkind == EQU && symptr->symu.equ.equtyp == TEXTMACRO) {
  129. #ifdef BCBOPT
  130. goodlbufp = FALSE;
  131. #endif
  132. expandTM (symptr->symu.equ.equrec.txtmacro.equtext);
  133. return (getitem (p));
  134. }
  135. else if (symptr->symkind == CLASS)
  136. errorn( E_IOT );
  137. else {
  138. addplusflagCur = FALSE;
  139. createitem (OPERAND, ISYM);
  140. p->addplusflag = addplusflagCur;
  141. return (OPERAND);
  142. }
  143. }
  144. fValidSym = 0;
  145. if (fnoper ())
  146. if ((opertype == OPNOTHING) || (opertype == OPDUP)) {
  147. lbufp = begatom;
  148. dupflag = (opertype == OPDUP);
  149. return (ENDEXPR);
  150. }
  151. else {
  152. createitem (OPERATOR, ISYM);
  153. return (OPERATOR);
  154. }
  155. else if (*naim.pszName == '.') {
  156. lbufp = begatom + 1;
  157. operprec = opprec[opertype = OPDOT];
  158. createitem (OPERATOR, ISYM);
  159. return (OPERATOR);
  160. }
  161. else if (fnsize ()) {
  162. createitem (OPERAND, ISIZE);
  163. return (OPERAND);
  164. }
  165. else if ((*naim.pszName == '$') && (naim.pszName[1] == 0)) {
  166. itemptr = defaultdsc ();
  167. pso = &(itemptr->dsckind.opnd);
  168. /* Create result entry */
  169. pso->doffset = pcoffset;
  170. pso->dsegment = pcsegment;
  171. pso->dcontext = pcsegment;
  172. pso->dtype = M_CODE;
  173. pso->dsize = CSNEAR;
  174. return (OPERAND);
  175. }
  176. else if ((*naim.pszName == '?') && (naim.pszName[1] == 0)) {
  177. createitem (OPERAND, IUNKNOWN);
  178. if (emittext)
  179. errorc (E_UID);
  180. return (OPERAND);
  181. }
  182. else {
  183. symptr = (SYMBOL FARSYM *)NULL;
  184. error (E_SND, naim.pszName); /* common pass1 error */
  185. createitem (OPERAND, ISYM);
  186. return (OPERAND);
  187. }
  188. }
  189. /* Dup tree is organized left to right horizonatally for each
  190. item in a DUP list at the same level( i. e. 5 DUP(1,2,3) ).
  191. This is considered the 'list' part. Any item in the list
  192. may be another DUP header instead of a data entry, in
  193. which case you go down a level and have another list.
  194. */
  195. /*** scanlist - scan duprec list
  196. *
  197. * scanlist (ptr, disp);
  198. *
  199. * Entry *ptr = duprec entry
  200. * disp = function to execute on entry
  201. * Exit depends upon function
  202. * Returns none
  203. * Calls
  204. */
  205. VOID PASCAL CODESIZE
  206. scanlist (
  207. struct duprec FARSYM *ptr,
  208. VOID (PASCAL CODESIZE *disp) (struct duprec FARSYM *)
  209. ){
  210. struct duprec FARSYM *iptr;
  211. struct duprec FARSYM *dptr;
  212. nestCur++;
  213. while (ptr) {
  214. /* set pointer to next entry */
  215. iptr = ptr->itemlst;
  216. if (ptr->dupkind == NEST)
  217. /* dptr = pointer to duplicated item */
  218. dptr = ptr->duptype.dupnext.dup;
  219. else
  220. dptr = (struct duprec FARSYM *)NULL;
  221. if (!(ptr->rptcnt == 1 && ptr->itemcnt) ||
  222. !(strucflag && initflag))
  223. (*disp) (ptr);
  224. if (dptr) {
  225. /* Go thru DUP list */
  226. scanlist (dptr, disp);
  227. if (displayflag)
  228. if (!(ptr->rptcnt == 1 && ptr->itemcnt) ||
  229. !(strucflag && initflag))
  230. enddupdisplay ();
  231. }
  232. if (ptr == iptr) /* corrupt data structure */
  233. break;
  234. /* Handle next in list */
  235. ptr = iptr;
  236. }
  237. nestCur--;
  238. }
  239. /*** calcsize - calculate size of DUP list
  240. *
  241. * value = calcsize (ptr);
  242. *
  243. * Entry *ptr = dup list
  244. * Exit none
  245. * Returns size of structure
  246. * Calls calcsize
  247. */
  248. OFFSET PASCAL CODESIZE
  249. calcsize (
  250. struct duprec FARSYM *ptr
  251. ){
  252. unsigned long clsize = 0, nextSize, limit;
  253. struct duprec FARSYM *p;
  254. limit = (wordsize == 2)? 0x10000: 0xffffffff;
  255. for (p = ptr; p; p = p->itemlst) {
  256. if (p->dupkind == NEST) {
  257. /* Process nested dup */
  258. nextSize = calcsize (p->duptype.dupnext.dup);
  259. if (nextSize && (p->rptcnt > limit / nextSize))
  260. errorc(E_VOR);
  261. nextSize *= p->rptcnt;
  262. }
  263. else {
  264. if (p->dupkind == LONG) {
  265. nextSize = p->duptype.duplong.llen;
  266. resvspace = FALSE;
  267. }
  268. else {
  269. /* Size is that of directive */
  270. nextSize = p->duptype.dupitem.ddata->dsckind.opnd.dsize;
  271. if (p->duptype.dupitem.ddata->dsckind.opnd.dflag != INDETER)
  272. resvspace = FALSE;
  273. }
  274. }
  275. if (nextSize > limit - clsize)
  276. errorc(E_VOR);
  277. clsize += nextSize;
  278. if (p == p->itemlst) /* corrupt data structure */
  279. break;
  280. }
  281. return (clsize);
  282. }
  283. /*** datascan - scan next data item
  284. *
  285. * datascan ();
  286. *
  287. * Entry
  288. * Exit
  289. * Returns
  290. * Calls
  291. */
  292. struct duprec FARSYM * PASCAL CODESIZE
  293. datascan (
  294. struct datarec *p
  295. ){
  296. register char cc;
  297. struct dsr a;
  298. if (ISBLANK (PEEKC ()))
  299. skipblanks ();
  300. a.initlist = a.flag = a.longstr = FALSE;
  301. /* check for textmacro substitution */
  302. a.dirscan = lbufp;
  303. xcreflag--;
  304. getatom ();
  305. if (fnsize())
  306. goto isASize;
  307. if (symsrch ())
  308. if (symptr->symkind == EQU &&
  309. symptr->symu.equ.equtyp == TEXTMACRO) {
  310. expandTM (symptr->symu.equ.equrec.txtmacro.equtext);
  311. a.dirscan = begatom;
  312. }
  313. else if (symptr->symkind == STRUC) {
  314. isASize:
  315. switchname();
  316. getatom();
  317. if (tokenIS("ptr")) {
  318. switchname();
  319. p->type = fnPtr(datadsize[optyp - TDB]);
  320. if (p->type > 512)
  321. goto noRescan;
  322. }
  323. }
  324. lbufp = a.dirscan;
  325. noRescan:
  326. xcreflag++;
  327. if ((optyp == TDB &&
  328. ((cc = PEEKC ()) == '\'' || cc == '"')) &&
  329. !initflag)
  330. datadb (&a);
  331. if (optyp != TDB && optyp != TDW)
  332. /* entry can be DD | DQ | DT */
  333. parselong (&a);
  334. if (!a.longstr)
  335. datacon (&a);
  336. else if (strucflag && initflag)
  337. errorc( E_OIL );
  338. if (!a.flag) {
  339. if (!strucflag || !initflag) {
  340. a.dupdsc->rptcnt = 1;
  341. a.dupdsc->itemcnt = 0;
  342. a.dupdsc->itemlst = (struct duprec FARSYM *)NULL;
  343. }
  344. }
  345. return (a.dupdsc);
  346. }
  347. /*** realeval - evaluate IEEE 8087 floating point number
  348. *
  349. * realeval (p);
  350. *
  351. * Entry
  352. * Exit
  353. * Returns
  354. * Calls
  355. */
  356. struct ddecrec {
  357. USHORT realv[5];
  358. USHORT intgv[2];
  359. USHORT cflag;
  360. };
  361. #if !defined FLATMODEL
  362. // Because this is called so seldom and it's so slow anyhow put it in
  363. // a far segment.
  364. # pragma alloc_text (FA_TEXT, realeval)
  365. #endif
  366. VOID PASCAL
  367. realeval (
  368. struct realrec *p
  369. ){
  370. register char cc, *cp;
  371. char numtext[61];
  372. struct ddecrec fltres;
  373. #if !defined NOFLOAT
  374. float *pTmpFloat;
  375. double *pTmpDouble;
  376. double TmpDouble;
  377. double AbsDouble;
  378. long double *pTmpLongDouble;
  379. char *pEnd;
  380. #endif
  381. cp = numtext;
  382. /* Copy the number - must have at least 1 char */
  383. *cp++ = NEXTC (); /* get leading sign or 1st char */
  384. do {
  385. cc = NEXTC ();
  386. *cp++ = cc;
  387. } while (isdigit (cc) || cc == '.');
  388. if ((cc = MAP (cc)) == 'E') {
  389. /* Get the next + - or digit */
  390. *cp++ = NEXTC ();
  391. /* Copy the exponent over */
  392. do {
  393. cc = NEXTC ();
  394. *cp++ = cc;
  395. } while (isdigit (cc));
  396. }
  397. *cp = '\0';
  398. BACKC ();
  399. // NOFLOAT is used when there are no floating point libraries available
  400. // Any masm version produced with NOFLOAT defined will cause a divide
  401. // by 0 error to be logged when a real number initializer is used.
  402. #if defined NOFLOAT
  403. ferrorc( E_DVZ );
  404. #else
  405. switch(optyp)
  406. {
  407. case TDD:
  408. errno = 0;
  409. TmpDouble = strtod( numtext, &pEnd );
  410. if( errno == ERANGE ){
  411. ferrorc( E_DVZ );
  412. }
  413. AbsDouble = TmpDouble > 0 ? TmpDouble : -TmpDouble;
  414. if( AbsDouble > FLT_MAX || AbsDouble < FLT_MIN ){
  415. ferrorc( E_DVZ );
  416. }else{
  417. // Convert the double to a float (8 byte to 4 byte)
  418. pTmpFloat = (float *)(p->num);
  419. *pTmpFloat = (float)TmpDouble;
  420. }
  421. break;
  422. case TDQ:
  423. pTmpDouble = (double *)(p->num);
  424. errno = 0;
  425. *pTmpDouble = strtod( numtext, &pEnd );
  426. if( errno == ERANGE ){
  427. ferrorc( E_DVZ );
  428. }
  429. break;
  430. case TDT:
  431. pTmpLongDouble = (long double *)(p->num);
  432. errno = 0;
  433. *pTmpLongDouble = _strtold( numtext, &pEnd );
  434. if( errno == ERANGE ){
  435. ferrorc( E_DVZ );
  436. }
  437. break;
  438. default:
  439. ferrorc(E_TIL);
  440. break;
  441. }
  442. #endif
  443. }
  444. /*** simpleExpr - short curcuit expression evaluator
  445. *
  446. */
  447. /* following are three protype parse records for the three simple
  448. * expressions that we simpleExpr understands
  449. */
  450. #ifdef EXPR_STATS
  451. long cExpr, cHardExpr;
  452. extern char verbose;
  453. #endif
  454. #define SHORT_CIR 1
  455. #if SHORT_CIR
  456. DSCREC consDS = {
  457. NULL, 0, 0, /* previtem, prec, type */
  458. { NULL, NULL, NULL, 0, /* dsegment, dcontext, dexptr, dlength */
  459. 6, /* rm */
  460. 1 << RCONST, /* dtype */
  461. 0, 0, /* 0, */ /* doffset, dsize, type */
  462. 4, /* mode */
  463. FALSE, FALSE, FALSE, /* w, s, sized*/
  464. NOSEG, /* seg */
  465. KNOWN, /* dflag */
  466. FCONSTANT, /* fixtype */
  467. FALSE /* dsign */
  468. }
  469. };
  470. DSCREC regDS = {
  471. NULL, 0, 0, /* previtem, prec, type */
  472. { NULL, NULL, NULL, 0, /* dsegment, dcontext, dexptr, dlength */
  473. 0, /* rm */
  474. 1 << REGRESULT, /* dtype */
  475. 0, 2, /* 0, */ /* doffset, dsize, type */
  476. 3, /* mode */
  477. TRUE, FALSE, TRUE, /* w, s, sized*/
  478. NOSEG, /* seg */
  479. KNOWN, /* dflag */
  480. FCONSTANT, /* fixtype */
  481. FALSE /* dsign */
  482. }
  483. };
  484. DSCREC labelDS = {
  485. NULL, 0, 0, /* previtem, prec, type */
  486. { NULL, NULL, NULL, 0, /* dsegment, dcontext, dexptr, dlength */
  487. 6, /* rm */
  488. 1 << DATA, /* dtype */
  489. 0, 2, /* 0, */ /* doffset, dsize, type */
  490. 0, /* mode */
  491. TRUE, FALSE, TRUE, /* w, s, sized*/
  492. NOSEG, /* seg */
  493. KNOWN, /* dflag */
  494. FNONE, /* fixtype */
  495. FALSE /* dsign */
  496. }
  497. };
  498. #if !defined XENIX286 && !defined FLATMODEL
  499. #pragma check_stack-
  500. #endif
  501. SHORT CODESIZE
  502. simpleExpr (
  503. struct ar *pAR
  504. ){
  505. register DSCREC *pDES; /* parse stack operand structure */
  506. register char kind;
  507. char cc;
  508. char *lbufSav;
  509. fValidSym = noexp = 0;
  510. lbufSav = lbufp;
  511. #ifdef EXPR_STATS
  512. cExpr++;
  513. #endif
  514. if (ISTERM (cc = skipblanks())) {
  515. notSimple:
  516. lbufp = lbufSav;
  517. notSimpleLab:
  518. #ifdef EXPR_STATS
  519. cHardExpr++;
  520. #endif
  521. return (FALSE);
  522. }
  523. if (LEGAL1ST (cc)){
  524. getatom ();
  525. fValidSym++; /* 1 means valid token */
  526. if (! (ISTERM (PEEKC()) || PEEKC() == ',')){
  527. #ifdef EXPR_STATS
  528. if (verbose && pass2)
  529. fprintf(stdout, "Not a Simple Expression: %s\n", lbufSav);
  530. #endif
  531. goto notSimpleLab;
  532. }
  533. if (symsearch ()){
  534. fValidSym++; /* 2 means valid symptr */
  535. if ((kind = symptr->symkind) == REGISTER &&
  536. (symptr->symu.regsym.regtype != STKREG)) {
  537. pAR->curresult = pDES = dalloc();
  538. *pDES = regDS;
  539. pDES->dsckind.opnd.dsegment = symptr;
  540. switch (symptr->symu.regsym.regtype) {
  541. case BYTREG:
  542. pDES->dsckind.opnd.dsize = 1;
  543. pDES->dsckind.opnd.w--;
  544. pDES->dsckind.opnd.s++;
  545. break;
  546. #ifdef V386
  547. case CREG:
  548. if (opctype != PMOV)
  549. errorc(E_WRT);
  550. case DWRDREG:
  551. pDES->dsckind.opnd.dsize = 4;
  552. break;
  553. #endif
  554. }
  555. pDES->dsckind.opnd.rm = (unsigned short)symptr->offset;
  556. return(TRUE);
  557. }
  558. else if (kind == CLABEL || kind == PROC || kind == DVAR ||
  559. (kind == EQU && symptr->symu.equ.equtyp == EXPR)) {
  560. pAR->curresult = pDES = dalloc();
  561. *pDES = labelDS;
  562. pDES->dsckind.opnd.doffset = symptr->offset;
  563. pDES->dsckind.opnd.dsegment = symptr->symsegptr;
  564. if (kind == EQU) {
  565. if (! (pDES->dsckind.opnd.dcontext =
  566. symptr->symu.equ.equrec.expr.eassume) &&
  567. ! pDES->dsckind.opnd.dsegment){
  568. val = pDES->dsckind.opnd.doffset;
  569. *pDES = consDS;
  570. pDES->dsckind.opnd.dsign =
  571. symptr->symu.equ.equrec.expr.esign;
  572. if (!(M_BACKREF & symptr->attr)){
  573. pDES->dsckind.opnd.dtype |= M_FORTYPE;
  574. pDES->dsckind.opnd.dflag = FORREF;
  575. }
  576. if (M_XTERN & symptr->attr){
  577. pDES->dsckind.opnd.dflag = XTERNAL;
  578. pDES->dsckind.opnd.dextptr = symptr;
  579. return (TRUE);
  580. }
  581. goto constEqu;
  582. }
  583. }
  584. pDES->dsckind.opnd.dsize = symptr->symtype;
  585. pDES->dsckind.opnd.dlength = symptr->length;
  586. if (M_XTERN & symptr->attr){
  587. pDES->dsckind.opnd.dflag = XTERNAL;
  588. pDES->dsckind.opnd.dextptr = symptr;
  589. }
  590. else if (!(M_DEFINED & symptr->attr)) {
  591. /* Cause error if undefined */
  592. pDES->dsckind.opnd.dflag = UNDEFINED;
  593. pDES->dsckind.opnd.dsize = wordsize;
  594. pDES->dsckind.opnd.dtype = M_CODE;
  595. errorn (E_SND);
  596. }
  597. else if (!(M_BACKREF & symptr->attr)){
  598. pDES->dsckind.opnd.dflag = FORREF;
  599. pDES->dsckind.opnd.dtype |= M_FORTYPE;
  600. }
  601. if (M_MULTDEFINED & symptr->attr)
  602. errorc (E_RMD);
  603. if (pDES->dsckind.opnd.dsize < 2) {
  604. pDES->dsckind.opnd.w--;
  605. pDES->dsckind.opnd.s++;
  606. }
  607. #ifdef V386
  608. if (wordsize == 4 ||
  609. (symptr->symsegptr && symptr->symsegptr->symu.segmnt.use32 == 4)) {
  610. pDES->dsckind.opnd.mode = 5;
  611. pDES->dsckind.opnd.rm--; /* = 5 */
  612. }
  613. #endif
  614. if (isCodeLabel(symptr)){
  615. pDES->dsckind.opnd.dtype = (unsigned short)
  616. (pDES->dsckind.opnd.dtype & ~M_DATA | M_CODE);
  617. if (emittext && kind != EQU)
  618. pDES->dsckind.opnd.dcontext =
  619. symptr->symu.clabel.csassume;
  620. }
  621. else {
  622. pAR->linktype = FNONE;
  623. pAR->rstype = M_DATA;
  624. findsegment ((UCHAR)pAR->index, pAR);
  625. pDES->dsckind.opnd.seg = pAR->segovr;
  626. }
  627. pDES->dsckind.opnd.fixtype = FOFFSET;
  628. return(TRUE);
  629. }
  630. #ifdef EXPR_STATS
  631. if (verbose && pass2)
  632. fprintf(stdout, "Not a Simple Label: %s\n", naim.pszName);
  633. #endif
  634. }
  635. goto notSimpleLab;
  636. }
  637. if (isdigit (cc)){
  638. evalconst (); /* value in global val */
  639. if (! (ISTERM (skipblanks()) || PEEKC() == ','))
  640. goto notSimple;
  641. pAR->curresult = pDES = dalloc();
  642. *pDES = consDS;
  643. constEqu:
  644. if (pDES->dsckind.opnd.dflag != FORREF) {
  645. if (val < 128)
  646. pDES->dsckind.opnd.s++;
  647. else {
  648. #ifdef V386 /* only consider 16 bits */
  649. if (wordsize == 2)
  650. pDES->dsckind.opnd.s = (char)((USHORT)(((USHORT) val & ~0x7F ) == (USHORT)(~0x7F)));
  651. else
  652. #endif
  653. pDES->dsckind.opnd.s = ((val & ~0x7F ) == ~0x7F);
  654. }
  655. }
  656. pDES->dsckind.opnd.doffset = val;
  657. if (val > 256){
  658. pDES->dsckind.opnd.w++;
  659. pDES->dsckind.opnd.sized++;
  660. }
  661. return(TRUE);
  662. }
  663. goto notSimple;
  664. }
  665. #if !defined XENIX286 && !defined FLATMODEL
  666. #pragma check_stack+
  667. #endif
  668. #endif
  669. /*** expreval - expression evaluator
  670. *
  671. * routine ();
  672. *
  673. * Entry
  674. * Exit
  675. * Returns
  676. * Calls
  677. */
  678. DSCREC * PASCAL CODESIZE
  679. expreval (
  680. UCHAR *dseg
  681. ){
  682. register struct psop *psoi; /* parse stack operand structure */
  683. struct ar a;
  684. SHORT i;
  685. dupflag = FALSE;
  686. nilseg = NOSEG;
  687. a.segovr = NOSEG;
  688. a.index = *dseg;
  689. #if SHORT_CIR
  690. if (simpleExpr(&a)){
  691. fSecondArg++;
  692. return (a.curresult);
  693. }
  694. #endif
  695. a.exprdone = a.addplusflag = FALSE;
  696. a.lastitem = (DSCREC *)NULL;
  697. /* No parens or [] yet, Lowest precedence, haven't found anything yet */
  698. a.parenlevel = a.bracklevel = a.lastprec = 0;
  699. a.index = 0;
  700. a.base = 0;
  701. noexp = 1;
  702. /* Start expression loop */
  703. while (!a.exprdone){
  704. switch (getitem (&a)) {
  705. case OPERAND:
  706. itemptr->previtem = a.lastitem;
  707. a.lastitem = itemptr;
  708. itemptr->prec = a.lastprec;
  709. noexp = 0;
  710. break;
  711. case OPERATOR:
  712. exprop (&a);
  713. noexp = 0;
  714. break;
  715. case ENDEXPR:
  716. a.exprdone = TRUE;
  717. }
  718. }
  719. /* Do some easy error checking */
  720. if (a.parenlevel + a.bracklevel)
  721. errorc (E_PAR);
  722. itemptr = (DSCREC *)NULL;
  723. if (!a.lastitem)
  724. a.curresult = defaultdsc ();
  725. else
  726. evaluate (&a); /* Evaluate whole expression */
  727. psoi = &(a.curresult->dsckind.opnd);
  728. a.rstype = (unsigned short)(psoi->dtype &
  729. (M_CODE|M_DATA|M_RCONST|M_REGRESULT|M_SEGRESULT|M_GROUPSEG));
  730. a.linktype = FNONE; /* Leave bits for link type */
  731. a.vmode = 4;
  732. psoi->sized = FALSE;
  733. psoi->w = TRUE;
  734. psoi->s = FALSE;
  735. #ifdef V386
  736. if ((a.base|a.index) & 0xf8) { /* have 386 index or base */
  737. if (a.index) {
  738. if (!(a.index&8))
  739. errorc(E_OCI);
  740. if ((a.index&7) == 4)
  741. errorc(E_DBR);
  742. a.vmode = 10; /* two register modes */
  743. /* here we are putting what goes into the SIB
  744. * into a.index. from here on, we have to
  745. * to a.index with masks, so we dont trash
  746. * the high order stuff
  747. * the encoding we derive this from is tricky--
  748. * see regcheck() for details -Hans
  749. * stick in the index register */
  750. i = (a.index&7) << 3;
  751. /* stick in base. ebp if there is none */
  752. if (a.base){
  753. if (!(a.base&8))
  754. errorc(E_OCI);
  755. i |= (a.base&7);
  756. }
  757. else {
  758. i |= 5;
  759. a.vmode = 8;
  760. }
  761. /* stick in scale. *1 if there is none */
  762. if (a.index&0x70)
  763. i |= ((a.index & 0x70) - 0x10) << 2;
  764. a.index = i;
  765. }
  766. else if (a.base == (4|8)) { /* esp */
  767. a.vmode = 10;
  768. a.index = 044;
  769. }
  770. else { /* one register modes */
  771. a.vmode = 7;
  772. a.index = (unsigned short)(a.base & 7);
  773. }
  774. /* note dirty way of checking for BP or SP */
  775. if (*dseg != ESSEG && (a.base&6) == 4)
  776. *dseg = SSSEG;
  777. } else
  778. #endif /* V386 */
  779. if (a.base + a.index){ /* Have some index or base */
  780. a.vmode = 2;
  781. /* Assume offset is direct */
  782. if (a.base && a.index) /* Have both */
  783. a.index = (unsigned short)(a.base - 3 + a.index - 6);
  784. else if (a.base) /* Have base address */
  785. a.index = (a.base == 3)? 7: 6;
  786. else /* Have only index address*/
  787. a.index = a.index - 2;
  788. if (1 << a.index & (1 << 2 | 1 << 3 | 1 << 6) && *dseg != ESSEG)
  789. *dseg = SSSEG;
  790. }
  791. /* No indexing */
  792. else if (a.rstype == xltsymtoresult[REGISTER]) {
  793. /* Have register */
  794. a.vmode = 3;
  795. psoi->sized = TRUE;
  796. switch(psoi->dsegment->symu.regsym.regtype) {
  797. case BYTREG:
  798. psoi->dsize = 1;
  799. goto mask7;
  800. case WRDREG:
  801. case INDREG:
  802. case SEGREG:
  803. case STKREG:
  804. psoi->dsize = 2;
  805. goto mask7;
  806. #ifdef V386
  807. case CREG:/* probably should turn this into memref if !386P */
  808. if (opctype != PMOV)
  809. errorc(E_WRT);
  810. psoi->dsize = 4;
  811. a.index = (unsigned short)psoi->doffset;
  812. break;
  813. case DWRDREG:
  814. psoi->dsize = 4;
  815. #endif
  816. mask7:
  817. if ((psoi->doffset > 7) || psoi->dsign)
  818. errorc (E_IRV);
  819. /* Set register # */
  820. a.index = (unsigned short)(psoi->doffset & 7);
  821. break;
  822. default:
  823. errorc(E_WRT);
  824. break;
  825. }
  826. }
  827. /* Might be segment result */
  828. else if (a.rstype & (M_SEGRESULT | M_GROUPSEG)) {
  829. /* we get here if we had offset operator with segment or group
  830. * or offset operator with data and rconst
  831. * Result is SEG. Rconst if OFFSET grp:var */
  832. if (a.rstype & (M_SEGRESULT | M_EXPLOFFSET)) {
  833. psoi->dsize = 2;
  834. /* Leave size if not OFFSET or */
  835. psoi->sized = TRUE;
  836. }
  837. a.linktype = FOFFSET;
  838. if ((M_GROUPSEG & a.rstype) && (psoi->fixtype != FOFFSET)) {
  839. a.linktype = FGROUPSEG;
  840. setdispmode(&a);
  841. }
  842. if ((a.vmode == 4) && (psoi->fixtype != FOFFSET))
  843. a.linktype = FBASESEG;
  844. }
  845. else
  846. a.index = 6;
  847. /**** Evaluate offset part of result ****/
  848. a.base = psoi->doffset;
  849. if (psoi->fixtype == FOFFSET ||
  850. a.vmode == 2 || a.vmode == 7 || a.vmode == 10)
  851. psoi->dtype |= M_RCONST;
  852. /* [] implicit const */
  853. if ((M_RCONST & psoi->dtype) &&
  854. (a.linktype == FNONE) && (a.vmode != 3)) {
  855. /* Need to make sure <s> not set if memory */
  856. if (!(psoi->dflag & (FORREF|UNDEFINED|XTERNAL))
  857. && !psoi->dsegment && psoi->fixtype == FCONSTANT) {
  858. psoi->s = (a.base < 128 && !psoi->dsign) ||
  859. (a.base < 129 && psoi->dsign);
  860. if (!(psoi->s || psoi->dsign))
  861. #ifdef V386 /* only consider 16 bits */
  862. if (wordsize == 2 && a.vmode < 6)
  863. psoi->s = (char)((USHORT)(((USHORT) a.base & ~0x7F ) == (USHORT)(~0x7F)));
  864. else
  865. #endif
  866. psoi->s = ((a.base & ~0x7F ) == ~0x7F);
  867. }
  868. psoi->w = (psoi->dsign && a.base > 256) ||
  869. (a.base > 255 && !psoi->dsign);
  870. if (a.vmode != 4) {
  871. /* This is offset for index */
  872. /* If value not known, don't allow shortning to mode 1 */
  873. /* Word or byte offset */
  874. if (!(M_FORTYPE & psoi->dtype) &&
  875. psoi->dsegment == 0 && psoi->s &&
  876. a.vmode != 8) {
  877. /* one byte offset */
  878. a.vmode--;
  879. if (a.base == 0 && psoi->dflag == KNOWN) {
  880. /* perhaps 0 byte offset */
  881. switch(a.vmode) {
  882. case 1:
  883. if (a.index != 6)
  884. a.vmode--;
  885. break;
  886. case 6:
  887. case 9:
  888. if ((a.index&7) != 5)
  889. a.vmode--;
  890. break;
  891. }
  892. }
  893. }
  894. }
  895. else { /* Must be immediate */
  896. if (!psoi->dsegment && !psoi->dcontext)
  897. a.linktype = FCONSTANT;
  898. /******????? I'm not exactly sure why
  899. * we think we have a size yet. seems
  900. * to me mov BYTE PTR mem,500 is legal
  901. */
  902. psoi->sized = psoi->w;
  903. if (!(M_EXPLOFFSET & psoi->dtype) && psoi->dcontext) {
  904. /* Have segreg:const */
  905. a.vmode = 0;
  906. if (!(M_PTRSIZE & psoi->dtype) && psoi->dsize == 0)
  907. psoi->dsize = wordsize;
  908. }
  909. }
  910. }
  911. else if ((a.rstype & (M_DATA | M_CODE)) && a.linktype == FNONE) {
  912. /* Have direct mode and Want offset */
  913. a.linktype = FOFFSET;
  914. setdispmode(&a);
  915. if (psoi->dsize == CSFAR && emittext)
  916. a.linktype = FPOINTER;
  917. }
  918. if (psoi->dflag == UNDEFINED) {
  919. /* Forward ref pass 1 */
  920. if (psoi->dsize == 0)
  921. psoi->dsize = wordsize;
  922. if (!(M_RCONST & psoi->dtype) && a.vmode == 4)
  923. setdispmode(&a);
  924. }
  925. if (!psoi->dsegment ||
  926. (1 << a.linktype & (M_FNONE|M_FOFFSET|M_FPOINTER|M_FGROUPSEG))){
  927. if (psoi->dcontext &&
  928. psoi->dcontext->symkind == REGISTER)
  929. /* Have reg:var */
  930. if (psoi->dcontext->symu.regsym.regtype == SEGREG) {
  931. /* Have segreg:VAR */
  932. a.segovr = (char)(psoi->dcontext->offset);
  933. psoi->dcontext = regsegment[a.segovr];
  934. /* Context is that of segreg */
  935. if (!psoi->dsegment && (psoi->dflag != XTERNAL)) {
  936. psoi->dcontext = NULL;
  937. psoi->dtype = xltsymtoresult[REC];
  938. psoi->mode = 4;
  939. a.linktype = FCONSTANT;
  940. }
  941. }
  942. else
  943. errorc (E_IUR);
  944. else /* Find if seg:var or no :, but needed */
  945. findsegment (*dseg, &a);
  946. }
  947. /* bogus error check removed, dcontext can be other then register
  948. *
  949. * else if (psoi->dcontext &&
  950. * psoi->dcontext->symu.regsym.regtype == SEGREG)
  951. *
  952. * errorc (E_IOT);
  953. */
  954. if (a.segovr != NOSEG)
  955. psoi->dtype |= xltsymtoresult[DVAR];
  956. if (a.vmode == 2 || a.vmode == 7 || a.vmode == 10) {
  957. if (a.segovr == NOSEG && *dseg != NOSEG &&
  958. (psoi->dsegment || psoi->dflag == XTERNAL))
  959. psoi->dcontext = regsegment[*dseg];
  960. psoi->dtype |= xltsymtoresult[DVAR];
  961. }
  962. if (! (1 << a.linktype & (M_FNONE | M_FCONSTANT)) ||
  963. psoi->dflag == XTERNAL) {
  964. if (M_HIGH & psoi->dtype)
  965. a.linktype = FHIGH;
  966. if (M_LOW & psoi->dtype)
  967. a.linktype = FLOW;
  968. }
  969. if ((psoi->dtype & (M_PTRSIZE | M_HIGH | M_LOW)) ||
  970. psoi->dsize && a.vmode != 4) {
  971. psoi->sized = TRUE;
  972. psoi->w = (psoi->dsize > 1);
  973. psoi->s = !psoi->w;
  974. }
  975. psoi->seg = a.segovr;
  976. psoi->mode = (char)(a.vmode);
  977. psoi->fixtype = a.linktype;
  978. psoi->rm = a.index;
  979. if ((M_REGRESULT & a.rstype) && (a.vmode != 3))
  980. errorc (E_IUR); /* bad use of regs, like CS:SI */
  981. fSecondArg++;
  982. return (a.curresult);
  983. }
  984. /* setdispmode -- set up elements of the ar structure to reflect
  985. the encoding of the disp addressing mode: [BP] or [EBP] means.
  986. there is a wordsize length displacement following and a zero
  987. index.
  988. input : struct ar *a; a pointer to the upper frame variable
  989. output : none
  990. modifies : a->vmode, a->index.
  991. */
  992. VOID CODESIZE
  993. setdispmode(
  994. register struct ar *a
  995. ){
  996. #ifdef V386
  997. if (a->vmode > 7) {
  998. a->vmode = 8; /* scaled index byte, not r/m */
  999. a->index = (a->index&~7) | 5;
  1000. }
  1001. else if (wordsize == 4 ||
  1002. highWord(a->curresult->dsckind.opnd.doffset) ||
  1003. (a->curresult->dsckind.opnd.dsegment &&
  1004. a->curresult->dsckind.opnd.dsegment->symu.segmnt.use32 == 4)) {
  1005. a->vmode = 5;
  1006. a->index = (a->index&~7) | 5;
  1007. }
  1008. else
  1009. #endif
  1010. {
  1011. a->vmode = 0;
  1012. a->index = 6;
  1013. }
  1014. }