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