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

📄 cgen2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

static cg_name TryExceptionInfoAddr()
{
    cg_name     name;

    name = TryFieldAddr( offsetof( struct try_block, exception_info ) );
//    name = CGUnary( O_POINTS, name, T_POINTER );
//    name = CGUnary( O_POINTS, name, T_POINTER );
    return( name );
}

static void SetTryTable( back_handle except_table )
{
    cg_name     name;
    cg_name     table;

    name = TryFieldAddr( offsetof( struct try_block, scope_table ) );
    table = CGBackName( except_table, T_POINTER );
    CGDone( CGAssign( name, table, T_POINTER ) );
}

static void SetTryScope( int scope )
{
    cg_name     name;

    name = TryFieldAddr( offsetof( struct try_block, scope_index ) );
    CGDone( CGAssign( name, CGInteger( scope, T_UINT_1 ), T_UINT_1 ) );
}

static void EndFinally()
{
    cg_name      name;
    cg_name      func;
    LABEL_HANDLE label_handle;
    call_handle  call_list;

    label_handle = BENewLabel();
    name = TryFieldAddr( offsetof( struct try_block, unwindflag ) );
    name = CGUnary( O_POINTS, name, T_UINT_1 );
    name = CGCompare( O_EQ, name, CGInteger( 0, T_UINT_1 ), T_UINT_1 );
    CGControl( O_IF_TRUE, name, label_handle );
    func = CGFEName( SymFinally, T_CODE_PTR );
    call_list = CGInitCall( func, T_INTEGER, SymFinally );
    CGDone( CGCall( call_list ) );
    CGControl( O_LABEL, NULL, label_handle );
    BEFiniLabel( label_handle );
}

static cg_name TryAbnormalTermination()
{
    cg_name      name;

    name = TryFieldAddr( offsetof( struct try_block, unwindflag ) );
    name = CGUnary( O_POINTS, name, T_UINT_1 );
    return( name );
}

static void CallTryRtn( SYM_HANDLE try_rtn, cg_name parm )
{
    call_handle call_list;

    call_list = CGInitCall( CGFEName( try_rtn, T_POINTER ),
                            T_INTEGER, try_rtn );
    CGAddParm( call_list, parm, T_POINTER );
    CGDone( CGCall( call_list ) );
}

static void CallTryInit( void )
{
    CallTryRtn( SymTryInit, CGFEName( TrySymHandle, T_POINTER ) );
}

static void CallTryFini( void )
{
    cg_name     name;

    name = TryFieldAddr( offsetof( struct try_block, next ) );
    name = CGUnary( O_POINTS, name, T_POINTER );
    CallTryRtn( SymTryFini, name );
}

static void TryUnwind( int scope_index )
{
    call_handle call_list;
    cg_name     parm;

    call_list = CGInitCall( CGFEName( SymTryUnwind, T_POINTER ),
                            T_INTEGER, SymTryUnwind );
    parm = CGInteger( scope_index, T_UINT_1 );
    CGAddParm( call_list, parm, T_INTEGER );
    CGDone( CGCall( call_list ) );
}
#endif

#if _MACHINE == _ALPHA
local void GenVaStart( cg_name op1, cg_name offset )
{
    cg_name     name;
    cg_name     baseptr;

    baseptr = CGVarargsBasePtr( T_POINTER );
    name = CGLVAssign( op1, baseptr, T_POINTER );
    name = CGBinary( O_PLUS, name, CGInteger( TARGET_POINTER, T_INTEGER ),
                                        T_POINTER );
    name = CGAssign( name, offset, T_INTEGER );
    CGDone( name );
}
#elif _MACHINE == _PPC
local void GenVaStart( cg_name op1, cg_name offset )
{
    cg_name     name;

    offset = offset;
    name = CGUnary( O_VA_START, op1, T_POINTER );
    CGDone( name );
}
#endif

static cg_name PushSym( OPNODE *node )
{
    cg_name     name;
    cg_type     dtype;
    TYPEPTR     typ;
    SYM_ENTRY   sym;

    SymGet( &sym, node->sym_handle );
    typ = sym.sym_type;
    if( sym.flags & SYM_FUNCTION ){
        dtype = CodePtrType( sym.attrib );
    }else{
        dtype = CGenType( typ );
    }
    if( sym.flags & SYM_FUNC_RETURN_VAR ) {
        name = CGTempName( sym.info.return_var, dtype );
    } else {
        name = CGFEName( node->sym_handle, dtype );
    }
    if( node->flags & OPFLAG_UNALIGNED ) {
        name = CGAttr( name, CG_SYM_UNALIGNED );
    }
    if( node->flags & OPFLAG_VOLATILE ) {
        name = CGVolatile( name );
    } else {
        name = ForceVolatileFloat( name, typ );
    }
    name = CGUnary( O_POINTS, name, dtype );
    return( name );
}

static cg_name PushSymAddr( OPNODE *node )
{
    cg_name     name;
    cg_type     dtype;
    SYM_ENTRY   sym;
    TYPEPTR     typ;

    SymGet( &sym, node->sym_handle );
    typ = sym.sym_type;
    if( sym.flags & SYM_FUNCTION ){
        dtype = CodePtrType( sym.attrib );
    }else{
         dtype = CGenType( typ );
    }
    if( sym.flags & SYM_FUNC_RETURN_VAR ) {
        name = CGTempName( sym.info.return_var, dtype );
    } else {
        name = CGFEName( node->sym_handle, dtype );
     // if( (sym.attrib & FLAG_VOLATILE) ||
     //     (sym.flags & SYM_USED_IN_PRAGMA) ) {
     //     name = CGVolatile( name );
     // }
        if( sym.flags & SYM_USED_IN_PRAGMA ) {
            name = CGVolatile( name );
        }
    }
    return( name );
}

static cg_name PushRValue( OPNODE *node, cg_name name )
{
    TYPEPTR     typ;

    if( node->flags & OPFLAG_RVALUE ) {
        typ = node->result_type;
        if( node->flags & OPFLAG_VOLATILE ) {
            name = CGVolatile( name );
        } else {
            name = ForceVolatileFloat( name, typ );
        }
        name = CGUnary( O_POINTS, name, CGenType( typ ) );
    } else {
//      if( node->flags & OPFLAG_VOLATILE ) {
//          name = CGVolatile( name );
//      }
    }
    return( name );
}

static cg_name DotOperator( cg_name op1, OPNODE *node, cg_name op2 )
{
    TYPEPTR     typ;
    cg_name     name;

    // node->result_type is the type of the data
    // for the O_PLUS we want a pointer type
    name = CGBinary( O_PLUS, op1, op2, DataPointerType( node ) );
    typ = node->result_type;
    if( typ->decl_type == TYPE_FIELD || typ->decl_type == TYPE_UFIELD ) {
        name = CGBitMask( name, typ->u.f.field_start,
                    typ->u.f.field_width, CGenType( typ ) );
    }
    if( node->flags & OPFLAG_UNALIGNED ) {
        name = CGAttr( name, CG_SYM_UNALIGNED );
    }
    return( PushRValue( node, name ) );
}

static cg_name ArrowOperator( cg_name op1, OPNODE *node, cg_name op2 )
{
    // node->result_type is the type of the data
    // for the O_PLUS we want a pointer type
#if _CPU == 386
    if( Far16Pointer( node->flags ) ) {
        op1 = CGUnary( O_PTR_TO_NATIVE, op1, T_POINTER );
    }
#endif
//  rvalue has already been done on left side of tree
//    op1 = CGUnary( O_POINTS, op1, DataPointerType( node ) );
    return( DotOperator( op1, node, op2 ) );
}

static cg_name IndexOperator( cg_name op1, OPNODE *node, cg_name op2 )
{
    long        element_size;
    int         index_type;

    // node->result_type is the type of the data
    // for the O_PLUS we want a pointer type
    // op2 needs to be multiplied by the element size of the array

#if _CPU == 386
    if( Far16Pointer( node->flags ) ) {
        op1 = CGUnary( O_PTR_TO_NATIVE, op1, T_POINTER );
    }
#endif
    element_size = SizeOfArg( node->result_type );
    if( element_size != 1 ) {
        index_type = T_INTEGER;
        #if _CPU == 8086
            if(( node->flags & OPFLAG_HUGEPTR) ||
               ((TargetSwitches & (BIG_DATA|CHEAP_POINTER))==BIG_DATA &&
                (node->flags & (OPFLAG_NEARPTR | OPFLAG_FARPTR))==0)) {
                index_type = T_INT_4;
            }
        #endif
        op2 = CGBinary( O_TIMES, op2,
                CGInteger( element_size, T_INTEGER ), index_type );
    }
    op1 = CGBinary( O_PLUS, op1, op2, DataPointerType( node ) );
    if( node->flags & OPFLAG_UNALIGNED ) {
        op1 = CGAttr( op1, CG_SYM_UNALIGNED );
    }
    return( PushRValue( node, op1 ) );
}

static cg_name DoAddSub( cg_name op1, OPNODE *node, cg_name op2 )
{
    cg_name     name;
    TYPEPTR     typ;

    typ = node->result_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    name = CGBinary( CGOperator[node->opr], op1, op2, CGenType( typ ) );
//  if( typ->decl_type == TYPE_POINTER ) {
//      if( typ->u.p.decl_flags & FLAG_VOLATILE ) {
//          name = CGVolatile( name );
//      }
//  }
    return( name );
}
static cg_name PushConstant( OPNODE *node )
{
    cg_name     name;
    cg_type     dtype;
    FLOATVAL    *flt;
#ifdef _LONG_DOUBLE_
    double      doubleval;
    long_double ld;
#endif
    auto char   buffer[32];

    dtype = CGDataType[ node->const_type ];
    switch( node->const_type ) {
    case TYPE_CHAR:
    case TYPE_UCHAR:
    case TYPE_SHORT:
    case TYPE_USHORT:
    case TYPE_INT:
    case TYPE_UINT:
    case TYPE_LONG:
    case TYPE_ULONG:
    case TYPE_POINTER:
        name = CGInteger( node->ulong_value, dtype );
        break;
    case TYPE_LONG64:
    case TYPE_ULONG64:
        name = CGInt64( node->ulong64_value, dtype );
        break;
    case TYPE_FLOAT:
    case TYPE_DOUBLE:
    case TYPE_LONG_DOUBLE:
    case TYPE_FIMAGINARY:
    case TYPE_DIMAGINARY:
    case TYPE_LDIMAGINARY:
        flt = node->float_value;
        if( flt->len != 0 ) {                   // if still in string form
            name = CGFloat( flt->string, dtype );
        } else {                                // else in binary form
#ifdef _LONG_DOUBLE_
            ld = flt->ld;
            __LDFD( (long_double near *)&ld, (double near *)&doubleval );
            ftoa( doubleval, buffer );
#else
            ftoa( flt->ld.value, buffer );
#endif
            name = CGFloat( buffer, dtype );
        }
        break;
    }
    return( name );
}

static cg_name PushString( OPNODE *node )
{
    STRING_LITERAL      *string;

    string = node->string_handle;
    Emit1String( string );
    return( CGBackName( string->cg_back_handle, T_UINT_1 ) );
}

static cg_name DoIndirection( OPNODE *node, cg_name name )
{
    TYPEPTR     typ;

    // check for special kinds of pointers, eg. call __Far16ToFlat
    typ = node->result_type;
#if _CPU == 386
    if( Far16Pointer( node->flags ) ) {
        // Do NOT convert __far16 function pointers to flat because the
        // thunk routine expects 16:16 pointers!
        if( ( typ->object != NULL ) &&
            ( typ->object->decl_type != TYPE_FUNCTION ) )
            name = CGUnary( O_PTR_TO_NATIVE, name, T_POINTER );
    }
#endif
    if( node->flags & OPFLAG_UNALIGNED ) {
        name = CGAttr( name, CG_SYM_UNALIGNED );
    }
    if( node->flags & OPFLAG_RVALUE ) {
        if( node->flags & OPFLAG_VOLATILE ) {
            name = CGVolatile( name );
        }
        name = CGUnary( O_POINTS, name, CGenType( typ->object ) );
    }
    return( name );
}

static cg_name ConvertPointer( OPNODE *node, cg_name name )
{
#if _CPU == 386
    if( node->oldptr_class == PTR_FAR16 ) {
        name = CGUnary( O_PTR_TO_NATIVE, name, T_POINTER );
    } else if( node->newptr_class == PTR_FAR16 ) {
        name = CGUnary( O_PTR_TO_FOREIGN, name, T_POINTER );
    }
#endif
    return( name );
}

static call_handle InitFuncCall( OPNODE *node )
{
    cg_name     name;
    cg_type     dtype;
    TYPEPTR     typ;
    SYMPTR      sym;

    sym = SymGetPtr( node->sym_handle );
    typ = sym->sym_type;
    dtype = CGenType( typ );
    name = CGFEName( node->sym_handle, dtype );
//    dtype = FESymType( sym );
    while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
    return( CGInitCall( name, CGenType( typ->object ), node->sym_handle ) );
}

static call_handle InitIndFuncCall( OPNODE *node, cg_name name )
{
    TYPEPTR     typ;
    SYMPTR      sym;

    sym = SymGetPtr( node->sym_handle );
    typ = sym->sym_type;

⌨️ 快捷键说明

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