1 /****************************************************************************
2 *
3 *                            Open Watcom Project
4 *
5 *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6 *
7 *  ========================================================================
8 *
9 *    This file contains Original Code and/or Modifications of Original
10 *    Code as defined in and that are subject to the Sybase Open Watcom
11 *    Public License version 1.0 (the 'License'). You may not use this file
12 *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13 *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14 *    provided with the Original Code and Modifications, and is also
15 *    available at www.sybase.com/developer/opensource.
16 *
17 *    The Original Code and all software distributed under the License are
18 *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19 *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20 *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22 *    NON-INFRINGEMENT. Please see the License for the specific language
23 *    governing rights and limitations under the License.
24 *
25 *  ========================================================================
26 *
27 * Description:  Parser
28 *
29 ****************************************************************************/
30 
31 #include <ctype.h>
32 #include <limits.h>
33 
34 #include "globals.h"
35 #include "memalloc.h"
36 #include "parser.h"
37 #include "preproc.h"
38 #include "reswords.h"
39 #include "codegen.h"
40 #include "expreval.h"
41 #include "fixup.h"
42 #include "types.h"
43 #include "label.h"
44 #include "segment.h"
45 #include "assume.h"
46 #include "proc.h"
47 #include "myassert.h"
48 #include "input.h"
49 #include "tokenize.h"
50 #include "listing.h"
51 #include "data.h"
52 #include "fastpass.h"
53 #include "omf.h"
54 #include "omfspec.h"
55 #include "condasm.h"
56 #include "extern.h"
57 #include "atofloat.h"
58 
59 #define ADDRSIZE( s, x ) ( ( ( x ) ^ ( s ) ) ? TRUE : FALSE )
60 #define IS_ADDR32( s )  ( s->Ofssize ? ( s->prefix.adrsiz == FALSE ) : ( s->prefix.adrsiz == TRUE ))
61 
62 #define OPSIZE32( s ) ( ( s->Ofssize ) ? FALSE : TRUE )
63 #define OPSIZE16( s ) ( ( s->Ofssize ) ? TRUE : FALSE )
64 
65 #define InWordRange( val ) ( (val > 65535 || val < -65535) ? FALSE : TRUE )
66 
67 extern ret_code (* const directive_tab[])( int, struct asm_tok[] );
68 
69 /* parsing of branch instructions with imm operand is found in branch.c */
70 extern ret_code         process_branch( struct code_info *, unsigned, const struct expr * );
71 
72 extern enum proc_status ProcStatus;
73 //extern struct asym   symPC; /* '$' symbol */
74 extern const int_64     maxintvalues[];
75 extern const int_64     minintvalues[];
76 extern const struct opnd_class opnd_clstab[];
77 #if AVXSUPP
78 extern const uint_8     vex_flags[];
79 #endif
80 extern int_8           Frame_Type;     /* Frame of current fixup */
81 extern uint_16         Frame_Datum;    /* Frame datum of current fixup */
82 
83 struct asym             *SegOverride;  /* set by SetSegOverride() */
84 static enum assume_segreg  LastRegOverride;/* needed for CMPS */
85 
86 /* linked lists of:     index
87  *--------------------------------
88  * - undefined symbols  TAB_UNDEF
89  * - externals          TAB_EXT
90  * - segments           TAB_SEG
91  * - groups             TAB_GRP
92  * - procedures         TAB_PROC
93  * - aliases            TAB_ALIAS
94  */
95 struct symbol_queue SymTables[TAB_LAST];
96 
97 /* add item to linked list of symbols */
98 
sym_add_table(struct symbol_queue * queue,struct dsym * item)99 void sym_add_table( struct symbol_queue *queue, struct dsym *item )
100 /*****************************************************************/
101 {
102 #ifdef DEBUG_OUT
103     if ( queue == &SymTables[TAB_UNDEF] )
104         item->sym.fwdref = TRUE;
105 #endif
106     if( queue->head == NULL ) {
107         queue->head = queue->tail = item;
108         item->next = item->prev = NULL;
109     } else {
110         item->prev = queue->tail;
111         queue->tail->next = item;
112         queue->tail = item;
113         item->next = NULL;
114     }
115 }
116 
117 /* remove an item from a symbol queue.
118  * this is called only for TAB_UNDEF and TAB_EXT,
119  * segments, groups, procs or aliases never change their state.
120  */
sym_remove_table(struct symbol_queue * queue,struct dsym * item)121 void sym_remove_table( struct symbol_queue *queue, struct dsym *item )
122 /********************************************************************/
123 {
124     /* unlink the node */
125     if( item->prev )
126         item->prev->next = item->next;
127     if( item->next )
128         item->next->prev = item->prev;
129 
130     //if ( dir->next == NULL )
131     //    dir->next = dir->prev;
132 
133     if ( queue->head == item )
134         queue->head = item->next;
135     if ( queue->tail == item )
136         queue->tail = item->prev;
137 
138     item->next = NULL;
139     item->prev = NULL;
140 }
141 
sym_ext2int(struct asym * sym)142 void sym_ext2int( struct asym *sym )
143 /**********************************/
144 /* Change symbol state from SYM_EXTERNAL to SYM_INTERNAL.
145  * called by:
146  * - CreateConstant()             EXTERNDEF name:ABS           -> constant
147  * - CreateAssemblyTimeVariable() EXTERNDEF name:ABS           -> assembly-time variable
148  * - CreateLabel()                EXTERNDEF name:NEAR|FAR|PROC -> code label
149  * - data_dir()                   EXTERNDEF name:typed memref  -> data label
150  * - ProcDir()           PROTO or EXTERNDEF name:NEAR|FAR|PROC -> PROC
151  */
152 {
153     /* v2.07: GlobalQueue has been removed */
154     if ( sym->isproc == FALSE && sym->ispublic == FALSE ) {
155         sym->ispublic = TRUE;
156         AddPublicData( sym );
157     }
158     sym_remove_table( &SymTables[TAB_EXT], (struct dsym *)sym );
159     if ( sym->isproc == FALSE ) /* v2.01: don't clear flags for PROTO */
160         sym->first_size = 0;
161     sym->state = SYM_INTERNAL;
162 }
163 
GetLangType(int * i,struct asm_tok tokenarray[],enum lang_type * plang)164 ret_code GetLangType( int *i, struct asm_tok tokenarray[], enum lang_type *plang )
165 /********************************************************************************/
166 {
167     if( tokenarray[*i].token == T_RES_ID ) {
168 #if 1 /* v2.03: simplified */
169         if ( tokenarray[(*i)].tokval >= T_C &&
170             tokenarray[(*i)].tokval <= T_FASTCALL ) {
171             *plang = tokenarray[(*i)].bytval;
172             (*i)++;
173             return( NOT_ERROR );
174         }
175 #else
176         switch( tokenarray[(*i)].tokval ) {
177         case T_C:        *plang = LANG_C;        break;
178         case T_SYSCALL:  *plang = LANG_SYSCALL;  break;
179         case T_STDCALL:  *plang = LANG_STDCALL;  break;
180         case T_PASCAL:   *plang = LANG_PASCAL;   break;
181         case T_FORTRAN:  *plang = LANG_FORTRAN;  break;
182         case T_BASIC:    *plang = LANG_BASIC;    break;
183         case T_FASTCALL: *plang = LANG_FASTCALL; break;
184         default:
185             return( ERROR );
186         }
187         (*i)++;
188         return( NOT_ERROR );
189 #endif
190     }
191     return( ERROR );
192 }
193 
194 /* get size of a register
195  * v2.06: rewritten, since the sflags field
196  * does now contain size for GPR, STx, MMX, XMM regs.
197  */
198 
SizeFromRegister(int registertoken)199 int SizeFromRegister( int registertoken )
200 /***************************************/
201 {
202     unsigned flags;
203     flags = GetSflagsSp( registertoken ) & SFR_SIZMSK;
204 
205     if ( flags )
206         return( flags );
207 
208     flags = GetValueSp( registertoken );
209     if ( flags & OP_SR )
210         return( CurrWordSize );
211 
212     /* CRx, DRx, TRx remaining */
213 #if AMD64_SUPPORT
214     return( ModuleInfo.Ofssize == USE64 ? 8 : 4 );
215 #else
216     return( 4 );
217 #endif
218 }
219 
220 /* get size from memory type */
221 
222 /* MT_PROC memtype is set ONLY in typedefs ( state=SYM_TYPE, typekind=TYPE_TYPEDEF)
223  * and makes the type a PROTOTYPE. Due to technical (obsolete?) restrictions the
224  * prototype data is stored in another symbol and is referenced in the typedef's
225  * target_type member.
226  */
227 
SizeFromMemtype(enum memtype mem_type,int Ofssize,struct asym * type)228 int SizeFromMemtype( enum memtype mem_type, int Ofssize, struct asym *type )
229 /**************************************************************************/
230 {
231     if ( ( mem_type & MT_SPECIAL) == 0 )
232         return ( (mem_type & MT_SIZE_MASK) + 1 );
233 
234     if ( Ofssize == USE_EMPTY )
235         Ofssize = ModuleInfo.Ofssize;
236 
237     switch ( mem_type ) {
238     case MT_NEAR:
239         DebugMsg1(("SizeFromMemtype( MT_NEAR, Ofssize=%u )=%u\n", Ofssize, 2 << Ofssize ));
240         return ( 2 << Ofssize );
241     case MT_FAR:
242         DebugMsg1(("SizeFromMemtype( MT_FAR, Ofssize=%u )=%u\n", Ofssize, ( 2 << Ofssize ) + 2 ));
243         return ( ( 2 << Ofssize ) + 2 );
244     case MT_PROC:
245         DebugMsg1(("SizeFromMemtype( MT_PROC, Ofssize=%u, type=%s )=%u\n", Ofssize, type->name, ( 2 << Ofssize ) + ( type->isfar ? 2 : 0 ) ));
246         /* v2.09: use type->isfar setting */
247         //return( ( 2 << Ofssize ) + ( ( SIZE_CODEPTR & ( 1 << ModuleInfo.model ) ) ? 2 : 0 ) );
248         return( ( 2 << Ofssize ) + ( type->isfar ? 2 : 0 ) );
249     case MT_PTR:
250         DebugMsg1(("SizeFromMemtype( MT_PTR, Ofssize=%u )=%u\n", Ofssize, ( 2 << Ofssize ) + ( ( SIZE_DATAPTR & ( 1 << ModuleInfo.model ) ) ? 2 : 0 ) ));
251         return( ( 2 << Ofssize ) + ( ( SIZE_DATAPTR & ( 1 << ModuleInfo.model ) ) ? 2 : 0 ) );
252     case MT_TYPE:
253         if ( type )
254             return( type->total_size );
255     default:
256         DebugMsg1(("SizeFromMemtype( memtype=%Xh, Ofssize=%u )=%u\n", mem_type, Ofssize, 0 ));
257         return( 0 );
258     }
259 }
260 
261 /* get memory type from size */
262 
MemtypeFromSize(int size,enum memtype * ptype)263 ret_code MemtypeFromSize( int size, enum memtype *ptype )
264 /*******************************************************/
265 {
266     int i;
267     for ( i = T_BYTE; SpecialTable[i].type == RWT_STYPE; i++ ) {
268         if( ( SpecialTable[i].bytval & MT_SPECIAL ) == 0 ) {
269             /* the size is encoded 0-based in field mem_type */
270             if( ( ( SpecialTable[i].bytval & MT_SIZE_MASK) + 1 ) == size ) {
271                 *ptype = SpecialTable[i].bytval;
272                 return( NOT_ERROR );
273             }
274         }
275     }
276     return( ERROR );
277 }
278 
OperandSize(enum operand_type opnd,const struct code_info * CodeInfo)279 int OperandSize( enum operand_type opnd, const struct code_info *CodeInfo )
280 /*************************************************************************/
281 {
282     /* v2.0: OP_M8_R8 and OP_M16_R16 have the DFT bit set! */
283     if( opnd == OP_NONE ) {
284         return( 0 );
285     } else if( opnd == OP_M ) {
286         return( SizeFromMemtype( CodeInfo->mem_type, CodeInfo->Ofssize, NULL ) );
287     } else if( opnd & ( OP_R8 | OP_M08 | OP_I8 ) ) {
288         return( 1 );
289     } else if( opnd & ( OP_R16 | OP_M16 | OP_I16 | OP_SR ) ) {
290         return( 2 );
291     } else if( opnd & ( OP_R32 | OP_M32 | OP_I32 ) ) {
292         return( 4 );
293 #if AMD64_SUPPORT
294     } else if( opnd & ( OP_R64 | OP_M64 | OP_MMX | OP_I64 ) ) {
295 #else
296     } else if( opnd & ( OP_M64 | OP_MMX ) ) {
297 #endif
298         return( 8 );
299 //    } else if( opnd & ( OP_I | OP_I48 ) ) {
300     } else if( opnd & ( OP_I48 | OP_M48 ) ) {
301         return( 6 );
302     } else if( opnd & ( OP_STI | OP_M80 ) ) {
303         return( 10 );
304     } else if( opnd & ( OP_XMM | OP_M128 ) ) {
305         return( 16 );
306 #if AVXSUPP
307     } else if( opnd & ( OP_YMM | OP_M256 ) ) {
308         return( 32 );
309 #endif
310     } else if( opnd & OP_RSPEC ) {
311 #if AMD64_SUPPORT
312         return( ( CodeInfo->Ofssize == USE64 ) ? 8 : 4 );
313 #else
314         return( 4 );
315 #endif
316     }
317     DebugMsg1(("OperandSize: unhandled operand type %Xh!!!\n", opnd ));
318     return( 0 );
319 }
320 
comp_mem16(int reg1,int reg2)321 static int comp_mem16( int reg1, int reg2 )
322 /*****************************************/
323 /*
324 - compare and return the r/m field encoding of 16-bit address mode;
325 - call by set_rm_sib() only;
326 */
327 {
328     switch( reg1 ) {
329     case T_BX:
330         switch( reg2 ) {
331         case T_SI: return( RM_BX_SI ); /* 00 */
332         case T_DI: return( RM_BX_DI ); /* 01 */
333         }
334         break;
335     case T_BP:
336         switch( reg2 ) {
337         case T_SI: return( RM_BP_SI ); /* 02 */
338         case T_DI: return( RM_BP_DI ); /* 03 */
339         }
340         break;
341     default:
342         return( EmitError( MULTIPLE_INDEX_REGISTERS_NOT_ALLOWED ) );
343     }
344     return( EmitError( MULTIPLE_BASE_REGISTERS_NOT_ALLOWED ) );
345 }
346 
check_assume(struct code_info * CodeInfo,const struct asym * sym,enum assume_segreg default_reg)347 static void check_assume( struct code_info *CodeInfo, const struct asym *sym, enum assume_segreg default_reg )
348 /************************************************************************************************************/
349 /* Check if an assumed segment register is found, and
350  * set CodeInfo->RegOverride if necessary.
351  * called by seg_override().
352  * at least either sym or SegOverride is != NULL.
353  */
354 {
355     enum assume_segreg     reg;
356     struct asym            *assume;
357 
358     if( sym && sym->state == SYM_UNDEFINED )
359         return;
360 
361     reg = GetAssume( SegOverride, sym, default_reg, &assume );
362     /* set global vars Frame and Frame_Datum */
363     DebugMsg1(("check_assume(%s): calling SetFixupFrame(%s, FALSE)\n", sym ? sym->name : "NULL", assume ? assume->name : "NULL" ));
364     SetFixupFrame( assume, FALSE );
365 
366     if( reg == ASSUME_NOTHING ) {
367         if ( sym ) {
368             //if( sym->state != SYM_EXTERNAL && sym->state != SYM_STACK ) {
369             /* v1.95: condition changed. Now there's an error msg only if
370              * the symbol has an explicite segment.
371              */
372             if( sym->segment != NULL ) {
373                 DebugMsg1(("check_assume: no segment register available to access label %s\n", sym->name ));
374                 EmitErr( CANNOT_ACCESS_LABEL_THROUGH_SEGMENT_REGISTERS, sym->name );
375             } else
376                 CodeInfo->prefix.RegOverride = default_reg;
377         } else {
378             DebugMsg1(("check_assume: no segment register available to access seg-label %s\n", SegOverride->name ));
379             EmitErr( CANNOT_ACCESS_LABEL_THROUGH_SEGMENT_REGISTERS, SegOverride->name );
380         }
381     } else if( default_reg != EMPTY ) {
382         CodeInfo->prefix.RegOverride = reg;
383     }
384 }
385 
seg_override(struct code_info * CodeInfo,int seg_reg,const struct asym * sym,bool direct)386 static void seg_override( struct code_info *CodeInfo, int seg_reg, const struct asym *sym, bool direct )
387 /******************************************************************************************************/
388 /*
389  * called by set_rm_sib(). determine if segment override is necessary
390  * with the current address mode;
391  * - seg_reg: register index (T_DS, T_BP, T_EBP, T_BX, ... )
392  */
393 {
394     enum assume_segreg  default_seg;
395     struct asym         *assume;
396 
397     /* don't touch segment overrides for string instructions */
398     //if ( InstrTable[optable_idx[CodeInfo->token]].allowed_prefix == AP_REP ||
399     //     InstrTable[optable_idx[CodeInfo->token]].allowed_prefix == AP_REPxx )
400     if ( CodeInfo->pinstr->allowed_prefix == AP_REP ||
401         CodeInfo->pinstr->allowed_prefix == AP_REPxx )
402             return;
403 
404     if( CodeInfo->token == T_LEA ) {
405         CodeInfo->prefix.RegOverride = ASSUME_NOTHING; /* skip segment override */
406         SetFixupFrame( sym, FALSE );
407         return;
408     }
409 
410     switch( seg_reg ) {
411     //case T_SS: /* doesn't happen */
412     case T_BP:
413     case T_EBP:
414     case T_ESP:
415         /* todo: check why cases T_RBP/T_RSP aren't needed! */
416         default_seg = ASSUME_SS;
417         break;
418     default:
419         default_seg = ASSUME_DS;
420     }
421 
422     if( CodeInfo->prefix.RegOverride != EMPTY ) {
423         assume = GetOverrideAssume( CodeInfo->prefix.RegOverride );
424         /* assume now holds assumed SEG/GRP symbol */
425         if ( sym ) {
426             DebugMsg1(("seg_override: sym=%s, assume=%s, calling SetFixupFrame()\n",
427                        sym->name, assume ? assume->name : "NULL" ));
428             SetFixupFrame( assume ? assume : sym, FALSE );
429         } else if ( direct ) {
430             /* no label attached (DS:[0]). No fixup is to be created! */
431             if ( assume ) {
432                 DebugMsg1(("seg_override, direct addressing: prefix.adrsiz will be set, assume=%s[Ofssize=%u] CI->Ofssize=%u\n",
433                     assume->name, GetSymOfssize( assume ), CodeInfo->Ofssize ));
434                 /* v2.12: args for ADDRSIZE must be USE16 and "> USE16". The old way
435                  * caused error 'magnitude of offset exceeds 16 bit' to be displayed if
436                  * module contained USE32 & USE64 segments. Todo: Most likely to be adjusted
437                  * in the other ADDRSIZE() locations as well!
438                  */
439                 //CodeInfo->prefix.adrsiz = ADDRSIZE( CodeInfo->Ofssize, GetSymOfssize( assume ) );
440                 CodeInfo->prefix.adrsiz = ADDRSIZE( CodeInfo->Ofssize > USE16, GetSymOfssize( assume ) > USE16 );
441                 DebugMsg1(("seg_override: new CI->prefix.adrsiz=%u\n", CodeInfo->prefix.adrsiz ));
442             } else {
443                 /* v2.01: if -Zm, then use current CS offset size.
444                  * This isn't how Masm v6 does it, but it matches Masm v5.
445                  */
446                 DebugMsg1(("seg_override, direct addressing: prefix.adrsiz will be set, no assume, CI->Ofssize=%u, MI.defOfssize=%u (MI.Ofssize=%u)\n",
447                     CodeInfo->Ofssize, ModuleInfo.defOfssize, ModuleInfo.Ofssize ));
448                 if ( ModuleInfo.m510 )
449                     CodeInfo->prefix.adrsiz = ADDRSIZE( CodeInfo->Ofssize, ModuleInfo.Ofssize );
450                 else {
451                     /* v2.12: see comment above */
452                     CodeInfo->prefix.adrsiz = ADDRSIZE( CodeInfo->Ofssize > USE16, ModuleInfo.defOfssize > USE16 );
453                     //CodeInfo->prefix.adrsiz = ADDRSIZE( CodeInfo->Ofssize, ModuleInfo.defOfssize );
454                 }
455             }
456         }
457     } else {
458         if ( sym || SegOverride )
459             check_assume( CodeInfo, sym, default_seg );
460         if ( sym == NULL && SegOverride ) {
461             CodeInfo->prefix.adrsiz = ADDRSIZE( CodeInfo->Ofssize, GetSymOfssize( SegOverride ) );
462         }
463     }
464 
465     if( CodeInfo->prefix.RegOverride == default_seg ) {
466         CodeInfo->prefix.RegOverride = ASSUME_NOTHING; /* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
467     }
468 }
469 
470 /* prepare fixup creation
471  * called by:
472  * - idata_fixup()
473  * - process_branch() in branch.c
474  * - data_item() in data.c
475  */
476 
set_frame(const struct asym * sym)477 void set_frame( const struct asym *sym )
478 /**************************************/
479 {
480     SetFixupFrame( SegOverride ? SegOverride : sym, FALSE );
481 }
482 
483 /* set fixup frame if OPTION OFFSET:SEGMENT is set and
484  * OFFSET or SEG operator was used.
485  * called by:
486  * - idata_fixup()
487  * - data_item()
488  */
set_frame2(const struct asym * sym)489 void set_frame2( const struct asym *sym )
490 /***************************************/
491 {
492     SetFixupFrame( SegOverride ? SegOverride : sym, TRUE );
493 }
494 
set_rm_sib(struct code_info * CodeInfo,unsigned CurrOpnd,char ss,int index,int base,const struct asym * sym)495 static ret_code set_rm_sib( struct code_info *CodeInfo, unsigned CurrOpnd, char ss, int index, int base, const struct asym *sym )
496 /*******************************************************************************************************************************/
497 /*
498  * encode ModRM and SIB byte for memory addressing.
499  * called by memory_operand().
500  * in:  ss = scale factor (00=1,40=2,80=4,C0=8)
501  *   index = index register (T_DI, T_ESI, ...)
502  *    base = base register (T_EBP, ... )
503  *     sym = symbol (direct addressing, displacement)
504  * out: CodeInfo->rm_byte, CodeInfo->sib, CodeInfo->prefix.rex
505 */
506 {
507     int                 temp;
508     unsigned char       mod_field;
509     unsigned char       rm_field;
510     unsigned char       base_reg;
511     unsigned char       idx_reg;
512 #if AMD64_SUPPORT
513     unsigned char       bit3_base;
514     unsigned char       bit3_idx;
515     unsigned char       rex;
516 #endif
517 
518     DebugMsg1(("set_rm_sib(scale=%u, index=%d, base=%d, sym=%s) enter [CI.adrsiz=%u]\n", 1 << (ss >> 6), index, base, sym ? sym->name : "NULL", CodeInfo->prefix.adrsiz ));
519 
520     /* clear mod */
521     rm_field = 0;
522 #if AMD64_SUPPORT
523     bit3_base = 0;
524     bit3_idx = 0;
525     rex = 0;
526 #endif
527     if( CodeInfo->opnd[CurrOpnd].InsFixup != NULL ) { /* symbolic displacement given? */
528         mod_field = MOD_10;
529     } else if( CodeInfo->opnd[CurrOpnd].data32l == 0 ) { /* no displacement (or 0) */
530         mod_field = MOD_00;
531     } else if( ( CodeInfo->opnd[CurrOpnd].data32l > SCHAR_MAX )
532        || ( CodeInfo->opnd[CurrOpnd].data32l < SCHAR_MIN ) ) {
533         mod_field = MOD_10; /* full size displacement */
534     } else {
535         mod_field = MOD_01; /* byte size displacement */
536     }
537 
538     if( ( index == EMPTY ) && ( base == EMPTY ) ) {
539         /* direct memory.
540          * clear the rightmost 3 bits
541          */
542         CodeInfo->isdirect = TRUE;
543         mod_field = MOD_00;
544 
545         /* default is DS:[], DS: segment override is not needed */
546         seg_override( CodeInfo, T_DS, sym, TRUE );
547 
548         DebugMsg1(( "set_rm_sib: direct addressing, CI.Ofssize=%u / adrsize=%u / data=%" I32_SPEC "X\n",
549                    CodeInfo->Ofssize, CodeInfo->prefix.adrsiz, CodeInfo->opnd[CurrOpnd].data32l ));
550         //if( !IS_ADDR32( CodeInfo ) ) {
551         if( ( CodeInfo->Ofssize == USE16 && CodeInfo->prefix.adrsiz == 0 ) ||
552             ( CodeInfo->Ofssize == USE32 && CodeInfo->prefix.adrsiz == 1 )) {
553             if( !InWordRange( CodeInfo->opnd[CurrOpnd].data32l ) ) {
554                 /* expect 16-bit but got 32-bit address */
555                 DebugMsg1(( "set_rm_sib: error, Ofssize=%u, adrsize=%u, data=%" I32_SPEC "X\n",
556                         CodeInfo->Ofssize, CodeInfo->prefix.adrsiz, CodeInfo->opnd[CurrOpnd].data32l ));
557                 return( EmitError( MAGNITUDE_OF_OFFSET_EXCEEDS_16BIT ) );
558             }
559             rm_field = RM_D16; /* D16=110b */
560         } else {
561             rm_field = RM_D32; /* D32=101b */
562 #if AMD64_SUPPORT
563             /* v2.03: the non-RIP encoding for 64bit uses a redundant SIB mode (base=none, index=none) */
564             /* v2.11: always use 64-bit non-RIP addressing if no fixup has been created. */
565             //if ( CodeInfo->Ofssize == USE64 && CodeInfo->prefix.RegOverride != EMPTY && SegOverride != &ModuleInfo.flat_grp->sym ) {
566             if ( CodeInfo->Ofssize == USE64 && CodeInfo->opnd[CurrOpnd].InsFixup == NULL ) {
567                 DebugMsg1(( "set_rm_sib: 64-bit, no fixup, data64=%" I64_SPEC "X\n", CodeInfo->opnd[CurrOpnd].data64 ));
568                 rm_field = RM_SIB;
569                 CodeInfo->sib = 0x25; /* IIIBBB, base=101b, index=100b */
570             }
571 #endif
572         }
573         DebugMsg1(("set_rm_sib, direct, CodeInfo->prefix.adrsiz=%u\n", CodeInfo->prefix.adrsiz ));
574     } else if( ( index == EMPTY ) && ( base != EMPTY ) ) {
575         /* for SI, DI and BX: default is DS:[],
576          * DS: segment override is not needed
577          * for BP: default is SS:[], SS: segment override is not needed
578          */
579         switch( base ) {
580         case T_SI:
581             rm_field = RM_SI; /* 4 */
582             break;
583         case T_DI:
584             rm_field = RM_DI; /* 5 */
585             break;
586         case T_BP:
587             rm_field = RM_BP; /* 6 */
588             if( mod_field == MOD_00 ) {
589                 mod_field = MOD_01;
590             }
591             break;
592         case T_BX:
593             rm_field = RM_BX; /* 7 */
594             break;
595         default: /* for 386 and up */
596             base_reg = GetRegNo( base );
597 #if AMD64_SUPPORT
598             bit3_base = base_reg >> 3;
599             base_reg &= BIT_012;
600 #endif
601             rm_field = base_reg;
602             DebugMsg1(("set_rm_sib: base_reg is %u\n", base_reg ));
603             if ( base_reg == 4 ) {
604                 /* 4 is RSP/ESP or R12/R12D, which must use SIB encoding.
605                  * SSIIIBBB, ss = 00, index = 100b ( no index ), base = 100b ( ESP ) */
606                 CodeInfo->sib = 0x24;
607             } else if ( base_reg == 5 && mod_field == MOD_00 ) {
608                 /* 5 is [E|R]BP or R13[D]. Needs displacement */
609                 mod_field = MOD_01;
610             }
611 #if AMD64_SUPPORT
612             /* v2.02 */
613             //rex = ( bit3_base << 2 ); /* set REX_R */
614             rex = bit3_base; /* set REX_R */
615 #endif
616         }
617 #if AMD64_SUPPORT
618         DebugMsg1(("set_rm_sib, indirect with base, mod_field=%X, rm_field=%X, rex=%X\n", mod_field, rm_field, rex ));
619 #else
620         DebugMsg1(("set_rm_sib, indirect with base, rm_field=%X\n", rm_field ));
621 #endif
622         seg_override( CodeInfo, base, sym, FALSE );
623     } else if( ( index != EMPTY ) && ( base == EMPTY ) ) {
624         idx_reg = GetRegNo( index );
625 #if AMD64_SUPPORT
626         bit3_idx = idx_reg >> 3;
627         idx_reg &= BIT_012;
628 #endif
629         /* mod field is 00 */
630         mod_field = MOD_00;
631         /* s-i-b is present ( r/m = 100b ) */
632         rm_field = RM_SIB;
633         /* scale factor, index, base ( 0x05 => no base reg ) */
634         CodeInfo->sib = ( ss | ( idx_reg << 3 ) | 0x05 );
635 #if AMD64_SUPPORT
636         rex = (bit3_idx << 1); /* set REX_X */
637 #endif
638         /* default is DS:[], DS: segment override is not needed */
639         seg_override( CodeInfo, T_DS, sym, FALSE );
640     } else {
641         /* base != EMPTY && index != EMPTY */
642         base_reg = GetRegNo( base );
643         idx_reg  = GetRegNo( index );
644 #if AMD64_SUPPORT
645         bit3_base = base_reg >> 3;
646         bit3_idx  = idx_reg  >> 3;
647         base_reg &= BIT_012;
648         idx_reg  &= BIT_012;
649 #endif
650         if ( ( GetSflagsSp( base ) & GetSflagsSp( index ) & SFR_SIZMSK ) == 0 ) {
651             return( EmitError( CANNOT_MIX_16_AND_32_BIT_REGISTERS ) );
652         }
653         switch( index ) {
654         case T_BX:
655         case T_BP:
656             if( ( temp = comp_mem16( index, base ) ) == ERROR )
657                 return( ERROR );
658             rm_field = temp;
659             seg_override( CodeInfo, index, sym, FALSE );
660             break;
661         case T_SI:
662         case T_DI:
663             if( ( temp = comp_mem16( base, index ) ) == ERROR )
664                 return( ERROR );
665             rm_field = temp;
666             seg_override( CodeInfo, base, sym, FALSE );
667             break;
668 #if AMD64_SUPPORT
669         case T_RSP:
670 #endif
671         case T_ESP:
672             //EmitErr( CANNOT_BE_USED_AS_INDEX_REGISTER, ??? );
673             return( EmitError( INVALID_USE_OF_REGISTER ) );
674         default:
675             if( base_reg == 5 ) { /* v2.03: EBP/RBP/R13/R13D? */
676                 if( mod_field == MOD_00 ) {
677                     mod_field = MOD_01;
678                 }
679             }
680             /* s-i-b is present ( r/m = 100b ) */
681             rm_field |= RM_SIB;
682             CodeInfo->sib = ( ss | idx_reg << 3 | base_reg );
683 #if AMD64_SUPPORT
684             rex = (bit3_idx << 1) + (bit3_base); /* set REX_X + REX_B */
685 #endif
686             seg_override( CodeInfo, base, sym, FALSE );
687         } /* end switch(index) */
688 #if AMD64_SUPPORT
689         DebugMsg1(("set_rm_sib, indirect, base+index: mod_field=%X, rm_field=%X, rex=%X\n", mod_field, rm_field, rex ));
690 #else
691         DebugMsg1(("set_rm_sib, indirect, base+index: rm_field=%X\n", rm_field ));
692 #endif
693     }
694     if( CurrOpnd == OPND2 ) {
695         /* shift the register field to left by 3 bit */
696         CodeInfo->rm_byte = mod_field | ( rm_field << 3 ) | ( CodeInfo->rm_byte & BIT_012 );
697 #if AMD64_SUPPORT
698         /* v2.02: exchange B and R, keep X */
699         //CodeInfo->prefix.rex |= (rex >> 2 );
700         CodeInfo->prefix.rex |= ( ( rex >> 2 ) | ( rex & REX_X ) | (( rex & 1) << 2 ) );
701 #endif
702     } else if( CurrOpnd == OPND1 ) {
703         CodeInfo->rm_byte = mod_field | rm_field;
704 #if AMD64_SUPPORT
705         CodeInfo->prefix.rex |= rex;
706 #endif
707     }
708     return( NOT_ERROR );
709 }
710 
711 /* override handling
712  * called by
713  * - process_branch()
714  * - idata_fixup()
715  * - memory_operand() (CodeInfo != NULL)
716  * - data_item()
717  * 1. If it's a segment register, set CodeInfo->prefix.RegOverride.
718  * 2. Set global variable SegOverride if it's a SEG/GRP symbol
719  *    (or whatever is assumed for the segment register)
720  */
SetSegOverride(const struct expr * opndx,struct code_info * CodeInfo)721 ret_code SetSegOverride( const struct expr *opndx, struct code_info *CodeInfo )
722 /*****************************************************************************/
723 {
724     struct asym      *sym;
725 
726     if( opndx->override != NULL ) {
727         if( opndx->override->token == T_REG ) {
728             int temp = GetRegNo( opndx->override->tokval );
729             if ( SegAssumeTable[temp].error ) {
730                 DebugMsg(("SetSegOverride: assume error, reg=%u\n", temp ));
731                 return( EmitError( USE_OF_REGISTER_ASSUMED_TO_ERROR ) );
732             }
733 #if AMD64_SUPPORT
734             /* ES,CS,SS and DS overrides are invalid in 64-bit */
735             if ( CodeInfo && CodeInfo->Ofssize == USE64 && temp < ASSUME_FS ) {
736                 return( EmitError( ILLEGAL_USE_OF_SEGMENT_REGISTER ) );
737             }
738 #endif
739             sym = GetOverrideAssume( temp );
740             if ( CodeInfo ) {
741                 /* hack: save the previous reg override value (needed for CMPS) */
742                 LastRegOverride = CodeInfo->prefix.RegOverride;
743                 CodeInfo->prefix.RegOverride = temp;
744             }
745         } else {
746             sym = SymSearch( opndx->override->string_ptr );
747         }
748         DebugMsg1(("SetSegOverride: sym=%s, type=%u\n", sym ? sym->name : "NULL", sym ? sym->state : 0 ));
749         if ( sym && ( sym->state == SYM_GRP || sym->state == SYM_SEG ))
750             SegOverride = sym;
751     }
752     return( NOT_ERROR );
753 }
754 
755 /* get an immediate operand without a fixup.
756  * output:
757  * - ERROR: error
758  * - NOT_ERROR: ok,
759  *   CodeInfo->opnd_type[CurrOpnd] = OP_Ix
760  *   CodeInfo->data[CurrOpnd]      = value
761  *   CodeInfo->prefix.opsiz
762  *   CodeInfo->iswide
763  */
idata_nofixup(struct code_info * CodeInfo,unsigned CurrOpnd,const struct expr * opndx)764 static ret_code idata_nofixup( struct code_info *CodeInfo, unsigned CurrOpnd, const struct expr *opndx )
765 /******************************************************************************************************/
766 {
767     enum operand_type op_type;
768     int_32      value;
769     int         size;
770 
771     DebugMsg1(("idata_nofixup( CurrOpnd=%u ) enter [opnd kind=%u mem_type=%Xh value=%" I64_SPEC "X]\n", CurrOpnd, opndx->kind, opndx->mem_type, opndx->value64));
772 
773     /* jmp/call/jxx/loop/jcxz/jecxz? */
774     if( IS_ANY_BRANCH( CodeInfo->token ) ) {
775         return( process_branch( CodeInfo, CurrOpnd, opndx ) );
776     }
777     value = opndx->value;
778     CodeInfo->opnd[CurrOpnd].data32l = value;
779 
780 #if AMD64_SUPPORT
781     /* 64bit immediates are restricted to MOV <reg>,<imm64>
782      */
783     if ( opndx->hlvalue != 0 ) { /* magnitude > 64 bits? */
784         DebugMsg1(("idata_nofixup: error, hlvalue=%" I64_SPEC "X\n", opndx->hlvalue ));
785         return( EmitConstError( opndx ) );
786     }
787     /* v2.03: handle QWORD type coercion here as well!
788      * This change also reveals an old problem in the expression evaluator:
789      * the mem_type field is set whenever a (simple) type token is found.
790      * It should be set ONLY when the type is used in conjuction with the
791      * PTR operator!
792      * current workaround: query the 'explicit' flag.
793      */
794     //if ( opndx->value64 <= minintvalues[0] || opndx->value64 > maxintvalues[0] ) {
795     /* use long format of MOV for 64-bit if value won't fit in a signed DWORD */
796     if ( CodeInfo->Ofssize == USE64 &&
797         CodeInfo->token == T_MOV &&
798         CurrOpnd == OPND2 &&
799         ( CodeInfo->opnd[OPND1].type & OP_R64 ) &&
800         /* v2.14: don't use LONG_MAX/MIN, won't work in 64-bit unix */
801         //( opndx->value64 > LONG_MAX || opndx->value64 < LONG_MIN ||
802         ( opndx->value64 > INT32_MAX || opndx->value64 < INT32_MIN ||
803          (opndx->explicit && ( opndx->mem_type == MT_QWORD || opndx->mem_type == MT_SQWORD ) ) ) ) {
804         // CodeInfo->iswide = 1; /* has been set by first operand already */
805         CodeInfo->opnd[CurrOpnd].type = OP_I64;
806         CodeInfo->opnd[CurrOpnd].data32h = opndx->hvalue;
807         return( NOT_ERROR );
808     }
809     if ( opndx->value64 <= minintvalues[0] || opndx->value64 > maxintvalues[0] ) {
810         DebugMsg1(("idata_nofixup: error, hvalue=%" I32_SPEC "Xh\n", opndx->hvalue ));
811         return( EmitConstError( opndx ) );
812     }
813 #endif
814 
815     /* v2.06: code simplified.
816      * to be fixed: the "wide" bit should not be set here!
817      * Problem: the "wide" bit isn't set in memory_operand(),
818      * probably because of the instructions which accept both
819      * signed and unsigned arguments (ADD, CMP, ... ).
820      */
821 
822     if ( opndx->explicit ) {
823         /* size coercion for immediate value */
824         CodeInfo->const_size_fixed = TRUE;
825         size = SizeFromMemtype( opndx->mem_type,
826                                opndx->Ofssize,
827                                opndx->type );
828         /* don't check if size and value are compatible. */
829         switch ( size ) {
830         case 1: op_type = OP_I8;  break;
831         case 2: op_type = OP_I16; break;
832         case 4: op_type = OP_I32; break;
833         default:
834             DebugMsg1(("idata_nofixup: invalid size %d for immediate operand\n", size ));
835             return( EmitError( INVALID_INSTRUCTION_OPERANDS ) );
836         }
837     } else {
838         /* use true signed values for BYTE only! */
839         if ( (int_8)value == value )
840             op_type = OP_I8;
841         //else if ( value <= SHRT_MAX && value >= SHRT_MIN )
842         /* v2.04: range FFFF0000-FFFF7FFF is also acceptable for 16-bit */
843         //else if ( value <= USHRT_MAX && value >= SHRT_MIN )
844         /* v2.04b: JWASMR needs a 1L */
845         //else if( value <= USHRT_MAX && value >= - (USHRT_MAX+1) )
846         /* v2.07: JWASMR needs 0L before the - op */
847         //else if( value <= USHRT_MAX && value >= - USHRT_MAX )
848         else if( value <= USHRT_MAX && value >= 0L - USHRT_MAX )
849             op_type = OP_I16;
850         else {
851             op_type = OP_I32;
852         }
853     }
854 
855     switch ( CodeInfo->token ) {
856     case T_PUSH:
857         if ( opndx->explicit == FALSE ) {
858             if ( CodeInfo->Ofssize > USE16 && op_type == OP_I16 )
859                 op_type = OP_I32;
860         }
861         if ( op_type == OP_I16 )
862             CodeInfo->prefix.opsiz = OPSIZE16( CodeInfo );
863         else if ( op_type == OP_I32 )
864             CodeInfo->prefix.opsiz = OPSIZE32( CodeInfo );
865         break;
866     case T_PUSHW:
867         if ( op_type != OP_I32 ) {
868             op_type = OP_I16;
869             if( (int_8)value == (int_16)value ) {
870                 op_type = OP_I8;
871             }
872         }
873         break;
874     case T_PUSHD:
875         if ( op_type == OP_I16 )
876             op_type = OP_I32;
877         break;
878     }
879 
880     /* v2.11: set the wide-bit if a mem_type size of > BYTE is set???
881      * actually, it should only be set if immediate is second operand
882      * ( and first operand is a memory ref with a size > 1 )
883      */
884     if ( CurrOpnd == OPND2 )
885         if ( !(CodeInfo->mem_type & MT_SPECIAL) && ( CodeInfo->mem_type & MT_SIZE_MASK ) )
886             CodeInfo->iswide = 1;
887 
888     CodeInfo->opnd[CurrOpnd].type = op_type;
889     DebugMsg1(("idata_nofixup exit, op_type=%" I32_SPEC "X\n", op_type ));
890     return( NOT_ERROR );
891 }
892 
893 /* get an immediate operand with a fixup.
894  * output:
895  * - ERROR: error
896  * - NOT_ERROR: ok,
897  *   CodeInfo->opnd_type[CurrOpnd] = OP_Ix
898  *   CodeInfo->data[CurrOpnd]      = value
899  *   CodeInfo->InsFixup[CurrOpnd]  = fixup
900  *   CodeInfo->mem_type
901  *   CodeInfo->prefix.opsiz
902  * to be fixed: don't modify CodeInfo->mem_type here!
903  */
idata_fixup(struct code_info * CodeInfo,unsigned CurrOpnd,struct expr * opndx)904 ret_code idata_fixup( struct code_info *CodeInfo, unsigned CurrOpnd, struct expr *opndx )
905 /***************************************************************************************/
906 {
907     //struct fixup      *fixup;
908     enum fixup_types    fixup_type;
909     enum fixup_options  fixup_option = OPTJ_NONE;
910     int                 size;
911     uint_8              Ofssize; /* 1=32bit, 0=16bit offset for fixup */
912 
913     DebugMsg1(("idata_fixup( CurrOpnd=%u ) enter [opndx.kind=%u mem_type=%Xh, CodeInfo.mem_type=%Xh]\n", CurrOpnd, opndx->kind, opndx->mem_type, CodeInfo->mem_type));
914 
915     /* jmp/call/jcc/loopcc/jxcxz? */
916     if( IS_ANY_BRANCH( CodeInfo->token ) ) {
917         return( process_branch( CodeInfo, CurrOpnd, opndx ) );
918     }
919     CodeInfo->opnd[CurrOpnd].data32l = opndx->value;
920 
921     if ( opndx->Ofssize != USE_EMPTY ) {
922         Ofssize = opndx->Ofssize;
923     } else if( opndx->sym == NULL ) { /* v2.15: branch added */
924         SetSegOverride( opndx, NULL );
925         if ( SegOverride )
926             Ofssize = GetSymOfssize( SegOverride );
927     } else if( ( opndx->sym->state == SYM_SEG )
928         || ( opndx->sym->state == SYM_GRP )
929         || ( opndx->instr == T_SEG ) ) {
930         Ofssize = USE16;
931     } else if( opndx->is_abs ) {  /* an (external) absolute symbol? */
932         Ofssize = USE16;
933     } else {
934         Ofssize = GetSymOfssize( opndx->sym );
935     }
936 
937     if( opndx->instr == T_SHORT ) {
938         /* short works for branch instructions only */
939         return( EmitErr( INVALID_INSTRUCTION_OPERANDS ) );
940     }
941 
942     /* the code below should be rewritten.
943      * - an address operator ( OFFSET, LROFFSET, IMAGEREL, SECTIONREL,
944      *   LOW, HIGH, LOWWORD, HIGHWORD, LOW32, HIGH32, SEG ) should not
945      *   force a magnitude, but may set a minimal magnitude - and the
946      *   fixup type, of course.
947      * - check if Codeinfo->mem_type really has to be set here!
948      */
949 
950     /* v2.06: added */
951     /* v2.10: modified */
952     //if ( opndx->explicit ) {
953     if ( opndx->explicit && !opndx->is_abs ) {
954         CodeInfo->const_size_fixed = TRUE;
955         if ( CodeInfo->mem_type == MT_EMPTY )
956             CodeInfo->mem_type = opndx->mem_type;
957     }
958     /* v2.03: don't ignore a "NEAR32 ptr" qualifier */
959     //if ( CodeInfo->mem_type == MT_EMPTY && CurrOpnd > OPND1 ) {
960     if ( CodeInfo->mem_type == MT_EMPTY && CurrOpnd > OPND1 && opndx->Ofssize == USE_EMPTY ) {
961         size = OperandSize( CodeInfo->opnd[OPND1].type, CodeInfo );
962         /* may be a forward reference, so wait till pass 2 */
963         if( Parse_Pass > PASS_1 && opndx->instr != EMPTY ) {
964             switch ( opndx->instr ) {
965             case T_SEG: /* v2.04a: added */
966                 if( size && (size < 2 ) ) {
967                     return( EmitErr( OPERANDS_MUST_BE_THE_SAME_SIZE, size, 2 ) );
968                 }
969                 break;
970             case T_OFFSET:
971             case T_LROFFSET:
972 #if IMAGERELSUPP
973             case T_IMAGEREL:
974 #endif
975 #if SECTIONRELSUPP
976             case T_SECTIONREL:
977 #endif
978                 if( size && (size < 2 || ( Ofssize && size < 4 ))) {
979                     return( EmitErr( OPERANDS_MUST_BE_THE_SAME_SIZE, size, ( 2 << Ofssize ) ) );
980                 }
981             }
982         }
983         switch ( size ) {
984         case 1:
985             /* v2.05: if () added */
986             if ( opndx->is_abs || opndx->instr == T_LOW || opndx->instr == T_HIGH )
987                 CodeInfo->mem_type = MT_BYTE;
988             break;
989         case 2:
990             /* v2.05: if () added */
991             if ( opndx->is_abs ||
992                 CodeInfo->Ofssize == USE16 ||
993                 opndx->instr == T_LOWWORD ||
994                 opndx->instr == T_HIGHWORD )
995                 CodeInfo->mem_type = MT_WORD;
996             break;
997         case 4:
998             CodeInfo->mem_type = MT_DWORD;
999             break;
1000 #if AMD64_SUPPORT
1001         case 8:
1002             /* v2.05: it's questionable if size 8 is a good assumption for an
1003              * immediate constant. It's valid for MOV <reg>, <imm> only.
1004              */
1005             //case 8: CodeInfo->mem_type = MT_QWORD;break;
1006             /* v2.05a: added */
1007             if ( Ofssize == USE64 ) {
1008                 if ( CodeInfo->token == T_MOV &&
1009                     ( CodeInfo->opnd[OPND1].type & OP_R64 ) )
1010                     CodeInfo->mem_type = MT_QWORD;
1011                 else if ( opndx->instr == T_LOW32 || opndx->instr == T_HIGH32 )
1012                     /* v2.10:added; LOW32/HIGH32 in expreval.c won't set mem_type anymore. */
1013                     CodeInfo->mem_type = MT_DWORD;
1014             }
1015             break;
1016 #endif
1017         }
1018     }
1019     if ( CodeInfo->mem_type == MT_EMPTY ) {
1020         if( opndx->is_abs ) {
1021             //if( opndx->mem_type != MT_EMPTY && opndx->mem_type != MT_ABS ) {
1022             if( opndx->mem_type != MT_EMPTY ) {
1023                 CodeInfo->mem_type = opndx->mem_type;
1024             } else if ( CodeInfo->token == T_PUSHW ) { /* v2.10: special handling PUSHW */
1025                 CodeInfo->mem_type = MT_WORD;
1026             } else {
1027                 CodeInfo->mem_type = ( IS_OPER_32( CodeInfo ) ? MT_DWORD : MT_WORD );
1028             }
1029         } else {
1030             switch ( CodeInfo->token ) {
1031             case T_PUSHW:
1032             case T_PUSHD:
1033             case T_PUSH:
1034                 /* for forward reference, assume BYTE */
1035                 /* v2.02: don't assume BYTE if it is SEG/GRP */
1036                 //if ( opndx->mem_type == MT_EMPTY ) {
1037                 /* v2.07: added cases IMAGEREL and SECTIONREL */
1038                 if ( opndx->mem_type == MT_EMPTY  ) {
1039                     switch( opndx->instr ) {
1040                     case EMPTY:
1041                     case T_LOW:
1042                     case T_HIGH:
1043                         opndx->mem_type = MT_BYTE;
1044                         break;
1045                     case T_LOWWORD: /*v2.12: added */
1046                     case T_HIGHWORD: /*v2.12: added */
1047                         opndx->mem_type = MT_WORD;
1048                         break;
1049                     case T_LOW32: /* v2.10: added - low32_op() doesn't set mem_type anymore. */
1050 #if IMAGERELSUPP
1051                     case T_IMAGEREL:
1052 #endif
1053 #if SECTIONRELSUPP
1054                     case T_SECTIONREL:
1055 #endif
1056                         opndx->mem_type = MT_DWORD;
1057                         break;
1058                     };
1059                 }
1060                 /* default: push offset only */
1061                 /* for PUSH + undefined symbol, assume BYTE */
1062                 if ( opndx->mem_type == MT_FAR && ( opndx->explicit == FALSE ) )
1063                     opndx->mem_type = MT_NEAR;
1064                 /* v2.04: curly brackets added */
1065                 if ( CodeInfo->token == T_PUSHW ) {
1066                     if ( SizeFromMemtype( opndx->mem_type, Ofssize, opndx->type ) < 2 )
1067                         opndx->mem_type = MT_WORD;
1068                 } else if ( CodeInfo->token == T_PUSHD ) {
1069                     if ( SizeFromMemtype( opndx->mem_type, Ofssize, opndx->type ) < 4 )
1070                         opndx->mem_type = MT_DWORD;
1071                 }
1072                 break;
1073             }
1074             /* if a WORD size is given, don't override it with */
1075             /* anything what might look better at first glance */
1076             if( opndx->mem_type != MT_EMPTY )
1077                 CodeInfo->mem_type = opndx->mem_type;
1078             /* v2.15: check for sym==NULL */
1079             /* v2.04: assume BYTE size if symbol is undefined */
1080             //else if ( opndx->sym->state == SYM_UNDEFINED ) {
1081             else if ( opndx->sym && opndx->sym->state == SYM_UNDEFINED ) {
1082                 CodeInfo->mem_type = MT_BYTE;
1083                 fixup_option = OPTJ_PUSH;
1084             } else
1085 #if AMD64_SUPPORT
1086                 /* v2.06d: changed */
1087                 CodeInfo->mem_type = ( Ofssize == USE64 ? MT_QWORD : Ofssize == USE32 ? MT_DWORD : MT_WORD );
1088 #else
1089                 CodeInfo->mem_type = ( Ofssize > USE16 ? MT_DWORD : MT_WORD );
1090 #endif
1091         }
1092     }
1093     size = SizeFromMemtype( CodeInfo->mem_type, Ofssize, NULL );
1094     switch( size ) {
1095     case 1:
1096         CodeInfo->opnd[CurrOpnd].type = OP_I8;
1097         CodeInfo->prefix.opsiz = FALSE; /* v2.10: reset opsize is not really a good idea - might have been set by previous operand */
1098         break;
1099     case 2:  CodeInfo->opnd[CurrOpnd].type = OP_I16; CodeInfo->prefix.opsiz = OPSIZE16( CodeInfo );  break;
1100     case 4:  CodeInfo->opnd[CurrOpnd].type = OP_I32; CodeInfo->prefix.opsiz = OPSIZE32( CodeInfo );  break;
1101 #if AMD64_SUPPORT
1102     case 8:
1103         /* v2.05: do only assume size 8 if the constant won't fit in 4 bytes. */
1104         /* v2.14: don't use LONG_MAX/MIN, won't work in 64-bit unix */
1105         //if ( opndx->value64 > LONG_MAX || opndx->value64 < LONG_MIN ||
1106         if ( opndx->value64 > INT32_MAX || opndx->value64 < INT32_MIN ||
1107             (opndx->explicit && ( opndx->mem_type & MT_SIZE_MASK ) == 7 ) ) {
1108             CodeInfo->opnd[CurrOpnd].type = OP_I64;
1109             CodeInfo->opnd[CurrOpnd].data32h = opndx->hvalue;
1110         //} else if ( Ofssize == USE64 ) { /* v2.11: assume 64-bit only for OFFSET or MOV r64, xxx */
1111         } else if ( Ofssize == USE64 && ( opndx->instr == T_OFFSET || ( CodeInfo->token == T_MOV && ( CodeInfo->opnd[OPND1].type & OP_R64 ) ) ) ) {
1112             /* v2.06d: in 64-bit, ALWAYS set OP_I64, so "mov m64, ofs" will fail,
1113              * This was accepted in v2.05-v2.06c)
1114              */
1115             CodeInfo->opnd[CurrOpnd].type = OP_I64;
1116             CodeInfo->opnd[CurrOpnd].data32h = opndx->hvalue;
1117         } else {
1118             CodeInfo->opnd[CurrOpnd].type = OP_I32;
1119         }
1120         CodeInfo->prefix.opsiz = OPSIZE32( CodeInfo );
1121         break;
1122 #endif
1123 #ifdef DEBUG_OUT
1124     default:
1125         DebugMsg1(("idata_fixup, unexpected size %u\n", size ));
1126         /**/myassert( 0 );
1127 #endif
1128     }
1129 
1130     /* set fixup_type */
1131 
1132     if( opndx->instr == T_SEG ) {
1133         fixup_type = FIX_SEG;
1134         DebugMsg1(("idata_fixup, fixup_type=SEG\n" ));
1135     } else if( CodeInfo->mem_type == MT_BYTE ) {
1136         DebugMsg1(("idata_fixup, mem_type=BYTE\n" ));
1137         if ( opndx->instr == T_HIGH ) {
1138             DebugMsg1(("idata_fixup, fixup_type=HIBYTE\n" ));
1139             fixup_type = FIX_HIBYTE;
1140         } else {
1141             DebugMsg1(("idata_fixup, fixup_type=OFF8\n" ));
1142             fixup_type = FIX_OFF8;
1143         }
1144 #if 0
1145     } else if( CodeInfo->mem_type == MT_FAR ) {
1146         /* v2.04: to be tested. this code is most likely obsolete.
1147          * There's never a PTR16|PTR32 fixup here. Far JMP/CALL are handled
1148          * elsewhere, and data items also.
1149          */
1150         /* temporary */
1151         printf("idata_fixup: MT_FAR occured at %s:%" I32_SPEC "u\n", CurrFName[ASM], LineNumber );
1152         fixup_type = ( Ofssize ) ? FIX_PTR32 : FIX_PTR16;
1153         CodeInfo->isfar = TRUE; /* needed for mark_fixupp() */
1154         if ( opndx->Ofssize != USE_EMPTY )
1155             CodeInfo->Ofssize = opndx->Ofssize;
1156 #endif
1157     } else if( IS_OPER_32( CodeInfo ) ) {
1158 #if AMD64_SUPPORT
1159         /* v2.06: changed */
1160         //if ( Ofssize == USE64 && CodeInfo->mem_type == MT_QWORD )
1161         /* v2.10: changed */
1162         //if ( CodeInfo->opnd[CurrOpnd].type == OP_I64 )
1163         if ( CodeInfo->opnd[CurrOpnd].type == OP_I64 && ( opndx->instr == EMPTY || opndx->instr == T_OFFSET ) ) {
1164             DebugMsg1(("idata_fixup, fixup_type=OFF64\n" ));
1165             fixup_type = FIX_OFF64;
1166         } else
1167 #endif
1168             /* v2.04: changed, no longer depends on OfsSize */
1169             /* v2.05a: changed, so size==8 won't get a FIX_OFF16 type */
1170             //if ( size == 4 )
1171             if ( size >= 4 && opndx->instr != T_LOWWORD ) {
1172                 /* v2.06: added branch for PTR16 fixup.
1173                  * it's only done if type coercion is FAR (Masm-compat)
1174                  */
1175                 if ( opndx->explicit && Ofssize == USE16 && opndx->mem_type == MT_FAR ) {
1176                     DebugMsg1(("idata_fixup, fixup_type=PTR16\n" ));
1177                     fixup_type = FIX_PTR16;
1178                 } else {
1179                     DebugMsg1(("idata_fixup, fixup_type=OFF32\n" ));
1180                     fixup_type = FIX_OFF32;
1181 #if AMD64_SUPPORT
1182 					if ( Ofssize == USE64 && Parse_Pass == PASS_2 )
1183 						EmitWarn( 3, ADDR32_FIXUP_FOR_64BIT_LABEL );
1184 #endif
1185                 }
1186             } else {
1187                 DebugMsg1(("idata_fixup, fixup_type=OFF16 (1)\n" ));
1188                 fixup_type = FIX_OFF16;
1189             }
1190     } else {
1191         /* v2.04: changed, no longer depends on OfsSize */
1192         //if ( CodeInfo->mem_type == MT_DWORD ) {
1193             /* fixme !!!! warning
1194              * operand size is 16bit
1195              * but fixup is 32-bit */
1196         //    fixup_type = FIX_OFF32;
1197         //} else
1198         DebugMsg1(("idata_fixup, fixup_type=OFF16 (2)\n" ));
1199         fixup_type = FIX_OFF16;
1200     }
1201     /* v2.04: 'if' added, don't set W bit if size == 1
1202      * code example:
1203      *   extern x:byte
1204      *   or al,x
1205      * v2.11: set wide bit only if immediate is second operand.
1206      * and first operand is a memory reference with size > 1
1207      */
1208     //if ( size != 1 )
1209     if ( CurrOpnd == OPND2 && size != 1 )
1210         CodeInfo->iswide = 1;
1211 
1212     SetSegOverride( opndx, NULL ); /* set SegOverride global var */
1213 
1214     /* set frame type in variables Frame_Type and Frame_Datum for fixup creation */
1215     if ( ModuleInfo.offsettype == OT_SEGMENT &&
1216         ( opndx->instr == T_OFFSET || opndx->instr == T_SEG ))
1217         set_frame2( opndx->sym );
1218     else
1219         set_frame( opndx->sym );
1220 
1221     //DebugMsg1(("idata_fixup: calling CreateFixup(%s, %u)\n", opndx->sym->name, fixup_type ));
1222     CodeInfo->opnd[CurrOpnd].InsFixup = CreateFixup( opndx->sym, fixup_type, fixup_option );
1223 
1224     if ( opndx->instr == T_LROFFSET )
1225         CodeInfo->opnd[CurrOpnd].InsFixup->loader_resolved = TRUE;
1226 
1227 #if IMAGERELSUPP
1228     if ( opndx->instr == T_IMAGEREL && fixup_type == FIX_OFF32 )
1229         CodeInfo->opnd[CurrOpnd].InsFixup->type = FIX_OFF32_IMGREL;
1230 #endif
1231 #if SECTIONRELSUPP
1232     if ( opndx->instr == T_SECTIONREL && fixup_type == FIX_OFF32 )
1233         CodeInfo->opnd[CurrOpnd].InsFixup->type = FIX_OFF32_SECREL;
1234 #endif
1235     DebugMsg1(("idata_fixup exit [CodeInfo.mem_type=%Xh Ofssize=%u opsiz=%u fixup.type=%u fixup.frame=%d]\n",
1236                CodeInfo->mem_type, CodeInfo->Ofssize, CodeInfo->prefix.opsiz,
1237                CodeInfo->opnd[CurrOpnd].InsFixup->type, CodeInfo->opnd[CurrOpnd].InsFixup->frame_type ));
1238 
1239     return( NOT_ERROR );
1240 }
1241 
1242 /* convert MT_PTR to MT_WORD, MT_DWORD, MT_FWORD, MT_QWORD.
1243  * MT_PTR cannot be set explicitely (by the PTR operator),
1244  * so this value must come from a label or a structure field.
1245  * (above comment is most likely plain wrong, see 'PF16 ptr [reg]'!
1246  * This code needs cleanup!
1247  */
SetPtrMemtype(struct code_info * CodeInfo,struct expr * opndx)1248 static void SetPtrMemtype( struct code_info *CodeInfo, struct expr *opndx )
1249 /*************************************************************************/
1250 {
1251     struct asym *sym = opndx->sym;
1252     int size = 0;
1253 
1254     if ( opndx->mbr )  /* the mbr field has higher priority */
1255         sym = opndx->mbr;
1256 
1257     /* v2.10: the "explicit" condition is now handled FIRST */
1258 #if 1 /* v2.0: handle PF16 ptr [ebx], which didn't work in v1.96 */
1259     if ( opndx->explicit && opndx->type ) {
1260         size = opndx->type->total_size;
1261         CodeInfo->isfar = opndx->type->isfar;
1262     } else
1263 #endif
1264     if ( sym ) {
1265         if ( sym->type ) {
1266             size = sym->type->total_size;
1267             CodeInfo->isfar = sym->type->isfar;
1268 
1269             /* there's an ambiguity with pointers of size DWORD,
1270              since they can be either NEAR32 or FAR16 */
1271             if ( size == 4 && sym->type->Ofssize != CodeInfo->Ofssize )
1272                 opndx->Ofssize = sym->type->Ofssize;
1273 
1274         } else if ( sym->mem_type == MT_PTR ) {
1275             size = SizeFromMemtype( sym->isfar ? MT_FAR : MT_NEAR, sym->Ofssize, NULL );
1276             CodeInfo->isfar = sym->isfar;
1277         } else  {
1278             if ( sym->isarray )
1279                 size = sym->total_size / sym->total_length;
1280             else
1281                 size = sym->total_size;
1282         }
1283     } else {
1284         if ( SIZE_DATAPTR & ( 1 << ModuleInfo.model ) ) {
1285             DebugMsg1(("SetPtrMemtype: model with FAR data pointers\n" ));
1286             size = 2;
1287         }
1288         size += (2 << ModuleInfo.defOfssize );
1289     }
1290     if ( size )
1291         MemtypeFromSize( size, &opndx->mem_type );
1292     DebugMsg1(("SetPtrMemtype: size=%u, new memtype=0x%x\n", size, opndx->mem_type ));
1293 }
1294 
1295 /*
1296  * set fields in CodeInfo:
1297  * - mem_type
1298  * - prefix.opsiz
1299  * - prefix.rex REX_W
1300  * called by memory_operand()
1301  */
Set_Memtype(struct code_info * CodeInfo,enum memtype mem_type)1302 static void Set_Memtype( struct code_info *CodeInfo, enum memtype mem_type )
1303 /**************************************************************************/
1304 {
1305     if( CodeInfo->token == T_LEA )
1306         return;
1307 
1308     /* v2.05: changed. Set "data" types only. */
1309     if( mem_type == MT_EMPTY || mem_type == MT_TYPE ||
1310        mem_type == MT_NEAR || mem_type == MT_FAR )
1311         return;
1312 
1313     CodeInfo->mem_type = mem_type;
1314 
1315     if( CodeInfo->Ofssize > USE16 ) {
1316         /* if we are in use32 mode, we have to add OPSIZ prefix for
1317          * most of the 386 instructions when operand has type WORD.
1318          * Exceptions ( MOVSX and MOVZX ) are handled in check_size().
1319          */
1320         if ( IS_MEM_TYPE( mem_type, WORD ) )
1321             CodeInfo->prefix.opsiz = TRUE;
1322 #if AMD64_SUPPORT
1323         /*
1324          * set rex Wide bit if a QWORD operand is found (not for FPU/MMX/SSE instr).
1325          * This looks pretty hackish now and is to be cleaned!
1326          * v2.01: also had issues with SSE2 MOVSD/CMPSD, now fixed!
1327          */
1328         /* v2.06: with AVX, SSE tokens may exist twice, one
1329          * for "legacy", the other for VEX encoding!
1330          */
1331         else if ( IS_MEMTYPE_SIZ( mem_type, sizeof( uint_64 ) ) ) {
1332             switch( CodeInfo->token ) {
1333             case T_PUSH: /* for PUSH/POP, REX_W isn't needed (no 32-bit variants in 64-bit mode) */
1334             case T_POP:
1335             case T_CMPXCHG8B:
1336 #if VMXSUPP
1337             case T_VMPTRLD:
1338             case T_VMPTRST:
1339             case T_VMCLEAR:
1340             case T_VMXON:
1341 #endif
1342                 break;
1343             default:
1344                 /* don't set REX for opcodes that accept memory operands
1345                  * of any size.
1346                  */
1347                 if ( opnd_clstab[CodeInfo->pinstr->opclsidx].opnd_type[OPND1] == OP_M_ANY ) {
1348                     //printf( "Set_Memtype: OP_M_ANY detected, file=%s, instr=%s\n", CurrFName[ASM], GetResWName( CodeInfo->token, NULL ) );
1349                     break;
1350                 }
1351                 /* don't set REX for FPU opcodes */
1352                 if ( CodeInfo->pinstr->cpu & P_FPU_MASK )
1353                     break;
1354                 /* don't set REX for - most - MMX/SSE opcodes */
1355                 if ( CodeInfo->pinstr->cpu & P_EXT_MASK ) {
1356                     switch ( CodeInfo->token ) {
1357                         /* [V]CMPSD and [V]MOVSD are also candidates,
1358                          * but currently they are handled in HandleStringInstructions()
1359                          */
1360                     case T_CVTSI2SD: /* v2.06: added */
1361                     case T_CVTSI2SS: /* v2.06: added */
1362                     case T_PEXTRQ: /* v2.06: added */
1363                     case T_PINSRQ: /* v2.06: added */
1364                     case T_MOVD:
1365 #if AVXSUPP
1366                     case T_VCVTSI2SD:
1367                     case T_VCVTSI2SS:
1368                     case T_VPEXTRQ:
1369                     case T_VPINSRQ:
1370                     case T_VMOVD:
1371 #endif
1372                         CodeInfo->prefix.rex |= REX_W;
1373                         break;
1374                     default:
1375                         break;
1376                     }
1377                 }
1378                 else
1379                     CodeInfo->prefix.rex |= REX_W;
1380             }
1381         }
1382 #endif
1383 
1384     /* v2.05: IS_MEM_TYPE() doesn't work with MT_REALx */
1385     //} else if( CodeInfo->Ofssize == USE16 && ( IS_MEM_TYPE( mem_type, DWORD ) ) ) {
1386     } else {
1387         if( IS_MEMTYPE_SIZ( mem_type, sizeof(uint_32) ) ) {
1388 
1389             /* in 16bit mode, a DWORD memory access usually requires an OPSIZ
1390              * prefix. A few instructions, which access m16:16 operands,
1391              * are exceptions.
1392              */
1393             switch( CodeInfo->token ) {
1394             case T_LDS:
1395             case T_LES:
1396             case T_LFS:
1397             case T_LGS:
1398             case T_LSS:
1399             case T_CALL: /* v2.0: added */
1400             case T_JMP:  /* v2.0: added */
1401                 /* in these cases, opsize does NOT need to be changed  */
1402                 break;
1403             default:
1404                 CodeInfo->prefix.opsiz = TRUE;
1405                 break;
1406             }
1407         }
1408 #if AMD64_SUPPORT
1409         /* v2.06: added because in v2.05, 64-bit memory operands were
1410          * accepted in 16-bit code
1411          */
1412         else if ( IS_MEMTYPE_SIZ( mem_type, sizeof(uint_64) ) ) {
1413             if ( opnd_clstab[CodeInfo->pinstr->opclsidx].opnd_type[OPND1] == OP_M_ANY ) {
1414                 //printf( "Set_Memtype: OP_M_ANY detected, file=%s, instr=%s\n", CurrFName[ASM], GetResWName( CodeInfo->token, NULL ) );
1415             } else if ( CodeInfo->pinstr->cpu & ( P_FPU_MASK | P_EXT_MASK ) ) {
1416                 ;
1417             } else if ( CodeInfo->token != T_CMPXCHG8B )
1418                 /* setting REX.W will cause an error in codegen */
1419                 CodeInfo->prefix.rex |= REX_W;
1420         }
1421 #endif
1422     }
1423     return;
1424 }
1425 
1426 /*
1427  * process direct or indirect memory operand
1428  * in: opndx=operand to process
1429  * in: CurrOpnd=no of operand (0=first operand,1=second operand)
1430  * out: CodeInfo->data[]
1431  * out: CodeInfo->opnd_type[]
1432  */
1433 
memory_operand(struct code_info * CodeInfo,unsigned CurrOpnd,struct expr * opndx,bool with_fixup)1434 static ret_code memory_operand( struct code_info *CodeInfo, unsigned CurrOpnd, struct expr *opndx, bool with_fixup )
1435 /******************************************************************************************************************/
1436 {
1437     char                ss = SCALE_FACTOR_1;
1438     int                 index;
1439     int                 base;
1440     int                 j;
1441     struct asym         *sym;
1442     uint_8              Ofssize;
1443     enum fixup_types    fixup_type;
1444 
1445     DebugMsg1(("memory_operand(opndx.value=%" I32_SPEC "X / sym=%s / memtype=%Xh, with_fixup=%u) enter, [CodeInfo->memtype=%Xh, Ofssize=%u, adrsiz=%u]\n",
1446                opndx->value, opndx->sym ? opndx->sym->name : "NULL", opndx->mem_type, with_fixup, CodeInfo->mem_type, CodeInfo->Ofssize, CodeInfo->prefix.adrsiz ));
1447 
1448     /* v211: use full 64-bit value */
1449     //CodeInfo->opnd[CurrOpnd].data = opndx->value;
1450     CodeInfo->opnd[CurrOpnd].data64 = opndx->value64;
1451     CodeInfo->opnd[CurrOpnd].type = OP_M;
1452 
1453     sym = opndx->sym;
1454 
1455     SetSegOverride( opndx, CodeInfo );
1456 
1457     /* change pointer types ( MT_NEAR, MT_FAR, MT_PTR */
1458     /* v2.04a: should not be called if OFFSET was used */
1459     //if ( opndx->mem_type == MT_PTR ) /* this was before v2.04 */
1460     //if ( ( opndx->mem_type & MT_SPECIAL_MASK ) == MT_ADDRESS )
1461     /* v2.05: change reverted */
1462     //if ( ( opndx->mem_type & MT_SPECIAL_MASK ) == MT_ADDRESS && opndx->instr == EMPTY )
1463     if ( opndx->mem_type == MT_PTR )
1464         SetPtrMemtype( CodeInfo, opndx );
1465     else if ( ( opndx->mem_type & MT_SPECIAL_MASK ) == MT_ADDRESS ) {
1466         int size;
1467         if ( opndx->Ofssize == USE_EMPTY && sym )
1468             opndx->Ofssize = GetSymOfssize( sym );
1469         /* v2.09: use opndx->type ( for MT_PROC ) */
1470         //size = SizeFromMemtype( opndx->mem_type, opndx->Ofssize, NULL );
1471         size = SizeFromMemtype( opndx->mem_type, opndx->Ofssize, opndx->type );
1472         MemtypeFromSize( size, &opndx->mem_type );
1473     }
1474 
1475     Set_Memtype( CodeInfo, opndx->mem_type );
1476     if( opndx->mbr != NULL ) {
1477         /* if the struct field is just another struct, use it's total size
1478          * to set CodeInfo->mem_type.
1479          */
1480         //if ( opndx->mbr->mem_type == MT_TYPE ) {
1481         /* v2: don't overwrite opndx->mem_type,
1482          *    testcase: cmp (dword ptr <struct_field>), 0
1483          */
1484         if ( opndx->mbr->mem_type == MT_TYPE && opndx->mem_type == MT_EMPTY ) {
1485             enum memtype mem_type;
1486             DebugMsg1(("memory_operand: mbr %s has mem_type MT_TYPE, total_size=%u\n", opndx->mbr->name, opndx->mbr->total_size ));
1487             if ( MemtypeFromSize( opndx->mbr->total_size, &mem_type ) == NOT_ERROR )
1488                 Set_Memtype( CodeInfo, mem_type );
1489         }
1490         //else  /* v2: obsolete */
1491         //    Set_Memtype( CodeInfo, opndx->mbr->mem_type );
1492         /* v2.06b: tell codegen that the member is a forward ref */
1493         if ( opndx->mbr->state == SYM_UNDEFINED )
1494             CodeInfo->undef_sym = TRUE;
1495     }
1496 
1497     /* instruction-specific handling */
1498     switch ( CodeInfo->token ) {
1499     case T_JMP:
1500     case T_CALL:
1501         /* the 2 branch instructions are peculiar because they
1502          * will work with an unsized label.
1503          */
1504         /* v1.95: convert MT_NEAR/MT_FAR and display error if no type.
1505          * For memory operands, expressions of type MT_NEAR/MT_FAR are
1506          * call [bx+<code_label>]
1507          */
1508         if ( CodeInfo->mem_type == MT_EMPTY ) {
1509             /* with -Zm, no size needed for indirect CALL/JMP */
1510             if ( ModuleInfo.m510 == FALSE &&
1511                 ( Parse_Pass > PASS_1 && opndx->sym == NULL ) ) {
1512                 DebugMsg1(("memory_operand, JMP/CALL: CodeInfo->memtype=empty, instruction operand must have size\n" ));
1513                 return( EmitError( INSTRUCTION_OPERAND_MUST_HAVE_SIZE ) );
1514             }
1515 #if AMD64_SUPPORT
1516             opndx->mem_type = (CodeInfo->Ofssize == USE64) ? MT_QWORD : (CodeInfo->Ofssize == USE32) ? MT_DWORD : MT_WORD;
1517 #else
1518             opndx->mem_type = (CodeInfo->Ofssize == USE32) ? MT_DWORD : MT_WORD;
1519 #endif
1520             Set_Memtype( CodeInfo, opndx->mem_type );
1521             DebugMsg1(("memory_operand, JMP/CALL: CodeInfo->memtype set to %Xh\n", CodeInfo->mem_type ));
1522         }
1523         j = SizeFromMemtype( CodeInfo->mem_type, CodeInfo->Ofssize, NULL );
1524         if ( ( j == 1 || j > 6 )
1525 #if AMD64_SUPPORT
1526             && ( CodeInfo->Ofssize != USE64 )
1527 #endif
1528         ) {
1529             /* CALL/JMP possible for WORD/DWORD/FWORD memory operands only */
1530             DebugMsg1(("memory_operand: invalid operand, size=%u\n", j ));
1531             return( EmitError( INVALID_OPERAND_SIZE ) );
1532         }
1533 
1534         if( opndx->mem_type == MT_FAR || CodeInfo->mem_type == MT_FWORD ||
1535 #if AMD64_SUPPORT
1536            ( CodeInfo->mem_type == MT_TBYTE && CodeInfo->Ofssize == USE64 ) ||
1537 #endif
1538             ( CodeInfo->mem_type == MT_DWORD &&
1539               (( CodeInfo->Ofssize == USE16 && opndx->Ofssize != USE32 ) ||
1540                ( CodeInfo->Ofssize == USE32 && opndx->Ofssize == USE16 )))) {
1541             CodeInfo->isfar = TRUE;
1542         }
1543         DebugMsg1(("memory_operand: JMP/CALL, CodeInfo->far=%u\n", CodeInfo->isfar ));
1544         break;
1545     }
1546 
1547     if ( ( CodeInfo->mem_type & MT_SPECIAL) == 0 ) {
1548         switch ( CodeInfo->mem_type & MT_SIZE_MASK ) {
1549             /* size is encoded 0-based */
1550         case  0:  CodeInfo->opnd[CurrOpnd].type = OP_M08;  break;
1551         case  1:  CodeInfo->opnd[CurrOpnd].type = OP_M16;  break;
1552         case  3:  CodeInfo->opnd[CurrOpnd].type = OP_M32;  break;
1553         case  5:  CodeInfo->opnd[CurrOpnd].type = OP_M48;  break;
1554         case  7:  CodeInfo->opnd[CurrOpnd].type = OP_M64;  break;
1555         case  9:  CodeInfo->opnd[CurrOpnd].type = OP_M80;  break;
1556         case 15:  CodeInfo->opnd[CurrOpnd].type = OP_M128; break;
1557 #if AVXSUPP
1558         case 31:  CodeInfo->opnd[CurrOpnd].type = OP_M256; break;
1559 #endif
1560 #ifdef DEBUG_OUT
1561         default:
1562             DebugMsg1(("memory_operand: unexpected mem_type=%X\n", CodeInfo->mem_type ));
1563             /**/myassert( 0 );
1564 #endif
1565         }
1566 #if 0 /* v2.06: the wide flag isn't set for memory operands currently, */
1567         if ( CodeInfo->opnd_type[CurrOpnd] & ( OP_M16 | OP_M32 | OP_M64 ) )
1568             CodeInfo->iswide = 1;
1569 #endif
1570     } else if ( CodeInfo->mem_type == MT_EMPTY ) {
1571         /* v2.05: added */
1572         switch ( CodeInfo->token ) {
1573         case T_INC:
1574         case T_DEC:
1575             /* jwasm v1.94-v2.04 accepted unsized operand for INC/DEC */
1576             if ( opndx->sym == NULL ) {
1577                 return( EmitError( INSTRUCTION_OPERAND_MUST_HAVE_SIZE ) );
1578             }
1579             break;
1580         case T_PUSH:
1581         case T_POP:
1582             if ( opndx->mem_type == MT_TYPE ) {
1583                 return( EmitError( INVALID_INSTRUCTION_OPERANDS ) );
1584             }
1585             break;
1586         }
1587     }
1588 
1589     base = ( opndx->base_reg ? opndx->base_reg->tokval : EMPTY );
1590     index = ( opndx->idx_reg ? opndx->idx_reg->tokval : EMPTY );
1591 
1592     /* use base + index from here - don't use opndx-> base_reg/idx_reg! */
1593 
1594 #if 0 /* v2.10: moved to expreval.c */
1595     if ( sym && sym->state == SYM_STACK ) {
1596         if( base != EMPTY ) {
1597             if( index != EMPTY ) {
1598                 /* no free index register */
1599                 return( EmitError( MULTIPLE_INDEX_REGISTERS_NOT_ALLOWED ) );
1600             } else {
1601                 index = base;
1602             }
1603         }
1604         base = basereg[CodeInfo->Ofssize];
1605     }
1606 #endif
1607 
1608     /* check for base registers */
1609 
1610     if ( base != EMPTY ) {
1611         if ( ( ( GetValueSp( base ) & OP_R32) && CodeInfo->Ofssize == USE32 ) ||
1612 #if AMD64_SUPPORT
1613             ( ( GetValueSp( base ) & OP_R64) && CodeInfo->Ofssize == USE64 ) ||
1614 #endif
1615             ( ( GetValueSp( base ) & OP_R16) && CodeInfo->Ofssize == USE16 ) )
1616             CodeInfo->prefix.adrsiz = FALSE;
1617         else {
1618             CodeInfo->prefix.adrsiz = TRUE;
1619 #if AMD64_SUPPORT
1620             /* 16bit addressing modes don't exist in long mode */
1621             if ( ( GetValueSp( base ) & OP_R16) && CodeInfo->Ofssize == USE64 ) {
1622                 return( EmitError( INVALID_ADDRESSING_MODE_WITH_CURRENT_CPU_SETTING ) );
1623             }
1624 #endif
1625         }
1626     }
1627 
1628     /* check for index registers */
1629 
1630     if( index != EMPTY ) {
1631         if ( ( ( GetValueSp( index ) & OP_R32) && CodeInfo->Ofssize == USE32 ) ||
1632 #if AMD64_SUPPORT
1633             ( ( GetValueSp( index ) & OP_R64) && CodeInfo->Ofssize == USE64 ) ||
1634 #endif
1635             ( ( GetValueSp( index ) & OP_R16) && CodeInfo->Ofssize == USE16 ) ) {
1636             CodeInfo->prefix.adrsiz = FALSE;
1637         } else {
1638             CodeInfo->prefix.adrsiz = TRUE;
1639 #if AMD64_SUPPORT /* v2.13: check added. see expr6.aso */
1640             /* 16bit addressing modes don't exist in long mode */
1641             if ( ( GetValueSp( index ) & OP_R16) && CodeInfo->Ofssize == USE64 ) {
1642                 return( EmitError( INVALID_ADDRESSING_MODE_WITH_CURRENT_CPU_SETTING ) );
1643             }
1644 #endif
1645         }
1646 
1647         /* v2.10: register swapping has been moved to expreval.c, index_connect().
1648          * what has remained here is the check if R/ESP is used as index reg.
1649          */
1650         if ( GetRegNo( index ) == 4 ) { /* [E|R]SP? */
1651             DebugMsg(( "memory_operand: error, base regno=%u, index regno=%u, opnd.scale=%u\n", GetRegNo( base ), GetRegNo( index ), opndx->scale ));
1652             //int tmp = index;
1653             if( opndx->scale ) { /* no scale must be set */
1654                 EmitErr( CANNOT_BE_USED_AS_INDEX_REGISTER, GetResWName( index, NULL ) );
1655                 //return( ERROR );
1656             } else {
1657             //if ( GetRegNo( base ) == 4 ) {
1658                 EmitErr( MULTIPLE_BASE_REGISTERS_NOT_ALLOWED );
1659                 //return( ERROR );
1660             }
1661             return( ERROR );
1662             /* swap base and index */
1663             //index = base;
1664             //base = tmp;
1665 #if 0
1666         } else if ( Options.masm_compat_gencode && opndx->scale == 0 && GetRegNo( base ) != 4 ) {
1667             /* v2.08: Masm 6+ swaps base and index, even if -Zm is set (Masm 5.1 does NOT swap) */
1668             int tmp = index;
1669             /* swap base and index */
1670             index = base;
1671             base = tmp;
1672 #endif
1673         }
1674 
1675         /* 32/64 bit indirect addressing? */
1676         if( ( CodeInfo->Ofssize == USE16 && CodeInfo->prefix.adrsiz == 1 ) ||
1677 #if AMD64_SUPPORT
1678            CodeInfo->Ofssize == USE64  ||
1679 #endif
1680            ( CodeInfo->Ofssize == USE32 && CodeInfo->prefix.adrsiz == 0 ) ) {
1681             if( ( ModuleInfo.curr_cpu & P_CPU_MASK ) >= P_386 ) {
1682                 /* scale, 0 or 1->00, 2->40, 4->80, 8->C0 */
1683                 switch( opndx->scale ) {
1684                 case 0:
1685                 case 1:  break; /* ss = 00 */
1686                 case 2: ss = SCALE_FACTOR_2; break; /* ss = 01 */
1687                 case 4: ss = SCALE_FACTOR_4; break; /* ss = 10 */
1688                 case 8: ss = SCALE_FACTOR_8; break; /* ss = 11 */
1689                 default: /* must be * 1, 2, 4 or 8 */
1690                     return( EmitError( SCALE_FACTOR_MUST_BE_1_2_4_OR_8 ) );
1691                 }
1692             } else {
1693                 /* 286 and down cannot use this memory mode */
1694                 return( EmitError( INVALID_ADDRESSING_MODE_WITH_CURRENT_CPU_SETTING ) );
1695             }
1696         } else {
1697             /* v2.01: 16-bit addressing mode. No scale possible */
1698             if ( opndx->scale ) {
1699                 return( EmitError( INVALID_USE_OF_REGISTER ) );
1700             }
1701         }
1702     }
1703 
1704     if( with_fixup ) {
1705 
1706         if( opndx->is_abs ) {
1707             Ofssize = IS_ADDR32( CodeInfo );
1708         } else if ( sym ) {
1709             Ofssize = GetSymOfssize( sym );
1710         } else if ( SegOverride ) {
1711             Ofssize = GetSymOfssize( SegOverride );
1712         } else
1713             Ofssize = CodeInfo->Ofssize;
1714 
1715         /* now set fixup_type.
1716          * for direct addressing, the fixup type can easily be set by
1717          * the symbol's offset size.
1718          */
1719         if( base == EMPTY && index == EMPTY ) {
1720             CodeInfo->prefix.adrsiz = ADDRSIZE( CodeInfo->Ofssize, Ofssize );
1721 #if AMD64_SUPPORT
1722             /* v2.13: also check CI->Ofssize. if current segm is 64-bit,
1723              * use 32-bit rel fixups (mixed mode 64-bit mz binary) - ignore Ofssize */
1724             //if ( Ofssize == USE64 )
1725             if (  Ofssize == USE64 || CodeInfo->Ofssize == USE64 )
1726                 /* v2.03: override with a segment assumed != FLAT? */
1727                 if ( opndx->override != NULL &&
1728                     SegOverride != &ModuleInfo.flat_grp->sym )
1729                     fixup_type = FIX_OFF32;
1730                 else
1731                     fixup_type = FIX_RELOFF32;
1732             else
1733 #endif
1734                 fixup_type = ( Ofssize ) ? FIX_OFF32 : FIX_OFF16;
1735             DebugMsg1(( "memory_operand: direct addressing, fixup type=%u\n", fixup_type ));
1736         } else {
1737             DebugMsg1(( "memory_operand: CodeInfo->Ofssize=%u/prefix.adrsize=%u, Ofssize=%u\n",
1738                       CodeInfo->Ofssize, CodeInfo->prefix.adrsiz, Ofssize ));
1739 #if AMD64_SUPPORT
1740             if( Ofssize == USE64 ) {
1741                 fixup_type = FIX_OFF32;
1742             } else
1743 #endif
1744             if( IS_ADDR32( CodeInfo ) ) { /* address prefix needed? */
1745                 /* changed for v1.95. Probably more tests needed!
1746                  * test case:
1747                  *   mov eax,[ebx*2-10+offset var] ;code and var are 16bit!
1748                  * the old code usually works fine because HiWord of the
1749                  * symbol's offset is zero. However, if there's an additional
1750                  * displacement which makes the value stored at the location
1751                  * < 0, then the target's HiWord becomes <> 0.
1752                  */
1753                 //fixup_type = ( Ofssize ) ? FIX_OFF32 : FIX_OFF16;
1754                 fixup_type = FIX_OFF32;
1755             } else {
1756                 fixup_type = FIX_OFF16;
1757                 if( Ofssize && Parse_Pass == PASS_2 ) {
1758                     /* address size is 16bit but label is 32-bit.
1759                      * example: use a 16bit register as base in FLAT model:
1760                      *   test buff[di],cl */
1761                     EmitWarn( 2, WORD_FIXUP_FOR_32BIT_LABEL, sym->name );
1762                 }
1763             }
1764         }
1765 
1766 #if IMAGERELSUPP || SECTIONRELSUPP /* v2.10: added; IMAGEREL/SECTIONREL for indirect memory operands */
1767         if ( fixup_type == FIX_OFF32 )
1768             if ( opndx->instr == T_IMAGEREL )
1769                 fixup_type = FIX_OFF32_IMGREL;
1770             else if ( opndx->instr == T_SECTIONREL )
1771                 fixup_type = FIX_OFF32_SECREL;
1772 #endif
1773         /* no fixups are needed for memory operands of string instructions and XLAT/XLATB.
1774          * However, CMPSD and MOVSD are also SSE2 opcodes, so the fixups must be generated
1775          * anyways.
1776          */
1777         if ( CodeInfo->token != T_XLAT && CodeInfo->token != T_XLATB ) {
1778             //DebugMsg1(("memory_operand: calling CreateFixup(%s, fixup=%u) [CodeInfo->memtype=%Xh]\n", sym ? sym->name : "NULL", fixup_type, CodeInfo->mem_type));
1779             CodeInfo->opnd[CurrOpnd].InsFixup = CreateFixup( sym, fixup_type, OPTJ_NONE );
1780         }
1781     }
1782 #ifdef DEBUG_OUT
1783     else
1784         DebugMsg1(("memory_operand: without fixup, CI->Ofssize=%u, adrsize=%u\n", CodeInfo->Ofssize, CodeInfo->prefix.adrsiz ));
1785 #endif
1786 
1787     if( set_rm_sib( CodeInfo, CurrOpnd, ss, index, base, sym ) == ERROR ) {
1788         return( ERROR );
1789     }
1790     /* set frame type/data in fixup if one was created */
1791     if ( CodeInfo->opnd[CurrOpnd].InsFixup ) {
1792         CodeInfo->opnd[CurrOpnd].InsFixup->frame_type = Frame_Type;
1793         CodeInfo->opnd[CurrOpnd].InsFixup->frame_datum = Frame_Datum;
1794     }
1795 
1796     DebugMsg1(("memory_operand exit, ok, opndx.type/value=%Xh/%Xh, CodeInfo.memtype/rmbyte=%X/%X opndtype=%Xh fix=%Xh\n",
1797               opndx->type, opndx->value, CodeInfo->mem_type, CodeInfo->rm_byte, CodeInfo->opnd[CurrOpnd].type, CodeInfo->opnd[CurrOpnd].InsFixup ));
1798     return( NOT_ERROR );
1799 }
1800 
process_address(struct code_info * CodeInfo,unsigned CurrOpnd,struct expr * opndx)1801 static ret_code process_address( struct code_info *CodeInfo, unsigned CurrOpnd, struct expr *opndx )
1802 /**************************************************************************************************/
1803 /*
1804  * parse the memory reference operand
1805  * CurrOpnd is 0 for first operand, 1 for second, ...
1806  * valid return values: NOT_ERROR, ERROR
1807  */
1808 {
1809     if( opndx->indirect ) {  /* indirect register operand or stack var */
1810 
1811         DebugMsg1(("process_address: INDIRECT, sym=%s mbr=%s ci.adrsiz=%u\n",
1812                    opndx->sym ? opndx->sym->name : "NULL",
1813                    opndx->mbr ? opndx->mbr->name : "NULL",
1814                    CodeInfo->prefix.adrsiz ));
1815         /* if displacement doesn't fit in 32-bits:
1816          * Masm (both ML and ML64) just truncates.
1817          * JWasm throws an error in 64bit mode and
1818          * warns (level 3) in the other modes.
1819          * todo: this check should also be done for direct addressing!
1820          */
1821         if ( opndx->hvalue && ( opndx->hvalue != -1 || opndx->value >= 0 ) ) {
1822             DebugMsg1(("process_address: displacement doesn't fit in 32 bits: %" I64_SPEC "X\n", opndx->value64 ));
1823 #if AMD64_SUPPORT
1824             if ( ModuleInfo.Ofssize == USE64 ) {
1825                 return( EmitConstError( opndx ) );
1826             }
1827 #endif
1828             if( Parse_Pass == PASS_1 ) /* v2.13: don't warn multiple times */
1829                 EmitWarn( 3, DISPLACEMENT_OUT_OF_RANGE, opndx->value64 );
1830         }
1831         if( opndx->sym == NULL || opndx->sym->state == SYM_STACK ) {
1832             return( memory_operand( CodeInfo, CurrOpnd, opndx, FALSE ) );
1833         }
1834         /* do default processing */
1835 
1836     } else if( opndx->instr != EMPTY ) {
1837         /* instr is OFFSET | LROFFSET | SEG | LOW | LOWWORD, ... */
1838         DebugMsg1(("process_address: instr=%s\n", GetResWName( opndx->instr, NULL ) ));
1839         /* v2.15 create fixup if override is given */
1840         //if( opndx->sym == NULL ) { /* better to check opndx->type? */
1841         if( opndx->sym == NULL && ( opndx->override == NULL || opndx->override->token == T_REG )) {
1842             return( idata_nofixup( CodeInfo, CurrOpnd, opndx ) );
1843         } else {
1844             /* allow "lea <reg>, [offset <sym>]" */
1845             if( CodeInfo->token == T_LEA && opndx->instr == T_OFFSET )
1846                 return( memory_operand( CodeInfo, CurrOpnd, opndx, TRUE ) );
1847             return( idata_fixup( CodeInfo, CurrOpnd, opndx ) );
1848         }
1849     } else if( opndx->sym == NULL ) { /* direct operand without symbol */
1850         DebugMsg1(("process_address: symbol=NULL\n" ));
1851         if( opndx->override != NULL ) {
1852             /* direct absolute memory without symbol.
1853              DS:[0] won't create a fixup, but
1854              DGROUP:[0] will create one! */
1855 #if AMD64_SUPPORT
1856             /* for 64bit, always create a fixup, since RIP-relative addressing is used
1857              * v2.11: don't create fixup in 64-bit.
1858              */
1859             //if ( opndx->override->token == T_REG && CodeInfo->Ofssize != USE64 )
1860             if ( opndx->override->token == T_REG || CodeInfo->Ofssize == USE64 )
1861 #else
1862             if ( opndx->override->token == T_REG )
1863 #endif
1864                 return( memory_operand( CodeInfo, CurrOpnd, opndx, FALSE ) );
1865             else
1866                 return( memory_operand( CodeInfo, CurrOpnd, opndx, TRUE ) );
1867         } else {
1868             return( idata_nofixup( CodeInfo, CurrOpnd, opndx ) );
1869         }
1870     } else if( ( opndx->sym->state == SYM_UNDEFINED ) && !opndx->explicit ) {
1871         DebugMsg1(("process_address: sym=SYM_UNDEFINED, name=%s, state=%X\n", opndx->sym->name, opndx->sym->state ));
1872         /* v2.04: unnecessary, the expression evaluator will have emitted an error already */
1873         //if( Parse_Pass != PASS_1 ) {
1874         //    EmitErr( SYMBOL_NOT_DEFINED, opndx->sym->name );
1875         //    return( ERROR );
1876         //}
1877         /* undefined symbol, it's not possible to determine
1878          * operand type and size currently. However, for backpatching
1879          * a fixup should be created.
1880          */
1881         /* assume a code label for branch instructions! */
1882         if( IS_ANY_BRANCH( CodeInfo->token ) )
1883             return( process_branch( CodeInfo, CurrOpnd, opndx ) );
1884 
1885         switch( CodeInfo->token ) {
1886         case T_PUSH:
1887         case T_PUSHW:
1888         case T_PUSHD:
1889             /* v2.0: don't assume immediate operand if cpu is 8086 */
1890             if ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) > P_86 ) {
1891                 //return( idata_nofixup( CodeInfo, opndx ) ); /* v1.96: changed */
1892                 return( idata_fixup( CodeInfo, CurrOpnd, opndx ) );
1893             }
1894             break;
1895         default:
1896             /* v2.04: if operand is the second argument (and the first is NOT
1897              * a segment register!), scan the
1898              * instruction table if the instruction allows an immediate!
1899              * If so, assume the undefined symbol is a constant.
1900              */
1901             if ( CurrOpnd == OPND2 && (( CodeInfo->opnd[OPND1].type & OP_SR ) == 0 ) ) {
1902                 const struct instr_item  *p = CodeInfo->pinstr;
1903                 do {
1904                     if ( opnd_clstab[p->opclsidx].opnd_type[OPND2] & OP_I ) {
1905                         return( idata_fixup( CodeInfo, CurrOpnd, opndx ) );
1906                     }
1907                     p++;
1908                 } while ( p->first == FALSE );
1909             }
1910             /* v2.10: if current operand is the third argument, always assume an immediate */
1911             if ( CurrOpnd == OPND3 )
1912                 return( idata_fixup( CodeInfo, CurrOpnd, opndx ) );
1913         }
1914         /* do default processing */
1915 
1916     } else if( ( opndx->sym->state == SYM_SEG ) ||
1917                ( opndx->sym->state == SYM_GRP ) ) {
1918         DebugMsg1(("process_address: sym->state=SEG/GROUP\n"));
1919         /* SEGMENT and GROUP symbol is converted to SEG symbol
1920          * for next processing */
1921         opndx->instr = T_SEG;
1922         return( idata_fixup( CodeInfo, CurrOpnd, opndx ) );
1923     } else {
1924         DebugMsg1(("process_address direct, sym=%s sym.memtype=%X opndx.memtype=%X\n", opndx->sym->name, opndx->sym->mem_type, opndx->mem_type ));
1925 
1926         /* symbol external, but absolute? */
1927         if( opndx->is_abs ) {
1928             return( idata_fixup( CodeInfo, CurrOpnd, opndx ) );
1929         }
1930 
1931         /* CODE location is converted to OFFSET symbol */
1932         if ( opndx->mem_type == MT_NEAR || opndx->mem_type == MT_FAR ) {
1933             if( CodeInfo->token == T_LEA ) {
1934                 return( memory_operand( CodeInfo, CurrOpnd, opndx, TRUE ) );
1935             //} else if( opndx->sym == &symPC ) {
1936             //    return( idata_fixup( CodeInfo, opndx ) );
1937             } else if( opndx->mbr != NULL ) { /* structure field? */
1938                 return( memory_operand( CodeInfo, CurrOpnd, opndx, TRUE ) );
1939             } else {
1940                 return( idata_fixup( CodeInfo, CurrOpnd, opndx ) );
1941             }
1942         }
1943     }
1944     /* default processing: memory with fixup */
1945     return( memory_operand( CodeInfo, CurrOpnd, opndx, TRUE ) );
1946 }
1947 
1948 /* Handle constant operands.
1949  * These never need a fixup. Externals - even "absolute" ones -
1950  * are always labeled as EXPR_ADDR by the expression evaluator.
1951  */
process_const(struct code_info * CodeInfo,unsigned CurrOpnd,struct expr * opndx)1952 static ret_code process_const( struct code_info *CodeInfo, unsigned CurrOpnd, struct expr *opndx )
1953 /************************************************************************************************/
1954 {
1955 #if 0 /* v2.06: obsolete */
1956     /* hack for IMUL: compress the operands so there are 2 only */
1957     if( ( CodeInfo->token == T_IMUL ) &&
1958        ( CodeInfo->opnd_type[OPND1] & OP_R ) ) {
1959         if( CurrOpnd == OPND2 ) {
1960 #if AMD64_SUPPORT
1961             CodeInfo->prefix.rex |= ((CodeInfo->prefix.rex & REX_B) ? REX_R : 0);
1962 #endif
1963             CodeInfo->rm_byte = ( CodeInfo->rm_byte & ~BIT_345 )
1964                           | ( ( CodeInfo->rm_byte & BIT_012 ) << 3 );
1965         } else if( CurrOpnd == OPND3 ) {
1966             /* v2.04b: if op2 was assumed an immediate due to fwd ref,
1967              * change it back to a mem ref now.
1968              */
1969             if ( ( CodeInfo->opnd_type[OPND2] & OP_I ) &&
1970                 CodeInfo->InsFixup[OPND2] &&
1971                 CodeInfo->InsFixup[OPND2]->sym->state == SYM_UNDEFINED )
1972                 CodeInfo->opnd_type[OPND2] = OP_M;
1973             CodeInfo->opnd_type[OPND1] = CodeInfo->opnd_type[OPND2];
1974             CodeInfo->opnd_type[OPND2] = OP_NONE;
1975             CodeInfo->data[OPND1] = CodeInfo->data[OPND2];
1976             CodeInfo->data[OPND2] = 0;
1977             CodeInfo->InsFixup[OPND1] = CodeInfo->InsFixup[OPND2];
1978             CodeInfo->InsFixup[OPND2] = NULL;
1979             CurrOpnd = OPND2;
1980         }
1981     }
1982 #endif
1983     /* v2.11: don't accept an empty string */
1984     if ( opndx->quoted_string && opndx->quoted_string->stringlen == 0 )
1985         return( EmitError( EMPTY_STRING ) );
1986 
1987     /* optimization: skip <value> if it is 0 and instruction
1988      * is RET[W|D|N|F]. */
1989     /* v2.06: moved here and checked the opcode directly, so
1990      * RETD and RETW are also handled. */
1991     if ( ( ( CodeInfo->pinstr->opcode & 0xf7 ) == 0xc2 ) &&
1992         CurrOpnd == OPND1 && opndx->value == 0 ) {
1993         //     (CodeInfo.token == T_RET ||
1994         //      CodeInfo.token == T_RETN ||
1995         //      CodeInfo.token == T_RETF)) {
1996         //if ( opndx.sym == NULL || opndx.sym->state == SYM_INTERNAL ) {
1997         return( NOT_ERROR );
1998     }
1999     return( idata_nofixup( CodeInfo, CurrOpnd, opndx ) );
2000 }
2001 
process_register(struct code_info * CodeInfo,unsigned CurrOpnd,const struct expr opndx[])2002 static ret_code process_register( struct code_info *CodeInfo, unsigned CurrOpnd, const struct expr opndx[] )
2003 /**********************************************************************************************************/
2004 /*
2005  * parse and encode direct register operands. Modifies:
2006  * - CodeInfo->opnd_type
2007  * - CodeInfo->rm_byte (depending on CurrOpnd)
2008  * - CodeInfo->iswide
2009  * - CodeInfo->x86hi_used/x64lo_used
2010  * - CodeInfo->prefix.rex
2011  */
2012 {
2013     enum special_token regtok;
2014     int  regno;
2015     uint_32 flags;
2016 
2017     DebugMsg1(( "process_register enter (%s)\n", opndx[CurrOpnd].base_reg->string_ptr ));
2018     regtok = opndx[CurrOpnd].base_reg->tokval;
2019     regno = GetRegNo( regtok );
2020     /* the register's "OP-flags" are stored in the 'value' field */
2021     flags = GetValueSp( regtok );
2022     CodeInfo->opnd[CurrOpnd].type = flags;
2023     if ( flags & OP_R8 ) {
2024         /* it's probably better to not reset the wide bit at all */
2025         if ( flags != OP_CL )      /* problem: SHL AX|AL, CL */
2026             CodeInfo->iswide = 0;
2027 
2028 #if AMD64_SUPPORT
2029         if ( CodeInfo->Ofssize == USE64 && regno >=4 && regno <=7 )
2030             if ( SpecialTable[regtok].cpu == P_86 )
2031                 CodeInfo->x86hi_used = 1; /* it's AH,BH,CH,DH */
2032             else
2033                 CodeInfo->x64lo_used = 1; /* it's SPL,BPL,SIL,DIL */
2034 #endif
2035         if ( StdAssumeTable[regno].error & (( regtok >= T_AH && regtok <= T_BH ) ? RH_ERROR : RL_ERROR ) ) {
2036             DebugMsg(("process_register: assume error, reg=%u\n", regno ));
2037             return( EmitError( USE_OF_REGISTER_ASSUMED_TO_ERROR ) );
2038         }
2039     } else if ( flags & OP_R ) { /* 16-, 32- or 64-bit GPR? */
2040         CodeInfo->iswide = 1;
2041         if ( StdAssumeTable[regno].error & flags & OP_R ) {
2042             DebugMsg(("process_register: assume error, reg=%u\n", regno ));
2043             return( EmitError( USE_OF_REGISTER_ASSUMED_TO_ERROR ) );
2044         }
2045         if ( flags & OP_R16 ) {
2046             if ( CodeInfo->Ofssize > USE16 )
2047                 CodeInfo->prefix.opsiz = TRUE;
2048         } else {
2049             if( CodeInfo->Ofssize == USE16 )
2050                 CodeInfo->prefix.opsiz = TRUE;
2051         }
2052     } else if ( flags & OP_SR ) {
2053         if( regno == 1 ) { /* 1 is CS */
2054             /* POP CS is not allowed */
2055             if( CodeInfo->token == T_POP ) {
2056                 return( EmitError( POP_CS_IS_NOT_ALLOWED ) );
2057             }
2058         }
2059     } else if ( flags & OP_ST ) {
2060 
2061         regno = opndx[CurrOpnd].st_idx;
2062         if ( regno > 7 ) { /* v1.96: index check added */
2063             return( EmitError( INVALID_COPROCESSOR_REGISTER ) );
2064         }
2065         CodeInfo->rm_byte |= regno;
2066         if( regno != 0 )
2067             CodeInfo->opnd[CurrOpnd].type = OP_ST_REG;
2068         /* v2.06: exit, rm_byte is already set. */
2069         return( NOT_ERROR );
2070 
2071     } else if ( flags & OP_RSPEC ) { /* CRx, DRx, TRx */
2072         if( CodeInfo->token != T_MOV ) {
2073             return( EmitError( ONLY_MOV_CAN_USE_SPECIAL_REGISTER ) );
2074         }
2075         /* v2.04: previously there were 3 flags, OP_CR, OP_DR and OP_TR.
2076          * this was summoned to one flag OP_RSPEC to free 2 flags, which
2077          * are needed if AVC ( new YMM registers ) is to be supported.
2078          * To distinguish between CR, DR and TR, the register number is
2079          * used now: CRx are numbers 0-F, DRx are numbers 0x10-0x1F and
2080          * TRx are 0x20-0x2F.
2081          */
2082         if ( regno >= 0x20 ) { /* TRx? */
2083             CodeInfo->opc_or |= 0x04;
2084             /* TR3-TR5 are available on 486-586
2085              * TR6+TR7 are available on 386-586
2086              * v2.11: simplified.
2087              */
2088             if( ( ModuleInfo.curr_cpu & P_CPU_MASK ) >= P_686 ) {
2089                 return( EmitErr( CANNOT_USE_TRN_TO_TRM_WITH_CURRENT_CPU_SETTING, regno > 0x25 ? 6 : 3, regno > 0x25 ? 7 : 5 ) );
2090             }
2091         } else if ( regno >= 0x10 ) { /* DRx? */
2092             CodeInfo->opc_or |= 0x01;
2093         }
2094         regno &= 0x0F;
2095     }
2096 
2097 #if AMD64_SUPPORT
2098     /* if it's a x86-64 register (SIL, R8W, R8D, RSI, ... */
2099     if ( ( SpecialTable[regtok].cpu & P_CPU_MASK ) == P_64 ) {
2100         CodeInfo->prefix.rex |= 0x40;
2101         if ( flags & OP_R64 )
2102             CodeInfo->prefix.rex |= REX_W;
2103     }
2104 #endif
2105 
2106     if( CurrOpnd == OPND1 ) {
2107         /* the first operand
2108          * r/m is treated as a 'reg' field */
2109         CodeInfo->rm_byte |= MOD_11;
2110 #if AMD64_SUPPORT
2111         CodeInfo->prefix.rex |= (regno & 8 ) >> 3; /* set REX_B */
2112         regno &= BIT_012;
2113 #endif
2114         /* fill the r/m field */
2115         CodeInfo->rm_byte |= regno;
2116     } else {
2117         /* the second operand
2118          * XCHG can use short form if op1 is AX/EAX/RAX */
2119         if( ( CodeInfo->token == T_XCHG ) && ( CodeInfo->opnd[OPND1].type & OP_A ) &&
2120              ( 0 == (CodeInfo->opnd[OPND1].type & OP_R8 ) ) ) {
2121 #if AMD64_SUPPORT
2122             CodeInfo->prefix.rex |= (regno & 8 ) >> 3; /* set REX_B */
2123             regno &= BIT_012;
2124 #endif
2125             CodeInfo->rm_byte = ( CodeInfo->rm_byte & BIT_67 ) | regno;
2126         } else {
2127             /* fill reg field with reg */
2128 #if AMD64_SUPPORT
2129             CodeInfo->prefix.rex |= (regno & 8 ) >> 1; /* set REX_R */
2130             regno &= BIT_012;
2131 #endif
2132             CodeInfo->rm_byte = ( CodeInfo->rm_byte & ~BIT_345 ) | ( regno << 3 );
2133         }
2134     }
2135     return( NOT_ERROR );
2136 }
2137 
2138 /* v2.14: check if variable is accessible thru ES */
2139 
IsAccessible(struct asym * sym,enum assume_segreg sr)2140 static bool IsAccessible( struct asym *sym, enum assume_segreg sr )
2141 /*****************************************************************/
2142 {
2143     if ( sym->segment && SegAssumeTable[sr].symbol )
2144         if ( sym->segment != SegAssumeTable[sr].symbol && GetGroup( sym ) != SegAssumeTable[sr].symbol )
2145             return( FALSE );
2146     return( TRUE );
2147 }
2148 
2149 /* special handling for string instructions
2150  * CMPS[B|W|D|Q]
2151  *  INS[B|W|D]
2152  * LODS[B|W|D|Q]
2153  * MOVS[B|W|D|Q]
2154  * OUTS[B|W|D]
2155  * SCAS[B|W|D|Q]
2156  * STOS[B|W|D|Q]
2157  * the peculiarity is that these instructions ( optionally )
2158  * have memory operands, which aren't used for code generation
2159  * <opndx> contains the last operand.
2160  */
2161 
HandleStringInstructions(struct code_info * CodeInfo,const struct expr opndx[])2162 static void HandleStringInstructions( struct code_info *CodeInfo, const struct expr opndx[] )
2163 /*******************************************************************************************/
2164 {
2165     int opndidx = OPND1;
2166     int op_size;
2167 
2168     /* v2.14: added quite a few checks. It works, but the source needs some cleanup now. */
2169 
2170     switch( CodeInfo->token ) {
2171 #if AVXSUPP
2172     case T_VCMPSD:
2173 #endif
2174     case T_CMPSD:
2175         /* filter SSE2 opcode CMPSD */
2176         if ( CodeInfo->opnd[OPND1].type & (OP_XMM | OP_MMX)) {
2177             /* v2.01: QWORD operand for CMPSD/MOVSD may have set REX_W! */
2178 #if AMD64_SUPPORT
2179             CodeInfo->prefix.rex &= ~REX_W;
2180 #endif
2181             return;
2182         }
2183         /* fall through */
2184     case T_CMPS:
2185     case T_CMPSB:
2186     case T_CMPSW:
2187 #if AMD64_SUPPORT
2188     case T_CMPSQ:
2189 #endif
2190         /* v2.14: reject segment != ES for second op if symbolic */
2191         if ( CodeInfo->opnd[OPND2].type != OP_NONE && opndx[OPND2].override == NULL && opndx[OPND2].sym ) {
2192             if (!IsAccessible( opndx[OPND2].sym, ASSUME_ES )) {
2193                 EmitError( INVALID_INSTRUCTION_OPERANDS );
2194                 break;
2195             }
2196         }
2197          /* cmps allows prefix for the first operand (=source) only */
2198         if ( CodeInfo->prefix.RegOverride != ASSUME_NOTHING ) {
2199             if ( opndx[OPND2].override != NULL ) {
2200                 if ( CodeInfo->prefix.RegOverride == ASSUME_ES ) {
2201                     /* content of LastRegOverride is valid if
2202                      * CodeInfo->RegOverride is != EMPTY.
2203                      */
2204                     if ( LastRegOverride == ASSUME_DS )
2205                         CodeInfo->prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2206                     else
2207                         CodeInfo->prefix.RegOverride = LastRegOverride;
2208                 } else {
2209                     DebugMsg1(("HandleStringInstructions: CMPS: CodeInfo->RegOverride=%X, opndx->override=%s\n", CodeInfo->prefix.RegOverride, opndx[OPND2].override->string_ptr ));
2210                     EmitError( INVALID_INSTRUCTION_OPERANDS );
2211                 }
2212             }
2213         } else if ( CodeInfo->opnd[OPND1].type != OP_NONE && /* v2.14 */
2214                    opndx[OPND1].override == NULL &&
2215                    opndx[OPND1].sym ) {
2216             check_assume( CodeInfo, opndx[OPND1].sym, ASSUME_DS );
2217         }
2218         if ( CodeInfo->prefix.RegOverride == ASSUME_DS ) {
2219             CodeInfo->prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2220         }
2221         break;
2222 #if AVXSUPP
2223     case T_VMOVSD:
2224 #endif
2225     case T_MOVSD:
2226         /* filter SSE2 opcode MOVSD */
2227         if ( ( CodeInfo->opnd[OPND1].type & (OP_XMM | OP_MMX) ) ||
2228             ( CodeInfo->opnd[OPND2].type & (OP_XMM | OP_MMX) ) ) {
2229             /* v2.01: QWORD operand for CMPSD/MOVSD may have set REX_W! */
2230 #if AMD64_SUPPORT
2231             CodeInfo->prefix.rex &= ~REX_W;
2232 #endif
2233             return;
2234         }
2235         /* fall through */
2236     case T_MOVS:
2237     case T_MOVSB:
2238     case T_MOVSW:
2239 #if AMD64_SUPPORT
2240     case T_MOVSQ:
2241 #endif
2242         /* v2.14: reject segment != ES for first op if symbolic */
2243         if ( CodeInfo->opnd[OPND1].type != OP_NONE && opndx[OPND1].override == NULL && opndx[OPND1].sym ) {
2244             if (!IsAccessible( opndx[OPND1].sym, ASSUME_ES )) {
2245                 EmitError( INVALID_INSTRUCTION_OPERANDS );
2246                 break;
2247             }
2248         }
2249         /* MOVSx allows prefix for the second operand (=source) only.
2250          * there's only one place to store the register override in CodeInfo,
2251          * so it's a problem if both operands have an override; to be improved.
2252          */
2253         if ( CodeInfo->prefix.RegOverride != ASSUME_NOTHING ) {/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2254 #if 1 /* v2.14: destination must be ES: */
2255             if ( opndx[OPND1].override && opndx[OPND1].override->token == T_REG && opndx[OPND1].override->tokval != T_ES ) {
2256                 DebugMsg1(("HandleStringInstructions: MOVS: CodeInfo->RegOverride=%X, opndx->override=%s\n", CodeInfo->prefix.RegOverride, opndx[OPND1].override->string_ptr ));
2257                 EmitError( INVALID_INSTRUCTION_OPERANDS );
2258             } else
2259 #endif
2260             if ( opndx[OPND2].override == NULL ) {
2261                 /* v2.14: "if block" added */
2262                 if ( CodeInfo->prefix.RegOverride == ASSUME_ES )
2263                     CodeInfo->prefix.RegOverride = ASSUME_NOTHING;
2264                 else {
2265                     DebugMsg(("HandleStringInstructions: MOVS: override==NULL for second operand\n" ));
2266                     EmitError( INVALID_INSTRUCTION_OPERANDS );
2267                 }
2268             } //else if ( CodeInfo->prefix.RegOverride == ASSUME_DS )
2269               //  CodeInfo->prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2270         } else if ( CodeInfo->opnd[OPND2].type != OP_NONE && /* v2.14 */
2271                    opndx[OPND2].override == NULL &&
2272                    opndx[OPND2].sym ) {
2273             check_assume( CodeInfo, opndx[OPND2].sym, ASSUME_DS );
2274         }
2275         if ( CodeInfo->prefix.RegOverride == ASSUME_DS )
2276             CodeInfo->prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2277         break;
2278     case T_OUTS:
2279     case T_OUTSB:
2280     case T_OUTSW:
2281     case T_OUTSD:
2282         /* v2.14 */
2283         if ( CodeInfo->opnd[OPND2].type != OP_NONE && opndx[OPND2].override == NULL && opndx[OPND2].sym )
2284             check_assume( CodeInfo, opndx[OPND2].sym, ASSUME_DS );
2285         /* v2.01: remove default DS prefix */
2286         if ( CodeInfo->prefix.RegOverride == ASSUME_DS )
2287             CodeInfo->prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2288         opndidx = OPND2;
2289         break;
2290     case T_LODS:
2291     case T_LODSB:
2292     case T_LODSW:
2293     case T_LODSD:
2294 #if AMD64_SUPPORT
2295     case T_LODSQ:
2296 #endif
2297         /* v2.14 */
2298         if ( CodeInfo->opnd[OPND1].type != OP_NONE && opndx[OPND1].override == NULL && opndx[OPND1].sym )
2299             check_assume( CodeInfo, opndx[OPND1].sym, ASSUME_DS );
2300         /* v2.10: remove unnecessary DS prefix ( Masm-compatible ) */
2301         if ( CodeInfo->prefix.RegOverride == ASSUME_DS )
2302             CodeInfo->prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2303         break;
2304     default: /*INS[B|W|D], SCAS[B|W|D|Q], STOS[B|W|D|Q] */
2305         /* INSx, SCASx and STOSx don't allow any segment prefix != ES
2306          for the memory operand.
2307          */
2308         /* v2.14: check added to reject invalid segment assumes */
2309         if ( CodeInfo->opnd[OPND1].type != OP_NONE && opndx[OPND1].override == NULL && opndx[OPND1].sym ) {
2310             DebugMsg1(("HandleStringInstructions: INS,SCAS,STOS: opndx->sym=%s\n", opndx[OPND1].sym->name ));
2311             if (!IsAccessible( opndx[OPND1].sym, ASSUME_ES )) {
2312                 EmitError( INVALID_INSTRUCTION_OPERANDS );
2313                 break;
2314             }
2315         }
2316         if ( CodeInfo->prefix.RegOverride != ASSUME_NOTHING )
2317             if ( CodeInfo->prefix.RegOverride == ASSUME_ES )
2318                 CodeInfo->prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
2319             else
2320                 EmitError( INVALID_INSTRUCTION_OPERANDS );
2321     }
2322 
2323     if ( opnd_clstab[CodeInfo->pinstr->opclsidx].opnd_type[opndidx] == OP_NONE ) {
2324         CodeInfo->iswide = 0;
2325         CodeInfo->prefix.opsiz = FALSE;
2326     }
2327 
2328     /* if the instruction is the variant without suffix (MOVS, LODS, ..),
2329      * then use the operand's size to get further info.
2330      */
2331     //if ( CodeInfo->pinstr->opnd_type[opndidx] != OP_NONE &&
2332     if ( opnd_clstab[CodeInfo->pinstr->opclsidx].opnd_type[opndidx] != OP_NONE &&
2333         CodeInfo->opnd[opndidx].type != OP_NONE ) {
2334         op_size = OperandSize( CodeInfo->opnd[opndidx].type, CodeInfo );
2335         /* v2.06: added. if memory operand has no size */
2336         if ( op_size == 0 ) {
2337             if ( CodeInfo->opnd[opndidx].InsFixup == NULL || CodeInfo->opnd[opndidx].InsFixup->sym->state != SYM_UNDEFINED )
2338                 EmitError( INSTRUCTION_OPERAND_MUST_HAVE_SIZE );
2339             op_size = 1; /* assume shortest format */
2340         }
2341         switch( op_size ) {
2342         case 1:
2343             CodeInfo->iswide = 0;
2344             //if( CodeInfo->Ofssize )
2345                 CodeInfo->prefix.opsiz = FALSE;
2346             break;
2347         case 2:
2348             CodeInfo->iswide = 1;
2349             CodeInfo->prefix.opsiz = CodeInfo->Ofssize ? TRUE : FALSE;
2350             break;
2351         case 4:
2352             CodeInfo->iswide = 1;
2353             CodeInfo->prefix.opsiz = CodeInfo->Ofssize ? FALSE : TRUE;
2354             break;
2355 #if AMD64_SUPPORT
2356         case 8:
2357             if ( CodeInfo->Ofssize == USE64 ) {
2358                 CodeInfo->iswide = 1;
2359                 CodeInfo->prefix.opsiz = FALSE;
2360                 CodeInfo->prefix.rex = REX_W;
2361             }
2362             break;
2363 #endif
2364         }
2365     }
2366     return;
2367 }
2368 
check_size(struct code_info * CodeInfo,const struct expr opndx[])2369 static ret_code check_size( struct code_info *CodeInfo, const struct expr opndx[] )
2370 /*********************************************************************************/
2371 /*
2372  * - use to make sure the size of first operand match the size of second operand;
2373  * - optimize MOV instruction;
2374  * - opndx contains last operand
2375  * todo: BOUND second operand check ( may be WORD/DWORD or DWORD/QWORD ).
2376  * tofix: add a flag in instr_table[] if there's NO check to be done.
2377  */
2378 {
2379     enum operand_type op1 = CodeInfo->opnd[OPND1].type;
2380     enum operand_type op2 = CodeInfo->opnd[OPND2].type;
2381     ret_code    rc = NOT_ERROR;
2382     int         op1_size;
2383     int         op2_size;
2384     //int         op_size = 0;
2385 
2386     DebugMsg1(("check_size enter, optype1=%" I32_SPEC "X, optype2=%" I32_SPEC "X\n", op1, op2 ));
2387     switch( CodeInfo->token ) {
2388     case T_IN:
2389         if( op2 == OP_DX ) {
2390             /* wide and size is NOT determined by DX, but
2391              * by the first operand, AL|AX|EAX
2392              */
2393             switch( op1 ) {
2394             case OP_AX:
2395                 break;
2396             case OP_AL:
2397                 CodeInfo->iswide = 0;         /* clear w-bit */
2398             case OP_EAX:
2399                 if( CodeInfo->Ofssize ) {
2400                     CodeInfo->prefix.opsiz = FALSE;
2401                 }
2402                 break;
2403             }
2404         }
2405         break;
2406     case T_OUT:
2407         if( op1 == OP_DX ) {
2408             switch( op2 ) {
2409             case OP_AX:
2410                 break;
2411             case OP_AL:
2412                 CodeInfo->iswide = 0;         /* clear w-bit */
2413             case OP_EAX:
2414                 if( CodeInfo->Ofssize ) {
2415                     CodeInfo->prefix.opsiz = FALSE;
2416                 }
2417             }
2418         }
2419         break;
2420     case T_LEA:
2421 #if 0
2422         /* first op must be 16/32 register, but this condition is checked
2423          in CodeGen. operands 1 and 2 can be mixed:
2424          lea cx,[bp]
2425          lea cx,[ebp]
2426          lea ecx,[bp]
2427          lea ecx,[ebp]
2428          are all valid. However, Masm sometimes complains
2429          "cannot use 16-bit register with a 32-bit address"
2430          */
2431         switch( OperandSize( op1, CodeInfo ) ) {
2432         case 2:
2433         case 4:
2434             break;
2435         default:
2436             EmitErr( OPERANDS_MUST_BE_THE_SAME_SIZE, OperandSize( op1, CodeInfo ), ModuleInfo.Ofssize ? 4 : 2);
2437             rc = ERROR;
2438         }
2439 #endif
2440         break;
2441     case T_RCL:
2442     case T_RCR:
2443     case T_ROL:
2444     case T_ROR:
2445     case T_SAL:
2446     case T_SAR:
2447     case T_SHL:
2448     case T_SHR:
2449         /* v2.11: added */
2450         if ( CodeInfo->opnd[OPND1].type == OP_M && CodeInfo->undef_sym == FALSE &&
2451             ( opndx[OPND1].sym == NULL || opndx[OPND1].sym->state != SYM_UNDEFINED ) ) {
2452             EmitErr( INSTRUCTION_OPERAND_MUST_HAVE_SIZE );
2453             rc = ERROR;
2454             break;
2455         }
2456         //if ( CodeInfo->opnd[OPND1].type == OP_M && Parse_Pass == PASS_2 )
2457         //    EmitWarn( 2, SIZE_NOT_SPECIFIED_ASSUMING, "BYTE" );
2458 
2459         /* v2.0: if second argument is a forward reference,
2460          * change type to "immediate 1"
2461          */
2462         if ( opndx[OPND2].kind == EXPR_ADDR &&
2463             Parse_Pass == PASS_1 &&
2464             opndx[OPND2].indirect == FALSE &&
2465             opndx[OPND2].sym &&
2466             opndx[OPND2].sym->state == SYM_UNDEFINED ) {
2467             CodeInfo->opnd[OPND2].type = OP_I8;
2468             CodeInfo->opnd[OPND2].data32l = 1;
2469         }
2470         /* v2.06: added (because if first operand is memory, wide bit
2471          * isn't set!)
2472          */
2473         if ( OperandSize( op1, CodeInfo ) > 1 )
2474             CodeInfo->iswide = 1;
2475         /* v2.06: makes the OP_CL_ONLY case in codegen.c obsolete */
2476         if ( op2 == OP_CL ) {
2477             /* CL is encoded in bit 345 of rm_byte, but we don't need it
2478              * so clear it here */
2479             CodeInfo->rm_byte &= NOT_BIT_345;
2480         }
2481         break;
2482     case T_LDS:
2483     case T_LES:
2484     case T_LFS:
2485     case T_LGS:
2486     case T_LSS:
2487         op1_size = OperandSize( op1, CodeInfo ) + 2; /* add 2 for the impl. segment register */
2488         op2_size = OperandSize( op2, CodeInfo );
2489         if ( op2_size != 0 && op1_size != op2_size ) {
2490             return( EmitError( INVALID_OPERAND_SIZE ) );
2491         }
2492         break;
2493     case T_ENTER:
2494 #if 0 /* v2.11: operand sizes are checked in codegen */
2495         /* ENTER has to be OP_I16, OP_I8_U */
2496         if( op1 == OP_I32 ) {
2497             /* parse_phase_1 will treat 16-bit data as OP_I32 if CPU is 386 */
2498             if( CodeInfo->opnd[OPND1].data32l > (int_32)USHRT_MAX ) {
2499                 /* if op1 is really 32-bit data, then error */
2500                 EmitError( INVALID_OPERAND_SIZE );
2501                 rc = ERROR;
2502             }
2503         }
2504         /* type cast op1 to OP_I16 */
2505         CodeInfo->opnd[OPND1].type = OP_I16;
2506         /* op2 have to be 8-bit data */
2507         if( op2 >= OP_I16 ) {
2508             if( CodeInfo->opnd[OPND2].data32l > UCHAR_MAX ) {
2509                 EmitError( INVALID_OPERAND_SIZE );
2510                 rc = ERROR;
2511             }
2512             CodeInfo->opnd[OPND2].type = OP_I8;
2513         }
2514 #endif
2515         break;
2516     case T_MOVSX:
2517     case T_MOVZX:
2518         CodeInfo->iswide = 0;
2519         op1_size = OperandSize( op1, CodeInfo );
2520         op2_size = OperandSize( op2, CodeInfo );
2521         DebugMsg1(("check_size, MOVZX/MOVSX: op2_size=%u, opndx.memtype=%Xh, opndx.sym=%X\n", op2_size, opndx[OPND2].mem_type, opndx[OPND2].sym ));
2522         if ( op2_size == 0 && Parse_Pass == PASS_2 )
2523             if ( op1_size == 2 ) {
2524                 EmitWarn( 2, SIZE_NOT_SPECIFIED_ASSUMING, "BYTE" );
2525             } else
2526                 EmitErr( INSTRUCTION_OPERAND_MUST_HAVE_SIZE );
2527         switch( op1_size ) {
2528 #if AMD64_SUPPORT
2529         case 8:
2530             //if ( CodeInfo->Ofssize == USE64 )
2531             //    break;
2532 #endif
2533         case 4:
2534             if (op2_size < 2)
2535                 ;
2536             else if (op2_size == 2)
2537                 CodeInfo->iswide = 1;
2538             else {
2539                 EmitError( OP2_TOO_BIG );
2540                 rc = ERROR;
2541             }
2542             CodeInfo->prefix.opsiz = CodeInfo->Ofssize ? FALSE : TRUE;
2543             break;
2544         case 2:
2545             if( op2_size >= 2 ) {
2546                 EmitError( OP2_TOO_BIG );
2547                 rc = ERROR;
2548             }
2549             CodeInfo->prefix.opsiz = CodeInfo->Ofssize ? TRUE : FALSE;
2550             break;
2551         default:
2552             /* op1 must be r16/r32/r64 */
2553             EmitError( OP1_TOO_SMALL );
2554             rc = ERROR;
2555         }
2556         break;
2557 #if AMD64_SUPPORT
2558     case T_MOVSXD:
2559         break;
2560 #endif
2561     case T_ARPL: /* v2.06: new, avoids the OP_R16 hack in codegen.c */
2562         CodeInfo->prefix.opsiz = 0;
2563         goto def_check;
2564         break;
2565 #if AMD64_SUPPORT
2566     case T_LAR: /* v2.04: added */
2567     case T_LSL: /* 19-sep-93 */
2568 #if 1 /* v2.04: changed */
2569         if ( ModuleInfo.Ofssize != USE64 || ( ( op2 & OP_M ) == 0 ) )
2570             goto def_check;
2571         /* in 64-bit, if second argument is memory operand,
2572          * ensure it has size WORD ( or 0 if a forward ref )
2573          */
2574         op2_size = OperandSize( op2, CodeInfo );
2575         if ( op2_size != 2 && op2_size != 0 ) {
2576             return( EmitError( INVALID_OPERAND_SIZE ) );
2577         }
2578         /* the opsize prefix depends on the FIRST operand only! */
2579         op1_size = OperandSize( op1, CodeInfo );
2580         if ( op1_size != 2 )
2581             CodeInfo->prefix.opsiz = FALSE;
2582 #else
2583         op1_size = OperandSize( op1, CodeInfo );
2584         switch( op1_size ) {
2585         case 2:
2586             if( CodeInfo->Ofssize )
2587                 CodeInfo->prefix.opsiz = TRUE;
2588             break;
2589         case 4:
2590             if( CodeInfo->Ofssize )
2591                 CodeInfo->prefix.opsiz = FALSE;
2592             break;
2593         default:
2594             return( EmitError( INVALID_OPERAND_SIZE ) );
2595         }
2596         op2_size = OperandSize( op2, CodeInfo );
2597         switch( op2_size ) {
2598         case 2:
2599         case 4:
2600             break;
2601         default:
2602             EmitError( INVALID_OPERAND_SIZE );
2603             rc = ERROR;
2604             break;
2605         }
2606 #endif
2607         break;
2608 #endif
2609     case T_IMUL: /* v2.06: check for 3rd operand must be done here */
2610         if ( CodeInfo->opnd[OPND3].type != OP_NONE ) {
2611             int op3_size;
2612             op1_size = OperandSize( op1, CodeInfo );
2613             op3_size = OperandSize( CodeInfo->opnd[OPND3].type, CodeInfo );
2614             /* the only case which must be checked here
2615              * is a WORD register as op1 and a DWORD immediate as op3 */
2616             if ( op1_size == 2 && op3_size > 2 ) {
2617                 EmitErr( OPERANDS_MUST_BE_THE_SAME_SIZE, op1_size, op3_size );
2618                 rc = ERROR;
2619                 break;
2620             }
2621             if ( CodeInfo->opnd[OPND3].type & ( OP_I16 | OP_I32 ) )
2622                 CodeInfo->opnd[OPND3].type = ( op1_size == 2 ? OP_I16 : OP_I32 );
2623         }
2624         goto def_check;
2625         break;
2626     case T_CVTSD2SI:
2627     case T_CVTTSD2SI:
2628     case T_CVTSS2SI:
2629     case T_CVTTSS2SI:
2630     //case T_MOVNTI: /* v2.05: removed */
2631 #if AVXSUPP
2632     case T_VBROADCASTSD:
2633     case T_VBROADCASTF128:
2634     case T_VEXTRACTF128:
2635     case T_VINSERTF128:
2636     case T_VCVTSD2SI:
2637     case T_VCVTTSD2SI:
2638     case T_VCVTSS2SI:
2639     case T_VCVTTSS2SI:
2640 #endif
2641 #if VMXSUPP /* v2.09: added */
2642     case T_INVEPT:
2643     case T_INVVPID:
2644 #endif
2645 #if SVMSUPP /* v2.09: added */
2646     case T_INVLPGA:
2647 #endif
2648         break;
2649 #if AVXSUPP
2650     case T_VCVTPD2DQ:
2651     case T_VCVTTPD2DQ:
2652     case T_VCVTPD2PS:
2653         if ( op2 == OP_M && opndx[OPND2].indirect ) {
2654             return( EmitError( INSTRUCTION_OPERAND_MUST_HAVE_SIZE ) );
2655         }
2656         break;
2657     case T_VMOVDDUP:
2658         if ( !( op1 & OP_YMM ) )
2659             break;
2660         /* fall through */
2661     case T_VPERM2F128: /* has just one memory variant, and VX_L isnt set */
2662         if ( op2 == OP_M )
2663             CodeInfo->opnd[OPND2].type |= OP_M256;
2664         break;
2665 #endif
2666 #if SSE4SUPP
2667     case T_CRC32:
2668         /* v2.02: for CRC32, the second operand determines whether an
2669          * OPSIZE prefix byte is to be written.
2670          */
2671         op2_size = OperandSize( op2, CodeInfo );
2672         if ( op2_size < 2)
2673             CodeInfo->prefix.opsiz = FALSE;
2674         else if ( op2_size == 2 )
2675             CodeInfo->prefix.opsiz = CodeInfo->Ofssize ? TRUE : FALSE;
2676         else
2677             CodeInfo->prefix.opsiz = CodeInfo->Ofssize ? FALSE : TRUE;
2678         break;
2679 #endif
2680     case T_MOVD:
2681 #if 0
2682         op1_size = OperandSize( op1, CodeInfo );
2683         op2_size = OperandSize( op2, CodeInfo );
2684         if( ( op1_size != 0 ) && ( op1_size != 4 )
2685             || ( op2_size != 0 ) && ( op2_size != 4 ) ) {
2686             EmitErr( OPERANDS_MUST_BE_THE_SAME_SIZE, op1_size, op2_size );
2687             rc = ERROR;
2688         }
2689 #endif
2690         break;
2691     case T_MOV:
2692         if( op1 & OP_SR ) { /* segment register as op1? */
2693             op2_size = OperandSize( op2, CodeInfo );
2694             if( ( op2_size == 2 ) || ( op2_size == 4 )
2695 #if AMD64_SUPPORT
2696                || ( op2_size == 8 && ModuleInfo.Ofssize == USE64 )
2697 #endif
2698               ) {
2699                 return( NOT_ERROR );
2700             }
2701         } else if( op2 & OP_SR ) {
2702             op1_size = OperandSize( op1, CodeInfo );
2703             if( ( op1_size == 2 ) || ( op1_size == 4 )
2704 #if AMD64_SUPPORT
2705                || ( op1_size == 8 && ModuleInfo.Ofssize == USE64 )
2706 #endif
2707               ) {
2708                 return( NOT_ERROR );
2709             }
2710         } else if( ( op1 & OP_M ) && ( op2 & OP_A ) ) { /* 1. operand memory reference, 2. AL|AX|EAX|RAX? */
2711 
2712             if ( CodeInfo->isdirect == FALSE ) {
2713                 /* address mode is indirect.
2714                  * don't use the short format (opcodes A0-A3) - it exists for direct
2715                  * addressing only. Reset OP_A flag!
2716                  */
2717                 CodeInfo->opnd[OPND2].type &= ~OP_A;
2718                 DebugMsg1(("check_size: OP_A flag reset, new op2=%X\n", CodeInfo->opnd[OPND2].type ));
2719 #if AMD64_SUPPORT
2720             } else if ( CodeInfo->Ofssize == USE64 && ( CodeInfo->opnd[OPND1].data64 < 0x80000000 || CodeInfo->opnd[OPND1].data64 >= 0xffffffff80000000 ) ) {
2721                 /* for 64bit, opcodes A0-A3 ( direct memory addressing with AL/AX/EAX/RAX )
2722                  * are followed by a full 64-bit moffs. This is only used if the offset won't fit
2723                  * in a 32-bit signed value.
2724                  */
2725                 CodeInfo->opnd[OPND2].type &= ~OP_A;
2726                 DebugMsg1(("check_size: OP_A flag reset, new op2=%X\n", CodeInfo->opnd[OPND2].type ));
2727 #endif
2728             }
2729 
2730         } else if( ( op1 & OP_A ) && ( op2 & OP_M ) ) { /* 2. operand memory reference, 1. AL|AX|EAX|RAX? */
2731 
2732             if ( CodeInfo->isdirect == FALSE ) {
2733                 CodeInfo->opnd[OPND1].type &= ~OP_A;
2734                 DebugMsg1(("check_size: OP_A flag reset, new op1=%X\n", CodeInfo->opnd[OPND1].type ));
2735 #if AMD64_SUPPORT
2736             } else if ( CodeInfo->Ofssize == USE64 && ( CodeInfo->opnd[OPND2].data64 < 0x80000000 || CodeInfo->opnd[OPND2].data64 >= 0xffffffff80000000 ) ) {
2737                 CodeInfo->opnd[OPND1].type &= ~OP_A;
2738                 DebugMsg1(("check_size: OP_A flag reset, new op2=%X\n", CodeInfo->opnd[OPND1].type ));
2739 #endif
2740             }
2741         }
2742         /* fall through */
2743     default:
2744 //#if AMD64_SUPPORT
2745     def_check:
2746 //#endif
2747         /* make sure the 2 opnds are of the same type */
2748         op1_size = OperandSize( op1, CodeInfo );
2749         op2_size = OperandSize( op2, CodeInfo );
2750         DebugMsg1(("check_size default: op1_size1=%u, op2_size=%u\n", op1_size, op2_size));
2751         if( op1_size > op2_size ) {
2752             if( ( op2 >= OP_I8 ) && ( op2 <= OP_I32 ) ) {     /* immediate */
2753                 op2_size = op1_size;    /* promote to larger size */
2754             }
2755         }
2756 #if 1
2757         /* v2.04: check in idata_nofixup was signed,
2758          * so now add -256 - -129 and 128-255 to acceptable byte range.
2759          * Since Masm v8, the check is more restrictive, -255 - -129
2760          * is no longer accepted.
2761          */
2762         if( ( op1_size == 1 ) && ( op2 == OP_I16 ) &&
2763             ( CodeInfo->opnd[OPND2].data32l <= UCHAR_MAX ) &&
2764             //CodeInfo->opnd[OPND2].data32l >= -128 ) ) {
2765             ( CodeInfo->opnd[OPND2].data32l >= -255 ) ) {
2766             return( rc ); /* OK cause no sign extension */
2767         }
2768 #endif
2769 #if 0
2770         /* v2.03: this "if" made JWasm accept any 32-bit constant
2771          *        for 16-bit destinations, which is Masm compatibel,
2772          *      "mov ax, 12345h"
2773          * the test is a bit too liberal here, IMO, because
2774          * it makes JWasm accept "mov ax, near32 ptr var",
2775          * which is rejected by Masm.
2776          */
2777         if( ( op1_size == 2 ) && ( op2 == OP_I32 )
2778             && ( CodeInfo->data[OPND2] <= USHRT_MAX ) ) {
2779             return( rc ); /* OK cause no sign extension */
2780         }
2781 #endif
2782         if( op1_size != op2_size ) {
2783             /* if one or more are !defined, set them appropriately */
2784 #if AVXSUPP
2785             if( ( op1 | op2 ) & ( OP_MMX | OP_XMM | OP_YMM ) ) {
2786 #else
2787             if( ( op1 | op2 ) & ( OP_MMX | OP_XMM ) ) {
2788 #endif
2789             } else if( ( op1_size != 0 ) && ( op2_size != 0 ) ) {
2790                 EmitErr( OPERANDS_MUST_BE_THE_SAME_SIZE, op1_size, op2_size );
2791                 rc = ERROR;
2792             }
2793             /* size == 0 is assumed to mean "undefined", but there
2794              * is also the case of an "empty" struct or union. The
2795              * latter case isn't handled correctly.
2796              */
2797             if( op1_size == 0 ) {
2798                 if( ( op1 & OP_M_ANY ) && ( op2 & OP_I ) ) {
2799                     char *p = "WORD";
2800                     if( (uint_32)CodeInfo->opnd[OPND2].data32l > USHRT_MAX || op2_size == 4 ) {
2801                         CodeInfo->iswide = 1;
2802                         DebugMsg1(("check_size: op1=%X op1_size=0, op2=%X, op2_size=%u CodeInfo->data[2]=%X\n", op1, op2, op2_size, CodeInfo->opnd[OPND2].data32l ));
2803 #if 1 /* added v1.95: in 16bit code, 'mov [di],8000h' should warn: assuming WORD */
2804                         if ( ModuleInfo.Ofssize == USE16 && op2_size > 2 && InWordRange( CodeInfo->opnd[OPND2].data32l ) )
2805                             op2_size = 2;
2806 #endif
2807                         if (op2_size <= 2 && CodeInfo->opnd[OPND2].data32l > SHRT_MIN && ModuleInfo.Ofssize == USE16 ) {
2808                             CodeInfo->mem_type = MT_WORD;
2809                             CodeInfo->opnd[OPND2].type = OP_I16;
2810                         } else {
2811                             CodeInfo->mem_type = MT_DWORD;
2812                             CodeInfo->opnd[OPND2].type = OP_I32;
2813                             p = "DWORD";
2814                         }
2815                     } else if( (uint_32)CodeInfo->opnd[OPND2].data32l > UCHAR_MAX || op2_size == 2 ) {
2816                          CodeInfo->mem_type = MT_WORD;
2817                          CodeInfo->iswide = 1;
2818                          CodeInfo->opnd[OPND2].type = OP_I16;
2819                     } else {
2820                          CodeInfo->mem_type = MT_BYTE;
2821                          CodeInfo->opnd[OPND2].type = OP_I8;
2822                          p = "BYTE";
2823                     }
2824                     if( opndx[OPND2].explicit == FALSE ) {
2825                         /* v2.06: emit warning at pass one if mem op isn't a forward ref */
2826                         /* v2.06b: added "undefined" check */
2827                         if ( ( CodeInfo->opnd[OPND1].InsFixup == NULL && Parse_Pass == PASS_1 && CodeInfo->undef_sym == FALSE ) ||
2828                             ( CodeInfo->opnd[OPND1].InsFixup && Parse_Pass == PASS_2 ) )
2829                                 EmitWarn( 1, SIZE_NOT_SPECIFIED_ASSUMING, p );
2830                     }
2831                 } else if( ( op1 & OP_M_ANY ) && ( op2 & ( OP_R | OP_SR ) ) ) {
2832                 } else if( ( op1 & ( OP_MMX | OP_XMM ) ) && ( op2 & OP_I ) ) {
2833                     if( (uint_32)CodeInfo->opnd[OPND2].data32l > USHRT_MAX ) {
2834                          CodeInfo->opnd[OPND2].type = OP_I32;
2835                     } else if( (uint_32)CodeInfo->opnd[OPND2].data32l > UCHAR_MAX ) {
2836                          CodeInfo->opnd[OPND2].type = OP_I16;
2837                     } else {
2838                          CodeInfo->opnd[OPND2].type = OP_I8;
2839                     }
2840                 } else if( ( op1 | op2 ) & ( OP_MMX | OP_XMM ) ) {
2841                 } else {
2842                     //AsmIntErr( 1 ); /* printf("internal error = %u", 1 ) */
2843                     switch( op2_size ) {
2844                     case 1:
2845                         CodeInfo->mem_type = MT_BYTE;
2846                         if( ( Parse_Pass == PASS_1 ) && ( op2 & OP_I ) ) {
2847                             EmitWarn( 1, SIZE_NOT_SPECIFIED_ASSUMING, "BYTE" );
2848                         }
2849                         break;
2850                     case 2:
2851                         CodeInfo->mem_type = MT_WORD;
2852                         CodeInfo->iswide = 1;
2853                         if( ( Parse_Pass == PASS_1 ) && ( op2 & OP_I ) ) {
2854                             EmitWarn( 1, SIZE_NOT_SPECIFIED_ASSUMING, "WORD" );
2855                         }
2856                         if( CodeInfo->Ofssize )
2857                             CodeInfo->prefix.opsiz = TRUE;
2858                         break;
2859                     case 4:
2860                         CodeInfo->mem_type = MT_DWORD;
2861                         CodeInfo->iswide = 1;
2862                         if( ( Parse_Pass == PASS_1 ) && ( op2 & OP_I ) ) {
2863                             EmitWarn( 1, SIZE_NOT_SPECIFIED_ASSUMING, "DWORD" );
2864                         }
2865                         break;
2866                     }
2867                 }
2868             }
2869         }
2870     }
2871     DebugMsg1(("check_size exit [CodeInfo->mem_type=%Xh]\n", CodeInfo->mem_type));
2872     return( rc );
2873 }
2874 
2875 static struct asym *IsType( const char *name )
2876 /********************************************/
2877 {
2878     struct asym *sym;
2879 
2880     sym = SymSearch( name );
2881     if ( sym && (sym->state == SYM_TYPE ) )
2882         return( sym );
2883     return( NULL );
2884 }
2885 
2886 /*
2887  * ParseLine() is the main parser function.
2888  * It scans the tokens in tokenarray[] and does:
2889  * - for code labels: call CreateLabel()
2890  * - for data items and data directives: call data_dir()
2891  * - for other directives: call directive[]()
2892  * - for instructions: fill CodeInfo and call codegen()
2893  */
2894 
2895 ret_code ParseLine( struct asm_tok tokenarray[] )
2896 /**********************************************/
2897 {
2898     int                 i;
2899     int                 j;
2900     unsigned            dirflags;
2901     unsigned            CurrOpnd;
2902     ret_code            temp;
2903     struct asym         *sym;
2904     uint_32             oldofs;
2905 #ifdef DEBUG_OUT
2906     char                *instr;
2907 #endif
2908     struct code_info    CodeInfo;
2909 #if AVXSUPP
2910     struct expr         opndx[MAX_OPND+1];
2911 #else
2912     struct expr         opndx[MAX_OPND];
2913 #endif
2914 
2915     DebugMsg1(("ParseLine enter, Token_Count=%u, ofs=%Xh\n",
2916               Token_Count, GetCurrOffset() ));
2917 
2918     i = 0;
2919 
2920     /* Does line start with a code label? */
2921     if ( tokenarray[0].token == T_ID && ( tokenarray[1].token == T_COLON || tokenarray[1].token == T_DBL_COLON ) ) {
2922         i = 2;
2923         DebugMsg1(("ParseLine T_COLON, code label=%s\n", tokenarray[0].string_ptr ));
2924         if( ProcStatus & PRST_PROLOGUE_NOT_DONE ) write_prologue( tokenarray );
2925 
2926         /* create a global or local code label */
2927         if( CreateLabel( tokenarray[0].string_ptr, MT_NEAR, NULL,
2928                         ( ModuleInfo.scoped && CurrProc && tokenarray[1].token != T_DBL_COLON ) ) == NULL ) {
2929             DebugMsg(("ParseLine, CreateLabel(%s) failed, exit\n", tokenarray[0].string_ptr ));
2930             return( ERROR );
2931         }
2932         if ( tokenarray[i].token == T_FINAL ) {
2933             /* v2.06: this is a bit too late. Should be done BEFORE
2934              * CreateLabel, because of '@@'. There's a flag supposed to
2935              * be used for this handling, LOF_STORED in line_flags.
2936              * It's only a problem if a '@@:' is the first line
2937              * in the code section.
2938              * v2.10: is no longer an issue because the label counter has
2939              * been moved to module_vars (see global.h).
2940              */
2941             FStoreLine(0);
2942             if ( CurrFile[LST] ) {
2943                 LstWrite( LSTTYPE_LABEL, 0, NULL );
2944             }
2945             return( NOT_ERROR );
2946         }
2947     }
2948 
2949     /* handle directives and (anonymous) data items */
2950 
2951     if ( tokenarray[i].token != T_INSTRUCTION ) {
2952         /* a code label before a data item is only accepted in Masm5 compat mode */
2953         Frame_Type = FRAME_NONE;
2954         SegOverride = NULL;
2955         if ( i == 0 && tokenarray[0].token == T_ID ) {
2956             /* token at pos 0 may be a label.
2957              * it IS a label if:
2958              * 1. token at pos 1 is a directive (lbl dd ...)
2959              * 2. token at pos 0 is NOT a userdef type ( lbl DWORD ...)
2960              * 3. inside a struct and token at pos 1 is a userdef type
2961              *    or a predefined type. (usertype DWORD|usertype ... )
2962              *    the separate namespace allows this syntax here.
2963              */
2964             if( tokenarray[1].token == T_DIRECTIVE )
2965                 i++;
2966             else {
2967                 sym = IsType( tokenarray[0].string_ptr );
2968                 if ( sym == NULL )
2969                     i++;
2970                 else if ( CurrStruct &&
2971                          ( ( tokenarray[1].token == T_STYPE ) ||
2972                           ( tokenarray[1].token == T_ID && ( IsType( tokenarray[1].string_ptr ) ) ) ) )
2973                     i++;
2974             }
2975         }
2976         switch ( tokenarray[i].token ) {
2977         case T_DIRECTIVE:
2978             DebugMsg1(("ParseLine: T_DIRECTIVE >%s<\n", tokenarray[i].string_ptr ));
2979             if ( tokenarray[i].dirtype == DRT_DATADIR ) {
2980                 return( data_dir( i, tokenarray, NULL ) );
2981             }
2982             dirflags = GetValueSp( tokenarray[i].tokval );
2983             if( CurrStruct && ( dirflags & DF_NOSTRUC ) ) {
2984                 return( EmitError( STATEMENT_NOT_ALLOWED_INSIDE_STRUCTURE_DEFINITION ) );
2985             }
2986             /* label allowed for directive? */
2987             //if ( tokenarray[i].flags & DF_LABEL ) {
2988             if ( dirflags & DF_LABEL ) {
2989                 if ( i && tokenarray[0].token != T_ID ) {
2990                     return( EmitErr( SYNTAX_ERROR_EX, tokenarray[0].string_ptr ) );
2991                 }
2992             } else if ( i && tokenarray[i-1].token != T_COLON && tokenarray[i-1].token != T_DBL_COLON ) {
2993                 return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i-1].string_ptr ) );
2994             }
2995             /* must be done BEFORE FStoreLine()! */
2996             if( ( ProcStatus & PRST_PROLOGUE_NOT_DONE ) && ( dirflags & DF_PROC ) ) write_prologue( tokenarray );
2997 #if FASTPASS
2998             if ( StoreState || ( dirflags & DF_STORE ) ) {
2999                 /* v2.07: the comment must be stored as well
3000                  * if a listing (with -Sg) is to be written and
3001                  * the directive will generate lines
3002                  */
3003                 if ( ( dirflags & DF_CGEN ) && ModuleInfo.CurrComment && ModuleInfo.list_generated_code ) {
3004                     FStoreLine(1);
3005                 } else
3006                     FStoreLine(0);
3007             }
3008 #endif
3009             if ( tokenarray[i].dirtype > DRT_DATADIR ) {
3010                 temp = directive_tab[tokenarray[i].dirtype]( i, tokenarray );
3011             } else {
3012                 temp = ERROR;
3013                 /* ENDM, EXITM and GOTO directives should never be seen here */
3014                 switch( tokenarray[i].tokval ) {
3015                 case T_ENDM:
3016                     EmitError( UNMATCHED_MACRO_NESTING );
3017                     break;
3018                 case T_EXITM:
3019                 case T_GOTO:
3020                     EmitError( DIRECTIVE_MUST_APPEAR_INSIDE_A_MACRO );
3021                     break;
3022                 default:
3023                     /* this error may happen if
3024                      * CATSTR, SUBSTR, MACRO, ...
3025                      * aren't at pos 1
3026                      */
3027                     EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr );
3028                     break;
3029                 }
3030             }
3031             /* v2.0: for generated code it's important that list file is
3032              * written in ALL passes, to update file position! */
3033             //if ( ModuleInfo.list && (( line_flags & LOF_LISTED ) == 0 ) && Parse_Pass == PASS_1 )
3034 #if FASTPASS
3035             /* v2.08: UseSavedState == FALSE added */
3036             if ( ModuleInfo.list && ( Parse_Pass == PASS_1 || ModuleInfo.GeneratedCode || UseSavedState == FALSE ) )
3037 #else
3038             if ( ModuleInfo.list )
3039 #endif
3040                 LstWriteSrcLine();
3041             return( temp );
3042         case T_STYPE:
3043             DebugMsg1(("ParseLine: T_STYPE >%s<\n", tokenarray[i].string_ptr ));
3044             return( data_dir( i, tokenarray, NULL ) );
3045         case T_ID:
3046             DebugMsg1(("ParseLine: T_ID >%s<\n", tokenarray[i].string_ptr ));
3047             if( sym = IsType( tokenarray[i].string_ptr ) ) {
3048                 return( data_dir( i, tokenarray, sym ) );
3049             }
3050             break;
3051         default:
3052             if ( tokenarray[i].token == T_COLON ) {
3053                 DebugMsg(("ParseLine: unexpected colon\n" ));
3054                 return( EmitError( SYNTAX_ERROR_UNEXPECTED_COLON ) );
3055             }
3056             break;
3057         } /* end switch (tokenarray[i].token) */
3058         if ( i && tokenarray[i-1].token == T_ID )
3059             i--;
3060         DebugMsg(("ParseLine: unexpected token=%u, i=%u, string=%s\n", tokenarray[i].token, i, tokenarray[i].string_ptr));
3061         return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
3062     }
3063 
3064     DebugMsg1(("ParseLine: %s\n", tokenarray[i].string_ptr));
3065     /* v2.04 added */
3066     if( CurrStruct ) {
3067         return( EmitError( STATEMENT_NOT_ALLOWED_INSIDE_STRUCTURE_DEFINITION ) );
3068     }
3069 
3070     if( ProcStatus & PRST_PROLOGUE_NOT_DONE ) write_prologue( tokenarray );
3071 
3072     /* v2.07: moved because special handling is needed for RET/IRET */
3073     //FStoreLine(); /* must be placed AFTER write_prologue() */
3074 
3075     if ( CurrFile[LST] ) oldofs = GetCurrOffset();
3076 
3077     /* init CodeInfo */
3078     CodeInfo.prefix.ins         = EMPTY;
3079     CodeInfo.prefix.RegOverride = ASSUME_NOTHING;/* v2.12: EMPTY -> ASSUME_NOTHING to avoid warning */
3080 #if AMD64_SUPPORT
3081     CodeInfo.prefix.rex     = 0;
3082 #endif
3083     CodeInfo.prefix.adrsiz  = FALSE;
3084     CodeInfo.prefix.opsiz   = FALSE;
3085     CodeInfo.mem_type       = MT_EMPTY;
3086     for( j = 0; j < MAX_OPND; j++ ) {
3087         CodeInfo.opnd[j].type = OP_NONE;
3088 #ifdef DEBUG_OUT
3089         CodeInfo.opnd[j].data32l = -1;
3090         /* make sure it's invalid */
3091         CodeInfo.opnd[j].InsFixup = (void *)0xffffffff;
3092 #endif
3093     }
3094     CodeInfo.rm_byte        = 0;
3095     CodeInfo.sib            = 0;            /* assume ss is *1 */
3096     CodeInfo.Ofssize        = ModuleInfo.Ofssize;
3097     CodeInfo.opc_or         = 0;
3098 #if AVXSUPP
3099     CodeInfo.vexregop       = 0;
3100 #endif
3101     CodeInfo.flags          = 0;
3102 
3103     /* instruction prefix?
3104      * T_LOCK, T_REP, T_REPE, T_REPNE, T_REPNZ, T_REPZ */
3105     if ( tokenarray[i].tokval >= T_LOCK && tokenarray[i].tokval <= T_REPZ ) {
3106         CodeInfo.prefix.ins = tokenarray[i].tokval;
3107         i++;
3108         /* prefix has to be followed by an instruction */
3109         if( tokenarray[i].token != T_INSTRUCTION ) {
3110             DebugMsg(("ParseLine: unexpected token %u after prefix, exit, error\n", tokenarray[i].token ));
3111             return( EmitError( PREFIX_MUST_BE_FOLLOWED_BY_AN_INSTRUCTION ) );
3112         }
3113         DebugMsg1(("ParseLine: %s\n", tokenarray[i].tokpos));
3114     };
3115 
3116     if( CurrProc ) {
3117         switch( tokenarray[i].tokval ) {
3118         case T_RET:
3119         case T_IRET:  /* IRET is always 16-bit; OTOH, IRETW doesn't exist */
3120         case T_IRETD:
3121 #if AMD64_SUPPORT
3122         case T_IRETQ:
3123 #endif
3124             if ( !( ProcStatus & PRST_INSIDE_EPILOGUE ) && ModuleInfo.epiloguemode != PEM_NONE ) {
3125                 /* v2.07: special handling for RET/IRET */
3126                 FStoreLine( ( ModuleInfo.CurrComment && ModuleInfo.list_generated_code ) ? 1 : 0 );
3127                 ProcStatus |= PRST_INSIDE_EPILOGUE;
3128                 temp = RetInstr( i, tokenarray, Token_Count );
3129                 ProcStatus &= ~PRST_INSIDE_EPILOGUE;
3130                 return( temp );
3131             }
3132             /* default translation: just RET to RETF if proc is far */
3133             /* v2.08: this code must run even if PRST_INSIDE_EPILOGUE is set */
3134             if ( tokenarray[i].tokval == T_RET && CurrProc->sym.mem_type == MT_FAR )
3135                 tokenarray[i].tokval = T_RETF;
3136         }
3137     }
3138 
3139     FStoreLine(0); /* must be placed AFTER write_prologue() */
3140 
3141 #ifdef DEBUG_OUT
3142     instr = tokenarray[i].string_ptr;
3143 #endif
3144     CodeInfo.token = tokenarray[i].tokval;
3145     /* get the instruction's start position in InstrTable[] */
3146     CodeInfo.pinstr = &InstrTable[IndexFromToken( CodeInfo.token )];
3147     i++;
3148 
3149     if( CurrSeg == NULL ) {
3150         return( EmitError( MUST_BE_IN_SEGMENT_BLOCK ) );
3151     }
3152     if( CurrSeg->e.seginfo->segtype == SEGTYPE_UNDEF ) {
3153         CurrSeg->e.seginfo->segtype = SEGTYPE_CODE;
3154     }
3155     if ( ModuleInfo.CommentDataInCode )
3156         omf_OutSelect( FALSE );
3157 
3158     /* get the instruction's arguments.
3159      * This loop accepts up to 4 arguments if AVXSUPP is on */
3160 
3161     for ( j = 0; j < sizeof(opndx)/sizeof(opndx[0]) && tokenarray[i].token != T_FINAL; j++ ) {
3162         if ( j ) {
3163             if ( tokenarray[i].token != T_COMMA )
3164                 break;
3165             i++;
3166         }
3167         DebugMsg1(("ParseLine(%s): calling EvalOperand, i=%u\n", instr, i));
3168         if( EvalOperand( &i, tokenarray, Token_Count, &opndx[j], 0 ) == ERROR ) {
3169             DebugMsg(("ParseLine(%s): EvalOperand() failed\n", instr ));
3170             return( ERROR );
3171         }
3172         switch ( opndx[j].kind ) {
3173         case EXPR_FLOAT:
3174             /* v2.06: accept float constants for PUSH */
3175             if ( j == OPND2 || CodeInfo.token == T_PUSH || CodeInfo.token == T_PUSHD ) {
3176 #if FPIMMEDIATE
3177                 if ( Options.strict_masm_compat == FALSE ) {
3178                     /* convert to REAL4, unless REAL8 coercion is requested */
3179                     atofloat( &opndx[j].fvalue, opndx[j].float_tok->string_ptr, opndx[j].mem_type == MT_REAL8 ? 8 : 4, opndx[j].negative, opndx[j].float_tok->floattype );
3180                     opndx[j].kind = EXPR_CONST;
3181                     opndx[j].float_tok = NULL;
3182                     break;
3183                 }
3184 #endif
3185                 /* Masm message is: real or BCD number not allowed */
3186                 return( EmitError( FP_INITIALIZER_IGNORED ) );
3187             }
3188             /* fall through */
3189         case EXPR_EMPTY:
3190             if ( i == Token_Count )
3191                 i--;  /* v2.08: if there was a terminating comma, display it */
3192             /* fall through */
3193         case EXPR_ERROR:
3194             DebugMsg(("ParseLine(%s): unexpected operand kind=%d, error, exit\n", instr, opndx[j].kind ));
3195             return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) );
3196         }
3197     }
3198     if ( tokenarray[i].token != T_FINAL ) {
3199         DebugMsg(("ParseLine(%s): too many operands (%s) \n", instr, tokenarray[i].tokpos ));
3200         return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
3201     }
3202 
3203     for ( CurrOpnd = 0; CurrOpnd < j && CurrOpnd < MAX_OPND; CurrOpnd++ ) {
3204 
3205         Frame_Type = FRAME_NONE;
3206         SegOverride = NULL; /* segreg prefix is stored in RegOverride */
3207         CodeInfo.opnd[CurrOpnd].data32l = 0;
3208         CodeInfo.opnd[CurrOpnd].InsFixup = NULL;
3209 
3210 #if AVXSUPP
3211         /* if encoding is VEX and destination op is XMM, YMM or memory,
3212          * the second argument may be stored in the vexregop field.
3213          */
3214         if ( CodeInfo.token >= VEX_START &&
3215             CurrOpnd == OPND2 &&
3216             ( CodeInfo.opnd[OPND1].type & ( OP_XMM | OP_YMM | OP_M | OP_M256 ) ) ) {
3217             if ( vex_flags[CodeInfo.token - VEX_START] & VX_NND )
3218                 ;
3219             else if ( ( vex_flags[CodeInfo.token - VEX_START] & VX_IMM ) &&
3220                      ( opndx[OPND3].kind == EXPR_CONST ) && ( j > 2 ) )
3221                 ;
3222             else if ( ( vex_flags[CodeInfo.token - VEX_START] & VX_NMEM ) &&
3223                      ( ( CodeInfo.opnd[OPND1].type & OP_M ) ||
3224                      /* v2.11: VMOVSD and VMOVSS always have 2 ops if a memory op is involved */
3225                      ( ( CodeInfo.token == T_VMOVSD || CodeInfo.token == T_VMOVSS ) && ( opndx[OPND2].kind != EXPR_REG || opndx[OPND2].indirect == TRUE ) ) )
3226                     )
3227                 ;
3228             else {
3229                 if ( opndx[OPND2].kind != EXPR_REG ||
3230                     ( ! ( GetValueSp( opndx[CurrOpnd].base_reg->tokval ) & ( OP_XMM | OP_YMM ) ) ) ) {
3231                     DebugMsg(("ParseLine(%s,%u): avx invalid operand, op2.kind=%u\n", instr, CurrOpnd, opndx[OPND2].kind ));
3232                     return( EmitErr( INVALID_INSTRUCTION_OPERANDS ) );
3233                 }
3234                 /* fixme: check if there's an operand behind OPND2 at all!
3235                  * if no, there's no point to continue with switch (opndx[].kind).
3236                  * v2.11: additional check for j <= 2 added
3237                  */
3238                 if ( j <= 2 ) {
3239                     DebugMsg(("ParseLine(%s,%u): avx not enough operands (%u)\n", instr, CurrOpnd, opndx[OPND2].kind, j ));
3240                     /* v2.11: next line should be activated - currently the error is emitted below as syntax error */
3241                     //return( EmitErr( INVALID_INSTRUCTION_OPERANDS ) );
3242                 } else
3243                 /* flag VX_DST is set if an immediate is expected as operand 3 */
3244                 if ( ( vex_flags[CodeInfo.token - VEX_START] & VX_DST ) &&
3245                     ( opndx[OPND3].kind == EXPR_CONST ) ) {
3246                     DebugMsg1(("ParseLine(%s,%u): avx VX_DST, op3.kind=CONST (value=%u), numops=%u\n", instr, CurrOpnd, opndx[OPND3].kind, opndx[OPND3].value, j ));
3247                     if ( opndx[OPND1].base_reg ) {
3248                         /* first operand register is moved to vexregop */
3249                         /* handle VEX.NDD */
3250                         CodeInfo.vexregop = opndx[OPND1].base_reg->bytval + 1;
3251                         memcpy( &opndx[OPND1], &opndx[CurrOpnd], sizeof( opndx[0] ) * 3 );
3252                         CodeInfo.rm_byte = 0;
3253                         if ( process_register( &CodeInfo, OPND1, opndx ) == ERROR )
3254                             return( ERROR );
3255                     }
3256                 } else {
3257                     unsigned flags = GetValueSp( opndx[CurrOpnd].base_reg->tokval );
3258                     DebugMsg1(("ParseLine(%s,%u): opnd2 is avx reg (%s), flags=%X ci.type[0]=%X numops=%u\n",
3259                                instr, CurrOpnd, opndx[CurrOpnd].base_reg->string_ptr, flags, CodeInfo.opnd[OPND1].type, j ));
3260 #if 1
3261                     /* v2.08: no error here if first op is an untyped memory reference
3262                      * note that OP_M includes OP_M128, but not OP_M256 (to be fixed?)
3263                      */
3264                     if ( CodeInfo.opnd[OPND1].type == OP_M )
3265                         ; else
3266 #endif
3267                     if ( ( flags & ( OP_XMM | OP_M128 ) ) &&
3268                         ( CodeInfo.opnd[OPND1].type & (OP_YMM | OP_M256 ) ) ||
3269                         ( flags & ( OP_YMM | OP_M256 ) ) &&
3270                         ( CodeInfo.opnd[OPND1].type & (OP_XMM | OP_M128 ) ) ) {
3271                         DebugMsg(("ParseLine(%s,%u): avx invalid opnd 2, flags=%X ci.type[0]=%X\n", instr, CurrOpnd, flags, CodeInfo.opnd[OPND1].type ));
3272                         return( EmitErr( INVALID_INSTRUCTION_OPERANDS ) );
3273                     }
3274                     /* second operand register is moved to vexregop */
3275                     /* to be fixed: CurrOpnd is always OPND2, so use this const here */
3276                     CodeInfo.vexregop = opndx[CurrOpnd].base_reg->bytval + 1;
3277                     memcpy( &opndx[CurrOpnd], &opndx[CurrOpnd+1], sizeof( opndx[0] ) * 2 );
3278                 }
3279                 j--;
3280             }
3281         }
3282 #endif
3283         DebugMsg1(("ParseLine(%s,%u): type/value/mem_type/ofssize=%Xh/%" I64_SPEC "Xh/%Xh/%d\n", instr, CurrOpnd, opndx[CurrOpnd].kind, opndx[CurrOpnd].value64, opndx[CurrOpnd].mem_type, opndx[CurrOpnd].Ofssize ));
3284         switch( opndx[CurrOpnd].kind ) {
3285         case EXPR_ADDR:
3286             DebugMsg1(("ParseLine(%s,%u): type ADDRESS\n", instr, CurrOpnd ));
3287             if ( process_address( &CodeInfo, CurrOpnd, &opndx[CurrOpnd] ) == ERROR )
3288                 return( ERROR );
3289             break;
3290         case EXPR_CONST:
3291             DebugMsg1(("ParseLine(%s,%u): type CONST, opndx.memtype=%Xh\n", instr, CurrOpnd, opndx[CurrOpnd].mem_type));
3292             if ( process_const( &CodeInfo, CurrOpnd, &opndx[CurrOpnd] ) == ERROR )
3293                 return( ERROR );
3294             break;
3295         case EXPR_REG:
3296             DebugMsg1(("ParseLine(%s,%u): type REG\n", instr, CurrOpnd ));
3297             if( opndx[CurrOpnd].indirect ) { /* indirect operand ( "[EBX+...]" )? */
3298                 if ( process_address( &CodeInfo, CurrOpnd, &opndx[CurrOpnd] ) == ERROR )
3299                     return( ERROR );
3300             } else {
3301                 /* process_register() can't handle 3rd operand */
3302                 if ( CurrOpnd == OPND3 ) {
3303                     CodeInfo.opnd[OPND3].type = GetValueSp( opndx[CurrOpnd].base_reg->tokval );
3304                     CodeInfo.opnd[OPND3].data32l = opndx[CurrOpnd].base_reg->bytval;
3305                 } else if ( process_register( &CodeInfo, CurrOpnd, opndx ) == ERROR )
3306                     return( ERROR );
3307             }
3308             break;
3309         }
3310     } /* end for */
3311 #if AVXSUPP
3312     /* 4 arguments are valid vor AVX only */
3313     if ( CurrOpnd != j ) {
3314         for ( ; tokenarray[i].token != T_COMMA; i-- )
3315             ;/* v2.12: semicolon on a separate line to avoid warning */
3316         DebugMsg(("ParseLine(%s): CurrOpnd != j ( %u - %u ) >%s<\n", instr, CurrOpnd, j, tokenarray[i].tokpos ));
3317         return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
3318     }
3319 #endif
3320 
3321     /* for FAR calls/jmps some special handling is required:
3322      * in the instruction tables, the "far" entries are located BEHIND
3323      * the "near" entries, that's why it's needed to skip all items
3324      * until the next "first" item is found.
3325      */
3326     if ( CodeInfo.isfar ) {
3327         if ( CodeInfo.token == T_CALL || CodeInfo.token == T_JMP ) {
3328             do {
3329                 CodeInfo.pinstr++;
3330             } while ( CodeInfo.pinstr->first == FALSE );
3331         }
3332     }
3333     /* special handling for string instructions */
3334 
3335     if ( CodeInfo.pinstr->allowed_prefix == AP_REP ||
3336          CodeInfo.pinstr->allowed_prefix == AP_REPxx ) {
3337         HandleStringInstructions( &CodeInfo, opndx );
3338 #if SVMSUPP /* v2.09, not active because a bit too hackish yet - it "works", though. */
3339     } else if ( CodeInfo.token >= T_VMRUN && CodeInfo.token <= T_INVLPGA && CodeInfo.pinstr->opclsidx ) {
3340         /* the size of the first operand is to trigger the address size byte 67h,
3341          * not the operand size byte 66h!
3342          */
3343         CodeInfo.prefix.adrsiz = CodeInfo.prefix.opsiz;
3344         CodeInfo.prefix.opsiz = 0;
3345         /* the first op must be EAX/AX or RAX/EAX. The operand class
3346          * used in the instruction table is OP_A ( which is AL/AX/EAX/RAX ).
3347          */
3348         if ( ( CodeInfo.opnd[OPND1].type & ( CodeInfo.Ofssize == USE64 ? OP_R64 | OP_R32 : OP_R32 | OP_R16 ) ) == 0 ) {
3349             DebugMsg(("ParseLine(%s): opnd1 unexpected type=%X\n", instr, CodeInfo.opnd[OPND1].type ));
3350             return( EmitErr( INVALID_INSTRUCTION_OPERANDS ) );
3351         }
3352         /* the INVLPGA instruction has a fix second operand (=ECX). However, there's no
3353          * operand class for ECX alone. So it has to be ensured here that the register IS ecx.
3354          */
3355         if ( CodeInfo.token == T_INVLPGA )
3356             if ( ( CodeInfo.rm_byte & BIT_345 ) != ( 1 << 3 ) ) { /* ECX is register 1 */
3357                 DebugMsg(("ParseLine(%s): opnd2 is not ecx\n", instr ));
3358                 return( EmitErr( INVALID_INSTRUCTION_OPERANDS ) );
3359             }
3360 #endif
3361     } else {
3362         if( CurrOpnd > 1 ) {
3363             /* v1.96: check if a third argument is ok */
3364             if ( CurrOpnd > 2 ) {
3365                 do {
3366                     //if ( CodeInfo.pinstr->opnd_type_3rd != OP3_NONE )
3367                     if ( opnd_clstab[CodeInfo.pinstr->opclsidx].opnd_type_3rd != OP3_NONE )
3368                         break;
3369                     CodeInfo.pinstr++;
3370                     if ( CodeInfo.pinstr->first == TRUE ) {
3371                         DebugMsg(("ParseLine(%s): no third operand expected\n", instr ));
3372                         for ( ; tokenarray[i].token != T_COMMA; i-- );
3373                         return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) );
3374                     }
3375                 } while ( 1 );
3376             }
3377             /* v2.06: moved here from process_const() */
3378             if ( CodeInfo.token == T_IMUL ) {
3379                 /* the 2-operand form with an immediate as second op
3380                  * is actually a 3-operand form. That's why the rm byte
3381                  * has to be adjusted. */
3382                 if ( CodeInfo.opnd[OPND3].type == OP_NONE && ( CodeInfo.opnd[OPND2].type & OP_I ) ) {
3383 #if AMD64_SUPPORT
3384                     CodeInfo.prefix.rex |= ((CodeInfo.prefix.rex & REX_B) ? REX_R : 0 );
3385 #endif
3386                     CodeInfo.rm_byte = ( CodeInfo.rm_byte & ~BIT_345 ) | ( ( CodeInfo.rm_byte & BIT_012 ) << 3 );
3387                 } else if ( ( CodeInfo.opnd[OPND3].type != OP_NONE ) &&
3388                            ( CodeInfo.opnd[OPND2].type & OP_I ) &&
3389                            CodeInfo.opnd[OPND2].InsFixup &&
3390                            CodeInfo.opnd[OPND2].InsFixup->sym->state == SYM_UNDEFINED )
3391                     CodeInfo.opnd[OPND2].type = OP_M;
3392             }
3393             if( check_size( &CodeInfo, opndx ) == ERROR ) {
3394                 DebugMsg(("ParseLine(%s): check_size() failed, exit\n", instr ));
3395                 return( ERROR );
3396             }
3397         }
3398 #if AMD64_SUPPORT
3399         if ( CodeInfo.Ofssize == USE64 ) {
3400 
3401             //if ( CodeInfo.x86hi_used && ( CodeInfo.x64lo_used || CodeInfo.prefix.rex & 7 ))
3402             if ( CodeInfo.x86hi_used && CodeInfo.prefix.rex )
3403                 EmitError( INVALID_USAGE_OF_AHBHCHDH );
3404 
3405             /* for some instructions, the "wide" flag has to be removed selectively.
3406              * this is to be improved - by a new flag in struct instr_item.
3407              */
3408             switch ( CodeInfo.token ) {
3409             case T_PUSH:
3410             case T_POP:
3411                 /* v2.06: REX.W prefix is always 0, because size is either 2 or 8 */
3412                 //if ( CodeInfo.opnd_type[OPND1] & OP_R64 )
3413                 CodeInfo.prefix.rex &= 0x7;
3414                 break;
3415             case T_CALL:
3416             case T_JMP:
3417 #if VMXSUPP /* v2.09: added */
3418             case T_VMREAD:
3419             case T_VMWRITE:
3420 #endif
3421                 /* v2.02: previously rex-prefix was cleared entirely,
3422                  * but bits 0-2 are needed to make "call rax" and "call r8"
3423                  * distinguishable!
3424                  */
3425                 //CodeInfo.prefix.rex = 0;
3426                 CodeInfo.prefix.rex &= 0x7;
3427                 break;
3428             case T_MOV:
3429                 /* don't use the Wide bit for moves to/from special regs */
3430                 if ( CodeInfo.opnd[OPND1].type & OP_RSPEC || CodeInfo.opnd[OPND2].type & OP_RSPEC )
3431                     CodeInfo.prefix.rex &= 0x7;
3432                 break;
3433             }
3434         }
3435 #endif
3436     }
3437 
3438     /* now call the code generator */
3439 
3440     return( codegen( &CodeInfo, oldofs ) );
3441 }
3442 
3443 /* process a file. introduced in v2.11 */
3444 
3445 void ProcessFile( struct asm_tok tokenarray[] )
3446 /*********************************************/
3447 {
3448     while ( ModuleInfo.EndDirFound == FALSE && GetTextLine( CurrSource ) ) {
3449         if ( PreprocessLine( CurrSource, tokenarray ) ) {
3450             ParseLine( tokenarray );
3451             if ( Options.preprocessor_stdout == TRUE && Parse_Pass == PASS_1 )
3452                 WritePreprocessedLine( CurrSource );
3453         }
3454     }
3455     return;
3456 }
3457 
3458