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