More CHANGES that were never documented properly.
[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, pass0, 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         result->opcode == I_INCBIN)  /* fbk */
194     {
195         critical = pass0;
196     }
197     else
198         critical = (pass==2 ? 2 : 0);
199
200     if (result->opcode == I_DB ||
201         result->opcode == I_DW ||
202         result->opcode == I_DD ||
203         result->opcode == I_DQ ||
204         result->opcode == I_DT ||
205         result->opcode == I_INCBIN) 
206     {
207         extop *eop, **tail = &result->eops, **fixptr;
208         int oper_num = 0;
209
210         result->eops_float = FALSE;
211
212         /*
213          * Begin to read the DB/DW/DD/DQ/DT/INCBIN operands.
214          */
215         while (1) {
216             i = stdscan(NULL, &tokval);
217             if (i == 0)
218                 break;
219             fixptr = tail;
220             eop = *tail = nasm_malloc(sizeof(extop));
221             tail = &eop->next;
222             eop->next = NULL;
223             eop->type = EOT_NOTHING;
224             oper_num++;
225
226             if (i == TOKEN_NUM && tokval.t_charptr && is_comma_next()) {
227                 eop->type = EOT_DB_STRING;
228                 eop->stringval = tokval.t_charptr;
229                 eop->stringlen = tokval.t_inttwo;
230                 i = stdscan(NULL, &tokval);       /* eat the comma */
231                 continue;
232             }
233
234             if ((i == TOKEN_FLOAT && is_comma_next()) || i == '-') {
235                 long sign = +1L;
236
237                 if (i == '-') {
238                     char *save = stdscan_bufptr;
239                     i = stdscan(NULL, &tokval);
240                     sign = -1L;
241                     if (i != TOKEN_FLOAT || !is_comma_next()) {
242                         stdscan_bufptr = save;
243                         i = tokval.t_type = '-';
244                     }
245                 }
246
247                 if (i == TOKEN_FLOAT) {
248                     eop->type = EOT_DB_STRING;
249                     result->eops_float = TRUE;
250                     if (result->opcode == I_DD)
251                         eop->stringlen = 4;
252                     else if (result->opcode == I_DQ)
253                         eop->stringlen = 8;
254                     else if (result->opcode == I_DT)
255                         eop->stringlen = 10;
256                     else {
257                         error(ERR_NONFATAL, "floating-point constant"
258                               " encountered in `D%c' instruction",
259                               result->opcode == I_DW ? 'W' : 'B');
260                         /*
261                          * fix suggested by Pedro Gimeno... original line
262                          * was:
263                          * eop->type = EOT_NOTHING;
264                          */
265                         eop->stringlen = 0;
266                     }
267                     eop = nasm_realloc(eop, sizeof(extop)+eop->stringlen);
268                     tail = &eop->next;
269                     *fixptr = eop;
270                     eop->stringval = (char *)eop + sizeof(extop);
271                     if (eop->stringlen < 4 ||
272                         !float_const (tokval.t_charptr, sign,
273                                       (unsigned char *)eop->stringval,
274                                       eop->stringlen, error))
275                         eop->type = EOT_NOTHING;
276                     i = stdscan(NULL, &tokval);       /* eat the comma */
277                     continue;
278                 }
279             }
280
281             /* anything else */ 
282             {
283                 expr *value;
284                 value = evaluate (stdscan, NULL, &tokval, NULL,
285                                   critical, error, NULL);
286                 i = tokval.t_type;
287                 if (!value) {          /* error in evaluator */
288                     result->opcode = -1;/* unrecoverable parse error: */
289                     return result;     /* ignore this instruction */
290                 }
291                 if (is_unknown(value)) {
292                     eop->type = EOT_DB_NUMBER;
293                     eop->offset = 0;   /* doesn't matter what we put */
294                     eop->segment = eop->wrt = NO_SEG;   /* likewise */
295                 } else if (is_reloc(value)) {
296                     eop->type = EOT_DB_NUMBER;
297                     eop->offset = reloc_value(value);
298                     eop->segment = reloc_seg(value);
299                     eop->wrt = reloc_wrt(value);
300                 } else {
301                     error (ERR_NONFATAL,
302                            "operand %d: expression is not simple"
303                            " or relocatable", oper_num);
304                 }
305             }
306
307             /*
308              * We're about to call stdscan(), which will eat the
309              * comma that we're currently sitting on between
310              * arguments. However, we'd better check first that it
311              * _is_ a comma.
312              */
313             if (i == 0)                /* also could be EOL */
314                 break;
315             if (i != ',') {
316                 error (ERR_NONFATAL, "comma expected after operand %d",
317                        oper_num);
318                 result->opcode = -1;/* unrecoverable parse error: */
319                 return result;     /* ignore this instruction */
320             }
321         }
322
323         if (result->opcode == I_INCBIN) {
324             /*
325              * Correct syntax for INCBIN is that there should be
326              * one string operand, followed by one or two numeric
327              * operands.
328              */
329             if (!result->eops || result->eops->type != EOT_DB_STRING)
330                 error (ERR_NONFATAL, "`incbin' expects a file name");
331             else if (result->eops->next &&
332                      result->eops->next->type != EOT_DB_NUMBER)
333                 error (ERR_NONFATAL, "`incbin': second parameter is",
334                        " non-numeric");
335             else if (result->eops->next && result->eops->next->next &&
336                      result->eops->next->next->type != EOT_DB_NUMBER)
337                 error (ERR_NONFATAL, "`incbin': third parameter is",
338                        " non-numeric");
339             else if (result->eops->next && result->eops->next->next &&
340                      result->eops->next->next->next)
341                 error (ERR_NONFATAL, "`incbin': more than three parameters");
342             else
343                 return result;
344             /*
345              * If we reach here, one of the above errors happened.
346              * Throw the instruction away.
347              */
348             result->opcode = -1;
349             return result;
350         } else /* DB ... */
351             if (oper_num == 0)
352                 error (ERR_WARNING|ERR_PASS1,
353                        "no operand for data declaration");
354             else
355                 result->operands = oper_num;
356
357         return result;
358     }
359
360     /* right. Now we begin to parse the operands. There may be up to three
361      * of these, separated by commas, and terminated by a zero token. */
362
363     for (operand = 0; operand < 3; operand++) {
364         expr *value;                   /* used most of the time */
365         int mref;                      /* is this going to be a memory ref? */
366         int bracket;                   /* is it a [] mref, or a & mref? */
367         int setsize = 0;
368
369         result->oprs[operand].addr_size = 0;/* have to zero this whatever */
370         result->oprs[operand].eaflags = 0;   /* and this */
371         result->oprs[operand].opflags = 0;
372
373         i = stdscan(NULL, &tokval);
374         if (i == 0) break;             /* end of operands: get out of here */
375         result->oprs[operand].type = 0;   /* so far, no override */
376         while (i == TOKEN_SPECIAL)      {/* size specifiers */
377             switch ((int)tokval.t_integer) {
378               case S_BYTE:
379                 if (!setsize)            /* we want to use only the first */
380                     result->oprs[operand].type |= BITS8;
381                 setsize = 1;
382                 break;
383               case S_WORD:
384                 if (!setsize)
385                     result->oprs[operand].type |= BITS16;
386                 setsize = 1;
387                 break;
388               case S_DWORD:
389               case S_LONG:
390                 if (!setsize)
391                     result->oprs[operand].type |= BITS32;
392                 setsize = 1;
393                 break;
394               case S_QWORD:
395                 if (!setsize)
396                     result->oprs[operand].type |= BITS64;
397                 setsize = 1;
398                 break;
399               case S_TWORD:
400                 if (!setsize)
401                     result->oprs[operand].type |= BITS80;
402                 setsize = 1;
403                 break;
404               case S_TO:
405                 result->oprs[operand].type |= TO;
406                 break;
407               case S_FAR:
408                 result->oprs[operand].type |= FAR;
409                 break;
410               case S_NEAR:
411                 result->oprs[operand].type |= NEAR;
412                 break;
413               case S_SHORT:
414                 result->oprs[operand].type |= SHORT;
415                 break;
416               default:
417                 error (ERR_NONFATAL, "invalid operand size specification");
418             }
419             i = stdscan(NULL, &tokval);
420         }
421
422         if (i == '[' || i == '&') {    /* memory reference */
423             mref = TRUE;
424             bracket = (i == '[');
425             i = stdscan(NULL, &tokval);
426             if (i == TOKEN_SPECIAL) {  /* check for address size override */
427                 if (tasm_compatible_mode) {
428                   switch ((int)tokval.t_integer) {
429                     /* For TASM compatibility a size override inside the
430                      * brackets changes the size of the operand, not the
431                      * address type of the operand as it does in standard
432                      * NASM syntax. Hence:
433                      *
434                      *  mov     eax,[DWORD val]
435                      *
436                      * is valid syntax in TASM compatibility mode. Note that
437                      * you lose the ability to override the default address
438                      * type for the instruction, but we never use anything
439                      * but 32-bit flat model addressing in our code.
440                      */
441                     case S_BYTE:
442                       result->oprs[operand].type |= BITS8;
443                       break;
444                     case S_WORD:
445                       result->oprs[operand].type |= BITS16;
446                       break;
447                     case S_DWORD:
448                     case S_LONG:
449                       result->oprs[operand].type |= BITS32;
450                       break;
451                     case S_QWORD:
452                       result->oprs[operand].type |= BITS64;
453                       break;
454                     case S_TWORD:
455                       result->oprs[operand].type |= BITS80;
456                       break;
457                     default:
458                       error (ERR_NONFATAL, "invalid operand size specification");
459                   }
460                 } else {
461                   /* Standard NASM compatible syntax */
462                   switch ((int)tokval.t_integer) {
463                     case S_NOSPLIT:
464                       result->oprs[operand].eaflags |= EAF_TIMESTWO;
465                       break;
466                     case S_BYTE:
467                       result->oprs[operand].eaflags |= EAF_BYTEOFFS;
468                       break;
469                     case S_WORD:
470                       result->oprs[operand].addr_size = 16;
471                       result->oprs[operand].eaflags |= EAF_WORDOFFS;
472                       break;
473                     case S_DWORD:
474                     case S_LONG:
475                       result->oprs[operand].addr_size = 32;
476                       result->oprs[operand].eaflags |= EAF_WORDOFFS;
477                       break;
478                     default:
479                       error (ERR_NONFATAL, "invalid size specification in"
480                              " effective address");
481                   }
482                 }
483                 i = stdscan(NULL, &tokval);
484             }
485         } else {                       /* immediate operand, or register */
486             mref = FALSE;
487             bracket = FALSE;           /* placate optimisers */
488         }
489
490         value = evaluate (stdscan, NULL, &tokval,
491                           &result->oprs[operand].opflags,
492                           critical, error, &hints);
493         i = tokval.t_type;
494         if (result->oprs[operand].opflags & OPFLAG_FORWARD) {
495             result->forw_ref = TRUE;
496         }
497         if (!value) {                  /* error in evaluator */
498             result->opcode = -1;       /* unrecoverable parse error: */
499             return result;             /* ignore this instruction */
500         }
501         if (i == ':' && mref) {        /* it was seg:offset */
502             /*
503              * Process the segment override.
504              */
505             if (value[1].type!=0 || value->value!=1 ||
506                 REG_SREG & ~reg_flags[value->type])
507                 error (ERR_NONFATAL, "invalid segment override");
508             else if (result->nprefix == MAXPREFIX)
509                 error (ERR_NONFATAL,
510                        "instruction has more than %d prefixes",
511                        MAXPREFIX);
512             else
513                 result->prefixes[result->nprefix++] = value->type;
514
515             i = stdscan(NULL, &tokval);        /* then skip the colon */
516             if (i == TOKEN_SPECIAL) {  /* another check for size override */
517                 switch ((int)tokval.t_integer) {
518                   case S_WORD:
519                     result->oprs[operand].addr_size = 16;
520                     break;
521                   case S_DWORD:
522                   case S_LONG:
523                     result->oprs[operand].addr_size = 32;
524                     break;
525                   default:
526                     error (ERR_NONFATAL, "invalid size specification in"
527                            " effective address");
528                 }
529                 i = stdscan(NULL, &tokval);
530             }
531             value = evaluate (stdscan, NULL, &tokval,
532                               &result->oprs[operand].opflags,
533                               critical, error, &hints);
534             i = tokval.t_type;
535             if (result->oprs[operand].opflags & OPFLAG_FORWARD) {
536                 result->forw_ref = TRUE;
537             }
538             /* and get the offset */
539             if (!value) {              /* but, error in evaluator */
540                 result->opcode = -1;   /* unrecoverable parse error: */
541                 return result;         /* ignore this instruction */
542             }
543         }
544         if (mref && bracket) {         /* find ] at the end */
545             if (i != ']') {
546                 error (ERR_NONFATAL, "parser: expecting ]");
547                 do {                   /* error recovery again */
548                     i = stdscan(NULL, &tokval);
549                 } while (i != 0 && i != ',');
550             } else                     /* we got the required ] */
551                 i = stdscan(NULL, &tokval);
552         } else {                       /* immediate operand */
553             if (i != 0 && i != ',' && i != ':') {
554                 error (ERR_NONFATAL, "comma or end of line expected");
555                 do {                   /* error recovery */
556                     i = stdscan(NULL, &tokval);
557                 } while (i != 0 && i != ',');
558             } else if (i == ':') {
559                 result->oprs[operand].type |= COLON;
560             }
561         }
562
563         /* now convert the exprs returned from evaluate() into operand
564          * descriptions... */
565
566         if (mref) {                    /* it's a memory reference */
567             expr *e = value;
568             int b, i, s;               /* basereg, indexreg, scale */
569             long o;                    /* offset */
570
571             b = i = -1, o = s = 0;
572             result->oprs[operand].hintbase = hints.base;
573             result->oprs[operand].hinttype = hints.type;
574
575             if (e->type <= EXPR_REG_END) {   /* this bit's a register */
576                 if (e->value == 1) /* in fact it can be basereg */
577                     b = e->type;
578                 else           /* no, it has to be indexreg */
579                     i = e->type, s = e->value;
580                 e++;
581             }
582             if (e->type && e->type <= EXPR_REG_END)   /* it's a 2nd register */
583             {
584                 if (b != -1)               /* If the first was the base, ... */
585                     i = e->type, s = e->value;  /* second has to be indexreg */
586
587                 else if (e->value != 1)          /* If both want to be index */
588                 {
589                     error(ERR_NONFATAL, "beroset-p-592-invalid effective address");
590                     result->opcode = -1;
591                     return result;
592                 } 
593                 else
594                     b = e->type;
595                 e++;
596             }
597             if (e->type != 0) {        /* is there an offset? */
598                 if (e->type <= EXPR_REG_END)  /* in fact, is there an error? */
599                 {
600                     error (ERR_NONFATAL, "beroset-p-603-invalid effective address");
601                     result->opcode = -1;
602                     return result;
603                 } 
604                 else 
605                 {
606                     if (e->type == EXPR_UNKNOWN) {
607                         o = 0;                       /* doesn't matter what */
608                         result->oprs[operand].wrt = NO_SEG;     /* nor this */
609                         result->oprs[operand].segment = NO_SEG;  /* or this */
610                         while (e->type) e++;   /* go to the end of the line */
611                     } 
612                     else 
613                     {
614                         if (e->type == EXPR_SIMPLE) {
615                             o = e->value;
616                             e++;
617                         }
618                         if (e->type == EXPR_WRT) {
619                             result->oprs[operand].wrt = e->value;
620                             e++;
621                         } else
622                             result->oprs[operand].wrt = NO_SEG;
623                         /*
624                          * Look for a segment base type.
625                          */
626                         if (e->type && e->type < EXPR_SEGBASE) {
627                             error (ERR_NONFATAL, "beroset-p-630-invalid effective address");
628                             result->opcode = -1;
629                             return result;
630                         }
631                         while (e->type && e->value == 0)
632                             e++;
633                         if (e->type && e->value != 1) {
634                             error (ERR_NONFATAL, "beroset-p-637-invalid effective address");
635                             result->opcode = -1;
636                             return result;
637                         }
638                         if (e->type) {
639                             result->oprs[operand].segment =
640                                 e->type - EXPR_SEGBASE;
641                             e++;
642                         } else
643                             result->oprs[operand].segment = NO_SEG;
644                         while (e->type && e->value == 0)
645                             e++;
646                         if (e->type) {
647                             error (ERR_NONFATAL, "beroset-p-650-invalid effective address");
648                             result->opcode = -1;
649                             return result;
650                         }
651                     }
652                 }
653             } else {
654                 o = 0;
655                 result->oprs[operand].wrt = NO_SEG;
656                 result->oprs[operand].segment = NO_SEG;
657             }
658
659             if (e->type != 0) {    /* there'd better be nothing left! */
660                 error (ERR_NONFATAL, "beroset-p-663-invalid effective address");
661                 result->opcode = -1;
662                 return result;
663             }
664
665             result->oprs[operand].type |= MEMORY;
666             if (b==-1 && (i==-1 || s==0))
667                 result->oprs[operand].type |= MEM_OFFS;
668             result->oprs[operand].basereg = b;
669             result->oprs[operand].indexreg = i;
670             result->oprs[operand].scale = s;
671             result->oprs[operand].offset = o;
672         } 
673         else                                  /* it's not a memory reference */
674         {
675             if (is_just_unknown(value)) {     /* it's immediate but unknown */
676                 result->oprs[operand].type |= IMMEDIATE;
677                 result->oprs[operand].offset = 0;   /* don't care */
678                 result->oprs[operand].segment = NO_SEG; /* don't care again */
679                 result->oprs[operand].wrt = NO_SEG;/* still don't care */
680             } 
681             else if (is_reloc(value))         /* it's immediate */
682             {
683                 result->oprs[operand].type |= IMMEDIATE;
684                 result->oprs[operand].offset = reloc_value(value);
685                 result->oprs[operand].segment = reloc_seg(value);
686                 result->oprs[operand].wrt = reloc_wrt(value);
687                 if (is_simple(value)) {
688                     if (reloc_value(value)==1)
689                         result->oprs[operand].type |= UNITY;
690                     if (optimizing>=0) {
691                         if (reloc_value(value) >= -128 &&
692                                  reloc_value(value) <= 127)
693                             result->oprs[operand].type |= SBYTE;
694                     }
695                 }
696             } 
697             else               /* it's a register */
698             {
699                 int i;
700
701                 if (value->type>=EXPR_SIMPLE || value->value!=1) {
702                     error (ERR_NONFATAL, "invalid operand type");
703                     result->opcode = -1;
704                     return result;
705                 }
706
707                 /*
708                  * check that its only 1 register, not an expression...
709                  */
710                 for (i = 1; value[i].type; i++)
711                     if (value[i].value) {
712                         error (ERR_NONFATAL, "invalid operand type");
713                         result->opcode = -1;
714                         return result;
715                     }
716
717                 /* clear overrides, except TO which applies to FPU regs */
718                 if (result->oprs[operand].type & ~TO) {
719                     /*
720                      * we want to produce a warning iff the specified size
721                      * is different from the register size
722                      */
723                     i = result->oprs[operand].type & SIZE_MASK;
724                 }
725                 else
726                     i = 0;
727
728                 result->oprs[operand].type &= TO;
729                 result->oprs[operand].type |= REGISTER;
730                 result->oprs[operand].type |= reg_flags[value->type];
731                 result->oprs[operand].basereg = value->type;
732
733                 if (i && (result->oprs[operand].type & SIZE_MASK) != i)
734                     error (ERR_WARNING|ERR_PASS1,
735                            "register size specification ignored");
736             }
737         }
738     }
739
740     result->operands = operand;       /* set operand count */
741
742     while (operand<3)                  /* clear remaining operands */
743         result->oprs[operand++].type = 0;
744
745     /*
746      * Transform RESW, RESD, RESQ, REST into RESB.
747      */
748     switch (result->opcode) {
749       case I_RESW: result->opcode=I_RESB; result->oprs[0].offset*=2; break;
750       case I_RESD: result->opcode=I_RESB; result->oprs[0].offset*=4; break;
751       case I_RESQ: result->opcode=I_RESB; result->oprs[0].offset*=8; break;
752       case I_REST: result->opcode=I_RESB; result->oprs[0].offset*=10; break;
753     }
754
755     return result;
756 }
757
758 static int is_comma_next (void) 
759 {
760     char *p;
761     int i;
762     struct tokenval tv;
763
764     p = stdscan_bufptr;
765     i = stdscan (NULL, &tv);
766     stdscan_bufptr = p;
767     return (i == ',' || i == ';' || !i);
768 }
769
770 void cleanup_insn (insn *i) 
771 {
772     extop *e;
773
774     while (i->eops) {
775         e = i->eops;
776         i->eops = i->eops->next;
777         nasm_free (e);
778     }
779 }