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