instruction *GenChoice(void) { instruction *ins; ins = NewIns( INS_CHOICE ); AddStream( LastIns, ins ); return( ins ); }
void GenSemCall( unsigned num ) { instruction *ins; ins = NewIns( INS_SEMANTIC ); ins->operand = num; CheckLong( ins ); AddStream( LastIns, ins ); }
void GenSetResult( unsigned value ) { instruction *ins; ins = NewIns( INS_SET_RESULT ); ins->operand = value; CheckLong( ins ); AddStream( LastIns, ins ); }
void GenLblCall( instruction *lbl ) { instruction *ins; ins = NewIns( INS_CALL ); ins->ptr = lbl; lbl->operand++; AddStream( LastIns, ins ); }
void GenJump( instruction *lbl ) { instruction *ins; ins = NewIns( INS_JUMP ); ins->ptr = lbl; lbl->operand++; AddStream( LastIns, ins ); }
void GenSetParm( unsigned value ) { instruction *ins; ins = NewIns( INS_SET_PARM ); ins->operand = value; CheckLong( ins ); AddStream( LastIns, ins ); }
void GenError( unsigned value ) { instruction *ins; ins = NewIns( INS_ERROR ); ins->operand = value; CheckLong( ins ); AddStream( LastIns, ins ); }
void GenOutput( unsigned value ) { instruction *ins; ins = NewIns( INS_OUTPUT ); ins->operand = value; CheckLong( ins ); AddStream( LastIns, ins ); }
void MkSelOp( name *idx, type_class_def type_class ) /*****************************************************/ { instruction *ins; ins = NewIns( 2 ); ins->head.opcode = OP_ADD; ins->type_class = WD; ins->operands[0] = idx->i.index; ins->operands[1] = idx->i.index; ins->result = idx->i.index; AddIns( ins ); ins = NewIns( 1 ); ins->operands[0] = idx; ins->result = idx->i.index; ins->head.opcode = OP_SELECT; ins->type_class = type_class; ins->ins_flags |= INS_CC_USED; AddIns( ins ); }
static void DropCall( instruction *ins, name *temp ) /******************************************************/ { name *eax_name; name *null_name; instruction *new_ins; null_name = AllocRegName( HW_EMPTY ); eax_name = AllocRegName( HW_EAX ); new_ins = NewIns( 3 ); new_ins->head.opcode = OP_CALL; new_ins->type_class = WD; new_ins->operands[ CALL_OP_USED ] = null_name; new_ins->operands[ CALL_OP_USED2 ] = null_name; new_ins->operands[ CALL_OP_ADDR ]= RTMemRef( RT_TLS_REGION ); new_ins->result = eax_name; new_ins->zap = &eax_name->r; new_ins->num_operands = 2; /* special case for OP_CALL*/ PrefixIns( ins, new_ins ); new_ins = MakeMove( eax_name, temp, WD ); PrefixIns( ins, 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 ); }
void GenReturn(void) { AddStream( LastIns, NewIns( INS_RETURN ) ); }
void GenInputAny( void ) { AddStream( LastIns, NewIns( INS_IN_ANY ) ); }
instruction *GenNewLbl(void) { return( NewIns( INS_LABEL ) ); }