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 + -
显示快捷键?