BoolU4 FixupBinaryOp1(IntermediateCode *tempi, IntermediateCode *tempi1,IntermediateCode *tempi2, BoolU4 *is_unsigned) { ClassStruct *tempc=tempi->ic_class,*tempc1,*tempc2; tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; *is_unsigned=tempc1->sub_type&1 || tempc2->sub_type&1; tempi->ic_class=tempc; if (tempc->sub_type==IT_DOUBLE) return FALSE; return tempi1->ic_code.u2[0]==EC_U8 && tempi2->ic_code.u2[0]==EC_U8; } BoolU4 FixupBinaryOp2(IntermediateCode **tempi1,IntermediateCode **tempi2) { IntermediateCode *tempii1=*tempi1, *tempii2=*tempi2; if (tempii1->ic_code.u2[0]==EC_U8 && !(tempii1->ic_flags & ICF_TO_DOUBLE)) return TRUE; if (tempii2->ic_code.u2[0]==EC_U8 && !(tempii2->ic_flags & ICF_TO_DOUBLE)) { *tempi1=tempii2; *tempi2=tempii1; return TRUE; } return FALSE; } BoolU4 FixupBinaryOp3(IntermediateCode *tempi1) { return tempi1->ic_code.u2[0]==EC_U8; } void ShiftNoPush(IntermediateCode *tempi) { if (tempi->ic_flags & ICF_NO_PUSHES) { while (TRUE) { if (!tempi->ic_code.u2[0]) return; if (tempi->ic_code.u2[0]!=EC_NOP) { tempi->ic_flags |= ICF_NO_PUSHES; return; } tempi+=sizeof(IntermediateCode); } } } void OptMissing(LexStruct *l,I8 pass,IntermediateCode *tempi) { coutln "Pass:",pass," Missing IC handler"; CbPutIc(tempi); PrsExcept(l,"ST_OPT_INTERNAL_ERROR"); } IntermediateCode opt_nop={EC_NOP,0,0,0,0}; ParseStack *OptStart(LexStruct *l,IntermediateCode **temp_lag) { I8 i; ParseStack *ps=MAlloc(sizeof(ParseStack)); CbInitInPtrs(&l->cb); ps->ptr=0; PrsPush(ps,0); for (i=0;i<4;i++) temp_lag[i]=&opt_nop; return ps; } LTextern CP_OPTNEXT BoolU4 OptNext(IntermediateCode *tempi, IntermediateCode **temp_lag); /********** void OptNext(IntermediateCode *tempi, IntermediateCode **temp_lag) { I8 i,j=0; for (i=3;i>0;i--) temp_lag[i]=temp_lag[i-1]; temp_lag[0]=tempi; for (i=0;i<4;i++) //TODO: move end_exp if (temp_lag[i]->ic_code.u2[0]>EC_END_EXP) temp_lag[j++]=temp_lag[i]; while (j<4) temp_lag[j++]=&opt_nop; } ************/ void OptEnd(LexStruct *l,I8 pass,ParseStack *ps) { if (ps->ptr>2) { PrintF("Pass:%d Stack:%d\r\n",pass,ps->ptr); PrsExcept(l,"ST_OPT_INTERNAL_ERROR"); } Free(ps); } IntermediateCode *CmpOptPass1(LexStruct *l,ClassStruct *fun_class,BoolU4 combined) { //simplify constant arithmetic I8 i1,i2; U8 u1,u2; BoolU4 is_unsigned; ClassStruct *tempc,*tempc1,*tempc2; IntermediateCode *tempi,*tempi1,*tempi2, *temp_lag[4],*last_with_class=NULL; ParseStack *ps=OptStart(l,temp_lag); if (combined) tempi=l->cb.cb_in_ptr; else tempi=CbGetIc1(&l->cb); while (tempi->ic_code.u2[0]) { OptNext(tempi,temp_lag); switch (tempi->ic_code.u2[0]) { case EC_U8: case EC_U4: case EC_U2: case EC_U1: case EC_DOUBLE: case EC_STRING_CONSTANT: case EC_EBP: case EC_FS: PrsPush(ps,tempi); break; case EC_COM: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_U8) { tempi->ic_data=~tempi1->ic_data; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_NOT: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_U8) { if (tempi1->ic_data) tempi->ic_data=0; else tempi->ic_data=1; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_UNARY_MINUS: tempi1=PrsPop(ps); tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { PrsPush(ps,tempi); break; } tempc=tempi1->ic_class; if (tempc->type&HTT_INTERNAL_TYPE && tempc->sub_type & 1) tempi->ic_class=sys_internal_types[tempc->sub_type-1]; if (tempi1->ic_code.u2[0]==EC_U8) { i1=tempi1->ic_data; tempi->ic_data=-i1; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_DEREF_U8: case EC_DEREF_U4: case EC_DEREF_U2: case EC_DEREF_U1: case EC_U8_PP: case EC_U4_PP: case EC_U2_PP: case EC_U1_PP: case EC_U8_MM: case EC_U4_MM: case EC_U2_MM: case EC_U1_MM: case EC_PP_U8: case EC_PP_U4: case EC_PP_U2: case EC_PP_U1: case EC_MM_U8: case EC_MM_U4: case EC_MM_U2: case EC_MM_U1: case EC_INC: case EC_DEC: case EC_SHL_CONSTANT1: case EC_SHL_CONSTANT2: case EC_SHR_CONSTANT1: case EC_SHR_CONSTANT2: case EC_ADD64: case EC_ADD32: case EC_ADD8: case EC_SUB64: case EC_SUB32: case EC_SUB8: ps->ptr--; PrsPush(ps,tempi); break; case EC_POWER: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; if (tempc->sub_type!=IT_DOUBLE) tempi->ic_flags|=ICF_TO_INT|ICF_USE_DOUBLE_TEMPLATE; PrsPush(ps,tempi); break; case EC_SHL: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1<ic_data; i2=tempi2->ic_data; tempi->ic_data=i1<ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } else if (FixupBinaryOp3(tempi2)) { tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; if (tempi2->ic_data<32) { tempi->ic_data=tempi2->ic_data; tempi->ic_code=EC_SHL_CONSTANT1; } else { tempi->ic_data=tempi2->ic_data-32; tempi->ic_code=EC_SHL_CONSTANT2; } } PrsPush(ps,tempi); break; case EC_SHR: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1>>u2; } else { i1=tempi1->ic_data; i2=tempi2->ic_data; tempi->ic_data=i1>>i2; } tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } else if (FixupBinaryOp3(tempi2)) { tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; if (tempi2->ic_data<32) { tempi->ic_data=tempi2->ic_data; tempi->ic_code=EC_SHR_CONSTANT1; } else { tempi->ic_data=tempi2->ic_data-32; tempi->ic_code=EC_SHR_CONSTANT2; } } PrsPush(ps,tempi); break; case EC_MULTIPLICATION: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=MulU8(u1,u2); } else { i1=tempi1->ic_data; i2=tempi2->ic_data; tempi->ic_data=MulI8(i1,i2); } tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; PrsPush(ps,tempi); } else { if (tempi1->ic_code.u2[0]==EC_U8) { switch (tempi1->ic_data) { case 1: tempi1->ic_flags|=tempi->ic_flags; tempi1->ic_code=EC_NOP; tempi->ic_code=EC_NOP; // tempi2->ic_class=tempi->ic_class; PrsPush(ps,tempi1); break; case 2: tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; tempi->ic_data=1; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 4: tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; tempi->ic_data=2; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 8: tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; tempi->ic_data=3; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 16: tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; tempi->ic_data=4; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 32: tempi->ic_flags|=tempi1->ic_flags; tempi1->ic_code=EC_NOP; tempi->ic_data=5; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; default: PrsPush(ps,tempi); } } else if (tempi2->ic_code.u2[0]==EC_U8) { switch (tempi2->ic_data) { case 1: tempi1->ic_flags|=tempi2->ic_flags|tempi->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_code=EC_NOP; // tempi1->ic_class=tempi->ic_class; PrsPush(ps,tempi1); break; case 2: tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_data=1; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 4: tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_data=2; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 8: tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_data=3; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 16: tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_data=4; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; case 32: tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_data=5; tempi->ic_code=EC_SHL_CONSTANT1; PrsPush(ps,tempi); break; default: PrsPush(ps,tempi); } } else PrsPush(ps,tempi); } break; case EC_DIVISION: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (!tempi2->ic_data) PrsExcept(l,"ST_DIVIDE_BY_ZERO"); if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=DivU8(u1,u2); } else { i1=tempi1->ic_data; i2=tempi2->ic_data; tempi->ic_data=DivI8(i1,i2); } tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; PrsPush(ps,tempi); } else { if (tempi2->ic_code.u2[0]==EC_U8) { switch (tempi2->ic_data) { case 1: tempi1->ic_flags|=tempi2->ic_flags|tempi->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_code=EC_NOP; // tempi1->ic_class=tempi->ic_class; PrsPush(ps,tempi1); break; case 2: tempi2->ic_data=1; tempi->ic_code=EC_SHR; PrsPush(ps,tempi); break; case 4: tempi2->ic_data=2; tempi->ic_code=EC_SHR; PrsPush(ps,tempi); break; case 8: tempi2->ic_data=3; tempi->ic_code=EC_SHR; PrsPush(ps,tempi); break; case 16: tempi2->ic_data=4; tempi->ic_code=EC_SHR; PrsPush(ps,tempi); break; case 32: tempi2->ic_data=5; tempi->ic_code=EC_SHR; PrsPush(ps,tempi); break; default: PrsPush(ps,tempi); } } else PrsPush(ps,tempi); } break; case EC_REMAINDER: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (!tempi2->ic_data) PrsExcept(l,"ST_DIVIDE_BY_ZERO"); if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=ModU8(u1,u2); } else { i1=tempi1->ic_data; i2=tempi2->ic_data; tempi->ic_data=ModI8(i1,i2); } tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_AND: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1&u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_OR: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1|u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_XOR: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1^u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_ADDITION: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1+u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; PrsPush(ps,tempi); } else { if (tempi1->ic_code.u2[0]==EC_U8 && !tempi1->ic_data) { tempi2->ic_flags|=tempi1->ic_flags|tempi->ic_flags; tempi1->ic_code=EC_NOP; tempi->ic_code=EC_NOP; // tempi2->ic_class=tempi->ic_class; PrsPush(ps,tempi2); } else if (tempi2->ic_code.u2[0]==EC_U8 && !tempi2->ic_data) { tempi1->ic_flags|=tempi2->ic_flags|tempi->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_code=EC_NOP; // tempi1->ic_class=tempi->ic_class; PrsPush(ps,tempi1); } else PrsPush(ps,tempi); } break; case EC_SUBTRACTION: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1-u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; PrsPush(ps,tempi); } else { if (tempi2->ic_code.u2[0]==EC_U8 && !tempi2->ic_data) { tempi1->ic_flags|=tempi2->ic_flags|tempi->ic_flags; tempi2->ic_code=EC_NOP; tempi->ic_code=EC_NOP; tempi1->ic_class=tempi->ic_class; PrsPush(ps,tempi1); } else PrsPush(ps,tempi); } break; case EC_EQUAL_EQUAL: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; tempi->ic_flags|=ICF_USE_DOUBLE_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1==u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_NOT_EQUAL_TO: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; tempi->ic_flags|=ICF_USE_DOUBLE_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1!=u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_LESS_THAN: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; tempi->ic_flags|=ICF_USE_DOUBLE_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1ic_data; i2=tempi2->ic_data; tempi->ic_data=i1ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } if (is_unsigned) tempi->ic_flags|=ICF_USE_UNSIGNED_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_GREATER_THAN: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; tempi->ic_flags|=ICF_USE_DOUBLE_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1>u2; } else { i1=tempi1->ic_data; i2=tempi2->ic_data; tempi->ic_data=i1>i2; } tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } if (is_unsigned) tempi->ic_flags|=ICF_USE_UNSIGNED_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_LESS_OR_EQUAL: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; tempi->ic_flags|=ICF_USE_DOUBLE_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1<=u2; } else { i1=tempi1->ic_data; i2=tempi2->ic_data; tempi->ic_data=i1<=i2; } tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } if (is_unsigned) tempi->ic_flags|=ICF_USE_UNSIGNED_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_GREATER_OR_EQUAL: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; tempi->ic_flags|=ICF_USE_DOUBLE_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; } if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { if (is_unsigned) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1>=u2; } else { i1=tempi1->ic_data; i2=tempi2->ic_data; tempi->ic_data=i1>=i2; } tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } if (is_unsigned) tempi->ic_flags|=ICF_USE_UNSIGNED_TEMPLATE; tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_AND_AND: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1&&u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_OR_OR: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1||u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_XOR_XOR: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) { u1=tempi1->ic_data; u2=tempi2->ic_data; tempi->ic_data=u1^^u2; tempi->ic_code=EC_U8; tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags; tempi1->ic_code=EC_NOP; tempi2->ic_code=EC_NOP; } tempi->ic_class=sys_internal_types[IT_I8]; PrsPush(ps,tempi); break; case EC_COLON: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc1=tempi1->ic_class; tempc2=tempi2->ic_class; if (tempc1->sub_type>=tempc2->sub_type) tempi->ic_class=tempc1; else tempi->ic_class=tempc2; tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { if (tempc1->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (tempc2->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; } ps->ptr-=1; PrsPush(ps,tempi); break; case EC_ASSIGN_U8: case EC_MUL_EQUAL_U8: case EC_DIV_EQUAL_U8: case EC_ADD_EQUAL_U8: case EC_SUB_EQUAL_U8: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc=tempi->ic_class; if (tempc->sub_type==IT_DOUBLE) { tempc=tempi2->ic_class; if (tempc->sub_type!=IT_DOUBLE) tempi2->ic_flags|=ICF_TO_DOUBLE; } else { tempc=tempi2->ic_class; if (tempc->sub_type==IT_DOUBLE) tempi2->ic_flags|=ICF_TO_INT; } PrsPush(ps,tempi); break; case EC_ASSIGN_U4: case EC_ASSIGN_U2: case EC_ASSIGN_U1: case EC_SHL_EQUAL_U8: case EC_SHL_EQUAL_U4: case EC_SHL_EQUAL_U2: case EC_SHL_EQUAL_U1: case EC_SHR_EQUAL_U8: case EC_SHR_EQUAL_U4: case EC_SHR_EQUAL_U2: case EC_SHR_EQUAL_U1: case EC_MUL_EQUAL_U4: case EC_MUL_EQUAL_U2: case EC_MUL_EQUAL_U1: case EC_DIV_EQUAL_U4: case EC_DIV_EQUAL_U2: case EC_DIV_EQUAL_U1: case EC_AND_EQUAL_U8: case EC_AND_EQUAL_U4: case EC_AND_EQUAL_U2: case EC_AND_EQUAL_U1: case EC_OR_EQUAL_U8: case EC_OR_EQUAL_U4: case EC_OR_EQUAL_U2: case EC_OR_EQUAL_U1: case EC_XOR_EQUAL_U8: case EC_XOR_EQUAL_U4: case EC_XOR_EQUAL_U2: case EC_XOR_EQUAL_U1: case EC_ADD_EQUAL_U4: case EC_ADD_EQUAL_U2: case EC_ADD_EQUAL_U1: case EC_SUB_EQUAL_U4: case EC_SUB_EQUAL_U2: case EC_SUB_EQUAL_U1: tempi2=PrsPop(ps); tempi1=PrsPop(ps); tempc=tempi2->ic_class; if (tempc->sub_type==IT_DOUBLE) tempi2->ic_flags|=ICF_TO_INT; PrsPush(ps,tempi); break; case EC_ENTER: case EC_LEAVE: tempi->ic_data=-fun_class->size; break; case EC_ADD_ESP32: ps->ptr-=1+tempi->ic_data>>3; if (temp_lag[1]->ic_code.u2[0]==EC_ADD_ESP32) { tempi->ic_data+=temp_lag[1]->ic_data; tempi->ic_flags|=temp_lag[1]->ic_flags; temp_lag[1]->ic_code=EC_NOP; } PrsPush(ps,tempi); break; case EC_CALL: case EC_CALL_INDIRECT: case EC_CALL_INDIRECT2: case EC_CLI: case EC_STI: case EC_GET_FLAGS: case EC_GET_BASE_PTR: case EC_GET_STACK_PTR: case EC_GET_LABEL: case EC_ABSOLUTE_ADDRESS: case EC_TYPE: PrsPush(ps,tempi); break; case EC_SET_FLAGS: case EC_SET_BASE_PTR: case EC_SET_STACK_PTR: case EC_BSF: case EC_BSR: case EC_BT_CONSTANT: case EC_BTS_CONSTANT: case EC_BTR_CONSTANT: case EC_BTC_CONSTANT: case EC_REMQUE: case EC_INPD: case EC_INPW: case EC_INP: case EC_STRLEN: ps->ptr--; PrsPush(ps,tempi); break; case EC_BT: case EC_BTS: case EC_BTR: case EC_BTC: tempi2=PrsPop(ps); tempi1=PrsPop(ps); i1=tempi1->ic_data; if (FixupBinaryOp3(tempi1) && i1>=-128 && i1<128) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_data=i1; tempi->ic_code+=EC_BT_CONSTANT-EC_BT; } PrsPush(ps,tempi); break; case EC_INSQUE: case EC_INSQUE_REV: case EC_OUTPD: case EC_OUTPW: case EC_OUTP: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_SWITCH: ps->ptr-=2; break; case EC_MEMCPY: case EC_MEMSET: ps->ptr-=3; PrsPush(ps,tempi); break; case EC_SKIPZ2: ps->ptr--; tempi2=temp_lag[1]; ec_skipz2: switch (tempi2->ic_code.u2[0]) { case EC_NOT: tempi->ic_code=EC_SKIPNZ2; tempi2->ic_code=EC_NOP; tempi->ic_class=tempi2->ic_class; tempi->ic_flags=tempi2->ic_flags; tempi2=temp_lag[2]; temp_lag[2]=temp_lag[3]; temp_lag[3]=&opt_nop; if (tempi2->ic_code.u2[0]!=EC_NOT) goto ec_skipnz2; else goto ec_skipz_done; case EC_EQUAL_EQUAL: tempi->ic_code=EC_EQUAL_EQUAL_SKIPZ2; break; case EC_NOT_EQUAL_TO: tempi->ic_code=EC_NOT_EQUAL_TO_SKIPZ2; break; case EC_LESS_THAN: tempi->ic_code=EC_LESS_THAN_SKIPZ2; break; case EC_GREATER_THAN: tempi->ic_code=EC_GREATER_THAN_SKIPZ2; break; case EC_LESS_OR_EQUAL: tempi->ic_code=EC_LESS_OR_EQUAL_SKIPZ2; break; case EC_GREATER_OR_EQUAL: tempi->ic_code=EC_GREATER_OR_EQUAL_SKIPZ2; break; case EC_OR_OR: tempi->ic_code=EC_OR_OR_SKIPZ2; break; case EC_AND_AND: tempi->ic_code=EC_AND_AND_SKIPZ2; break; } if (tempi->ic_code.u2[0]!=EC_SKIPZ2) { tempi->ic_class=tempi2->ic_class; tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; } ec_skipz_done: PrsPush(ps,tempi); break; case EC_SKIPNZ2: ps->ptr--; tempi2=temp_lag[1]; ec_skipnz2: switch (tempi2->ic_code.u2[0]) { case EC_NOT: tempi->ic_code=EC_SKIPZ2; tempi2->ic_code=EC_NOP; tempi->ic_class=tempi2->ic_class; tempi->ic_flags=tempi2->ic_flags; tempi2=temp_lag[2]; temp_lag[2]=temp_lag[3]; temp_lag[3]=&opt_nop; if (tempi2->ic_code.u2[0]!=EC_NOT) goto ec_skipz2; else goto ec_skipnz_done; case EC_EQUAL_EQUAL: tempi->ic_code=EC_NOT_EQUAL_TO_SKIPZ2; break; case EC_NOT_EQUAL_TO: tempi->ic_code=EC_EQUAL_EQUAL_SKIPZ2; break; case EC_LESS_THAN: tempi->ic_code=EC_GREATER_OR_EQUAL_SKIPZ2; break; case EC_GREATER_THAN: tempi->ic_code=EC_LESS_OR_EQUAL_SKIPZ2; break; case EC_LESS_OR_EQUAL: tempi->ic_code=EC_GREATER_THAN_SKIPZ2; break; case EC_GREATER_OR_EQUAL: tempi->ic_code=EC_LESS_THAN_SKIPZ2; break; case EC_OR_OR: tempi->ic_code=EC_OR_OR_SKIPNZ2; break; case EC_AND_AND: tempi->ic_code=EC_AND_AND_SKIPNZ2; break; } if (tempi->ic_code.u2[0]!=EC_SKIPNZ2) { tempi->ic_class=tempi2->ic_class; tempi->ic_flags|=tempi2->ic_flags; tempi2->ic_code=EC_NOP; } ec_skipnz_done: PrsPush(ps,tempi); break; case EC_EQUAL_EQUAL_SKIPZ2: case EC_NOT_EQUAL_TO_SKIPZ2: case EC_LESS_THAN_SKIPZ2: case EC_GREATER_THAN_SKIPZ2: case EC_LESS_OR_EQUAL_SKIPZ2: case EC_GREATER_OR_EQUAL_SKIPZ2: case EC_AND_AND_SKIPZ2: case EC_AND_AND_SKIPNZ2: case EC_OR_OR_SKIPZ2: case EC_OR_OR_SKIPNZ2: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_NULL: case EC_LABEL: case EC_ADDRESS: case EC_QUESTION: case EC_JMP: case EC_IRQ: case EC_NOP: case EC_RET: break; case EC_END_EXP: ps->ptr--; break; default: OptMissing(l,1,tempi); } if (tempi->ic_class) last_with_class=tempi; if (combined) tempi+=sizeof(IntermediateCode); else tempi=CbGetIc1(&l->cb); } OptEnd(l,1,ps); return last_with_class; } #define PASS2_OFFSETS 4 void CmpOptPass2(LexStruct *l,ClassStruct *fun_class) { MemberListStruct *tempm; ClassStruct *tempc; IntermediateCode *tempi,*tempi1,*tempi2, *temp_lag[4],*last_with_class=NULL; I8 i,j,o[PASS2_OFFSETS+2],c[PASS2_OFFSETS+2],lea_s[PASS2_OFFSETS+2]; ParseStack *ps=OptStart(l,temp_lag); for (i=0;imember_list; while (tempm) { tempc=tempm->member_class; if (!tempm->cnt && tempc->pointer_cnt && tempm->use_cnt>c[PASS2_OFFSETS-1]) { for (i=0;iuse_cnt>c[i]) { for (j=i;juse_cnt; o[i]=tempm->offset; break; } } tempm=tempm->next; } } tempi=l->cb.cb_in_ptr; while (tempi->ic_code.u2[0]) { OptNext(tempi,temp_lag); switch (tempi->ic_code.u2[0]) { case EC_U8: case EC_U4: case EC_U2: case EC_U1: case EC_DOUBLE: case EC_STRING_CONSTANT: case EC_EBP: case EC_FS: PrsPush(ps,tempi); break; case EC_COM: case EC_NOT: case EC_UNARY_MINUS: ps->ptr--; PrsPush(ps,tempi); break; case EC_DEREF_U8: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { for (i=0;iic_data) lea_s[i]--; } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_EBP) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_U8_DISP32; } else if (temp_lag[2]->ic_code.u2[0]==EC_FS) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_FS_U8_DISP32; } else if (temp_lag[2]->ic_data==3 && temp_lag[2]->ic_code.u2[0]==EC_SHL_CONSTANT1) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_U8_DISP32_SCALED; for (i=0;iic_data) lea_s[i]+=100000; } } PrsPush(ps,tempi); break; case EC_DEREF_U4: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { for (i=0;iic_data) lea_s[i]--; } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_EBP) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_U4_DISP32; } else if (temp_lag[2]->ic_code.u2[0]==EC_FS) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_FS_U4_DISP32; } else if (temp_lag[2]->ic_data==2 && temp_lag[2]->ic_code.u2[0]==EC_SHL_CONSTANT1) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_U4_DISP32_SCALED; for (i=0;iic_data) lea_s[i]+=100000; } } PrsPush(ps,tempi); break; case EC_DEREF_U2: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { for (i=0;iic_data) lea_s[i]--; } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_EBP) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_U2_DISP32; } else if (temp_lag[2]->ic_code.u2[0]==EC_FS) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_FS_U2_DISP32; } else if (temp_lag[2]->ic_data==1 && temp_lag[2]->ic_code.u2[0]==EC_SHL_CONSTANT1) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_U2_DISP32_SCALED; for (i=0;iic_data) lea_s[i]+=100000; } } PrsPush(ps,tempi); break; case EC_DEREF_U1: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { for (i=0;iic_data) lea_s[i]--; } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_EBP) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_U1_DISP32; } else if (temp_lag[2]->ic_code.u2[0]==EC_FS) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_FS_U1_DISP32; } } PrsPush(ps,tempi); break; case EC_U4_PP: case EC_U4_MM: case EC_PP_U4: case EC_MM_U4: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { for (i=0;iic_data) lea_s[i]--; } else if (temp_lag[1]->ic_code.u2[0]==EC_ADD32 && temp_lag[2]->ic_code.u2[0]==EC_EBP) { for (i=0;iic_data) lea_s[i]--; } PrsPush(ps,tempi); break; case EC_U8_PP: case EC_U2_PP: case EC_U1_PP: case EC_U8_MM: case EC_U2_MM: case EC_U1_MM: case EC_PP_U8: case EC_PP_U2: case EC_PP_U1: case EC_MM_U8: case EC_MM_U2: case EC_MM_U1: case EC_SHL_CONSTANT1: case EC_SHL_CONSTANT2: case EC_SHR_CONSTANT1: case EC_SHR_CONSTANT2: ps->ptr--; PrsPush(ps,tempi); break; case EC_POWER: case EC_SHL: case EC_SHR: case EC_MULTIPLICATION: case EC_DIVISION: case EC_REMAINDER: case EC_AND: case EC_OR: case EC_XOR: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_ADDITION: if (tempi->ic_class->sub_type==IT_DOUBLE) { ps->ptr-=2; PrsPush(ps,tempi); break; } tempi1=PrsPop(ps); tempi2=PrsPop(ps); if (FixupBinaryOp2(&tempi1,&tempi2)) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_data=tempi1->ic_data; tempi->ic_code=EC_ADD32; } PrsPush(ps,tempi); break; case EC_SUBTRACTION: if (tempi->ic_class->sub_type==IT_DOUBLE) { ps->ptr-=2; PrsPush(ps,tempi); break; } tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (FixupBinaryOp3(tempi2)) { tempi->ic_flags|=(tempi2->ic_flags&~ICF_NO_PUSHES); tempi2->ic_code=EC_NOP; ShiftNoPush(tempi2); tempi->ic_data=tempi2->ic_data; tempi->ic_code=EC_SUB32; } PrsPush(ps,tempi); break; case EC_EQUAL_EQUAL: case EC_NOT_EQUAL_TO: case EC_LESS_THAN: case EC_GREATER_THAN: case EC_LESS_OR_EQUAL: case EC_GREATER_OR_EQUAL: case EC_AND_AND: case EC_OR_OR: case EC_XOR_XOR: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_COLON: ps->ptr-=3; PrsPush(ps,tempi); break; case EC_ASSIGN_U4: case EC_SHL_EQUAL_U4: case EC_SHR_EQUAL_U4: case EC_MUL_EQUAL_U4: case EC_DIV_EQUAL_U4: case EC_AND_EQUAL_U4: case EC_OR_EQUAL_U4: case EC_XOR_EQUAL_U4: case EC_ADD_EQUAL_U4: case EC_SUB_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) for (i=0;iic_data) lea_s[i]--; PrsPush(ps,tempi); break; case EC_ASSIGN_U8: case EC_ASSIGN_U2: case EC_ASSIGN_U1: case EC_SHL_EQUAL_U8: case EC_SHL_EQUAL_U2: case EC_SHL_EQUAL_U1: case EC_SHR_EQUAL_U8: case EC_SHR_EQUAL_U2: case EC_SHR_EQUAL_U1: case EC_MUL_EQUAL_U8: case EC_MUL_EQUAL_U2: case EC_MUL_EQUAL_U1: case EC_DIV_EQUAL_U8: case EC_DIV_EQUAL_U2: case EC_DIV_EQUAL_U1: case EC_AND_EQUAL_U8: case EC_AND_EQUAL_U2: case EC_AND_EQUAL_U1: case EC_OR_EQUAL_U8: case EC_OR_EQUAL_U2: case EC_OR_EQUAL_U1: case EC_XOR_EQUAL_U8: case EC_XOR_EQUAL_U2: case EC_XOR_EQUAL_U1: case EC_ADD_EQUAL_U8: case EC_ADD_EQUAL_U2: case EC_ADD_EQUAL_U1: case EC_SUB_EQUAL_U8: case EC_SUB_EQUAL_U2: case EC_SUB_EQUAL_U1: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_SHL_CONSTANT1: case EC_SHL_CONSTANT2: case EC_SHR_CONSTANT1: case EC_SHR_CONSTANT2: case EC_ADD64: case EC_ADD32: case EC_ADD8: case EC_INC: case EC_SUB64: case EC_SUB32: case EC_SUB8: case EC_DEC: ps->ptr--; PrsPush(ps,tempi); break; case EC_ENTER: break; case EC_ADD_ESP32: ps->ptr-=1+tempi->ic_data>>3; PrsPush(ps,tempi); break; case EC_CALL: case EC_CALL_INDIRECT: case EC_CALL_INDIRECT2: PrsPush(ps,tempi); break; case EC_CLI: case EC_STI: case EC_GET_FLAGS: PrsPush(ps,tempi); break; case EC_SET_FLAGS: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_BASE_PTR: PrsPush(ps,tempi); break; case EC_SET_BASE_PTR: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_STACK_PTR: PrsPush(ps,tempi); break; case EC_SET_STACK_PTR: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_LABEL: case EC_ABSOLUTE_ADDRESS: PrsPush(ps,tempi); break; case EC_TYPE: PrsPush(ps,tempi); break; case EC_BT: case EC_BTS: case EC_BTR: case EC_BTC: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_BSF: case EC_BSR: case EC_BT_CONSTANT: case EC_BTS_CONSTANT: case EC_BTR_CONSTANT: case EC_BTC_CONSTANT: ps->ptr--; PrsPush(ps,tempi); break; case EC_INSQUE: case EC_INSQUE_REV: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_REMQUE: ps->ptr--; PrsPush(ps,tempi); break; case EC_MEMCPY: case EC_MEMSET: ps->ptr-=3; PrsPush(ps,tempi); break; case EC_INPD: case EC_INPW: case EC_INP: case EC_STRLEN: ps->ptr--; PrsPush(ps,tempi); break; case EC_OUTPD: case EC_OUTPW: case EC_OUTP: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_SWITCH: ps->ptr-=2; break; case EC_SKIPZ: case EC_SKIPZ2: case EC_SKIPNZ: case EC_SKIPNZ2: //not present yet ps->ptr--; PrsPush(ps,tempi); break; case EC_EQUAL_EQUAL_SKIPZ: case EC_EQUAL_EQUAL_SKIPZ2: case EC_NOT_EQUAL_TO_SKIPZ: case EC_NOT_EQUAL_TO_SKIPZ2: case EC_LESS_THAN_SKIPZ: case EC_LESS_THAN_SKIPZ2: case EC_GREATER_THAN_SKIPZ: case EC_GREATER_THAN_SKIPZ2: case EC_LESS_OR_EQUAL_SKIPZ: case EC_LESS_OR_EQUAL_SKIPZ2: case EC_GREATER_OR_EQUAL_SKIPZ: case EC_GREATER_OR_EQUAL_SKIPZ2: case EC_AND_AND_SKIPZ: case EC_AND_AND_SKIPZ2: case EC_AND_AND_SKIPNZ: case EC_AND_AND_SKIPNZ2: case EC_OR_OR_SKIPZ: case EC_OR_OR_SKIPZ2: case EC_OR_OR_SKIPNZ: case EC_OR_OR_SKIPNZ2: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_LEAVE: case EC_RET: if (fun_class && (tempi1=last_with_class)) { if (fun_class->return_class->sub_type==IT_DOUBLE && tempi1->ic_class->sub_type!=IT_DOUBLE) tempi1->ic_flags|=ICF_TO_DOUBLE; if (fun_class->return_class->sub_type!=IT_DOUBLE && tempi1->ic_class->sub_type==IT_DOUBLE) tempi1->ic_flags|=ICF_TO_INT; } break; case EC_NULL: case EC_LABEL: case EC_ADDRESS: case EC_QUESTION: case EC_JMP: case EC_IRQ: case EC_NOP: break; case EC_END_EXP: ps->ptr--; break; default: OptMissing(l,2,tempi); } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_EBP) { temp_lag[1]->ic_flags|=temp_lag[2]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_LEA_DISP32_EBP; for (i=0;iic_data) lea_s[i]++; } } if (tempi->ic_class) last_with_class=tempi; tempi+=sizeof(IntermediateCode); } j=0; if (fun_class && !Bt(&l->flags,LFf_NO_REG_VAR)) { for (i=0;iESI_offset=o[0]; l->EDI_offset=o[1]; } else { l->ESI_offset=MAX_I8; l->EDI_offset=MAX_I8; } OptEnd(l,2,ps); } void CmpOptPass3(LexStruct *l,ClassStruct *fun_class) { //Reg optimization I8 i1; IntermediateCode *tempi,*tempi1,*tempi2, *temp_lag[4]; ClassStruct *tempc,*tempc2; ParseStack *ps; fun_class; //no unused warning if (l->flags & LF_NO_REG_OPT) return; ps=OptStart(l,temp_lag); tempi=l->cb.cb_in_ptr; while (tempi->ic_code.u2[0]) { OptNext(tempi,temp_lag); switch (tempi->ic_code.u2[0]) { case EC_U8: case EC_U4: PrsPush(ps,tempi); break; case EC_U2: //doesn't occur case EC_U1: //doesn't occur case EC_DOUBLE: case EC_STRING_CONSTANT: case EC_EBP: case EC_FS: PrsPush(ps,tempi); break; case EC_LEA_DISP32_EBP: PrsPush(ps,tempi); break; case EC_COM: case EC_NOT: case EC_UNARY_MINUS: ps->ptr--; PrsPush(ps,tempi); break; case EC_U4_DISP32: if (tempi->ic_data==l->ESI_offset) tempi->ic_code=EC_ESI; else if (tempi->ic_data==l->EDI_offset) tempi->ic_code=EC_EDI; PrsPush(ps,tempi); break; case EC_U8_DISP32: case EC_U2_DISP32: case EC_U1_DISP32: PrsPush(ps,tempi); break; case EC_U8_DISP32_SCALED: case EC_U4_DISP32_SCALED: case EC_U2_DISP32_SCALED: ps->ptr--; PrsPush(ps,tempi); break; case EC_FS_U8_DISP32: case EC_FS_U4_DISP32: case EC_FS_U2_DISP32: case EC_FS_U1_DISP32: PrsPush(ps,tempi); break; case EC_DEREF_U8: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_DEREF_U8; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_DEREF_U8; } } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_ESI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_ESI_U8_DISP32; } if (temp_lag[2]->ic_code.u2[0]==EC_EDI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_EDI_U8_DISP32; } } PrsPush(ps,tempi); break; case EC_DEREF_U4: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_DEREF_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_DEREF_U4; } } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_ESI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_ESI_U4_DISP32; } if (temp_lag[2]->ic_code.u2[0]==EC_EDI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_EDI_U4_DISP32; } } PrsPush(ps,tempi); break; case EC_DEREF_U2: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_DEREF_U2; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_DEREF_U2; } } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_ESI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_ESI_U2_DISP32; } if (temp_lag[2]->ic_code.u2[0]==EC_EDI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_EDI_U2_DISP32; } } PrsPush(ps,tempi); break; case EC_DEREF_U1: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_DEREF_U1; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_DEREF_U1; } } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_ESI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_ESI_U1_DISP32; } if (temp_lag[2]->ic_code.u2[0]==EC_EDI) { tempi->ic_flags|=temp_lag[2]->ic_flags|temp_lag[1]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_NOP; tempi->ic_data=temp_lag[1]->ic_data; tempi->ic_code=EC_EDI_U1_DISP32; } } PrsPush(ps,tempi); break; case EC_U4_PP: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_U4_PP; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_U4_PP; } } PrsPush(ps,tempi); break; case EC_U4_MM: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_U4_MM; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_U4_MM; } } PrsPush(ps,tempi); break; case EC_PP_U4: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_PP_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_PP_U4; } } PrsPush(ps,tempi); break; case EC_MM_U4: tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_MM_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags & ~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_MM_U4; } } PrsPush(ps,tempi); break; case EC_U8_PP: case EC_U2_PP: case EC_U1_PP: case EC_U8_MM: case EC_U2_MM: case EC_U1_MM: case EC_PP_U8: case EC_PP_U2: case EC_PP_U1: case EC_MM_U8: case EC_MM_U2: case EC_MM_U1: ps->ptr--; PrsPush(ps,tempi); break; case EC_POWER: case EC_SHL: case EC_SHR: case EC_MULTIPLICATION: case EC_DIVISION: case EC_REMAINDER: case EC_AND: case EC_OR: case EC_XOR: case EC_ADDITION: case EC_SUBTRACTION: case EC_EQUAL_EQUAL: case EC_NOT_EQUAL_TO: case EC_LESS_THAN: case EC_GREATER_THAN: case EC_LESS_OR_EQUAL: case EC_GREATER_OR_EQUAL: case EC_AND_AND: case EC_OR_OR: case EC_XOR_XOR: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_COLON: ps->ptr-=3; PrsPush(ps,tempi); break; case EC_ASSIGN_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_ASSIGN_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_ASSIGN_U4; } } PrsPush(ps,tempi); break; case EC_SHL_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_SHL_EQUAL_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_SHL_EQUAL_U4; } } PrsPush(ps,tempi); break; case EC_SHR_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_SHR_EQUAL_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_SHR_EQUAL_U4; } } PrsPush(ps,tempi); break; case EC_MUL_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_MUL_EQUAL_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_MUL_EQUAL_U4; } } PrsPush(ps,tempi); break; case EC_DIV_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_DIV_EQUAL_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_DIV_EQUAL_U4; } } PrsPush(ps,tempi); break; case EC_AND_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_AND_EQUAL_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_AND_EQUAL_U4; } } PrsPush(ps,tempi); break; case EC_OR_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_OR_EQUAL_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_OR_EQUAL_U4; } } PrsPush(ps,tempi); break; case EC_XOR_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_XOR_EQUAL_U4; } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_XOR_EQUAL_U4; } } PrsPush(ps,tempi); break; case EC_ADD_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); i1=tempi2->ic_data; if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_ADD_EQUAL_U4; if (tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_ESI_ADD_EQUAL_U4_CONSTANT_U1; } } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_ADD_EQUAL_U4; if (tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_EDI_ADD_EQUAL_U4_CONSTANT_U1; } } } if (tempi->ic_code.u2[0]==EC_ADD_EQUAL_U4 && tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_ADD_EQUAL_U4_CONSTANT_U1; } PrsPush(ps,tempi); break; case EC_SUB_EQUAL_U4: tempi2=PrsPop(ps); tempi1=PrsPop(ps); i1=-tempi2->ic_data; if (tempi1->ic_code.u2[0]==EC_LEA_DISP32_EBP) { if (tempi1->ic_data==l->ESI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_ESI_SUB_EQUAL_U4; if (tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_ESI_ADD_EQUAL_U4_CONSTANT_U1; } } else if (tempi1->ic_data==l->EDI_offset) { tempi->ic_flags|=(tempi1->ic_flags&~ICF_NO_PUSHES); tempi1->ic_code=EC_NOP; ShiftNoPush(tempi1); tempi->ic_code=EC_EDI_SUB_EQUAL_U4; if (tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_EDI_ADD_EQUAL_U4_CONSTANT_U1; } } } if (tempi->ic_code.u2[0]==EC_SUB_EQUAL_U4 && tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_ADD_EQUAL_U4_CONSTANT_U1; } PrsPush(ps,tempi); break; case EC_ASSIGN_U8: case EC_ASSIGN_U2: case EC_ASSIGN_U1: case EC_SHL_EQUAL_U8: case EC_SHL_EQUAL_U2: case EC_SHL_EQUAL_U1: case EC_SHR_EQUAL_U8: case EC_SHR_EQUAL_U2: case EC_SHR_EQUAL_U1: case EC_MUL_EQUAL_U8: case EC_MUL_EQUAL_U2: case EC_MUL_EQUAL_U1: case EC_DIV_EQUAL_U8: case EC_DIV_EQUAL_U2: case EC_DIV_EQUAL_U1: case EC_AND_EQUAL_U8: case EC_AND_EQUAL_U2: case EC_AND_EQUAL_U1: case EC_OR_EQUAL_U8: case EC_OR_EQUAL_U2: case EC_OR_EQUAL_U1: case EC_XOR_EQUAL_U8: case EC_XOR_EQUAL_U2: case EC_XOR_EQUAL_U1: case EC_ADD_EQUAL_U2: case EC_ADD_EQUAL_U1: case EC_SUB_EQUAL_U2: case EC_SUB_EQUAL_U1: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_ADD_EQUAL_U8: tempi2=PrsPop(ps); tempi1=PrsPop(ps); i1=tempi2->ic_data; tempc=tempi->ic_class; tempc2=tempi2->ic_class; if (tempc->sub_type!=IT_DOUBLE && tempc2->sub_type!=IT_DOUBLE && tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_ADD_EQUAL_U8_CONSTANT_U1; } PrsPush(ps,tempi); break; case EC_SUB_EQUAL_U8: tempi2=PrsPop(ps); tempi1=PrsPop(ps); i1=tempi2->ic_data; tempc=tempi->ic_class; tempc2=tempi2->ic_class; if (tempc->sub_type!=IT_DOUBLE && tempc2->sub_type!=IT_DOUBLE && tempi2->ic_code.u2[0]==EC_U8 && i1>=-128 && i1<=127) { tempi2->ic_code=EC_NOP; tempi->ic_flags|=tempi2->ic_flags; tempi->ic_data=i1; tempi->ic_code=EC_SUB_EQUAL_U8_CONSTANT_U1; } PrsPush(ps,tempi); break; case EC_SHL_CONSTANT1: case EC_SHL_CONSTANT2: case EC_SHR_CONSTANT1: case EC_SHR_CONSTANT2: case EC_ADD64: case EC_ADD32: case EC_SUB64: case EC_SUB32: ps->ptr--; PrsPush(ps,tempi); break; case EC_ENTER: if (l->EDI_offset!=MAX_I8) tempi->ic_code=EC_ENTER2; else if (l->ESI_offset!=MAX_I8) tempi->ic_code=EC_ENTER1; break; case EC_LEAVE: if (l->EDI_offset!=MAX_I8) tempi->ic_code=EC_LEAVE2; else if (l->ESI_offset!=MAX_I8) tempi->ic_code=EC_LEAVE1; break; case EC_ADD_ESP32: i1=tempi->ic_data; ps->ptr-=1+i1>>3; PrsPush(ps,tempi); break; case EC_CALL: case EC_CALL_INDIRECT: case EC_CALL_INDIRECT2: PrsPush(ps,tempi); break; case EC_IRQ: break; case EC_CLI: case EC_STI: case EC_GET_FLAGS: PrsPush(ps,tempi); break; case EC_SET_FLAGS: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_BASE_PTR: PrsPush(ps,tempi); break; case EC_SET_BASE_PTR: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_STACK_PTR: PrsPush(ps,tempi); break; case EC_SET_STACK_PTR: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_LABEL: case EC_ABSOLUTE_ADDRESS: PrsPush(ps,tempi); break; case EC_TYPE: PrsPush(ps,tempi); break; case EC_BT: case EC_BTS: case EC_BTR: case EC_BTC: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_BSF: case EC_BSR: case EC_BT_CONSTANT: case EC_BTS_CONSTANT: case EC_BTR_CONSTANT: case EC_BTC_CONSTANT: ps->ptr--; PrsPush(ps,tempi); break; case EC_INSQUE: case EC_INSQUE_REV: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_REMQUE: ps->ptr--; PrsPush(ps,tempi); break; case EC_MEMCPY: case EC_MEMSET: ps->ptr-=3; PrsPush(ps,tempi); break; case EC_INPD: case EC_INPW: case EC_INP: case EC_STRLEN: ps->ptr--; PrsPush(ps,tempi); break; case EC_OUTPD: case EC_OUTPW: case EC_OUTP: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_JMP: case EC_SHORT_JMP: break; case EC_SWITCH: ps->ptr-=2; break; case EC_SKIPZ: case EC_SKIPZ2: case EC_SKIPNZ: case EC_SKIPNZ2: //not present yet ps->ptr--; PrsPush(ps,tempi); break; case EC_EQUAL_EQUAL_SKIPZ: case EC_EQUAL_EQUAL_SKIPZ2: case EC_NOT_EQUAL_TO_SKIPZ: case EC_NOT_EQUAL_TO_SKIPZ2: case EC_LESS_THAN_SKIPZ: case EC_LESS_THAN_SKIPZ2: case EC_GREATER_THAN_SKIPZ: case EC_GREATER_THAN_SKIPZ2: case EC_LESS_OR_EQUAL_SKIPZ: case EC_LESS_OR_EQUAL_SKIPZ2: case EC_GREATER_OR_EQUAL_SKIPZ: case EC_GREATER_OR_EQUAL_SKIPZ2: case EC_AND_AND_SKIPZ: case EC_AND_AND_SKIPZ2: case EC_AND_AND_SKIPNZ: case EC_AND_AND_SKIPNZ2: case EC_OR_OR_SKIPZ: case EC_OR_OR_SKIPZ2: case EC_OR_OR_SKIPNZ: case EC_OR_OR_SKIPNZ2: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_NULL: case EC_LABEL: case EC_ADDRESS: case EC_QUESTION: case EC_JMP: case EC_IRQ: case EC_NOP: case EC_RET: break; case EC_END_EXP: ps->ptr--; break; default: OptMissing(l,3,tempi); } if (temp_lag[1]->ic_code.u2[0]==EC_ADD32) { if (temp_lag[2]->ic_code.u2[0]==EC_ESI) { temp_lag[1]->ic_flags|=temp_lag[2]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_LEA_DISP32_ESI; } else if (temp_lag[2]->ic_code.u2[0]==EC_EDI) { temp_lag[1]->ic_flags|=temp_lag[2]->ic_flags; temp_lag[2]->ic_code=EC_NOP; temp_lag[1]->ic_code=EC_LEA_DISP32_EDI; } } tempi+=sizeof(IntermediateCode); } OptEnd(l,3,ps); } void CmpOptPass4(LexStruct *l,ClassStruct *fun_class) { //adjust constants to smaller sizes I8 i1,i; IntermediateCode *tempi,*tempi1, *temp_lag[4]; ClassStruct *tempc; ParseStack *ps=OptStart(l,temp_lag); fun_class; //no unused warning tempi=l->cb.cb_in_ptr; while (tempi->ic_code.u2[0]) { OptNext(tempi,temp_lag); switch (tempi->ic_code.u2[0]) { case EC_U8: if (!(tempi->ic_data&0xFFFFFFFF00000000)) { if (!tempi->ic_data) tempi->ic_code=EC_ZERO; else if (tempi->ic_data<=127) { tempc=tempi->ic_class; if (!(tempc->sub_type&1)) tempi->ic_class=sys_internal_types[tempc->sub_type+1]; tempi->ic_code=EC_U1; } else { tempc=tempi->ic_class; if (!(tempc->sub_type&1)) tempi->ic_class=sys_internal_types[tempc->sub_type+1]; tempi->ic_code=EC_U4; } } else if (tempi->ic_data&0xFFFFFFFF80000000==0xFFFFFFFF80000000) { tempc=tempi->ic_class; if (tempc->sub_type&1) tempi->ic_class=sys_internal_types[tempc->sub_type-1]; tempi->ic_code=EC_U4; } PrsPush(ps,tempi); break; case EC_U4: if (!tempi->ic_data) tempi->ic_code=EC_ZERO; else if (tempi->ic_data<=127) { tempc=tempi->ic_class; if (!(tempc->sub_type&1)) tempi->ic_class=sys_internal_types[tempc->sub_type+1]; tempi->ic_code=EC_U1; } PrsPush(ps,tempi); break; case EC_U2: //doesn't occur case EC_U1: //doesn't occur case EC_DOUBLE: case EC_STRING_CONSTANT: case EC_EBP: case EC_FS: case EC_ESI: case EC_EDI: PrsPush(ps,tempi); break; case EC_LEA_DISP32_EBP: i1=tempi->ic_data; if (i1>=-128 && i1<=127) tempi->ic_code=EC_LEA_DISP8_EBP; PrsPush(ps,tempi); break; case EC_LEA_DISP32_ESI: i1=tempi->ic_data; if (i1>=-128 && i1<=127) tempi->ic_code=EC_LEA_DISP8_ESI; PrsPush(ps,tempi); break; case EC_LEA_DISP32_EDI: i1=tempi->ic_data; if (i1>=-128 && i1<=127) tempi->ic_code=EC_LEA_DISP8_EDI; PrsPush(ps,tempi); break; case EC_COM: case EC_NOT: case EC_UNARY_MINUS: ps->ptr--; PrsPush(ps,tempi); break; case EC_U8_DISP32: case EC_U4_DISP32: case EC_U2_DISP32: case EC_U1_DISP32: case EC_ESI_U8_DISP32: case EC_ESI_U4_DISP32: case EC_ESI_U2_DISP32: case EC_ESI_U1_DISP32: case EC_EDI_U8_DISP32: case EC_EDI_U4_DISP32: case EC_EDI_U2_DISP32: case EC_EDI_U1_DISP32: i1=tempi->ic_data; if (i1>=-128 && i1<=127) tempi->ic_code+=EC_U8_DISP8-EC_U8_DISP32; PrsPush(ps,tempi); break; case EC_U8_DISP32_SCALED: case EC_U4_DISP32_SCALED: case EC_U2_DISP32_SCALED: ps->ptr--; PrsPush(ps,tempi); break; case EC_FS_U8_DISP32: case EC_FS_U4_DISP32: case EC_FS_U2_DISP32: case EC_FS_U1_DISP32: case EC_ESI_DEREF_U8: case EC_ESI_DEREF_U4: case EC_ESI_DEREF_U2: case EC_ESI_DEREF_U1: case EC_EDI_DEREF_U8: case EC_EDI_DEREF_U4: case EC_EDI_DEREF_U2: case EC_EDI_DEREF_U1: case EC_ESI_U4_PP: case EC_ESI_U4_MM: case EC_ESI_PP_U4: case EC_ESI_MM_U4: case EC_EDI_U4_PP: case EC_EDI_U4_MM: case EC_EDI_PP_U4: case EC_EDI_MM_U4: PrsPush(ps,tempi); break; case EC_DEREF_U8: case EC_DEREF_U4: case EC_DEREF_U2: case EC_DEREF_U1: case EC_U8_PP: case EC_U4_PP: case EC_U2_PP: case EC_U1_PP: case EC_U8_MM: case EC_U4_MM: case EC_U2_MM: case EC_U1_MM: case EC_PP_U8: case EC_PP_U4: case EC_PP_U2: case EC_PP_U1: case EC_MM_U8: case EC_MM_U4: case EC_MM_U2: case EC_MM_U1: ps->ptr--; PrsPush(ps,tempi); break; case EC_POWER: case EC_SHL: case EC_SHR: case EC_MULTIPLICATION: case EC_DIVISION: case EC_REMAINDER: case EC_AND: case EC_OR: case EC_XOR: case EC_ADDITION: case EC_SUBTRACTION: case EC_EQUAL_EQUAL: case EC_NOT_EQUAL_TO: case EC_LESS_THAN: case EC_GREATER_THAN: case EC_LESS_OR_EQUAL: case EC_GREATER_OR_EQUAL: case EC_AND_AND: case EC_OR_OR: case EC_XOR_XOR: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_COLON: ps->ptr-=3; PrsPush(ps,tempi); break; case EC_ESI_ASSIGN_U4: ps->ptr--; if (temp_lag[1]->ic_code.u2[0]==EC_DEREF_U4 && temp_lag[2]->ic_code.u2[0]==EC_ESI) { temp_lag[1]->ic_code=EC_NOP; temp_lag[2]->ic_code=EC_NOP; tempi->ic_flags|=temp_lag[2]->ic_flags; tempi->ic_code=EC_ESI_NEXT_EQUAL_U4; } PrsPush(ps,tempi); break; case EC_EDI_ASSIGN_U4: ps->ptr--; if (temp_lag[1]->ic_code.u2[0]==EC_DEREF_U4 && temp_lag[2]->ic_code.u2[0]==EC_EDI) { temp_lag[1]->ic_code=EC_NOP; temp_lag[2]->ic_code=EC_NOP; tempi->ic_flags|=temp_lag[2]->ic_flags; tempi->ic_code=EC_EDI_NEXT_EQUAL_U4; } PrsPush(ps,tempi); break; case EC_ADD_EQUAL_U8_CONSTANT_U1: case EC_SUB_EQUAL_U8_CONSTANT_U1: case EC_ADD_EQUAL_U4_CONSTANT_U1: ps->ptr--; PrsPush(ps,tempi); break; case EC_ESI_ADD_EQUAL_U4_CONSTANT_U1: case EC_EDI_ADD_EQUAL_U4_CONSTANT_U1: PrsPush(ps,tempi); break; case EC_ESI_SHL_EQUAL_U4: case EC_ESI_SHR_EQUAL_U4: case EC_ESI_MUL_EQUAL_U4: case EC_ESI_DIV_EQUAL_U4: case EC_ESI_AND_EQUAL_U4: case EC_ESI_OR_EQUAL_U4: case EC_ESI_XOR_EQUAL_U4: case EC_ESI_ADD_EQUAL_U4: case EC_ESI_SUB_EQUAL_U4: case EC_EDI_SHL_EQUAL_U4: case EC_EDI_SHR_EQUAL_U4: case EC_EDI_MUL_EQUAL_U4: case EC_EDI_DIV_EQUAL_U4: case EC_EDI_AND_EQUAL_U4: case EC_EDI_OR_EQUAL_U4: case EC_EDI_XOR_EQUAL_U4: case EC_EDI_ADD_EQUAL_U4: case EC_EDI_SUB_EQUAL_U4: ps->ptr--; PrsPush(ps,tempi); break; case EC_ASSIGN_U8: case EC_ASSIGN_U4: case EC_ASSIGN_U2: case EC_ASSIGN_U1: case EC_SHL_EQUAL_U8: case EC_SHL_EQUAL_U4: case EC_SHL_EQUAL_U2: case EC_SHL_EQUAL_U1: case EC_SHR_EQUAL_U8: case EC_SHR_EQUAL_U4: case EC_SHR_EQUAL_U2: case EC_SHR_EQUAL_U1: case EC_MUL_EQUAL_U8: case EC_MUL_EQUAL_U4: case EC_MUL_EQUAL_U2: case EC_MUL_EQUAL_U1: case EC_DIV_EQUAL_U8: case EC_DIV_EQUAL_U4: case EC_DIV_EQUAL_U2: case EC_DIV_EQUAL_U1: case EC_AND_EQUAL_U8: case EC_AND_EQUAL_U4: case EC_AND_EQUAL_U2: case EC_AND_EQUAL_U1: case EC_OR_EQUAL_U8: case EC_OR_EQUAL_U4: case EC_OR_EQUAL_U2: case EC_OR_EQUAL_U1: case EC_XOR_EQUAL_U8: case EC_XOR_EQUAL_U4: case EC_XOR_EQUAL_U2: case EC_XOR_EQUAL_U1: case EC_ADD_EQUAL_U8: case EC_ADD_EQUAL_U4: case EC_ADD_EQUAL_U2: case EC_ADD_EQUAL_U1: case EC_SUB_EQUAL_U8: case EC_SUB_EQUAL_U4: case EC_SUB_EQUAL_U2: case EC_SUB_EQUAL_U1: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_SHL_CONSTANT1: case EC_SHL_CONSTANT2: case EC_SHR_CONSTANT1: case EC_SHR_CONSTANT2: case EC_ADD64: ps->ptr--; PrsPush(ps,tempi); break; case EC_ADD32: tempi1=PrsPop(ps); if (!(i1=tempi->ic_data)) { tempi1->ic_class=tempi->ic_class; tempi1->ic_flags|=tempi->ic_flags; tempi->ic_code=EC_NOP; PrsPush(ps,tempi1); } else { if (i1==1) tempi->ic_code=EC_INC; else if (i1==-1) tempi->ic_code=EC_DEC; else if (i1>=-128 && i1<=127) tempi->ic_code=EC_ADD8; PrsPush(ps,tempi); } break; case EC_SUB64: ps->ptr--; PrsPush(ps,tempi); break; case EC_SUB32: tempi1=PrsPop(ps); if (!(i1=tempi->ic_data)) { tempi1->ic_class=tempi->ic_class; tempi1->ic_flags|=tempi->ic_flags; tempi->ic_code=EC_NOP; PrsPush(ps,tempi1); } else { if (i1==1) tempi->ic_code=EC_DEC; else if (i1==-1) tempi->ic_code=EC_INC; else if (i1>=-128 && i1<=127) tempi->ic_code=EC_SUB8; PrsPush(ps,tempi); } break; case EC_ENTER: case EC_ENTER1: case EC_ENTER2: break; case EC_LEAVE: if (temp_lag[1]->ic_code.u2[0]==EC_ADD_ESP32 || temp_lag[1]->ic_code.u2[0]==EC_ADD_ESP8) { tempi->ic_data+=temp_lag[1]->ic_data; tempi->ic_flags|=temp_lag[1]->ic_flags; temp_lag[1]->ic_code=EC_NOP; } break; case EC_LEAVE1: case EC_LEAVE2: break; case EC_ADD_ESP32: i1=tempi->ic_data; ps->ptr-=1+i1>>3; if (i1>=-128 && i1<=127) { if (!i1) { temp_lag[1]->ic_flags|=tempi->ic_flags; tempi->ic_code=EC_NOP; } else tempi->ic_code=EC_ADD_ESP8; } PrsPush(ps,tempi); break; case EC_CALL: case EC_CALL_INDIRECT: case EC_CALL_INDIRECT2: PrsPush(ps,tempi); break; case EC_IRQ: break; case EC_CLI: case EC_STI: case EC_GET_FLAGS: PrsPush(ps,tempi); break; case EC_SET_FLAGS: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_BASE_PTR: PrsPush(ps,tempi); break; case EC_SET_BASE_PTR: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_STACK_PTR: PrsPush(ps,tempi); break; case EC_SET_STACK_PTR: ps->ptr--; PrsPush(ps,tempi); break; case EC_GET_LABEL: case EC_ABSOLUTE_ADDRESS: PrsPush(ps,tempi); break; case EC_TYPE: PrsPush(ps,tempi); break; case EC_BT: case EC_BTS: case EC_BTR: case EC_BTC: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_BSF: case EC_BSR: case EC_BT_CONSTANT: case EC_BTS_CONSTANT: case EC_BTR_CONSTANT: case EC_BTC_CONSTANT: ps->ptr--; PrsPush(ps,tempi); break; case EC_INSQUE: case EC_INSQUE_REV: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_REMQUE: ps->ptr--; PrsPush(ps,tempi); break; case EC_MEMCPY: case EC_MEMSET: ps->ptr-=3; PrsPush(ps,tempi); break; case EC_INPD: case EC_INPW: case EC_INP: case EC_STRLEN: ps->ptr--; PrsPush(ps,tempi); break; case EC_OUTPD: case EC_OUTPW: case EC_OUTP: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_JMP: case EC_SHORT_JMP: break; case EC_SWITCH: ps->ptr-=2; break; case EC_SKIPZ: case EC_SKIPZ2: case EC_SKIPNZ: case EC_SKIPNZ2: //not present yet ps->ptr--; PrsPush(ps,tempi); break; case EC_EQUAL_EQUAL_SKIPZ: case EC_EQUAL_EQUAL_SKIPZ2: case EC_NOT_EQUAL_TO_SKIPZ: case EC_NOT_EQUAL_TO_SKIPZ2: case EC_LESS_THAN_SKIPZ: case EC_LESS_THAN_SKIPZ2: case EC_GREATER_THAN_SKIPZ: case EC_GREATER_THAN_SKIPZ2: case EC_LESS_OR_EQUAL_SKIPZ: case EC_LESS_OR_EQUAL_SKIPZ2: case EC_GREATER_OR_EQUAL_SKIPZ: case EC_GREATER_OR_EQUAL_SKIPZ2: case EC_AND_AND_SKIPZ: case EC_AND_AND_SKIPZ2: case EC_AND_AND_SKIPNZ: case EC_AND_AND_SKIPNZ2: case EC_OR_OR_SKIPZ: case EC_OR_OR_SKIPZ2: case EC_OR_OR_SKIPNZ: case EC_OR_OR_SKIPNZ2: ps->ptr-=2; PrsPush(ps,tempi); break; case EC_NULL: case EC_LABEL: case EC_ADDRESS: case EC_QUESTION: case EC_JMP: case EC_IRQ: case EC_NOP: case EC_RET: break; case EC_END_EXP: ps->ptr--; break; default: OptMissing(l,4,tempi); } if (Bt(push_bitmap,tempi->ic_code.u2[0]) && !(tempi->ic_flags & ICF_NO_PUSHES)) { tempi1=temp_lag[1]; i=push_map[tempi1->ic_code.u2[0]]; i1=tempi1->ic_data; tempc=tempi1->ic_class; switch (i) { case EC_PUSH_U4: if (!(tempc->sub_type&1) && i1<0) i=EC_PUSH_NEG_U4; break; case EC_PUSH_U2: if (!(tempc->sub_type&1) && i1<0) i=EC_PUSH_NEG_U2; break; case EC_PUSH_U1: if (i1<-0x80 || i1>0x7F) { i=EC_PUSH_U2; if (!(tempc->sub_type&1) && i1<0) i=EC_PUSH_NEG_U2; } else { if (!(tempc->sub_type&1) && i1<0) i=EC_PUSH_NEG_U1; } break; } if (i) { tempi1->ic_code=i; if (!(tempi1->ic_flags & (ICF_TO_DOUBLE|ICF_TO_INT)) ) tempi->ic_flags|=ICF_NO_PUSHES; else tempi1->ic_flags|=ICF_NO_PUSHES_TO_DOUBLE_OR_INT; } } tempi+=sizeof(IntermediateCode); } OptEnd(l,4,ps); }