void AddRegs( void ) /****************************** Add some registers to the N_REGISTER list, so that we can do scoreboarding on them */ { hw_reg_set lo_part; name *reg_name; int i; int j; DS = AllocRegName( HW_DS ); SS = AllocRegName( HW_SS ); /* 89-01-03*/ ES = AllocRegName( HW_ES ); for( i = S_MAX; i-- > 0; ) { for( j = I_MAX; j-- > 0; ) { PtrRegs[i][j] = NULL; } } for( reg_name = Names[N_REGISTER]; reg_name != NULL; reg_name = reg_name->n.next_name ) { if( IsIndexReg( reg_name->r.reg, CP, false ) ) { if( HW_COvlap( reg_name->r.reg, HW_DS ) || HW_COvlap( reg_name->r.reg, HW_ES ) || HW_COvlap( reg_name->r.reg, HW_SS ) ) { lo_part = LowReg( reg_name->r.reg ); if( HW_COvlap( lo_part, HW_BX ) ) { PtrRegs[S_DS][I_BX] = NewRegName( HW_DS_BX ); PtrRegs[S_SS][I_BX] = NewRegName( HW_SS_BX ); PtrRegs[S_ES][I_BX] = NewRegName( HW_ES_BX ); } else if( HW_COvlap( lo_part, HW_SI ) ) { PtrRegs[S_DS][I_SI] = NewRegName( HW_DS_SI ); PtrRegs[S_SS][I_SI] = NewRegName( HW_SS_SI ); PtrRegs[S_ES][I_SI] = NewRegName( HW_ES_SI ); } else if( HW_COvlap( lo_part, HW_DI ) ) { PtrRegs[S_DS][I_DI] = NewRegName( HW_DS_DI ); PtrRegs[S_SS][I_DI] = NewRegName( HW_SS_DI ); PtrRegs[S_ES][I_DI] = NewRegName( HW_ES_DI ); } } } } /* 89-01-03*/ }
extern bool DoVerify( vertype kind, instruction *ins ) { /**********************************************************/ name *op1; name *op2; name *result; hw_reg_set tmp; result = ins->result; if( ins->num_operands != 0 ) { op1 = ins->operands[ 0 ]; if( ins->num_operands != 1 ) { op2 = ins->operands[ 1 ]; } } switch( kind ) { case V_OP2I2: /* * U2 is OK too. A U2 operand wouldn't be present in the instruction * unless the tree code decided it was ok for a halfword instruction * Kludgey? Maybe just a little. */ if( op2->n.name_class == U2 ) return( TRUE ); if( op2->n.name_class == I2 ) return( TRUE ); return( FALSE ); case V_OP1SMALL: if( op1->c.const_type != CONS_ABSOLUTE ) return( FALSE ); if( op1->c.int_value < 0 ) return( FALSE ); if( op1->c.int_value > 4095 ) return( FALSE ); return( TRUE ); case V_OP1TEMP: if( op1->n.class == N_TEMP ) return( TRUE ); return( FALSE ); case V_OP1ADDR: case V_OP1LOC: if( op1->n.class == N_MEMORY ) return( TRUE ); return( FALSE ); case V_OP2I2CON: if( op2->c.const_type == CONS_ABSOLUTE && CFIsI16( op2->c.value ) ) return( TRUE ); return( FALSE ); case V_LA2: if( HW_CEqual( op1->r.reg, HW_G0 ) ) return( FALSE ); /* fall through ! */ case V_OP2SMALL: if( op2->c.const_type != CONS_ABSOLUTE ) return( FALSE ); if( op2->c.int_value < 0 ) return( FALSE ); if( op2->c.int_value > 4095 ) return( FALSE ); return( TRUE ); case V_MULPAIR: if( !IsRegPair( result->r.reg ) ) return( FALSE ); tmp = LowReg( result->r.reg ); if( !HW_Equal( tmp, op1->r.reg ) ) return( FALSE ); return( TRUE ); case V_CONVPAIR: if( !IsRegPair( result->r.reg ) ) return( FALSE ); tmp = HighReg( result->r.reg ); if( !HW_Equal( tmp, op1->r.reg ) ) return( FALSE ); return( TRUE ); case V_SIZE_SMALL: if( op1->n.size > 256 ) return( FALSE ); return( TRUE ); case V_OP2BYTE4CONS: if( !CFIsI32( op2->c.value ) ) return( FALSE ); if( ( op2->c.int_value & 0xFFFFFF00 ) == 0 ) return( TRUE ); if( ( op2->c.int_value & 0xFFFF00FF ) == 0 ) return( TRUE ); if( ( op2->c.int_value & 0xFF00FFFF ) == 0 ) return( TRUE ); if( ( op2->c.int_value & 0x00FFFFFF ) == 0 ) return( TRUE ); return( FALSE ); case V_OP2BYTE2CONS: if( !CFIsI16( op2->c.value ) ) return( FALSE ); if( ( op2->c.int_value & 0xFFFFFF00 ) == 0 ) return( TRUE ); if( ( op2->c.int_value & 0xFFFF00FF ) == 0 ) return( TRUE ); return( FALSE ); case V_CMPEQ_OP2ZERO: if( !OtherVerify( V_CMPEQ, ins, op1, op2, result ) ) return( FALSE ); if( !OtherVerify( V_OP2ZERO, ins, op1, op2, result ) ) return( FALSE ); return( TRUE ); default: return( OtherVerify( kind, ins, op1, op2, result ) ); } return( FALSE ); }
extern void DumpOperand( name *operand ) { /********************************************/ char buffer[20]; hw_reg_set reg; name *base; if( operand->n.class == N_INDEXED ) { if( operand->i.base != NULL ) { if( !( operand->i.index_flags & X_FAKE_BASE ) ) { if( operand->i.index_flags & X_LOW_ADDR_BASE ) { DumpLiteral( "l^" ); } DumpOperand( operand->i.base ); if( operand->i.constant > 0 ) { DumpChar( '+' ); } } } if( operand->i.constant != 0 ) { DumpLong( operand->i.constant ); } DumpChar( '[' ); if( operand->i.index_flags & X_BASE ) { reg = operand->i.index->r.reg; #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( HW_COvlap( reg, HW_SEGS ) ) { hw_reg_set tmp; tmp = reg; HW_COnlyOn( tmp, HW_SEGS ); DumpRegName( tmp ); DumpChar( ':' ); HW_CTurnOff( reg, HW_SEGS ); } #endif if( operand->i.index_flags & X_HIGH_BASE ) { DumpRegName( HighReg( reg ) ); DumpChar( '+' ); DumpRegName( LowReg( reg ) ); } else { DumpRegName( LowReg( reg ) ); DumpChar( '+' ); DumpRegName( HighReg( reg ) ); } } else { DumpOperand( operand->i.index ); } if( operand->i.scale != 0 ) { DumpChar( '*' ); DumpInt( 1 << operand->i.scale ); } if( operand->i.index_flags & ( X_ALIGNED_1 | X_ALIGNED_2 | X_ALIGNED_4 | X_ALIGNED_8 ) ) { DumpChar( '$' ); DumpInt( FlagsToAlignment( operand->i.index_flags ) ); } DumpChar( ']' ); base = operand->i.base; if( base != NULL ) { if( operand->i.index_flags & X_FAKE_BASE ) { DumpChar( '{' ); if( base->n.class == N_MEMORY ) { DumpXString( AskName(base->v.symbol, base->m.memory_type) ); } else if( base->n.class == N_TEMP ) { if( _FrontEndTmp( base ) ) { DumpXString( FEName( base->v.symbol ) ); } else { DumpOperand( base ); } } DumpChar( '}' ); } }