instruction *rCLRHI_R( instruction *ins ) /********************************************/ { instruction *new_ins; instruction *and_ins; type_class_def type_class; hw_reg_set high; name *res; signed_32 value; type_class_def half_type_class; name *op; half_type_class = HalfClass[ins->type_class]; op = ins->operands[0]; type_class = ins->base_type_class; res = ins->result; high = HighReg( res->r.reg ); if( op->n.class == N_INDEXED && ( ( op->i.index->n.class == N_REGISTER && HW_Ovlap( op->i.index->r.reg, res->r.reg ) ) /* (1) */ || ( CheckIndecies( ins, res->r.reg, HW_EMPTY, NULL ) == MB_MAYBE ) /* 2 */ ) ) { /* (1) would have gen'd movzd eax,[eax] * (2) avoid incorrect reduction of "cnv [foo] => BX" to * xor bx,bx / mov bx, [foo] / mov bl, [bx] * (zoiks register allocator) */ new_ins = NULL; } else if( !HW_CEqual( high, HW_EMPTY ) && half_type_class == type_class ) {
bool ScConvert( instruction *ins ) /******************************************** Get rid of instructions like CBW if the high part is not used in the next instruction. */ { hw_reg_set tmp; if( G( ins ) == G_SIGNEX ) { tmp = HighReg( ins->result->r.reg ); if( !HW_Ovlap( ins->head.next->head.live.regs, tmp ) ) { FreeIns( ins ); /* get rid of the pesky cwd or cbw instruction!*/ return( true ); } } return( false ); }
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( '}' ); } }