i87sched.c

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

C
1,092
字号
            ins->operands[ 0 ] = ST( temp->actual_locn );
            ins->result = ins->operands[ 0 ];
            ins->operands[ 1 ] = ST( 0 );
            InsLoc( ins, VIRTUAL_0 ) = temp->actual_locn;
            DecrementAll();
            break;
        }
        temp->actual_locn = ACTUAL_NONE;
    } else {
        if( ( ins == temp->first ) && !temp->defined && !temp->whole_block ) {
            PrefFLDOp( ins, OP_MEM, temp->actual_op );
            IncrementAll();
            temp->actual_locn = ACTUAL_0;
            if( ins->u.gen_table->generate == G_MFLD ) {
                // PushStack( ins );
                ins->operands[ 0 ] = ST( ACTUAL_0 );
            } else {
                GetToTopOfStack( ins, VIRTUAL_0 );
                ins->operands[ 0 ] = ST( temp->actual_locn );
            }
        } else {
            ins->operands[ 0 ] = ST( temp->actual_locn );
            // if( attr & PUSHES ) {
            //     PushStack( ins );
            // }
        }
        if( attr & PUSHES ) {
            PushStack( ins );
        } else if( attr & POPS2 ) {
            PopStack( ins );
            PopStack( ins );
        } else if( attr & POPS ) {
            PopStack( ins );
        }
        ins->u.gen_table = RegAction( ins );
    }
    return( ins );
}


static  void    SetResultReg( instruction *ins, int virtual_reg ) {
/**********************************************************/

    ins->result = ST( InsLoc( ins, virtual_reg ) );
    ins->operands[ 0 ] = ins->result;
}


static  void    GetToTopOfStack( instruction *ins, int virtual_reg ) {
/*************************************************************/

    byte        actual_locn;
    byte        *actual_top_owner;

    actual_locn = InsLoc( ins, virtual_reg );
    if( actual_locn == ACTUAL_0 ) return;
    actual_top_owner = ActualStackOwner( ACTUAL_0 );
    if( actual_top_owner != NULL ) {
        PrefixExchange( ins, actual_locn );
        InsLoc( ins, virtual_reg ) = ACTUAL_0;
        *actual_top_owner = actual_locn;
        return;
    }
    _Zoiks( ZOIKS_076 );
}

static  instruction     *FComppKluge( instruction *ins ) {
/********************************************************/
    byte        actual_0,actual_1;
    byte        *owner_0,*owner_1;

    actual_0 = InsLoc( ins, VIRTUAL_0 );
    actual_1 = InsLoc( ins, VIRTUAL_1 );
    owner_0 = ActualStackOwner( ACTUAL_0 );
    owner_1 = ActualStackOwner( ACTUAL_1 );
    if( actual_0 == ACTUAL_0 ) {
        if( actual_1 == ACTUAL_1 ) {    // actual_0=0 actual_1=1
            return( ins );
        } else {                        // actual_0=0 actual_1=n
            PrefFXCH( ins, ACTUAL_1 );
            PrefFXCH( ins, actual_1 );
            PrefFXCH( ins, ACTUAL_1 );
            *owner_1 = actual_1;
        }
    } else if( actual_1 == ACTUAL_0 ) {
        if( actual_0 == ACTUAL_1 ) {    // actual_0=1 actual_1=0
            PrefFXCH( ins, ACTUAL_1 );
        } else {                        // actual_0=n actual_1=0
            PrefFXCH( ins, ACTUAL_1 );
            PrefFXCH( ins, actual_0 );
            *owner_1 = actual_0;
        }
    } else if( actual_1 == ACTUAL_1 ) { // actual_1=1 actual_0=n
        PrefFXCH( ins, actual_0 );
        *owner_0 = actual_0;
    } else {                            // actual_0=1,n actual_1=n
        PrefFXCH( ins, actual_1 );
        PrefFXCH( ins, ACTUAL_1 );
        PrefFXCH( ins, actual_0 );
        *owner_0 = actual_1;
        *owner_1 = actual_0;
    }
    InsLoc( ins, VIRTUAL_0 ) = ACTUAL_0;
    InsLoc( ins, VIRTUAL_1 ) = ACTUAL_1;
    return( ins );
}

static  instruction     *GetST0andST1( instruction *ins ) {
/*********************************************************/

    byte        actual_0,actual_1;

    actual_0 = InsLoc( ins, VIRTUAL_0 );
    actual_1 = InsLoc( ins, VIRTUAL_1 );
    if( actual_0 == ACTUAL_0 ) {
        if( actual_1 == ACTUAL_1 ) {    // actual_0=0 actual_1=1
            return( ins );
        } else {                        // actual_0=0 actual_1=n
            PrefFLDOp( ins, OP_STKI, ST( actual_1 ) );
            PrefFXCH( ins, ACTUAL_1 );
            return( SuffFSTPRes( ins, ST( actual_1 ), RES_STKI ) );
        }
    } else if( actual_1 == ACTUAL_0 ) {
        if( actual_0 == ACTUAL_1 ) {    // actual_0=1 actual_1=0
            GetToTopOfStack( ins, VIRTUAL_0 );
            return( ins );
        } else {                        // actual_0=n actual_1=0
            InsLoc( ins, VIRTUAL_1 ) = actual_0;
            PrefFLDOp( ins, OP_STKI, ST( actual_0 ) );
            return( SuffFSTPRes( ins, ST( actual_0 ), RES_STKI ) );
        }
    } else if( actual_1 == ACTUAL_1 ) { // actual_1=1 actual_0=n
        GetToTopOfStack( ins, VIRTUAL_0 );
        return( ins );
    } else {                            // actual_0=1,n actual_1=n
        GetToTopOfStack( ins, VIRTUAL_1 );
        InsLoc( ins, VIRTUAL_1 ) = actual_0;
        PrefFLDOp( ins, OP_STKI, ST( actual_0 ) );
        return( SuffFSTPRes( ins, ST( actual_0 ), RES_STKI ) );
    }
}


static  void    IncrementAll( void ) {
/*************************/

    int         i,j;
    temp_entry  *temp;

    for( i = 0; i < MaxSeq; ++i ) {
        for( j = VIRTUAL_0; j < VIRTUAL_NONE-1; ++j ) {
            if( RegLoc( i, j ) != ACTUAL_NONE ) {
                ++RegLoc( i, j );
            }
        }
    }
    for( temp = TempList; temp != NULL; temp = temp->next ) {
        if( temp->actual_locn != ACTUAL_NONE ) {
            temp->actual_locn++;
        }
    }
}


static  void    PushVirtualStack( instruction *ins ) {
/****************************************************/

    int i;

    for( i = VIRTUAL_NONE-1; i > VIRTUAL_0; --i ) {
        InsLoc( ins, i ) = InsLoc( ins, i-1 );
    }
    InsLoc( ins, VIRTUAL_0 ) = ACTUAL_0;
}


static  void    PushStack( instruction *ins ) {
/*******************************************/

    IncrementAll();
    PushVirtualStack( ins );
}


static  void    DecrementAll( void ) {
/************************/

    int         i,j;
    temp_entry  *temp;

    for( i = 0; i < MaxSeq; ++i ) {
        for( j = VIRTUAL_0; j < VIRTUAL_NONE-1; ++j ) {
            if( RegLoc( i, j ) != ACTUAL_NONE ) {
                --RegLoc( i, j );
            }
        }
    }
    for( temp = TempList; temp != NULL; temp = temp->next ) {
        if( temp->actual_locn != ACTUAL_NONE ) {
            temp->actual_locn--;
        }
    }
}


static  void    PopVirtualStack( instruction *ins ) {
/*******************************************************/

    int         i;

    for( i = VIRTUAL_0; i < VIRTUAL_NONE-1; ++i ) {
        InsLoc( ins, i ) = InsLoc( ins, i+1 );
    }
    InsLoc( ins, VIRTUAL_7 ) = VIRTUAL_NONE;
}


static  void    PopStack( instruction *ins ) {
/******************************************/

    PopVirtualStack( ins );
    DecrementAll();
}




static  void    InitStackLocations( void ) {
/**************************************/

    temp_entry  *temp;
    int         i,j;

    _Alloc( STLocations, MaxSeq * sizeof( *STLocations ) );
    for( i = 0; i < MaxSeq; ++i ) {
        for( j = VIRTUAL_0; j < VIRTUAL_NONE; ++j ) {
            RegLoc( i, j ) = ACTUAL_NONE;
        }
    }
    for( temp = TempList; temp != NULL; temp = temp->next ) {
        temp->actual_locn = ACTUAL_NONE;
    }
}


static  void    FiniStackLocations( void ) {
/**************************/

    _Free( STLocations, MaxSeq * sizeof( st_seq ) );
    STLocations = NULL;
}


static  temp_entry      *LookupTempEntry( name *op ) {
/***********************************************/

    temp_entry  *temp;

    if( op == NULL ) return( NULL );
    if( op->n.class == N_TEMP ) op = DeAlias( op );
    for( temp = TempList; temp != NULL; temp = temp->next ) {
        if( temp->op == op ) return( temp );
    }
    return( NULL );
}


static  temp_entry      *AddTempEntry( name *op ) {
/********************************************/

    temp_entry  *temp;

    temp = LookupTempEntry( op );
    if( temp == NULL ) {
        _Alloc( temp, sizeof( *temp ) );
        temp->next = TempList;
        TempList = temp;
        temp->actual_op = op;
        if( op->n.class == N_TEMP ) op = DeAlias( op );
        temp->op = op;
        temp->first = NULL;
        temp->last = NULL;
        temp->savings = 0;
        temp->actual_locn = ACTUAL_NONE;
        temp->savings = 0;
        temp->cached = FALSE;
        temp->defined = FALSE;
        temp->killed = FALSE;
        temp->global = FALSE;
        temp->whole_block = FALSE;
    }
    return( temp );
}


static  void            DefUseTemp( name *op,
                                    instruction *ins, bool defined ) {
/********************************************************************/

    temp_entry *temp;

    temp = AddTempEntry( op );
    if( op->v.offset != temp->actual_op->v.offset ||
        op->n.size != temp->actual_op->n.size ) {
        temp->killed = TRUE;
        return;
    }
    if( temp->first == NULL ) temp->first = ins;
    temp->last = ins;
    temp->savings++;
    if( defined ) temp->defined = TRUE;
}


static  void            KillTempEntry( name *op ) {
/*************************************************/

    temp_entry  *temp;

    temp = AddTempEntry( op );
    temp->killed = TRUE;
}


static  void    CheckTemp( instruction *ins, name *op, bool defined ) {
/*********************************************************************/

    if( op->n.class == N_MEMORY ) {
        if( _IsntModel( RELAX_ALIAS ) ) return;
    } else if( op->n.class != N_TEMP ) {
        return;
    }
    if( op->v.usage & USE_ADDRESS ) return;
    if( !_GenIs8087( ins->u.gen_table->generate ) ) {
        KillTempEntry( op );
    } else {
        DefUseTemp( op, ins, defined );
    }
}


static  bool Better( void *t1, void *t2 ) {
/*****************************************************/

    return( ((temp_entry *)t1)->savings > ((temp_entry *)t2)->savings );
}



extern  void    InitTempEntries( block *blk ) {
/***************************************/

    instruction *ins;
    int         i;

    TempList = NULL;
    for( ins = blk->ins.hd.next;
         ins->head.opcode != OP_BLOCK; ins = ins->head.next ) {
        if( ins->ins_flags & FP_INS_INTRODUCED ) continue;
        for( i = 0; i < ins->num_operands; ++i ) {
            CheckTemp( ins, ins->operands[i], FALSE );
        }
        if( ins->result != NULL ) {
            CheckTemp( ins, ins->result, TRUE );

⌨️ 快捷键说明

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