void CfrTil_BeginCombinator ( int32 quotesUsed ) { Compiler * compiler = _Context_->Compiler0 ; BlockInfo *bi = ( BlockInfo * ) _Stack_Pick ( compiler->CombinatorBlockInfoStack, quotesUsed - 1 ) ; // -1 : remember - stack is zero based ; stack[0] is top // optimize out jmps such that the jmp from first block is to Here the start of the combinator code bi->CombinatorStartsAt = Here ; _SetOffsetForCallOrJump ( bi->JumpOffset, bi->CombinatorStartsAt, 1 ) ; }
int32 _Compile_Block_WithLogicFlag ( byte * srcAddress, int32 bindex, int32 jccFlag, int n ) { Compiler * compiler = _Context_->Compiler0 ; int32 jccFlag2 ; BlockInfo *bi = ( BlockInfo * ) _Stack_Pick ( compiler->CombinatorBlockInfoStack, bindex ) ; // -1 : remember - stack is zero based ; stack[0] is top if ( jccFlag ) { if ( ! ( _Q_->OVT_LC && GetState ( _Q_->OVT_LC, ( LC_COMPILE_MODE ) ) ) ) { if ( bi->LiteralWord )//&& bi->LiteralWord->StackPushRegisterCode ) // leave value in EAX, don't push it { if ( bi->LiteralWord->W_Value != 0 ) { return 1 ; // nothing need to be compiled } // else somehow don't use this block at all ie. eliminate the dead code and don't just ... return 0 ; // TODO : don't use the block/combinator } } jccFlag2 = Compile_ReConfigureLogicInBlock ( bi, 1 ) ; } if ( ! GetState ( _Q_->OVT_CfrTil, INLINE_ON ) ) Compile_Call ( srcAddress ) ; else { _Block_Copy ( srcAddress, bi->bp_Last - bi->bp_First ) ; } if ( jccFlag ) { if ( jccFlag2 ) { Compile_JCC ( n ? bi->NegFlag : ! bi->NegFlag, bi->Ttt, 0 ) ; } else { Compile_GetLogicFromTOS ( bi ) ; Compile_JCC ( n, ZERO_CC, 0 ) ; } _Stack_PointerToJmpOffset_Set ( Here - CELL ) ; } return 1 ; }
void CfrTil_EndCombinator ( int32 quotesUsed, int32 moveFlag ) { Compiler * compiler = _Context_->Compiler0 ; BlockInfo *bi = ( BlockInfo * ) _Stack_Pick ( compiler->CombinatorBlockInfoStack, quotesUsed - 1 ) ; // -1 : remember - stack is zero based ; stack[0] is top _CfrTil_InstallGotoCallPoints_Keyed ( ( BlockInfo* ) bi, GI_BREAK | GI_CONTINUE ) ; if ( moveFlag && GetState ( _Q_->OVT_CfrTil, INLINE_ON ) ) { byte * qCodeStart ; if ( bi->FrameStart ) qCodeStart = bi->bp_First ; // after the stack frame else qCodeStart = bi->ActualCodeStart ; Block_Copy ( qCodeStart, bi->CombinatorStartsAt, Here - bi->CombinatorStartsAt ) ; } _Stack_DropN ( compiler->CombinatorBlockInfoStack, quotesUsed ) ; if ( GetState ( compiler, LISP_COMBINATOR_MODE ) ) { _Stack_Pop ( compiler->CombinatorInfoStack ) ; if ( ! Stack_Depth ( compiler->CombinatorInfoStack ) ) SetState ( compiler, LISP_COMBINATOR_MODE, false ) ; } }
void _Compile_Jcc ( int32 bindex, int32 overwriteFlag, int32 n, int32 ttt ) { BlockInfo *bi = ( BlockInfo * ) _Stack_Pick ( _Context_->Compiler0->CombinatorBlockInfoStack, bindex ) ; // -1 : remember - stack is zero based ; stack[0] is top if ( Compile_ReConfigureLogicInBlock ( bi, overwriteFlag ) ) { _Compile_JCC ( ! bi->NegFlag, bi->Ttt, 0 ) ; // we do need to store and get this logic set by various conditions by the compiler : _Compile_SET_tttn_REG } else { Compile_GetLogicFromTOS ( bi ) ; // after cmp we test our condition with setcc. if cc is true a 1 will be sign extended in EAX and pushed on the stack // then in the non optimized|inline case we cmp the TOS with 0. If ZERO (zf is 1) we know the test was false (for IF), if N(ot) ZERO we know it was true // (for IF). So, in the non optimized|inline case if ZERO we jmp if N(ot) ZERO we continue. In the optimized|inline case we check result of first cmp; if jcc sees // not true (with IF that means jcc N(ot) ZERO) we jmp and if true (with IF that means jcc ZERO) we continue. // nb. without optimize|inline there is another cmp in Compile_GetLogicFromTOS which reverse the polarity of the logic // ?? an open question ?? i assume it works the same in all cases we are using - exceptions ?? // so adjust ... if ( GetState ( _CfrTil_, OPTIMIZE_ON | INLINE_ON ) ) _Compile_JCC ( n, ttt, 0 ) ; else _Compile_JCC ( ! n, ttt, 0 ) ; } }