static instruction *PromoteOperand( instruction *ins ) { /***********************************************************/ name *temp; instruction *new_ins; if( _IsFloating( ins->type_class ) ) { if( ins->type_class == FS ) { temp = AllocTemp( FD ); new_ins = MakeConvert( ins->operands[0], temp, ins->type_class, FD ); ins->operands[0] = temp; PrefixIns( ins, new_ins ); UpdateLive( new_ins, ins ); return( new_ins ); } } else { if( ins->type_class < U8 ) { temp = AllocTemp( U8 ); new_ins = MakeConvert( ins->operands[0], temp, ins->type_class, U8 ); ins->operands[0] = temp; PrefixIns( ins, new_ins ); UpdateLive( new_ins, ins ); return( new_ins ); } } return( NULL ); }
static bool SameLocation( name *n1, name *n2 ) { /**************************************************/ type_length loc1, loc2; name *base; if( n1->t.location == NO_LOCATION ) return( FALSE ); if( n2->t.location == NO_LOCATION ) return( FALSE ); base = DeAlias( n1 ); loc1 = base->t.location + n1->v.offset - base->v.offset; base = DeAlias( n2 ); loc2 = base->t.location + n2->v.offset - base->v.offset; if( _IsFloating( n1->n.name_class ) || _IsFloating( n2->n.name_class ) ) { if( n1->n.name_class != n2->n.name_class ) return( FALSE ); } return( loc1 == loc2 ); }
static instruction *SetToConst( block *blk, signed_64 *pcons ) { /*******************************************************************/ instruction *ins; instruction *next; name *op; for( ins = blk->ins.hd.next; ins->head.opcode == OP_NOP; ) { ins = ins->head.next; } if( ins->head.opcode != OP_MOV ) return( NULL ); if( _IsFloating( ins->type_class ) ) return( NULL ); for( next = ins->head.next; next->head.opcode == OP_NOP; ) { next = next->head.next; } if( next->head.opcode != OP_BLOCK ) return( NULL ); op = ins->operands[0]; if( op->n.class != N_CONSTANT || op->c.const_type != CONS_ABSOLUTE ) { return( NULL ); } U64Set( pcons, op->c.lo.int_value, op->c.hi.int_value ); return( ins ); }
static instruction *SetToConst( block *blk, signed_32 *pcons ) /*****************************************************************/ { instruction *ins; instruction *next; name *op; ins = blk->ins.hd.next; while( ins->head.opcode == OP_NOP ) { ins = ins->head.next; } if( ins->head.opcode != OP_MOV ) return( NULL ); if( _IsFloating( ins->type_class ) ) return( NULL ); next = ins->head.next; while( next->head.opcode == OP_NOP ) { next = next->head.next; } if( next->head.opcode != OP_BLOCK ) return( NULL ); op = ins->operands[0]; if( op->n.class != N_CONSTANT || op->c.const_type != CONS_ABSOLUTE ) return( NULL ); *pcons = op->c.int_value; return( ins ); }
static void AssignPushLocals( void ) { /*********************************** Scan through HeadBlock to see if there are any leading instructions of the form MOV REG => temp, where temp is on the stack. We can eliminate the instruction (call DoNothing to mark it as unnecessary to generate) and then the guy that generates the prolog can come along later and generate PUSH REG, and adjust the SUB SP,n instruction appropriately. this replaces a move with a less expensive push, and if all locals turn out to be push locals, eliminates the SUP SP,n instruction as well */ instruction *move; name *src; name *dst; type_length curr_offset; move = HeadBlock->ins.hd.next; curr_offset = 0; for(;;) { if( CurrProc->prolog_state & GENERATED_PROLOG ) break; if( DoesSomething( move ) ) { if( move->head.opcode != OP_MOV ) break; if( UnChangeable( move ) ) break; src = move->operands[ 0 ]; dst = move->result; if( src->n.class != N_REGISTER ) break; if( _IsFloating( src->n.name_class ) ) break; /*90-Dec-17*/ if( dst->n.class != N_TEMP ) break; #if _TARGET & _TARG_80386 if( dst->n.size != 4 ) break; #else if( dst->n.size != 2 && dst->n.size != 4 ) break; #endif curr_offset -= PushSize( dst->n.size );/* assume it will be pushed*/ if( DeAlias( dst ) != dst ) break; if( dst->v.usage & HAS_MEMORY ) { if( dst->t.location != curr_offset ) break; } else { CurrProc->targ.push_local_size += PushSize( dst->n.size ); dst->t.location = - CurrProc->targ.push_local_size; dst->v.usage |= HAS_MEMORY; PropLocal( dst ); } move->head.state = OPERANDS_NEED_WORK; DoNothing( move ); } move = move->head.next; } }