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 ) ; } }
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 ) ; } }
void _Compile_CpuState_Restore_EbpEsp ( CpuState * cpu ) { _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Ebp, CELL ) ; _Compile_Move_Rm_To_Reg ( EBP, EAX, 0 ) ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Esp, CELL ) ; _Compile_Move_Rm_To_Reg ( ESP, EAX, 0 ) ; }
// 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 Compile_Peek ( Compiler * compiler, int32 stackReg ) // @ { int optFlag = CheckOptimizeOperands ( compiler, 2 ) ; if ( optFlag == OPTIMIZE_DONE ) return ; else // assume arg is tos { _Compile_Move_Rm_To_Reg ( EAX, stackReg, 0 ) ; _Compile_Move_Rm_To_Reg ( EAX, EAX, 0 ) ; _Compile_Move_Reg_To_Rm ( stackReg, 0, EAX ) ; } }
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_X_Group3 ( Compiler * compiler, int32 code ) { //if ( CheckOptimizeOperands ( compiler, 5 ) ) int optFlag = CheckOptimizeOperands ( compiler, 5 ) ; if ( optFlag == OPTIMIZE_DONE ) return ; else if ( optFlag ) { //_Compile_Group3 ( cell code, cell mod, cell rm, cell sib, cell disp, cell imm, cell size ) _Compile_Group3 ( code, compiler->Optimizer->Optimize_Mod, compiler->Optimizer->Optimize_Rm, 0, compiler->Optimizer->Optimize_Disp, compiler->Optimizer->Optimize_Imm, 0 ) ; if ( 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_Group3 ( code, MEM, DSP, 0, 0, 0, 0 ) ; } }
void _Compile_Move_FromAtMem_ToMem ( int32 dstAddress, int32 srcAddress ) // thruReg == EAX { _Compile_Move_AddressValue_To_EAX ( srcAddress ) ; _Compile_Move_Rm_To_Reg ( EAX, EAX, 0 ) ; _Compile_Move_EAX_To_MemoryAddress ( dstAddress ) ; }
void _Compile_Rsp_Fetch ( ) { _Compile_Move_Reg_To_Reg ( EAX, ESP ) ; _Compile_Move_Rm_To_Reg ( EAX, EAX, 0 * CELL ) ; _Compile_Stack_PushReg ( DSP, EAX ) ; }
void _Compile_ESP_Restore ( ) { #if 1 _Compile_Move_Rm_To_Reg ( ESP, EDI, 4 ) ; // 4 : placeholder _Context_->Compiler0->EspRestoreOffset = Here - 1 ; #else _Compile_Stack_PopToReg ( DSP, ESP ) ; #endif }
void _Compile_CpuState_Restore ( CpuState * cpu ) { // push order for pushad // nb : intel stacks grow down toward lesser memory by subtracting from ESP to push and adding to pop // SoftwareDevelopersManual-253665.pdf, section 6.2 // registers are pushed in this order ... // eax, ecx, edx, ebx, esp, ebp, esi, edi //int32 saveEAX = cpu->Eax ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Edi, CELL ) ; _Compile_Move_Rm_To_Reg ( EDI, EAX, 0 ) ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Esi, CELL ) ; _Compile_Move_Rm_To_Reg ( ESI, EAX, 0 ) ; #if 0 // ebp & esp should n't be restored _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Ebp, CELL ) ; _Compile_Move_Rm_To_Reg ( EBP, EAX, 0 ) ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Esp, CELL ) ; _Compile_Move_Rm_To_Reg ( ESP, EAX, 0 ) ; #endif _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Ebx, CELL ) ; _Compile_Move_Rm_To_Reg ( EBX, EAX, 0 ) ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Edx, CELL ) ; _Compile_Move_Rm_To_Reg ( EDX, EAX, 0 ) ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->EFlags, CELL ) ; _Compile_Move_Rm_To_Reg ( EAX, EAX, 0 ) ; //_Compile_Sahf ( ) ; // store al to eflags ?? doesn't work ?? core 2 duo ?? _Compile_PushReg ( EAX ) ; _Compile_PopFD ( ) ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Ecx, CELL ) ; _Compile_Move_Rm_To_Reg ( ECX, EAX, 0 ) ; _Compile_MoveImm_To_Reg ( EAX, ( int32 ) & cpu->Eax, CELL ) ; //_Compile_MoveImm_To_Reg ( EAX, ( int32 ) & saveEAX, CELL ) ; _Compile_Move_Rm_To_Reg ( EAX, EAX, 0 ) ; _Compile_Return ( ) ; // x86 - return opcode }
void _Compile_ESP_Restore ( ) { _Compile_Move_Rm_To_Reg ( ESP, EDI, 4 ) ; // 4 : placeholder _Context_->Compiler0->EspRestoreOffset = Here - 1 ; }
void _Compile_MoveMem_To_Reg ( int32 reg, byte * address, int32 thruReg, int32 iSize ) { _Compile_MoveImm_To_Reg ( thruReg, (int32) address, iSize ) ; _Compile_Move_Rm_To_Reg ( reg, thruReg, 0 ) ; }