parser.c
上传用户:yuppie_zhu
上传日期:2007-01-08
资源大小:535k
文件大小:22k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* parser.c   source line parser for the Netwide Assembler
  2.  *
  3.  * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  4.  * Julian Hall. All rights reserved. The software is
  5.  * redistributable under the licence given in the file "Licence"
  6.  * distributed in the NASM archive.
  7.  *
  8.  * initial version 27/iii/95 by Simon Tatham
  9.  */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <stddef.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include "nasm.h"
  16. #include "nasmlib.h"
  17. #include "parser.h"
  18. #include "float.h"
  19. static long reg_flags[] = {        /* sizes and special flags */
  20.     0, REG8, REG_AL, REG_AX, REG8, REG8, REG16, REG16, REG8, REG_CL,
  21.     REG_CREG, REG_CREG, REG_CREG, REG_CR4, REG_CS, REG_CX, REG8,
  22.     REG16, REG8, REG_DREG, REG_DREG, REG_DREG, REG_DREG, REG_DREG,
  23.     REG_DREG, REG_DESS, REG_DX, REG_EAX, REG32, REG32, REG_ECX,
  24.     REG32, REG32, REG_DESS, REG32, REG32, REG_FSGS, REG_FSGS,
  25.     MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG,
  26.     REG16, REG16, REG_DESS, FPU0, FPUREG, FPUREG, FPUREG, FPUREG,
  27.     FPUREG, FPUREG, FPUREG, REG_TREG, REG_TREG, REG_TREG, REG_TREG,
  28.     REG_TREG,
  29.     XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG
  30. };
  31. enum {        /* special tokens */
  32.     S_BYTE, S_DWORD, S_FAR, S_LONG, S_NEAR, S_NOSPLIT, S_QWORD,
  33.     S_SHORT, S_TO, S_TWORD, S_WORD
  34. };
  35. static int is_comma_next (void);
  36. static int i;
  37. static struct tokenval tokval;
  38. static efunc error;
  39. static struct ofmt *outfmt;  /* Structure of addresses of output routines */
  40. static loc_t *location;      /* Pointer to current line's segment,offset */
  41. void parser_global_info (struct ofmt *output, loc_t *locp) 
  42. {
  43.     outfmt = output;
  44.     location = locp;
  45. }
  46. insn *parse_line (int pass, char *buffer, insn *result,
  47.   efunc errfunc, evalfunc evaluate, ldfunc ldef) 
  48. {
  49.     int operand;
  50.     int critical;
  51.     struct eval_hints hints;
  52.     result->forw_ref = FALSE;
  53.     error = errfunc;
  54.     stdscan_reset();
  55.     stdscan_bufptr = buffer;
  56.     i = stdscan(NULL, &tokval);
  57.     result->label = NULL;        /* Assume no label */
  58.     result->eops = NULL;        /* must do this, whatever happens */
  59.     result->operands = 0;        /* must initialise this */
  60.     if (i==0) {        /* blank line - ignore */
  61. result->opcode = -1;        /* and no instruction either */
  62. return result;
  63.     }
  64.     if (i != TOKEN_ID && i != TOKEN_INSN && i != TOKEN_PREFIX &&
  65. (i!=TOKEN_REG || (REG_SREG & ~reg_flags[tokval.t_integer]))) {
  66. error (ERR_NONFATAL, "label or instruction expected"
  67.        " at start of line");
  68. result->opcode = -1;
  69. return result;
  70.     }
  71.     if (i == TOKEN_ID) {        /* there's a label here */
  72. result->label = tokval.t_charptr;
  73. i = stdscan(NULL, &tokval);
  74. if (i == ':') {        /* skip over the optional colon */
  75.     i = stdscan(NULL, &tokval);
  76. } else if (i == 0) {
  77.     error (ERR_WARNING|ERR_WARN_OL|ERR_PASS1,
  78.    "label alone on a line without a colon might be in error");
  79. }
  80. if (i != TOKEN_INSN || tokval.t_integer != I_EQU)
  81. {
  82.     /*
  83.      * FIXME: location->segment could be NO_SEG, in which case
  84.      * it is possible we should be passing 'abs_seg'. Look into this.
  85.      * Work out whether that is *really* what we should be doing.
  86.      * Generally fix things. I think this is right as it is, but
  87.      * am still not certain.
  88.      */
  89.     ldef (result->label, location->segment,
  90.   location->offset, NULL, TRUE, FALSE, outfmt, errfunc);
  91. }
  92.     }
  93.     if (i==0) {
  94. result->opcode = -1;        /* this line contains just a label */
  95. return result;
  96.     }
  97.     result->nprefix = 0;
  98.     result->times = 1L;
  99.     while (i == TOKEN_PREFIX ||
  100.    (i==TOKEN_REG && !(REG_SREG & ~reg_flags[tokval.t_integer]))) 
  101.     {
  102. /*
  103.  * Handle special case: the TIMES prefix.
  104.  */
  105. if (i == TOKEN_PREFIX && tokval.t_integer == P_TIMES) {
  106.     expr *value;
  107.     i = stdscan(NULL, &tokval);
  108.     value = evaluate (stdscan, NULL, &tokval, NULL, pass, error, NULL);
  109.     i = tokval.t_type;
  110.     if (!value) {        /* but, error in evaluator */
  111. result->opcode = -1;   /* unrecoverable parse error: */
  112. return result;        /* ignore this instruction */
  113.     }
  114.     if (!is_simple (value)) {
  115. error (ERR_NONFATAL,
  116.        "non-constant argument supplied to TIMES");
  117. result->times = 1L;
  118.     } else {
  119. result->times = value->value;
  120. if (value->value < 0) {
  121.     error(ERR_NONFATAL, "TIMES value %d is negative",
  122.   value->value);
  123.     result->times = 0;
  124. }
  125.     }
  126. } else {
  127.     if (result->nprefix == MAXPREFIX)
  128. error (ERR_NONFATAL,
  129.        "instruction has more than %d prefixes", MAXPREFIX);
  130.     else
  131. result->prefixes[result->nprefix++] = tokval.t_integer;
  132.     i = stdscan(NULL, &tokval);
  133. }
  134.     }
  135.     if (i != TOKEN_INSN) {
  136. if (result->nprefix > 0 && i == 0) {
  137.     /*
  138.      * Instruction prefixes are present, but no actual
  139.      * instruction. This is allowed: at this point we
  140.      * invent a notional instruction of RESB 0.
  141.      */
  142.     result->opcode = I_RESB;
  143.     result->operands = 1;
  144.     result->oprs[0].type = IMMEDIATE;
  145.     result->oprs[0].offset = 0L;
  146.     result->oprs[0].segment = result->oprs[0].wrt = NO_SEG;
  147.     return result;
  148. } else {
  149.     error (ERR_NONFATAL, "parser: instruction expected");
  150.     result->opcode = -1;
  151.     return result;
  152. }
  153.     }
  154.     result->opcode = tokval.t_integer;
  155.     result->condition = tokval.t_inttwo;
  156.     /*
  157.      * RESB, RESW and RESD cannot be satisfied with incorrectly
  158.      * evaluated operands, since the correct values _must_ be known
  159.      * on the first pass. Hence, even in pass one, we set the
  160.      * `critical' flag on calling evaluate(), so that it will bomb
  161.      * out on undefined symbols. Nasty, but there's nothing we can
  162.      * do about it.
  163.      *
  164.      * For the moment, EQU has the same difficulty, so we'll
  165.      * include that.
  166.      */
  167.     if (result->opcode == I_RESB ||
  168. result->opcode == I_RESW ||
  169. result->opcode == I_RESD ||
  170. result->opcode == I_RESQ ||
  171. result->opcode == I_REST ||
  172. result->opcode == I_EQU)
  173.     {
  174. critical = pass;
  175.     }
  176.     else
  177. critical = (pass==2 ? 2 : 0);
  178.     if (result->opcode == I_DB ||
  179. result->opcode == I_DW ||
  180. result->opcode == I_DD ||
  181. result->opcode == I_DQ ||
  182. result->opcode == I_DT ||
  183. result->opcode == I_INCBIN) 
  184.     {
  185. extop *eop, **tail = &result->eops, **fixptr;
  186. int oper_num = 0;
  187. result->eops_float = FALSE;
  188. /*
  189.  * Begin to read the DB/DW/DD/DQ/DT/INCBIN operands.
  190.  */
  191. while (1) {
  192.     i = stdscan(NULL, &tokval);
  193.     if (i == 0)
  194. break;
  195.     fixptr = tail;
  196.     eop = *tail = nasm_malloc(sizeof(extop));
  197.     tail = &eop->next;
  198.     eop->next = NULL;
  199.     eop->type = EOT_NOTHING;
  200.     oper_num++;
  201.     if (i == TOKEN_NUM && tokval.t_charptr && is_comma_next()) {
  202. eop->type = EOT_DB_STRING;
  203. eop->stringval = tokval.t_charptr;
  204. eop->stringlen = tokval.t_inttwo;
  205. i = stdscan(NULL, &tokval);       /* eat the comma */
  206. continue;
  207.     }
  208.     if ((i == TOKEN_FLOAT && is_comma_next()) || i == '-') {
  209. long sign = +1L;
  210. if (i == '-') {
  211.     char *save = stdscan_bufptr;
  212.     i = stdscan(NULL, &tokval);
  213.     sign = -1L;
  214.     if (i != TOKEN_FLOAT || !is_comma_next()) {
  215. stdscan_bufptr = save;
  216. i = tokval.t_type = '-';
  217.     }
  218. }
  219. if (i == TOKEN_FLOAT) {
  220.     eop->type = EOT_DB_STRING;
  221.     result->eops_float = TRUE;
  222.     if (result->opcode == I_DD)
  223. eop->stringlen = 4;
  224.     else if (result->opcode == I_DQ)
  225. eop->stringlen = 8;
  226.     else if (result->opcode == I_DT)
  227. eop->stringlen = 10;
  228.     else {
  229. error(ERR_NONFATAL, "floating-point constant"
  230.       " encountered in `D%c' instruction",
  231.       result->opcode == I_DW ? 'W' : 'B');
  232. /*
  233.  * fix suggested by Pedro Gimeno... original line
  234.  * was:
  235.  * eop->type = EOT_NOTHING;
  236.  */
  237. eop->stringlen = 0;
  238.     }
  239.     eop = nasm_realloc(eop, sizeof(extop)+eop->stringlen);
  240.     tail = &eop->next;
  241.     *fixptr = eop;
  242.     eop->stringval = (char *)eop + sizeof(extop);
  243.     if (eop->stringlen < 4 ||
  244. !float_const (tokval.t_charptr, sign,
  245.       (unsigned char *)eop->stringval,
  246.       eop->stringlen, error))
  247. eop->type = EOT_NOTHING;
  248.     i = stdscan(NULL, &tokval);       /* eat the comma */
  249.     continue;
  250. }
  251.     }
  252.     /* anything else */ 
  253.     {
  254. expr *value;
  255. value = evaluate (stdscan, NULL, &tokval, NULL,
  256.   critical, error, NULL);
  257. i = tokval.t_type;
  258. if (!value) {        /* error in evaluator */
  259.     result->opcode = -1;/* unrecoverable parse error: */
  260.     return result;     /* ignore this instruction */
  261. }
  262. if (is_unknown(value)) {
  263.     eop->type = EOT_DB_NUMBER;
  264.     eop->offset = 0;   /* doesn't matter what we put */
  265.     eop->segment = eop->wrt = NO_SEG;   /* likewise */
  266. } else if (is_reloc(value)) {
  267.     eop->type = EOT_DB_NUMBER;
  268.     eop->offset = reloc_value(value);
  269.     eop->segment = reloc_seg(value);
  270.     eop->wrt = reloc_wrt(value);
  271. } else {
  272.     error (ERR_NONFATAL,
  273.    "operand %d: expression is not simple"
  274.    " or relocatable", oper_num);
  275. }
  276.     }
  277.     /*
  278.      * We're about to call stdscan(), which will eat the
  279.      * comma that we're currently sitting on between
  280.      * arguments. However, we'd better check first that it
  281.      * _is_ a comma.
  282.      */
  283.     if (i == 0)        /* also could be EOL */
  284. break;
  285.     if (i != ',') {
  286. error (ERR_NONFATAL, "comma expected after operand %d",
  287.        oper_num);
  288. result->opcode = -1;/* unrecoverable parse error: */
  289. return result;     /* ignore this instruction */
  290.     }
  291. }
  292. if (result->opcode == I_INCBIN) {
  293.     /*
  294.      * Correct syntax for INCBIN is that there should be
  295.      * one string operand, followed by one or two numeric
  296.      * operands.
  297.      */
  298.     if (!result->eops || result->eops->type != EOT_DB_STRING)
  299. error (ERR_NONFATAL, "`incbin' expects a file name");
  300.     else if (result->eops->next &&
  301.      result->eops->next->type != EOT_DB_NUMBER)
  302. error (ERR_NONFATAL, "`incbin': second parameter is",
  303.        " non-numeric");
  304.     else if (result->eops->next && result->eops->next->next &&
  305.      result->eops->next->next->type != EOT_DB_NUMBER)
  306. error (ERR_NONFATAL, "`incbin': third parameter is",
  307.        " non-numeric");
  308.     else if (result->eops->next && result->eops->next->next &&
  309.      result->eops->next->next->next)
  310. error (ERR_NONFATAL, "`incbin': more than three parameters");
  311.     else
  312. return result;
  313.     /*
  314.      * If we reach here, one of the above errors happened.
  315.      * Throw the instruction away.
  316.      */
  317.     result->opcode = -1;
  318.     return result;
  319. } else /* DB ... */
  320.     if (oper_num == 0)
  321. error (ERR_WARNING|ERR_PASS1,
  322.        "no operand for data declaration");
  323.             else
  324.                 result->operands = oper_num;
  325. return result;
  326.     }
  327.     /* right. Now we begin to parse the operands. There may be up to three
  328.      * of these, separated by commas, and terminated by a zero token. */
  329.     for (operand = 0; operand < 3; operand++) {
  330. expr *value;        /* used most of the time */
  331. int mref;        /* is this going to be a memory ref? */
  332. int bracket;        /* is it a [] mref, or a & mref? */
  333. int setsize = 0;
  334. result->oprs[operand].addr_size = 0;/* have to zero this whatever */
  335. result->oprs[operand].eaflags = 0;   /* and this */
  336. result->oprs[operand].opflags = 0;
  337. i = stdscan(NULL, &tokval);
  338. if (i == 0) break;        /* end of operands: get out of here */
  339. result->oprs[operand].type = 0;   /* so far, no override */
  340. while (i == TOKEN_SPECIAL) {/* size specifiers */
  341.     switch ((int)tokval.t_integer) {
  342.       case S_BYTE:
  343. if (!setsize)  /* we want to use only the first */
  344.     result->oprs[operand].type |= BITS8;
  345. setsize = 1;
  346. break;
  347.       case S_WORD:
  348. if (!setsize)
  349.     result->oprs[operand].type |= BITS16;
  350. setsize = 1;
  351. break;
  352.       case S_DWORD:
  353.       case S_LONG:
  354. if (!setsize)
  355.     result->oprs[operand].type |= BITS32;
  356. setsize = 1;
  357. break;
  358.       case S_QWORD:
  359. if (!setsize)
  360.     result->oprs[operand].type |= BITS64;
  361. setsize = 1;
  362. break;
  363.       case S_TWORD:
  364. if (!setsize)
  365.     result->oprs[operand].type |= BITS80;
  366. setsize = 1;
  367. break;
  368.       case S_TO:
  369. result->oprs[operand].type |= TO;
  370. break;
  371.       case S_FAR:
  372. result->oprs[operand].type |= FAR;
  373. break;
  374.       case S_NEAR:
  375. result->oprs[operand].type |= NEAR;
  376. break;
  377.       case S_SHORT:
  378. result->oprs[operand].type |= SHORT;
  379. break;
  380.       default:
  381. error (ERR_NONFATAL, "invalid operand size specification");
  382.     }
  383.     i = stdscan(NULL, &tokval);
  384. }
  385. if (i == '[' || i == '&') {    /* memory reference */
  386.     mref = TRUE;
  387.     bracket = (i == '[');
  388.     i = stdscan(NULL, &tokval);     
  389.     if (i == TOKEN_SPECIAL) {  /* check for address size override */
  390. switch ((int)tokval.t_integer) {
  391.   case S_NOSPLIT:
  392.     result->oprs[operand].eaflags |= EAF_TIMESTWO;
  393.     break;
  394.   case S_BYTE:
  395.     result->oprs[operand].eaflags |= EAF_BYTEOFFS;
  396.     break;
  397.   case S_WORD:
  398.     result->oprs[operand].addr_size = 16;
  399.     result->oprs[operand].eaflags |= EAF_WORDOFFS;
  400.     break;
  401.   case S_DWORD:
  402.   case S_LONG:
  403.     result->oprs[operand].addr_size = 32;
  404.     result->oprs[operand].eaflags |= EAF_WORDOFFS;
  405.     break;
  406.   default:
  407.     error (ERR_NONFATAL, "invalid size specification in"
  408.    " effective address");
  409. }
  410. i = stdscan(NULL, &tokval);
  411.     }
  412. } else {        /* immediate operand, or register */
  413.     mref = FALSE;
  414.     bracket = FALSE;        /* placate optimisers */
  415. }
  416. value = evaluate (stdscan, NULL, &tokval,
  417.   &result->oprs[operand].opflags,
  418.   critical, error, &hints);
  419. i = tokval.t_type;
  420. if (result->oprs[operand].opflags & OPFLAG_FORWARD) {
  421.     result->forw_ref = TRUE;
  422. }
  423. if (!value) {        /* error in evaluator */
  424.     result->opcode = -1;       /* unrecoverable parse error: */
  425.     return result;        /* ignore this instruction */
  426. }
  427. if (i == ':' && mref) {        /* it was seg:offset */
  428.     /*
  429.      * Process the segment override.
  430.      */
  431.     if (value[1].type!=0 || value->value!=1 ||
  432. REG_SREG & ~reg_flags[value->type])
  433. error (ERR_NONFATAL, "invalid segment override");
  434.     else if (result->nprefix == MAXPREFIX)
  435. error (ERR_NONFATAL,
  436.        "instruction has more than %d prefixes",
  437.        MAXPREFIX);
  438.     else
  439. result->prefixes[result->nprefix++] = value->type;
  440.     i = stdscan(NULL, &tokval);        /* then skip the colon */
  441.     if (i == TOKEN_SPECIAL) {  /* another check for size override */
  442. switch ((int)tokval.t_integer) {
  443.   case S_WORD:
  444.     result->oprs[operand].addr_size = 16;
  445.     break;
  446.   case S_DWORD:
  447.   case S_LONG:
  448.     result->oprs[operand].addr_size = 32;
  449.     break;
  450.   default:
  451.     error (ERR_NONFATAL, "invalid size specification in"
  452.    " effective address");
  453. }
  454. i = stdscan(NULL, &tokval);
  455.     }
  456.     value = evaluate (stdscan, NULL, &tokval,
  457.       &result->oprs[operand].opflags,
  458.       critical, error, &hints);
  459.     i = tokval.t_type;
  460.     if (result->oprs[operand].opflags & OPFLAG_FORWARD) {
  461. result->forw_ref = TRUE;
  462.     }
  463.     /* and get the offset */
  464.     if (!value) {        /* but, error in evaluator */
  465. result->opcode = -1;   /* unrecoverable parse error: */
  466. return result;        /* ignore this instruction */
  467.     }
  468. }
  469. if (mref && bracket) {        /* find ] at the end */
  470.     if (i != ']') {
  471. error (ERR_NONFATAL, "parser: expecting ]");
  472. do {        /* error recovery again */
  473.     i = stdscan(NULL, &tokval);
  474. } while (i != 0 && i != ',');
  475.     } else        /* we got the required ] */
  476. i = stdscan(NULL, &tokval);
  477. } else {        /* immediate operand */
  478.     if (i != 0 && i != ',' && i != ':') {
  479. error (ERR_NONFATAL, "comma or end of line expected");
  480. do {        /* error recovery */
  481.     i = stdscan(NULL, &tokval);
  482. } while (i != 0 && i != ',');
  483.     } else if (i == ':') {
  484. result->oprs[operand].type |= COLON;
  485.     }
  486. }
  487. /* now convert the exprs returned from evaluate() into operand
  488.  * descriptions... */
  489. if (mref) {        /* it's a memory reference */
  490.     expr *e = value;
  491.     int b, i, s;        /* basereg, indexreg, scale */
  492.     long o;        /* offset */
  493.     b = i = -1, o = s = 0;
  494.     result->oprs[operand].hintbase = hints.base;
  495.     result->oprs[operand].hinttype = hints.type;
  496.     if (e->type <= EXPR_REG_END) {   /* this bit's a register */
  497. if (e->value == 1) /* in fact it can be basereg */
  498.     b = e->type;
  499. else        /* no, it has to be indexreg */
  500.     i = e->type, s = e->value;
  501. e++;
  502.     }
  503.     if (e->type && e->type <= EXPR_REG_END)   /* it's a 2nd register */
  504.     {
  505. if (b != -1)               /* If the first was the base, ... */
  506.     i = e->type, s = e->value;  /* second has to be indexreg */
  507. else if (e->value != 1)          /* If both want to be index */
  508. {
  509.     error(ERR_NONFATAL, "invalid effective address");
  510.     result->opcode = -1;
  511.     return result;
  512. else
  513.     b = e->type;
  514. e++;
  515.     }
  516.     if (e->type != 0) {        /* is there an offset? */
  517. if (e->type <= EXPR_REG_END)  /* in fact, is there an error? */
  518. {
  519.     error (ERR_NONFATAL, "invalid effective address");
  520.     result->opcode = -1;
  521.     return result;
  522. else 
  523. {
  524.     if (e->type == EXPR_UNKNOWN) {
  525. o = 0;                      /* doesn't matter what */
  526. result->oprs[operand].wrt = NO_SEG;     /* nor this */
  527. result->oprs[operand].segment = NO_SEG;  /* or this */
  528. while (e->type) e++;   /* go to the end of the line */
  529.     } 
  530.     else 
  531.     {
  532. if (e->type == EXPR_SIMPLE) {
  533.     o = e->value;
  534.     e++;
  535. }
  536. if (e->type == EXPR_WRT) {
  537.     result->oprs[operand].wrt = e->value;
  538.     e++;
  539. } else
  540.     result->oprs[operand].wrt = NO_SEG;
  541. /*
  542.  * Look for a segment base type.
  543.  */
  544. if (e->type && e->type < EXPR_SEGBASE) {
  545.     error (ERR_NONFATAL, "invalid effective address");
  546.     result->opcode = -1;
  547.     return result;
  548. }
  549. while (e->type && e->value == 0)
  550.     e++;
  551. if (e->type && e->value != 1) {
  552.     error (ERR_NONFATAL, "invalid effective address");
  553.     result->opcode = -1;
  554.     return result;
  555. }
  556. if (e->type) {
  557.     result->oprs[operand].segment =
  558. e->type - EXPR_SEGBASE;
  559.     e++;
  560. } else
  561.     result->oprs[operand].segment = NO_SEG;
  562. while (e->type && e->value == 0)
  563.     e++;
  564. if (e->type) {
  565.     error (ERR_NONFATAL, "invalid effective address");
  566.     result->opcode = -1;
  567.     return result;
  568. }
  569.     }
  570. }
  571.     } else {
  572. o = 0;
  573. result->oprs[operand].wrt = NO_SEG;
  574. result->oprs[operand].segment = NO_SEG;
  575.     }
  576.     if (e->type != 0) {    /* there'd better be nothing left! */
  577. error (ERR_NONFATAL, "invalid effective address");
  578. result->opcode = -1;
  579. return result;
  580.     }
  581.     result->oprs[operand].type |= MEMORY;
  582.     if (b==-1 && (i==-1 || s==0))
  583. result->oprs[operand].type |= MEM_OFFS;
  584.     result->oprs[operand].basereg = b;
  585.     result->oprs[operand].indexreg = i;
  586.     result->oprs[operand].scale = s;
  587.     result->oprs[operand].offset = o;
  588. else                       /* it's not a memory reference */
  589. {
  590.     if (is_just_unknown(value)) {     /* it's immediate but unknown */
  591. result->oprs[operand].type |= IMMEDIATE;
  592. result->oprs[operand].offset = 0;   /* don't care */
  593. result->oprs[operand].segment = NO_SEG; /* don't care again */
  594. result->oprs[operand].wrt = NO_SEG;/* still don't care */
  595.     } 
  596.     else if (is_reloc(value))         /* it's immediate */
  597.     {
  598. result->oprs[operand].type |= IMMEDIATE;
  599. result->oprs[operand].offset = reloc_value(value);
  600. result->oprs[operand].segment = reloc_seg(value);
  601. result->oprs[operand].wrt = reloc_wrt(value);
  602. if (is_simple(value) && reloc_value(value)==1)
  603.     result->oprs[operand].type |= UNITY;
  604.     } 
  605.     else        /* it's a register */
  606.     {
  607. int i;
  608. if (value->type>=EXPR_SIMPLE || value->value!=1) {
  609.     error (ERR_NONFATAL, "invalid operand type");
  610.     result->opcode = -1;
  611.     return result;
  612. }
  613. /*
  614.  * check that its only 1 register, not an expression...
  615.  */
  616. for (i = 1; value[i].type; i++)
  617.     if (value[i].value) {
  618. error (ERR_NONFATAL, "invalid operand type");
  619. result->opcode = -1;
  620. return result;
  621.     }
  622. /* clear overrides, except TO which applies to FPU regs */
  623. if (result->oprs[operand].type & ~TO) {
  624.     /*
  625.      * we want to produce a warning iff the specified size
  626.      * is different from the register size
  627.      */
  628.     i = result->oprs[operand].type & SIZE_MASK;
  629. }
  630. else
  631.     i = 0;
  632. result->oprs[operand].type &= TO;
  633. result->oprs[operand].type |= REGISTER;
  634. result->oprs[operand].type |= reg_flags[value->type];
  635. result->oprs[operand].basereg = value->type;
  636. if (i && (result->oprs[operand].type & SIZE_MASK) != i)
  637.     error (ERR_WARNING|ERR_PASS1,
  638.    "register size specification ignored");
  639.     }
  640. }
  641.     }
  642.     result->operands = operand;       /* set operand count */
  643.     while (operand<3)        /* clear remaining operands */
  644. result->oprs[operand++].type = 0;
  645.     /*
  646.      * Transform RESW, RESD, RESQ, REST into RESB.
  647.      */
  648.     switch (result->opcode) {
  649.       case I_RESW: result->opcode=I_RESB; result->oprs[0].offset*=2; break;
  650.       case I_RESD: result->opcode=I_RESB; result->oprs[0].offset*=4; break;
  651.       case I_RESQ: result->opcode=I_RESB; result->oprs[0].offset*=8; break;
  652.       case I_REST: result->opcode=I_RESB; result->oprs[0].offset*=10; break;
  653.     }
  654.     return result;
  655. }
  656. static int is_comma_next (void) 
  657. {
  658.     char *p;
  659.     int i;
  660.     struct tokenval tv;
  661.     p = stdscan_bufptr;
  662.     i = stdscan (NULL, &tv);
  663.     stdscan_bufptr = p;
  664.     return (i == ',' || i == ';' || !i);
  665. }
  666. void cleanup_insn (insn *i) 
  667. {
  668.     extop *e;
  669.     while (i->eops) {
  670. e = i->eops;
  671. i->eops = i->eops->next;
  672. nasm_free (e);
  673.     }
  674. }