Exemple #1
0
void    UpdateReturn( call_state *state, type_def *tipe, type_class_def type_class, aux_handle aux )
/**************************************************************************************************/
{
    hw_reg_set  normal;

    if( _FPULevel( FPU_87 ) && _NPX( state->attr ) && (tipe->attr & TYPE_FLOAT) ) {
        HW_COnlyOn( state->return_reg, HW_ST0 );
    } else {
        HW_CTurnOff( state->return_reg, HW_FLTS );
    }
    if( tipe == TypeNone ) {
        if( HW_CEqual( state->return_reg, HW_EMPTY ) )
            return;
        FEMessage( MSG_BAD_RETURN_REGISTER, aux );
        HW_CAsgn( state->return_reg, HW_EMPTY );
        state->attr &= ~ROUTINE_HAS_SPECIAL_RETURN;
    } else if( type_class == XX ) {
        normal = ReturnReg( WD, _NPX( state->attr ) );
        if( HW_Equal( state->return_reg, normal ) )
            return;
        if( HW_CEqual( state->return_reg, HW_EMPTY ) )
            return;
        // if( !HW_Ovlap( state->return_reg, state->unalterable ) &&
        //    IsRegClass( state->return_reg, WD ) )
        //     return;
        if( IsRegClass( state->return_reg, WD ) )
            return;
        FEMessage( MSG_BAD_RETURN_REGISTER, aux );
        state->return_reg = normal;
        state->attr &= ~ROUTINE_HAS_SPECIAL_RETURN;
    } else {
        normal = ReturnReg( type_class, _NPX( state->attr ) );
        if( HW_Equal( state->return_reg, normal ) )
            return;
        // if( !HW_Ovlap( state->return_reg, state->unalterable ) &&
        //    IsRegClass( state->return_reg, type_class ) )
        //     return;
        if( IsRegClass( state->return_reg, type_class ) )
            return;
        FEMessage( MSG_BAD_RETURN_REGISTER, aux );
        state->return_reg = normal;
        state->attr &= ~ROUTINE_HAS_SPECIAL_RETURN;
    }
}
Exemple #2
0
void    Zoiks( int msg )
/***********************
    put out an internal compiler error.  2 is chunks unfreed which we
    may want to hide.  1 is unfreed code labels which we always hide.
*/
{
    if( ( msg == ZOIKS_001 ) )
        return;
    if( ( msg == ZOIKS_002 ) && ( !WantZoiks2() ) )
        return;
    if( ( msg == ZOIKS_040 ) && ( ++Zoiks40 < MAX_ZOIKS_40 ) )
        return;
    FEMessage( MSG_BACK_END_ERROR, (pointer)(pointer_int)msg );
}
Exemple #3
0
static  void    CheckEvents( void )
/*********************************/
{
    uint        ticks;

    ticks = GetTickCnt();
    if( ticks < LastBlipCount || ticks >= NextTickCount ) {
        OSCall();       /* force a DOS call to get version number */
        if( ticks < LastBlipCount || ticks >= NextBlipCount ) {
            FEMessage( MSG_BLIP, NULL );
            LastBlipCount = ticks;
            SetNextBlipCount();
        }
        SetNextTickCount();
    }
    if( TBreak() ) {
        FatalError( "Program interrupted from keyboard" );
    }
}
Exemple #4
0
type_class_def  CallState( aux_handle aux, type_def *tipe, call_state *state )
/****************************************************************************/
{
    type_class_def      class;
    uint                i;
    hw_reg_set          parms[24];
    hw_reg_set          *parm_src;
    hw_reg_set          *parm_dst;

    state->unalterable = FixedRegs();
    HW_CAsgn( state->modify, HW_FULL );
    HW_TurnOff( state->modify, SavedRegs() );
    HW_CTurnOff( state->modify, HW_UNUSED );
    state->used = state->modify;     /* anything not saved is used*/
    state->attr = 0;
    i = 0;
    parm_src = ParmRegs();
    parm_dst = &parms[0];
    for(;;) {
        *parm_dst = *parm_src;
        if( HW_CEqual( *parm_dst, HW_EMPTY ) ) break;
        if( HW_Ovlap( *parm_dst, state->unalterable ) ) {
            FEMessage( MSG_BAD_SAVE, aux );
        }
        HW_CTurnOff( *parm_dst, HW_UNUSED );
        parm_dst++;
        parm_src++;
        i++;
    }
    i++;
    state->parm.table = CGAlloc( i*sizeof( hw_reg_set ) );
    Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) );
    HW_CAsgn( state->parm.used, HW_EMPTY );
    state->parm.curr_entry = state->parm.table;
    state->parm.offset  = 0;
    InitPPCParmState( state );
    class = ReturnClass( tipe, state->attr );
    if( *(call_class *)FEAuxInfo( aux, CALL_CLASS ) & HAS_VARARGS ) {
        state->attr |= ROUTINE_HAS_VARARGS;
    }
    UpdateReturn( state, tipe, class, aux );
    return( class );
}
Exemple #5
0
static  bool    FlushSomeOpt( pointer_int size )
/**********************************************/
{
    seg_id      old;
    bool        freed;

    if( InOptimizer == 0 && HaveCodeSeg() ) {
        old = SetOP( AskCodeSeg() );
        freed = ShrinkQueue( size );
        SetOP( old );
        if( _IsntModel( NO_OPTIMIZATION ) && IckyWicky == FALSE ) {
            IckyWicky = TRUE;
            FEMessage( MSG_PEEPHOLE_FLUSHED, NULL );
        }
    } else {
        freed = FALSE;
    }
    return( freed );
}
Exemple #6
0
static int GetExtName( cg_sym_handle sym, char *buffer, int max_len )
/*******************************************************************/
{
    const char           *src;
    char                 *dst;
    const char           *p;
    const char           *prefix;
    const char           *sufix;
    char                 *dst_basename;
    char                 *tmp_suffix;
    char                 c;
    int                  base_len;
    int                  dst_len;
    const char           *pattern;

    pattern = FEExtName( sym, EXTN_PATTERN );
    c = '\0';
    base_len = 0;
    prefix = pattern;
    for( p = pattern; *p != '\0'; p++ ) {
        if(( *p == '*' ) || ( *p == '!' ) || ( *p == '^' )) {
            if( c == '\0' ) {
                prefix = p;
                c = *p;
            }
        } else if( ( c != '\0' ) || ( *p == '#' ) ) {
            break;
        } else if( *p == '\\' ) {
            p++;
        }
    }
    if( c == '\0' )
        base_len = p - pattern;
    sufix = p;
    // add prefix to output buffer
    dst = buffer;
    for( src = pattern; src != prefix; ++src ) {
        if( *src != '\\' ) {
            *(dst++) = *src;
        }
    }
    *dst = '\0';
    // add sufix to output buffer
    dst_basename = dst;
    for( src = sufix; *src != '\0'; ++src ) {
        if( *src == '#' ) {
            unsigned    size;

            size = (unsigned)(pointer_int)FEExtName( sym, EXTN_PRMSIZE );
            if( size != (unsigned)-1 ) {
                *(dst++) = '@';
                dst = xtoa( dst, size );
            }
        } else {
            if( *src == '\\' )
                ++src;
            *(dst++) = *src;
        }
    }
    *dst = '\0';
    // max base name length
    dst_len = max_len - ( dst - buffer );
    if( dst_len > 0 ) {
        int     sufix_len;
        int     len;

        if( base_len != 0 ) {
            // alias
            src = pattern;
        } else {
            src = FEExtName( sym, EXTN_BASENAME );
            base_len = strlen( src );
        }
        // shift sufix to the end of buffer
        sufix_len = dst - dst_basename;
        tmp_suffix = buffer + max_len - sufix_len;
        memmove( tmp_suffix, dst_basename, sufix_len + 1 );
        // copy + truncate base symbol name
        len = copyBaseName( c, dst_basename, dst_len, src, base_len );
        if( len < 0 ) {
            FEMessage( MSG_SYMBOL_TOO_LONG, sym );
        } else {
            // shift sufix to the end of symbol name
            memcpy( dst_basename + len, tmp_suffix, sufix_len + 1 );
        }
    } else {
       // TODO: error prefix + sufix >= max_len
       assert( 0 );
    }
    return( 0 );
}
Exemple #7
0
type_class_def  CallState( aux_handle aux, type_def *tipe, call_state *state )
/****************************************************************************/
{
    call_class          cclass;
    type_class_def      type_class;
    uint                i;
    hw_reg_set          parms[10];
    hw_reg_set          *parm_src;
    hw_reg_set          *parm_dst;
    hw_reg_set          *pregs;
    hw_reg_set          tmp;

    state->unalterable = FixedRegs();
    pregs = FEAuxInfo( aux, SAVE_REGS );
    HW_CAsgn( state->modify, HW_FULL );
    HW_TurnOff( state->modify, *pregs );
    HW_CTurnOff( state->modify, HW_UNUSED );
    state->used = state->modify;     /* anything not saved is used*/
    tmp = state->used;
    HW_TurnOff( tmp, StackReg() );
    HW_CTurnOff( tmp, HW_BP );  // should be able to call routine which modifies BP
    if( HW_Ovlap( state->unalterable, tmp ) ) {
        FEMessage( MSG_BAD_SAVE, aux );
    }
    state->attr = ROUTINE_REMOVES_PARMS;
    cclass = *(call_class *)FEAuxInfo( aux, CALL_CLASS );
    if( cclass & INTERRUPT ) {
        state->attr |= ROUTINE_INTERRUPT;
    } else if( cclass & FAR_CALL ) {
        state->attr |= ROUTINE_LONG;
    } else if( cclass & FAR16_CALL ) {
        state->attr |= ROUTINE_FAR16;
    }
    if( cclass & CALLER_POPS ) {
        state->attr &= ~ROUTINE_REMOVES_PARMS;
    }
    if( cclass & SUICIDAL ) {
        state->attr |= ROUTINE_NEVER_RETURNS;
    }
    if( cclass & ROUTINE_RETURN ) {
        state->attr |= ROUTINE_ALLOCS_RETURN;
    }
    if( cclass & NO_STRUCT_REG_RETURNS ) {
        state->attr |= ROUTINE_NO_STRUCT_REG_RETURNS;
    }
    if( cclass & NO_FLOAT_REG_RETURNS ) {
        state->attr |= ROUTINE_NO_FLOAT_REG_RETURNS;
        state->attr |= ROUTINE_NO_8087_RETURNS;
    }
    if( cclass & NO_8087_RETURNS ) {
        state->attr |= ROUTINE_NO_8087_RETURNS;
    }
    if( cclass & MODIFY_EXACT ) {
        state->attr |= ROUTINE_MODIFY_EXACT;
    }
    if( cclass & NO_MEMORY_CHANGED ) {
        state->attr |= ROUTINE_MODIFIES_NO_MEMORY;
    }
    if( cclass & NO_MEMORY_READ ) {
        state->attr |= ROUTINE_READS_NO_MEMORY;
    }
    if( cclass & LOAD_DS_ON_ENTRY ) {
        state->attr |= ROUTINE_LOADS_DS;
    }
    if( cclass & LOAD_DS_ON_CALL ) {
        state->attr |= ROUTINE_NEEDS_DS_LOADED;
    }
    if( cclass & PARMS_STACK_RESERVE ) {
        state->attr |= ROUTINE_STACK_RESERVE;
    }
    if( cclass & PARMS_PREFER_REGS ) {
        state->attr |= ROUTINE_PREFER_REGS;
    }
    if( cclass & FARSS ) {
        state->attr |= ROUTINE_FARSS;
    }
    if( state == &CurrProc->state ) {
        if( cclass & ( GENERATE_STACK_FRAME | PROLOG_HOOKS | EPILOG_HOOKS ) ) {
            CurrProc->prolog_state |= GENERATE_FAT_PROLOG;
            state->attr |= ROUTINE_NEEDS_PROLOG;
        }
        if( cclass & PROLOG_HOOKS ) {
            CurrProc->prolog_state |= GENERATE_PROLOG_HOOKS;
        }
        if( cclass & EPILOG_HOOKS ) {
            CurrProc->prolog_state |= GENERATE_EPILOG_HOOKS;
        }
        if( cclass & FAT_WINDOWS_PROLOG ) {
            CurrProc->prolog_state |= GENERATE_FAT_PROLOG;
        }
        if( cclass & EMIT_FUNCTION_NAME ) {
            CurrProc->prolog_state |= GENERATE_FUNCTION_NAME;
        }
        if( cclass & THUNK_PROLOG ) {
            CurrProc->prolog_state |= GENERATE_THUNK_PROLOG;
        }
        if( cclass & GROW_STACK ) {
            CurrProc->prolog_state |= GENERATE_GROW_STACK;
        }
        if( cclass & TOUCH_STACK ) {
            CurrProc->prolog_state |= GENERATE_TOUCH_STACK;
        }
        if( cclass & LOAD_RDOSDEV_ON_ENTRY ) {
            CurrProc->prolog_state |= GENERATE_RDOSDEV_PROLOG;
        }
    }
    type_class = ReturnClass( tipe, state->attr );
    i = 0;
    parm_dst = &parms[0];
    for( parm_src = FEAuxInfo( aux, PARM_REGS ); !HW_CEqual( *parm_src, HW_EMPTY ); ++parm_src ) {
        *parm_dst = *parm_src;
        if( HW_Ovlap( *parm_dst, state->unalterable ) ) {
            FEMessage( MSG_BAD_SAVE, aux );
        }
        HW_CTurnOff( *parm_dst, HW_UNUSED );
        parm_dst++;
        i++;
    }
    *parm_dst = *parm_src;
    i++;
    state->parm.table = CGAlloc( i*sizeof( hw_reg_set ) );
    Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) );
    HW_CAsgn( state->parm.used, HW_EMPTY );
    state->parm.curr_entry = state->parm.table;
    state->parm.offset  = 0;
    if( tipe == TypeNone ) {
        HW_CAsgn( state->return_reg, HW_EMPTY );
    } else if( type_class == XX ) {
        if( cclass & SPECIAL_STRUCT_RETURN ) {
            pregs = FEAuxInfo( aux, STRETURN_REG );
            state->return_reg = *pregs;
            state->attr |= ROUTINE_HAS_SPECIAL_RETURN;
        } else {
            state->return_reg = StructReg();
        }
        if( (state->attr & ROUTINE_ALLOCS_RETURN) == 0 ) {
            tmp = ReturnReg( WD, false );
            HW_TurnOn( state->modify, tmp );
        }
    } else {
        if( cclass & SPECIAL_RETURN ) {
            pregs = FEAuxInfo( aux, RETURN_REG );
            state->return_reg = *pregs;
            state->attr |= ROUTINE_HAS_SPECIAL_RETURN;
        } else {
            state->return_reg = ReturnReg( type_class, _NPX( state->attr ) );
        }
    }
    UpdateReturn( state, tipe, type_class, aux );
    return( type_class );
}
Exemple #8
0
extern  type_class_def CallState( aux_handle aux,
                                  type_def *tipe, call_state *state )
/*******************************************************************/
{
    type_class_def      class;
    uint                i;
    hw_reg_set          parms[20];
    hw_reg_set          *parm_src;
    hw_reg_set          *parm_dst;
    hw_reg_set          *pregs;
    call_class          cclass;
    call_class          *pcclass;
    risc_byte_seq       *code;
    bool                have_aux_code = FALSE;

    state->unalterable = FixedRegs();
    if( FEAttr( AskForLblSym( CurrProc->label ) ) & FE_VARARGS ) {
        HW_TurnOn( state->unalterable, VarargsHomePtr() );
    }

    // For code bursts only, query the #pragma aux instead of using
    // hardcoded calling convention. If it ever turns out that we need
    // to support more than a single calling convention, this will need
    // to change to work more like x86
    if( !AskIfRTLabel( CurrProc->label ) ) {
        code = FEAuxInfo( aux, CALL_BYTES );
        if( code != NULL ) {
            have_aux_code = TRUE;
        }
    }

    pregs = FEAuxInfo( aux, SAVE_REGS );
    HW_CAsgn( state->modify, HW_FULL );
    if( have_aux_code ) {
        HW_TurnOff( state->modify, *pregs );
    } else {
        HW_TurnOff( state->modify, SavedRegs() );
    }
    HW_CTurnOff( state->modify, HW_UNUSED );
    state->used = state->modify;    /* anything not saved is used */
    state->attr = 0;
    pcclass = FEAuxInfo( aux, CALL_CLASS );
    cclass = *pcclass;
    if( cclass & SETJMP_KLUGE ) {
        state->attr |= ROUTINE_IS_SETJMP;
    }
    if( cclass & SUICIDAL ) {
        state->attr |= ROUTINE_NEVER_RETURNS;
    }
    if( cclass & NO_MEMORY_CHANGED ) {
        state->attr |= ROUTINE_MODIFIES_NO_MEMORY;
    }
    if( cclass & NO_MEMORY_READ ) {
        state->attr |= ROUTINE_READS_NO_MEMORY;
    }
    i = 0;
    if( have_aux_code ) {
        parm_src = FEAuxInfo( aux, PARM_REGS );
    } else {
        parm_src = ParmRegs();
    }

    parm_dst = &parms[0];

    for( ;; ) {
        *parm_dst = *parm_src;
        if( HW_CEqual( *parm_dst, HW_EMPTY ) ) break;
        if( HW_Ovlap( *parm_dst, state->unalterable ) ) {
            FEMessage( MSG_BAD_SAVE, aux );
        }
        HW_CTurnOff( *parm_dst, HW_UNUSED );
        parm_dst++;
        parm_src++;
        i++;
    }
    i++;
    state->parm.table = CGAlloc( i * sizeof( hw_reg_set ) );
    Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) );
    HW_CAsgn( state->parm.used, HW_EMPTY );
    state->parm.curr_entry = state->parm.table;
    state->parm.offset  = 0;
    class = ReturnClass( tipe, state->attr );
    UpdateReturn( state, tipe, class, aux );
    return( class );
}
Exemple #9
0
void FatalError( char * str ) {
/*****************************/

     FEMessage( MSG_FATAL, str );
}