i86enc16.c

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

C
745
字号
        return( DoIndex( HW_BP_DI ) + RMR_MOD_IND );
    case ZP_USES_SI:
        DoMAddr( op );
        return( DoIndex( HW_BP_SI ) + RMR_MOD_IND );
    }
    return( 0 );
}


extern  void    LayModRM( name *op ) {
/**************************************/

    hw_reg_set  regs;
    name        *base;
    hw_reg_set  tmp;

    switch( op->n.class ) {
    case N_MEMORY:
        CheckSize();
        Inst[ RMR ] |= DoMDisp( op, TRUE );
        break;
    case N_TEMP:
        CheckSize();
        base = DeAlias( op );
        if( base->t.location == NO_LOCATION ) {
            _Zoiks( ZOIKS_030 );
        }
        Inst[ RMR ] |= Displacement( NewBase( base ) + op->v.offset
                                        - base->v.offset, HW_BP )
                         + ( BP_INDEX << S_RMR_RM );
        break;
    case N_INDEXED:
        CheckSize();
        regs = op->i.index->r.reg;
        if( HW_COvlap( regs, HW_SEGS ) ) {
            /* check for seg override*/
            GenSeg( regs );
            HW_CTurnOff( regs, HW_SEGS );
        }
        if( HasTrueBase( op ) ) {
            if( op->i.base->n.class == N_TEMP ) {
                HW_CTurnOn( regs, HW_BP );
            } else if( op->i.base->n.class == N_MEMORY ) {
                tmp = CalcSegment( op->i.base->v.symbol,
                                  op->i.base->m.memory_type );
                HW_TurnOn( regs, tmp );
                if( HW_COvlap( regs, HW_SS ) ) {
                    switch( ZPageType ) {
                    case ZP_USES_SS:
                    case ZP_USES_DI:
                    case ZP_USES_SI:
                        GenSeg( regs );
                        break;
                    case ZP_USES_DS:
                        /* nothing*/
                        break;
                    case ZP_USES_BP:
                        if( HW_COvlap( regs, HW_BX ) ) {
                            GenSeg( regs );
                        } else {
                            HW_CTurnOn( regs, HW_BP );
                        }
                        break;
                    }
                } else {
                    GenSeg( regs );
                }
                HW_CTurnOff( regs, HW_SEGS );
            }
        }
        Inst[ RMR ] |= DoDisp( op, regs ) + DoIndex( regs );
        break;
    case N_REGISTER:
        LayRMRegOp( op );
        break;
    default:
        break;
    }
}


extern  void    DoRelocConst( name *op, type_class_def kind ) {
/*********************************************************/

    kind = kind;
    ILen += 2;
    if( op->c.const_type == CONS_OFFSET ) {
        DoSymRef( op->c.value, ((var_name *)op->c.value)->offset, FALSE );
    } else if( op->c.const_type == CONS_SEGMENT ) {
        if( op->c.value == NULL ) {
            DoSegRef( op->c.int_value );
        } else {
            DoSymRef( op->c.value, 0, TRUE );
        }
    } else if( op->c.const_type == CONS_ADDRESS ) {
        _Zoiks( ZOIKS_045 );
    }
}


extern  void    Do4Shift( instruction *ins ) {
/********************************************/

    name        *op;

    op = ins->result;
    if( ins->head.opcode == OP_LSHIFT ) {
        LayOpword( M_SHL1 | B_KEY_W );
        LayModRM( op );
        _Next;
        SetOff( op,  2 );
        LayOpword( M_RCL1 | B_KEY_W );
        LayModRM( op );
        SetOff( op, -2 );
    } else {
        SetOff( op,  2 );
        LayOpword( M_SHR1 | B_KEY_W );
        if( ins->type_class == I4 ) {
            Inst[ RMR ] |= B_RMR_SHR_SAR;
        }
        LayModRM( op );
        _Next;
        SetOff( op, -2 );
        LayOpword( M_RCR1 | B_KEY_W );
        LayModRM( op );
    }
}


extern  void    Do4RShift( instruction *ins ) {
/*********************************************/

    hw_reg_set  regs;

    regs = ins->result->r.reg;
    if( ins->head.opcode == OP_LSHIFT ) {
        LayOpword( M_SHL1 | B_KEY_W );
        LayRegRM( Low32Reg( regs ) );
        _Next;
        LayOpword( M_RCL1 | B_KEY_W );
        LayRegRM( High32Reg( regs ) );
    } else {
        LayOpword( M_SHR1 | B_KEY_W );
        if( ins->type_class == I4 ) {
            Inst[ RMR ] |= B_RMR_SHR_SAR;
        }
        LayRegRM( High32Reg( regs ) );
        _Next;
        LayOpword( M_RCR1 | B_KEY_W );
        LayRegRM( Low32Reg( regs ) );
    }
}


extern  void    Gen4RNeg( instruction *ins ) {
/********************************************/

    hw_reg_set  regs;

    regs = ins->result->r.reg;
    LayOpword( M_NEG );
    LayW( I2 );
    LayRegRM( High32Reg( regs ) );
    _Next;
    LayOpword( M_NEG );
    LayW( I2 );
    LayRegRM( Low32Reg( regs ) );
    _Next;
    LayOpword( M_SBB );
    LayW( I2 );
    LayRegRM( High32Reg( regs ) );
    AddSData( 0, I2 );
}


extern  void    Gen4Neg( instruction *ins ) {
/*******************************************/

    name        *res;

    res = ins->result;
    SetOff( res,  2 );
    LayOpword( M_NEG );
    LayW( I2 );
    LayModRM( res );
    _Next;
    SetOff( res, -2 );
    LayOpword( M_NEG );
    LayW( I2 );
    LayModRM( res );
    _Next;
    SetOff( res,  2 );
    LayOpword( M_SBB );
    LayW( I2 );
    LayModRM( res );
    AddSData( 0, I2 );
    SetOff( res, -2 );
}


extern  void    By2Div( instruction *ins ) {
/*******************************************/

    switch( ins->type_class ) {
    case I1:
    case U1:
        LayOpword( 0xc42a );    /* sub  al,ah */
        _Next;
        LayOpword( 0xf8d0 );    /* sar  al,1 */
        break;
    case I2:
    case U2:
        LayOpword( 0xc22b );    /* sub  ax,dx */
        OpndSizeIf();
        _Next;
        LayOpword( 0xf8d1 );    /* sar  ax,1 */
        OpndSizeIf();
    default:
        break;
    }
}


extern void Pow2Div286( instruction *ins ) {
/******************************************/

    int         log2;

    log2 = GetLog2( ins->operands[1]->c.int_value );
    switch( ins->type_class ) {
    case I1:
    case U1:
        LayOpword( 0xe4c0 );    /* shl  ah,n */
        AddByte( log2 );
        _Next;
        LayOpword( 0xc41a );    /* sbb  al,ah */
        _Next;
        LayOpword( 0xf8c0 );    /* sar  al,n */
        AddByte( log2 );
        break;
    case I2:
    case U2:
        LayOpword( 0xe2c1 );    /* shl  dx,n */
        OpndSizeIf();
        AddByte( log2 );
        _Next;
        LayOpword( 0xc21b );    /* sbb  ax,dx */
        OpndSizeIf();
        _Next;
        LayOpword( 0xf8c1 );    /* sar  ax,n */
        OpndSizeIf();
        AddByte( log2 );
        break;
    default:
        break;
    }
}


extern  void    Pow2Div( instruction *ins ) {
/*******************************************/

    int         log2;

    log2 = GetLog2( ins->operands[1]->c.int_value );
    switch( ins->type_class ) {
    case I1:
    case U1:
        LayOpbyte( 0xb1 );              /* mov  cl,n */
        AddByte( log2 );
        _Next;
        LayOpbyte( 0xe4d2 );    /* shl  ah,cl */
        _Next;
        LayOpword( 0xc41a );    /* sbb  al,ah */
        _Next;
        break;
    case I2:
    case U2:
        LayOpbyte( 0xb1 );              /* mov  cl,n */
        AddByte( log2 );
        _Next;
        LayOpword( 0xe2d3 );    /* shl  dx,cl */
        OpndSizeIf();
        _Next;
        LayOpword( 0xc21b );    /* sbb  ax,dx */
        OpndSizeIf();
        _Next;
        LayOpword( 0xf8d3 );    /* sar  ax,cl */
        OpndSizeIf();
        break;
    default:
        break;
    }
}

static  void    SetOff( name *op, int val ) {
/**********************************************/

    if( op->n.class == N_INDEXED ) {
        op->i.constant += val;
    } else if( op->n.class == N_TEMP ) {
        op = DeAlias( op );
        op->t.location += val;
    } else { /* N_MEMORY*/
        op->v.offset += val;
    }
}

extern  void    GenUnkLea( pointer value ) {
/******************************************/


    LayOpword( M_LEA );
    OpndSize( HW_SP );
    LayReg( HW_SP );
    Inst[ RMR ] |= D16;
    ILen += 2;
    DoAbsPatch( value, 2 );
    Inst[ RMR ] |= DoIndex( HW_BP );
}

extern  void    GenLeaSP( long offset ) {
/***************************************
    LEA         sp,offset[bp]
*/

    _Code;
    LayOpword( M_LEA );
    OpndSize( HW_SP );
    LayReg( HW_SP );
    Inst[ RMR ] |= Displacement( offset, HW_BP );
    Inst[ RMR ] |= DoIndex( HW_BP );
    _Emit;
}

extern  void    GFstp10( type_length where ) {
/************************************/

    GCondFwait();
    LayOpword( 0x3edb );
    Inst[ RMR ] |= Displacement( -where, HW_BP );
    _Emit;
}


extern  void    GFld10( type_length where ) {
/***********************************/

    GCondFwait();
    LayOpword( 0x2edb );
    Inst[ RMR ] |= Displacement( -where, HW_BP );
    _Emit;
}

void StartBlockProfiling( block *blk ) {
/**************************************/

    blk = blk;
}

void EndBlockProfiling( void ) {
/************************/

}

segment_id GenP5ProfileData( char *fe_name, label_handle *data ) {
/****************************************************************/
    fe_name = fe_name;
    data = data;
    return( 0 );
}

⌨️ 快捷键说明

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