asmstmt.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 238 行

C
238
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "plusplus.h"
#include "preproc.h"
#include "name.h"
#include "memmgr.h"
#include "errdefns.h"
#include "cgdata.h"
#include "pragdefn.h"
#include "pdefn2.h"
#include "ptree.h"
#include "scan.h"
#include "asmstmt.h"

#if _INTEL_CPU
#include "asminlin.h"
#else
#include "asinline.h"
#endif

#ifdef DISABLE_ASM_STMT

PTREE AsmStmt( void )
{
    return NULL;
}

#else

static void ensureBufferReflectsCurToken( void )
{
    if( TokenUsesBuffer( CurToken ) ) {
        if( CurToken == T_CONSTANT ) {
            switch( ConstType ) {
            case TYP_UCHAR:
            case TYP_UINT:
            case TYP_ULONG:
                ultoa( U32Fetch( Constant64 ), Buffer, 10 );
                break;
            case TYP_SCHAR:
            case TYP_SINT:
            case TYP_SLONG:
                ltoa( U32Fetch( Constant64 ), Buffer, 10 );
                break;
            case TYP_ULONG64:
            case TYP_SLONG64:
                sti64cpy( Buffer, Constant64.u._64[0] );
                break;
            }
        }
    } else {
        strcpy( Buffer, Tokens[ CurToken ] );
    }

}

static PTREE genFnCall( char *name )
{
    return( PTreeBinary( CO_CALL, PTreeId( name ), NULL ) );
}

static boolean endOfAsmStmt( void )
{
    if( CurToken == T_EOF ) return( TRUE );
    if( CurToken == T_NULL ) return( TRUE );
    if( CurToken == T___ASM ) return( TRUE );
    if( CurToken == T_RIGHT_BRACE ) return( TRUE );
    if( CurToken == T_ALT_RIGHT_BRACE ) return( TRUE );
    if( CurToken == T_SEMI_COLON ) return( TRUE );
    return( FALSE );
}

static boolean isId( unsigned token )
{
    if( token == T_ID ) {
        return( TRUE );
    }
    if( token >= FIRST_KEYWORD && token <= LAST_KEYWORD ) {
        return( TRUE );
    }
    return( FALSE );
}

static void getAsmLine( VBUF *buff )
{
    char line[256];

    if( endOfAsmStmt() )
        return;
    /* reserve at least MAX_INSTR_SIZE bytes in the buffer */
    VbufReqd( buff, ((AsmCodeAddress+MAX_INSTR_SIZE) + (MAX_INSTR_SIZE-1)) & ~(MAX_INSTR_SIZE-1) );
    AsmCodeBuffer = buff->buf;
    ensureBufferReflectsCurToken();
    if( isId( CurToken ) && strcmp( Buffer, "__emit" ) == 0 ) {
        strcpy( line, AsmSysDefineByte() );
        strcat( line, " " );
        NextToken();
        ensureBufferReflectsCurToken();
    } else {
        line[0] = '\0';
    }
    for(;;) {
        if( endOfAsmStmt() ) break;
        strncat( line, Buffer, sizeof(line)-1 );
        switch( CurToken ) {
        case T_ALT_XOR:
        case T_ALT_EXCLAMATION:
        case T_ALT_AND_AND:
        case T_ALT_OR_OR:
            strncat( line, " ", sizeof(line)-1 );
            break;
        default:
            if( isId( CurToken ) )
                strncat( line, " ", sizeof(line)-1 );
            break;
        }
        NextToken();
        ensureBufferReflectsCurToken();
    }
    if( line[0] != '\0' ) {
        AsmLine( line );
    }
    VbufUsed( buff, AsmCodeAddress );
    if( CurToken == T_SEMI_COLON ) {
        // ; .ASM comment
        for(;;) {
            NextToken();
            if( CurToken == T_EOF ) break;
            if( CurToken == T_NULL ) break;
        }
    }
}

int NextTokenSkipEOL( void )
/**************************/
{
    PPState = PPS_NORMAL;
    NextToken();
    PPState = PPS_EOL;
    return( CurToken );
}

PTREE AsmStmt( void )
/*******************/
{
    boolean     uses_auto;
    AUX_INFO    *aux_info;
    unsigned    skip_token;
    unsigned    skip_alt_token;
    PTREE       expr;
    TYPE        fn_type;
    TYPE        ret_type;
    SYMBOL      sym;
    char        *fn_name;
    auto VBUF   code_buffer;
    ppstate_t   save_ppstate;

    save_ppstate = PPState;
    PPState = PPS_EOL;
    PPStateAsm = TRUE;
    VbufInit( &code_buffer );
    NextTokenSkipEOL();
    AsmSysInit();
    if( ( CurToken == T_LEFT_BRACE ) || ( CurToken == T_ALT_LEFT_BRACE ) ) {
        NextTokenSkipEOL();
        for(;;) {
            getAsmLine( &code_buffer );
            if( CurToken == T_RIGHT_BRACE ) break;
            if( CurToken == T_ALT_RIGHT_BRACE ) break;
            if( CurToken == T_EOF ) break;
            NextTokenSkipEOL();
        }
        skip_token = T_RIGHT_BRACE;
        skip_alt_token = T_ALT_RIGHT_BRACE;
    } else {
        getAsmLine( &code_buffer );
        skip_token = skip_alt_token = T_NULL;
    }
    PPStateAsm = FALSE;
    PPState = save_ppstate;
    if( ( CurToken == skip_token ) || ( CurToken == skip_alt_token ) ) {
        NextToken();
    }
    if( AsmCodeAddress != 0 ) {
        fn_name = NameDummy();
        aux_info = AsmSysCreateAux( fn_name );
        uses_auto = AsmSysInsertFixups( &code_buffer );
        if( uses_auto ) {
            AsmSysUsesAuto();
        }
        AsmSysDone();
        ret_type = GetBasicType( TYP_VOID );
        fn_type = MakeModifiableFunction( ret_type, NULL );
        fn_type->u.f.pragma = aux_info;
        fn_type = CheckDupType( fn_type );
        sym = SymCreateFileScope( fn_type, SC_NULL, SF_NULL, fn_name );
        LinkageSet( sym, "C" );
        expr = genFnCall( fn_name );
    } else {
        expr = NULL;
    }
    AsmSysFini();
    VbufFree( &code_buffer );
    return( expr );
}

#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?