/* handle .model directive * syntax: .MODEL <FLAT|TINY|SMALL...> [,<C|PASCAL|STDCALL...>][,<NEARSTACK|FARSTACK>][,<OS_DOS|OS_OS2>] * sets fields * - ModuleInfo.model * - ModuleInfo.language * - ModuleInfo.distance * - ModuleInfo.ostype * if model is FLAT, defines FLAT pseudo-group * set default segment names for code and data */ ret_code ModelDirective( int i, struct asm_tok tokenarray[] ) /***********************************************************/ { enum model_type model; enum lang_type language; enum dist_type distance; enum os_type ostype; int index; uint_8 init; uint_8 initv; DebugMsg1(("ModelDirective enter\n")); /* v2.03: it may occur that "code" is defined BEFORE the MODEL * directive (i.e. DB directives in AT-segments). For FASTPASS, * this may have caused errors because contents of the ModuleInfo * structure was saved before the .MODEL directive. */ //if( Parse_Pass != PASS_1 ) { if( Parse_Pass != PASS_1 && ModuleInfo.model != MODEL_NONE ) { /* just set the model with SetModel() if pass is != 1. * This won't set the language ( which can be modified by * OPTION LANGUAGE directive ), but the language in ModuleInfo * isn't needed anymore once pass one is done. */ SetModel(); return( NOT_ERROR ); } i++; if ( tokenarray[i].token == T_FINAL ) { EmitError( EXPECTED_MEMORY_MODEL ); return( ERROR ); } /* get the model argument */ index = FindToken( tokenarray[i].string_ptr, ModelToken, sizeof( ModelToken )/sizeof( ModelToken[0] ) ); if( index >= 0 ) { if( ModuleInfo.model != MODEL_NONE ) { EmitWarn( 2, MODEL_DECLARED_ALREADY ); return( NOT_ERROR ); } model = index + 1; i++; } else { EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ); return( ERROR ); } /* get the optional arguments: language, stack distance, os */ init = 0; while ( i < ( Token_Count - 1 ) && tokenarray[i].token == T_COMMA ) { i++; if ( tokenarray[i].token != T_COMMA ) { if ( GetLangType( &i, tokenarray, &language ) == NOT_ERROR ) { initv = INIT_LANG; } else { index = FindToken( tokenarray[i].string_ptr, ModelAttr, sizeof( ModelAttr )/sizeof( ModelAttr[0] ) ); if ( index < 0 ) break; initv = ModelAttrValue[index].init; switch ( initv ) { case INIT_STACK: if ( model == MODEL_FLAT ) { EmitError( INVALID_MODEL_PARAM_FOR_FLAT ); return( ERROR ); } distance = ModelAttrValue[index].value; break; case INIT_OS: ostype = ModelAttrValue[index].value; break; } i++; } /* attribute set already? */ if ( initv & init ) { i--; break; } init |= initv; } } /* everything parsed successfully? */ if ( tokenarray[i].token != T_FINAL ) { EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ); return( ERROR ); } if ( model == MODEL_FLAT ) { if ( ( ModuleInfo.curr_cpu & P_CPU_MASK) < P_386 ) { EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE ); return( ERROR ); } DefineFlatGroup(); } ModuleInfo.model = model; if ( init & INIT_LANG ) { ModuleInfo.langtype = language; #if AMD64_SUPPORT /* v2.03: set header and fastcall type to win64 if x64 is active. * This is rather hackish, but currently there's no other possibility * to enable the win64 ABI from the source. */ if ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) == P_64 ) if ( language == LANG_FASTCALL && model == MODEL_FLAT && Options.output_format != OFORMAT_ELF ) { DebugMsg(("ModelDirective: FASTCALL type set to WIN64\n")); ModuleInfo.header_format = HFORMAT_WIN64; ModuleInfo.fctype = FCT_WIN64; } #endif } if ( init & INIT_STACK ) ModuleInfo.distance = distance; if ( init & INIT_OS ) ModuleInfo.ostype = ostype; SetModelDefaultSegNames(); SetModel(); return( NOT_ERROR ); }
/* handle .model directive * syntax: .MODEL <FLAT|TINY|SMALL...> [,<C|PASCAL|STDCALL...>][,<NEARSTACK|FARSTACK>][,<OS_DOS|OS_OS2>] * sets fields * - ModuleInfo.model * - ModuleInfo.language * - ModuleInfo.distance * - ModuleInfo.ostype * if model is FLAT, defines FLAT pseudo-group * set default segment names for code and data */ ret_code ModelDirective( int i, struct asm_tok tokenarray[] ) /***********************************************************/ { enum model_type model; enum lang_type language; enum dist_type distance; enum os_type ostype; int index; uint_8 init; uint_8 initv; DebugMsg1(("ModelDirective enter\n")); /* v2.03: it may occur that "code" is defined BEFORE the MODEL * directive (i.e. DB directives in AT-segments). For FASTPASS, * this may have caused errors because contents of the ModuleInfo * structure was saved before the .MODEL directive. */ //if( Parse_Pass != PASS_1 ) { if( Parse_Pass != PASS_1 && ModuleInfo.model != MODEL_NONE ) { /* just set the model with SetModel() if pass is != 1. * This won't set the language ( which can be modified by * OPTION LANGUAGE directive ), but the language in ModuleInfo * isn't needed anymore once pass one is done. */ SetModel(); return( NOT_ERROR ); } i++; if ( tokenarray[i].token == T_FINAL ) { return( EmitError( EXPECTED_MEMORY_MODEL ) ); } /* get the model argument */ index = FindToken( tokenarray[i].string_ptr, ModelToken, sizeof( ModelToken )/sizeof( ModelToken[0] ) ); if( index >= 0 ) { if( ModuleInfo.model != MODEL_NONE ) { //if ( Parse_Pass == PASS_1 ) /* not needed, this code runs in pass one only */ EmitWarn( 2, MODEL_DECLARED_ALREADY ); } model = index + 1; /* model is one-base ( 0 is MODEL_NONE ) */ i++; } else { return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].string_ptr ) ); } /* get the optional arguments: language, stack distance, os */ init = 0; while ( i < ( Token_Count - 1 ) && tokenarray[i].token == T_COMMA ) { i++; if ( tokenarray[i].token != T_COMMA ) { if ( GetLangType( &i, tokenarray, &language ) == NOT_ERROR ) { initv = INIT_LANG; } else { index = FindToken( tokenarray[i].string_ptr, ModelAttr, sizeof( ModelAttr )/sizeof( ModelAttr[0] ) ); if ( index < 0 ) break; initv = ModelAttrValue[index].init; switch ( initv ) { case INIT_STACK: if ( model == MODEL_FLAT ) { return( EmitError( INVALID_MODEL_PARAM_FOR_FLAT ) ); } distance = ModelAttrValue[index].value; break; case INIT_OS: ostype = ModelAttrValue[index].value; break; } i++; } /* attribute set already? */ if ( initv & init ) { i--; break; } init |= initv; } } /* everything parsed successfully? */ if ( tokenarray[i].token != T_FINAL ) { return( EmitErr( SYNTAX_ERROR_EX, tokenarray[i].tokpos ) ); } if ( model == MODEL_FLAT ) { if ( ( ModuleInfo.curr_cpu & P_CPU_MASK) < P_386 ) { return( EmitError( INSTRUCTION_OR_REGISTER_NOT_ACCEPTED_IN_CURRENT_CPU_MODE ) ); } #if AMD64_SUPPORT if ( ( ModuleInfo.curr_cpu & P_CPU_MASK ) >= P_64 ) /* cpu 64-bit? */ switch ( Options.output_format ) { case OFORMAT_COFF: ModuleInfo.fmtopt = &coff64_fmtopt; break; case OFORMAT_ELF: ModuleInfo.fmtopt = &elf64_fmtopt; break; }; #endif /* v2.11: define FLAT symbol is to early here, because defOfssize isn't set yet */ //DefineFlatGroup(); } ModuleInfo.model = model; if ( init & INIT_LANG ) ModuleInfo.langtype = language; if ( init & INIT_STACK ) ModuleInfo.distance = distance; if ( init & INIT_OS ) ModuleInfo.ostype = ostype; SetModelDefaultSegNames(); SetModel(); return( NOT_ERROR ); }