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

📄 cgen2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
    return( CGInitCall( name, CGenType( typ->object ), node->sym_handle ) );
}

local void DoSwitch( OPNODE *node, cg_name name )
{
    sel_handle  table;
    SWITCHPTR   sw;
    CASEPTR     ce;

    table = CGSelInit();
    sw = node->switch_info;
    for( ce = sw->case_list; ce; ce = ce->next_case ) {
        CGSelCase( table, CGLabelHandles[ ce->label ], ce->value );
    }
    CGSelOther( table, CGLabelHandles[ sw->default_label ] );
    CGSelect( table, name );
}

static bool IsStruct( TYPEPTR typ ){
/*********************************/
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_STRUCT  ||
        typ->decl_type == TYPE_FCOMPLEX ||
        typ->decl_type == TYPE_DCOMPLEX ||
        typ->decl_type == TYPE_LDCOMPLEX ||
        typ->decl_type == TYPE_UNION ) {
            return( TRUE );
    }
    return( FALSE );
}

local void EmitNodes( TREEPTR tree )
{
    cg_name     op1;
    cg_name     op2;
    cg_name     expr;
    call_handle call_list;
    cg_name     *cgnames;
    unsigned    index;
    OPNODE      *node;

    index = 0;
    cgnames = (cg_name *)&ValueStack[0];
    for( ; tree != NULL; tree = tree->thread ) {
        node = &tree->op;
        switch( node->opr ) {
        case OPR_FUNCTION:              // start of function
            StartFunction( node );
            break;
        case OPR_NEWBLOCK:              // start of new block { vars; }
            DBBegBlock();
            DoAutoDecl( node->sym_handle );
            break;
        case OPR_ENDBLOCK:              // end of new block { vars; }
            DBEndBlock();
            LocalVarList = ReleaseVars( node->sym_handle, LocalVarList );
            break;
        case OPR_LABELCOUNT:            // number of labels used in function
            DefineLabels( node );
            break;
        case OPR_RETURN:                // return( expression );
            op1 = PopCGName();          // - get expression
            ReturnExpression( node, op1 );
            break;
        case OPR_FUNCEND:               // end of function
            EndFunction( node );
            break;
        case OPR_EQUALS:                // =
          {
            cg_type     dtype;

            op2 = PopCGName();          // get right opnd
            op1 = PopCGName();          // get lvalue
            if( node->flags & OPFLAG_VOLATILE ) { // is lvalue volatile
                 op1 = CGVolatile( op1 );
            }
            if( IsStruct( node->result_type ) ){
                dtype = DataPointerType( node );
                op1 = CGLVAssign( op1, op2, CGenType( node->result_type ));
                op1 = PushRValue( node, op1 );
            }else{
                dtype =  CGenType( node->result_type );
                op1 = CGAssign( op1, op2, CGenType( node->result_type ));
            }
            PushCGName( op1 );
          } break;
        case OPR_ADD:                   // +
        case OPR_SUB:                   // -
            op2 = PopCGName();
            op1 = PopCGName();
            PushCGName( DoAddSub( op1, node, op2 ) );
            break;
        case OPR_MUL:                   // *
        case OPR_DIV:                   // /
        case OPR_MOD:                   // %
        case OPR_OR:                    // |
        case OPR_AND:                   // &
        case OPR_XOR:                   // ^
        case OPR_RSHIFT:                // >>
        case OPR_LSHIFT:                // <<
            op2 = PopCGName();
            op1 = PopCGName();
            PushCGName( CGBinary( CGOperator[node->opr], op1, op2,
                                    CGenType( node->result_type ) ) );
            break;
        case OPR_COMMA:                 // expr , expr
          {
            cg_type     dtype;
            op2 = PopCGName();
            op1 = PopCGName();
            dtype =  IsStruct( node->result_type ) ?
                   DataPointerType( node ) : CGenType( node->result_type );
            op1 = CGBinary( O_COMMA, op1, op2, dtype );
            PushCGName( PushRValue( node, op1 ) );
          } break;
        case OPR_PLUS_EQUAL:
        case OPR_MINUS_EQUAL:
        case OPR_TIMES_EQUAL:
        case OPR_DIV_EQUAL:
        case OPR_MOD_EQUAL:
        case OPR_XOR_EQUAL:
        case OPR_AND_EQUAL:
        case OPR_OR_EQUAL:
        case OPR_RSHIFT_EQUAL:
        case OPR_LSHIFT_EQUAL:
            op2 = PopCGName();          // get right opnd
            op1 = PopCGName();          // get lvalue
            if( node->flags & OPFLAG_VOLATILE ) { // is lvalue volatile
                 op1 = CGVolatile( op1 );
            }
            PushCGName( CGPreGets( CGOperator[node->opr], op1, op2,
                                    CGenType( node->result_type ) ) );
            break;
        case OPR_NEG:                   // negate
            op1 = PopCGName();
            PushCGName( CGUnary( O_UMINUS, op1,
                                    CGenType( node->result_type ) ) );
            break;
        case OPR_CMP:                   // compare
            op2 = PopCGName();
            op1 = PopCGName();
            PushCGName( CGCompare( CC2CGOp[ node->cc ], op1, op2,
                                    CGenType( node->compare_type ) ) );
            break;
        case OPR_COM:                   // ~
            op1 = PopCGName();
            PushCGName( CGUnary( O_COMPLEMENT, op1,
                                    CGenType( node->result_type ) ) );
            break;
        case OPR_NOT:                   // !
            op1 = PopCGName();
            PushCGName( CGFlow( O_FLOW_NOT, op1, NULL ) );
            break;
        case OPR_QUESTION:             // ?
          {
            cg_type     dtype;

            op2 = PopCGName();          // false_part
            op1 = PopCGName();          // true_part
            expr = PopCGName();         // test expr
            dtype =  IsStruct( node->result_type ) ?
                   DataPointerType( node ) : CGenType( node->result_type );
            op1 = CGChoose( expr, op1, op2, dtype );

            PushCGName( PushRValue( node, op1 ) );
          } break;
        case OPR_COLON:                 // :
            // do nothing, wait for OPR_QUESTION to come along
            break;
        case OPR_OR_OR:                 // ||
        case OPR_AND_AND:               // &&
            op2 = PopCGName();
            op1 = PopCGName();
            PushCGName( CGFlow( CGOperator[ node->opr ], op1, op2 ) );
            break;
        case OPR_POINTS:                // *ptr
            op1 = PopCGName();
            PushCGName( DoIndirection( node, op1 ) );
            break;
        case OPR_POSTINC:               // lvalue++
        case OPR_POSTDEC:               // lvalue--
            op2 = PopCGName();          // get amount to inc/dec by
            op1 = PopCGName();          // get lvalue
            if( node->flags & OPFLAG_VOLATILE ) { // is lvalue volatile
                 op1 = CGVolatile( op1 );
            }
            PushCGName( CGPostGets( CGOperator[node->opr], op1, op2,
                                    CGenType( node->result_type ) ) );
            break;
        case OPR_PUSHSYM:               // push sym_handle
            PushCGName( PushSym( node ) );
            break;
        case OPR_PUSHADDR:              // push address of sym_handle
            PushCGName( PushSymAddr( node ) );
            break;
        case OPR_PUSHINT:               // push integer constant
        case OPR_PUSHFLOAT:             // push floating-point constant
            PushCGName( PushConstant( node ) );
            break;
        case OPR_PUSHSTRING:            // push address of string literal
            PushCGName( PushString( node ) );
            break;
        case OPR_PUSHSEG:               // push seg of sym
            PushCGName( PushSymSeg( node ) );
            break;
        case OPR_DUPE:               // push seg of sym
         {
            temp_handle temp_name;
            cg_name     name;
            cg_name     left;

            op1 = PopCGName();      // - get expression
            temp_name = CGTemp( T_LONG_POINTER );
            name = CGTempName( temp_name, T_LONG_POINTER );
            left = CGAssign( name, op1, T_LONG_POINTER );
            name = CGTempName( temp_name, T_LONG_POINTER );
            PushCGName( left );
            PushCGName( PushRValue( node, name ) );
          } break;
        case OPR_CONVERT:
            if( node->result_type->decl_type != TYPE_VOID ) {
                op1 = PopCGName();      // - get expression
                PushCGName( CGUnary( O_CONVERT, op1,
                                CGenType(node->result_type)) );
            }
            break;
        case OPR_CONVERT_PTR:           // convert pointer
            op1 = PopCGName();          // - get expression
            PushCGName( ConvertPointer( node, op1 ) );
            break;
        case OPR_MATHFUNC:              // intrinsic math func with 1 parm
            op1 = PopCGName();          // - get expression
            PushCGName( CGUnary( node->mathfunc, op1, TY_DOUBLE ) );
            break;
        case OPR_MATHFUNC2:             // intrinsic math func with 2 parms
            op2 = PopCGName();          // - get expression
            op1 = PopCGName();          // - get expression
            PushCGName( CGBinary( node->mathfunc, op1, op2, TY_DOUBLE ) );
            break;
        case OPR_DOT:                   // sym.field
            op2 = PopCGName();          // - get offset of field
            op1 = PopCGName();          // - get address of sym
            PushCGName( DotOperator( op1, node, op2 ) );
            break;
        case OPR_ARROW:                 // ptr->field
            op2 = PopCGName();          // - get offset of field
            op1 = PopCGName();          // - get pointer
            PushCGName( ArrowOperator( op1, node, op2 ) );
            break;
        case OPR_INDEX:                 // array[index]
            op2 = PopCGName();          // - get index
            op1 = PopCGName();          // - get address of array
            PushCGName( IndexOperator( op1, node, op2 ) );
            break;
        case OPR_ADDROF:                // & expr
        case OPR_NOP:                   // nop
            break;
        case OPR_FARPTR:                // segment :> offset
            op2 = PopCGName();          // - get offset
            op1 = PopCGName();          // - get segment
            PushCGName( CGBinary( O_CONVERT, op2, op1, T_LONG_POINTER ) );
            break;
        case OPR_FUNCNAME:              // function name
            PushCGName( InitFuncCall( node ) ); // - push call_handle
            break;
        case OPR_CALL_INDIRECT:         // indirect function call
            op1 = PopCGName();                          // - get name
            PushCGName( InitIndFuncCall( node, op1 ) ); // - push call_handle
            break;
        case OPR_CALL:                  // function call
            call_list = PopCGName();    // - get call_handle
            op1 = CGCall( call_list );
            if( node->flags & OPFLAG_RVALUE ) {
                op1 = CGUnary( O_POINTS, op1, CGenType( node->result_type ) );
            }
            PushCGName( op1 );
            break;
        case OPR_PARM:                  // function parm
            op1 = PopCGName();          // - get parm
            call_list = PopCGName();    // - get call_handle
            CGAddParm( call_list, op1, CGenType( node->result_type ) );
            PushCGName( call_list );
            break;
        case OPR_LABEL:                 // label
        case OPR_CASE:                  // case label
            CGControl( O_LABEL, NULL, CGLabelHandles[ node->label_index ] );
            break;
        case OPR_JUMP:                  // jump
            CGControl( O_GOTO, NULL, CGLabelHandles[ node->label_index ] );
            break;
        case OPR_JUMPTRUE:              // jump if true
            op1 = PopCGName();
            CGControl( O_IF_TRUE, op1, CGLabelHandles[ node->label_index ] );
            break;
        case OPR_JUMPFALSE:             // jump if false
            op1 = PopCGName();
            CGControl( O_IF_FALSE, op1, CGLabelHandles[ node->label_index ] );
            break;
        case OPR_SWITCH:                // switch
            op1 = PopCGName();
            DoSwitch( node, op1 );
            break;
#ifdef __SEH__
        case OPR_TRY:                   // start of try block
            SetTryScope( node->parent_scope );
            break;
        case OPR_EXCEPT:
        case OPR_FINALLY:
            CGBigLabel( FEBack( node->sym_handle ) );
            break;
        case OPR_END_FINALLY:
            EndFinally();
            break;
        case OPR_UNWIND:
            TryUnwind( node->try_index );
            break;
        case OPR_EXCEPT_CODE:
            op1 = TryExceptionInfoAddr();
            op1 = CGUnary( O_POINTS, op1, T_POINTER );
            PushCGName( CGUnary( O_POINTS, op1, T_INTEGER ) );
            break;
        case OPR_EXCEPT_INFO:
            PushCGName( TryExceptionInfoAddr() );
            break;
        case OPR_ABNORMAL_TERMINATION:
            PushCGName( TryAbnormalTermination() );
            break;
#endif
#if _MACHINE == _ALPHA  || _MACHINE == _PPC
        case OPR_VASTART:
            op2 = PopCGName();          // - get offset of parm
            op1 = PopCGName();          // - get address of va_list
            GenVaStart( op1, op2 );
            break;
        case OPR_ALLOCA:
            op1 = PopCGName();          // - get size
            PushCGName( CGUnary( O_STACK_ALLOC, op1, T_POINTER ) );
            break;
#endif
        default:
           {
             char        msgbuf[MAX_MSG_LEN];

             sprintf( msgbuf, "opr=%d not handled\n", node->opr );
             DebugMsg( msgbuf );
           }
            break;
        }
    }
    if( index != 0 ) {
        CGDone( PopCGName() );
    }
}

local void ThreadNode( TREEPTR node )
{
    if( FirstNode == NULL )  FirstNode = node;
    if( LastNode != NULL )   LastNode->thread = node;
    LastNode = node;
}

local TREEPTR LinearizeTree( TREEPTR tree )
{
    FirstNode = NULL;
    LastNode = NULL;
    WalkExprTree( tree, ThreadNode, NoOp, NoOp, ThreadNode );
    LastNode->thread = NULL;
    return( FirstNode );
}


void EmitInit()
{
    SegListHead = NULL;
    SegImport = SegData-1;
    Refno = T_FIRST_FREE;
}


local int NewRefno()
{
    return( Refno++ );
}


void EmitAbort()
{
}

local TREEPTR GenOptimizedCode( TREEPTR tree )
{
    unsigned    unroll_count;

    unroll_count = 0;
    while( tree != NULL ) {
        SrcFno = tree->op.source_fno;
        SrcLineNum = tree->srclinenum;
        if( SrcLineNum != SrcLineCount ) {
            if( Saved_CurFunc == 0 ) {      /* 24-nov-91 */
                DBSrcCue( SrcFno, SrcLineNum, 1 );
            }
        }

⌨️ 快捷键说明

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