INASM386.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:35k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /*
  23.  * inline assembler (386)
  24.  */
  25. #include        <stdio.h> 
  26. #include        "expr.h" 
  27. #include        "c.h" 
  28. #include        "errors.h"
  29. #include "gen386.h"
  30. extern long framedepth, stackdepth, lc_maxauto;
  31. extern int asmline;
  32. extern int lastch;
  33. extern int prm_linkreg;
  34. extern enum e_sym lastst;
  35. extern long ival;
  36. extern short *lptr ;
  37. extern TABLE lsyms;
  38. extern int nextlabel;
  39. extern char lastid[];
  40. ASMNAME *keyimage;
  41. ASMREG *regimage;
  42. static SYM *lastsym;
  43. static enum e_op op;
  44. ASMREG reglst[] = {
  45. { "cs",am_seg,1,2 },
  46. { "ds",am_seg,2,2 },
  47. { "es",am_seg,3,2 },
  48. { "fs",am_seg,4,2 },
  49. { "gs",am_seg,5,2 },
  50. { "ss",am_seg,6,2 },
  51. { "al",am_dreg,0,1 },
  52. { "cl",am_dreg,1,1 },
  53. { "dl",am_dreg,2,1 },
  54. { "bl",am_dreg,3,1 },
  55. { "ah",am_dreg,4,1 },
  56. { "ch",am_dreg,5,1 },
  57. { "dh",am_dreg,6,1 },
  58. { "bh",am_dreg,7,1 },
  59. { "ax",am_dreg,0,2 },
  60. { "cx",am_dreg,1,2 },
  61. { "dx",am_dreg,2,2 },
  62. { "bx",am_dreg,3,2 },
  63. { "sp",am_dreg,4,2 },
  64. { "bp",am_dreg,5,2 },
  65. { "si",am_dreg,6,2 },
  66. { "di",am_dreg,7,2 },
  67. { "eax",am_dreg,0,4 },
  68. { "ecx",am_dreg,1,4 },
  69. { "edx",am_dreg,2,4 },
  70. { "ebx",am_dreg,3,4 },
  71. { "esp",am_dreg,4,4 },
  72. { "ebp",am_dreg,5,4 },
  73. { "esi",am_dreg,6,4 },
  74. { "edi",am_dreg,7,4 },
  75. { "st",am_freg,0,10 },
  76. { "cr0",am_screg,0,4 },
  77. { "cr1",am_screg,2,4 },
  78. { "cr2",am_screg,3,4 },
  79. { "cr3",am_screg,4,4 },
  80. { "cr4",am_screg,5,4 },
  81. { "cr5",am_screg,6,4 },
  82. { "cr6",am_screg,7,4 },
  83. { "cr7",am_screg,8,4 },
  84. { "dr0",am_sdreg,0,4 },
  85. { "dr1",am_sdreg,2,4 },
  86. { "dr2",am_sdreg,3,4 },
  87. { "dr3",am_sdreg,4,4 },
  88. { "dr4",am_sdreg,5,4 },
  89. { "dr5",am_sdreg,6,4 },
  90. { "dr6",am_sdreg,7,4 },
  91. { "dr7",am_sdreg,8,4 },
  92. { "tr0",am_streg,0,4 },
  93. { "tr1",am_streg,2,4 },
  94. { "tr2",am_streg,3,4 },
  95. { "tr3",am_streg,4,4 },
  96. { "tr4",am_streg,5,4 },
  97. { "tr5",am_streg,6,4 },
  98. { "tr6",am_streg,7,4 },
  99. { "tr7",am_streg,8,4 },
  100. { "st",am_freg,0,4 },
  101. { "byte", am_ext,akw_byte,0 },
  102. { "word", am_ext,akw_word,0 },
  103. { "dword", am_ext,akw_dword,0 },
  104. { "fword", am_ext,akw_fword,0 },
  105. { "qword", am_ext,akw_qword,0 },
  106. { "tbyte", am_ext,akw_tbyte,0 },
  107. { "ptr", am_ext, akw_ptr,0 },
  108. { "offset", am_ext,akw_offset,0 },
  109. { 0 , 0 , 0 },
  110. };
  111. static int floating;
  112. void inasmini(void)
  113. {
  114. }
  115. static void asm_err(int errnum)
  116. {
  117. *lptr = 0;
  118. lastch = ' ';
  119. generror(errnum,0,0);
  120. getsym();
  121. }
  122. static ENODE *asm_ident(void)
  123. {
  124. ENODE *node = 0;
  125. char *nm;
  126. int fn = FALSE;
  127. if (lastst != id)
  128. asm_err(ERR_IDEXPECT);
  129. else {
  130.         SYM             *sp;
  131. ENODE *qnode = 0;
  132. nm = litlate(lastid);
  133. getsym();
  134. /* No such identifier */
  135. /* label, put it in the symbol table */
  136.         if( (sp = gsearch(nm)) == 0 ) { 
  137.                  sp = xalloc(sizeof(SYM)); 
  138.                 sp->name = nm; 
  139.                  sp->storage_class = sc_ulabel; 
  140. sp->tp = xalloc(sizeof(TYP));
  141. sp->tp->type = bt_unsigned;
  142. sp->tp->uflags = UF_USED;
  143.                  sp->value.i = nextlabel++; 
  144.                 insert(sp,&lsyms); 
  145.          node = xalloc(sizeof(ENODE));
  146.          node->nodetype = en_labcon;
  147.          node->v.i = sp->value.i;
  148.                 }
  149.         else    {
  150. /* If we get here the symbol was already in the table
  151.  */
  152. foundsp:
  153. sp->tp->uflags |= UF_USED;
  154.                 switch( sp->storage_class ) {
  155.                         case sc_static:
  156.                         case sc_global:
  157.                         case sc_external:
  158.                         case sc_externalfunc:
  159. case sc_abs:
  160. sp->extflag = TRUE;
  161. if (sp->tp->type == bt_ptrfunc || sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
  162. /* make a function node */
  163. if (sp->tp->type == bt_ptrfunc)
  164.                                  node = makenode(en_nacon,sp,0);
  165. else
  166.                                  node = makenode(en_napccon,sp,0);
  167. isfunc:
  168. if (sp->tp->type != bt_ptrfunc && sp->tp->type != bt_func && sp->tp->type != bt_ifunc)
  169. generror(ERR_MISMATCH,0,0);
  170. }
  171. else
  172. /* otherwise make a node for a regular variable */
  173. if (sp->absflag)
  174.                                  node = makenode(en_absacon,sp,0);
  175. else
  176. if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
  177. fn = TRUE;
  178.                                  node = makenode(en_napccon,sp,0);
  179. }
  180. else
  181. if (sp->staticlabel)
  182. node = makenode(en_nalabcon,(char *)sp->value.i,0);
  183. else
  184.                                  node = makenode(en_nacon,sp,0);
  185.                                 break;
  186.                         case sc_const:
  187. /* constants and enums */
  188.                                 node = makenode(en_icon,(char *)sp->value.i,0);
  189. break;
  190. case sc_label:
  191. case sc_ulabel:
  192.          node = xalloc(sizeof(ENODE));
  193.          node->nodetype = en_labcon;
  194.          node->v.i = sp->value.i;
  195. break;
  196.                         default:        /* auto and any errors */
  197.                                 if( sp->storage_class != sc_auto && sp->storage_class != sc_autoreg) {
  198.                                         gensymerror(ERR_ILLCLASS2,sp->name);
  199. }
  200. else {
  201. /* auto variables */
  202.   if (sp->storage_class == sc_auto)
  203.                                  node = makenode(en_autocon,sp,0);
  204. else if (sp->storage_class == sc_autoreg)
  205.                                  node = makenode(en_autoreg,sp,0);
  206. if (fn)
  207. goto isfunc;
  208. }
  209.                                 break;
  210.                         }
  211. (node)->cflags = 0;
  212.                 }
  213. lastsym = sp;
  214. }
  215. return node;
  216. }
  217. static ENODE * asm_label(void)
  218. {
  219. char *nm = litlate(lastid);
  220. ENODE *node;
  221. SYM *sp;
  222. getsym();
  223. /* No such identifier */
  224. /* label, put it in the symbol table */
  225.         if( (sp = search(lastid,&lsyms)) == 0 ) { 
  226.                  sp = xalloc(sizeof(SYM)); 
  227.                 sp->name = litlate(lastid); 
  228.                  sp->storage_class = sc_label; 
  229. sp->tp = xalloc(sizeof(TYP));
  230. sp->tp->type = bt_unsigned;
  231. sp->tp->uflags = 0;
  232.                  sp->value.i = nextlabel++; 
  233.                 insert(sp,&lsyms); 
  234.                 }
  235.         else    {
  236. if (sp->storage_class == sc_label) {
  237. asm_err(ERR_DUPLABEL);
  238. return 0;
  239. }
  240. if (sp->storage_class != sc_ulabel) {
  241. asm_err(ERR_ALABEXPECT);
  242. return 0;
  243. }
  244. sp->storage_class = sc_label;
  245. }
  246. if (lastst != colon) {
  247. asm_err(ERR_ALABEXPECT);
  248. return 0;
  249. }
  250. getsym();
  251.     node = xalloc(sizeof(ENODE));
  252.     node->nodetype = en_labcon;
  253.     node->v.i = sp->value.i;
  254. return node;
  255. }
  256. static int asm_getsize(void)
  257. {
  258. int sz=0;
  259. switch (regimage->regnum) {
  260. case akw_byte: sz = 1; break;
  261. case akw_word: sz = 2; break;
  262. case akw_dword: sz = floating ? 6 : 4; break;
  263. case akw_fword: sz = 6; break;
  264. case akw_qword: sz = 8; break;
  265. case akw_tbyte: sz = 10; break;
  266. case akw_offset: sz = 4; break;
  267. };
  268. getsym();
  269. if (lastst == kw_asmreg) {
  270. regimage = keyimage;
  271. if (regimage->regtype == am_ext) {
  272. if (regimage->regnum != akw_ptr) {
  273. asm_err(ERR_AILLADDRESS);
  274. return 0;
  275. }
  276. getsym();
  277. }
  278. }
  279. if (lastst != kw_asmreg && lastst != openbr && lastst != id) {
  280. asm_err(ERR_AMODEEXPECT);
  281. return 0;
  282. }
  283. regimage=keyimage;
  284. return sz;
  285. }
  286. static int getscale (int *scale)
  287. {
  288. if (lastst == star) {
  289. getsym();
  290. if (lastst == iconst && !*scale) 
  291. if (ival== 1 || ival==2 || ival==4 || ival==8) {
  292. if (ival < 3)
  293. ival--;
  294. else
  295. ival = ival/4+1;
  296. *scale =ival;
  297. getsym();
  298. return 1;
  299. }
  300. asm_err(ERR_ASCALE);
  301. *scale = -1;
  302. return 1;
  303. }
  304. return 0;
  305. }
  306. int asm_enterauto(ENODE *node, int *reg1, int *reg2)
  307. {
  308. if (node && (node->nodetype == en_autocon || node->nodetype == en_autoreg)) {
  309. int *vreg;
  310. if (*reg1 >=0 && *reg2 >=0) {
  311. asm_err(ERR_AINVINDXMODE);
  312. return 0;
  313. }
  314. if (reg1 < 0)
  315. vreg = reg1;
  316. else
  317. vreg = reg2 ;
  318. *vreg = ESP;
  319. if (prm_linkreg) {
  320.            *vreg = EBP;
  321. }
  322. return 1;
  323. }
  324. return 2;
  325. }
  326. static AMODE *asm_mem(void)
  327. {
  328. int reg1=-1, reg2=-1, scale=0, temp,sz=0;
  329. ENODE *node=0;
  330. AMODE *rv;
  331. int gotident = FALSE,autonode = FALSE;
  332. while (TRUE) {
  333. int rg;
  334. getsym();
  335. regimage = keyimage;
  336. rg = regimage->regnum;
  337. switch(lastst) {
  338. case kw_asmreg:
  339. regimage = keyimage;
  340. if (regimage->regtype != am_dreg || regimage->size != 4) {
  341. asm_err(ERR_AINVINDXMODE);
  342. return 0;
  343. }
  344. if (reg1 >= 0) {
  345. if (reg2 >=0) {
  346. asm_err(ERR_AINVINDXMODE);
  347. return 0;
  348. }
  349. reg2 = rg;
  350. getsym();
  351. getscale(&scale);
  352. if (scale == -1)
  353. return 0;
  354. }
  355. else {
  356. getsym();
  357. if (getscale(&scale)) {
  358. if (scale == -1)
  359. return 0;
  360. if (reg2 >= 0) {
  361. reg1 = reg2;
  362. }
  363. reg2 = rg;
  364. }
  365. else {
  366. reg1 = rg;
  367. }
  368. }
  369. break;
  370. case iconst:
  371. if (node)
  372. node = makenode(en_add,node,makenode(en_icon,(char *)intexpr(0),0));
  373. else
  374. node = makenode(en_icon,(char *)intexpr(0),0);
  375. break;
  376. case id:
  377. if (gotident) {
  378. asm_err(ERR_AINVINDXMODE);
  379. return 0;
  380. }
  381. node = asm_ident();
  382. gotident = TRUE;
  383. sz = lastsym->tp->size;
  384. switch(asm_enterauto(node,&reg1,&reg2)) {
  385. case 0:
  386. return 0;
  387. case 1:
  388. autonode = TRUE;
  389. break;
  390. case 2:
  391. autonode = FALSE;
  392. break;
  393. }
  394. break;
  395. default:
  396. asm_err(ERR_AILLADDRESS);
  397. return 0;
  398. }
  399. if (lastst == closebr) {
  400. getsym();
  401. break;
  402. }
  403. if (lastst != plus) {
  404. asm_err(ERR_AINVINDXMODE);
  405. return 0;
  406. }
  407. }
  408. if ((reg2 == 4 || reg2 == 5) && scale > 1) {
  409. asm_err(ERR_AINVINDXMODE);
  410. return 0;
  411. }
  412. rv = xalloc(sizeof(AMODE));
  413. if (node) {
  414. rv->offset = node;
  415. }
  416. if (reg1 >=0) {
  417. rv->preg = reg1;
  418. if (reg2 >=0) {
  419. rv->sreg = reg2;
  420. rv->scale = scale;
  421. rv->mode = am_indispscale;
  422. }
  423. else {
  424. rv->mode = am_indisp;
  425. }
  426. }
  427. else
  428. if (reg2 >=0) {
  429. rv->preg = -1;
  430. rv->sreg = reg2;
  431. rv->scale = scale;
  432. rv->mode = am_indispscale;
  433. }
  434. else
  435. rv->mode = am_direct;
  436. return rv;
  437. }
  438. static AMODE *asm_amode(int nosegreg)
  439. {
  440. AMODE *rv=xalloc(sizeof(AMODE));
  441. int sz = 0,seg=0;
  442. lastsym = 0;
  443. switch (lastst) {
  444.       case iconst:
  445.         case iuconst:
  446.         case lconst:
  447.         case luconst:
  448.         case cconst:
  449. case kw_asmreg:
  450. case openbr:
  451. case id:
  452. break;
  453. default:
  454. asm_err(ERR_AMODEEXPECT);
  455. return 0;
  456. }
  457. if (lastst== kw_asmreg) {
  458. regimage = keyimage;
  459. if (regimage->regtype == am_ext) {
  460. sz = asm_getsize();
  461. regimage = keyimage;
  462. }
  463. }
  464. loop:
  465. switch (lastst) {
  466. case kw_asmreg:
  467. if (regimage->regtype == am_ext) {
  468. asm_err(ERR_ATOOMANYSPECS);
  469. return 0;
  470. }
  471. if (regimage->regtype == am_freg) {
  472. getsym();
  473. if (lastst == openpa) {
  474. getsym();
  475. if (lastst != iconst || ival < 0 || ival > 7) {
  476. asm_err(ERR_ANEEDFP);
  477. return 0;
  478. }
  479. getsym();
  480. needpunc(closepa,0);
  481. }
  482. else ival = 0;
  483. rv->preg = ival;
  484. rv->mode = am_freg;
  485. sz = 10;
  486. }
  487. else if (regimage->regtype == am_seg) {
  488. if (rv->seg) {
  489. asm_err(ERR_ATOOMANYSEGS);
  490. return 0;
  491. }
  492. rv->seg = seg = regimage->regnum;
  493. getsym();
  494. if (lastst == colon) {
  495. getsym();
  496. goto loop;
  497. }
  498. rv->mode = am_seg;
  499. sz = regimage->size;
  500. }
  501. else {
  502. rv->preg = regimage->regnum;
  503. rv->mode = regimage->regtype;
  504. sz = regimage->size;
  505. getsym();
  506. }
  507. break;
  508. case openbr:
  509. rv = asm_mem();
  510. break;
  511. case id:
  512. rv->mode = am_immed;
  513. rv->offset = asm_ident();
  514. rv->length = 4;
  515. if (rv->offset->nodetype == en_autocon || rv->offset->nodetype == en_autoreg) {
  516. asm_err(ERR_AUSELEA);
  517. return 0;
  518. }
  519. break;
  520.       case iconst:
  521.         case iuconst:
  522.         case lconst:
  523.         case luconst:
  524.         case cconst:
  525.                 rv = make_immed(ival);
  526. getsym();
  527.           break;
  528. default:
  529. asm_err(ERR_AILLADDRESS);
  530. return 0;
  531. }
  532. if (rv) {
  533. if (rv->seg) 
  534. if (nosegreg || rv->mode != am_dreg)
  535. if (rv->mode != am_direct && rv->mode != am_indisp && rv->mode != am_indispscale && rv->mode != am_seg) {
  536. asm_err(ERR_ATOOMANYSEGS);
  537. return 0;
  538. }
  539. if (!rv->length)
  540. if (sz)
  541. rv->length = sz;
  542. else if (lastsym)
  543. rv->length = lastsym->tp->size;
  544. if (rv->length < 0)
  545. rv->length = - rv->length;
  546. rv->seg = seg;
  547. }
  548. return rv;
  549. }
  550. static AMODE *asm_immed(void)
  551. {
  552. AMODE *rv;
  553. switch(lastst) {
  554.       case iconst:
  555.         case iuconst:
  556.         case lconst:
  557.         case luconst:
  558.         case cconst:
  559.                 rv = make_immed(ival);
  560. rv->length = 4;
  561. getsym();
  562. return rv;
  563. }
  564. return 0;
  565. }
  566. int isrm(AMODE* ap, int dreg_allowed)
  567. {
  568. switch (ap->mode) {
  569. case am_dreg:
  570. return dreg_allowed;
  571. case am_indisp:
  572. case am_direct:
  573. case am_indispscale:
  574. return 1;
  575. default:
  576. return 0;
  577. }
  578. }
  579. AMODE *getimmed(void)
  580. {
  581. AMODE *rv;
  582. switch(lastst) {
  583.       case iconst:
  584.         case iuconst:
  585.         case lconst:
  586.         case luconst:
  587.         case cconst:
  588.                 rv = make_immed(ival);
  589. getsym();
  590. return rv;
  591. default:
  592. return 0;
  593. }
  594. }
  595. enum e_op asm_op(void)
  596. {
  597. int op;
  598. if (lastst != kw_asminst) {
  599. asm_err(ERR_AINVOP);
  600. return -1;
  601. }
  602. op = keyimage->atype;
  603. getsym();
  604. floating = op >= op_f2xm1;
  605. return op;
  606. }
  607. static OCODE *make_ocode(AMODE *ap1, AMODE *ap2, AMODE *ap3)
  608. {
  609. OCODE *o = xalloc(sizeof(OCODE));
  610. o->oper1 = ap1;
  611. o->oper2 = ap2;
  612. o->oper3 = ap3;
  613. return o;
  614. }
  615. static OCODE *ope_math (void)
  616. {
  617. AMODE *ap1,*ap2;
  618. ap1 = asm_amode(TRUE);
  619. if (!ap1)
  620. return 0;
  621. if (!isrm(ap1,TRUE))
  622. return (OCODE *)-1;
  623. needpunc(comma,0);
  624. ap2 = asm_amode(TRUE);
  625. if (!ap2)
  626. return 0;
  627. if (ap1->mode != am_dreg) {
  628. if (ap2->mode != am_immed && ap2->mode != am_dreg)
  629. return (OCODE *)-1;
  630. }
  631. else
  632. if (!isrm(ap2,TRUE) && ap2->mode != am_immed)
  633. return (OCODE *)-1;
  634. if (ap2->mode != am_immed)
  635. if (ap1->length && ap2->length && ap1->length != ap2->length)
  636. return (OCODE *) -2;
  637. return make_ocode(ap1,ap2,0);
  638. }
  639. static OCODE *ope_arpl (void)
  640. {
  641. AMODE *ap1,*ap2;
  642. ap1 = asm_amode(TRUE);
  643. if (!ap1)
  644. return 0;
  645. if (!isrm(ap1,TRUE))
  646. return (OCODE *)-1;
  647. needpunc(comma,0);
  648. ap2 = asm_amode(TRUE);
  649. if (!ap2)
  650. return 0;
  651.   if (ap2->mode != am_dreg)
  652. return (OCODE *)-1;
  653. if (!ap1->length || !ap2->length || ap1->length != ap2->length || ap1->length != 2)
  654. return (OCODE *) -2;
  655. return make_ocode(ap1,ap2,0);
  656. }
  657. static OCODE *ope_bound (void)
  658. {
  659. AMODE *ap1,*ap2;
  660. ap1 = asm_amode(TRUE);
  661. if (!ap1)
  662. return 0;
  663.   if (ap1->mode != am_dreg)
  664. return (OCODE *)-1;
  665. needpunc(comma,0);
  666. ap2 = asm_amode(TRUE);
  667. if (!ap2)
  668. return 0;
  669. if (!isrm(ap2,FALSE))
  670. return (OCODE *)-1;
  671. switch(ap1->length) {
  672. case 1:
  673. return (OCODE *)-1;
  674. case 2:
  675. if (ap2->length != 4) {
  676. return (OCODE *) -2;
  677. }
  678. break;
  679. case 4:
  680. if (ap2->length != 8) {
  681. return (OCODE *) -2;
  682. }
  683. break;
  684. }
  685. return make_ocode(ap1,ap2,0);
  686. }
  687. static OCODE *ope_bitscan (void)
  688. {
  689. AMODE *ap1,*ap2;
  690. ap1 = asm_amode(TRUE);
  691. if (!ap1)
  692. return 0;
  693. if (ap1->mode != am_dreg)
  694. return (OCODE *)-1;
  695. needpunc(comma,0);
  696. ap2 = asm_amode(TRUE);
  697. if (!ap2)
  698. return 0;
  699. if (!isrm(ap2,TRUE))
  700. return (OCODE *)-1;
  701. if (ap1->length == 1 || ap2->length != ap1->length)
  702. return (OCODE *) -2;
  703. return make_ocode(ap1,ap2,0);
  704. }
  705. static OCODE *ope_bit (void)
  706. {
  707. AMODE *ap1,*ap2;
  708. ap1 = asm_amode(TRUE);
  709. if (!ap1)
  710. return 0;
  711. if (!isrm(ap1,TRUE))
  712. return (OCODE *)-1;
  713. needpunc(comma,0);
  714. ap2 = asm_amode(TRUE);
  715. if (!ap2) 
  716. return 0;
  717. if (ap2->mode != am_immed && ap2->mode != am_dreg)
  718. return (OCODE *)-1;
  719. if (ap1->length == 1 || ap2->mode == am_dreg && ap2->length == 1)
  720. return (OCODE *) -2;
  721. return make_ocode(ap1,ap2,0);
  722. }
  723. static OCODE *ope_call (void)
  724. {  
  725. AMODE *ap1=asm_amode(TRUE);
  726. if (!ap1)
  727. return 0;
  728. if (ap1->mode == am_immed) {
  729. if (ap1->offset->nodetype != en_nalabcon && ap1->offset->nodetype != en_labcon 
  730. && ap1->offset->nodetype != en_napccon || ap1->seg)
  731. return (OCODE *)-1;
  732. }
  733. else {
  734. if (!isrm(ap1,TRUE))
  735. return (OCODE *)-1;
  736. if ((ap1->length != 4) && (ap1->length != 6))
  737. return (OCODE *) -2;
  738. }
  739. return make_ocode(ap1,0,0);
  740. }
  741. static OCODE *ope_incdec (void)
  742. {
  743. AMODE *ap1=asm_amode(TRUE);
  744. if (!ap1)
  745. return 0;
  746. if (!isrm(ap1,TRUE))
  747. return (OCODE *)-1;
  748. if (ap1->length >4) {
  749. return (OCODE *) -2;
  750. }
  751. return make_ocode(ap1,0,0);
  752. }
  753. static OCODE *ope_rm (void)
  754. {
  755. return(ope_incdec());
  756. }
  757. static OCODE *ope_enter (void)
  758. {
  759. AMODE *ap1, *ap2;
  760. ap1 = asm_immed();
  761. if (!ap1)
  762. return 0;
  763. needpunc(comma,0);
  764. ap2 = asm_immed();
  765. if (!ap2)
  766. return 0;
  767. return make_ocode(ap1,ap2,0);
  768. }
  769. static OCODE *ope_imul (void)
  770. {
  771. AMODE *ap1 = asm_amode(TRUE),*ap2=0,*ap3=0;
  772. if (!ap1)
  773. return 0;
  774. if (!isrm(ap1,TRUE))
  775. return (OCODE *)-1;
  776. if (lastst == comma) {
  777. getsym();
  778. ap2 = asm_amode(TRUE);
  779. if (lastst == comma) {
  780. getsym();
  781. ap3 = asm_amode(TRUE);
  782. }
  783. }
  784. if (ap2) {
  785. if (ap1->mode != am_dreg || ap1->length == 1)
  786. return (OCODE *)-1;
  787. if (!isrm(ap2,TRUE) && ap2->mode != am_immed)
  788. return (OCODE *)-1;
  789. if (ap3)
  790. if (ap2->mode == am_immed || ap3->mode != am_immed)
  791. return (OCODE *)-1;
  792. }
  793. return make_ocode(ap1,ap2,ap3);
  794. }
  795. static OCODE *ope_in (void)
  796. {
  797. AMODE *ap1 = asm_amode(TRUE),*ap2;
  798. if (!ap1)
  799. return 0;
  800. if (ap1-> mode != am_dreg || ap1->preg != 0)
  801. return (OCODE *)-1;
  802. needpunc(comma,0);
  803. ap2 = asm_amode(TRUE);
  804. if (!ap2)
  805. return 0;
  806. if (ap2->mode != am_immed &&( ap2->mode != am_dreg || ap2->preg != 2 || ap2->length !=2))
  807. return (OCODE *)-1;
  808. return make_ocode(ap1,ap2,0);
  809. }
  810. static OCODE *ope_imm8 (void)
  811. {
  812. AMODE *ap1 = asm_immed();
  813. if (!ap1)
  814. return 0;
  815. return make_ocode(ap1,0,0);
  816. }
  817. static OCODE *ope_relbra (void)
  818. {
  819. AMODE *ap1=asm_amode(TRUE);
  820. if (!ap1)
  821. return 0;
  822. if (ap1->mode != am_immed)
  823. return (OCODE *)-1;
  824. if (ap1->offset->nodetype != en_nalabcon && ap1->offset->nodetype != en_labcon)
  825.   return (OCODE *)-1;
  826. return make_ocode(ap1,0,0);
  827. }
  828. static OCODE *ope_relbr8 (void)
  829. {
  830. return ope_relbra();
  831. }
  832. static OCODE *ope_jmp (void)
  833. {
  834. return ope_call();
  835. }
  836. static OCODE *ope_regrm (void)
  837. {
  838. AMODE *ap1,*ap2;
  839. ap1 = asm_amode(TRUE);
  840. if (!ap1) 
  841. return 0;
  842. if (ap1->mode != am_dreg)
  843. return (OCODE *)-1;
  844. needpunc(comma,0);
  845. ap2 = asm_amode(TRUE);
  846. if (!ap2) 
  847. return 0;
  848. if (!isrm(ap2,TRUE))
  849. return (OCODE *)-1;
  850. if (op == op_lea && ap2->mode == am_dreg)
  851. return (OCODE *)-1;
  852. if (ap2->length && ap1->length != ap2->length || ap1->length == 1)
  853. return (OCODE *)-2;
  854. return make_ocode(ap1,ap2,0);
  855. }
  856. static OCODE *ope_loadseg (void)
  857. {
  858. AMODE *ap1,*ap2;
  859. ap1 = asm_amode(TRUE);
  860. if (!ap1)
  861. return 0;
  862. if (ap1->mode != am_dreg)
  863. return (OCODE *)-1;
  864. needpunc(comma,0);
  865. ap2 = asm_amode(TRUE);
  866. if (!ap2)
  867. return 0;
  868. if (!isrm(ap2,TRUE))
  869. return (OCODE *)-1;
  870. if (ap1->length != 4 || ap2->length != 6)
  871. return (OCODE *)-1;
  872. return make_ocode(ap1,ap2,0);
  873. }
  874. static OCODE *ope_lgdt (void)
  875. {
  876. AMODE *ap1,*ap2;
  877. ap1 = asm_amode(TRUE);
  878. if (!ap1)
  879. return 0;
  880.   if (!isrm(ap1,FALSE) || ap1->length != 6)
  881. return (OCODE *)-1;
  882. return make_ocode(ap1,0,0);
  883. }
  884. static OCODE *ope_lidt (void)
  885. {
  886. return ope_lgdt();
  887. }
  888. static OCODE *ope_rm16 (void)
  889. {
  890. AMODE *ap1,*ap2;
  891. ap1 = asm_amode(TRUE);
  892. if (!ap1)
  893. return 0;
  894.   if (!isrm(ap1,TRUE) || ap1->length != 2)
  895. return (OCODE *)-1;
  896. return make_ocode(ap1,0,0);
  897. }
  898. static OCODE *ope_mov (void)
  899. {
  900. AMODE *ap1 = asm_amode(TRUE),*ap2;
  901. if (!ap1)
  902. return 0;
  903. if (!isrm(ap1,TRUE) && ap1->mode != am_seg && ap1->mode != am_screg && ap1->mode != am_sdreg && ap1->mode != am_streg)
  904. return (OCODE *)-1;
  905. needpunc(comma,0);
  906. ap2 = asm_amode(TRUE);
  907. if (!ap2)
  908. return 0;
  909. if (ap1->mode == am_dreg) {
  910. if (!isrm(ap2,TRUE) && ap2->mode != am_immed && (ap2->length != 4 || (ap2->mode != am_screg && ap2->mode != am_sdreg && ap2->mode != am_streg)))
  911. return (OCODE *)-1;
  912. }
  913. else if (isrm(ap1,TRUE)) {
  914. if (ap2->mode != am_dreg && ap2->mode != am_immed && ap2->mode != am_seg)
  915. return (OCODE *)-1;
  916. }
  917. else if (ap1->mode == am_seg) {
  918. if (!isrm(ap2,TRUE))
  919. return (OCODE *)-1;
  920. }
  921. else if (ap2->length != 4 || ap2->mode != am_dreg)
  922. return (OCODE *)-1;
  923. if (ap1->length && ap2->length && ap1->length != ap2->length)
  924. return (OCODE *) -2;
  925. return make_ocode(ap1,ap2,0);
  926. }
  927. static OCODE *ope_movsx (void)
  928. {
  929. AMODE *ap1,*ap2;
  930. ap1 = asm_amode(TRUE);
  931. if (!ap1)
  932. return 0;
  933.   if (ap1->mode != am_dreg)
  934. return (OCODE *)-1;
  935. needpunc(comma,0);
  936. ap2 = asm_amode(TRUE);
  937. if (!ap2)
  938. return 0;
  939. if (!isrm(ap2,TRUE))
  940. return (OCODE *)-1;
  941. if (!ap2->length || ap1->length <= ap2->length) {
  942. asm_err(ERR_AINVSIZE);
  943. }
  944. return make_ocode(ap1,ap2,0);
  945. }
  946. static OCODE *ope_out (void)
  947. {
  948. AMODE *ap1 = asm_amode(TRUE),*ap2;
  949. if (!ap1)
  950. return 0;
  951. if (ap1->mode != am_immed &&( ap1->mode != am_dreg || ap1->preg != 2 || ap1->length !=2))
  952. return (OCODE *)-1;
  953. needpunc(comma,0);
  954. ap2 = asm_amode(TRUE);
  955. if (!ap2)
  956. return 0;
  957. if (ap2-> mode != am_dreg || ap2->preg != 0)
  958. return (OCODE *)-1;
  959. return make_ocode(ap1,ap2,0);
  960. }
  961. static OCODE *ope_pushpop (void)
  962. {
  963. AMODE *ap1;
  964. ap1 = asm_amode(TRUE);
  965. if (!ap1)
  966. return 0;
  967. if (!isrm(ap1,TRUE) && ap1->mode != am_seg && ap1->mode != am_immed || (ap1->mode == am_immed && op == op_pop))
  968. return (OCODE *)-1;
  969. if (ap1->mode != am_immed && ap1->length !=2 && ap1->length != 4 ) {
  970. return (OCODE *) -2;
  971. }
  972. if (op == op_pop && ap1->mode == am_seg && ap1->seg == 1)
  973. return (OCODE *) -1;
  974. return make_ocode (ap1,0,0);
  975. }
  976. static OCODE *ope_shift (void)
  977. {
  978. AMODE *ap1,*ap2;
  979. ap1 = asm_amode(2);
  980. if (!ap1)
  981. return 0;
  982. if (!isrm(ap1,TRUE))
  983. return (OCODE *)-1;
  984. needpunc(comma,0);
  985. ap2 = asm_amode(TRUE);
  986. if (!ap2)
  987. return 0;
  988. if (ap2->mode != am_immed && ap2->mode != am_dreg)
  989. return (OCODE *)-1;
  990. if (ap2->mode == am_dreg)
  991. if (ap2->preg != 1 || ap2->length != 1)
  992. return (OCODE *)-1;
  993. return make_ocode(ap1,ap2,0);
  994. }
  995. static OCODE *ope_ret (void)
  996. {
  997. AMODE *ap1 ;
  998. if (lastst != iconst)
  999. return make_ocode(0,0,0);
  1000. ap1 = asm_amode(TRUE);
  1001. return make_ocode(ap1,0,0);
  1002. }
  1003. static OCODE *ope_set (void)
  1004. {
  1005. AMODE *ap1;
  1006. ap1 = asm_amode(TRUE);
  1007. if (!ap1)
  1008. return 0;
  1009.   if (!isrm(ap1,TRUE) || ap1 ->length != 1)
  1010. return (OCODE *)-1;
  1011. return make_ocode(ap1,0,0);
  1012. }
  1013. static OCODE *ope_shld (void)
  1014. {
  1015. AMODE *ap1,*ap2,*ap3;
  1016. ap1 = asm_amode(TRUE);
  1017. if (!ap1)
  1018. return 0;
  1019. if (!isrm(ap1,TRUE))
  1020. return (OCODE *)-1;
  1021. needpunc(comma,0);
  1022. ap2 = asm_amode(TRUE);
  1023. if (!ap2)
  1024. return 0;
  1025. if (ap2->mode != am_dreg || ap2->length == 1)
  1026. return (OCODE *)-1;
  1027. if (ap1->length != ap2->length) {
  1028. asm_err(ERR_AINVSIZE);
  1029. }
  1030. needpunc(comma,0);
  1031. ap3 = asm_amode(TRUE);
  1032. if (!ap3)
  1033. return 0;
  1034. if (ap3->mode != am_immed && ap3->mode != am_dreg)
  1035. return (OCODE *)-1;
  1036. if (ap3->mode == am_dreg)
  1037. if (ap3->preg != 1 || ap3->length != 1)
  1038. return (OCODE *)-1;
  1039. return make_ocode(ap1,ap2,ap3);
  1040. }
  1041. static OCODE *ope_test (void)
  1042. {
  1043. AMODE *ap1,*ap2;
  1044. ap1 = asm_amode(TRUE);
  1045. if (!ap1)
  1046. return 0;
  1047. if (!isrm(ap1,TRUE))
  1048. return (OCODE *)-1;
  1049. needpunc(comma,0);
  1050. ap2 = asm_amode(TRUE);
  1051. if (!ap2)
  1052. return 0;
  1053. if (ap2->mode != am_dreg && ap2->mode != am_immed)
  1054. return (OCODE *)-1;
  1055. if (ap2->mode == am_dreg && ap1->length != ap2->length) {
  1056. return (OCODE *) -2;
  1057. }
  1058. return make_ocode(ap1,ap2,0);
  1059. }
  1060. static OCODE *ope_xchg (void)
  1061. {
  1062. AMODE *ap1, *ap2;
  1063. ap1 = asm_amode(TRUE);
  1064. if (!ap1)
  1065. return 0;
  1066. if (!isrm(ap1,TRUE))
  1067. return (OCODE *)-1;
  1068. needpunc(comma,0);
  1069. ap2 = asm_amode(TRUE);
  1070. if (!ap2)
  1071. return 0;
  1072. if (ap1->mode == am_dreg) {
  1073. if (!isrm(ap2,TRUE))
  1074. return (OCODE *)-1;
  1075. }
  1076. else
  1077. if (ap2->mode != am_dreg)
  1078. return (OCODE *)-1;
  1079. if (ap1->length != ap2->length)
  1080. return (OCODE *)-2;
  1081. return make_ocode(ap1,ap2,0);
  1082. }
  1083. static OCODE *ope_fmath (void)
  1084. {
  1085. AMODE *ap1, *ap2=0;
  1086. ap1 = asm_amode(TRUE);
  1087. if (!ap1)
  1088. return 0;
  1089. if (isrm(ap1,FALSE)) {
  1090. if (ap1->length != 6 && ap1->length != 8)
  1091. return (OCODE *) -2;
  1092. }
  1093. else {
  1094. if (ap1->mode != am_freg)
  1095. return (OCODE *)-1;
  1096. needpunc(comma,0);
  1097. ap2 = asm_amode(TRUE);
  1098. if (ap2->mode != am_freg)
  1099. return (OCODE *)-1;
  1100. if (ap1->preg && ap2->preg)
  1101. return (OCODE *)-1;
  1102. }
  1103. return make_ocode(ap1,ap2,0);
  1104. }
  1105. static OCODE *ope_fmathp (void)
  1106. {
  1107. AMODE *ap1, *ap2;
  1108. if (lastst != kw_asmreg)
  1109. return make_ocode(0,0,0);
  1110. ap1 = asm_amode(TRUE);
  1111. if (!ap1)
  1112. return 0;
  1113. if (ap1->mode != am_freg)
  1114. return (OCODE *)-1;
  1115. needpunc(comma,0);
  1116. ap2 = asm_amode(TRUE);
  1117. if (!ap2)
  1118. return 0;
  1119. if (ap2->mode != am_freg)
  1120.   return (OCODE *)-1;
  1121. if (ap1->preg && ap2->preg)
  1122.   return (OCODE *)-1;
  1123. return make_ocode(ap1,ap2,0);
  1124. }
  1125. static OCODE *ope_fmathi (void)
  1126. {
  1127. AMODE *ap1;
  1128. ap1 = asm_amode(TRUE);
  1129. if (!ap1)
  1130. return 0;
  1131. if (isrm(ap1,FALSE)) {
  1132. if (ap1->length != 6 && ap1->length != 2)
  1133. return (OCODE *) -2;
  1134. }
  1135. else {
  1136. return (OCODE *)-1;
  1137. }
  1138. return make_ocode(ap1,0,0);
  1139. }
  1140. static OCODE *ope_fcom (void)
  1141. {
  1142. AMODE *ap1;
  1143. if (lastst != kw_asmreg && lastst != openbr)
  1144. return make_ocode(0,0,0);
  1145. ap1 = asm_amode(TRUE);
  1146. if (!ap1)
  1147. return 0;
  1148. if (isrm(ap1,FALSE)) {
  1149. if (ap1->length != 6 && ap1->length != 8)
  1150. return (OCODE *) -2;
  1151. }
  1152. else {
  1153. if (ap1->mode != am_freg)
  1154. return (OCODE *)-1;
  1155. }
  1156. return make_ocode(ap1,0,0);
  1157. }
  1158. static OCODE *ope_freg (void)
  1159. {
  1160. AMODE *ap1;
  1161. ap1 = asm_amode(TRUE);
  1162. if (!ap1)
  1163. return 0;
  1164. if (ap1->mode != am_freg)
  1165. return (OCODE *)-1;
  1166. return make_ocode(ap1,0,0);
  1167. }
  1168. static OCODE *ope_ficom (void)
  1169. {
  1170. AMODE *ap1,*ap2;
  1171. ap1 = asm_amode(TRUE);
  1172. if (!ap1)
  1173. return 0;
  1174. if (!isrm(ap1,FALSE))
  1175. return (OCODE *)-1;
  1176. if (ap1->length != 2 && ap1->length != 6)
  1177. return (OCODE *)-2;
  1178. return make_ocode(ap1,0,0);
  1179. }
  1180. static OCODE *ope_fild (void)
  1181. {
  1182. AMODE *ap1;
  1183. ap1 = asm_amode(TRUE);
  1184. if (!ap1)
  1185. return 0;
  1186. if (! isrm(ap1,FALSE))
  1187. return (OCODE *)-1;
  1188. if (ap1->length != 2 && ap1->length != 6 && ap1->length != 8)
  1189. return (OCODE *) -2;
  1190. return make_ocode(ap1,0,0);
  1191. }
  1192. static OCODE *ope_fist (void)
  1193. {
  1194. AMODE *ap1;
  1195. ap1 = asm_amode(TRUE);
  1196. if (!ap1)
  1197. return 0;
  1198. if (! isrm(ap1,FALSE))
  1199. return (OCODE *)-1;
  1200. if (ap1->length != 2 && ap1->length != 6)
  1201. return (OCODE *) -2;
  1202. return make_ocode(ap1,0,0);
  1203. }
  1204. static OCODE *ope_fld (void)
  1205. {
  1206. AMODE *ap1;
  1207. ap1 = asm_amode(TRUE);
  1208. if (!ap1)
  1209. return 0;
  1210. if (isrm(ap1,FALSE)) {
  1211. if (ap1->length != 6 && ap1->length != 8 && ap1->length != 10)
  1212. return (OCODE *) -2;
  1213. }
  1214. else if (ap1->mode != am_freg)
  1215. return (OCODE *)-1;
  1216. return make_ocode(ap1,0,0);
  1217. }
  1218. static OCODE *ope_fst (void)
  1219. {
  1220. AMODE *ap1;
  1221. ap1 = asm_amode(TRUE);
  1222. if (!ap1)
  1223. return 0;
  1224. if (isrm(ap1,FALSE)) {
  1225. if (ap1->length != 6 && ap1->length != 8)
  1226. return (OCODE *) -2;
  1227. }
  1228. else if (ap1->mode != am_freg || ap1->preg == 0)
  1229. return (OCODE *)-1;
  1230. return make_ocode(ap1,0,0);
  1231. }
  1232. static OCODE *ope_fstp (void)
  1233. {
  1234. AMODE *ap1;
  1235. ap1 = asm_amode(TRUE);
  1236. if (!ap1)
  1237. return 0;
  1238. if (isrm(ap1,FALSE)) {
  1239. if (ap1->length != 6 && ap1->length != 8 && ap1->length != 10)
  1240. return (OCODE *) -2;
  1241. }
  1242. else if (ap1->mode != am_freg || ap1->preg == 0)
  1243. return (OCODE *)-1;
  1244. return make_ocode(ap1,0,0);
  1245. }
  1246. static OCODE *ope_fucom (void)
  1247. {
  1248. AMODE *ap1;
  1249. if (lastst != kw_asmreg)
  1250. return make_ocode(0,0,0);
  1251.   ap1 = asm_amode(TRUE);
  1252. if (!ap1)
  1253. return 0;
  1254. if (ap1->mode != am_freg || ap1->preg == 0)
  1255. return (OCODE *)-1;
  1256. return make_ocode(ap1,0,0);
  1257. }
  1258. static OCODE *ope_fxch (void)
  1259. {
  1260. return ope_fucom();
  1261. }
  1262. static OCODE *ope_mn (void)
  1263. {
  1264. AMODE *ap1;
  1265. ap1 = asm_amode(TRUE);
  1266. if (!ap1)
  1267. return 0;
  1268. if (!isrm(ap1,FALSE))
  1269. return (OCODE *)-1;
  1270. ap1->length = 10;
  1271. return make_ocode(ap1,0,0);
  1272. }
  1273. static OCODE *ope_m16 (void)
  1274. {
  1275. AMODE *ap1;
  1276. ap1 = asm_amode(TRUE);
  1277. if (!ap1)
  1278. return 0;
  1279. if (!isrm(ap1,TRUE))
  1280. return (OCODE *)-1;
  1281. if (ap1->mode == am_dreg)
  1282. if  (op != op_fstsw && op != op_fnstsw && op != op_fldsw && ap1->preg != 0) 
  1283. return (OCODE *)-1;
  1284. if (ap1->length != 2)
  1285. return (OCODE *) -2;
  1286. return make_ocode(ap1,0,0);
  1287. }
  1288. static OCODE *ope_cmps(void)
  1289. {
  1290. AMODE *ap1,*ap2;
  1291. ap1 = asm_amode(TRUE);
  1292. if (!ap1)
  1293. return 0;
  1294. needpunc(comma,0);
  1295. ap2 = asm_amode(TRUE);
  1296. if (!ap2)
  1297. return 0;
  1298. if (ap1->mode != am_indisp || ap2->mode != am_indisp)
  1299. return (OCODE *)-1;
  1300. if (ap1->preg != 6 || ap2->preg != 7)
  1301. return (OCODE *)-1;
  1302. if (ap1->offset || ap2->offset)
  1303. return (OCODE *)-1;
  1304. if (!ap1->seg || ap2->seg != 3)
  1305. return (OCODE *)-1;
  1306. if (!ap1->length && !ap2->length)
  1307. return (OCODE *)-2;
  1308. return make_ocode(ap1,ap2,0);
  1309. }
  1310. static OCODE *ope_ins(void)
  1311. {
  1312. AMODE *ap1,*ap2;
  1313. ap1 = asm_amode(TRUE);
  1314. if (!ap1)
  1315. return 0;
  1316. needpunc(comma,0);
  1317. ap2 = asm_amode(TRUE);
  1318. if (!ap2)
  1319. return 0;
  1320. if (ap1->mode != am_indisp || ap2->mode != am_dreg)
  1321. return (OCODE *)-1;
  1322. if (ap1->offset)
  1323. return (OCODE *)-1;
  1324. if (ap1->preg != 7 || ap2->preg != 2)
  1325. return (OCODE *)-1;
  1326. if (ap2->seg || ap1->seg != 3)
  1327. return (OCODE *)-1;
  1328. if (ap2->length != 2 || !ap1->length)
  1329. return (OCODE *)-2;
  1330. return make_ocode(ap1,ap2,0);
  1331. }
  1332. static OCODE *ope_lods(void)
  1333. {
  1334. AMODE *ap1,*ap2;
  1335. ap1 = asm_amode(TRUE);
  1336. if (!ap1)
  1337. return 0;
  1338. if (ap1->mode != am_indisp || ap1->offset)
  1339. return (OCODE *)-1;
  1340. if (ap1->preg != 6)
  1341. return (OCODE *)-1;
  1342. if (!ap1->length)
  1343. return (OCODE *)-2;
  1344. return make_ocode(ap1,0,0);
  1345. }
  1346. static OCODE *ope_movs(void)
  1347. {
  1348. AMODE *ap1,*ap2;
  1349. ap2 = asm_amode(TRUE);
  1350. if (!ap2)
  1351. return 0;
  1352. needpunc(comma,0);
  1353. ap1 = asm_amode(TRUE);
  1354. if (!ap1)
  1355. return 0;
  1356. if (ap1->mode != am_indisp || ap2->mode != am_indisp)
  1357. return (OCODE *)-1;
  1358. if (ap1->preg != 6 || ap2->preg != 7)
  1359. return (OCODE *)-1;
  1360. if (ap1->offset || ap2->offset)
  1361. return (OCODE *)-1;
  1362. if (!ap1->seg || ap2->seg != 3)
  1363. return (OCODE *)-1;
  1364. if (!ap1->length && !ap2->length)
  1365. return (OCODE *)-2;
  1366. return make_ocode(ap2,ap1,0);
  1367. }
  1368. static OCODE *ope_outs(void)
  1369. {
  1370. AMODE *ap1,*ap2;
  1371. ap1 = asm_amode(TRUE);
  1372. if (!ap1)
  1373. return 0;
  1374. needpunc(comma,0);
  1375. ap2 = asm_amode(TRUE);
  1376. if (!ap2)
  1377. return 0;
  1378. if (ap2->mode != am_indisp || ap1->mode != am_dreg || ap2->offset)
  1379. return (OCODE *)-1;
  1380. if (ap2->preg != 6 || ap1->preg != 2)
  1381. return (OCODE *)-1;
  1382. if (ap1->seg || ap2->seg != 2)
  1383. return (OCODE *)-1;
  1384. if (ap1->length != 2 || !ap2->length)
  1385. return (OCODE *)-2;
  1386. return make_ocode(ap1,ap2,0);
  1387. }
  1388. static OCODE *ope_scas(void)
  1389. {
  1390. AMODE *ap1,*ap2;
  1391. ap1 = asm_amode(TRUE);
  1392. if (!ap1)
  1393. return 0;
  1394. if (ap1->mode != am_indisp || ap1->offset)
  1395. return (OCODE *)-1;
  1396. if (ap1->preg != 7)
  1397. return (OCODE *)-1;
  1398. if (ap1->seg != 3)
  1399. return (OCODE *)-1;
  1400. if (!ap1->length)
  1401. return (OCODE *)-2;
  1402. return make_ocode(ap1,0,0);
  1403. }
  1404. static OCODE *ope_xlat(void)
  1405. {
  1406. AMODE *ap1,*ap2;
  1407. ap1 = asm_amode(TRUE);
  1408. if (!ap1)
  1409. return 0;
  1410. if (ap1->mode != am_indisp || ap1->offset)
  1411. return (OCODE *)-1;
  1412. if (ap1->preg != 3)
  1413. return (OCODE *)-1;
  1414. if (ap1->length && ap1->length != 1)
  1415. return (OCODE *)-2;
  1416. ap1->length = 1;
  1417. return make_ocode(ap1,0,0);
  1418. }
  1419. static OCODE *ope_reg32(void)
  1420. {
  1421. AMODE *ap1 = asm_amode(TRUE);
  1422. if (!ap1)
  1423. return 0;
  1424. if (ap1->mode != am_dreg)
  1425. return (OCODE *)-1;
  1426. if (ap1->length != 4)
  1427. return (OCODE *)-2;
  1428. return make_ocode(ap1,0,0);
  1429. }
  1430. static OCODE *ope_stos(void)
  1431. {
  1432. return ope_scas();
  1433. }
  1434. OCODE *(*funcs[])(void) = {
  1435. 0, ope_math,ope_arpl,ope_bound ,ope_bitscan ,ope_bit ,ope_call ,ope_incdec, 
  1436. ope_rm ,ope_enter ,ope_imul ,ope_in ,ope_imm8 ,ope_relbra ,ope_relbr8, 
  1437. ope_jmp ,ope_regrm ,ope_loadseg ,ope_lgdt ,ope_lidt ,ope_rm16 ,ope_mov ,
  1438. ope_movsx ,ope_out ,ope_pushpop ,ope_shift ,ope_ret ,ope_set ,ope_shld ,
  1439. ope_test ,ope_xchg ,ope_fmath ,ope_fmathp ,ope_fmathi ,ope_fcom ,ope_freg ,
  1440. ope_ficom ,ope_fild ,ope_fist ,ope_fld ,ope_fst ,ope_fstp ,ope_fucom ,
  1441. ope_fxch ,ope_mn, ope_m16, ope_cmps, ope_ins, ope_lods, ope_movs,
  1442. ope_outs, ope_scas, ope_stos, ope_xlat, ope_reg32  };
  1443. SNODE *asm_statement (int shortfin)
  1444. {
  1445. SNODE *snp=0, **snpp = &snp;
  1446. OCODE *rv;
  1447. ENODE *node;
  1448. ASMNAME *ki;
  1449. int iserr = 0;
  1450. lastsym = 0;
  1451. do {
  1452. (*snpp) = xalloc(sizeof(SNODE));
  1453. (*snpp)->stype = st_asm;
  1454. (*snpp)->label = 0;
  1455. (*snpp)->exp = 0;
  1456. (*snpp)->next = 0;
  1457. if (lastst != kw_asminst) {
  1458. if (lastst == kw_int) {
  1459. getsym();
  1460. op = op_int;
  1461. rv = ope_imm8();
  1462. goto join;
  1463. }
  1464. node = asm_label();
  1465. if (!node)
  1466. return (*snpp);
  1467. asmline = shortfin;
  1468. if (lastst==semicolon)
  1469. getsym();
  1470. (*snpp)->stype = st_label;
  1471. (*snpp)->label = (SNODE *)node->v.i;
  1472. return (*snpp);
  1473. }
  1474. ki = keyimage;
  1475. op = asm_op();
  1476. if (op == -1)
  1477. return (*snpp);
  1478. if (keyimage->amode == 0) {
  1479. rv = xalloc(sizeof(OCODE));
  1480. rv->oper1=rv->oper2=rv->oper3 = 0;
  1481. }
  1482. else {
  1483. rv = (*funcs[ki->amode])();
  1484. join:
  1485. if (!rv || rv == (OCODE *)-1 || rv == (OCODE *)-2) {
  1486. if (rv == (OCODE *)-1 )
  1487. asm_err(ERR_AILLADDRESS);
  1488. if (rv == (OCODE *)-2 )
  1489. asm_err(ERR_AINVSIZE);
  1490. iserr=1;
  1491. return (snp);
  1492. }
  1493. }
  1494. if (rv->oper1 && rv->oper2) {
  1495. if (!rv->oper1->length)
  1496. if (!rv->oper2->length) {
  1497. asm_err(ERR_AINVSIZE);
  1498. iserr=1;
  1499. }
  1500. else
  1501. rv->oper1->length = rv->oper2->length;
  1502. else
  1503. if (!rv->oper2->length)
  1504. rv->oper2->length = rv->oper1->length;
  1505. }
  1506. rv->noopt = TRUE;
  1507. rv->opcode = op;
  1508. rv->fwd = rv->back = 0;
  1509. (*snpp)->exp = rv;
  1510. snpp = &(*snpp)->next;
  1511. } while (op == op_rep || op == op_repnz || op == op_repz || op == op_repe || op == op_repne || op == op_lock);
  1512. asmline = shortfin;
  1513. if (!iserr)
  1514. needpunc(semicolon,0);
  1515. else if (lastst == semicolon)
  1516. getsym();
  1517. return (snp);
  1518. }