⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cprag86.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    if( CurToken == T_FLOAT ) {
        NextToken();                    /* 20-jun-92 */
        return( FIXWORD_FLOAT );
    }
    if( PragRecog( "seg" ) )    return( FIXWORD_SEGMENT );
    if( PragRecog( "offset" ) ) return( FIXWORD_OFFSET );
    if( PragRecog( "reloff" ) ) return( FIXWORD_RELOFF );
    return( FIXWORD_NONE );
}


enum sym_state AsmQueryExternal( char *name )
{
    SYM_HANDLE sym_handle;
    auto SYM_ENTRY sym;

    sym_handle = SymLook( CalcHash( name, strlen( name ) ), name );
    if( sym_handle == 0 ) return( SYM_UNDEFINED );
    SymGet( &sym, sym_handle );
    switch( sym.stg_class ) {
    case SC_AUTO:
    case SC_REGISTER:
        return( SYM_STACK );
    }
    return( SYM_EXTERNAL );
}

#if _CPU == 8086
    #define SYM_INT     SYM_INT2
    #define SYM_FFAR    SYM_FAR2
    #define SYM_FNEAR   SYM_NEAR2
    #define SYM_DFAR    SYM_INT4
    #define SYM_DNEAR   SYM_INT2
#else
    #define SYM_INT     SYM_INT4
    #define SYM_FFAR    SYM_FAR4
    #define SYM_FNEAR   SYM_NEAR2
    #define SYM_DFAR    SYM_INT6
    #define SYM_DNEAR   SYM_INT4
#endif

static int CodePtrType( int flags )
{
    if( flags & FLAG_FAR ) {
        return( SYM_FFAR );
    } else if( flags & FLAG_NEAR ) {
        return( SYM_FNEAR );
    } else if( TargetSwitches & BIG_CODE ) {
        return( SYM_FFAR );
    } else {
        return( SYM_FNEAR );
    }
}


static int PtrType( TYPEPTR typ, int flags )
{
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_FUNCTION ) {
        return( CodePtrType( flags ) );
    } else if( flags & (FLAG_FAR|FLAG_HUGE) ) {
        return( SYM_DFAR );
    } else if( flags & FLAG_NEAR ) {
        return( SYM_DNEAR );
    } else if( TargetSwitches & BIG_DATA ) {
        return( SYM_DFAR );
    } else {
        return( SYM_DNEAR );
    }
}

/* matches enum DataType in ctypes.h */
static enum sym_type AsmDataType[] = {
        SYM_INT1,       /* TYPE_CHAR,*/
        SYM_INT1,       /* TYPE_UCHAR,*/
        SYM_INT2,       /* TYPE_SHORT,*/
        SYM_INT2,       /* TYPE_USHORT,*/
        SYM_INT,        /* TYPE_INT,*/
        SYM_INT,        /* TYPE_UINT,*/
        SYM_INT4,       /* TYPE_LONG,*/
        SYM_INT4,       /* TYPE_ULONG,*/
        SYM_INT8,       /* TYPE_LONG64,*/
        SYM_INT8,       /* TYPE_ULONG64,*/
        SYM_FLOAT4,     /* TYPE_FLOAT,*/
        SYM_FLOAT8,     /* TYPE_DOUBLE,*/
        0,              /* TYPE_POINTER,*/
        0,              /* TYPE_ARRAY,*/
        0,              /* TYPE_STRUCT,*/
        0,              /* TYPE_UNION,*/
        0,              /* TYPE_FUNCTION,*/
        0,              /* TYPE_FIELD,*/
        SYM_INT1,       /* TYPE_VOID,*/
        0,              /* TYPE_ENUM,*/
        0,              /* TYPE_TYPEDEF,*/
        0,              /* TYPE_UFIELD,*/
        0,              /* TYPE_DOT_DOT_DOT,*/
        SYM_INT1,       /* TYPE_PLAIN_CHAR,*/
        SYM_INT2,       /* TYPE_WCHAR,  */
        SYM_FLOAT10,    /* TYPE_LONG_DOUBLE */
        0,              /* TYPE_FCOMPLEX, */
        0,              /* TYPE_DCOMPLEX, */
        0,              /* TYPE_LDCOMPLEX, */
        SYM_FLOAT4,     /* TYPE_FIMAGINARY, */
        SYM_FLOAT8,     /* TYPE_DIMAGINARY, */
        SYM_FLOAT10,    /* TYPE_LDIMAGINARY, */
        SYM_INT1,       /* TYPE_BOOL, */
        0,              /* TYPE_UNUSED,  */
};

local int AsmType( TYPEPTR typ, int flags )
{
    while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
    switch( typ->decl_type ) {
    case TYPE_STRUCT:
    case TYPE_UNION:
        return( SYM_INT1 );
    case TYPE_ARRAY:
        return( AsmType( typ->object, flags ) );
    case TYPE_FIELD:
    case TYPE_UFIELD:
        return( AsmDataType[ typ->u.f.field_type ] );
    case TYPE_FUNCTION:
        return( CodePtrType( flags ) );
    case TYPE_POINTER:
        return( PtrType( typ->object, typ->u.p.decl_flags ) );
    case TYPE_ENUM:
        typ = typ->object;
        /* fall through */
    default:
        return( AsmDataType[ typ->decl_type ] );
    }
}

enum sym_type AsmQueryType( char *name )
{
    SYM_HANDLE sym_handle;
    auto SYM_ENTRY sym;

    sym_handle = SymLook( CalcHash( name, strlen( name ) ), name );
    if( sym_handle == 0 ) return( SYM_INT1 );
    SymGet( &sym, sym_handle );
    return( AsmType( sym.sym_type, sym.attrib ) );
}

static int InsertFixups( unsigned char *buff, unsigned i )
{
                        /* additional slop in buffer to simplify the code */
    unsigned char       temp[ MAXIMUM_BYTESEQ + 1 + 2*sizeof(long) ];
    struct asmfixup     *fix;
    struct asmfixup     *head;
    struct asmfixup     *chk;
    struct asmfixup     *next;
    struct asmfixup     **owner;
    unsigned char       *dst;
    unsigned char       *src;
    unsigned char       *end;
    byte_seq            *seq;
    byte_seq_len        perform_fixups;
    unsigned char       cg_fix;
    SYM_HANDLE          sym_handle;
    SYM_ENTRY           sym;
    char                *name;
    unsigned            skip;
    int                 mutate_to_segment;
    int                 uses_auto;
#if _CPU == 8086
    int                 fixup_padding;
#endif

    uses_auto = 0;
    perform_fixups = 0;
    head = FixupHead;
    if( head != NULL ) {
        FixupHead = NULL;
        /* sort the fixup list in increasing fixup_loc's */
        for( fix = head; fix != NULL; fix = next ) {
            owner = &FixupHead;
            for( ;; ) {
                chk = *owner;
                if( chk == NULL ) break;
                if( chk->fixup_loc > fix->fixup_loc ) break;
                owner = &chk->next;
            }
            next = fix->next;
            fix->next = *owner;
            *owner = fix;
        }
        dst = temp;
        src = buff;
        end = src + i;
        fix = FixupHead;
        owner = &FixupHead;
        /* insert fixup escape sequences */
        while( src < end ) {
            if( fix != NULL && fix->fixup_loc == (src - buff) ) {
                name = fix->name;
                if( name != NULL ) {
                    sym_handle = SymLook( CalcHash( name, strlen( name ) ),
                                name );
                    if( sym_handle == 0 ) {
                        CErr2p( ERR_UNDECLARED_SYM, name );
                        return( 0 );
                    }
                    SymGet( &sym, sym_handle );
                    sym.flags |= SYM_REFERENCED | SYM_ADDR_TAKEN;
                    switch( sym.stg_class ) {
                    case SC_REGISTER:
                    case SC_AUTO:
                        sym.flags |= SYM_USED_IN_PRAGMA;
                        CurFuncNode->op.func.flags &= ~FUNC_OK_TO_INLINE;
                        uses_auto = 1;
                        break;
                    }
                    SymReplace( &sym, sym_handle );
                }
                /* insert fixup information */
                skip = 0;
                *dst++ = FLOATING_FIXUP_BYTE;
                mutate_to_segment = 0;
#if _CPU == 8086
                fixup_padding = 0;
#endif
                switch( fix->fixup_type ) {
                case FIX_SEG:
                    if( name == NULL ) {
                        /* special case for floating point fixup */
                        if( *src != 0x9b ) { /* FWAIT */
                            *dst++ = 0x9b;
                        }
                    } else {
                        skip = 2;
                        cg_fix = FIX_SYM_SEGMENT;
                    }
                    break;
                case FIX_RELOFF8:
                    CErr2p( ERR_UNREACHABLE_SYM, name );
                    break;
                case FIX_RELOFF16:
                    skip = 2;
                    cg_fix = FIX_SYM_RELOFF;
                    break;
                case FIX_RELOFF32:
                    skip = 4;
                    cg_fix = FIX_SYM_RELOFF;
#if _CPU == 8086
                    fixup_padding = 1;
#endif
                    break;
                case FIX_PTR16:
                    mutate_to_segment = 1;
                    /* fall through */
                case FIX_OFF16:
                    skip = 2;
                    cg_fix = FIX_SYM_OFFSET;
                    break;
                case FIX_PTR32:
                    mutate_to_segment = 1;
                    /* fall through */
                case FIX_OFF32:
                    skip = 4;
                    cg_fix = FIX_SYM_OFFSET;
#if _CPU == 8086
                    fixup_padding = 1;
#endif
                    break;
                }
                if( skip != 0 ) {
                    *dst++ = cg_fix;
                    *((unsigned long *)dst) = sym_handle;
                    dst += sizeof( long );
                    *((unsigned long *)dst) = fix->offset;
                    dst += sizeof( long );
                    src += skip;
                }
#if _CPU == 8086
                if( fixup_padding ) {
                    // add offset fixup padding to 32-bit
                    // cg create only 16-bit offset fixup
                    *dst++ = 0;
                    *dst++ = 0;
                    //
                }
#endif
                if( mutate_to_segment ) {
                    /*
                        Since the CG escape sequences don't allow for
                        FAR pointer fixups, we have to split them into two.
                        This is done by doing the offset fixup first, then
                        mutating the fixup structure to look like a segment
                        fixup one near pointer size later.
                    */
                    fix->fixup_type = FIX_SEG;
                    fix->fixup_loc += skip;
                    fix->offset = 0;
                } else {
                    head = fix;
                    fix = fix->next;
                    if( head->external ) {
                        *owner = fix;
                        if( head->name != NULL ) {
                            CMemFree( head->name );
                        }
                        CMemFree( head );
                    } else {
                        owner = &head->next;
                    }
                }
            } else {
                if( *src == FLOATING_FIXUP_BYTE ) {
                    *dst++ = FLOATING_FIXUP_BYTE;
                }
                *dst++ = *src++;
            }
            if( dst > &temp[ MAXIMUM_BYTESEQ ] ) {
                CErr1( ERR_TOO_MANY_BYTES_IN_PRAGMA );
                return( 0 );
            }
        }
        buff = temp;
        i = dst - temp;
        perform_fixups = DO_FLOATING_FIXUPS;
    }
    seq = (byte_seq *) CMemAlloc( sizeof(byte_seq) + i );
    seq->length = i | perform_fixups;
    memcpy( &seq->data[0], buff, i );
    CurrInfo->code = seq;
    return( uses_auto );
}


local void AddAFix( unsigned i, char *name, unsigned type, unsigned long off )
{
    struct asmfixup     *fix;

    fix = (struct asmfixup *)CMemAlloc( sizeof( *fix ) );
    fix->external = 1;
    fix->fixup_loc = i;
    fix->name = name;
    fix->offset = off;
    fix->fixup_type = type;
    fix->next = FixupHead;
    FixupHead = fix;
}

local void FreeAsmFixups()
{
    struct asmfixup     *fix;

    for(;;) {
        fix = FixupHead;
        if( fix == NULL ) break;
        FixupHead = fix->next;
        CMemFree( fix );
    }
}


local int GetByteSeq( void )
{
    auto unsigned char  buff[ MAXIMUM_BYTESEQ + 32 ];
    int                 i;
    char                *name;
    unsigned long       offset;
    unsigned            fixword;
    int                 uses_auto;
    char                too_many_bytes;

    CompFlags.pre_processing = 1;       /* enable macros */
    NextToken();
    too_many_bytes = 0;
    i = 0;
    for(;;) {
#if _CPU == 8086  ||  _CPU == 386
        if( CurToken == T_STRING ) {    /* 06-sep-91 */
            Address = i;
            CodeBuffer = &buff[0];
            AsmLine( Buffer );
            i = Address;
            if( i >= MAXIMUM_BYTESEQ ) {
                if( ! too_many_bytes ) {
                    CErr1( ERR_TOO_MANY_BYTES_IN_PRAGMA );
                    too_many_bytes = 1;
                }
                i = 0;          // reset index to we don't overrun buffer
            }
            NextToken();
            if( CurToken == T_COMMA )  NextToken();
        } else
#endif

⌨️ 快捷键说明

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