Exemple #1
0
void
_Compile_GetVarLitObj_RValue_To_Reg ( Word * word, int32 reg, int32 index )
{
    _Set_SCA ( index ) ;
    word->Coding = Here ; // we don't need the word's code if compiling -- this is an optimization though
    if ( word->CProperty & REGISTER_VARIABLE )
    {
        return ;
        //if ( word->RegToUse == reg ) return ;
        //else _Compile_Move_Reg_To_Reg ( reg, word->RegToUse ) ;
    }
    else if ( word->CProperty & LOCAL_VARIABLE )
    {
        _Compile_Move_StackN_To_Reg ( reg, FP, LocalVarOffset ( word ) ) ; // 2 : account for saved fp and return slot
    }
    else if ( word->CProperty & PARAMETER_VARIABLE )
    {
        _Compile_Move_StackN_To_Reg ( reg, FP, ParameterVarOffset ( word ) ) ; // account for stored bp and return value
    }
    else if ( word->CProperty & ( LITERAL | CONSTANT | OBJECT | THIS ) )
    {
        _Compile_Move_Literal_Immediate_To_Reg ( reg, ( int32 ) * word->W_PtrToValue ) ;
    }
    else if ( word->CProperty & NAMESPACE_VARIABLE )
    {
        _Compile_Move_Literal_Immediate_To_Reg ( reg, ( int32 ) word->W_PtrToValue ) ;
        _Compile_Move_Rm_To_Reg ( reg, reg, 0 ) ;
    }
    else SyntaxError ( QUIT ) ;
    if ( word->CProperty & ( OBJECT | THIS ) )
    {
        Do_ObjectOffset ( word, reg ) ;
        _Compile_Move_Rm_To_Reg ( reg, reg, 0 ) ;
    }
}
Exemple #2
0
void
Compile_Cmp_Set_tttn_Logic ( Compiler * compiler, int32 ttt, int32 negateFlag )
{
    int32 optFlag = CheckOptimizeOperands ( compiler, 5 ) ;
    if ( optFlag == OPTIMIZE_DONE ) return ;
    else if ( optFlag )
    {
        if ( ( optFlag == 2 ) && ( compiler->Optimizer->Optimize_Rm == DSP ) )
        {
            _Compile_Stack_PopToReg ( DSP, ECX ) ; // assuming optimize always uses EAX first
            compiler->Optimizer->Optimize_Rm = ECX ;
            compiler->Optimizer->Optimize_Mod = REG ;
        }
        // Compile_CMPI( mod, operandReg, offset, immediateData, size
        if ( compiler->Optimizer->OptimizeFlag & OPTIMIZE_IMM ) Compile_CMPI ( compiler->Optimizer->Optimize_Mod,
            compiler->Optimizer->Optimize_Rm, compiler->Optimizer->Optimize_Disp, compiler->Optimizer->Optimize_Imm, CELL ) ;
            // Compile_CMP( toRegOrMem, mod, reg, rm, sib, disp )
        else Compile_CMP ( compiler->Optimizer->Optimize_Dest_RegOrMem, compiler->Optimizer->Optimize_Mod,
            compiler->Optimizer->Optimize_Reg, compiler->Optimizer->Optimize_Rm, 0, compiler->Optimizer->Optimize_Disp, CELL ) ;
    }
    else
    {
        _Compile_Move_StackN_To_Reg ( ECX, DSP, 0 ) ;
        _Compile_Move_StackN_To_Reg ( EAX, DSP, - 1 ) ;
        // ?? must do the DropN before the CMP because CMP sets eflags 
        _Compile_Stack_DropN ( DSP, 2 ) ; // before cmp allows smoother optimizing with C conditionals
        Compile_CMP ( REG, REG, EAX, ECX, 0, 0, CELL ) ;
    }
    _Compile_SET_tttn_REG ( ttt, negateFlag, EAX ) ; // immediately after the 'cmp' insn which changes the flags appropriately
    _Compile_MOVZX_REG ( EAX ) ;
    Word *zero = ( Word* ) Compiler_WordStack ( compiler, 0 ) ;
    _Word_CompileAndRecord_PushEAX ( zero ) ;
}
Exemple #3
0
void
Compile_Logical_X ( Compiler * compiler, int32 op )
{
    int optFlag = CheckOptimizeOperands ( compiler, 5 ) ;
    if ( optFlag == OPTIMIZE_DONE ) return ;
    else if ( optFlag )
    {
        // TODO : this optimization somehow is *very* little used, why is that ?!? 
        // assumes we have unordered operands in eax, ecx
        _Compile_Group1 ( op, REG, REG, EAX, ECX, 0, 0, CELL ) ;
        _Compile_TEST_Reg_To_Reg ( EAX, EAX ) ;
        _Compiler_Setup_BI_tttn ( _Context_->Compiler0, ZERO, N ) ; // not less than 0 == greater than 0
        Word *zero = Compiler_WordStack ( compiler, 0 ) ;
        _Word_CompileAndRecord_PushEAX ( zero ) ;
    }
    else
    {
        // operands are still on the stack
        _Compile_Move_StackN_To_Reg ( EAX, DSP, 0 ) ;
        //_Compile_Group1 ( int32 code, int32 toRegOrMem, int32 mod, int32 reg, int32 rm, int32 sib, int32 disp, int32 osize )
        _Compile_Group1 ( op, REG, MEM, EAX, DSP, 0, - 4, CELL ) ;
        _Compile_Stack_DropN ( DSP, 2 ) ;
        _Compile_TEST_Reg_To_Reg ( EAX, EAX ) ;
        _Compiler_Setup_BI_tttn ( _Context_->Compiler0, ZERO, N ) ; // not less than 0 == greater than 0
        Word *zero = Compiler_WordStack ( compiler, 0 ) ;
        _Word_CompileAndRecord_PushEAX ( zero ) ;
    }
}
Exemple #4
0
void
Compile_X_Shift ( Compiler * compiler, int32 op, int32 stackFlag )
{
    //if ( CheckOptimizeOperands ( compiler, 5 ) )
    int optFlag = CheckOptimizeOperands ( compiler, 5 ) ;
    if ( optFlag == OPTIMIZE_DONE ) return ;
    else if ( optFlag )
    {
        // _Compile_Group2 ( int mod, int regOpCode, int rm, int sib, cell disp, cell imm )
        _Compile_Group2 ( compiler->Optimizer->Optimize_Mod,
                op, compiler->Optimizer->Optimize_Rm, 0, compiler->Optimizer->Optimize_Disp, compiler->Optimizer->Optimize_Imm ) ;
        if ( stackFlag && ( compiler->Optimizer->Optimize_Rm != DSP ) ) // if the result is not already tos
        {
            Word *zero = Compiler_WordStack ( compiler, 0 ) ; // refers to this current multiply insn word
            if ( compiler->Optimizer->Optimize_Rm != EAX ) _Compile_Move_Rm_To_Reg ( EAX, compiler->Optimizer->Optimize_Rm,
                    compiler->Optimizer->Optimize_Disp ) ;
            zero->StackPushRegisterCode = Here ;
            _Compile_Stack_Push_Reg ( DSP, EAX ) ;
        }
    }
    else
    {
        _Compile_Move_StackN_To_Reg ( ECX, DSP, 0 ) ;
        Compile_SUBI ( REG, ESI, 0, CELL, BYTE ) ;
        //_Compile_Group2_CL ( int mod, int regOpCode, int rm, int sib, cell disp )
        _Compile_Group2_CL ( MEM, op, DSP, 0, 0 ) ;
    }
}
Exemple #5
0
void
_Compile_LocalOrStackVar_RValue_To_Reg ( Word * word, int32 reg )
{
    word->Coding = Here ; // we don't need the word's code if compiling -- this is an optimization though
    if ( word->CProperty & REGISTER_VARIABLE )
    {
        if ( word->RegToUse == reg ) return ;
        else _Compile_Move_Reg_To_Reg ( reg, word->RegToUse ) ;
    }
    else if ( word->CProperty & LOCAL_VARIABLE )
    {
        _Compile_Move_StackN_To_Reg ( reg, FP, LocalVarOffset ( word ) ) ; // 2 : account for saved fp and return slot
    }
    else if ( word->CProperty & PARAMETER_VARIABLE )
    {
        _Compile_Move_StackN_To_Reg ( reg, FP, ParameterVarOffset ( word ) ) ; // account for stored bp and return value
    }
    else if ( word->CProperty & ( OBJECT | THIS ) )
    {
        _Compile_Move_Literal_Immediate_To_Reg ( reg, ( int32 ) * word->W_PtrToValue ) ;
    }
}
Exemple #6
0
void
Compile_LogicalNot ( Compiler * compiler )
{
    Word *one = Compiler_WordStack ( compiler, - 1 ) ;
    int optFlag = CheckOptimizeOperands ( compiler, 2 ) ;
    if ( optFlag == OPTIMIZE_DONE ) return ;
    else if ( optFlag )
    {
        if ( compiler->Optimizer->OptimizeFlag & OPTIMIZE_IMM )
        {
            _Compile_MoveImm_To_Reg ( EAX, compiler->Optimizer->Optimize_Imm, CELL ) ;
        }
        else if ( compiler->Optimizer->Optimize_Rm == DSP )
        {
            _Compile_Move_StackN_To_Reg ( EAX, DSP, 0 ) ;
        }
        else if ( compiler->Optimizer->Optimize_Rm != EAX )
        {
            _Compile_VarConstOrLit_RValue_To_Reg ( one, EAX ) ;
        }
        _Compile_TEST_Reg_To_Reg ( EAX, EAX ) ;
        _Compile_SET_tttn_REG ( ZERO, 0, EAX ) ; // SET : this only sets one byte of reg
        _Compile_MOVZX_REG ( EAX ) ; // so Zero eXtend reg
        if ( compiler->Optimizer->Optimize_Rm != DSP ) // optimize sets this
        {
            Word *zero = Compiler_WordStack ( compiler, 0 ) ;
            _Word_CompileAndRecord_PushEAX ( zero ) ;
        }
        else Compile_Move_EAX_To_TOS ( DSP ) ;
    }
    else
    {
        if ( one->StackPushRegisterCode ) SetHere ( one->StackPushRegisterCode ) ;
        else Compile_Move_TOS_To_EAX ( DSP ) ; //_Compile_Move_StackN_To_Reg ( EAX, DSP, 0 ) ;
        _Compile_TEST_Reg_To_Reg ( EAX, EAX ) ; //logical and eax eax => if ( eax > 0 ) 1 else 0
        _Compile_SET_tttn_REG ( ZERO, 0, EAX ) ; // if (eax == zero) => zero flag is 1 if zero flag is true (1) set EAX to 1 else set eax to 0 :: SET : this only sets one byte of reg
        _Compile_MOVZX_REG ( EAX ) ; // so Zero eXtend reg
        Word *zero = Compiler_WordStack ( compiler, 0 ) ;
        zero->StackPushRegisterCode = Here ;
        Compile_Move_EAX_To_TOS ( DSP ) ;
        //int a, b, c= 0, d ; a = 1; b = !a, d= !c ; Printf ( "a = %d b = %d c =%d ~d = %d", a, b, c, d ) ;
    }
}
Exemple #7
0
void
_Compiler_RemoveLocalFrame ( Compiler * compiler )
{
    int32 parameterVarsSubAmount, returnValueFlag ;
    Compiler_SetLocalsFrameSize_AtItsCellOffset ( compiler ) ;
    parameterVarsSubAmount = ( compiler->NumberOfParameterVariables * CELL ) ;
    if ( GetState ( _Context_, C_SYNTAX ) && ( ! String_Equal ( compiler->CurrentWord->S_ContainingNamespace->Name, "void" ) ) ) 
    {
        SetState ( compiler, RETURN_TOS, true ) ;
    }
    //returnValueFlag = rvf = ( _Context_->CurrentRunWord->CProperty & C_RETURN ) || ( GetState ( compiler, RETURN_TOS | RETURN_EAX ) ) || IsWordRecursive || compiler->ReturnVariableWord ;
    returnValueFlag = ( _Context_->CurrentlyRunningWord->CProperty & C_RETURN ) || ( GetState ( compiler, RETURN_TOS | RETURN_EAX ) ) || IsWordRecursive || compiler->ReturnVariableWord ;
    Word * word = compiler->ReturnVariableWord ;
#if 0    
    if ( GetState ( _Context_->Compiler0, SAVE_ESP ) )
    {
        _Compile_ESP_Restore ( ) ;
    }
#endif    
    if ( word )
    {
        _Compile_GetVarLitObj_RValue_To_Reg ( word, EAX, 0 ) ; // nb. these variables have no lasting lvalue - they exist on the stack - therefore we can only return there rvalue
    }
    //else if ( compiler->NumberOfParameterVariables && returnValueFlag && ( ! compiler->NumberOfRegisterVariables ) && ( ! GetState ( compiler, RETURN_EAX ) ) )
    else if ( compiler->NumberOfParameterVariables && returnValueFlag && ( ! GetState ( compiler, RETURN_EAX ) ) )
    {
#if 0  // for some unknown reason this code will overwrite the function call address also      
        byte add_esi_eax [ ] = { 0x01, 0x06 } ; //0106           add [esi], eax 
        byte * here = _Q_CodeByteArray->EndIndex ;

        if ( memcmp ( add_esi_eax, here - 2, 2 ) )
        {
            //_ByteArray_UnAppendSpace ( _Q_CodeByteArray, 2 ) ;
            SetHere ( Here - 2  ) ;
            _Compile_X_Group1 ( ADD, REG, MEM, EAX, DSP, 0, 0, CELL ) ; // result is on TOS
        }
            //{returnValueFlag ++ ; rvf = 0 ;}
        //else 
#else        
        Compile_Move_TOS_To_EAX ( DSP ) ; // save TOS to EAX so we can set return it as TOS below
#endif         
        //else { parameterVarsSubAmount += CELL ; rvf = 0 ; }
    }
    else if ( GetState ( compiler, RETURN_TOS ) )
    {
        Compile_Move_TOS_To_EAX ( DSP ) ;
    }
    _Compile_LEA ( DSP, FP, 0, - LocalVarIndex_Disp ( 1 ) ) ; // restore sp - release locals stack frame
    _Compile_Move_StackN_To_Reg ( FP, DSP, 1 ) ; // restore the saved pre fp - cf AddLocalsFrame
    // remove the incoming parameters -- like in C
    parameterVarsSubAmount -= returnValueFlag * CELL ; // reduce the subtract amount to make room for the return value
    if ( parameterVarsSubAmount > 0 )
    {
        Compile_SUBI ( REG, DSP, 0, parameterVarsSubAmount, CELL ) ; // remove stack variables
    }
    else if ( parameterVarsSubAmount < 0 )
    {
        Compile_ADDI ( REG, DSP, 0, - parameterVarsSubAmount, CELL ) ; // add a place on the stack for return value
    }
    //if ( rvf && returnValueFlag && ( ! GetState ( compiler, RETURN_EAX ) ) )
    if ( returnValueFlag && ( ! GetState ( compiler, RETURN_EAX ) ) )
    {
        // nb : stack was already adjusted accordingly for this above by reducing the SUBI subAmount or adding if there weren't any parameter variables
        Compile_Move_EAX_To_TOS ( DSP ) ;
    }
}