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