コード例 #1
0
ファイル: axprgtbl.c プロジェクト: ArmstrongJ/open-watcom-v2
hw_reg_set      FixedRegs( void )
/***********************************/
/* MJC do you really want to fix them */
{
    hw_reg_set          fixed;

    HW_CAsgn( fixed, HW_R30 );
    HW_CTurnOn( fixed, HW_R31 );
    HW_CTurnOn( fixed, HW_R15 );
    HW_CTurnOn( fixed, HW_F30 ); // Used to generate problematic converts (I8->FD and such)
    return( fixed );
}
コード例 #2
0
ファイル: cpragx86.c プロジェクト: XVilka/owp4v1copy
static void CopyAuxInfo( void )
/*****************************/
{
    hw_reg_set      default_flt_n_seg;
    hw_reg_set      flt_n_seg;

    if( CurrEntry == NULL ) {
        // Redefining a built-in calling convention
    } else {
        CurrInfo = (struct aux_info *)CMemAlloc( sizeof( struct aux_info ) );
        *CurrInfo = *CurrAlias;
    }
    if( AuxInfo.code != NULL ) {
        CurrInfo->code = AuxInfo.code;
    }
    if( AuxInfoFlg.f_near ) {
        CurrInfo->cclass &= ~FAR;
    }
    if( AuxInfoFlg.f_routine_pops ) {
        CurrInfo->cclass &= ~CALLER_POPS;
    }
    if( AuxInfoFlg.f_caller_return ) {
        CurrInfo->cclass &= ~ROUTINE_RETURN;
    }
    if( AuxInfoFlg.f_8087_returns ) {
        CurrInfo->cclass &= ~NO_8087_RETURNS;
    }
    CurrInfo->cclass |= AuxInfo.cclass;
    CurrInfo->flags |= AuxInfo.flags;
    if( AuxInfo.objname != NULL )
        CurrInfo->objname = AuxInfo.objname;
    if( AuxInfo.cclass & SPECIAL_RETURN )
        CurrInfo->returns = AuxInfo.returns;
    if( AuxInfo.cclass & SPECIAL_STRUCT_RETURN )
        CurrInfo->streturn = AuxInfo.streturn;
    if( AuxInfo.parms != NULL )
        CurrInfo->parms = AuxInfo.parms;

    if( !HW_CEqual( AuxInfo.save, HW_EMPTY ) ) {
        HW_CTurnOn( CurrInfo->save, HW_FULL );
        if( !( AuxInfo.cclass & MODIFY_EXACT ) && !CompFlags.save_restore_segregs ) {
            HW_Asgn( default_flt_n_seg, WatcallInfo.save );
            HW_CAsgn( flt_n_seg, HW_FLTS );
            HW_CTurnOn( flt_n_seg, HW_SEGS );
            HW_TurnOff( CurrInfo->save, flt_n_seg );
            HW_OnlyOn( default_flt_n_seg, flt_n_seg );
            HW_TurnOn( CurrInfo->save, default_flt_n_seg );
        }
        HW_TurnOff( CurrInfo->save, AuxInfo.save );
    }
}
コード例 #3
0
ファイル: cpragx86.c プロジェクト: jossk/open-watcom-v2
static void GetSaveInfo(
    void )
{
    hw_reg_set      modlist;
    hw_reg_set      default_flt_n_seg;
    hw_reg_set      flt_n_seg;

    struct {
        unsigned f_exact        : 1;
        unsigned f_nomemory     : 1;
        unsigned f_list         : 1;
    } have;

    have.f_exact    = 0;
    have.f_nomemory = 0;
    have.f_list     = 0;
    for( ;; ) {
        if( !have.f_exact && PragRecog( "exact" ) ) {
            CurrInfo->cclass |= MODIFY_EXACT;
            have.f_exact = 1;
        } else if( !have.f_nomemory && PragRecog( "nomemory" ) ) {
            CurrInfo->cclass |= NO_MEMORY_CHANGED;
            have.f_nomemory = 1;
        } else if( !have.f_list && IS_REGSET( CurToken ) ) {
            modlist = PragRegList();
            have.f_list = 1;
        } else {
            break;
        }
    }
    if( have.f_list ) {
        HW_Asgn( default_flt_n_seg, DefaultInfo.save );
        HW_CTurnOn( CurrInfo->save, HW_FULL );
        if( !have.f_exact && !CompFlags.save_restore_segregs ) {
            HW_CAsgn( flt_n_seg, HW_FLTS );
            HW_CTurnOn( flt_n_seg, HW_SEGS );
            HW_TurnOff( CurrInfo->save, flt_n_seg );
            HW_OnlyOn( default_flt_n_seg, flt_n_seg );
            HW_TurnOn( CurrInfo->save, default_flt_n_seg );
        }
        HW_TurnOff( CurrInfo->save, modlist );
    }
}
コード例 #4
0
ファイル: x86call.c プロジェクト: ArmstrongJ/open-watcom-v2
an      BGCall( cn call, bool use_return, bool in_line )
/******************************************************/
{
    instruction         *call_ins;
    call_state          *state;
    name                *ret_ptr = NULL;
    name                *result;
    name                *temp;
    name                *reg_name;
    instruction         *ret_ins = NULL;
    hw_reg_set          return_reg;
    hw_reg_set          zap_reg;

    if( call->name->tipe == TypeProcParm ) {
        SaveDisplay( OP_PUSH );
    }

    state = call->state;
    result = BGNewTemp( call->tipe );
    call_ins = call->ins;

/*   If we have a return value that won't fit in a register*/
/*   pass a pointer to result as the first parm*/

    if( call_ins->type_class == XX ) {
        if( _RoutineIsFar16( state->attr ) ) {
            if( state->attr & ROUTINE_ALLOCS_RETURN ) {
                HW_CAsgn( state->return_reg, HW_EAX );
            } else {
                HW_CAsgn( state->return_reg, HW_EBX );
            }
        }
        if( ( state->attr & ROUTINE_ALLOCS_RETURN ) == 0 ) {
            if( HW_CEqual( state->return_reg, HW_EMPTY ) ) {
                ret_ptr = AllocTemp( WD );
            } else {
                ret_ptr = AllocRegName( state->return_reg );
            }
            ret_ins = MakeUnary( OP_LA, result, ret_ptr, WD );
            HW_TurnOn( state->parm.used, state->return_reg );
            call_ins->flags.call_flags |= CALL_RETURNS_STRUCT;
        }
    }
    if( _IsTargetModel(FLOATING_DS) && (state->attr&ROUTINE_NEEDS_DS_LOADED) ) {
        HW_CTurnOn( state->parm.used, HW_DS );
    }
    if( _RoutineIsFar16( state->attr ) ) {
#if _TARGET & _TARG_80386
        Far16Parms( call );
#endif
    } else {
        if( AssgnParms( call, in_line ) ) {
            if( state->attr & ROUTINE_REMOVES_PARMS ) {
                call_ins->flags.call_flags |= CALL_POPS_PARMS;
            }
        }
    }

    if( state->attr & (ROUTINE_MODIFIES_NO_MEMORY | ROUTINE_NEVER_RETURNS) ) {
        /* a routine that never returns can not write any memory as far
            as this routine is concerned */
        call_ins->flags.call_flags |= CALL_WRITES_NO_MEMORY;
    }
    if( state->attr & ROUTINE_READS_NO_MEMORY ) {
        call_ins->flags.call_flags |= CALL_READS_NO_MEMORY;
    }
    if( state->attr & ROUTINE_NEVER_RETURNS ) {
        call_ins->flags.call_flags |= CALL_ABORTS;
    }
    if( _RoutineIsInterrupt( state->attr ) ) {
        call_ins->flags.call_flags |= CALL_INTERRUPT | CALL_POPS_PARMS;
    }
    if( !use_return ) {
        call_ins->flags.call_flags |= CALL_IGNORES_RETURN;
    }
    if( call_ins->type_class == XX ) {
        reg_name = AllocRegName( state->return_reg );
        if( state->attr & ROUTINE_ALLOCS_RETURN ) {
            call_ins->result = reg_name;
            AddCall( call_ins, call );
            if( use_return ) {
                temp = AllocTemp( WD ); /* assume near pointer*/
                AddIns( MakeMove( reg_name, temp, WD ) );
                temp = SAllocIndex( temp, NULL, 0,
                                    result->n.type_class, call->tipe->length );
                AddIns( MakeMove( temp, result, result->n.type_class ) );
            }
        } else {
            call_ins->result = result;
            AddIns( ret_ins );
            if( HW_CEqual( state->return_reg, HW_EMPTY ) ) {
                AddIns( MakeUnary( OP_PUSH, ret_ptr, NULL, WD ) );
                state->parm.offset += TypeClassSize[WD];
                call_ins->operands[CALL_OP_POPS] =
                        AllocS32Const( call_ins->operands[CALL_OP_POPS]->c.lo.int_value + TypeClassSize[WD] );
                if( state->attr & ROUTINE_REMOVES_PARMS ) {
                    call_ins->flags.call_flags |= CALL_POPS_PARMS;
                }
            }
            AddCall( call_ins, call );
        }
    } else {
        return_reg = state->return_reg;
        zap_reg = call_ins->zap->reg;
        HW_CTurnOn( zap_reg, HW_FLTS );
        HW_OnlyOn( return_reg, zap_reg );
        call_ins->result = AllocRegName( return_reg );
        reg_name = AllocRegName( state->return_reg );
        AddCall( call_ins, call );
        if( use_return ) {
            ret_ins = MakeMove( reg_name, result, result->n.type_class );
            if( HW_COvlap( reg_name->r.reg, HW_FLTS ) ) {
                ret_ins->stk_entry = 1;
                ret_ins->stk_exit = 0;
            }
            AddIns( ret_ins );
        }
    }
    if( state->parm.offset != 0 && ( state->attr & ROUTINE_REMOVES_PARMS ) == 0 ) {
        reg_name = AllocRegName( HW_SP );
        AddIns( MakeBinary( OP_ADD, reg_name,
                AllocS32Const( state->parm.offset ), reg_name, WD ) );
    }
    return( MakeTempAddr( result ) );
}
コード例 #5
0
ファイル: cfeinfo.c プロジェクト: MikeyG/open-watcom-v2
/*
//    This section is for
//        8086
//        386
//
//    pass auxiliary information to back end
*/
CGPOINTER FEAuxInfo( CGPOINTER req_handle, int request )
{
    aux_info             *inf;
    auto SYM_ENTRY       sym;
    static hw_reg_set    save_set;

    switch( request ) {
    case SOURCE_LANGUAGE:
        return( (CGPOINTER)"C" );
    case STACK_SIZE_8087:
        return( (CGPOINTER)(pointer_int)Stack87 );
    case CODE_GROUP:
        return( (CGPOINTER)GenCodeGroup );
    case DATA_GROUP:
        return( (CGPOINTER)DataSegName );
    case OBJECT_FILE_NAME:
        return( (CGPOINTER)ObjFileName() );
    case REVISION_NUMBER:
        return( (CGPOINTER)(pointer_int)II_REVISION );
    case AUX_LOOKUP:
        return( req_handle );
    case PROEPI_DATA_SIZE:
        return( (CGPOINTER)(pointer_int)ProEpiDataSize );
    case DBG_PREDEF_SYM:
        return( (CGPOINTER)SymDFAbbr );
    case P5_CHIP_BUG_SYM:
        return( (CGPOINTER)SymChipBug );
    case CODE_LABEL_ALIGNMENT:
        {
            static  unsigned char   Alignment[] = { 2, 1, 1 };

            if( OptSize == 0 )
                Alignment[1] = TARGET_INT;

            return( (CGPOINTER)Alignment );
        }
    case CLASS_NAME:
        return( (CGPOINTER)SegClassName( (segment_id)(pointer_int)req_handle ) );
    case USED_8087:
        CompFlags.pgm_used_8087 = 1;
        return( NULL );
  #if _CPU == 386
    case P5_PROF_DATA:
        return( (CGPOINTER)FunctionProfileBlock );
    case P5_PROF_SEG:
        return( (CGPOINTER)(pointer_int)FunctionProfileSegment );
  #endif
    case SOURCE_NAME:
        if( SrcFName == ModuleName ) {
            return( (CGPOINTER)FNameFullPath( FNames ) );
        } else {
            return( (CGPOINTER)ModuleName );
        }
    case CALL_CLASS:
        {
            static call_class cclass;

            cclass = GetCallClass( req_handle );
            return( (CGPOINTER)&cclass );
        }
    case FREE_SEGMENT:
        return( NULL );
    case NEXT_LIBRARY:
    case LIBRARY_NAME:
        return( NextLibrary( (int)(pointer_int)req_handle, request ) );
    case NEXT_IMPORT:
    case IMPORT_NAME:
        return( NextImport( (int)(pointer_int)req_handle, request ) );
    case NEXT_IMPORT_S:
    case IMPORT_NAME_S:
        return( NextImportS( (int)(pointer_int)req_handle, request ) );
    case NEXT_ALIAS:
    case ALIAS_NAME:
    case ALIAS_SYMBOL:
    case ALIAS_SUBST_NAME:
    case ALIAS_SUBST_SYMBOL:
        return( NextAlias( (int)(pointer_int)req_handle, request ) );
    case TEMP_LOC_NAME:
        return( (CGPOINTER)(pointer_int)TEMP_LOC_QUIT );
    case TEMP_LOC_TELL:
        return( NULL );
    case NEXT_DEPENDENCY:
        if( CompFlags.emit_dependencies )
            return( (CGPOINTER)NextDependency( (FNAMEPTR)req_handle ) );
        return( NULL );
    case DEPENDENCY_TIMESTAMP:
        return( (CGPOINTER)getFileDepTimeStamp( (FNAMEPTR)req_handle ) );
    case DEPENDENCY_NAME:
        return( (CGPOINTER)FNameFullPath( (FNAMEPTR)req_handle ) );
    case PEGGED_REGISTER:
        return( (CGPOINTER)SegPeggedReg( (segment_id)(pointer_int)req_handle ) );
    default:
        break;
    }

    inf = FindInfo( &sym, req_handle );
    switch( request ) {
    case SAVE_REGS:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        } else {
            sym.mods = 0;
        }
        save_set = inf->save;
        if( sym.mods & FLAG_SAVEREGS ) {
            HW_CTurnOn( save_set, HW_SEGS );
        }

  #ifdef __SEH__
        if( (SYM_HANDLE)req_handle == SymTryInit ) {
            HW_CTurnOff( save_set, HW_SP );
        }
  #endif
        return( (CGPOINTER)&save_set );
    case RETURN_REG:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        }
        return( (CGPOINTER)&inf->returns );
    case CALL_BYTES:
        return( (CGPOINTER)inf->code );
    case PARM_REGS:
  #ifdef __SEH__
        if(( (SYM_HANDLE)req_handle == SymTryInit )
          || ( (SYM_HANDLE)req_handle == SymTryFini )
          || ( (SYM_HANDLE)req_handle == SymTryUnwind )
          || ( (SYM_HANDLE)req_handle == SymExcept )) {
            return( (CGPOINTER)TryParms );
        }
  #endif
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
            if( inf->code == NULL && VarFunc( &sym ) ) {
                return( (CGPOINTER)DefaultVarParms );
            }
        }
        return( (CGPOINTER)inf->parms );
    case STRETURN_REG:
        if( req_handle != 0 ) {
            inf = LangInfo( sym.mods, inf );
        }
        return( (CGPOINTER)&inf->streturn );
    default:
        break;
    }
    return( NULL );
}
コード例 #6
0
ファイル: mpsreg.c プロジェクト: XVilka/owp4v1copy
extern hw_reg_set SavedRegs( void )
/*********************************/
{
    hw_reg_set          saved;

    HW_CAsgn( saved, HW_EMPTY );
    HW_CTurnOn( saved, HW_R16 );
    HW_CTurnOn( saved, HW_R17 );
    HW_CTurnOn( saved, HW_R18 );
    HW_CTurnOn( saved, HW_R19 );
    HW_CTurnOn( saved, HW_R20 );
    HW_CTurnOn( saved, HW_R21 );
    HW_CTurnOn( saved, HW_R22 );
    HW_CTurnOn( saved, HW_R23 );
    HW_CTurnOn( saved, HW_R30 );
    HW_CTurnOn( saved, HW_R31 );
    HW_CTurnOn( saved, HW_F20 );
    HW_CTurnOn( saved, HW_F21 );
    HW_CTurnOn( saved, HW_F22 );
    HW_CTurnOn( saved, HW_F23 );
    HW_CTurnOn( saved, HW_F24 );
    HW_CTurnOn( saved, HW_F25 );
    HW_CTurnOn( saved, HW_F26 );
    HW_CTurnOn( saved, HW_F27 );
    HW_CTurnOn( saved, HW_F28 );
    HW_CTurnOn( saved, HW_F29 );
    HW_CTurnOn( saved, HW_F30 );
    return( saved );
}
コード例 #7
0
ファイル: cpragx86.c プロジェクト: XVilka/owp4v1copy
void PragAux( void )
/******************/
{
    struct {
        unsigned    f_call   : 1;
        unsigned    f_loadds : 1;
        unsigned    f_rdosdev: 1;
        unsigned    f_export : 1;
        unsigned    f_parm   : 1;
        unsigned    f_value  : 1;
        unsigned    f_modify : 1;
        unsigned    f_frame  : 1;
        unsigned    uses_auto: 1;
    } have;

    InitAuxInfo();
    if( !GetAliasInfo() )
        return;
    if( CurToken != T_ID )
        return;
    SetCurrInfo( Buffer );
    NextToken();
    PragObjNameInfo( &AuxInfo.objname );
    have.f_call   = 0;
    have.f_loadds = 0;
    have.f_rdosdev = 0;
    have.f_export = 0;
    have.f_parm   = 0;
    have.f_value  = 0;
    have.f_modify = 0;
    have.f_frame = 0;
    have.uses_auto = 0; /* BBB - Jan 26, 1994 */
    for( ;; ) {
        if( !have.f_call && CurToken == T_EQUAL ) {
            have.uses_auto = GetByteSeq( &AuxInfo.code );
            have.f_call = 1;
        } else if( !have.f_call && PragRecog( "far" ) ) {
            AuxInfo.cclass |= FAR;
            have.f_call = 1;
        } else if( !have.f_call && PragRecog( "near" ) ) {
            AuxInfo.cclass &= ~FAR;
            AuxInfoFlg.f_near = 1;
            have.f_call = 1;
        } else if( !have.f_loadds && PragRecog( "loadds" ) ) {
            AuxInfo.cclass |= LOAD_DS_ON_ENTRY;
            have.f_loadds = 1;
        } else if( !have.f_rdosdev && PragRecog( "rdosdev" ) ) {
            AuxInfo.cclass |= LOAD_RDOSDEV_ON_ENTRY;
            have.f_rdosdev = 1;
        } else if( !have.f_export && PragRecog( "export" ) ) {
            AuxInfo.cclass |= DLL_EXPORT;
            have.f_export = 1;
        } else if( !have.f_parm && PragRecog( "parm" ) ) {
            GetParmInfo();
            have.f_parm = 1;
        } else if( !have.f_value && PragRecog( "value" ) ) {
            GetRetInfo();
            have.f_value = 1;
        } else if( !have.f_value && PragRecog( "aborts" ) ) {
            AuxInfo.cclass |= SUICIDAL;
            have.f_value = 1;
        } else if( !have.f_modify && PragRecog( "modify" ) ) {
            GetSaveInfo();
            have.f_modify = 1;
        } else if( !have.f_frame && PragRecog( "frame" ) ) {
            AuxInfo.cclass |= GENERATE_STACK_FRAME;
            have.f_frame = 1;
        } else {
            break;
        }
    }
    if( have.uses_auto ) {
        /*
           We want to force the calling routine to set up a [E]BP frame
           for the use of this pragma. This is done by saying the pragma
           modifies the [E]SP register. A kludge, but it works.
        */
        HW_CTurnOn( AuxInfo.save, HW_SP );
    }
    CopyAuxInfo();
    PragEnding();
}
コード例 #8
0
ファイル: axprgtbl.c プロジェクト: ArmstrongJ/open-watcom-v2
hw_reg_set      ParmRegConflicts( hw_reg_set regs )
/*************************************************/
{
    hw_reg_set          conflicts;

    conflicts = regs;
    if( HW_COvlap( regs, HW_R16 ) ) {
        HW_CTurnOn( conflicts, HW_F16 );
        HW_CTurnOn( conflicts, HW_R16 );
    }
    if( HW_COvlap( regs, HW_R17 ) ) {
        HW_CTurnOn( conflicts, HW_F17 );
        HW_CTurnOn( conflicts, HW_R17 );
    }
    if( HW_COvlap( regs, HW_R18 ) ) {
        HW_CTurnOn( conflicts, HW_F18 );
        HW_CTurnOn( conflicts, HW_R18 );
    }
    if( HW_COvlap( regs, HW_R19 ) ) {
        HW_CTurnOn( conflicts, HW_F19 );
        HW_CTurnOn( conflicts, HW_R19 );
    }
    if( HW_COvlap( regs, HW_R20 ) ) {
        HW_CTurnOn( conflicts, HW_F20 );
        HW_CTurnOn( conflicts, HW_R20 );
    }
    if( HW_COvlap( regs, HW_R21 ) ) {
        HW_CTurnOn( conflicts, HW_F21 );
        HW_CTurnOn( conflicts, HW_R21 );
    }
    if( HW_COvlap( regs, HW_F16 ) ) {
        HW_CTurnOn( conflicts, HW_R16 );
        HW_CTurnOn( conflicts, HW_F16 );
    }
    if( HW_COvlap( regs, HW_F17 ) ) {
        HW_CTurnOn( conflicts, HW_R17 );
        HW_CTurnOn( conflicts, HW_F17 );
    }
    if( HW_COvlap( regs, HW_F18 ) ) {
        HW_CTurnOn( conflicts, HW_R18 );
        HW_CTurnOn( conflicts, HW_F18 );
    }
    if( HW_COvlap( regs, HW_F19 ) ) {
        HW_CTurnOn( conflicts, HW_R19 );
        HW_CTurnOn( conflicts, HW_F19 );
    }
    if( HW_COvlap( regs, HW_F20 ) ) {
        HW_CTurnOn( conflicts, HW_R20 );
        HW_CTurnOn( conflicts, HW_F20 );
    }
    if( HW_COvlap( regs, HW_F21 ) ) {
        HW_CTurnOn( conflicts, HW_R21 );
        HW_CTurnOn( conflicts, HW_F21 );
    }
    return( conflicts );
}
コード例 #9
0
ファイル: rtcall.c プロジェクト: ArmstrongJ/open-watcom-v2
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 );
}