s37txt.c

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

C
1,685
字号
        case BEAD_ADDR:
            DmpAddr( obj, (bead_addr*)bead );
            break;
        case BEAD_INT:
            DmpInt( obj, (bead_int*)bead );
            break;
        case BEAD_FLT:
            DmpFlt( obj, (bead_flt*)bead );
            break;
        case BEAD_DISP:
            DmpDisp( obj, (bead_disp*)bead );
            break;
        case BEAD_XSYM:
            DmpXsym( obj, (bead_xsym*)bead );
            break;
        case BEAD_USING:
            DmpUsing( obj, (bead_using*)bead );
            break;
        case BEAD_DROP:
            DmpDrop( obj, (bead_drop*)bead );
            break;
        case BEAD_LTORG: /* returns next bead */
            bead = DmpLtorg( obj, (bead_ltorg*)bead );
            break;
        case BEAD_STARTPROC: /* internal queues */
            DmpMsg( obj, "STARTPROC" );
            break;
        case BEAD_EPILOGUE:
            DmpMsg( obj, "EPILOGUE" );
            break;
        case BEAD_ENDPROC:
            DmpMsg( obj, "ENDPROC" );
            break;
        case BEAD_QUEUE:
            DmpQueue( obj, (bead_queue*)bead );
            break;
        case BEAD_SEG:
           DmpSeg( obj, (bead_seg*)bead );
           break;
        case BEAD_STORE:
            DmpStore( obj, (bead_store*)bead );
            break;
        default:
            Zoiks( ZOIKS_061 );
        }
        if( ( obj->opts & LST_ASM )&& (bead->class != BEAD_QUEUE) ){
            PutAsm( obj );
        }
        bead = bead->next;
    }
}

static  short int GetDispSX(  txt_obj *obj, hwins_op_sx *sx ) {
/*********************************************/

    long int disp;
    bead_def *bead;
    offset    base_disp;

    disp = sx->disp;
    if( sx->ref != NULL ) {
        if( sx->ref->entry.class == REF_LIT ) { /* lit ref */
            bead = sx->ref->lit.def;
            base_disp = obj->using.base_disp;
            sx->b = obj->using.base_reg;
        } else if( sx->ref->entry.class == REF_SYM) {/* sym ref */
            bead = sx->ref->sym.sym->def;
            base_disp = obj->using.base_disp;
            sx->b = obj->using.base_reg;
        } else if( sx->ref->entry.class == REF_DISP ) {/* sym ref */
            bead = sx->ref->disp.base->def;
            base_disp = bead->address;
            bead = sx->ref->disp.sym->def;
        }
        disp += bead->address-base_disp;
    }
    if( disp > 4095 || disp < 0 ) {
        if( obj->opts & LST_ASM ) {
            fmt_str( obj->asm->com, "ADDRESS ERROR" );
        }
        Zoiks( ZOIKS_062 ); /* addressability error */
    }
    return( disp );

}

static  offset GetAddrSX( hwins_op_sx *sx ) {
/*** Get addr of sx from start of CSECT   ****/

    bead_def *bead;
    offset    ref_addr;

    ref_addr = sx->disp;
    if( sx->ref != NULL ) {
        if( sx->ref->entry.class == REF_LIT ) { /* lit ref */
            bead = sx->ref->lit.def;
            ref_addr = bead->address;
        } else if( sx->ref->entry.class == REF_SYM) {/* sym ref */
            bead = sx->ref->sym.sym->def;
            ref_addr = bead->address;
        }
    }
    return( ref_addr );

}

static void DmpHwIns( txt_obj *obj, any_bead_hwins *bead  ) {
/****************************************/

    hwins_class    hwclass;
    hwins_opcode   opcode;
    int            inslen;
    char           out[6];


    char           inscode;

    enum ON_flags{
         ON_none = 0,
         ON_b2 = 0x1,
         ON_n1 = 0x2,
         ON_n2 = 0x4,
         ON_d1 = 0x8,
         ON_d2 = 0x10
    }flags;

    char           b2;
    char           n1;
    char           n2;
    hwins_op_sx    *d1;
    hwins_op_sx    *d2;

    hwclass = bead->ins.class;
    opcode = bead->ins.opcode;
    inslen = HWOpICL[hwclass];
    inscode   = HWOpTable[opcode].inscode;

    flags = ON_none;
    switch( hwclass ) {
    case HWINS_RR:
        n1 = bead->rr.r1;
        n2 = bead->rr.r2;
        flags = ON_n1 + ON_n2;
        break;
    case HWINS_RX:
        n1 = bead->rx.r1;
        n2 =  bead->rx.s2.a;
        d1 =  &bead->rx.s2;
        flags = ON_n1 + ON_n2 + ON_d1;
        break;
    case HWINS_RS1:
        n1 = bead->rs1.r1;
        n2 = bead->rs1.r3;
        d1 = &bead->rs1.s2;
        flags = ON_n1 + ON_n2 + ON_d1;
        break;
    case HWINS_RS2:
        n1 = bead->rs2.r1;
        d1 = &bead->rs2.s2;
        flags = ON_n1 + ON_d1;
        break;
    case HWINS_SI:
        b2 = bead->si.i2;
        d1 = &bead->si.s1;
        flags = ON_b2 + ON_d1;
        break;
    case HWINS_S:
        d1 = &bead->s.s2;
        flags = ON_d1;
        break;
    case HWINS_SS1:
        b2 = bead->ss1.s1.a-1;
        d1 = &bead->ss1.s1;
        d2 = &bead->ss1.s2;
        flags = ON_b2 + ON_d1 + ON_d2;
        break;
    case HWINS_SS2:
        n1 = bead->ss2.s1.b-1;
        n2 = bead->ss2.s2.a-1;
        d1 = &bead->ss2.s1;
        d2 = &bead->ss2.s2;
        flags = ON_n1 + ON_n2 + ON_d1 + ON_d2;
        break;
    case HWINS_SSP:
        n1 = bead->ssp.s1.b-1;
        n2 = bead->ssp.s2.a;
        d1 = &bead->ssp.s1;
        d2 = &bead->ssp.s2;
        flags = ON_n1 + ON_n2 + ON_d1 + ON_d2;
        break;
    default:
        Zoiks( ZOIKS_063 );
    }
    out[0] = inscode;
    memset( &out[1], 0, 5 );
    if( flags & ON_b2 ) {
        out[1] = b2;
    }
    if( flags & ON_n1 ) {
        out[1] = n1<<4;
    }
    if( flags & ON_n2 ) {
        out[1] |= n2;
    }
    if( flags & ON_d1 ) {
        Stick16( &out[2], GetDispSX( obj, d1 ) );
        out[2] |= d1->b << 4;
    }
    if( flags & ON_d2 ) {
        Stick16( &out[4], GetDispSX( obj, d2 ) );
        out[4] |= d2->b << 4;
    }
    if( obj->opts & LST_ASM ) {
        if( obj->opts & LST_OBJ ) {
            fmt_hex( &obj->ocodes->c[0], bead->ins.common.address, 5 );
            fmt_lxstr( &obj->ocodes->c[6], &out[0], 2 );
            if( inslen > 2 ) {
                fmt_lxstr( &obj->ocodes->c[11], &out[2], 2 );
            }
            if( inslen > 4 ) {
                fmt_lxstr( &obj->ocodes->c[16], &out[4], 2 );
            }
            if( flags & ON_d1 ) {
                fmt_hex( &obj->ocodes->c[21], GetAddrSX( d1 ), 5);
            }
            if( flags & ON_d2 ) {
                fmt_hex( &obj->ocodes->c[27], GetAddrSX( d2 ), 5 );
            }
        }
        AsmHwIns( obj, bead );
    }
    TxtOut( obj, bead->ins.common.address, out, inslen );
}

static char *DmpLitRef( char *cur, ref_lit *lit ) {
/***************************************/
    bead_def  *bead;

    bead = lit->def;
    *cur++ = '=';
    switch( bead->class ) {
    case BEAD_DATA:
        cur = PrtData( cur, (bead_data *)bead );
        break;
    case BEAD_ADDR:
        cur = PrtAddr( cur, (bead_addr *)bead );
        break;
    case BEAD_INT:
        cur = PrtInt( cur,  (bead_int *)bead );
        break;
    case BEAD_FLT:
        cur = PrtFlt( cur,  (bead_flt *)bead );
        break;
    }
    return( cur );
}

static  char *DmpSX( char *cur,  hwins_op_sx *sx, int a ) {
/*********************************************/

    hw_sym *sym;
    hw_sym *base;

    if( sx->ref == NULL ) {
        cur = fmt_dec( cur, sx->disp );
        *cur++ = '(';
        if( a ) {
            cur = fmt_dec( cur, sx->a );
            *cur++ = ',';
        }
        cur = fmt_dec( cur, sx->b );
        *cur++ = ')';
    } else {
        if( sx->ref->entry.class == REF_LIT ) { /* lit ref */
            cur = DmpLitRef( cur, sx->ref );
        } else if( sx->ref->entry.class == REF_SYM) {/* sym ref */
            sym = (hw_sym *)sx->ref->sym.sym;
            cur = OutSym( cur, sym, TRUE );
            if( sx->disp != 0 ) {
                *cur++ = '+';
                cur = fmt_dec( cur, sx->disp );
            }
        } else if( sx->ref->entry.class == REF_DISP) {/* explicit base */
            sym = (hw_sym *)sx->ref->disp.sym;
            base = (hw_sym *)sx->ref->disp.base;
            cur = OutSym( cur, sym, TRUE );
            if( sx->disp < 0 ) {
                cur = fmt_dec( cur, sx->disp );
            }else if( sx->disp > 0 ) {
                *cur++ = '+';
                cur = fmt_dec( cur, sx->disp );
            }
            *cur++ = '-';
            cur = OutSym( cur, base, TRUE );
            *cur++ = '(';
            *cur++ = ',';
            cur = fmt_dec( cur, sx->b );
            *cur++ = ')';
        }
    }
    return( cur );
}

static void AsmHwIns( txt_obj *obj, any_bead_hwins *bead  ) {
/********** dump assemble mnemonics******/
    hwins_class    hwclass;
    hwins_opcode   opcode;
    char          *cur;
    char const    *brmnem;

    enum asm_op { /* asm format of fields    */
        ASM_NULL, /* field not used          */
        ASM_R,    /* field is reg            */
        ASM_S,    /* field is disp(base)     */
        ASM_SX,   /* field is disp( l|r,base)*/
        ASM_I     /* field is immediate      */
    };

    struct { /* assembler field  */
        enum asm_op class;
        union {
            hwins_op_sx  *sx;
            char          r;
            char          i;
        }op;
    } f[3], *cur_f;
    int fcount;  /* number of operands     */


    hwclass = bead->ins.class;
    opcode = bead->ins.opcode;
    switch( hwclass ) {
    case HWINS_RR:
        f[0].class = ASM_R;
        f[0].op.r = bead->rr.r1;
        f[1].class = ASM_R;
        f[1].op.r = bead->rr.r2;
        fcount = 2;
        break;
    case HWINS_RX:
        f[0].class = ASM_R;
        f[0].op.r = bead->rx.r1;
        f[1].class = ASM_SX;
        f[1].op.sx = &bead->rx.s2;
        fcount = 2;
        break;
    case HWINS_RS1:
        f[0].class = ASM_R;
        f[0].op.r = bead->rs1.r1;
        f[1].class = ASM_R;
        f[1].op.r = bead->rs1.r3;
        f[2].class = ASM_S;
        f[2].op.sx = &bead->rs1.s2;
        fcount = 3;
        break;
    case HWINS_RS2:
        f[0].class = ASM_R;
        f[0].op.r = bead->rs2.r1;
        f[1].class = ASM_S;
        f[1].op.sx = &bead->rs2.s2;
        fcount = 2;
        break;
    case HWINS_SI:
        f[0].class = ASM_S;
        f[0].op.sx = &bead->si.s1;
        f[1].class = ASM_I;
        f[1].op.i =  bead->si.i2;
        fcount = 2;
        break;
    case HWINS_S:
        f[0].class = ASM_S;
        f[0].op.sx = &bead->s.s2;
        fcount = 1;
        break;
    case HWINS_SS1:
        f[0].class = ASM_SX;
        f[0].op.sx = &bead->ss1.s1;
        f[1].class = ASM_S;
        f[1].op.sx = &bead->ss1.s2;
        fcount = 2;
        break;
    case HWINS_SS2:
        f[0].class = ASM_SX;
        f[0].op.sx = &bead->ss2.s1;
        f[1].class = ASM_SX;
        f[1].op.sx = &bead->ss2.s2;
        fcount = 2;
        break;
    case HWINS_SSP:
        f[0].class = ASM_SX;
        f[0].op.sx = &bead->ssp.s1;
        f[1].class = ASM_S;
        f[1].op.sx = &bead->ssp.s2;
        f[2].class = ASM_I;
        f[2].op.i = bead->ssp.s2.a;
        fcount = 3;
        break;
    default:
        Zoiks( ZOIKS_063 );
    }
    cur_f = f;
    if( opcode == HWOP_BCR || opcode == HWOP_BC ) {
        brmnem = BRMnem[ f[0].op.r ];
        if( *brmnem != '\0' ) {
            cur = fmt_str( obj->asm->code, brmnem );
            if( opcode == HWOP_BCR ) {
                *cur = 'R';
            }
            ++cur_f;
            --fcount;
        } else {
            fmt_str( obj->asm->code, HWOpTable[opcode].name );
        }
    } else {
        fmt_str( obj->asm->code, HWOpTable[opcode].name );
    }
    cur = obj->asm->ops;
    for(;;) {
        switch( cur_f->class ) {
        case ASM_R:
            cur = fmt_dec( cur, cur_f->op.r );
            break;

⌨️ 快捷键说明

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