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