Source code of Windows XP (NT5)
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.

1471 lines
34 KiB

  1. /* asmeval.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 "asm86.h"
  12. #include "asmfcn.h"
  13. #include "asmexpr.h"
  14. char parseset[] = {14,
  15. OPUNPLUS, OPPLUS,
  16. OPMINUS, OPUNMINUS,
  17. OPHIGH, OPLOW,
  18. OPDOT, OPOFFSET,
  19. OPCOLON, OPLPAR,
  20. OPLBRK, OPTHIS,
  21. OPSHORT, OPPTR};
  22. /* POPvalue pops a operand from the top of the evaluation stack
  23. If the item is not an operand or the stack is empty, an
  24. error is generated and a value of 0 is supplied. The operand
  25. is returned to the caller in <valu> and is a result type
  26. operand. The original operand will not be a result unless it
  27. has been already used. The operand entry is destroyed and a
  28. result operand is created for constants and symbols( which
  29. are not record/struc names or fields ). */
  30. /*** valerror - process error in operand entry
  31. *
  32. * valerror (p);
  33. *
  34. * Entry
  35. * Exit
  36. * Returns
  37. * Calls
  38. */
  39. VOID PASCAL CODESIZE
  40. valerror (
  41. register struct ar *p
  42. ){
  43. DSCREC *oldlast;
  44. /* Operand was expected */
  45. errorc (E_OPN);
  46. /* save expr stack */
  47. oldlast = p->lastitem;
  48. p->lastitem = defaultdsc ();
  49. /* Point to rest */
  50. p->lastitem->previtem = oldlast;
  51. }
  52. /*** popvalue - pop operand entry off parse stack
  53. *
  54. * dscrec = popvalue (p);
  55. *
  56. * Entry
  57. * Exit
  58. * Returns
  59. * Calls
  60. */
  61. DSCREC * PASCAL CODESIZE
  62. popvalue (
  63. register struct ar *p
  64. ){
  65. register DSCREC *valu;
  66. if (!p->lastitem)
  67. valerror (p);
  68. if (p->lastitem->itype != OPERAND)
  69. valerror (p);
  70. /* If not operand, insert one at LASTitem */
  71. /* In case need to convert */
  72. valu = p->lastitem;
  73. /* Assume won't convert */
  74. /* Pop operand off stack */
  75. p->lastitem = valu->previtem;
  76. return (valu);
  77. }
  78. /*** popoperator - pop next operator from stack
  79. *
  80. * op = popoperator (p);
  81. *
  82. * Entry *p = parse stack entry
  83. * Exit
  84. * Returns operator
  85. * Calls
  86. */
  87. UCHAR PASCAL CODESIZE
  88. popoperator (
  89. register struct ar *p
  90. ){
  91. register char op;
  92. if (!p->lastitem) {
  93. errorc( E_OPR ); /* expected operator */
  94. return( (char)OPPLUS ); /* use '+' as default */
  95. }
  96. else {
  97. if (p->lastitem->itype != OPERATOR) {
  98. errorc( E_OPR ); /* expected operator */
  99. return( (char)OPPLUS ); /* use '+' as default */
  100. }
  101. else {
  102. /* Return OPERATOR number */
  103. op = p->lastitem->dsckind.opr.oidx;
  104. /* Pop OPERATOR off stack */
  105. itemptr = p->lastitem;
  106. p->lastitem = p->lastitem->previtem;
  107. return (op);
  108. }
  109. }
  110. }
  111. /* Evaluate is called to evaluate part of the expression. It is
  112. usually called just before a lower precedence is pushed, but
  113. also when the expression is complete and for close parens of
  114. various kinds regadless of precedence. The amount of the
  115. expression stack evauated depends on the caller. There are
  116. 3 cases:
  117. 1. Lower precedence OPERATOR( 3+4*5 AND 3 ). Evaluate
  118. back until left paren or precedence<= OPERATOR. If
  119. paren, leave on stack.
  120. 2. A paren of some kind( )>] ). Evaluate back to match-
  121. ing paren. Leave paren off stack. If any other paren
  122. seen, cause error.
  123. 3. End of expression( ENDexpr TRUE ). Evaluate all that
  124. is left of expression.
  125. */
  126. /*** pushpar - push paren or bracket back onto stack
  127. *
  128. * routine ();
  129. *
  130. * Entry
  131. * Exit
  132. * Returns
  133. * Calls
  134. */
  135. VOID PASCAL CODESIZE
  136. pushpar (
  137. register struct evalrec *p
  138. ){
  139. itemptr->previtem = p->p->lastitem;
  140. p->p->lastitem = itemptr;
  141. /* So OPERATOR not removed */
  142. itemptr = NULL;
  143. }
  144. /* EVALtop evaluates the top OPERATOR on the stack and its
  145. operands and produces CURresult as a result. It assumes that
  146. the stack is arranged as follows:
  147. Operand( If not already result type, will convert )
  148. OPERATOR( <> will cause error, [ executes as OPERATOR
  149. ( will not evaluate, but whether stays on
  150. stack is determined by PARENflag )
  151. Operand ( If not result, will convert. If OPERATOR is
  152. unary, will not be looked for. Special check
  153. for +/- used as unary. )
  154. Any deviation from the above will cause an error to be
  155. generated by popvalue/popoperator. */
  156. /*** signadjust - calculate offset and sign of result and put in right operand
  157. *
  158. * routine ();
  159. *
  160. * Entry
  161. * Exit
  162. * Returns
  163. * Calls
  164. * Note Right and left operands may be switched
  165. */
  166. VOID PASCAL CODESIZE
  167. signadjust (
  168. UCHAR minus,
  169. register struct exprec *p
  170. ){
  171. register struct psop *psol; /* parse stack operand structure */
  172. register struct psop *psor; /* parse stack operand structure */
  173. DSCREC *t;
  174. OFFSET maxInt;
  175. char fOverflow = FALSE;
  176. maxInt = (fArth32)? OFFSETMAX: 0xffff;
  177. psor = &(p->valright->dsckind.opnd);
  178. psol = &(p->valleft->dsckind.opnd);
  179. if (psol->s) /* arthmethic on data size item - NEAR/FAR */
  180. errorc(E_TIL);
  181. if (minus)
  182. psor->dsign = !psor->dsign;
  183. if (psol->dsegment || psol->dflag == XTERNAL ||
  184. (M_FLTSTACK & psol->dtype)) {
  185. /* Want to preserve Left operand */
  186. t = p->valleft;
  187. p->valleft = p->valright;
  188. p->valright = t;
  189. p->right = p->left;
  190. p->left = p->valleft->dsckind.opnd.doffset;
  191. psor = &(p->valright->dsckind.opnd);
  192. psol = &(p->valleft->dsckind.opnd);
  193. }
  194. if (psol->dflag == UNDEFINED)
  195. psor->dtype = M_CODE | M_FORTYPE;
  196. if (psor->dflag == UNDEFINED && !(psol->dtype & M_PTRSIZE))
  197. psol->dsize = 0;
  198. if (psol->dsign == psor->dsign) {
  199. /* Signs are same */
  200. fOverflow = (((maxInt - p->right) + 1) == p->left);
  201. p->right = p->right + p->left;
  202. } else if (p->right > p->left)
  203. /* Different signs */
  204. p->right = p->right - p->left;
  205. else {
  206. p->right = p->left - p->right;
  207. psor->dsign = !psor->dsign;
  208. }
  209. if (p->right == 0 && !fOverflow)
  210. psor->dsign = FALSE;
  211. if (psor->dsign && (psor->dtype & M_SEGRESULT))
  212. errorc (E_OSA);
  213. psor->doffset = p->right;
  214. }
  215. /*** foldsigns - force evaluating 17 bit signed values back to 16 bits
  216. *
  217. * routine ();
  218. *
  219. * Entry
  220. * Exit
  221. * Returns
  222. * Calls
  223. */
  224. VOID PASCAL CODESIZE
  225. foldsigns (
  226. register struct exprec *p
  227. ){
  228. /* the forms inside the comments seem to be trying to manage
  229. * things as unsigned short even though they are stored in a
  230. * larger field--ie this would be running as a cross assembler
  231. * from a 32 bit host to a 16 bit object. since for the 386,
  232. * we keep all this stuff as long, this turns out to be a bad
  233. * approach. so without completely understanding what is going
  234. * on, I am doing a simple negate (on the OFFSET field, which
  235. * is probably an unsigned long) rather than trying to preserve
  236. * the odd typing of the previous version -Hans, 19/9/86 */
  237. if (p->valright->dsckind.opnd.dsign)
  238. /* p->right = 65535 - p->right + 1; */
  239. p->right = -(long)p->right;
  240. if (p->valleft)
  241. if (p->valleft->dsckind.opnd.dsign)
  242. /* p->left = 65535 - p->left + 1; */
  243. p->left = -(long)p->left;
  244. }
  245. /*** shiftoper - execute shift left or right
  246. *
  247. * result = shiftoper (p);
  248. *
  249. * Entry *p = parse stack entry
  250. * Exit none
  251. * Returns shifted value
  252. * Calls
  253. */
  254. OFFSET PASCAL CODESIZE
  255. shiftoper (
  256. register struct exprec *p
  257. ){
  258. register OFFSET argl;
  259. register USHORT argr;
  260. argl = p->valleft->dsckind.opnd.doffset;
  261. if (p->valleft->dsckind.opnd.dsign)
  262. argl = -(long)argl;
  263. argr = (USHORT)(p->valright->dsckind.opnd.doffset);
  264. if (p->valright->dsckind.opnd.dsign) {
  265. errorc (E_SCN);
  266. return (argl);
  267. }
  268. else if (sizeof(OFFSET)*8 < argr)
  269. return (0);
  270. else if (p->stkoper == OPSHL)
  271. return (argl << argr);
  272. else
  273. return (argl >> argr);
  274. }
  275. /* VALcheck is used by all OPERATOR execute routines to make
  276. sure their arguments are correct. If the arguments are
  277. expected to be some kind of result( i.e. not a structure
  278. or record item or data size ), the old argument is destroy-
  279. ed and DEFAULTdsc is called to create a substitute. Error
  280. messages are also generated on type mismatches. A number
  281. of procedures of the form: VALUExxxx are called, these
  282. check if the given argument is of that type and if not,
  283. generate an error and a value of zero. There is one kludge
  284. in this procedure, the LENGTH OPERATOR should work with
  285. records and structures, but these are still in the form of
  286. <Isym> records so they will work with MASK, ...
  287. The operand types are as follows:
  288. Callabs May be unary or binary. In any case, all
  289. values must have a NIL segment.
  290. Clsize May be unary or binary. If unary, value must
  291. be a size( which is: structure name, -2 .. n
  292. or BYTE WORD ... ). If binary, left value is
  293. a size.
  294. Csame Is always binary. If not results, coerce them.
  295. Both must belong to the same segment and not
  296. be external.
  297. Cdata Is always unary. Result must be associated
  298. with data( Dtype is [data] ). Exception if
  299. LENGTH OPERATOR and is record or record field
  300. in which case converts to approriate result
  301. record.
  302. Ccode Is always unary. Result must be associated
  303. with code( Dtype is [code] ).
  304. Crec Is always unary. Value must be record field
  305. or record name.
  306. Cseg Is always unary. Value must have a segment.
  307. Cvar Always unary. Value must be constant or data
  308. or code.
  309. Clseg Always binary. The left value must be a
  310. SEGresult or a segment register.
  311. Coneabs Always binary. One of the values must be a
  312. constant.
  313. Csamabs Always binary. Either both values have the
  314. same segment or the second value is a constant
  315. */
  316. /*** valconst - give error if value is not constant
  317. *
  318. * routine ();
  319. *
  320. * Entry
  321. * Exit
  322. * Returns
  323. * Calls
  324. */
  325. VOID PASCAL CODESIZE
  326. valconst (
  327. register DSCREC *arg
  328. ){
  329. if (!(M_RCONST & arg->dsckind.opnd.dtype) ||
  330. arg->dsckind.opnd.dsegment ||
  331. arg->dsckind.opnd.dflag == XTERNAL)
  332. /* Not constant */
  333. errorc (E_CXP);
  334. }
  335. /*** valusize - check size of operand
  336. *
  337. * val = valusize (arg);
  338. *
  339. * Entry
  340. * Exit
  341. * Returns
  342. * Calls
  343. */
  344. USHORT PASCAL CODESIZE
  345. valuesize (
  346. register DSCREC *arg
  347. ){
  348. if (!fArth32)
  349. arg->dsckind.opnd.doffset = (long) (SHORT) arg->dsckind.opnd.doffset;
  350. if (arg->dsckind.opnd.doffset == 0) {
  351. /* 0 means no size */
  352. errorc (E_OHS);
  353. return (0);
  354. }
  355. else if (arg->dsckind.opnd.doffset >= CSFAR_LONG)
  356. return (xltsymtoresult[PROC]);
  357. else
  358. return (xltsymtoresult[DVAR]);
  359. }
  360. /*** valcheck - check operand value
  361. *
  362. * valcheck (valtype, unary, p);
  363. *
  364. * Entry
  365. * Exit
  366. * Returns
  367. * Calls
  368. */
  369. VOID PASCAL CODESIZE
  370. valcheck (
  371. UCHAR valtype,
  372. UCHAR unary,
  373. register struct exprec *p
  374. ){
  375. register struct psop *psol; /* parse stack operand structure */
  376. register struct psop *psor; /* parse stack operand structure */
  377. psol = &(p->valleft->dsckind.opnd);
  378. psor = &(p->valright->dsckind.opnd);
  379. /* Should give error if have 2 externals */
  380. if (p->valleft)
  381. if (psol->dflag == XTERNAL && psor->dflag == XTERNAL)
  382. errorc (E_IUE);
  383. switch (valtype) {
  384. case CALLABS:
  385. valconst (p->valright);
  386. if (!unary)
  387. valconst (p->valleft);
  388. break;
  389. case CLSIZE:
  390. if (unary)
  391. psor->dtype = valuesize (p->valright);
  392. else
  393. psol->dtype = valuesize (p->valleft);
  394. break;
  395. case CSAME:
  396. if (psol->dsegment != psor->dsegment)
  397. errorc (E_OMM);
  398. break;
  399. case CDATA:
  400. if ((p->stkoper != OPLENGTH) || !psor->dextptr
  401. || (psor->dflag == XTERNAL)) {
  402. if (!(M_DATA & psor->dtype) &&
  403. (psor->dlength == 0))
  404. errorc (E_ASD);
  405. }
  406. else {
  407. /* Special case for LENGTH */
  408. p->valleft = defaultdsc ();
  409. /* Create value */
  410. p->valleft->prec = p->valright->prec;
  411. psol = &(p->valleft->dsckind.opnd);
  412. psol->dlength = psor->dextptr->length;
  413. /* Lose old value */
  414. oblititem (p->valright);
  415. p->valright = p->valleft;
  416. p->valleft = NULL;
  417. psor = psol;
  418. psol = NULL;
  419. }
  420. break;
  421. case CCODE:
  422. if (!(M_CODE & p->valright->dsckind.opnd.dtype))
  423. errorc (E_ASC);
  424. break;
  425. case CREC:
  426. if (!psor->dextptr || psor->dflag == XTERNAL)
  427. errorc (E_RRF);
  428. break;
  429. case CSEG:
  430. if (!psor->dsegment && psor->dflag != XTERNAL
  431. || (M_REGRESULT & psor->dtype))
  432. errorc (E_OSG);
  433. break;
  434. case CLSEG:
  435. if (M_SEGRESULT & psol->dtype) {
  436. /* ??? if (!psor->dsegment || (psor->dtype & M_RCONST))
  437. errorc (E_IOT); ??? */
  438. }
  439. else if (M_REGRESULT & psol->dtype) {
  440. if (psol->dsegment->symu.regsym.regtype != SEGREG)
  441. errorc (E_LOS);
  442. }
  443. else
  444. errorc (E_LOS);
  445. break;
  446. case CONEABS:
  447. if (psor->dsegment && psol->dsegment)
  448. errorc (E_OOC);
  449. break;
  450. case CSAMABS:
  451. if (psor->dsegment &&
  452. psol->dsegment != psor->dsegment)
  453. errorc (E_OSA);
  454. break;
  455. }
  456. p->right = psor->doffset;
  457. if (p->valleft)
  458. p->left = psol->doffset;
  459. }
  460. /*** regcheck - check for <arg> a register in [...]
  461. *
  462. * routine ();
  463. *
  464. * Entry
  465. * Exit
  466. * Returns
  467. * Calls
  468. */
  469. DSCREC * PASCAL CODESIZE
  470. regcheck (
  471. DSCREC *arg,
  472. UCHAR minus,
  473. register struct exprec *ptr
  474. ){
  475. struct psop *pso; /* parse stack operand structure */
  476. register struct ar *pAR;
  477. USHORT reg;
  478. pso = &(arg->dsckind.opnd);
  479. pAR = ptr->p->p;
  480. if (M_REGRESULT & pso->dtype) {
  481. /* Is some register */
  482. if (ptr->p->parenflag || pAR->bracklevel) {
  483. /* Have index reg in []s */
  484. /* Lose size based on register */
  485. pso->dsize = 0;
  486. reg = (USHORT)(pso->dsegment->offset);
  487. /* Must be index or ptr reg */
  488. switch(pso->dsegment->symu.regsym.regtype)
  489. {
  490. default:
  491. errorc (E_IBR);
  492. break;
  493. case INDREG:
  494. if (reg <= 5)
  495. /* Have base reg BX | BP */
  496. if (pAR->base)
  497. errorc (E_DBR);
  498. else
  499. pAR->base = reg;
  500. else /* Have index reg DI | SI */
  501. if (pAR->index)
  502. errorc (E_DIR);
  503. else
  504. pAR->index = reg;
  505. break;
  506. #ifdef V386
  507. case DWRDREG:
  508. /* Have 386 reg in []s */
  509. if (minus == 2)
  510. {
  511. if (pAR->index & 0xf)
  512. errorc(E_DIR);
  513. pAR->index |= 8 | reg;
  514. }
  515. else if (pAR->base)
  516. {
  517. if (pAR->index)
  518. errorc(E_DIR);
  519. if (reg == 4) {
  520. /* swap base with index
  521. * to allow [index][eSp] */
  522. pAR->index = (USHORT)(pAR->base);
  523. pAR->base = 4|8;
  524. }
  525. else
  526. pAR->index = reg|8;
  527. }
  528. else
  529. pAR->base = reg|8;
  530. break;
  531. #endif /* V386 */
  532. }
  533. if (minus == TRUE && (ptr->valright == arg))
  534. errorc (E_IUR);
  535. oblititem (arg);
  536. return (defaultdsc ());
  537. }
  538. else {
  539. errorc(E_IUR);
  540. return (arg);
  541. }
  542. }
  543. #ifdef V386 /* scaled indexing modes */
  544. else if (minus == 2 && (M_RCONST & pso->dtype))
  545. {
  546. if (pAR->index&0x70)
  547. errorc(E_MBR);
  548. if (highWord(arg->dsckind.opnd.doffset))
  549. goto scaleErr;
  550. switch((SHORT) arg->dsckind.opnd.doffset) {
  551. case 1:
  552. pAR->index |= 0x10;
  553. break;
  554. case 2:
  555. pAR->index |= 0x20;
  556. break;
  557. case 4:
  558. pAR->index |= 0x30;
  559. break;
  560. case 8:
  561. pAR->index |= 0x40;
  562. break;
  563. scaleErr:
  564. default:
  565. error(E_EXP, "scale value of 1,2,4 or 8");
  566. }
  567. oblititem (arg);
  568. return (defaultdsc ());
  569. }
  570. #endif /* V386 */
  571. else return (arg);
  572. }
  573. /*** idxcheck - check for arg to +- is register
  574. *
  575. * routine ();
  576. *
  577. * Entry
  578. * Exit
  579. * Returns
  580. * Calls
  581. * Note See if arg to +/- is register, in which case see if should
  582. * be stored in Ridx or Rbas due to []s
  583. */
  584. VOID PASCAL CODESIZE
  585. idxcheck (
  586. UCHAR minus,
  587. register struct exprec *p
  588. ){
  589. p->valleft = regcheck (p->valleft, minus, p);
  590. p->valright = regcheck (p->valright, minus, p);
  591. p->right = p->valright->dsckind.opnd.doffset;
  592. p->left = p->valleft->dsckind.opnd.doffset;
  593. }
  594. /*** makeGrpRel - make an offset group relative
  595. *
  596. * routine ();
  597. *
  598. * Entry
  599. * Exit
  600. * Returns
  601. * Calls
  602. */
  603. VOID PASCAL CODESIZE
  604. makeGrpRel (
  605. register struct psop *p
  606. ){
  607. if (!(p->dtype&M_EXPLCOLON) && p->dsegment &&
  608. p->dsegment->symkind == SEGMENT && p->dsegment->symu.segmnt.grouptr){
  609. p->dtype |= M_GROUPSEG;
  610. p->dcontext = p->dsegment->symu.segmnt.grouptr;
  611. }
  612. }
  613. /*** evaltop - evaluate top entry
  614. *
  615. * routine ();
  616. *
  617. * Entry
  618. * Exit
  619. * Returns
  620. * Calls
  621. */
  622. VOID PASCAL CODESIZE
  623. evaltop (
  624. struct evalrec *ptr
  625. ){
  626. register struct psop *psol; /* parse stack operand structure */
  627. register struct psop *psor; /* parse stack operand structure */
  628. struct exprec a;
  629. a.p = ptr;
  630. /* Get right operand */
  631. a.valright = popvalue (a.p->p);
  632. itemptr = NULL;
  633. if (a.p->p->lastitem) {
  634. /* Get OPERATOR */
  635. a.stkoper = popoperator (a.p->p);
  636. a.valleft = NULL;
  637. /* assume is unary */
  638. if (!inset (a.stkoper, unaryset))
  639. /* Not unary OPERATOR */
  640. a.valleft = (a.stkoper == OPUNPLUS || a.stkoper == OPUNMINUS)
  641. ? defaultdsc() : popvalue (a.p->p);
  642. /* Save for EVALtop */
  643. a.p->idx = a.stkoper;
  644. if (a.valleft)
  645. a.valleft->prec = a.valright->prec;
  646. psol = &(a.valleft->dsckind.opnd);
  647. psor = &(a.valright->dsckind.opnd);
  648. switch (a.stkoper) {
  649. /* All OPERATORs are executed thru this CASE statement. The
  650. * VALcheck routine makes sure operands are of the correct
  651. * type and may create dummy entries in the case of the real
  652. * operand not being of type result when required. The REStype
  653. * routine uses it's argument to know what part of the result
  654. * record should be kept and the type of the result. Unary
  655. * and binary OPERATORs both return their results in VALright. */
  656. case OPAND:
  657. case OPOR:
  658. case OPXOR:
  659. /* Make sure operands ok */
  660. valcheck (CALLABS, FALSE, &a);
  661. /* Must work on 16 bits */
  662. foldsigns (&a);
  663. switch (a.stkoper) {
  664. case OPAND:
  665. psor->doffset = a.left & a.right;
  666. break;
  667. case OPOR:
  668. psor->doffset = a.left | a.right;
  669. break;
  670. case OPXOR:
  671. psor->doffset = a.left ^ a.right;
  672. break;
  673. }
  674. psor->dsign = FALSE;
  675. /* Must clear out Dsign in case was signed value */
  676. break;
  677. case OPNOT:
  678. /* TRUE constant arg */
  679. valcheck (CALLABS, TRUE, &a);
  680. foldsigns (&a);
  681. psor->doffset = ~a.right;
  682. psor->dsign = FALSE;
  683. if (optyp == TDB &&
  684. (psor->doffset & ((OFFSET) ~0xff)) == ((OFFSET) ~0xff))
  685. psor->doffset &= 0xFF;
  686. #ifdef V386_noCode
  687. if (!(cputype & P386)) /* truncate result to 16 bits */
  688. psor->doffset &= 0xffff; /* for compatablity */
  689. #endif
  690. break;
  691. case OPSHL:
  692. case OPSHR:
  693. valcheck (CALLABS, FALSE, &a);
  694. psor->doffset = shiftoper (&a);
  695. psor->dsign = FALSE;
  696. break;
  697. case OPSEG:
  698. /* Must have segment */
  699. valcheck (CSEG, TRUE, &a);
  700. if (psor->dcontext && !(psor->dtype&M_EXPLCOLON))
  701. psor->dsegment = psor->dcontext;
  702. psor->dtype = (USHORT)((psor->dtype&M_FORTYPE) | M_SEGRESULT| M_RCONST);
  703. psor->doffset = 0;
  704. psor->dsign = FALSE;
  705. break;
  706. case OPDOT:
  707. /* See if idx reg */
  708. idxcheck (FALSE, &a);
  709. valcheck (CONEABS, FALSE, &a);
  710. psol = &(a.valleft->dsckind.opnd);
  711. psor = &(a.valright->dsckind.opnd);
  712. if (psor->dsize)
  713. psol->dsize = psor->dsize;
  714. /* Adjust signs on records */
  715. signadjust (FALSE, &a);
  716. psol = &(a.valleft->dsckind.opnd);
  717. psor = &(a.valright->dsckind.opnd);
  718. break;
  719. case OPUNPLUS:
  720. case OPPLUS:
  721. /* See if idx reg */
  722. idxcheck (FALSE, &a);
  723. valcheck (CONEABS, FALSE, &a);
  724. psol = &(a.valleft->dsckind.opnd);
  725. psor = &(a.valright->dsckind.opnd);
  726. /* Adjust signs on records */
  727. signadjust (FALSE, &a);
  728. psol = &(a.valleft->dsckind.opnd);
  729. psor = &(a.valright->dsckind.opnd);
  730. break;
  731. case OPUNMINUS:
  732. case OPMINUS:
  733. idxcheck (TRUE, &a);
  734. if (psor->dsegment == psol->dsegment &&
  735. psol->dsegment) {
  736. if (psol->dtype & M_SEGRESULT) {
  737. psol->dtype = M_SEGRESULT | M_RCONST;
  738. psol->doffset = 0;
  739. psol->dsign = FALSE;
  740. }
  741. if (psor->dtype & M_SEGRESULT) {
  742. psor->dtype = M_SEGRESULT | M_RCONST;
  743. psor->doffset = 0;
  744. psor->dsign = FALSE;
  745. }
  746. }
  747. valcheck (CSAMABS, FALSE, &a);
  748. signadjust (TRUE, &a);
  749. psol = &(a.valleft->dsckind.opnd);
  750. psor = &(a.valright->dsckind.opnd);
  751. if (psol->dsegment) {
  752. /* clear Dcontext if have var-var */
  753. psor->dtype = (USHORT)((psor->dtype &
  754. (M_EXPLOFFSET | M_PTRSIZE | M_FORTYPE)) | M_RCONST);
  755. psor->dsegment = NULL;
  756. psor->dcontext = NULL;
  757. psor->dsize = 0;
  758. oblititem (a.valleft);
  759. a.valleft = NULL;
  760. }
  761. break;
  762. case OPMULT:
  763. #ifdef V386
  764. if (M_REGRESULT & (psol->dtype|psor->dtype))
  765. {
  766. if (cputype&P386) {
  767. idxcheck (2, &a);
  768. if (a.p->p->index&0x78)
  769. break;
  770. } else
  771. errorc (E_IRV);
  772. }
  773. #endif
  774. /* fall through */
  775. case OPDIV:
  776. valcheck (CALLABS, FALSE, &a);
  777. /* Both are constant */
  778. if (a.stkoper == OPMULT)
  779. psor->doffset = a.left * a.right;
  780. else if (a.right == 0)
  781. errorc (E_DVZ);
  782. else
  783. psor->doffset = a.left / a.right;
  784. if (psor->doffset == 0)
  785. psor->dsign = FALSE;
  786. else
  787. psor->dsign = (psol->dsign != psor->dsign);
  788. break;
  789. case OPHIGH:
  790. if (psor->dtype & M_RCONST) {
  791. if (psor->dsign) {
  792. psor->doffset = -(long)psor->doffset;
  793. psor->dsign = 0;
  794. }
  795. psor->doffset = psor->doffset >> 8 & 0xff;
  796. }
  797. psor->dtype |= M_HIGH;
  798. goto highlow;
  799. case OPLOW:
  800. if (psor->dtype & M_RCONST)
  801. psor->doffset &= 0xFF;
  802. psor->dtype |= M_LOW;
  803. highlow:
  804. psor->dsize = 1;
  805. if ((!(psor->dflag & XTERNAL && psor->dtype & M_EXPLOFFSET))
  806. && psor->dsegment
  807. && (psor->dtype & (M_EXPLOFFSET | M_SEGRESULT
  808. | M_REGRESULT | M_GROUPSEG | M_DATA | M_CODE)))
  809. errorc (E_CXP);
  810. break;
  811. case OPOFFSET:
  812. psor->fixtype = FOFFSET;
  813. if (!(psor->dsegment || psor->dflag == XTERNAL))
  814. errorc(E_OSG|E_WARN2);
  815. if (!(M_DATA & psor->dtype))
  816. psor->dcontext = NULL;
  817. psor->dtype = (USHORT)(
  818. (psor->dtype |
  819. M_RCONST | M_EXPLOFFSET) & ~(M_SEGRESULT));
  820. if (fSimpleSeg)
  821. makeGrpRel (psor);
  822. /* preserve OFFSET arg size it's a const */
  823. if ((psor->dsegment ||
  824. psor->dcontext ||
  825. psor->dflag == XTERNAL) &&
  826. !(M_PTRSIZE & psor->dtype))
  827. psor->dsize = 0;
  828. break;
  829. case OPLENGTH:
  830. case OPSIZE:
  831. /* Must be data associated */
  832. valcheck (CDATA, TRUE, &a);
  833. psol = &(a.valleft->dsckind.opnd);
  834. psor = &(a.valright->dsckind.opnd);
  835. if (a.stkoper == OPLENGTH)
  836. psor->doffset = psor->dlength;
  837. else
  838. psor->doffset =
  839. psor->dsize * psor->dlength;
  840. psor->dflag &= ~XTERNAL;
  841. break;
  842. case OPTYPE:
  843. a.right = psor->dsize;
  844. oblititem (a.valright);
  845. a.valright = defaultdsc ();
  846. psor = &(a.valright->dsckind.opnd);
  847. psor->doffset = a.right;
  848. a.p->p->base = 0;
  849. a.p->p->index = 0;
  850. break;
  851. case OPMASK:
  852. case OPWIDTH:
  853. /* Must be record or field */
  854. valcheck (CREC, TRUE, &a);
  855. if (psor->dextptr && psor->dflag != XTERNAL) {
  856. if (a.stkoper == OPWIDTH)
  857. if (psor->dextptr->symkind == REC)
  858. psor->doffset = psor->dextptr->length;
  859. else
  860. psor->doffset = psor->dextptr->symu.rec.recwid;
  861. else if (psor->dextptr->symkind == REC)
  862. psor->doffset = psor->dextptr->offset;
  863. else
  864. psor->doffset = psor->dextptr->symu.rec.recmsk;
  865. }
  866. break;
  867. case OPSTYPE:
  868. a.right = 0;
  869. if (errorcode == 0) {
  870. if (psor->dflag == XTERNAL)
  871. a.right |= 0x80; /* external */
  872. if (psor->dflag != UNDEFINED)
  873. a.right |= 0x20; /* defined */
  874. if (psor->dtype & M_DATA)
  875. a.right |= 0x02; /* data */
  876. if (psor->dtype & M_CODE)
  877. a.right |= 0x01; /* program */
  878. if ((a.p->p->base == 0) && (a.p->p->index == 0)) {
  879. if (psor->dtype == xltsymtoresult[REGISTER])
  880. a.right |= 0x10; /* register */
  881. else if (psor->dtype & M_RCONST)
  882. a.right |= 0x04; /* constant */
  883. else if (psor->dtype & M_DATA)
  884. a.right |= 0x08; /* direct */
  885. } else {
  886. a.p->p->base = 0;
  887. a.p->p->index = 0;
  888. }
  889. }
  890. oblititem (a.valright);
  891. a.valright = defaultdsc ();
  892. psor = &(a.valright->dsckind.opnd);
  893. psor->doffset = a.right;
  894. errorcode = 0;
  895. break;
  896. case OPLPAR:
  897. case OPLBRK:
  898. if (!(a.p->parenflag || a.p->p->exprdone))
  899. pushpar (a.p);
  900. else if (a.stkoper == OPLBRK)
  901. a.valright = regcheck (a.valright, FALSE, &a);
  902. psol = &(a.valleft->dsckind.opnd);
  903. psor = &(a.valright->dsckind.opnd);
  904. break;
  905. case OPMOD:
  906. valcheck (CALLABS, FALSE, &a);
  907. if (a.right == 0) {
  908. /* div 0 */
  909. errorc (E_DVZ);
  910. psor->doffset = 0;
  911. psor->dsign = FALSE;
  912. }
  913. else {
  914. psor->doffset = a.left % a.right;
  915. if (psor->doffset == 0 || !psol->dsign)
  916. psor->dsign = FALSE;
  917. else
  918. psor->dsign = TRUE;
  919. }
  920. break;
  921. case OPTHIS:
  922. valcheck (CLSIZE, TRUE, &a);
  923. /* Unary, right is size */
  924. psor->s = 0;
  925. psor->dsize = (USHORT)a.right;
  926. psor->doffset = pcoffset;
  927. psor->dsegment = pcsegment;
  928. if (a.right >= CSFAR_LONG)
  929. psor->dcontext = regsegment[CSSEG];
  930. break;
  931. case OPSHORT:
  932. valcheck (CCODE, TRUE, &a);
  933. /* Unary, must be code */
  934. psor->dtype |= M_SHRT;
  935. break;
  936. case OPPTR:
  937. valcheck (CLSIZE, FALSE, &a);
  938. if (psol->doffset >= CSFAR_LONG &&
  939. (M_RCONST == psor->dtype ||
  940. (psor->dcontext && (M_DATA&psor->dtype && !(M_CODE&psor->dtype))) ))
  941. errorc (E_NSO); /* Can't code_data */
  942. else {
  943. psor->dsize = (USHORT)a.left;
  944. if ((M_DATA & psol->dtype)
  945. && !(M_DATA & psor->dtype))
  946. psor->dcontext = NULL;
  947. /* Change code/data */
  948. psor->dtype = (USHORT)(
  949. (psor->dtype & ~(M_CODE | M_DATA) |
  950. (psol->dtype & (M_CODE | M_DATA))) &
  951. ~(M_FORTYPE) | (M_PTRSIZE));
  952. }
  953. break;
  954. case OPEQ:
  955. case OPGE:
  956. case OPGT:
  957. case OPLE:
  958. case OPLT:
  959. case OPNE:
  960. valcheck (CSAME, FALSE, &a);
  961. signadjust (TRUE, &a);
  962. /* Do signed R=L-R */
  963. psol = &(a.valleft->dsckind.opnd);
  964. psor = &(a.valright->dsckind.opnd);
  965. if (!fArth32)
  966. a.right &= 0xffff;
  967. switch (a.stkoper) {
  968. case OPEQ:
  969. a.right = (a.right == 0);
  970. break;
  971. case OPGE:
  972. a.right = !psor->dsign;
  973. break;
  974. case OPGT:
  975. a.right = (!psor->dsign && a.right);
  976. break;
  977. case OPLE:
  978. a.right = (psor->dsign || a.right == 0);
  979. break;
  980. case OPLT:
  981. a.right = psor->dsign;
  982. break;
  983. case OPNE:
  984. a.right = (a.right != 0);
  985. break;
  986. }
  987. /* Set Dsign if result TRUE */
  988. psor->doffset = a.right;
  989. psor->dsign = (a.right == 1);
  990. psor->dcontext = NULL;
  991. oblititem (a.valleft);
  992. a.valleft = NULL;
  993. break;
  994. case OPCOLON:
  995. /* <segment> : <var> */
  996. valcheck (CLSEG, FALSE, &a);
  997. if ((a.p->p->bracklevel || a.p->evalop == OPLBRK) &&
  998. (M_REGRESULT & (psol->dtype | psor->dtype)))
  999. errorc(E_ISR);
  1000. psor->dtype = (USHORT)((psor->dtype|M_EXPLCOLON|M_DATA) & ~M_RCONST);
  1001. if (psol->dsegment) {
  1002. if (psol->dsegment->symkind == GROUP)
  1003. psor->dtype |= M_GROUPSEG;
  1004. if (!psor->dsegment &&
  1005. !(M_REGRESULT & psol->dtype) &&
  1006. !(a.p->p->base || a.p->p->index))
  1007. psor->dsegment = psol->dsegment;
  1008. }
  1009. psor->dcontext = psol->dsegment;
  1010. break;
  1011. } /* operator case */
  1012. if (!inset (a.stkoper, parseset)) {
  1013. /* Have constant or segment result */
  1014. psor->dlength = 0;
  1015. psor->dsize = 0;
  1016. psor->sized = 0;
  1017. if (a.valleft)
  1018. psol->dsize = 0;
  1019. /* Have constant result( typeless ) */
  1020. if (a.stkoper != OPSEG) {
  1021. psor->dtype = (USHORT)((psor->dtype & M_FORTYPE) | M_RCONST);
  1022. psor->dsegment = NULL;
  1023. if (a.valleft)
  1024. psol->dtype &= ~M_PTRSIZE;
  1025. }
  1026. }
  1027. a.p->p->curresult = a.valright;
  1028. psor = &(a.p->p->curresult->dsckind.opnd);
  1029. if (!fArth32 && optyp != TDD)
  1030. psor->doffset &= 0xffff;
  1031. if (a.valleft) {
  1032. /* Might need to copy some info */
  1033. /* Prevent OPERATORs like +, -, . from
  1034. losing the [DATA] flag if it it is the
  1035. Left operand. This is ok, except when
  1036. surrounded by a PTR which will drop
  1037. segment override if not data type */
  1038. if (a.stkoper != OPCOLON)
  1039. psor->dtype |= psol->dtype & (M_DATA | M_CODE);
  1040. if (psor->dflag == KNOWN)
  1041. psor->dflag = psol->dflag;
  1042. if (!psor->dcontext)
  1043. psor->dcontext = psol->dcontext;
  1044. if (psor->dsize == 0)
  1045. psor->dsize = psol->dsize;
  1046. if (psor->fixtype == FCONSTANT)
  1047. psor->fixtype = psol->fixtype;
  1048. psor->dtype |= psol->dtype & (M_PTRSIZE|M_EXPLOFFSET|M_FORTYPE);
  1049. /* Above makes sure PTR or OFFSET is not lost */
  1050. oblititem (a.valleft);
  1051. a.valleft = NULL;
  1052. }
  1053. }
  1054. else { /* no operator case */
  1055. a.p->p->curresult = a.valright;
  1056. psor = &(a.p->p->curresult->dsckind.opnd);
  1057. a.p->parenflag = FALSE;
  1058. }
  1059. if (!a.p->p->lastitem) {
  1060. a.p->p->lastprec = 0;
  1061. a.p->p->curresult->prec = 0;
  1062. }
  1063. else if (a.p->p->lastitem->itype == OPERATOR) {
  1064. if ((a.p->p->lastitem->dsckind.opr.oidx == OPLBRK) ||
  1065. (a.p->p->lastitem->dsckind.opr.oidx == OPLPAR))
  1066. /* Stop evaluating back at paren */
  1067. a.p->p->lastprec = 0;
  1068. else {
  1069. a.p->p->lastprec = a.p->p->lastitem->prec;
  1070. if ((a.p->p->lastitem->dsckind.opr.oidx == OPUNPLUS) ||
  1071. (a.p->p->lastitem->dsckind.opr.oidx == OPUNMINUS))
  1072. /* Force eval */
  1073. a.p->p->lastitem->prec = a.p->p->lastprec = 20;
  1074. }
  1075. }
  1076. else
  1077. a.p->p->lastprec = a.p->p->lastitem->prec;
  1078. if (itemptr) {
  1079. oblititem (itemptr);
  1080. itemptr = NULL;
  1081. }
  1082. /* Hook rest of list in */
  1083. a.p->p->curresult->previtem = a.p->p->lastitem;
  1084. a.p->p->lastitem = a.p->p->curresult;
  1085. /* Push result back on */
  1086. if (!a.p->p->curresult->previtem && a.p->p->exprdone)
  1087. a.p->p->lastitem = NULL;
  1088. }
  1089. /*** evaluate - evaluate stack
  1090. *
  1091. * routine ();
  1092. *
  1093. * Entry
  1094. * Exit
  1095. * Returns
  1096. * Calls
  1097. */
  1098. VOID PASCAL CODESIZE
  1099. evaluate (
  1100. struct ar *p
  1101. ){
  1102. struct evalrec a;
  1103. a.p = p;
  1104. a.parenflag = FALSE;
  1105. a.evalop = OPNOTHING;
  1106. /* No paren or match to find */
  1107. a.curoper = itemptr;
  1108. if (a.curoper)
  1109. a.parenflag = !a.p->exprdone &&
  1110. (a.curoper->dsckind.opr.oidx == OPRPAR ||
  1111. a.curoper->dsckind.opr.oidx == OPRBRK);
  1112. if (a.parenflag)
  1113. a.evalop = (a.curoper->dsckind.opr.oidx == OPRPAR)? OPLPAR: OPLBRK;
  1114. do { /* Evaluate to OPERATOR */
  1115. evaltop (&a);
  1116. } while (a.p->lastitem && a.p->lastitem->previtem &&
  1117. (a.p->exprdone ||
  1118. (!a.parenflag && a.p->lastprec >= a.p->curprec ) ||
  1119. ( a.parenflag && a.idx != a.evalop)) );
  1120. /* stop if just value on expression stack */
  1121. itemptr = a.curoper;
  1122. if (a.p->lastprec == 0)
  1123. a.p->lastprec = a.p->curresult->prec;
  1124. if (!a.p->exprdone)
  1125. if (a.parenflag) {/* Push value and set prec */
  1126. if (!a.p->lastitem->previtem)/* start of expr */
  1127. a.p->lastprec = 0;
  1128. else
  1129. a.p->lastprec = a.p->lastitem->previtem->prec;
  1130. /* Restore preced */
  1131. a.p->lastitem->prec = a.p->lastprec;
  1132. oblititem (itemptr);
  1133. itemptr = NULL;
  1134. /* Destroy close paren */
  1135. }
  1136. else { /* Case 1, OPERATOR eval */
  1137. itemptr->previtem = a.p->lastitem;
  1138. a.p->lastitem = itemptr;
  1139. /* Push OPERATOR */
  1140. if (a.p->lastprec != 20)
  1141. a.p->lastprec = itemptr->prec;
  1142. }
  1143. }
  1144. /* Return a descriptor record to help instruction routines
  1145. generate the right code. The items are as follows:
  1146. mode:: Value 0..4 Corresponds to 8086 mod
  1147. 0 No displacement unless rm=6 in which
  1148. case this is direct mode with 2 bytes.
  1149. ( Arg is code or data, no indexing )
  1150. 1 Memory, 8 bit sign extended displace-
  1151. ment.( Using indexing, Rconst )
  1152. 2 Memory, 16 bit displacement.( Using
  1153. indexing, Rconst type )
  1154. 3 Register, rm is register code, not
  1155. indexing mode.( Was REGresult )
  1156. 4 Immediate mode.( arg was Rconst, no
  1157. indexing )
  1158. 386 modes are represented in an analogous way:
  1159. 3 Register, rm is register code, as above
  1160. 4 Immediate, as above
  1161. 5 No displacement indirect, unless rm=5,
  1162. in which case this is a direct mode with
  1163. 4 byte offset.
  1164. 6 Memory, 8 bit signed displacement
  1165. 7 Memory, 32 bit signed displacement
  1166. similarly, scaled modes are indicated with
  1167. the next group. if mode > 7, then rm contains
  1168. the value of the Scaled Index Byte (SIB) and
  1169. rm is implicitly 4.
  1170. 8 No displacement indirect, unless rm=5,
  1171. in which case this is a direct mode with
  1172. 4 byte offset.
  1173. 9 Memory, 8 bit signed displacement
  1174. 10 Memory, 32 bit signed displacement
  1175. rm :: Value 0..7 Corresponds to 8086 or 80386 r/m
  1176. Value Register Index 386 index
  1177. 0 AX AL EAX [BX][SI] [EAX]
  1178. 1 CX CL ECX [BX][DI] [ECX]
  1179. 2 DX DL EDX [BP][SI] [EDX]
  1180. 3 BX BL EBX [BP][DI] [EBX]
  1181. 4 SP AH ESP [SI] not implemented
  1182. 5 BP CH EBP [DI] Direct or [EBP]
  1183. 6 SI DH ESI Direct or [BP] [ESI]
  1184. 7 DI BH EDI [BX] [EDI]
  1185. Ridx contained pointer to index reg( DI | SI )
  1186. Rbas contained pointer to base reg( BX | BP )
  1187. Both were NIL if no indexing.
  1188. 386 registers have 8 added to them while in
  1189. the ar structure's base and index fields.
  1190. this is so we can tell eax from no register
  1191. at all.
  1192. w :: Boolean Corresponds to 8086 w flag. TRUE if
  1193. word mode, FALSE if byte mode.
  1194. s :: TRUE if value is -128..+127
  1195. Dsize :: Size of var/label or PTR value
  1196. FIXtype :: Type of fixup to feed to EMITxxx
  1197. routines:
  1198. Fpointer Label is FAR
  1199. Foffset Word, not constant
  1200. Fbaseseg SEG or seg/group name
  1201. Fgroupseg Offset to group
  1202. Fconstant Immediate data
  1203. Fhigh Take high of offset
  1204. Flow Take low of offset
  1205. Fnone No fixup( register )
  1206. Dtype :: Kind of value. Seg,group, const, Data
  1207. Dflag :: Value attr, undef,?,extern,forw,...
  1208. Doffset :: 16 bit value of result
  1209. Dsegment:: Copy of Dsegment. Pointer to segment of
  1210. result. If NIL, is constant. Will point
  1211. to segment name or possibly name of
  1212. external if external with no segment.
  1213. Dcontext:: Copy of Dcontext. Pointer to segment
  1214. from which to calculate offset. If :
  1215. OPERATOR used, Dcontext will be left
  1216. arg. If result is code label, will be
  1217. CS assume at time of label define. Else
  1218. will be NIL and then filled in with
  1219. segment register assume that contains
  1220. Dsegment.
  1221. seg :: Segment register of override. If none
  1222. given, will be 4. If register is not
  1223. known, will be 5.
  1224. */