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.

2831 lines
62 KiB

  1. /* asmopc.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. #include "asmopcod.h"
  16. static SHORT CODESIZE nolong(struct psop *);
  17. VOID CODESIZE pmovx(struct parsrec *);
  18. VOID CODESIZE psetcc(struct parsrec *);
  19. VOID CODESIZE pbit(struct parsrec *);
  20. VOID CODESIZE pbitscan(struct parsrec *);
  21. CODESIZE checkwreg(struct psop *);
  22. VOID PASCAL CODESIZE pclts (void);
  23. #define M_ESCAPE (M_PRELJMP | M_PCALL | M_PJUMP | M_PRETURN | M_PINT | M_PARITH | \
  24. M_PINOUT | M_PLOAD | M_PSTR | M_PESC | M_PBOUND | M_PARSL)
  25. #define M_ERRIMMED (M_PSHIFT | M_PARITH | M_PINCDEC | M_PCALL | M_PJUMP | \
  26. M_PMOV | M_PSTR | M_PRELJMP | M_PGENARG | M_PXCHG | \
  27. M_PBOUND | M_PCLTS | M_PDESCRTBL | M_PDTTRSW | M_PARSL | \
  28. M_PARPL | M_PVER)
  29. /* EMITcall decides what type of calljump is present and outputs
  30. the appropriate code. Coding of last 4 args to EMITcall:
  31. DIRto: Direct to different segment(inter)
  32. DIRin: DIRect in same segment(intra)
  33. INDto: Indirect to different segment(inter)
  34. INDin: Indirect in same segment(intra)
  35. */
  36. /*** emitcall - emit call
  37. *
  38. * emitcall (dirin, dirto, indin, indto, p);
  39. *
  40. * Entry
  41. * Exit
  42. * Returns
  43. * Calls
  44. */
  45. VOID
  46. PASCAL
  47. CODESIZE
  48. emitcall (
  49. UCHAR dirin,
  50. UCHAR dirto,
  51. UCHAR indin,
  52. UCHAR indto,
  53. struct parsrec *p
  54. )
  55. {
  56. register struct psop *pso; /* parse stack operand structure */
  57. char fNop = FALSE;
  58. pso = &(p->dsc1->dsckind.opnd);
  59. if (!isdirect(pso)) {
  60. /* Have indexing? */
  61. if (pso->dsize == 0) {
  62. /* make [BX] be word */
  63. pso->dsize = wordsize;
  64. pso->dtype |= xltsymtoresult[DVAR];
  65. } else if (pso->dsize >= CSFAR) {
  66. errorc (E_ASD);
  67. pso->dsize = wordsize;
  68. /* Data only, force word */
  69. }
  70. }
  71. if ((M_DATA & pso->dtype) && pso->dflag == UNDEFINED)
  72. pso->dflag = KNOWN;
  73. if (pso->dsize == CSNEAR ||
  74. (pso->dflag == UNDEFINED && !(M_PTRSIZE & pso->dtype))) {
  75. #ifndef FEATURE
  76. if (regsegment[CSSEG] == pFlatGroup)
  77. pso->dcontext = pFlatGroup;
  78. #endif
  79. if (regsegment[CSSEG] != pso->dcontext &&
  80. pso->dflag != XTERNAL)
  81. errorc (E_JCD); /* Can't go near to dif assume */
  82. pso->dsize = wordsize;
  83. pso->dtype |= M_SHRT;
  84. emitopcode (dirin);
  85. } else if (pso->dsize == CSFAR) {
  86. if (M_FORTYPE & pso->dtype) /* Forward far */
  87. errorc (E_FOF); /* Couldn't guess */
  88. pso->fixtype = FPOINTER;
  89. pso->dsize = wordsize;
  90. if (pso->dsegment) {
  91. /* target has different segment size */
  92. pso->dsize = pso->dsegment->symu.segmnt.use32;
  93. if (pso->dsize != wordsize) {
  94. if (!(M_BACKREF & pso->dsegment->attr))
  95. errorc (E_FOF); /* Forward mixed type */
  96. emitsize(0x66);
  97. if (wordsize == 4) { /* set modes so you get the */
  98. pso->mode = 0; /* correct OFFSET size */
  99. pso->rm = 6;
  100. fNop++; /* 16:32 -> 0x66 16:16 */
  101. } else {
  102. pso->fixtype = F32POINTER;
  103. pso->mode = 8;
  104. pso->rm = 5;
  105. }
  106. }
  107. }
  108. pso->dsize += 2;
  109. emitopcode (dirto);
  110. } else {
  111. #ifdef V386
  112. emit67(pso, NULL);
  113. #endif
  114. if ((pso->dsize == wordsize) || (pso->dsize == wordsize+2)) {
  115. /* Indirect */
  116. #ifdef V386
  117. /* if mode is through register, then it must be a near
  118. * call, so we can tell if its a foreign mode call */
  119. if (pso->dsize != wordsize && pso->mode == 3)
  120. emitsize(0x66);
  121. #endif
  122. emitescape (p->dsc1, p->defseg);
  123. emitopcode (255); /* must use defseg([BP]) */
  124. if (pso->dsize == wordsize || pso->mode == 3)
  125. /* Near indirect */
  126. emitmodrm ((USHORT)pso->mode, (USHORT)(indin>>3), pso->rm);
  127. else
  128. /* Far indirect */
  129. emitmodrm ((USHORT)pso->mode, (USHORT)(indto>>3), pso->rm);
  130. }
  131. #ifdef V386
  132. else if (pso->dsize == 2 || pso->dsize == 6) {
  133. /* indirect foreign mode call */
  134. /* in 16 bit mode normal near and far get done by the
  135. * above, and only 32 bit mode far gets here. for 32
  136. * bit normal only 16 bit near. the latter seems a bit
  137. * useless....*/
  138. emitsize(0x66);
  139. emitescape (p->dsc1, p->defseg);
  140. emitopcode (255); /* must use defseg([BP]) */
  141. if (pso->dsize == 2)
  142. /* Near indirect */
  143. emitmodrm ((USHORT)pso->mode, (USHORT)(indin>>3), pso->rm);
  144. else
  145. /* Far indirect */
  146. emitmodrm ((USHORT)pso->mode, (USHORT)(indto>>3), pso->rm);
  147. }
  148. #endif
  149. else
  150. /* Bad size */
  151. errorc (E_IIS);
  152. }
  153. emitrest (p->dsc1);
  154. if (fNop)
  155. emitnop();
  156. }
  157. /*** movesegreg - emit move to/from segment register
  158. *
  159. * movesegreg (first, p);
  160. *
  161. * Entry
  162. * Exit
  163. * Returns
  164. * Calls
  165. */
  166. VOID
  167. PASCAL
  168. CODESIZE
  169. movesegreg (
  170. char first,
  171. struct parsrec *p
  172. )
  173. {
  174. register struct psop *pso1; /* parse stack operand structure */
  175. register struct psop *pso2; /* parse stack operand structure */
  176. DSCREC *t;
  177. if (!first) {
  178. if (p->dsc1->dsckind.opnd.mode != 3 && impure)
  179. /* MOV cs:mem,segreg */
  180. errorc (E_IMP);
  181. t = p->dsc1;
  182. p->dsc1 = p->dsc2;
  183. p->dsc2 = t;
  184. }
  185. pso1 = &(p->dsc1->dsckind.opnd);
  186. pso2 = &(p->dsc2->dsckind.opnd);
  187. if ((pso2->dsize | wordsize) == 6)
  188. emitsize(0x66);
  189. emitopcode ((UCHAR)(first? 142: 140));
  190. errorimmed (p->dsc2);
  191. #ifdef V386
  192. rangecheck (&pso1->rm, (UCHAR)((cputype&P386)?5:3));
  193. #else
  194. rangecheck (&pso1->rm, (UCHAR)3);
  195. #endif
  196. if ((pso2->mode == 3)
  197. && (pso2->dsegment->symu.regsym.regtype == SEGREG))
  198. errorc (E_WRT); /* MOV segreg,segreg not allowed */
  199. if (pso2->sized && !pso2->w)
  200. errorc (E_IIS);
  201. if (first && (pso1->rm == CSSEG))
  202. /* CS illegal */
  203. errorc (E_CSI);
  204. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  205. emitrest (p->dsc2);
  206. }
  207. #ifdef V386
  208. /*** movecreg - emit move to/from control/debug/test register
  209. *
  210. * movecreg (first, p);
  211. *
  212. * Entry
  213. * Exit
  214. * Returns
  215. * Calls
  216. */
  217. VOID
  218. PASCAL
  219. CODESIZE
  220. movecreg (
  221. char first,
  222. struct parsrec *p
  223. )
  224. {
  225. register struct psop *pso1; /* parse stack operand structure */
  226. register struct psop *pso2; /* parse stack operand structure */
  227. UCHAR opbase;
  228. if ((cputype&(P386|PROT)) != (P386|PROT)) {
  229. errorc(E_WRT);
  230. return;
  231. }
  232. emitopcode (0x0F);
  233. pso1 = &(p->dsc1->dsckind.opnd);
  234. opbase = 0x22;
  235. if (first)
  236. pso2 = &(p->dsc2->dsckind.opnd);
  237. else {
  238. opbase = 0x20;
  239. pso2 = pso1;
  240. pso1 = &(p->dsc2->dsckind.opnd);
  241. }
  242. if ((pso2->dsegment->symkind != REGISTER)
  243. || (pso2->dsegment->symu.regsym.regtype != DWRDREG))
  244. errorc (E_OCI);
  245. if ((pso1->rm&030) == 020) /* test register */
  246. opbase += 2;
  247. emitopcode((UCHAR)(opbase + (pso1->rm >> 3)));
  248. emitmodrm((USHORT)3, (USHORT)(pso1->rm & 7), (USHORT)(pso2->rm & 7));
  249. if (pso2->mode != 3) /* only allowed to from register */
  250. errorc(E_MBR);
  251. }
  252. #endif
  253. /*** emitmove - emit code for MOV reg and MOV accum
  254. *
  255. * emitmove (opcode, first, p);
  256. *
  257. * Entry
  258. * Exit
  259. * Returns
  260. * Calls
  261. */
  262. VOID
  263. PASCAL
  264. CODESIZE
  265. emitmove (
  266. UCHAR opc,
  267. char first,
  268. struct parsrec *p
  269. )
  270. {
  271. DSCREC *t;
  272. char accummove;
  273. register struct psop *pso1; /* parse stack operand structure */
  274. register struct psop *pso2; /* parse stack operand structure */
  275. accummove = (opc == 160);
  276. if (!first) {
  277. t = p->dsc1;
  278. p->dsc1 = p->dsc2;
  279. p->dsc2 = t;
  280. }
  281. pso1 = &(p->dsc1->dsckind.opnd);
  282. pso2 = &(p->dsc2->dsckind.opnd);
  283. emit66 (pso1, pso2);
  284. if ((pso1->dsize != pso2->dsize) && pso2->sized)
  285. errorc (E_OMM);
  286. emitopcode ((UCHAR)(opc + ((accummove != first)? 2: 0) + pso1->w));
  287. errorimmed (p->dsc2);
  288. if (!accummove)
  289. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  290. emitrest (p->dsc2);
  291. }
  292. /*** moveaccum - move to/from accumulator and direct address
  293. *
  294. * moveaccum (first, p);
  295. *
  296. * Entry
  297. * Exit
  298. * Returns
  299. * Calls
  300. */
  301. VOID
  302. PASCAL
  303. CODESIZE
  304. moveaccum (
  305. char first,
  306. struct parsrec *p
  307. )
  308. {
  309. if (!first && p->dsc1->dsckind.opnd.mode != 3 && impure)
  310. errorc (E_IMP);
  311. emitmove (160, first, p);
  312. }
  313. /*** movereg - emit general move between register and memory
  314. *
  315. * movereg (first, p);
  316. *
  317. * Entry
  318. * Exit
  319. * Returns
  320. * Calls
  321. */
  322. VOID
  323. PASCAL
  324. CODESIZE
  325. movereg (
  326. char first,
  327. struct parsrec *p
  328. )
  329. {
  330. register struct psop *pso2; /* parse stack operand structure */
  331. char flag;
  332. flag = FALSE;
  333. pso2 = &(p->dsc2->dsckind.opnd);
  334. /* Is not special */
  335. if (pso2->mode == 3)
  336. /* 2nd is reg */
  337. switch (pso2->dsegment->symu.regsym.regtype) {
  338. case SEGREG:
  339. /* Catch 2nd is SEGREG */
  340. movesegreg (FALSE, p);
  341. return;
  342. #ifdef V386
  343. case CREG:
  344. /* Catch 2nd is SEGREG */
  345. movecreg (FALSE, p);
  346. return;
  347. #endif
  348. }
  349. if (p->dsc1->dsckind.opnd.mode != 3 && impure)
  350. errorc (E_IMP);
  351. emitmove (136, first, p);
  352. }
  353. /*** segdefault - return default segment for operand
  354. *
  355. * seg = segdefault (op);
  356. *
  357. * Entry
  358. * Exit
  359. * Returns
  360. * Calls
  361. */
  362. USHORT
  363. PASCAL
  364. CODESIZE
  365. segdefault (
  366. register char goo
  367. )
  368. {
  369. register USHORT defseg;
  370. register char op;
  371. defseg = NOSEG;
  372. if (1 << goo & xoptoseg[opctype])
  373. defseg = DSSEG;
  374. if (opctype == PSTR) {
  375. op = (opcbase == O_CMPS || opcbase == O_LODS || opcbase == O_OUTS);
  376. defseg = ((goo == FIRSTDS) != op)? ESSEG: DSSEG;
  377. }
  378. return (defseg);
  379. }
  380. /*** errorover -
  381. *
  382. * errorover (seg);
  383. *
  384. * Entry
  385. * Exit
  386. * Returns
  387. * Calls
  388. */
  389. VOID
  390. PASCAL
  391. CODESIZE
  392. errorover (
  393. char seg
  394. )
  395. {
  396. if (seg != ESSEG && seg != NOSEG)
  397. errorc (E_OES);
  398. }
  399. /*** checksize - check for memory s byte and immed is word
  400. *
  401. * checksize (p);
  402. *
  403. * Entry
  404. * Exit
  405. * Returns
  406. * Calls
  407. */
  408. SHORT
  409. PASCAL
  410. CODESIZE
  411. checksize (
  412. struct parsrec *p
  413. )
  414. {
  415. OFFSET off;
  416. register struct psop *pso1; /* parse stack operand structure */
  417. register struct psop *pso2; /* parse stack operand structure */
  418. pso1 = &(p->dsc1->dsckind.opnd);
  419. pso2 = &(p->dsc2->dsckind.opnd);
  420. if (pso1->sized) {
  421. /* Only set dsc2->w if dsc2 has no size. Set
  422. * dsc1->w to dsc2->w, not TRUE(WORD). [BX],WRD PTR 5 */
  423. if (!pso2->sized)
  424. pso2->w = pso1->w;
  425. } else
  426. pso1->w = pso2->w;
  427. if (pso2->fixtype == FCONSTANT) { /* check for constant overflow */
  428. off = (pso2->doffset > 0x7fffffff)? -(long)pso2->doffset: pso2->doffset;
  429. if ((pso1->dsize == 1 && off > 0xff && off < 0xff00) ||
  430. (pso1->dsize == 2 && off > 0xffff))
  431. errorc (E_VOR);
  432. }
  433. /* check fixup'ed constants with implied sizes */
  434. if ((pso1->sized && pso1->dsize != 2) &&
  435. (pso2->dtype & (M_SEGMENT) ||
  436. pso2->fixtype == FGROUPSEG || pso2->fixtype == FBASESEG))
  437. errorc (E_OMM);
  438. if (!(pso1->sized || pso2->sized))
  439. errorc (E_OHS);
  440. /* Also need to set <w> field if operand 1 sized */
  441. if (pso1->sized) {/* Force size */
  442. pso2->dsize = pso1->dsize;
  443. pso2->w = pso1->w;
  444. }
  445. if (pso2->dsize == 1 && pso2->dflag == XTERNAL
  446. && pso2->fixtype != FHIGH)
  447. /* makes sure linker puts out correct stuff */
  448. pso2->fixtype = FLOW;
  449. return(0);
  450. }
  451. /*** opcode - process opcode and emit code
  452. *
  453. * opcode ();
  454. *
  455. * Entry
  456. * Exit
  457. * Returns
  458. * Calls
  459. */
  460. SHORT
  461. PASCAL
  462. CODESIZE
  463. opcode ()
  464. {
  465. struct parsrec a;
  466. register struct psop *pso1; /* parse stack operand structure */
  467. register struct psop *pso2; /* parse stack operand structure */
  468. long opctypemask; /* 1L << opctype */
  469. char leaflag;
  470. a.dsc1 = a.dsc2 = NULL;
  471. pso1 = pso2 = NULL;
  472. impure = FALSE;
  473. if (xoptoargs[opctype] != NONE) {
  474. /* Evaulate 1st arg */
  475. a.dirscan = lbufp;
  476. /* In case JMP should be SHORT */
  477. a.defseg = (unsigned char)segdefault (FIRSTDS);
  478. a.dsc1 = expreval (&a.defseg);
  479. if (noexp && (xoptoargs[opctype] == ONE
  480. || xoptoargs[opctype] == TWO))
  481. errorc(E_MDZ);
  482. if ((pso1 = &(a.dsc1->dsckind.opnd))
  483. && pso1->dtype & M_STRUCTEMPLATE)
  484. errorc(E_IOT);
  485. /* Give error so sizes >wordsize and not CODE don't get thru */
  486. if (!((opctypemask = 1L << opctype) & (M_PLOAD | M_PCALL | M_PJUMP | M_PDESCRTBL))
  487. && ((pso1->dsize > wordszdefault) &&
  488. (pso1->dsize < CSFAR)))
  489. if (pso1->mode != 4) {
  490. errorc (E_IIS);
  491. /* No error if cst */
  492. /* Don't allow CSFAR or CSNEAR if not CODE opcode */
  493. pso1->dsize = wordszdefault;
  494. }
  495. if (!(opctypemask & (M_PRELJMP | M_PCALL | M_PJUMP)))
  496. if (pso1->dsize >= CSFAR)
  497. errorc (E_IIS);
  498. if (!(opctypemask & M_ESCAPE))
  499. emitescape (a.dsc1, a.defseg);
  500. if (opctypemask & M_ERRIMMED)
  501. /* 1st operand not immediate */
  502. errorimmed (a.dsc1);
  503. if (!(opctypemask & (M_PMOV | M_PSTACK)))
  504. /* Give error if segment reg used */
  505. errorsegreg (a.dsc1);
  506. if (opctypemask & (M_PRETURN | M_PINT | M_PESC | M_PENTER))
  507. forceimmed (a.dsc1);
  508. if ((xoptoargs[opctype] == TWO) || ((opctype == PSTR) &&
  509. ((opcbase == O_MOVS) || (opcbase == O_CMPS) ||
  510. (opcbase == O_INS) || (opcbase == O_OUTS)))) {
  511. /* Two args or 2 arg string oper */
  512. if (NEXTC () != ',')
  513. error (E_EXP,"comma");
  514. leaflag = (opcbase == O_LEA)? TRUE: FALSE;
  515. a.defseg = (unsigned char)segdefault (SECONDDS);
  516. a.dsc2 = expreval (&a.defseg);
  517. if (noexp)
  518. errorc(E_MDZ);
  519. if ((pso2 = &(a.dsc2->dsckind.opnd))
  520. && pso2->dtype & M_STRUCTEMPLATE)
  521. errorc(E_IOT);
  522. /* IF LEA(215), then never segment prefix */
  523. if ((opcbase != O_LEA) && (opctype != PSTR))
  524. emitescape (a.dsc2, a.defseg);
  525. if (opctypemask & (M_PLOAD | M_PXCHG | M_PESC |
  526. M_PSTR | M_PBOUND | M_PARSL | M_PARPL))
  527. errorimmed (a.dsc2);
  528. if (opctype != PMOV)
  529. /* Give error if SEGREG and not a MOV opcode */
  530. errorsegreg (a.dsc2);
  531. if (!(opctypemask & (M_PLOAD | M_PBOUND)) &&
  532. (pso2->dsize > 2 &&
  533. #ifdef V386
  534. ( !(cputype & P386) || pso2->dsize != 4) &&
  535. #endif
  536. pso2->dsize < CSFAR))
  537. /* Give error so sizes > 2 and not CODE don't
  538. * get thru */
  539. if (pso2->mode != 4)
  540. errorc (E_IIS);
  541. if (pso2->dsize >= CSFAR && !leaflag)
  542. /* Don't allow CSFAR or CSNEAR if not
  543. code opcode. But allow LEA since
  544. it is untyped anyway. */
  545. errorc (E_IIS);
  546. }
  547. }
  548. #ifdef V386
  549. /* for most instructions, the 386 0x66 prefix is appropriate.
  550. * for some classes, we either never allow it, or do some
  551. * special handling specific to the instruction. */
  552. if (cputype & P386) {
  553. switch (opctype) {
  554. default:
  555. emit67(pso1, pso2);
  556. emit66(pso1, pso2);
  557. break;
  558. case PMOV:
  559. case PMOVX:
  560. case PLOAD:
  561. case PSHIFT:
  562. case PSTACK:
  563. case PSTR:
  564. case PARPL:
  565. case PDTTRSW:
  566. case PDESCRTBL:
  567. emit67(pso1, pso2);
  568. break;
  569. case PCALL:
  570. case PJUMP:
  571. case PRELJMP:
  572. case PENTER:
  573. case PNOARGS:
  574. case PESC:
  575. case PRETURN:
  576. case PINT:
  577. case PINOUT:
  578. case PARITH:
  579. break;
  580. }
  581. }
  582. #endif
  583. switch (opctype) {
  584. case PNOARGS:
  585. pnoargs ();
  586. break;
  587. case PJUMP:
  588. case PRELJMP:
  589. preljmp (&a);
  590. break;
  591. case PSHIFT:
  592. pshift (&a);
  593. break;
  594. case PSTACK:
  595. pstack (&a);
  596. break;
  597. case PARITH:
  598. parith (&a);
  599. break;
  600. case PBOUND:
  601. pbound (&a);
  602. break;
  603. case PENTER:
  604. penter (&a);
  605. break;
  606. case PCLTS:
  607. pclts ();
  608. break;
  609. case PDESCRTBL:
  610. pdescrtbl (&a);
  611. break;
  612. case PDTTRSW:
  613. pdttrsw (&a);
  614. break;
  615. case PVER:
  616. pver (&a);
  617. break;
  618. case PARSL:
  619. parsl (&a);
  620. break;
  621. case PARPL:
  622. parpl (&a);
  623. break;
  624. case PRETURN:
  625. preturn (&a);
  626. break;
  627. case PINCDEC:
  628. pincdec (&a);
  629. break;
  630. case PINT:
  631. pint (&a);
  632. break;
  633. case PINOUT:
  634. pinout (&a);
  635. break;
  636. case PLOAD:
  637. pload (&a);
  638. break;
  639. case PCALL:
  640. emitcall (232, 154, 16, 24, &a);
  641. break;
  642. case PMOV:
  643. pmov (&a);
  644. break;
  645. case PGENARG:
  646. pgenarg (&a);
  647. break;
  648. case PXCHG:
  649. pxchg (&a);
  650. break;
  651. case PESC:
  652. pesc (&a);
  653. break;
  654. case PREPEAT:
  655. prepeat (&a);
  656. break;
  657. case PSTR:
  658. pstr (&a);
  659. break;
  660. case PXLAT:
  661. pxlat (&a);
  662. break;
  663. #ifdef V386
  664. case PMOVX:
  665. pmovx (&a);
  666. break;
  667. case PSETCC:
  668. psetcc (&a);
  669. break;
  670. case PBIT:
  671. pbit (&a);
  672. break;
  673. case PBITSCAN:
  674. pbitscan (&a);
  675. break;
  676. #endif
  677. }
  678. if (a.dsc1)
  679. dfree ((char *)a.dsc1 );
  680. if (a.dsc2)
  681. dfree ((char *)a.dsc2 );
  682. if (pcsegment) {
  683. pcsegment->symu.segmnt.hascode = 1;
  684. }
  685. return (0);
  686. }
  687. /*** pnoargs - no arguments
  688. *
  689. * pnoargs ();
  690. *
  691. * Entry
  692. * Exit
  693. * Returns
  694. * Calls
  695. */
  696. #ifdef V386
  697. UCHAR stackOps[] = {O_PUSHA, O_PUSHAD,
  698. O_POPA, O_POPAD,
  699. O_PUSHF, O_PUSHFD,
  700. O_POPF, O_POPFD,
  701. O_IRET, O_IRETD,
  702. NULL
  703. };
  704. #endif
  705. VOID
  706. PASCAL
  707. CODESIZE
  708. pnoargs ()
  709. {
  710. /* some no argument instructions have an implied arg which determines
  711. * whether to do the 386 66 prefix. that this is the case is encoded
  712. * in the modrm in the op code table. -Hans */
  713. #ifdef V386
  714. if (modrm != 0 && modrm <= 4 && modrm != wordsize) {
  715. emitsize(0x66);
  716. if (strchr(stackOps, (UCHAR) opcbase))
  717. errorc (E_ONW);
  718. }
  719. #endif
  720. emitopcode (opcbase);
  721. if (opcbase == O_AAM || opcbase == O_AAD)
  722. /* emit modrm byte for AAD/AAM* */
  723. emitopcode (modrm);
  724. }
  725. /*** preljmp - Relative jump -128..+127
  726. *
  727. * preljmp (p);
  728. *
  729. * Entry
  730. * Exit
  731. * Returns
  732. * Calls
  733. */
  734. VOID
  735. PASCAL
  736. CODESIZE
  737. preljmp (
  738. struct parsrec *p
  739. )
  740. {
  741. register struct psop *pso1; /* parse stack operand structure */
  742. register SHORT cPadNop;
  743. SHORT rangeisshort;
  744. #ifdef V386
  745. SHORT maybelong;
  746. #else
  747. #define maybelong 0
  748. #endif
  749. pso1 = &(p->dsc1->dsckind.opnd);
  750. #ifdef V386
  751. maybelong = (cputype & P386) && !nolong(pso1) && pso1->dsize != CSFAR;
  752. #endif
  753. rangeisshort = shortrange(p);
  754. cPadNop = 0;
  755. if (opcbase == O_JMP) {
  756. if (pso1->dtype & M_SHRT ||
  757. rangeisshort && pso1->dflag != XTERNAL) {
  758. opcbase += 2;
  759. if (rangeisshort == 2 &&
  760. !(pso1->dtype & M_SHRT)) {
  761. cPadNop = wordsize;
  762. errorc(E_JSH);
  763. if (M_PTRSIZE & pso1->dtype && pso1->dsize == CSFAR)
  764. cPadNop += 2;
  765. }
  766. } else { /* Is normal jump */
  767. emitcall (opcbase, 234, 32, 40, p);
  768. return;
  769. }
  770. }
  771. if (!(M_CODE & pso1->dtype))
  772. errorc (E_ASC);
  773. /* an extrn may have no segment with it but still be near */
  774. if (pso1->dsegment != pcsegment && !(maybelong && !pso1->dsegment))
  775. errorc (E_NIP);
  776. if (pso1->dtype & (M_HIGH | M_LOW))
  777. errorc (E_IOT);
  778. if (M_SHRT & pso1->dtype) {
  779. if (pass2 && !rangeisshort)
  780. errorc (E_JOR);
  781. } else if (!rangeisshort && !maybelong)
  782. error (E_JOR, (char *)NULL); /* common pass1 error */
  783. #ifdef V386
  784. if (maybelong && !(M_SHRT & pso1->dtype) &&
  785. (!rangeisshort || pso1->dflag == XTERNAL)) {
  786. /* 386 long conditional branches */
  787. emitopcode(0x0f);
  788. emitopcode((UCHAR)(0x80 | (opcbase&0xf)));
  789. pso1->dtype |= M_SHRT;
  790. emitrest(p->dsc1);
  791. return;
  792. }
  793. #endif
  794. emitopcode (opcbase);
  795. if (pso1->dflag == XTERNAL) { /* EXTERNAL jump */
  796. pso1->dsize = 1;
  797. pso1->fixtype = FLOW; /* SHORT to EXTERNAL */
  798. pso1->dtype |= M_SHRT; /* One byte result */
  799. emitOP (pso1);
  800. } else
  801. emitopcode ((UCHAR)pso1->doffset);
  802. while (--cPadNop > 0)
  803. emitnop();
  804. }
  805. #ifdef V386
  806. /* most 386 conditional jumps can take a long or short form. these can
  807. * only take a short form */
  808. static
  809. SHORT
  810. CODESIZE
  811. nolong(
  812. register struct psop *pso1
  813. )
  814. {
  815. switch (opcbase) {
  816. case O_JCXZ:
  817. case O_LOOP:
  818. case O_LOOPZ:
  819. case O_LOOPNZ:
  820. #ifdef V386
  821. pso1->dtype |= M_SHRT;
  822. pso1->dtype &= ~M_PTRSIZE;
  823. /* allow `loop word ptr label' for cx|ecx overide */
  824. if (modrm && modrm != wordsize ||
  825. pso1->sized && pso1->dsize != wordsize &&
  826. (pso1->dsize == 4 || pso1->dsize == 2)) {
  827. pso1->dtype = (USHORT)((pso1->dtype & ~M_DATA) | M_CODE);
  828. emitsize(0x67);
  829. }
  830. #endif
  831. return(1);
  832. default:
  833. return(0);
  834. }
  835. }
  836. #endif
  837. /*** shortrange - check range of short jump
  838. *
  839. * flag = shortrange (p);
  840. *
  841. * Entry
  842. * Exit
  843. * Returns 1 for short jump, not shortened
  844. * 2 for forward label shortened
  845. * 0 for not short jmp
  846. * Calls
  847. */
  848. SHORT
  849. PASCAL
  850. CODESIZE
  851. shortrange (
  852. struct parsrec *p
  853. )
  854. {
  855. register struct psop *pso1; /* parse stack operand structure */
  856. register OFFSET disp;
  857. pso1 = &(p->dsc1->dsckind.opnd);
  858. if (pso1->dtype & M_PTRSIZE
  859. #ifdef V386
  860. && !((cputype & P386) && (pso1->dsize == CSNEAR))
  861. #endif
  862. )
  863. if (opcbase == O_JMP) {
  864. if (!isdirect(pso1))
  865. return (0);
  866. } else
  867. errorc (E_IIS|E_WARN1);
  868. if (pso1->dflag == XTERNAL && pso1->dsize == CSNEAR)
  869. return (1);
  870. if (pso1->dsegment == pcsegment && M_CODE&pso1->dtype &&
  871. pso1->dflag != UNDEFINED) {
  872. if (pso1->dflag == XTERNAL)
  873. return (1);
  874. if (pcoffset + 2 < pso1->doffset) {
  875. /* Forward */
  876. disp = (pso1->doffset - pcoffset) - 2;
  877. CondJmpDist = disp - 127;
  878. /* Get displace, only jump shorten for explicid
  879. * forward jumps */
  880. if (disp < 128)
  881. if (pso1->dflag == KNOWN ||
  882. opcbase == O_JMP || !(cputype&P386) ||
  883. (cputype&P386 && pso1->dtype & M_SHRT)) {
  884. pso1->doffset = disp;
  885. if (pso1->dflag == KNOWN)
  886. return(1);
  887. else
  888. return (2);
  889. } else
  890. errorc(E_JSH);
  891. } else {
  892. /* Backwards jump */
  893. disp = (pcoffset + 2) - pso1->doffset;
  894. CondJmpDist = disp - 128;
  895. if (disp < 129) {
  896. pso1->doffset = 256 - disp;
  897. return (1);
  898. }
  899. }
  900. }
  901. return (FALSE);
  902. }
  903. /*** pshift - shift opcodes
  904. *
  905. * pshift (p);
  906. *
  907. * Entry
  908. * Exit
  909. * Returns
  910. * Calls
  911. */
  912. VOID
  913. PASCAL
  914. CODESIZE
  915. pshift (
  916. struct parsrec *p
  917. )
  918. {
  919. register struct psop *pso1; /* parse stack operand structure */
  920. register struct psop *pso2; /* parse stack operand structure */
  921. DSCREC *op3;
  922. pso1 = &(p->dsc1->dsckind.opnd);
  923. pso2 = &(p->dsc2->dsckind.opnd);
  924. if (impure)
  925. errorc (E_IMP);
  926. #ifdef V386
  927. /* Shift/rotate opcodes */
  928. if (pso1->dsize >= 2 && pso1->dsize != wordsize)
  929. emitsize(0x66);
  930. /* parse 3rd operand for SHLD and SHRD */
  931. /* note that we wont have even gotten here if not 386 */
  932. if (opcbase == O_SHRD || opcbase == O_SHLD) {
  933. if (pso1->dsize != pso2->dsize)
  934. errorc (E_OMM);
  935. pso2->dsegment = NULL; /* for checksize */
  936. checksize (p);
  937. emitopcode(0x0f);
  938. checkwreg(pso2);
  939. if (NEXTC() == ',') {
  940. op3 = expreval (&nilseg);
  941. if (op3->dsckind.opnd.mode == 3 && op3->dsckind.opnd.rm == 1 && !op3->dsckind.opnd.w)
  942. emitopcode((UCHAR)(opcbase | 1));
  943. else {
  944. forceimmed (op3);
  945. emitopcode(opcbase);
  946. }
  947. emitmodrm ((USHORT)pso1->mode, (USHORT)(pso2->rm & 7), pso1->rm);
  948. /* Emit any effective address */
  949. emitrest (p->dsc1);
  950. /* and the immediate if appropriate */
  951. if (op3->dsckind.opnd.mode == 4)
  952. emitrest (op3);
  953. } else error(E_EXP,"comma");
  954. return;
  955. }
  956. #endif
  957. if (pso2->mode == 3 && pso2->rm == 1 && pso2->dsize == 1)
  958. /* Have CL now */
  959. emitopcode ((UCHAR)(0xD2 + pso1->w));
  960. /* * 1st byte * */
  961. else {
  962. /* Shift count is 1 */
  963. forceimmed (p->dsc2);
  964. if (pso2->doffset == 1)
  965. /* * 1st byte */
  966. emitopcode ((UCHAR)(0xD0 + pso1->w));
  967. else if (cputype == P86)
  968. errorc (E_IOT);
  969. else {
  970. if (pso2->doffset > 0xFF)
  971. errorc (E_VOR);
  972. emitopcode ((UCHAR)(0xC0 + pso1->w));
  973. }
  974. }
  975. /* Must have size or error */
  976. forcesize (p->dsc1);
  977. emitmodrm ((USHORT)pso1->mode, modrm, pso1->rm);
  978. /* Emit any effective address */
  979. emitrest (p->dsc1);
  980. if ((cputype != P86) && (pso2->doffset != 1))
  981. emitrest (p->dsc2);
  982. }
  983. #ifdef V386
  984. /*** pmovx - 386 movzx, movsx operators
  985. *
  986. */
  987. VOID
  988. CODESIZE
  989. pmovx(
  990. struct parsrec *p
  991. )
  992. {
  993. register struct psop *pso1; /* parse stack operand structure */
  994. register struct psop *pso2; /* parse stack operand structure */
  995. pso1 = &(p->dsc1->dsckind.opnd);
  996. pso2 = &(p->dsc2->dsckind.opnd);
  997. checkwreg(pso1);
  998. if (pso2->mode == 4)
  999. errorc(E_IOT);
  1000. if (pso1->dsize != wordsize)
  1001. emitsize(0x66);
  1002. if (pso2->sized && pso2->dsize != 1 && (pso1->dsize>>1 != pso2->dsize))
  1003. errorc(E_IIS);
  1004. emitopcode(0x0f);
  1005. emitopcode((UCHAR)(opcbase|pso2->w));
  1006. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  1007. emitrest (p->dsc2);
  1008. }
  1009. /*** psetcc - 386 setle, seto, etc
  1010. *
  1011. */
  1012. VOID
  1013. CODESIZE
  1014. psetcc(
  1015. struct parsrec *p
  1016. )
  1017. {
  1018. register struct psop *pso1; /* parse stack operand structure */
  1019. pso1 = &(p->dsc1->dsckind.opnd);
  1020. if (pso1->dsize != 1)
  1021. errorc(E_IIS);
  1022. emitopcode(0x0f);
  1023. emitopcode(modrm);
  1024. emitmodrm ((USHORT)pso1->mode, 0, pso1->rm);
  1025. emitrest (p->dsc1);
  1026. }
  1027. /*** pbit -- 386 bit test and set, complement or reset
  1028. *
  1029. */
  1030. VOID
  1031. CODESIZE
  1032. pbit(
  1033. register struct parsrec *p
  1034. )
  1035. {
  1036. register struct psop *pso1;
  1037. struct psop *pso2;
  1038. pso1 = &(p->dsc1->dsckind.opnd);
  1039. emitopcode(0x0f);
  1040. if (pso1->mode == 4)
  1041. errorc(E_NIM);
  1042. pso2 = &(p->dsc2->dsckind.opnd);
  1043. if (pso2->mode == 4) {
  1044. emitopcode(0xBA);
  1045. emitmodrm ((USHORT)pso1->mode, modrm, pso1->rm);
  1046. emitrest (p->dsc1);
  1047. emitrest (p->dsc2);
  1048. forcesize (p->dsc1);
  1049. byteimmcheck (pso2);
  1050. } else if (pso2->mode == 3) {
  1051. static UCHAR byte2[] = {0xA3, 0xAB, 0xB3, 0xBB};
  1052. emitopcode(byte2[modrm&3]);
  1053. emitmodrm ((USHORT)pso1->mode, pso2->rm, pso1->rm);
  1054. checkmatch (p->dsc2, p->dsc1);
  1055. emitrest (p->dsc1);
  1056. } else
  1057. errorc(E_IOT);
  1058. }
  1059. /*** pbitscan -- 386 bit scan forward, reverse
  1060. *
  1061. */
  1062. VOID
  1063. CODESIZE
  1064. pbitscan(
  1065. register struct parsrec *p
  1066. )
  1067. {
  1068. register struct psop *pso2;
  1069. pso2 = &(p->dsc2->dsckind.opnd);
  1070. checkwreg (&p->dsc1->dsckind.opnd);
  1071. if (pso2->mode == 4)
  1072. errorc (E_NIM);
  1073. checkmatch (p->dsc1, p->dsc2);
  1074. emitopcode(0x0f);
  1075. emitopcode(modrm);
  1076. emitmodrm ((USHORT)pso2->mode, p->dsc1->dsckind.opnd.rm, pso2->rm);
  1077. emitrest (p->dsc2);
  1078. }
  1079. #endif /* V386 */
  1080. /*** parith - arithmetic operators
  1081. *
  1082. * parith (p);
  1083. *
  1084. * Entry
  1085. * Exit
  1086. * Returns
  1087. * Calls
  1088. */
  1089. VOID
  1090. PASCAL
  1091. CODESIZE
  1092. parith (
  1093. register struct parsrec *p
  1094. )
  1095. {
  1096. register struct psop *pso1; /* parse stack operand structure */
  1097. register struct psop *pso2; /* parse stack operand structure */
  1098. DSCREC *op1;
  1099. pso1 = &(p->dsc1->dsckind.opnd);
  1100. /* note that opcbase is the same for IMUL and IDIV--thus this was
  1101. * trying to accept immediates. modrm has the right stuff, strangely */
  1102. if (opcbase == O_IMUL && (modrm == R_IMUL) &&
  1103. (PEEKC () == ',') && (cputype != P86)) {
  1104. /* IMUL reg | ea,imm */
  1105. SKIPC ();
  1106. if (pso1->dsize != 2 && pso1->dsize != 4)
  1107. errorc (E_BRI);
  1108. p->defseg = (unsigned char)segdefault (SECONDDS);
  1109. p->dsc2 = expreval (&p->defseg);
  1110. pso2 = &(p->dsc2->dsckind.opnd);
  1111. if (PEEKC () == ',') {
  1112. SKIPC ();
  1113. if (pso2->sized && ((pso2->dsize != 2 && pso2->dsize != 4)
  1114. || pso2->dsize != pso1->dsize))
  1115. errorc (E_IIS);
  1116. /* IMUL reg,ea,immed */
  1117. #ifdef V386
  1118. emit67 (pso1, pso2);
  1119. emit66 (pso1, pso2);
  1120. #endif
  1121. op1 = p->dsc1;
  1122. p->dsc1 = p->dsc2;
  1123. pso1 = pso2;
  1124. p->dsc2 = expreval (&nilseg);
  1125. pso2 = &(p->dsc2->dsckind.opnd);
  1126. forceimmed (p->dsc2);
  1127. emitescape (p->dsc1, p->defseg);
  1128. emitopcode ((UCHAR)(IMUL3 + 2 * pso2->s));
  1129. emitmodrm ((USHORT)pso1->mode, op1->dsckind.opnd.rm, pso1->rm);
  1130. emitrest (p->dsc1);
  1131. pso2->w = !pso2->s; /* shorten to byte if necessary */
  1132. if (!pso2->w)
  1133. byteimmcheck(pso2);
  1134. /* force size immediate size to match op 1 */
  1135. pso2->dsize = op1->dsckind.opnd.dsize;
  1136. emitrest (p->dsc2);
  1137. dfree ((char *)op1 );
  1138. }
  1139. #ifdef V386
  1140. else if (pso2->mode != 4 && (cputype & P386)) {
  1141. /* IMUL reg, reg/mem */
  1142. if (pso1->dsize != pso2->dsize && pso2->sized)
  1143. errorc (E_OMM);
  1144. emit67 (pso1, pso2);
  1145. emit66 (pso1, pso2);
  1146. emitescape (p->dsc2, p->defseg);
  1147. emitopcode(0x0f);
  1148. emitopcode(0xaf);
  1149. emitmodrm(pso2->mode, pso1->rm, pso2->rm);
  1150. emitrest(p->dsc2);
  1151. }
  1152. #endif /* V386 */
  1153. else {
  1154. /* IMUL reg,immed */
  1155. #ifdef V386 /* recompute immediate size based op 1 size not word size */
  1156. if (!(pso2->dflag & (UNDEFINED|FORREF|XTERNAL))
  1157. && pso2->fixtype == FCONSTANT
  1158. && pso2->doffset & 0x8000)
  1159. if (pso1->dsize == 2)
  1160. pso2->s = (char)((USHORT)(((USHORT) pso2->doffset & ~0x7F ) == (USHORT)(~0x7F)));
  1161. else
  1162. pso2->s = (char)((OFFSET)((pso2->doffset & ~0x7F ) == (OFFSET)(~0x7F)));
  1163. emit67 (pso1, pso2);
  1164. emit66 (pso1, pso2);
  1165. #endif
  1166. forceimmed (p->dsc2);
  1167. checksize(p);
  1168. emitopcode ((UCHAR)(IMUL3 + 2 * pso2->s));
  1169. emitmodrm ((USHORT)pso1->mode, pso1->rm, pso1->rm);
  1170. pso2->w = !pso2->s; /* shorten to byte if necessary */
  1171. if (!pso2->w)
  1172. byteimmcheck(pso2);
  1173. pso2->dsize = pso1->dsize;
  1174. emitrest (p->dsc2);
  1175. }
  1176. } else {
  1177. #ifdef V386
  1178. emit67 (pso1, NULL);
  1179. emit66 (pso1, NULL);
  1180. #endif
  1181. forcesize (p->dsc1);
  1182. emitescape (p->dsc1, p->defseg);
  1183. if ((opcbase == O_NEG || opcbase == O_NOT) && impure)
  1184. errorc (E_IMP);
  1185. emitopcode ((UCHAR)(ARITHBASE + pso1->w));
  1186. emitmodrm ((USHORT)pso1->mode, modrm, pso1->rm);
  1187. emitrest (p->dsc1);
  1188. }
  1189. }
  1190. /*** pbound - bounds operators
  1191. *
  1192. * pbound (p);
  1193. *
  1194. * Entry
  1195. * Exit
  1196. * Returns
  1197. * Calls
  1198. */
  1199. VOID
  1200. PASCAL
  1201. CODESIZE
  1202. pbound (
  1203. struct parsrec *p
  1204. )
  1205. {
  1206. register struct psop *pso1; /* parse stack operand structure */
  1207. register struct psop *pso2; /* parse stack operand structure */
  1208. pso1 = &(p->dsc1->dsckind.opnd);
  1209. pso2 = &(p->dsc2->dsckind.opnd);
  1210. checkwreg(pso1);
  1211. if (pso2->dsize != pso1->dsize*2)
  1212. errorc (E_IIS);
  1213. #ifdef V386_0
  1214. if (wordsize != pso1->dsize)
  1215. emitsize(0x66);
  1216. #endif
  1217. emitopcode (opcbase);
  1218. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  1219. emitrest (p->dsc2);
  1220. }
  1221. /*** penter - enter operators
  1222. *
  1223. * penter (p);
  1224. *
  1225. * Entry
  1226. * Exit
  1227. * Returns
  1228. * Calls
  1229. */
  1230. VOID
  1231. PASCAL
  1232. CODESIZE
  1233. penter (
  1234. register struct parsrec *p
  1235. )
  1236. {
  1237. emitopcode (opcbase);
  1238. p->dsc1->dsckind.opnd.dsize = 2;
  1239. emitOP (&p->dsc1->dsckind.opnd);
  1240. p->dsc2->dsckind.opnd.dsize = 1;
  1241. forceimmed (p->dsc2);
  1242. emitOP (&p->dsc2->dsckind.opnd);
  1243. }
  1244. /*** pclts - operators
  1245. *
  1246. * pclts ();
  1247. *
  1248. * Entry
  1249. * Exit
  1250. * Returns
  1251. * Calls
  1252. */
  1253. VOID
  1254. PASCAL
  1255. CODESIZE
  1256. pclts ()
  1257. {
  1258. emitopcode (opcbase);
  1259. emitopcode (modrm);
  1260. }
  1261. /*** pdescrtbl - table operators
  1262. *
  1263. * pdescrtbl (p);
  1264. *
  1265. * Entry
  1266. * Exit
  1267. * Returns
  1268. * Calls
  1269. */
  1270. VOID
  1271. PASCAL
  1272. CODESIZE
  1273. pdescrtbl (
  1274. struct parsrec *p
  1275. )
  1276. {
  1277. register struct psop *pso1; /* parse stack operand structure */
  1278. pso1 = &(p->dsc1->dsckind.opnd);
  1279. if (pso1->dsize != 6)
  1280. errorc (E_IIS);
  1281. emitopcode (opcbase);
  1282. emitopcode (1);
  1283. emitmodrm ((USHORT)pso1->mode, modrm, pso1->rm);
  1284. emitrest (p->dsc1);
  1285. }
  1286. /*** pdttrsw - operators
  1287. *
  1288. * pdttrsw (p);
  1289. *
  1290. * Entry
  1291. * Exit
  1292. * Returns
  1293. * Calls
  1294. */
  1295. VOID
  1296. PASCAL CODESIZE
  1297. pdttrsw (
  1298. struct parsrec *p
  1299. )
  1300. {
  1301. register struct psop *pso1; /* parse stack operand structure */
  1302. pso1 = &(p->dsc1->dsckind.opnd);
  1303. if (!pso1->w || (pso1->sized && pso1->dsize != 2))
  1304. errorc ((USHORT)(pso1->mode != 3? E_IIS: E_IIS & ~E_WARN1));
  1305. emitopcode (opcbase);
  1306. if ((modrm == R_LMSW) || (modrm == R_SMSW))
  1307. emitopcode (1);
  1308. else
  1309. emitopcode (0);
  1310. emitmodrm ((USHORT)pso1->mode, modrm, pso1->rm);
  1311. emitrest (p->dsc1);
  1312. }
  1313. /*** pver - operators
  1314. *
  1315. * pver (p);
  1316. *
  1317. * Entry
  1318. * Exit
  1319. * Returns
  1320. * Calls
  1321. */
  1322. VOID
  1323. PASCAL
  1324. CODESIZE
  1325. pver (
  1326. struct parsrec *p
  1327. )
  1328. {
  1329. register struct psop *pso1; /* parse stack operand structure */
  1330. pso1 = &(p->dsc1->dsckind.opnd);
  1331. if (!pso1->w || (pso1->sized && pso1->dsize != 2))
  1332. errorc ((UCHAR)(pso1->mode != 3? E_IIS: E_IIS & ~E_WARN1));
  1333. emitopcode (opcbase);
  1334. emitopcode (0);
  1335. emitmodrm ((USHORT)pso1->mode, modrm, pso1->rm);
  1336. emitrest (p->dsc1);
  1337. }
  1338. /*** parsl - operators
  1339. *
  1340. * parsl (p);
  1341. *
  1342. * Entry
  1343. * Exit
  1344. * Returns
  1345. * Calls
  1346. */
  1347. VOID
  1348. PASCAL
  1349. CODESIZE
  1350. parsl (
  1351. struct parsrec *p
  1352. )
  1353. {
  1354. register struct psop *pso1; /* parse stack operand structure */
  1355. register struct psop *pso2; /* parse stack operand structure */
  1356. pso1 = &(p->dsc1->dsckind.opnd);
  1357. pso2 = &(p->dsc2->dsckind.opnd);
  1358. checkmatch (p->dsc1, p->dsc2);
  1359. checkwreg(pso1);
  1360. emitopcode (opcbase);
  1361. emitopcode (modrm);
  1362. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  1363. emitrest (p->dsc2);
  1364. }
  1365. /*** parpl - operators
  1366. *
  1367. * parpl (p);
  1368. *
  1369. * Entry
  1370. * Exit
  1371. * Returns
  1372. * Calls
  1373. */
  1374. VOID
  1375. PASCAL
  1376. CODESIZE
  1377. parpl (
  1378. struct parsrec *p
  1379. )
  1380. {
  1381. register struct psop *pso1; /* parse stack operand structure */
  1382. register struct psop *pso2; /* parse stack operand structure */
  1383. pso1 = &(p->dsc1->dsckind.opnd);
  1384. pso2 = &(p->dsc2->dsckind.opnd);
  1385. if (pso2->dsize != 2)
  1386. errorc (E_IIS);
  1387. checkmatch (p->dsc2, p->dsc1);
  1388. emitopcode (opcbase);
  1389. emitmodrm ((USHORT)pso1->mode, pso2->rm, pso1->rm);
  1390. emitrest (p->dsc1);
  1391. }
  1392. /*** pstack - push|pos stack
  1393. *
  1394. * pstack (p);
  1395. *
  1396. * Entry
  1397. * Exit
  1398. * Returns
  1399. * Calls
  1400. */
  1401. VOID
  1402. PASCAL
  1403. CODESIZE
  1404. pstack (
  1405. struct parsrec *p
  1406. )
  1407. {
  1408. register struct psop *pso1; /* parse stack operand structure */
  1409. pso1 = &(p->dsc1->dsckind.opnd);
  1410. #ifdef V386
  1411. if (!(pso1->fixtype == FBASESEG || pso1->fixtype == FGROUPSEG) &&
  1412. pso1->sized && (pso1->dsize|wordsize) == 6 &&
  1413. !(pso1->mode == 3 && pso1->dsegment->symu.regsym.regtype == SEGREG)) {
  1414. emitsize(0x66);
  1415. errorc (E_ONW);
  1416. }
  1417. #endif
  1418. if (pso1->mode == 3) { /* Using register */
  1419. /* Forward is error */
  1420. errorforward (p->dsc1);
  1421. switch (pso1->dsegment->symu.regsym.regtype) {
  1422. case SEGREG:
  1423. /* CS | DS | ES | SS | FS | GS */
  1424. rangecheck (&pso1->rm, (UCHAR)7);
  1425. if (opcbase == O_POP && pso1->rm == CSSEG)
  1426. errorc (E_CSI);
  1427. #ifdef V386
  1428. if (pso1->rm >= FSSEG) {
  1429. emitopcode(0x0f);
  1430. emitopcode ((UCHAR)(((pso1->rm << 3)+ 0x80) + (opcbase == O_POP)));
  1431. } else
  1432. #endif
  1433. emitopcode ((UCHAR)(((pso1->rm << 3)+ 6) + (opcbase == O_POP)));
  1434. break;
  1435. case WRDREG:
  1436. case INDREG:
  1437. #ifdef V386
  1438. case DWRDREG:
  1439. #endif
  1440. rangecheck (&pso1->rm, (UCHAR)7);
  1441. emitopcode ((UCHAR)(opcbase + pso1->rm));
  1442. /* Reg form */
  1443. break;
  1444. default:
  1445. errorc(E_BRI);
  1446. }
  1447. } else if (pso1->mode == 4) {
  1448. #ifdef V386 /* detect immediate too big */
  1449. if (wordsize == 2 && pso1->dsize != 4 && highWord(pso1->doffset))
  1450. if (highWord(pso1->doffset) != 0xFFFF || !pso1->s)
  1451. errorc(E_VOR);
  1452. #endif
  1453. if (opcbase == O_POP || cputype == P86)
  1454. errorimmed (p->dsc1);
  1455. emitopcode ((UCHAR)(0x68 + 2 * pso1->s));
  1456. pso1->w = !pso1->s; /* shorten to byte if necessary */
  1457. if (!pso1->w)
  1458. byteimmcheck(pso1);
  1459. else if (!(M_PTRSIZE & pso1->dtype))
  1460. pso1->dsize = wordsize; /* force size to wordsize */
  1461. emitrest (p->dsc1);
  1462. } else {
  1463. if (pso1->sized && pso1->dsize &&
  1464. !(pso1->dsize == 2 || pso1->dsize == 4))
  1465. errorc(E_IIS);
  1466. /* Have memory operand of some kind */
  1467. if (opcbase == O_POP && impure)
  1468. errorc (E_IMP);
  1469. emitopcode ((UCHAR)((opcbase == O_PUSH)? O_PUSHM: O_POPM));
  1470. emitmodrm ((USHORT)pso1->mode,
  1471. (USHORT)((opcbase == O_PUSH)? 6: 0),
  1472. pso1->rm);
  1473. emitrest (p->dsc1);
  1474. }
  1475. }
  1476. /*** buildFrame - builds stack frame
  1477. *
  1478. * preturn (p);
  1479. *
  1480. * Entry before first instruction is generated in proc
  1481. */
  1482. VOID
  1483. PASCAL
  1484. CODESIZE
  1485. buildFrame()
  1486. {
  1487. char szLocal[32];
  1488. char szT[48];
  1489. SHORT i;
  1490. strcpy(save, lbuf); /* save line for later .. */
  1491. fSkipList++;
  1492. fProcArgs = -fProcArgs; /* mark already processed */
  1493. if (fProcArgs < -ARGS_REG) {
  1494. *radixconvert (cbProcLocals, szLocal) = NULL;
  1495. if (cputype & P86) {
  1496. doLine("push bp");
  1497. doLine("mov bp,sp");
  1498. if (fProcArgs == -ARGS_LOCALS) /* locals present */
  1499. doLine(strcat( strcpy(szT, "sub sp,"), szLocal));
  1500. } else
  1501. doLine(strcat( strcat( strcpy(szT, "enter "), szLocal), ",0"));
  1502. }
  1503. for (i = 0; i <= iRegSave; i++) { /* push all the saved registers */
  1504. doLine( strcat( strcpy(lbuf, "push "), regSave[i]) );
  1505. }
  1506. fSkipList--;
  1507. lbufp = strcpy(lbuf, save);
  1508. linebp = lbufp + strlen(lbufp);
  1509. strcpy(linebuffer, save);
  1510. parse();
  1511. }
  1512. /*** preturn - various forms of return
  1513. *
  1514. * preturn (p);
  1515. *
  1516. * Entry
  1517. * Exit
  1518. * Returns
  1519. * Calls
  1520. */
  1521. VOID
  1522. PASCAL
  1523. CODESIZE
  1524. preturn (
  1525. struct parsrec *p
  1526. )
  1527. {
  1528. register struct psop *pso1; /* parse stack operand structure */
  1529. SHORT i;
  1530. pso1 = &(p->dsc1->dsckind.opnd);
  1531. /* Decide whether inter or intra segment */
  1532. if (!modrm) { /* determine distance, if not RETN or RETF */
  1533. if (fProcArgs) { /* tear down the stack frame */
  1534. strcpy(save, linebuffer);
  1535. fSkipList++;
  1536. for (i = iRegSave; i >= 0; i--) { /* pop all the saved registers */
  1537. doLine( strcat( strcpy(lbuf, "pop "), regSave[i]) );
  1538. }
  1539. if (fProcArgs < -ARGS_REG)
  1540. if (cputype & P86) {
  1541. if (fProcArgs == -ARGS_LOCALS) /* locals present */
  1542. doLine("mov sp,bp");
  1543. doLine("pop bp");
  1544. } else
  1545. doLine("leave");
  1546. if (!(pcproc->attr & M_CDECL))
  1547. pso1->doffset = cbProcParms;
  1548. strcpy(linebuffer, save);
  1549. listindex = 1;
  1550. fSkipList = FALSE;
  1551. }
  1552. opcbase = O_RET;
  1553. if (pcproc && pcproc->symtype == CSFAR)
  1554. opcbase = O_RET + 8;
  1555. }
  1556. /* Optimize, if constant is 0 and not forward, use SHORT */
  1557. if (pso1->doffset == 0 && pso1->dflag != FORREF)
  1558. emitopcode (opcbase);
  1559. else { /* Gen 2 byte version */
  1560. emitopcode ((UCHAR)(opcbase - 1)); /* Pop form */
  1561. /* Force word--always 2 bytes, even on 386 */
  1562. pso1->dsize = 2;
  1563. emitOP (pso1); /* Immediate word */
  1564. }
  1565. }
  1566. /*** pincdec - increment|decrement
  1567. *
  1568. * pincdec (p);
  1569. *
  1570. * Entry
  1571. * Exit
  1572. * Returns
  1573. * Calls
  1574. */
  1575. VOID
  1576. PASCAL
  1577. CODESIZE
  1578. pincdec (
  1579. struct parsrec *p
  1580. )
  1581. {
  1582. register struct psop *pso1; /* parse stack operand structure */
  1583. pso1 = &(p->dsc1->dsckind.opnd);
  1584. /* INC | DEC */
  1585. if (!pso1->sized)
  1586. errorc (E_OHS);
  1587. if (pso1->mode == 3 && pso1->w)
  1588. /* Is word reg */
  1589. emitopcode ((UCHAR)(opcbase + pso1->rm));
  1590. else {
  1591. /* Use mod reg r/m form */
  1592. if (impure)
  1593. errorc (E_IMP);
  1594. emitopcode ((UCHAR)(0xFE + pso1->w));
  1595. emitmodrm ((USHORT)pso1->mode,
  1596. (USHORT)(opcbase == O_DEC), pso1->rm);
  1597. emitrest (p->dsc1);
  1598. }
  1599. }
  1600. /*** pint - interrupt
  1601. *
  1602. * pint (p);
  1603. *
  1604. * Entry
  1605. * Exit
  1606. * Returns
  1607. * Calls
  1608. */
  1609. VOID
  1610. PASCAL
  1611. CODESIZE
  1612. pint (
  1613. struct parsrec *p
  1614. )
  1615. {
  1616. register struct psop *pso1; /* parse stack operand structure */
  1617. pso1 = &(p->dsc1->dsckind.opnd);
  1618. /* INT */
  1619. valuecheck (&pso1->doffset, 255);
  1620. if (pso1->doffset == 3 && pso1->dflag != FORREF)
  1621. /* Use SHORT form */
  1622. emitopcode (opcbase);
  1623. else {
  1624. /* Use long form */
  1625. emitopcode ((UCHAR)(opcbase + 1));
  1626. emitopcode ((UCHAR)(pso1->doffset & 255));
  1627. }
  1628. }
  1629. /*** pinout - input|output
  1630. *
  1631. * pinout (p);
  1632. *
  1633. * Entry
  1634. * Exit
  1635. * Returns
  1636. * Calls
  1637. */
  1638. VOID
  1639. PASCAL
  1640. CODESIZE
  1641. pinout (
  1642. struct parsrec *p
  1643. )
  1644. {
  1645. register DSCREC *pso1;
  1646. register DSCREC *pso2;
  1647. pso1 = p->dsc1;
  1648. pso2 = p->dsc2;
  1649. if (opcbase == O_OUT) {
  1650. pso2 = pso1;
  1651. pso1 = p->dsc2;
  1652. }
  1653. /* IN ax|al, DX|immed */
  1654. /* OUT DX|immed, ax|al, */
  1655. #ifdef V386
  1656. emit66(&pso1->dsckind.opnd, NULL);
  1657. #endif
  1658. forceaccum (pso1);
  1659. /* Must be accum */
  1660. if (pso2->dsckind.opnd.mode == 3 && pso2->dsckind.opnd.rm == 2) {
  1661. /* Have DX */
  1662. emitopcode ((UCHAR)(opcbase + pso1->dsckind.opnd.w + 8));
  1663. if (pso2->dsckind.opnd.dsize != 2)
  1664. errorc(E_IRV);
  1665. } else {
  1666. /* Have port # */
  1667. forceimmed (pso2);
  1668. /* Must be constant */
  1669. valuecheck (&pso2->dsckind.opnd.doffset, 255);
  1670. emitopcode ((UCHAR)(opcbase + pso1->dsckind.opnd.w));
  1671. emitopcode ((UCHAR)(pso2->dsckind.opnd.doffset));
  1672. }
  1673. }
  1674. /*** pload - load
  1675. *
  1676. * pload (p); lea, les, les, etc
  1677. *
  1678. * Entry
  1679. * Exit
  1680. * Returns
  1681. * Calls
  1682. */
  1683. VOID
  1684. PASCAL
  1685. CODESIZE
  1686. pload (
  1687. struct parsrec *p
  1688. )
  1689. {
  1690. register struct psop *pso1; /* parse stack operand structure */
  1691. register struct psop *pso2; /* parse stack operand structure */
  1692. pso1 = &(p->dsc1->dsckind.opnd);
  1693. pso2 = &(p->dsc2->dsckind.opnd);
  1694. /* LDS | LEA | LES */
  1695. if (pso1->mode != 3)
  1696. /* Must be reg */
  1697. errorc (E_MBR);
  1698. else if (1 << pso1->dsegment->symu.regsym.regtype
  1699. & (M_STKREG | M_SEGREG | M_BYTREG))
  1700. errorc (E_WRT);
  1701. if (pso2->mode == 3)
  1702. errorc (E_IUR);
  1703. if (opcbase != O_LEA) {
  1704. if (pso2->dsize && pso2->dsize != 4 && pso2->dsize != 6)
  1705. errorc (E_IIS);
  1706. /* complain about mismatching source and destination */
  1707. if (pso2->dsize && pso1->dsize &&
  1708. pso1->dsize + 2 != pso2->dsize)
  1709. errorc (E_IIS);
  1710. #ifdef V386
  1711. else if (pso2->dsize && pso2->dsize != wordsize+2)
  1712. emitsize(0x66);
  1713. else if (pso1->dsize && pso1->dsize != wordsize)
  1714. emitsize(0x66);
  1715. #endif
  1716. }
  1717. #ifdef V386
  1718. else
  1719. if (pso1->dsize != wordsize)
  1720. emitsize(0x66);
  1721. switch (opcbase) {
  1722. case O_LFS:
  1723. case O_LGS:
  1724. case O_LSS:
  1725. emitopcode(0x0F);
  1726. break;
  1727. }
  1728. #endif
  1729. emitopcode (opcbase);
  1730. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  1731. /* If FAR, make offset so only 2 bytes out */
  1732. if (pso2->fixtype == FPOINTER)
  1733. pso2->fixtype = FOFFSET;
  1734. emitrest (p->dsc2);
  1735. }
  1736. /*** pmov - move
  1737. *
  1738. * pmov (p);
  1739. *
  1740. * Entry
  1741. * Exit
  1742. * Returns
  1743. * Calls
  1744. */
  1745. VOID
  1746. PASCAL
  1747. CODESIZE
  1748. pmov (
  1749. struct parsrec *p
  1750. )
  1751. {
  1752. register struct psop *pso1; /* parse stack operand structure */
  1753. register struct psop *pso2; /* parse stack operand structure */
  1754. pso1 = &(p->dsc1->dsckind.opnd);
  1755. pso2 = &(p->dsc2->dsckind.opnd);
  1756. /* If 1st arg is memory or undef, force 2nd to be
  1757. * immed for pass 1 and set <EXPLOFFSET> in pass 2 */
  1758. if ((pso1->mode < 3) && (pso2->mode != 3)) {
  1759. /* mem,immed */
  1760. pso2->dtype |= M_EXPLOFFSET;
  1761. /* Look like OFFSET val */
  1762. if (!pass2)
  1763. /* Force immed on pass1 */
  1764. pso2->mode = 4;
  1765. }
  1766. /* See if this is immediate move */
  1767. if (pso2->mode == 4) {
  1768. emit66 (pso1, pso2);
  1769. /* MOV arg,immed */
  1770. if (pso1->mode == 3) {
  1771. /* MOV reg,immed */
  1772. if (1 << pso1->dsegment->symu.regsym.regtype
  1773. & (M_SEGREG | M_STKREG | M_CREG ))
  1774. /* Wrong type of register */
  1775. errorc (E_NIM);
  1776. emitopcode ((UCHAR)(176 + 8*pso1->w + pso1->rm));
  1777. /* Make sure agree */
  1778. checksize (p);
  1779. emitrest (p->dsc2);
  1780. /* Emit immed */
  1781. if (pso1->rm &&
  1782. pso2->dtype & M_FORTYPE &&
  1783. !pso2->dsegment && !(M_EXPLOFFSET & pso2->dtype))
  1784. /* Pass 1 assumed not immed */
  1785. emitnop();
  1786. } else {/* MOV mem,immed */
  1787. checksize (p);
  1788. if (!(pso1->sized || pso2->sized)) {
  1789. pso1->sized = pso2->sized = TRUE;
  1790. pso1->w = pso2->w = TRUE;
  1791. }
  1792. /* Make sure agree */
  1793. if (impure)
  1794. errorc (E_IMP);
  1795. emitopcode ( ( UCHAR)( 198 + pso1->w));
  1796. emitmodrm ((USHORT)pso1->mode, 0, pso1->rm);
  1797. emitrest (p->dsc1);
  1798. emitrest (p->dsc2);
  1799. }
  1800. if (!pso1->w)
  1801. /* 1st operand is byte, 2nd is immed
  1802. * Check below on dsc1 should only be done
  1803. * on MOV since the PGENARG opcodes always shorten a known
  1804. * byte const */
  1805. if ((pso1->dtype & (M_FORTYPE|M_PTRSIZE|M_EXPLOFFSET)) == M_FORTYPE ||
  1806. (pso2->dtype & (M_FORTYPE|M_PTRSIZE|M_EXPLOFFSET)) == M_FORTYPE)
  1807. emitnop();
  1808. }
  1809. /* See if either is segment register */
  1810. else if (pso1->mode == 3) {
  1811. /* 1st arg is reg */
  1812. switch (pso1->dsegment->symu.regsym.regtype) {
  1813. case SEGREG:
  1814. /* MOV SEGREG,arg */
  1815. movesegreg (TRUE, p);
  1816. break;
  1817. #ifdef V386
  1818. case CREG:
  1819. /* mov CREG,reg */
  1820. movecreg (TRUE, p);
  1821. break;
  1822. case DWRDREG:
  1823. #endif
  1824. case BYTREG:
  1825. case WRDREG:
  1826. /* MOV ac,addr? */
  1827. if ((pso1->rm == 0) && isdirect(pso2))
  1828. /* MOV ac,addr */
  1829. moveaccum (TRUE, p);
  1830. else
  1831. /* MOV reg,arg */
  1832. movereg (TRUE, p);
  1833. break;
  1834. case INDREG:
  1835. /* MOV indreg,arg */
  1836. movereg (TRUE, p);
  1837. break;
  1838. default:
  1839. errorc (E_WRT);
  1840. break;
  1841. }
  1842. } else if (pso2->mode == 3) {
  1843. /* 2nd arg is reg */
  1844. switch (pso2->dsegment->symu.regsym.regtype) {
  1845. case SEGREG:
  1846. /* MOV arg,SEGREG */
  1847. movesegreg (FALSE, p);
  1848. break;
  1849. #ifdef V386
  1850. case CREG:
  1851. /* mov reg, CREG */
  1852. movecreg(FALSE, p);
  1853. break;
  1854. case DWRDREG:
  1855. #endif
  1856. case BYTREG:
  1857. case WRDREG:
  1858. /* MOV addr,ac? */
  1859. if ((pso2->rm == 0) && isdirect(pso1))
  1860. /* MOV addr,ac */
  1861. moveaccum (FALSE, p);
  1862. else
  1863. /* MOV arg,reg */
  1864. movereg (FALSE, p);
  1865. break;
  1866. case INDREG:
  1867. /* MOV arg,indreg */
  1868. movereg (FALSE, p);
  1869. break;
  1870. default:
  1871. errorc (E_WRT);
  1872. break;
  1873. }
  1874. } else
  1875. errorc (E_IOT);
  1876. }
  1877. /*** pgenarg
  1878. *
  1879. * pgenarg (p);
  1880. *
  1881. * Entry
  1882. * Exit
  1883. * Returns
  1884. * Calls
  1885. */
  1886. VOID
  1887. PASCAL
  1888. CODESIZE
  1889. pgenarg (
  1890. struct parsrec *p
  1891. )
  1892. {
  1893. register struct psop *pso1; /* parse stack operand structure */
  1894. register struct psop *pso2; /* parse stack operand structure */
  1895. char fAccumMode = 0;
  1896. pso1 = &(p->dsc1->dsckind.opnd);
  1897. pso2 = &(p->dsc2->dsckind.opnd);
  1898. /* ADC | ADD | AND | CMP | OR | SBB SUB | XOR | TEST */
  1899. if (pso1->mode != 3 && pso2->mode != 3) {
  1900. /* Force to mem,immed */
  1901. if (!pass2)
  1902. /* Force immediate */
  1903. pso2->mode = 4;
  1904. }
  1905. /* Not AX,immed */
  1906. if (pso2->mode == 4) {
  1907. #ifdef V386 /* recompute immediate size based op 1 size not word size */
  1908. if (!(pso2->dflag & (UNDEFINED|FORREF|XTERNAL))
  1909. && pso2->fixtype == FCONSTANT
  1910. && pso2->doffset & 0x8000)
  1911. if (pso1->dsize == 2)
  1912. pso2->s = (char)((USHORT)(((USHORT) pso2->doffset & ~0x7F ) == (USHORT)(~0x7F)));
  1913. else
  1914. pso2->s = (char)((OFFSET)((pso2->doffset & ~0x7F ) == (OFFSET)(~0x7F)));
  1915. #endif
  1916. /* OP mem/reg,immed */
  1917. if (pso1->mode == 3 && pso1->rm == 0
  1918. #ifdef V386
  1919. && !(pso1->dsize == 4 && pso2->s &&
  1920. opcbase != O_TEST) /* chose size extended */
  1921. #endif /* general purpose over ac*/
  1922. ) {
  1923. /* OP al|ax|eax,immed */
  1924. checksize (p);
  1925. /* Make sure agree */
  1926. if (opcbase == O_TEST)
  1927. /* * TEST is special * */
  1928. emitopcode ((UCHAR)(0xA8 + pso1->w));
  1929. else/* Other reg immed */
  1930. /* Is AX,immed */
  1931. emitopcode ((UCHAR)(opcbase + 4 + pso1->w));
  1932. fAccumMode = 1;
  1933. } else {/* OP mem/reg, immed */
  1934. checksize (p);
  1935. if (!(pso1->sized || pso2->sized)) {
  1936. pso1->sized = pso2->sized = TRUE;
  1937. pso1->w = pso2->w = TRUE;
  1938. }
  1939. /* Make sure agree */
  1940. if (opcbase == O_TEST) {
  1941. /* TEST is special */
  1942. emitopcode ((UCHAR)(ARITHBASE + pso1->w));
  1943. emitmodrm ((USHORT)pso1->mode, 0, pso1->rm);
  1944. } else {
  1945. if (opcbase != O_CMP && impure)
  1946. errorc (E_IMP);
  1947. if (pso2->w) {
  1948. /* Try to shorten word */
  1949. emitopcode ((UCHAR)(0x80 + (pso2->s <<1) +pso1->w));
  1950. pso2->w = !pso2->s;
  1951. /* So only byte out */
  1952. if (!pso2->w) {
  1953. fAccumMode = wordsize - 1;
  1954. byteimmcheck(pso2);
  1955. }
  1956. } else {
  1957. emitopcode (128);
  1958. }
  1959. emitmodrm ((USHORT)pso1->mode, (USHORT)(opcbase>>3), pso1->rm);
  1960. }
  1961. emitrest (p->dsc1);
  1962. }
  1963. if (pso2->w && !pso1->w)
  1964. /* size mismatch */
  1965. errorc (E_VOR);
  1966. emitrest (p->dsc2); /* Emit immed */
  1967. if (!pso1->w)
  1968. if (((pso2->dtype & (M_FORTYPE|M_PTRSIZE|M_EXPLOFFSET)) == M_FORTYPE ||
  1969. opcbase == O_TEST && pso1->mode != 3) &&
  1970. ((pso1->dtype & (M_FORTYPE|M_PTRSIZE|M_EXPLOFFSET)) == M_FORTYPE ||
  1971. pso1->mode == 3))
  1972. emitnop();
  1973. if (fAccumMode &&
  1974. M_FORTYPE & pso2->dtype &&
  1975. !(M_EXPLOFFSET & pso2->dtype))
  1976. while (--fAccumMode >= 0)
  1977. emitnop();
  1978. } else { /* Not immediate */
  1979. if (pso1->mode == 3) {
  1980. /* OP reg,mem/reg */
  1981. checkmatch (p->dsc1, p->dsc2);
  1982. if (opcbase == O_TEST)
  1983. opcbase = O_TEST - 2;
  1984. emitopcode ((UCHAR)(opcbase + 2 + pso1->w));
  1985. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  1986. emitrest (p->dsc2);
  1987. } else if (pso2->mode != 3)
  1988. errorc (E_IOT);
  1989. else { /* Have OP mem,reg */
  1990. if (opcbase != O_CMP && opcbase != O_TEST && impure)
  1991. errorc (E_IMP);
  1992. checkmatch (p->dsc2, p->dsc1);
  1993. emitopcode ((UCHAR)(opcbase + pso2->w));
  1994. emitmodrm ((USHORT)pso1->mode, pso2->rm, pso1->rm);
  1995. emitrest (p->dsc1);
  1996. }
  1997. }
  1998. }
  1999. /*** pxchg - exchange register and register/memory
  2000. *
  2001. * pxchg (p);
  2002. *
  2003. * Entry
  2004. * Exit
  2005. * Returns
  2006. * Calls
  2007. */
  2008. VOID
  2009. PASCAL
  2010. CODESIZE
  2011. pxchg (
  2012. struct parsrec *p
  2013. )
  2014. {
  2015. register struct psop *pso1; /* parse stack operand structure */
  2016. register struct psop *pso2; /* parse stack operand structure */
  2017. DSCREC *t;
  2018. if (impure)
  2019. errorc (E_IMP);
  2020. pso1 = &(p->dsc1->dsckind.opnd);
  2021. pso2 = &(p->dsc2->dsckind.opnd);
  2022. if (pso1->mode != 3) {
  2023. if (pso2->mode != 3) {
  2024. errorc (E_OCI); /* Illegal */
  2025. return;
  2026. }
  2027. t = p->dsc1;
  2028. p->dsc1 = p->dsc2;
  2029. p->dsc2 = t;
  2030. pso1 = &(p->dsc1->dsckind.opnd);
  2031. pso2 = &(p->dsc2->dsckind.opnd);
  2032. }
  2033. /* First operand is register */
  2034. if (1 << pso1->dsegment->symu.regsym.regtype & (M_STKREG | M_SEGREG))
  2035. errorc (E_WRT);
  2036. rangecheck (&pso1->rm, (UCHAR)7);
  2037. if (pso1->dsize != pso2->dsize && pso2->sized)
  2038. errorc (E_OMM);
  2039. if (pso2->mode == 3) {
  2040. /* XCHG reg, reg */
  2041. if (1 << pso2->dsegment->symu.regsym.regtype & (M_STKREG | M_SEGREG))
  2042. errorc (E_WRT);
  2043. rangecheck (&pso2->rm, (UCHAR)7);
  2044. /* Check for XCHG accum, reg */
  2045. if (pso1->rm == 0 && pso1->w) {
  2046. emitopcode ((UCHAR)(144 + pso2->rm));
  2047. return;
  2048. } else if (pso2->w && pso2->rm == 0) {
  2049. emitopcode ((UCHAR)(144 + pso1->rm));
  2050. return;
  2051. }
  2052. }
  2053. emitopcode ((UCHAR)(134 + pso1->w));
  2054. emitmodrm ((USHORT)pso2->mode, pso1->rm, pso2->rm);
  2055. emitrest (p->dsc2);
  2056. }
  2057. /*** pesc - escape operators
  2058. *
  2059. * pesc (p);
  2060. *
  2061. * Entry
  2062. * Exit
  2063. * Returns
  2064. * Calls
  2065. */
  2066. VOID
  2067. PASCAL
  2068. CODESIZE
  2069. pesc (
  2070. struct parsrec *p
  2071. )
  2072. {
  2073. register struct psop *pso1; /* parse stack operand structure */
  2074. register struct psop *pso2; /* parse stack operand structure */
  2075. pso1 = &(p->dsc1->dsckind.opnd);
  2076. pso2 = &(p->dsc2->dsckind.opnd);
  2077. /* ESC opcode,modrm */
  2078. valuecheck (&pso1->doffset, 63);
  2079. emitopcode ((UCHAR)(216 + pso1->doffset / 8));
  2080. emitmodrm ((USHORT)pso2->mode, (USHORT)(pso1->doffset & 7), pso2->rm);
  2081. emitrest (p->dsc2);
  2082. }
  2083. /*** prepeat - repeat operators
  2084. *
  2085. * prepeat (p);
  2086. *
  2087. * Entry
  2088. * Exit
  2089. * Returns
  2090. * Calls
  2091. */
  2092. VOID
  2093. PASCAL
  2094. CODESIZE
  2095. prepeat (
  2096. struct parsrec *p
  2097. )
  2098. {
  2099. /* REP | REPZ | REPE | REPNE | REPNZ */
  2100. emitopcode (opcbase);
  2101. listbuffer[listindex-1] = '/';
  2102. listindex++;
  2103. /* Flag is LOCK/REP */
  2104. getatom ();
  2105. if (!opcodesearch ())
  2106. /* Must have another op */
  2107. errorc (E_OAP);
  2108. else
  2109. /* Prefix for string instr */
  2110. opcode ();
  2111. p->dsc1 = NULL;
  2112. p->dsc2 = NULL;
  2113. }
  2114. /*** pstr - string operators
  2115. *
  2116. * pstr (p);
  2117. *
  2118. * Entry
  2119. * Exit
  2120. * Returns
  2121. * Calls
  2122. */
  2123. VOID
  2124. PASCAL
  2125. CODESIZE
  2126. pstr (
  2127. struct parsrec *p
  2128. )
  2129. {
  2130. register struct psop *pso1; /* parse stack operand structure */
  2131. register struct psop *pso2; /* parse stack operand structure */
  2132. /* SCAS | STOS | MOVS | LODS | CMPS */
  2133. if (!p->dsc2)
  2134. p->dsc2 = p->dsc1;
  2135. pso1 = &(p->dsc1->dsckind.opnd);
  2136. pso2 = &(p->dsc2->dsckind.opnd);
  2137. if (opcbase == O_OUTS) {
  2138. if (pso1->mode != 3)
  2139. errorc (E_MBR);
  2140. else if (pso1->rm != 2)
  2141. errorc (E_WRT);
  2142. p->dsc1 = p->dsc2;
  2143. pso1 = pso2;
  2144. }
  2145. if (opcbase == O_INS) {
  2146. if (pso2->mode != 3)
  2147. errorc (E_MBR);
  2148. else if (pso2->rm != 2)
  2149. errorc (E_WRT);
  2150. p->dsc2 = p->dsc1;
  2151. pso2 = pso1;
  2152. }
  2153. /* Had to wait til now, so OUTS, INS would be adjusted already */
  2154. emit66 (pso1, pso2);
  2155. if ((pso1->mode > 2 && pso1->mode < 5) ||
  2156. (pso2->mode > 2 && pso2->mode < 5))
  2157. errorc (E_IOT);
  2158. if (!(pso1->sized || pso2->sized))
  2159. /* Give error if don't have a size specified */
  2160. errorc (E_OHS);
  2161. if (pso1->w != pso2->w)
  2162. errorc (E_OMM);
  2163. if (opcbase == O_MOVS || opcbase == O_LODS || opcbase == O_OUTS) {
  2164. emitescape (p->dsc2, DSSEG);
  2165. /* 2nd can be override */
  2166. if (p->dsc1 != p->dsc2)
  2167. errorover (pso1->seg);
  2168. } else {
  2169. errorover (pso2->seg);
  2170. /* No 2nd override */
  2171. if (p->dsc1 != p->dsc2)
  2172. emitescape (p->dsc1, DSSEG);
  2173. }
  2174. emitopcode ((UCHAR)(opcbase + pso1->w));
  2175. if (p->dsc1 == p->dsc2) {
  2176. p->dsc1 = NULL;
  2177. }
  2178. }
  2179. /*** pxlat
  2180. *
  2181. * pxlat (p);
  2182. *
  2183. * Entry
  2184. * Exit
  2185. * Returns
  2186. * Calls
  2187. */
  2188. VOID
  2189. PASCAL
  2190. CODESIZE
  2191. pxlat (
  2192. struct parsrec *p
  2193. )
  2194. {
  2195. register struct psop *pso1; /* parse stack operand structure */
  2196. pso1 = &(p->dsc1->dsckind.opnd);
  2197. /* XLAT */
  2198. if (pso1->mode <= 2 || pso1->mode >= 5)
  2199. /* Good mode */
  2200. if (pso1->w)
  2201. /* Must be byte */
  2202. errorc (E_IIS);
  2203. emitopcode (opcbase);
  2204. }
  2205. /* isdirect -- given a psop representing a modrm, is it mem-direct? */
  2206. USHORT
  2207. CODESIZE
  2208. isdirect(
  2209. register struct psop *pso /* parse stack operand structure */
  2210. )
  2211. {
  2212. return ((pso->mode == 0 && pso->rm == 6) || /* for 8086 */
  2213. (pso->mode == 5 && pso->rm == 5)); /* for 386 */
  2214. }
  2215. #ifdef V386
  2216. /* emit66 -- if dsize == 2 && wordsize == 4, or vice versa, we generate
  2217. * a 66 prefix to locally change the operand mode.
  2218. */
  2219. VOID
  2220. PASCAL
  2221. CODESIZE
  2222. emit66(
  2223. register struct psop *pso1, /* parse stack operand structure */
  2224. register struct psop *pso2 /* parse stack operand structure */
  2225. )
  2226. {
  2227. if (!pso1)
  2228. return;
  2229. if (!pso2) {
  2230. if (pso1->sized && (pso1->dsize | wordsize) == 6)
  2231. emitsize(0x66);
  2232. } else {
  2233. /* key off the first operand if size known AND second isn't a register */
  2234. if (pso1->sized && pso2->mode != 3 ||
  2235. /* bogusness--sized and dsize 0 means immed bigger than 127 */
  2236. (pso2->sized &&
  2237. (pso1->dsize == pso2->dsize || pso2->dsize == 0))) {
  2238. if ((pso1->dsize | wordsize) == 6)
  2239. emitsize(0x66);
  2240. } else if (pso2->sized) {
  2241. if ((pso2->dsize | wordsize) == 6)
  2242. emitsize(0x66);
  2243. }
  2244. }
  2245. /* otherwise we have inconsistent opcodes and we cant do a thing.
  2246. so dont. bogus!!! */
  2247. }
  2248. /* emit67-- checks for operand size not matching wordsize and emits the
  2249. * appropriate override */
  2250. VOID
  2251. PASCAL
  2252. emit67(
  2253. register struct psop *pso1, /* parse stack operand structure */
  2254. register struct psop *pso2 /* parse stack operand structure */
  2255. )
  2256. {
  2257. if (!pso1)
  2258. return;
  2259. if ((1<<FIRSTDS) & xoptoseg[opctype]) {
  2260. if (wordsize < 4 && pso1->mode > 4) {
  2261. emitsize(0x67);
  2262. return;
  2263. } else if (wordsize > 2 && pso1->mode < 3) {
  2264. emitsize(0x67);
  2265. return;
  2266. }
  2267. }
  2268. if (!pso2 || !(1<<SECONDDS & xoptoseg[opctype]))
  2269. return;
  2270. if (wordsize < 4 && pso2->mode > 4) {
  2271. emitsize(0x67);
  2272. return;
  2273. } else if (wordsize > 2 && pso2->mode < 3) {
  2274. emitsize(0x67);
  2275. return;
  2276. }
  2277. }
  2278. #endif /* V386 */
  2279. /* check for word register, or if 386, dword register */
  2280. CODESIZE
  2281. checkwreg(
  2282. register struct psop *psop /* parse stack operand structure */
  2283. )
  2284. {
  2285. if (psop->mode != 3)
  2286. errorc (E_MBR);
  2287. if (psop->dsize != 2
  2288. #ifdef V386
  2289. && (!(cputype&P386) || psop->dsize != 4)
  2290. #endif
  2291. )
  2292. errorc (E_BRI);
  2293. return(0);
  2294. }