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