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 ) ; } }
void Compile_Poke ( Compiler * compiler, int32 stackReg ) // = { //if ( CheckOptimizeOperands ( compiler, 3 ) ) int optFlag = CheckOptimizeOperands ( compiler, 4 ) ; if ( optFlag == OPTIMIZE_DONE ) return ; else if ( optFlag ) { // _Compile_MoveImm ( cell direction, cell rm, cell disp, cell imm, cell operandSize ) if ( compiler->Optimizer->OptimizeFlag & OPTIMIZE_IMM ) _Compile_MoveImm ( compiler->Optimizer->Optimize_Dest_RegOrMem, compiler->Optimizer->Optimize_Rm, 0, compiler->Optimizer->Optimize_Disp, compiler->Optimizer->Optimize_Imm, CELL ) ; else if ( compiler->Optimizer->OptimizeFlag & OPTIMIZE_REGISTER ) { // allow for one of these to be EAX which is 0 if ( compiler->Optimizer->Optimize_SrcReg || compiler->Optimizer->Optimize_DstReg ) _Compile_Move_Reg_To_Reg ( compiler->Optimizer->Optimize_DstReg, compiler->Optimizer->Optimize_SrcReg ) ; //_Compile_Move ( int32 direction, int32 reg, int32 rm, int32 sib, int32 disp ) else _Compile_Move ( compiler->Optimizer->Optimize_Dest_RegOrMem, compiler->Optimizer->Optimize_Reg, compiler->Optimizer->Optimize_Rm, 0, 0 ) ; } else _Compile_Move_Reg_To_Rm ( compiler->Optimizer->Optimize_Rm, compiler->Optimizer->Optimize_Disp, compiler->Optimizer->Optimize_Reg ) ; } else { _Compile_Move_Rm_To_Reg ( ECX, stackReg, 0 ) ; _Compile_Move_Rm_To_Reg ( EAX, stackReg, - CELL_SIZE ) ; _Compile_Move_Reg_To_Rm ( EAX, 0, ECX ) ; Compile_SUBI ( REG, stackReg, 0, 8, BYTE ) ; } }
// n = *m // ( n m -- ) // void Compile_AtEqual ( int32 stackReg ) // ! { _Compile_Move_Rm_To_Reg ( EAX, stackReg, 0 ) ; _Compile_Move_Rm_To_Reg ( EAX, EAX, 0 ) ; _Compile_Move_Rm_To_Reg ( ECX, stackReg, - CELL_SIZE ) ; _Compile_Move_Reg_To_Rm ( ECX, 0, EAX ) ; Compile_SUBI ( REG, stackReg, 0, CELL_SIZE * 2, BYTE ) ; }
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 ) ; } }