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 + -
显示快捷键?