cmdlnx86.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,273 行 · 第 1/3 页
C
1,273 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Command line processing for C++ compiler (x86 targets)
*
****************************************************************************/
#include "plusplus.h"
#include "errdefns.h"
#include "memmgr.h"
#include "macro.h"
#include "cmdline.h"
#include "cgdata.h"
#include "codegen.h"
#include "pragdefn.h"
#ifdef __OSI__
#include "ostype.h"
#endif
#include "cmdlnpr1.gh"
#include "cmdlnsys.h"
typedef enum { // flags to control memory model settings
MMC_DS = 0x01, // 'ds' reg is pegged/floated by user
MMC_FS = 0x02, // 'fs' reg is pegged/floated by user
MMC_GS = 0x04, // 'gs' reg is pegged/floated by user
MMC_WIN = 0x08, // model forced by Windows
MMC_NETWARE = 0x10, // model forced by NetWare
MMC_NULL = 0
} mem_model_control;
#if 0
#define DEF_SWITCHES_ALL ( MEMORY_LOW_FAILS | ENABLE_FP_EXCEPTIONS )
#else
#define DEF_SWITCHES_ALL ( MEMORY_LOW_FAILS )
#endif
#if _CPU != 386
#define DEF_TARGET_SWITCHES CHEAP_POINTER
#define DEF_SWITCHES 0
#define DEFAULT_CPU CPU_86
#define DEFAULT_FPU FPU_87
#else
#define DEF_TARGET_SWITCHES CHEAP_POINTER|USE_32|FLAT_MODEL
#define DEF_SWITCHES 0
#define DEFAULT_CPU CPU_686
#define DEFAULT_FPU FPU_387
#endif
#if _CPU == 386
#define MM_ARCH "386"
#else
#define MM_ARCH "I86"
#endif
void CmdSysInit( void )
/*********************/
{
GenSwitches = DEF_SWITCHES | DEF_SWITCHES_ALL;
TargetSwitches = DEF_TARGET_SWITCHES;
SET_CPU( CpuSwitches, DEFAULT_CPU );
SET_FPU( CpuSwitches, DEFAULT_FPU );
SET_FPU_EMU( CpuSwitches );
Stack87 = 8;
CodeClassName = NULL;
TextSegName = strsave( "" );
DataSegName = strsave( "" );
GenCodeGroup = strsave( "" );
CompFlags.use_stdcall_at_number = 1;
CompFlags.register_conventions = 1;
}
void CmdSysFini( void )
/*********************/
{
CMemFreePtr( &ModuleName );
CMemFreePtr( &CodeClassName );
CMemFreePtr( &DataSegName );
CMemFreePtr( &GenCodeGroup );
}
char *CmdSysEnvVar( void )
/************************/
{
#if _CPU == 386
return( "WPP386" );
#else
return( "WPP" );
#endif
}
void CmdX86CheckStack87( unsigned *p )
/************************************/
{
// 0 means no change to default
if( *p <= 8 ) {
return;
}
*p = 0;
}
void CmdX86CheckThreshold( unsigned *p )
/**************************************/
{
// 0 is allowed
if( *p <= 32767 ) {
return;
}
*p = 256;
}
void CmdSysSetMaxOptimization( void )
/***********************************/
{
TargetSwitches |= I_MATH_INLINE;
}
static void defineM_IX86Macro( void )
{
unsigned cpu;
char buff[32];
strcpy( buff, "_M_IX86=" );
#if _CPU == 386
cpu = 3;
#else
cpu = 0;
#endif
switch( GET_CPU( CpuSwitches ) ) {
case CPU_86: cpu = 0; break;
case CPU_186: cpu = 1; break;
case CPU_286: cpu = 2; break;
case CPU_386: cpu = 3; break;
case CPU_486: cpu = 4; break;
case CPU_586: cpu = 5; break;
case CPU_686: cpu = 6; break;
}
ConcatBase10( buff, cpu * 100 );
PreDefineStringMacro( buff );
}
static void setWindowsSystem( void )
{
#if _CPU == 386
PreDefineStringMacro( "__WINDOWS_386__" );
TargetSwitches |= FLOATING_FS;
SET_FPU_INLINE( CpuSwitches );
#else
PreDefineStringMacro( "__WINDOWS__" );
PreDefineStringMacro( "_WINDOWS" );
TargetSwitches |= WINDOWS | CHEAP_WINDOWS;
TargetSwitches &= ~ FLOATING_DS;
#endif
}
static void setFinalTargetSystem( OPT_STORAGE *data, char *target_name )
{
char buff[128];
TargetSystem = TS_OTHER;
#if _CPU == 386
PreDefineStringMacro( "M_I386" );
PreDefineStringMacro( "_M_I386" );
PreDefineStringMacro( "__386__" );
#else
PreDefineStringMacro( "M_I86" );
PreDefineStringMacro( "_M_I86" );
PreDefineStringMacro( "__I86__" );
#endif
PreDefineStringMacro( "__X86__" );
PreDefineStringMacro( "_X86_" );
if( target_name == NULL ) {
#if defined( __OSI__ )
switch( __OS ) {
case OS_DOS:
case OS_WIN:
SetTargetLiteral( &target_name, "DOS" );
break;
case OS_OS2:
SetTargetLiteral( &target_name, "OS2" );
break;
case OS_NT:
SetTargetLiteral( &target_name, "NT" );
break;
}
#elif defined( __QNX__ )
SetTargetLiteral( &target_name, "QNX" );
#elif defined( __LINUX__ )
SetTargetLiteral( &target_name, "LINUX" );
#elif defined( __OS2__ )
SetTargetLiteral( &target_name, "OS2" );
#elif defined( __NT__ )
SetTargetLiteral( &target_name, "NT" );
#elif defined( __DOS__ )
SetTargetLiteral( &target_name, "DOS" );
#else
#error "Target System not defined"
#endif
}
if( 0 == strcmp( target_name, "DOS" ) ) {
TargetSystem = TS_DOS;
PreDefineStringMacro( "MSDOS" );
PreDefineStringMacro( "__DOS__" );
PreDefineStringMacro( "_DOS" );
#if _CPU == 386
} else if( 0 == strcmp( target_name, "NETWARE" ) ) {
TargetSystem = TS_NETWARE;
PreDefineStringMacro( "__NETWARE_386__" );
} else if( 0 == strcmp( target_name, "NETWARE5" ) ) {
TargetSystem = TS_NETWARE5;
PreDefineStringMacro( "__NETWARE_386__" );
PreDefineStringMacro( "__NETWARE__" );
/* can get away with this because "netware5" is longer */
strcpy( target_name, "NETWARE" );
} else if( 0 == strcmp( target_name, "NT" ) ) {
PreDefineStringMacro( "_WIN32" );
TargetSystem = TS_NT;
} else if( 0 == strcmp( target_name, "OS2" ) ) {
TargetSystem = TS_OS2;
} else if( 0 == strcmp( target_name, "QNX" ) ) {
TargetSystem = TS_QNX;
PreDefineStringMacro( "__QNX__" );
PreDefineStringMacro( "__UNIX__" );
} else if( 0 == strcmp( target_name, "LINUX" ) ) {
TargetSystem = TS_LINUX;
PreDefineStringMacro( "__LINUX__" );
PreDefineStringMacro( "__UNIX__" );
#endif
} else if( 0 == strcmp( target_name, "WINDOWS" ) ) {
TargetSystem = TS_WINDOWS;
setWindowsSystem();
} else if( 0 == strcmp( target_name, "CHEAP_WINDOWS" ) ) {
#if _CPU == 8086
TargetSystem = TS_CHEAP_WINDOWS;
#else
TargetSystem = TS_WINDOWS;
#endif
/* can get away with this because "cheap_windows" is longer */
strcpy( target_name, "WINDOWS" );
setWindowsSystem();
} else {
TargetSystem = TS_OTHER;
}
strcpy( buff, "__" );
strcat( buff, target_name );
strcat( buff, "__" );
PreDefineStringMacro( buff );
/*
// Note the hacks for windows/cheap_windows & netware/netware5, above.
*/
strcpy( buff, target_name );
strcat( buff, "_INCLUDE" );
MergeIncludeFromEnv( buff );
MergeIncludeFromEnv( "INCLUDE" );
CMemFree( target_name );
if( data->bm ) {
CompFlags.target_multi_thread = 1;
}
if( data->bd ) {
switch( TargetSystem ) {
case TS_WINDOWS:
#if _CPU == 8086
case TS_CHEAP_WINDOWS:
#endif
break;
default:
CompFlags.target_multi_thread = 1;
}
}
}
static void setMemoryModel( OPT_STORAGE *data, mem_model_control control )
{
char model;
unsigned long bit;
if( data->mem_model == OPT_mem_model_default ) {
#if _CPU == 386
data->mem_model = OPT_mem_model_mf;
#else
data->mem_model = OPT_mem_model_ms;
#endif
}
#if _CPU == 386
if( control & MMC_NETWARE ) {
data->mem_model = OPT_mem_model_ms;
}
#endif
bit = 0;
switch( data->mem_model ) {
case OPT_mem_model_ms:
model = 's';
DataPtrSize = TARGET_POINTER;
CodePtrSize = TARGET_POINTER;
PreDefineStringMacro( "M_" MM_ARCH "SM" );
PreDefineStringMacro( "_M_" MM_ARCH "SM" );
PreDefineStringMacro( "__SMALL__" );
CompFlags.strings_in_code_segment = 0;
TargetSwitches &= ~CONST_IN_CODE;
bit |= CHEAP_POINTER;
break;
case OPT_mem_model_mm:
model = 'm';
WatcallInfo.cclass |= FAR;
DataPtrSize = TARGET_POINTER;
CodePtrSize = TARGET_FAR_POINTER;
PreDefineStringMacro( "M_" MM_ARCH "MM" );
PreDefineStringMacro( "_M_" MM_ARCH "MM" );
PreDefineStringMacro( "__MEDIUM__" );
CompFlags.strings_in_code_segment = 0;
TargetSwitches &= ~CONST_IN_CODE;
bit |= BIG_CODE | CHEAP_POINTER;
break;
case OPT_mem_model_ml:
model = 'l';
PreDefineStringMacro( "M_" MM_ARCH "LM" );
PreDefineStringMacro( "_M_" MM_ARCH "LM" );
PreDefineStringMacro( "__LARGE__" );
WatcallInfo.cclass |= FAR;
CodePtrSize = TARGET_FAR_POINTER;
DataPtrSize = TARGET_FAR_POINTER;
bit |= BIG_CODE | BIG_DATA | CHEAP_POINTER;
break;
case OPT_mem_model_mc:
model = 'c';
PreDefineStringMacro( "M_" MM_ARCH "CM" );
PreDefineStringMacro( "_M_" MM_ARCH "CM" );
PreDefineStringMacro( "__COMPACT__" );
CodePtrSize = TARGET_POINTER;
DataPtrSize = TARGET_FAR_POINTER;
bit |= BIG_DATA | CHEAP_POINTER;
break;
#if _CPU == 386
case OPT_mem_model_mfi:
CompFlags.mfi_switch_used = 1;
/* fall thru */
case OPT_mem_model_mf:
model = 's';
DataPtrSize = TARGET_POINTER;
CodePtrSize = TARGET_POINTER;
PreDefineStringMacro( "M_" MM_ARCH "FM" );
PreDefineStringMacro( "_M_" MM_ARCH "FM" );
PreDefineStringMacro( "__FLAT__" );
bit |= FLAT_MODEL;
break;
#else
case OPT_mem_model_mh:
model = 'h';
PreDefineStringMacro( "M_" MM_ARCH "HM" );
PreDefineStringMacro( "_M_" MM_ARCH "HM" );
PreDefineStringMacro( "__HUGE__" );
WatcallInfo.cclass |= FAR;
CodePtrSize = TARGET_FAR_POINTER;
DataPtrSize = TARGET_FAR_POINTER;
bit |= BIG_CODE | BIG_DATA;
break;
#endif
default:
DbgNever();
}
// setup default "floating" segment registers
#if _CPU == 8086
bit |= FLOATING_ES;
#else
// 386 flat model needs at least one floating segment register
bit |= FLOATING_GS;
if( !( bit & FLAT_MODEL ) ) {
bit |= FLOATING_ES;
}
#endif
if( bit & BIG_DATA ) {
bit |= FLOATING_DS;
}
if( control & ( MMC_DS | MMC_WIN ) ) {
bit &= ~FLOATING_DS;
} else {
TargetSwitches &= ~ FLOATING_DS;
}
if( control & MMC_FS ) {
bit &= ~FLOATING_FS;
} else {
TargetSwitches &= ~ FLOATING_FS;
}
if( control & MMC_GS ) {
bit &= ~FLOATING_GS;
} else {
TargetSwitches &= ~ FLOATING_GS;
}
TargetSwitches &= ~( FLAT_MODEL | BIG_CODE | BIG_DATA | CHEAP_POINTER
| FLOATING_ES);
TargetSwitches |= bit;
#if _CPU == 8086
if( data->bm ) { // .DLL
strcpy( DLL_CLIB_Name, "2clibmt?" );
} else {
if( control & MMC_WIN ) {
strcpy( DLL_CLIB_Name, "2clib?" );
} else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?