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