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