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.

830 lines
14 KiB

  1. /* asmrec.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 <string.h>
  12. #include "asm86.h"
  13. #include "asmfcn.h"
  14. #include "asmctype.h"
  15. struct recpars {
  16. SYMBOL FARSYM *recptr;
  17. SYMBOL FARSYM *curfld;
  18. OFFSET recval;
  19. };
  20. struct recdef {
  21. USHORT fldcnt;
  22. USHORT reclen;
  23. SYMBOL FARSYM *recptr;
  24. SYMBOL FARSYM *curfld;
  25. short i;
  26. };
  27. VOID PASCAL CODESIZE recordspec PARMS((struct recdef *));
  28. VOID PASCAL CODESIZE recfill PARMS((struct recpars *));
  29. static OFFSET svpc = 0;
  30. static struct duprec FARSYM *pDUPCur;
  31. /*** checkvalue - insure value will fit in field
  32. *
  33. * checkvalue (width, sign, magnitude)
  34. *
  35. * Entry width = width of field
  36. * sign = sign of result
  37. * magnitude= magnitude of result
  38. * Exit none
  39. * Returns adjusted value
  40. * Calls none
  41. */
  42. OFFSET PASCAL CODESIZE
  43. checkvalue (
  44. register SHORT width,
  45. register char sign,
  46. register OFFSET mag
  47. ){
  48. register OFFSET mask;
  49. if (width == sizeof(OFFSET)*8)
  50. mask = OFFSETMAX;
  51. else
  52. mask = (1 << width) - 1;
  53. if (!sign) {
  54. if (width < sizeof(OFFSET)*8)
  55. if (mag > mask) {
  56. errorc (E_VOR);
  57. mag = mask;
  58. }
  59. }
  60. else {
  61. mag = OFFSETMAX - mag;
  62. mag++;
  63. if (width < sizeof(OFFSET)*8)
  64. if ((mag ^ OFFSETMAX) & ~mask) {
  65. errorc (E_VOR);
  66. mag = mask;
  67. }
  68. }
  69. return (mag & mask);
  70. }
  71. /*** recordspec - parse record field specification fld:wid[=val]
  72. *
  73. * recordspec (p);
  74. *
  75. * Entry p = pointer to record definition structure
  76. * Exit
  77. * Returns
  78. * Calls
  79. */
  80. VOID PASCAL CODESIZE
  81. recordspec (
  82. register struct recdef *p
  83. ){
  84. register SYMBOL FARSYM *fldptr;
  85. register USHORT width;
  86. register struct symbrecf FARSYM *s;
  87. char sign;
  88. OFFSET mag;
  89. getatom ();
  90. if (*naim.pszName) {
  91. if (!symFet ())
  92. symcreate (M_DEFINED | M_BACKREF, RECFIELD);
  93. else {
  94. if (symptr->symu.rec.recptr != p->recptr ||
  95. M_BACKREF & symptr->attr)
  96. errorn (E_SMD);
  97. symptr->attr |= M_BACKREF;
  98. }
  99. crefdef ();
  100. s = &(symptr->symu.rec);
  101. if (symptr->symkind != RECFIELD)
  102. /* Not field */
  103. errorn (E_SDK);
  104. else {
  105. /* Ptr to field */
  106. fldptr = symptr;
  107. if (!p->curfld)
  108. p->recptr->symu.rsmsym.rsmtype.rsmrec.reclist = fldptr;
  109. else
  110. p->curfld->symu.rec.recnxt = fldptr;
  111. /* New last field */
  112. p->curfld = fldptr;
  113. s->recptr = p->recptr;
  114. s->recnxt = NULL;
  115. p->fldcnt++;
  116. if (NEXTC () != ':')
  117. error (E_EXP,"colon");
  118. /* Get field width */
  119. width = (USHORT)exprconst ();
  120. if (skipblanks () == '=') {
  121. SKIPC ();
  122. mag = exprsmag (&sign);
  123. }
  124. else {
  125. sign = FALSE;
  126. mag = 0;
  127. }
  128. if (width == 0 ||
  129. p->reclen + width > wordsize*8) {
  130. STRNFCPY (save, p->curfld->nampnt->id);
  131. /*Overflow */
  132. error (E_VOR, save);
  133. width = 0;
  134. }
  135. s->recinit = checkvalue (width, sign, mag);
  136. s->recmsk = (OFFSET)((1L << width) - 1);
  137. s->recwid = (char)width;
  138. p->reclen += width;
  139. }
  140. }
  141. }
  142. /*** recorddefine - parse record definition
  143. *
  144. * recorddefine ();
  145. *
  146. * Entry
  147. * Exit
  148. * Returns
  149. * Calls
  150. */
  151. VOID PASCAL CODESIZE
  152. recorddefine ()
  153. {
  154. struct recdef a;
  155. struct symbrecf FARSYM *s;
  156. register SHORT cbRec;
  157. a.reclen = 0;
  158. a.fldcnt = 0;
  159. checkRes();
  160. if (!symFet ()) {
  161. /* Make record */
  162. symcreate (M_DEFINED | M_BACKREF, REC);
  163. }
  164. else
  165. symptr->attr |= M_BACKREF;
  166. /* This is def */
  167. crefdef ();
  168. if (symptr->symkind != REC)
  169. /* Wasn't record */
  170. errorn (E_SDK);
  171. else {
  172. /* Leftmost bit of record */
  173. a.reclen = 0;
  174. /*No record filed yet */
  175. a.curfld = NULL;
  176. /* In case error */
  177. symptr->symu.rsmsym.rsmtype.rsmrec.reclist = NULL;
  178. /* Pointer to record name */
  179. a.recptr = symptr;
  180. /* Parse record field list */
  181. BACKC ();
  182. do {
  183. SKIPC ();
  184. recordspec (&a);
  185. } while (skipblanks() == ',');
  186. /* Length of record in bits */
  187. cbRec = a.reclen;
  188. a.recptr->length = cbRec;
  189. a.recptr->offset = (OFFSET)((1L << cbRec) - 1);
  190. a.recptr->symtype = (cbRec > 16 )? 4: ((cbRec > 8)? 2: 1);
  191. /* # of fields in record */
  192. a.recptr->symu.rsmsym.rsmtype.rsmrec.recfldnum = (char)a.fldcnt;
  193. /* 1st field */
  194. a.curfld = a.recptr->symu.rsmsym.rsmtype.rsmrec.reclist;
  195. }
  196. /* For all the fields adjust the shift (stored in offset),
  197. * initial value and mask so the last field is right justified */
  198. while (a.curfld) {
  199. s = &(a.curfld->symu.rec);
  200. /* Start of field */
  201. cbRec = (cbRec > s->recwid)? cbRec - s->recwid: 0;
  202. /* Shift count */
  203. a.curfld->offset = cbRec;
  204. s->recinit <<= cbRec;
  205. s->recmsk <<= cbRec;
  206. a.curfld = s->recnxt; /* Next field */
  207. }
  208. }
  209. /*** recfill - get initial value for field in list
  210. *
  211. * recfill (p);
  212. *
  213. * Entry
  214. * Exit
  215. * Returns
  216. * Calls
  217. */
  218. VOID PASCAL CODESIZE
  219. recfill (
  220. register struct recpars *p
  221. ){
  222. register char cc;
  223. struct symbrecf FARSYM *s;
  224. char sign;
  225. OFFSET mag, t;
  226. if (!p->curfld) {
  227. /* More fields than exist */
  228. errorc (E_MVD);
  229. }
  230. else {
  231. s = &(p->curfld->symu.rec);
  232. if ((cc = skipblanks ()) == ',' || cc == '>') {
  233. /* Use default value */
  234. t = s->recinit;
  235. }
  236. else {
  237. /* Have an override */
  238. mag = exprsmag (&sign);
  239. t = checkvalue (s->recwid, sign, mag);
  240. /* Scale value */
  241. t <<= p->curfld->offset;
  242. }
  243. /* Add in new field */
  244. if (s->recwid)
  245. p->recval = (p->recval & ~(s->recmsk)) | t;
  246. p->curfld = s->recnxt;
  247. }
  248. }
  249. /*** recordparse - parse record specification
  250. *
  251. * recordparse ();
  252. *
  253. * Entry
  254. * Exit
  255. * Returns
  256. * Calls
  257. */
  258. OFFSET PASCAL CODESIZE
  259. recordparse ()
  260. {
  261. struct recpars a;
  262. struct symbrecf FARSYM *s;
  263. a.recptr = symptr; /* Current record */
  264. if (PEEKC () != '<')
  265. error (E_EXP,"<"); /* Must have < */
  266. else
  267. SKIPC ();
  268. /* No value yet */
  269. a.recval = 0;
  270. /* 1st field in record */
  271. a.curfld = a.recptr->symu.rsmsym.rsmtype.rsmrec.reclist;
  272. BACKC ();
  273. do { /* Fill in values */
  274. SKIPC ();
  275. recfill (&a);
  276. } while (skipblanks () == ',');
  277. while (a.curfld) {
  278. /* Fill in remaining defaults */
  279. s = &(a.curfld->symu.rec);
  280. if (s->recwid)
  281. a.recval = (a.recval & ~(s->recmsk)) | s->recinit;
  282. a.curfld = s->recnxt;
  283. }
  284. if (NEXTC () != '>') /* Must have > */
  285. error (E_EXP,">");
  286. return (a.recval); /* Value of record */
  287. }
  288. /*** recordinit - parse record allocation
  289. *
  290. * recordinit ();
  291. *
  292. * Entry
  293. * Exit
  294. * Returns
  295. * Calls
  296. */
  297. VOID PASCAL CODESIZE
  298. recordinit ()
  299. {
  300. initflag = TRUE;
  301. strucflag = FALSE; /* This is RECORD init */
  302. recptr = symptr;
  303. optyp = TDB;
  304. if (symptr->symtype == 2)
  305. optyp = TDW;
  306. #ifdef V386
  307. else if (symptr->symtype == 4)
  308. optyp = TDD;
  309. #endif
  310. datadefine ();
  311. initflag = FALSE;
  312. }
  313. /*** nodecreate - create one DUP record
  314. *
  315. * nodecreate ();
  316. *
  317. * Entry
  318. * Exit
  319. * Returns
  320. * Calls
  321. */
  322. struct duprec FARSYM * PASCAL CODESIZE
  323. nodecreate ()
  324. {
  325. register struct duprec FARSYM *node;
  326. node = (struct duprec FARSYM *)falloc (sizeof (*node), "nodecreate");
  327. node->rptcnt = 1;
  328. node->itemcnt = 0;
  329. node->duptype.dupnext.dup = NULL;
  330. node->itemlst = NULL;
  331. node->dupkind = NEST;
  332. return (node);
  333. }
  334. /*** strucdefine - define structure
  335. *
  336. * strucdefine ();
  337. *
  338. * Entry
  339. * Exit
  340. * Returns
  341. * Calls
  342. */
  343. VOID PASCAL CODESIZE
  344. strucdefine ()
  345. {
  346. checkRes();
  347. if (!symFet()) {
  348. /* Make STRUC */
  349. symcreate (M_DEFINED | M_BACKREF, STRUC);
  350. }
  351. else
  352. symptr->attr |= M_BACKREF;
  353. /* This is definition */
  354. crefdef ();
  355. if (symptr->symkind != STRUC)
  356. errorn (E_SDK);
  357. else {
  358. symptr->attr |= M_BACKREF;
  359. recptr = symptr; /* Pointer to STRUC name */
  360. recptr->symu.rsmsym.rsmtype.rsmstruc.strucfldnum = 0;
  361. if (! pass2) {
  362. recptr->symu.rsmsym.rsmtype.rsmstruc.type = typeIndex;
  363. typeIndex += 3;
  364. if (pStrucCur)
  365. pStrucCur->alpha = recptr;
  366. else
  367. pStrucFirst = recptr;
  368. pStrucCur = recptr;
  369. }
  370. /* No labeled fields yet */
  371. recptr->symu.rsmsym.rsmtype.rsmstruc.struclist = NULL;
  372. /* Delete old STRUC */
  373. scandup (recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody, oblitdup);
  374. recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody = nodecreate ();
  375. struclabel = NULL; /* No named fields */
  376. strucprev = NULL; /* No body yet */
  377. count = 0; /* No fields yet */
  378. strucflag = TRUE; /* We are STRUC not RECORD */
  379. svpc = pcoffset; /* Save normal PC */
  380. pcoffset = 0; /* Relative to STRUC begin */
  381. swaphandler = TRUE; /* Switch to STRUC builder */
  382. handler = HSTRUC;
  383. }
  384. }
  385. /*** strucbuild - build the struc block
  386. *
  387. * strucbuild ();
  388. *
  389. * Entry
  390. * Exit
  391. * Returns
  392. * Calls
  393. */
  394. VOID PASCAL CODESIZE
  395. strucbuild ()
  396. {
  397. labelflag = FALSE;
  398. optyp = 0;
  399. getatom ();
  400. #ifndef FEATURE
  401. if (naim.pszName[0] == '%' && naim.pszName[1] == 0) { /* expand all text macros */
  402. *begatom = ' ';
  403. substituteTMs();
  404. getatom();
  405. }
  406. #endif
  407. /* First, look for IF, ELSE & ENDIF stuff */
  408. if (fndir () && (opkind & CONDBEG)) {
  409. firstDirect();
  410. }
  411. else if (generate && *naim.pszName) {
  412. /* next, classify the current token, which is either
  413. * and ENDS, data label or data name */
  414. if (optyp == 0 || !fndir2 ()){
  415. /* first token was a label */
  416. switchname ();
  417. getatom ();
  418. optyp = 0;
  419. if (!fndir2 ())
  420. errorc(E_DIS);
  421. labelflag = TRUE; /* Do have label */
  422. switchname ();
  423. }
  424. if (optyp == TENDS) {
  425. if (!symFet () || symptr != recptr)
  426. errorc(E_BNE);
  427. /* Have end of STRUC */
  428. handler = HPARSE;
  429. swaphandler = TRUE;
  430. strucflag = FALSE;
  431. recptr->symu.rsmsym.rsmtype.rsmstruc.strucfldnum =
  432. /* # of fields */
  433. recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->itemcnt;
  434. if (pcoffset & 0xFFFF0000)
  435. errorc (E_DVZ);
  436. recptr->symtype = (USHORT)pcoffset; /* Size of STRUC */
  437. recptr->length = 1;
  438. pcdisplay ();
  439. /* Restore PC */
  440. pcoffset = svpc;
  441. }
  442. else if (! (optyp >= TDB && optyp <= TDW))
  443. errorc (E_DIS);
  444. else { /* Have another line of body */
  445. if (!strucprev) {
  446. /* Make first node */
  447. strucprev = nodecreate ();
  448. recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->
  449. duptype.dupnext.dup = strucprev;
  450. }
  451. else {
  452. strucprev->itemlst = nodecreate ();
  453. strucprev = strucprev->itemlst;
  454. }
  455. recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->itemcnt++;
  456. /* Add new data line to STRUC */
  457. datadefine ();
  458. strucprev->decltype = optyp;
  459. }
  460. }
  461. if (generate) {
  462. if (!ISTERM (skipblanks()))
  463. errorc (E_ECL);
  464. }
  465. listline ();
  466. }
  467. struct srec {
  468. struct duprec FARSYM *curfld;
  469. USHORT curlen;
  470. };
  471. /*** createduprec - create short data record with null data
  472. *
  473. * createduprec ();
  474. *
  475. * Entry
  476. * Exit
  477. * Returns
  478. * Calls
  479. */
  480. struct duprec FARSYM * PASCAL CODESIZE
  481. createduprec ()
  482. {
  483. register struct duprec FARSYM *newrec;
  484. newrec = (struct duprec FARSYM *)falloc (sizeof (*newrec), "createduprec");
  485. newrec->rptcnt = 1;
  486. /* Not a DUP */
  487. newrec->itemcnt = 0;
  488. newrec->itemlst = NULL;
  489. newrec->dupkind = ITEM;
  490. /* this also clears ddata and dup in other variants of struc */
  491. newrec->duptype.duplong.ldata = NULL;
  492. newrec->duptype.duplong.llen = 1;
  493. return (newrec);
  494. }
  495. /*** strucerror - generate structure error message
  496. *
  497. * strucerror ();
  498. *
  499. * Entry
  500. * Exit
  501. * Returns
  502. * Calls
  503. */
  504. struct duprec FARSYM * PASCAL CODESIZE
  505. strucerror (
  506. SHORT code,
  507. struct duprec FARSYM *node
  508. ){
  509. errorc (code);
  510. /* Get rid of bad Oitem */
  511. oblitdup (node);
  512. /* Make up a dummy */
  513. return (createduprec ());
  514. }
  515. /*** strucfill - fill in structure values
  516. *
  517. * strucfill ();
  518. *
  519. * Entry
  520. * Exit
  521. * Returns
  522. * Calls
  523. */
  524. VOID PASCAL CODESIZE
  525. strucfill ()
  526. {
  527. register struct duprec FARSYM *pOver;
  528. register struct duprec FARSYM *pInit;
  529. register char *cp;
  530. char svop;
  531. short i, cbCur;
  532. struct datarec drT;
  533. if (!pDUPCur) {
  534. errorc (E_MVD);
  535. return;
  536. }
  537. if (skipblanks() == ',' || PEEKC() == '>') {
  538. /* use default values */
  539. pOver = createduprec ();
  540. }
  541. else {
  542. /* Save operation type */
  543. svop = optyp;
  544. /* Original directive type */
  545. optyp = pDUPCur->decltype;
  546. pOver = datascan (&drT); /* Get item */
  547. optyp = svop;
  548. pInit = pDUPCur->duptype.dupnext.dup;
  549. cbCur = pInit->duptype.duplong.llen;
  550. if (pOver->dupkind == NEST)
  551. /* Bad override val */
  552. pOver = strucerror (E_ODI, pOver);
  553. else if (pDUPCur->itemcnt != 1 || pInit->itemcnt)
  554. /* Can't override field */
  555. pOver = strucerror (E_FCO, pOver);
  556. else if (pOver->dupkind != pInit->dupkind) {
  557. if (pInit->dupkind == ITEM)
  558. cbCur = pInit->duptype.dupitem.ddata->dsckind.opnd.dsize;
  559. }
  560. if (pOver->dupkind == LONG) {
  561. /* If too long, truncate */
  562. if ((i = pOver->duptype.duplong.llen) < cbCur) {
  563. /* Space fill short (after reallocating more space) */
  564. if (!(pOver->duptype.duplong.ldata =
  565. realloc (pOver->duptype.duplong.ldata, cbCur)))
  566. memerror("strucfil");
  567. cp = pOver->duptype.duplong.ldata + i;
  568. for (; i < cbCur; i++)
  569. *cp++ = ' ';
  570. }
  571. else if (pOver->duptype.duplong.llen > cbCur)
  572. errorc (E_OWL);
  573. pOver->duptype.duplong.llen = (unsigned char)cbCur;
  574. }
  575. if ((pOver->dupkind == pInit->dupkind) &&
  576. (pOver->dupkind == ITEM) && !errorcode)
  577. pOver->duptype.dupitem.ddata->dsckind.opnd.dsize =
  578. pInit->duptype.dupitem.ddata->dsckind.opnd.dsize;
  579. }
  580. pDUPCur = pDUPCur->itemlst;
  581. if (strucoveride)
  582. strclastover->itemlst = pOver;
  583. else
  584. strucoveride = pOver;
  585. strclastover = pOver;
  586. }
  587. /*** strucparse - parse structure specification
  588. *
  589. * strucparse ();
  590. *
  591. * Entry
  592. * Exit
  593. * Returns
  594. * Calls
  595. */
  596. struct duprec FARSYM * PASCAL CODESIZE
  597. strucparse ()
  598. {
  599. /* No items yet */
  600. strucoveride = NULL;
  601. recptr = symptr;
  602. if (skipblanks () != '<')
  603. error (E_EXP,"<");
  604. /* 1st default field */
  605. pDUPCur = recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody->duptype.dupnext.dup;
  606. initflag = FALSE;
  607. strucflag = FALSE;
  608. /* Build list of overrides */
  609. do {
  610. SKIPC ();
  611. strucfill ();
  612. } while (skipblanks () == ',');
  613. initflag = TRUE;
  614. strucflag = TRUE;
  615. while (pDUPCur) {/* Fill rest with overrides */
  616. /* Make dummy entry */
  617. strclastover->itemlst = createduprec ();
  618. strclastover = strclastover->itemlst;
  619. /* Advance to next field */
  620. pDUPCur = pDUPCur->itemlst;
  621. }
  622. if (PEEKC () != '>')
  623. error (E_EXP,">");
  624. else
  625. SKIPC ();
  626. return (recptr->symu.rsmsym.rsmtype.rsmstruc.strucbody);
  627. }
  628. /*** strucinit - initialize structure
  629. *
  630. * strucinit ();
  631. *
  632. * Entry
  633. * Exit
  634. * Returns
  635. * Calls
  636. */
  637. VOID PASCAL CODESIZE
  638. strucinit ()
  639. {
  640. initflag = TRUE;
  641. strucflag = TRUE;
  642. recptr = symptr;
  643. optyp = TMACRO;
  644. datadsize[TMACRO - TDB] = recptr->symtype;
  645. datadefine ();
  646. initflag = FALSE;
  647. strucflag = FALSE;
  648. }