/* 370 */ instruction *rUSEREGISTER( instruction *ins ) /************************************************/ { instruction *new_ins; instruction *ins2; name *name1; name1 = ins->operands[0]; if( CanUseOp1( ins, name1 ) ) { new_ins = MakeMove( name1, ins->result, ins->type_class ); ins->result = name1; MoveSegRes( ins, new_ins ); SuffixIns( ins, new_ins ); new_ins = ins; } else { name1 = AllocTemp( ins->type_class ); new_ins = MakeMove( ins->operands[0], name1, ins->type_class ); CheckCC( ins, new_ins ); ins->operands[0] = name1; MoveSegOp( ins, new_ins, 0 ); PrefixIns( ins, new_ins ); ins2 = MakeMove( name1, ins->result, ins->type_class ); ins->result = name1; MoveSegRes( ins, ins2 ); SuffixIns( ins, ins2 ); MarkPossible( ins, name1, ResultPossible( ins ) ); ins->u.gen_table = NULL; GiveRegister( NameConflict( ins, name1 ), true ); } return( new_ins ); }
instruction *rMOVOP2TEMP( instruction *ins ) /***********************************************/ { instruction *new_ins; name *name1; name1 = AllocTemp( ins->type_class ); new_ins = MakeMove( ins->operands[1], name1, ins->type_class ); ins->operands[1] = name1; MoveSegOp( ins, new_ins, 0 ); PrefixIns( ins, new_ins ); return( new_ins ); }
instruction *rMOVOP1TEMP( instruction *ins ) /**********************************************/ { instruction *new_ins; type_class_def type_class; name *name; type_class = _OpClass( ins ); name = AllocTemp( type_class ); new_ins = MakeMove( ins->operands[0], name, type_class ); ins->operands[0] = name; MoveSegOp( ins, new_ins, 0 ); PrefixIns( ins, new_ins ); return( new_ins ); }
instruction *rOP2REG( instruction *ins ) /*******************************************/ { instruction *new_ins; name *name1; type_class_def type_class; type_class = _OpClass( ins ); name1 = AllocTemp( type_class ); new_ins = MakeMove( ins->operands[1], name1, type_class ); ins->operands[1] = name1; MoveSegOp( ins, new_ins, 0 ); PrefixIns( ins, new_ins ); MarkPossible( ins, name1, Op1Possible( ins ) ); ins->u.gen_table = NULL; GiveRegister( NameConflict( ins, name1 ), true ); return( new_ins ); }
instruction *rOP1RESREG( instruction *ins ) /**********************************************/ { instruction *new_ins; instruction *ins2; name *name1; name *name2; name1 = AllocRegName( Op1Reg( ins ) ); new_ins = MakeMove( ins->operands[0], name1, _OpClass( ins ) ); ins->operands[0] = name1; MoveSegOp( ins, new_ins, 0 ); PrefixIns( ins, new_ins ); name2 = AllocRegName( ResultReg( ins ) ); ins2 = MakeMove( name2, ins->result, ins->type_class ); ins->result = name2; MoveSegRes( ins, ins2 ); SuffixIns( ins, ins2 ); return( new_ins ); }
instruction *rCLRHI_BW( instruction *ins ) /*********************************************/ { instruction *new_ins; instruction *ins2; name *name1; type_class_def half_type_class; half_type_class = HalfClass[ins->type_class]; name1 = AllocTemp( ins->type_class ); new_ins = MakeMove( ins->operands[0], LowPart( name1, half_type_class ), half_type_class ); ins->operands[0] = name1; MoveSegOp( ins, new_ins, 0 ); PrefixIns( ins, new_ins ); ins2 = MoveConst( 0, HighPart( name1, half_type_class ), half_type_class ); PrefixIns( ins, ins2 ); ins->head.opcode = OP_MOV; ins->table = NULL; ins->u.gen_table = NULL; return( new_ins ); }
instruction *rMAKECALL( instruction *ins ) /********************************************* Using the table RTInfo[], do all the necessary stuff to turn instruction "ins" into a call to a runtime support routine. Move the parms into registers, and move the return register of the runtime routine into the result. Used for 386 and 370 versions */ { rtn_info *info; label_handle lbl; instruction *left_ins; instruction *new_ins; instruction *last_ins; name *reg_name; hw_reg_set regs; hw_reg_set all_regs; hw_reg_set tmp; rt_class rtindex; if( !_IsConvert( ins ) ) { rtindex = LookupRoutine( ins ); } else { /* look it up again in case we ran out of memory during expansion*/ rtindex = LookupConvertRoutine( ins ); } info = &RTInfo[rtindex]; regs = _ParmReg( info->left ); all_regs = regs; left_ins = MakeMove( ins->operands[0], AllocRegName( regs ), info->operand_class ); ins->operands[0] = left_ins->result; MoveSegOp( ins, left_ins, 0 ); PrefixIns( ins, left_ins ); regs = _ParmReg( info->right ); if( !HW_CEqual( regs, HW_EMPTY ) ) { new_ins = MakeMove( ins->operands[1], AllocRegName( regs ), info->operand_class ); ins->operands[1] = new_ins->result; MoveSegOp( ins, new_ins, 0 ); HW_TurnOn( all_regs, regs ); PrefixIns( ins, new_ins ); } #if _TARGET & _TARG_370 tmp = RAReg(); HW_TurnOn( all_regs, tmp ); tmp = LNReg(); HW_TurnOn( all_regs, tmp ); #elif _TARGET & _TARG_80386 { tmp = ReturnReg( WD, false ); HW_TurnOn( all_regs, tmp ); } #endif reg_name = AllocRegName( all_regs ); lbl = RTLabel( rtindex ); new_ins = NewIns( 3 ); new_ins->head.opcode = OP_CALL; new_ins->type_class = ins->type_class; new_ins->operands[CALL_OP_USED] = reg_name; new_ins->operands[CALL_OP_USED2] = reg_name; new_ins->operands[CALL_OP_ADDR] = AllocMemory( lbl, 0, CG_LBL, ins->type_class ); new_ins->result = NULL; new_ins->num_operands = 2; /* special case for OP_CALL*/ #if _TARGET & _TARG_AXP { HW_CTurnOn( all_regs, HW_FULL ); HW_TurnOff( all_regs, SavedRegs() ); HW_CTurnOff( all_regs, HW_UNUSED ); HW_TurnOn( all_regs, ReturnAddrReg() ); } #endif new_ins->zap = (register_name *)AllocRegName( all_regs ); /* all parm regs could be zapped*/ last_ins = new_ins; if( ins->result == NULL || _OpIsCondition( ins->head.opcode ) ) { /* comparison, still need conditional jumps*/ ins->operands[0] = AllocIntConst( 0 ); ins->operands[1] = AllocIntConst( 1 ); DelSeg( ins ); DoNothing( ins ); /* just conditional jumps for ins*/ PrefixIns( ins, new_ins ); new_ins->ins_flags |= INS_CC_USED; last_ins = ins; } else { regs = _ParmReg( info->result ); tmp = regs; HW_TurnOn( tmp, new_ins->zap->reg ); new_ins->zap = (register_name *)AllocRegName( tmp ); reg_name = AllocRegName( regs ); new_ins->result = reg_name; last_ins = MakeMove( reg_name, ins->result, ins->type_class ); ins->result = last_ins->operands[0]; MoveSegRes( ins, last_ins ); SuffixIns( ins, last_ins ); ReplIns( ins, new_ins ); } FixCallIns( new_ins ); UpdateLive( left_ins, last_ins ); return( left_ins ); }