s37enc.c

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

C
1,197
字号
            GenMemDown( result, left );
            break;
        case G_NORMF:
            GenNormF( result, left );
            break;
        default:
            _Zoiks( ZOIKS_028 );
        }
    }
    if( _OpIsCondition( ins->head.opcode ) ) {
        GenCondJump( ins );
    }
}


static  void    GenSRL( name *result, int by ) {
/**********************************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( result );
    hwop2.sx.a = 0;
    hwop2.sx.b = 0;
    hwop2.sx.ref  = NULL;
    hwop2.sx.disp = by;
    HWInsGen( HWOP_SRL, &hwop1, &hwop2, NULL );
}


static  bool    ZapsOperand( name *result, name *left ) {
/******************************************************/

    if( left->n.class != N_INDEXED ) return( FALSE );
    if( left->i.index == result ) return( TRUE );
    if( left->i.base == result ) return( TRUE );
    return( FALSE );
}


static  void    GenUConv1( name *result, name *left ) {
/*****************************************************/

    if( ZapsOperand( result, left ) ) {
        GenRmS( HWOP_ICM, result, 0x8, left );
        GenSRL( result, 24 );
    } else {
        GenRR( HWOP_SR, result, result );
        GenRX( HWOP_IC, result, left );
    }
}


static  void    GenUConv2( name *result, name *left ) {
/*****************************************************/

    if( ZapsOperand( result, left ) ) {
        GenRmS( HWOP_ICM, result, 0xc, left );
        GenSRL( result, 16 );
    } else {
        GenRR( HWOP_SR, result, result );
        GenRmS( HWOP_ICM, result, 0x3, left );
    }
}

static  void    GenMemDown( name *op1,  name *op2 ) {
/**Do a mem to mem convert of big int op2 to small int op1******/
    hwins_op_any hwop1;
    hwins_op_any hwop2;
    int adjust;

    GetOpName( &hwop1, op1 );
    GetOpName( &hwop2, op2 );
    hwop1.sx.a = op1->n.size;
    adjust = op2->n.size - op1->n.size;
    hwop2.sx.disp += adjust; /* JD says it will never be over 4K */
    HWInsGen( HWOP_MVC, &hwop1, &hwop2, NULL );
}

static  void    GenSelect( name *targ ) {
/***************************************/

    reg_num      reg;
    label_handle label;
    hw_sym       *hwlabel;
    name         *base;

    reg = RegOp( targ->i.index );
    base = targ->i.base;
    label = AskForSymLabel( base->v.symbol, base->m.memory_type );
    hwlabel = AskForHWLabel( label );
    HWBIndexGen( reg, hwlabel );
}


static  void    GenCLRR( type_class_def class, name *result ) {
/*****************************************************/

    hwins_opcode        op;

    op = HWOP_SR;
    if( class == FD ) {
        op = HWOP_SDR;
    } else if( class == FS ) {
        op = HWOP_SER;
    }
    GenRR( op, result, result );
}


static void GenPow2Div( name *res, name *cons ) {
/***********************************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop2.r = RegOp( res );
    hwop1.r = hwop2.r + 1;
    HWInsGen( HWOP_AR, &hwop1, &hwop2, NULL );
    hwop2.sx.b = 0;
    hwop2.sx.ref  = NULL;
    hwop2.sx.a = 0;
    hwop2.sx.disp = Log2( cons->c.int_value );
    HWInsGen( HWOP_SRA, &hwop1, &hwop2, NULL );
    hwop2.r = hwop1.r - 1;
    HWInsGen( HWOP_SR, &hwop1, &hwop2, NULL );
}


static void GenMVCL( hwins_opcode hwins, name *op1, name *op2 ) {
/*************************************************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( op1 ) - 1;
    hwop2.r = RegOp( op2 ) - 1;
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}


static void GenRR( hwins_opcode hwins, name *op1, name *op2 ) {
/*************************************************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( op1 );
    hwop2.r = RegOp( op2 );
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}


static void GenRDisp( hwins_opcode hwins, name *op1, int b, int disp ) {
/*******************************************************/

  /* RX instruction where op2 + op3 form base disp */
    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( op1 );
    hwop2.sx.ref = NULL;
    hwop2.sx.disp = disp;
    hwop2.sx.b = b;
    hwop2.sx.a = 0;
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}


static void GenRX( hwins_opcode hwins, name *op1, name *op2 ) {
/*************************************************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( op1 );
    GetOpName( &hwop2, op2 );
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}


static void GenRXH( hwins_opcode hwins, name *op1, name *op2 ) {
/****watch out for half word lits******************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( op1 );
    ChkLitOp( &hwop2, op2, I2 );
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}

static void GenRFX( hwins_opcode hwins, name *op1, name *op2,
                                        type_class_def tipe ) {
/*** Check for short or long float literal in X op2**********************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( op1 );
    ChkLitOp( &hwop2, op2, tipe );
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}

static  void    GenNormF( name *op1,  name *op2 ) {
/**********************************************************************
 Normalize result from CONV of op2 in mem to op1 reg
 if integer subtract 0x80000000  to set sign and compliment is negative
*/
    hwins_op_any hwop1;
    hwins_op_any hwop2;

    hwop1.r = RegOp( op1 );
    HWInsGen( HWOP_SDR, &hwop1, &hwop1, NULL );
    GetOpName( &hwop2, op2 );
    HWInsGen( HWOP_AD, &hwop1, &hwop2, NULL );
}



static void GenShift( hwins_opcode hwins, name *op1, name *op2 ) {
/****************************************************************/

  /* generate r,mask,s type instruction */
    hwins_op_any hwop1;
    hwins_op_any hwop2;
    hwins_op_any hwop3;

    hwop1.r = RegOp( op1 );
    hwop2.sx.a = 0;
    hwop2.sx.b = 0;
    hwop2.sx.ref  = NULL;
    if( op2->n.class == N_CONSTANT ) {
        hwop2.sx.disp = op2->c.int_value;
    } else {
        hwop2.sx.b = RegOp( op2 );
        hwop2.sx.disp = 0;
    }
    HWInsGen( hwins, &hwop1, &hwop2, &hwop3 );
}


static void GenRmS( hwins_opcode hwins, name *op1, int mask, name *op2 ) {
/*******************************************************/

  /* generate r,mask,s type instruction */
    hwins_op_any hwop1;
    hwins_op_any hwop2;
    hwins_op_any hwop3;

    hwop1.r = RegOp( op1 );
    hwop3.i = mask;
    GetOpName( &hwop2, op2 );
    HWInsGen( hwins, &hwop1, &hwop2, &hwop3 );
}


static void GenSS( hwins_opcode hwins, name *op1, name *op2,
                                       type_class_def tipe ){
/*************************************************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    ChkLitOp( &hwop1, op1, tipe );
    hwop1.sx.a = op1->n.size;
    ChkLitOp( &hwop2, op2, tipe );
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}


static void GenSI( hwins_opcode hwins, name *op1, name *op2 ) {
/*************************************************************/

    hwins_op_any hwop1;
    hwins_op_any hwop2;

    GetOpName( &hwop1, op1 );
    hwop2.i = op2->c.int_value;
    HWInsGen( hwins, &hwop1, &hwop2, NULL );
}


static void GetConsLit( hwins_op_any *hwop, name *op ){
/*****************************************************/

    name *op2;

    switch( op->c.const_type ) {
    case CONS_ABSOLUTE:
        hwop->sx.b  = 0xff; /* set to a bad value for now */
        hwop->sx.ref = HWLitIntGen( op->c.int_value, 4 );
        break;
    case CONS_ADDRESS:
        op2 = op->c.value;
        GetAddrLit( hwop, op2 );
        break;
    case CONS_OFFSET:
        Zoiks( ZOIKS_060 );
        break;
    case CONS_SEGMENT:
        Zoiks( ZOIKS_060 );
        break;
    case CONS_TEMP_ADDR:
        Zoiks( ZOIKS_060 );
        break;
    }

}

static void GetAddrLit( hwins_op_any *hwop, name *op ){
/*****************************************************/
    label_handle  label;
    hw_sym       *hwlabel;
    bool          rel;

    label = AskForSymLabel( op->v.symbol, op->m.memory_type );
    hwlabel = AskForHWLabel( label );
    if( op->m.memory_type == CG_FE ) {
        if( FEAttr( op->v.symbol ) & FE_IMPORT ){
            HWExtern( hwlabel );
        }
    }else if( AskIfRTLabel( label ) ) {
        HWExtern( hwlabel );
    }
    hwop->sx.a  = 0;
    hwop->sx.b  = 0;
    hwop->sx.disp = 0;
    rel = MemNeedsReloc( op->v.symbol, op->m.memory_type );
    hwop->sx.ref =   HWLitAddr( hwlabel, op->v.offset, rel );
}

extern bead_def *GetanAddr( label_handle label, bool reloc ){
/**Make an addr bead for label used by dbginfo stuff****/

    sym_handle  sym;
    hw_sym      *hwlabel;
    bead_addr   *bead;

    hwlabel = AskForHWLabel( label );
    sym = AskForLblSym( label );
    if( sym != NULL ) {
        if( FEAttr( sym ) & FE_IMPORT ){
            HWExtern( hwlabel );
        }

    }
    bead =   HWSymAddr( hwlabel, 0, reloc );
    return( (bead_def *)bead );
}


static void GetMemRef( hwins_op_any *hwop, name *op ) {
/*****************************************************/

    label_handle label;
    hw_sym      *hwlabel;

    label = AskForSymLabel( op->v.symbol, op->m.memory_type );
    hwlabel =  AskForHWLabel( label );
    hwop->sx.b  = 0;
    hwop->sx.ref = HWSymRef( hwlabel );
    hwop->sx.disp = op->v.offset;
}

static void GetMemDisp( hwins_op_any *hwop, name *op ) {
/*****************************************************/

    label_handle label;
    hw_sym      *hwlabel;
    hw_loc      *hwbase;
    name        *base;

    base = op->i.base;
    label = AskForSymLabel( base->v.symbol, base->m.memory_type );
    hwlabel =  AskForHWLabel( label );
    hwbase  =  AskForBaseHW( label );
    if( hwlabel->defflag & TXT_DATA ){ /* defined in another file */
        hwop->sx.disp = op->i.constant;
    }else{
        hwop->sx.disp  = base->v.offset - hwbase->disp;
        hwop->sx.ref = HWDispRef( hwlabel, hwbase->sym );
    }
}

static  reg_num TempBase( name *temp ) {
/**************************************/

    if( temp->t.temp_flags & STACK_PARM ) return( CurrProc->state.regs.PA );
    return( CurrProc->state.regs.AR );
}

static void ChkLitOp( hwins_op_any *hwop, name *op, type_class_def tipe ) {
/**** check for int & flt lits with regard to type or just load op********/
    type_length tlen;

    if( op->n.class == N_CONSTANT
     && op->c.const_type == CONS_ABSOLUTE ){
        hwop->sx.a = 0;

⌨️ 快捷键说明

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