BoolU8 CmpOptIc5(LexStruct *lx,IntermediateCode *tempi,BoolU4 inside_return) { I8 i; IntermediateCode *tempil1,*tempil2; nounusedwarn inside_return; if (tempi->ic_opcodeic_opcode==EC_ADD_CONST) { if (tempil1->ic_opcode==EC_DEREF) { if (tempil1->ic_flags&ICF_P1_WAS_STK) { if (tempil1->p1.type&TY_MASK==TY_REG && tempil2->p1.type&TY_MASK==TY_REG && tempil2->r.type&TY_MASK==TY_REG && tempil2->r.reg==tempil1->p1.reg) { i=tempil2->ic_data; if (i>=MIN_I4 && i<=MAX_I4 && !Bt(&non_ptr_vars_mask,tempil2->p1.reg)) { tempil1->ic_flags=(tempil1->ic_flags & ~ICF_P1_WAS_STK)| tempil2->ic_flags; tempil2->ic_opcode=EC_NOP1; tempil2->ic_data=1; tempil2->ic_data=-1; tempil2->p1.type=TY_NULL+tempil2->p1.type&IT_MASK; tempil2->r.type=TY_NULL+tempil2->r.type&IT_MASK; tempil1->ic_opcode=EC_MOV; tempil1->p1.type=TY_DISP+tempil1->p1.ptype; tempil1->p1.reg=tempil2->p1.reg; tempil1->p1.disp=i; return TRUE; } } } } } return FALSE; } void CmpOptPass5Lag(LexStruct *lx, ParseStack *ps,IntermediateCode *tempi,I8 *i_,I8 num_stk,BoolU4 *inside_return, U8 *trashed_reg_mask_,U8 fun_num) { I8 i=*i_; I8 j,k,l,code; U8 trashed_reg_mask=*trashed_reg_mask_; ClassStruct *tempc; code=tempi->ic_opcode; if (code<=EC_END_EXP || code==EC_NOP1) return; else { if (tempi->ic_flags&ICF_TRACE) { if (Bt(&lx->pass_trace_mask,5)) { PrintF("%2d:",i); CbPutIc(tempi); } } if (code==EC_CALL_START) { if (iic_data) { if (Bt(&tempc->flags,Cf_INTERNAL)) j=0; else { j&=tempc->trashed_reg_mask; trashed_reg_mask|=tempc->trashed_reg_mask; } } tempi->ic_data=j; PrsPush(ps,i); PrsPush(ps,j); } else if (code==EC_CALL_END) { tempi->ic_data=PrsPop(ps); i=PrsPop(ps); } // else if (code==EC_LEAVE) // i=0; else if (code==EC_CALL_END2) { ps->ptr--; i=PrsPop(ps); } else if (code==EC_RETURN_START) *inside_return=TRUE; else if (code==EC_RETURN_END) *inside_return=FALSE; if (cmp_param_cnt[code]==9) i-=tempi->ic_data>>3; if (tempi->p3.type&TY_MASK==TY_STK) { i--; if (ip3.type=tempi->p3.type&IT_MASK+TY_REG; if (fun_num&1) tempi->p3.reg=to_stk_temps_map_odd[i]; else tempi->p3.reg=to_stk_temps_map_even[i]; } } if (tempi->p2.type&TY_MASK==TY_STK) { i--; if (ip2.type=tempi->p2.type&IT_MASK+TY_REG; if (fun_num&1) tempi->p2.reg=to_stk_temps_map_odd[i]; else tempi->p2.reg=to_stk_temps_map_even[i]; } } if (tempi->p1.type&TY_MASK==TY_STK) { i--; if (ip1.type=TY_REG+tempi->p1.type&IT_MASK; if (fun_num&1) tempi->p1.reg=to_stk_temps_map_odd[i]; else tempi->p1.reg=to_stk_temps_map_even[i]; } } if (tempi->r.type&TY_MASK==TY_STK && !(tempi->ic_flags & ICF_PUSH_RESULT)) { i++; if (i<=num_stk) { tempi->r.type=TY_REG+tempi->r.type&IT_MASK; if (fun_num&1) { tempi->r.reg=to_stk_temps_map_odd[i-1]; Bts(&trashed_reg_mask,to_stk_temps_map_odd[i-1]); } else { tempi->r.reg=to_stk_temps_map_even[i-1]; Bts(&trashed_reg_mask,to_stk_temps_map_even[i-1]); } } } while (CmpOptIc5(lx,tempi,*inside_return)); if (tempi->r.type&IT_MASK!=IT_DOUBLE && !(tempi->ic_flags&ICF_USE_DOUBLE)) tempi->ic_flags|=ICF_USE_INT; } *i_=i; *trashed_reg_mask_=trashed_reg_mask; } void CmpOptPass5(LexStruct *lx,ClassStruct *fun_class) { IntermediateCode *tempi,*tempil1,*tempif1,*tempif2, *temp_lag[4],*old_tempil1=NULL; BoolU4 inside_return; ParseStack *ps=OptStart(lx,temp_lag); I8 code; I8 i=0,num_stk,trashed_reg_mask=CALWAYS_TRASHED_MASK; U8 fun_num=0; if (fun_class) fun_num=compiled_functions++; if (Bt(&lx->flags,LFf_NO_REG_VAR) || lx->flags&LF_NO_REG_OPT) num_stk=0; else num_stk=num_stk_temps; tempi=lx->cb.cb_in_ptr; while (code=tempi->ic_opcode) { OptNext3(tempi,temp_lag); tempil1=temp_lag[1]; if (tempil1->ic_opcode==EC_END_EXP) { if (code!=EC_RETURN_END && code!=EC_NOP) { if (!(temp_lag[2]->ic_flags& (ICF_R_TO_DOUBLE|ICF_R_TO_INT|ICF_PUSH_RESULT|ICF_DEPEND_RESULT))) { temp_lag[2]->ic_flags|=ICF_NO_DEPEND_RESULT; temp_lag[2]->r.type=TY_NULL+temp_lag[2]->r.type&IT_MASK; tempil1->ic_flags|=ICF_NO_DEPEND_RESULT; tempil1->r.type=TY_NULL+tempil1->r.type&IT_MASK; } } } if (code<=EC_END_EXP || code==EC_NOP1) { } else { if (tempi->p3.type&TY_MASK) { if (tempi->p3.type&TY_MASK==TY_STK) { if (tempil1->r.type&TY_MASK==TY_STK && !(tempil1->ic_flags&ICF_PUSH_RESULT)) { tempi->p3.type=TY_REG+tempi->p3.type&IT_MASK; tempi->p3.reg=CREG_RAX; tempil1->r.type=TY_REG+tempil1->r.type&IT_MASK; tempil1->r.reg=CREG_RAX; } } } else { if (tempi->p2.type&TY_MASK==TY_STK) { if (tempil1->r.type&TY_MASK==TY_STK && !(tempil1->ic_flags&ICF_PUSH_RESULT)) { tempif2=NULL; if (tempi->ic_opcode==EC_ASSIGN && tempi->ic_flags&ICF_NOT_ADDRESS && tempil1->ic_opcode!=EC_CALL_END && tempil1->ic_opcode!=EC_CALL_END2 && tempil1->ic_opcode!=EC_SET_RAX && !(tempi->ic_flags& (ICF_P2_TO_DOUBLE|ICF_P2_TO_INT)) && !(tempil1->ic_flags& (ICF_R_TO_DOUBLE|ICF_R_TO_INT))) { if (tempif1=OptLead1(lx,tempi)) //predict NO_DEPEND if (tempif2=OptLead1(lx,tempif1)) if (tempif1->ic_opcode==EC_END_EXP && tempif2->ic_opcode!=EC_RETURN_END) { tempi->ic_opcode=EC_NOP; tempil1->r.type =tempi->p1.type&TY_MASK+tempi->p1.ptype; tempil1->r.ptype=tempi->p1.ptype; tempil1->r.reg =tempi->p1.reg; tempil1->r.disp =tempi->p1.disp; tempil1->ic_flags=tempil1->ic_flags&~(ICF_NO_DEPEND_RESULT|ICF_R_WAS_STK)| tempi->ic_flags&~(ICF_NOT_ADDRESS|ICF_P1_WAS_STK|ICF_P2_WAS_STK)|ICF_DEPEND_RESULT; old_tempil1=NULL; } else tempif2=NULL; } if (!tempif2) { tempi->p2.type=TY_REG+tempi->p2.type&IT_MASK; tempi->p2.reg=CREG_RAX; tempil1->r.type=TY_REG+tempil1->r.type&IT_MASK; tempil1->r.reg=CREG_RAX; } } } else if (tempi->p1.type&TY_MASK==TY_STK) { if (tempil1->r.type&TY_MASK==TY_STK && !(tempil1->ic_flags&ICF_PUSH_RESULT)) { tempi->p1.type=TY_REG+tempi->p1.type&IT_MASK; tempi->p1.reg=CREG_RAX; tempil1->r.type=TY_REG+tempil1->r.type&IT_MASK; tempil1->r.reg=CREG_RAX; } } } if (tempi->ic_flags & ICF_PUSH_RESULT) tempi->r.type==TY_STK+tempi->r.type&IT_MASK; } if (old_tempil1!=tempil1) { CmpOptPass5Lag(lx,ps,tempil1,&i,num_stk,&inside_return,&trashed_reg_mask,fun_num); old_tempil1=tempil1; } tempi+=sizeof(IntermediateCode); } OptEnd(lx,5,ps); if (fun_class) { fun_class->used_reg_mask&=~CSTK_TEMPS_MASK; fun_class->used_reg_mask|=trashed_reg_mask; fun_class->trashed_reg_mask=trashed_reg_mask; if (Bt(&lx->flags,LFf_OPT_TRACE_PRESENT)) if (Bt(&lx->pass_trace_mask,4)) { PrintF("Used Reg Mask:%04X\r\n",fun_class->used_reg_mask); PrintF("Trashed Reg Mask:%04X\r\n",trashed_reg_mask); } } }