Windows NT 4.0 source code leak
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.

1274 lines
26 KiB

4 years ago
  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 = 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 = 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 =
  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 = (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 = a.index = a.base = 0;
  699. noexp = 1;
  700. /* Start expression loop */
  701. while (!a.exprdone){
  702. switch (getitem (&a)) {
  703. case OPERAND:
  704. itemptr->previtem = a.lastitem;
  705. a.lastitem = itemptr;
  706. itemptr->prec = a.lastprec;
  707. noexp = 0;
  708. break;
  709. case OPERATOR:
  710. exprop (&a);
  711. noexp = 0;
  712. break;
  713. case ENDEXPR:
  714. a.exprdone = TRUE;
  715. }
  716. }
  717. /* Do some easy error checking */
  718. if (a.parenlevel + a.bracklevel)
  719. errorc (E_PAR);
  720. itemptr = (DSCREC *)NULL;
  721. if (!a.lastitem)
  722. a.curresult = defaultdsc ();
  723. else
  724. evaluate (&a); /* Evaluate whole expression */
  725. psoi = &(a.curresult->dsckind.opnd);
  726. a.rstype = psoi->dtype &
  727. (M_CODE|M_DATA|M_RCONST|M_REGRESULT|M_SEGRESULT|M_GROUPSEG);
  728. a.linktype = FNONE; /* Leave bits for link type */
  729. a.vmode = 4;
  730. psoi->sized = FALSE;
  731. psoi->w = TRUE;
  732. psoi->s = FALSE;
  733. #ifdef V386
  734. if ((a.base|a.index) & 0xf8) { /* have 386 index or base */
  735. if (a.index) {
  736. if (!(a.index&8))
  737. errorc(E_OCI);
  738. if ((a.index&7) == 4)
  739. errorc(E_DBR);
  740. a.vmode = 10; /* two register modes */
  741. /* here we are putting what goes into the SIB
  742. * into a.index. from here on, we have to
  743. * to a.index with masks, so we dont trash
  744. * the high order stuff
  745. * the encoding we derive this from is tricky--
  746. * see regcheck() for details -Hans
  747. * stick in the index register */
  748. i = (a.index&7) << 3;
  749. /* stick in base. ebp if there is none */
  750. if (a.base){
  751. if (!(a.base&8))
  752. errorc(E_OCI);
  753. i |= (a.base&7);
  754. }
  755. else {
  756. i |= 5;
  757. a.vmode = 8;
  758. }
  759. /* stick in scale. *1 if there is none */
  760. if (a.index&0x70)
  761. i |= ((a.index & 0x70) - 0x10) << 2;
  762. a.index = i;
  763. }
  764. else if (a.base == (4|8)) { /* esp */
  765. a.vmode = 10;
  766. a.index = 044;
  767. }
  768. else { /* one register modes */
  769. a.vmode = 7;
  770. a.index = a.base & 7;
  771. }
  772. /* note dirty way of checking for BP or SP */
  773. if (*dseg != ESSEG && (a.base&6) == 4)
  774. *dseg = SSSEG;
  775. } else
  776. #endif /* V386 */
  777. if (a.base + a.index){ /* Have some index or base */
  778. a.vmode = 2;
  779. /* Assume offset is direct */
  780. if (a.base && a.index) /* Have both */
  781. a.index = a.base - 3 + a.index - 6;
  782. else if (a.base) /* Have base address */
  783. a.index = (a.base == 3)? 7: 6;
  784. else /* Have only index address*/
  785. a.index = a.index - 2;
  786. if (1 << a.index & (1 << 2 | 1 << 3 | 1 << 6) && *dseg != ESSEG)
  787. *dseg = SSSEG;
  788. }
  789. /* No indexing */
  790. else if (a.rstype == xltsymtoresult[REGISTER]) {
  791. /* Have register */
  792. a.vmode = 3;
  793. psoi->sized = TRUE;
  794. switch(psoi->dsegment->symu.regsym.regtype) {
  795. case BYTREG:
  796. psoi->dsize = 1;
  797. goto mask7;
  798. case WRDREG:
  799. case INDREG:
  800. case SEGREG:
  801. case STKREG:
  802. psoi->dsize = 2;
  803. goto mask7;
  804. #ifdef V386
  805. case CREG:/* probably should turn this into memref if !386P */
  806. if (opctype != PMOV)
  807. errorc(E_WRT);
  808. psoi->dsize = 4;
  809. a.index = psoi->doffset;
  810. break;
  811. case DWRDREG:
  812. psoi->dsize = 4;
  813. #endif
  814. mask7:
  815. if ((psoi->doffset > 7) || psoi->dsign)
  816. errorc (E_IRV);
  817. /* Set register # */
  818. a.index = psoi->doffset & 7;
  819. break;
  820. default:
  821. errorc(E_WRT);
  822. break;
  823. }
  824. }
  825. /* Might be segment result */
  826. else if (a.rstype & (M_SEGRESULT | M_GROUPSEG)) {
  827. /* we get here if we had offset operator with segment or group
  828. * or offset operator with data and rconst
  829. * Result is SEG. Rconst if OFFSET grp:var */
  830. if (a.rstype & (M_SEGRESULT | M_EXPLOFFSET)) {
  831. psoi->dsize = 2;
  832. /* Leave size if not OFFSET or */
  833. psoi->sized = TRUE;
  834. }
  835. a.linktype = FOFFSET;
  836. if ((M_GROUPSEG & a.rstype) && (psoi->fixtype != FOFFSET)) {
  837. a.linktype = FGROUPSEG;
  838. setdispmode(&a);
  839. }
  840. if ((a.vmode == 4) && (psoi->fixtype != FOFFSET))
  841. a.linktype = FBASESEG;
  842. }
  843. else
  844. a.index = 6;
  845. /**** Evaluate offset part of result ****/
  846. a.base = psoi->doffset;
  847. if (psoi->fixtype == FOFFSET ||
  848. a.vmode == 2 || a.vmode == 7 || a.vmode == 10)
  849. psoi->dtype |= M_RCONST;
  850. /* [] implicit const */
  851. if ((M_RCONST & psoi->dtype) &&
  852. (a.linktype == FNONE) && (a.vmode != 3)) {
  853. /* Need to make sure <s> not set if memory */
  854. if (!(psoi->dflag & (FORREF|UNDEFINED|XTERNAL))
  855. && !psoi->dsegment && psoi->fixtype == FCONSTANT) {
  856. psoi->s = (a.base < 128 && !psoi->dsign) ||
  857. (a.base < 129 && psoi->dsign);
  858. if (!(psoi->s || psoi->dsign))
  859. #ifdef V386 /* only consider 16 bits */
  860. if (wordsize == 2 && a.vmode < 6)
  861. psoi->s = (USHORT)(((USHORT) a.base & ~0x7F ) == (USHORT)(~0x7F));
  862. else
  863. #endif
  864. psoi->s = ((a.base & ~0x7F ) == ~0x7F);
  865. }
  866. psoi->w = (psoi->dsign && a.base > 256) ||
  867. (a.base > 255 && !psoi->dsign);
  868. if (a.vmode != 4) {
  869. /* This is offset for index */
  870. /* If value not known, don't allow shortning to mode 1 */
  871. /* Word or byte offset */
  872. if (!(M_FORTYPE & psoi->dtype) &&
  873. psoi->dsegment == 0 && psoi->s &&
  874. a.vmode != 8) {
  875. /* one byte offset */
  876. a.vmode--;
  877. if (a.base == 0 && psoi->dflag == KNOWN) {
  878. /* perhaps 0 byte offset */
  879. switch(a.vmode) {
  880. case 1:
  881. if (a.index != 6)
  882. a.vmode--;
  883. break;
  884. case 6:
  885. case 9:
  886. if ((a.index&7) != 5)
  887. a.vmode--;
  888. break;
  889. }
  890. }
  891. }
  892. }
  893. else { /* Must be immediate */
  894. if (!psoi->dsegment && !psoi->dcontext)
  895. a.linktype = FCONSTANT;
  896. /******????? I'm not exactly sure why
  897. * we think we have a size yet. seems
  898. * to me mov BYTE PTR mem,500 is legal
  899. * albeit silly. -Hans */
  900. psoi->sized = psoi->w;
  901. if (!(M_EXPLOFFSET & psoi->dtype) && psoi->dcontext) {
  902. /* Have segreg:const */
  903. a.vmode = 0;
  904. if (!(M_PTRSIZE & psoi->dtype) && psoi->dsize == 0)
  905. psoi->dsize = wordsize;
  906. }
  907. }
  908. }
  909. else if ((a.rstype & (M_DATA | M_CODE)) && a.linktype == FNONE) {
  910. /* Have direct mode and Want offset */
  911. a.linktype = FOFFSET;
  912. setdispmode(&a);
  913. if (psoi->dsize == CSFAR && emittext)
  914. a.linktype = FPOINTER;
  915. }
  916. if (psoi->dflag == UNDEFINED) {
  917. /* Forward ref pass 1 */
  918. if (psoi->dsize == 0)
  919. psoi->dsize = wordsize;
  920. if (!(M_RCONST & psoi->dtype) && a.vmode == 4)
  921. setdispmode(&a);
  922. }
  923. if (!psoi->dsegment ||
  924. (1 << a.linktype & (M_FNONE|M_FOFFSET|M_FPOINTER|M_FGROUPSEG))){
  925. if (psoi->dcontext &&
  926. psoi->dcontext->symkind == REGISTER)
  927. /* Have reg:var */
  928. if (psoi->dcontext->symu.regsym.regtype == SEGREG) {
  929. /* Have segreg:VAR */
  930. a.segovr = psoi->dcontext->offset;
  931. psoi->dcontext = regsegment[a.segovr];
  932. /* Context is that of segreg */
  933. if (!psoi->dsegment && (psoi->dflag != XTERNAL)) {
  934. psoi->dcontext = NULL;
  935. psoi->dtype = xltsymtoresult[REC];
  936. psoi->mode = 4;
  937. a.linktype = FCONSTANT;
  938. }
  939. }
  940. else
  941. errorc (E_IUR);
  942. else /* Find if seg:var or no :, but needed */
  943. findsegment (*dseg, &a);
  944. }
  945. /* bogus error check removed, dcontext can be other then register
  946. *
  947. * else if (psoi->dcontext &&
  948. * psoi->dcontext->symu.regsym.regtype == SEGREG)
  949. *
  950. * errorc (E_IOT);
  951. */
  952. if (a.segovr != NOSEG)
  953. psoi->dtype |= xltsymtoresult[DVAR];
  954. if (a.vmode == 2 || a.vmode == 7 || a.vmode == 10) {
  955. if (a.segovr == NOSEG && *dseg != NOSEG &&
  956. (psoi->dsegment || psoi->dflag == XTERNAL))
  957. psoi->dcontext = regsegment[*dseg];
  958. psoi->dtype |= xltsymtoresult[DVAR];
  959. }
  960. if (! (1 << a.linktype & (M_FNONE | M_FCONSTANT)) ||
  961. psoi->dflag == XTERNAL) {
  962. if (M_HIGH & psoi->dtype)
  963. a.linktype = FHIGH;
  964. if (M_LOW & psoi->dtype)
  965. a.linktype = FLOW;
  966. }
  967. if ((psoi->dtype & (M_PTRSIZE | M_HIGH | M_LOW)) ||
  968. psoi->dsize && a.vmode != 4) {
  969. psoi->sized = TRUE;
  970. psoi->w = (psoi->dsize > 1);
  971. psoi->s = !psoi->w;
  972. }
  973. psoi->seg = a.segovr;
  974. psoi->mode = a.vmode;
  975. psoi->fixtype = a.linktype;
  976. psoi->rm = a.index;
  977. if ((M_REGRESULT & a.rstype) && (a.vmode != 3))
  978. errorc (E_IUR); /* bad use of regs, like CS:SI */
  979. fSecondArg++;
  980. return (a.curresult);
  981. }
  982. /* setdispmode -- set up elements of the ar structure to reflect
  983. the encoding of the disp addressing mode: [BP] or [EBP] means.
  984. there is a wordsize length displacement following and a zero
  985. index.
  986. input : struct ar *a; a pointer to the upper frame variable
  987. output : none
  988. modifies : a->vmode, a->index.
  989. */
  990. VOID CODESIZE
  991. setdispmode(
  992. register struct ar *a
  993. ){
  994. #ifdef V386
  995. if (a->vmode > 7) {
  996. a->vmode = 8; /* scaled index byte, not r/m */
  997. a->index = (a->index&~7) | 5;
  998. }
  999. else if (wordsize == 4 ||
  1000. highWord(a->curresult->dsckind.opnd.doffset) ||
  1001. (a->curresult->dsckind.opnd.dsegment &&
  1002. a->curresult->dsckind.opnd.dsegment->symu.segmnt.use32 == 4)) {
  1003. a->vmode = 5;
  1004. a->index = (a->index&~7) | 5;
  1005. }
  1006. else
  1007. #endif
  1008. {
  1009. a->vmode = 0;
  1010. a->index = 6;
  1011. }
  1012. }