fcstack.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 672 行 · 第 1/2 页

C
672
字号
        }
        if( i != NULL ) {
            i = CGBinary( O_PLUS, i, CGInteger( offset, T_INT_4 ), T_INT_4 );
        } else {
            i = CGInteger( offset, T_INT_4 );
        }
        addr = CGBinary( O_PLUS, addr, i, SymPtrType( sym ) );
        if( (sym->ns.typ == TY_CHAR) && !(sym->ns.flags & SY_SUBSCRIPTED) ) {
            // tell code generator where storage pointed to by SCB is located
            addr = CGBinary( O_COMMA, addr,
                             CGFEName( sym, F772CGType( sym ) ), T_DEFAULT );
        }
        i = NULL;
    } else if( ( sym->ns.typ == TY_CHAR ) &&
               ( ( sym->ns.flags & SY_SUBSCRIPTED ) == 0 ) ) {
        // character variable, address of scb
        addr = CGFEName( sym, F772CGType( sym ) );
    } else if( sym->ns.flags & SY_IN_COMMON ) {
        ce_ext = sym->ns.si.va.vi.ec_ext;
        if( i != NULL ) {
            i = CGBinary( O_PLUS, i, CGInteger( ce_ext->offset, T_INT_4 ),
                          T_INT_4 );
        } else {
            i = CGInteger( ce_ext->offset, T_INT_4 );
        }
        addr = CGBinary( O_PLUS, CGFEName( ce_ext->com_blk, F772CGType( sym ) ),
                         i, SymPtrType( sym ) );
        i = NULL;
    } else {
        addr = CGFEName( sym, F772CGType( sym ) );
        if( ( sym->ns.flags & SY_SUBSCRIPTED ) && _Allocatable( sym ) ) {
            addr = CGUnary( O_POINTS, addr, ArrayPtrType( sym ) );
        }
    }
    if( i != NULL ) {
        addr = CGBinary( O_PLUS, addr, i, SymPtrType( sym ) );
    }
    if( ( OZOpts & OZOPT_O_VOLATILE ) && data_reference &&
        ( ( sym->ns.typ >= TY_REAL ) && ( sym->ns.typ <= TY_XCOMPLEX ) ) ) {
        addr = CGVolatile( addr );
    } else if( sym->ns.xflags & SY_VOLATILE ) {
        addr = CGVolatile( addr );
    }
    return( addr );
}


cg_name SymAddr( sym_id sym ) {
//=============================

    return( SymIndex( sym, NULL ) );
}


void    FCPush( void ) {
//================

// Process PUSH F-Code.

    sym_id      sym;

    sym = GetPtr();
    if( TypeCmplx( sym->ns.typ ) ) {
        PushComplex( sym );
    } else {
        XPush( SymAddr( sym ) );
    }
}


cg_name SymValue( sym_id sym ) {
//==============================

// Generate value of a symbol.

    return( CGUnary( O_POINTS, SymAddr( sym ), F772CGType( sym ) ) );
}


void    XPush( cg_name cgname ) {
//===============================

// Push a CG-name on the stack.

    *(cg_name *)StkPtr = cgname;
    StkPtr = (char *)StkPtr + sizeof( cg_name );
}


char *  StackBuffer( int * len ) {
//================================

// Return a pointer to a buffer on the stack.  This is a very temporary buffer.

    *len = TOKLEN - ((char *)StkPtr - TokenBuff);
    return( StkPtr );
}


void    DXPush( intstar4 val ) {
//==============================

// Push a constant on the stack for DATA statement expressions.

    *(intstar4 *)StkPtr = val;
    StkPtr = (char *)StkPtr + sizeof( intstar4 );
}


void    SymPush( sym_id val ) {
//=============================

// Push a symbol table entry on the stack.

    *(sym_id *)StkPtr = val;
    StkPtr = (char *)StkPtr + sizeof( sym_id );
}


cg_name XPop( void ) {
//==============

// Pop a CG-name from the stack.

    StkPtr = (char *)StkPtr - sizeof( cg_name );
    return( *(cg_name *)StkPtr );
}


cg_name XPopValue( cg_type typ ) {
//================================

// Pop a CG-name from the stack (its value).

    cg_name     opn;

    opn = XPop();
    if( TypePointer( CGType( opn ) ) ) {
        opn = CGUnary( O_POINTS, opn, typ );
    }
    return( opn );
}


void    FCPop( void ) {
//===============

// Process POP F-Code.

    sym_id      sym;
    cg_name     dst;
    unsigned_16 typ_info;
    cg_type     dst_typ;
    cg_type     src_typ;
    sym_id      fd;

    sym = GetPtr();
    typ_info = GetU16();
    dst_typ = GetType1( typ_info );
    src_typ = GetType2( typ_info );
    if( ( dst_typ == T_COMPLEX ) || ( dst_typ == T_DCOMPLEX )
        || ( dst_typ == T_XCOMPLEX ) ) {
        CmplxAssign( sym, dst_typ, src_typ );
    } else {
        if( (sym->ns.flags & SY_CLASS) == SY_SUBPROGRAM ) {
            // it's a statement function
            if( !(OZOpts & OZOPT_O_INLINE) ) {
                dst = SymAddr( sym );
            }
        } else {
            fd = NULL;
            if( sym->ns.typ == TY_STRUCTURE ) {
                if( GetU16() ) {
                    // target is a sub-field
                    dst = XPop();
                    if( dst_typ == T_USER_DEFINED ) {
                        // sub-field is a structure or an array element
                        fd = GetPtr();
                    }
                } else {
                    dst = SymAddr( sym );
                }
            } else if( sym->ns.flags & SY_SUBSCRIPTED ) {
                // target is an array element
                dst = XPop();
            } else {
                dst = SymAddr( sym );
            }
            if( dst_typ == T_USER_DEFINED ) {
                if( fd == NULL ) {
                    dst_typ = sym->ns.xt.record->cg_typ;
                } else {
                    dst_typ = fd->fd.xt.record->cg_typ;
                }
                XPush( CGAssign( dst, CGUnary( O_POINTS, XPop(), dst_typ ),
                                 dst_typ ) );
                return;
            }
        }
        if( (src_typ == T_COMPLEX) || (src_typ == T_DCOMPLEX)
            || (src_typ == T_XCOMPLEX) ) {
            Cmplx2Scalar();
            src_typ = CmplxBaseType( src_typ );
        }
        if( ((sym->ns.flags & SY_CLASS) == SY_SUBPROGRAM) &&
            (OZOpts & OZOPT_O_INLINE ) ) return;
        XPush( CGAssign( dst, XPopValue( src_typ ), dst_typ ) );
    }
}


cg_name GetTypedValue( void ) {
//=======================

// Pop a CG-name from the stack (its value).

    cg_name     opn;
    cg_type     typ;

    opn = XPop();
    typ = GetType( GetU16() );
    if( TypePointer( CGType( opn ) ) ) {
        opn = CGUnary( O_POINTS, opn, typ );
    }
    return( opn );
}


cg_name         StkElement( int idx ) {
//=====================================

// Get idx'th stack element.

    return(  *(cg_name * )((char *)StkPtr - idx * sizeof( cg_name )) );
}


void            PopStkElements( int num ) {
//=========================================

// Pop stack elements from the stack.

    StkPtr = (char *)StkPtr - num * sizeof( cg_name );
}


intstar4        DXPop( void ) {
//=======================

// Pop a constant from the stack for DATA statement expressions.

    StkPtr = (char *)StkPtr - sizeof( intstar4 );
    return( *(intstar4 *)StkPtr );
}


sym_id          SymPop( void ) {
//========================

// Pop a symbol table entry from the stack.

    StkPtr = (char *)StkPtr - sizeof( sym_id );
    return( *(sym_id *)StkPtr );
}


cg_name IntegerConstant( ftn_type *value, uint size ) {
//===================================================

    if( size == sizeof( intstar1 ) ) {
        return( CGInteger( value->intstar1, T_INT_1 ) );
    } else if( size == sizeof( intstar2 ) ) {
        return( CGInteger( value->intstar2, T_INT_2 ) );
    } else {
        return( CGInteger( value->intstar4, T_INT_4 ) );
    }
}


void    FCPushConst( void ) {
//=====================

// Process PUSH_CONST F-Code.

    sym_id      sym;
    char        fmt_buff[CONVERSION_BUFFER+1];

    sym = GetPtr();
    switch( sym->cn.typ ) {
    case TY_INTEGER_1 :
    case TY_INTEGER_2 :
    case TY_INTEGER :
        XPush( IntegerConstant( &sym->cn.value, sym->cn.size ) );
        break;
    case TY_LOGICAL_1 :
    case TY_LOGICAL :
        XPush( CGInteger( sym->cn.value.logstar4, T_UINT_1 ) );
        break;
    case TY_REAL :
        CnvS2S( &sym->cn.value.single, fmt_buff );
        XPush( CGFloat( fmt_buff, T_SINGLE ) );
        break;
    case TY_DOUBLE :
        CnvD2S( &sym->cn.value.dble, fmt_buff );
        XPush( CGFloat( fmt_buff, T_DOUBLE ) );
        break;
    case TY_TRUE_EXTENDED :
        CnvX2S( &sym->cn.value.extended, fmt_buff );
        XPush( CGFloat( fmt_buff, T_LONGDOUBLE ) );
        break;
    case TY_COMPLEX :
        PushCmplxConst( sym );
        break;
    case TY_DCOMPLEX :
        PushCmplxConst( sym );
        break;
    case TY_TRUE_XCOMPLEX :
        PushCmplxConst( sym );
        break;
    }
}


void    FCPushLit( void ) {
//===================

// Process PUSH_LIT F-Code.

    sym_id      sym;

    sym = GetPtr();
    if( sym->lt.flags & (LT_SCB_REQUIRED | LT_SCB_TMP_REFERENCE) ) {
        XPush( CGBackName( ConstBack( sym ), T_CHAR ) );
    }
}

⌨️ 快捷键说明

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