Files
TempleOS-Rijn/LT/COMPILE/OPT.CPZ
T
2018-09-08 21:45:17 +02:00

3045 lines
78 KiB
Plaintext

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<<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_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=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_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;i<PASS2_OFFSETS+2;i++) {
c[i]=0;
o[i]=MAX_I8;
lea_s[i]=0;
}
if (fun_class) {
tempm=fun_class->member_list;
while (tempm) {
tempc=tempm->member_class;
if (!tempm->cnt && tempc->pointer_cnt && tempm->use_cnt>c[PASS2_OFFSETS-1]) {
for (i=0;i<PASS2_OFFSETS;i++)
if (tempm->use_cnt>c[i]) {
for (j=i;j<PASS2_OFFSETS-1;j++) {
c[j+1]=c[j];
o[j+1]=o[j];
}
c[i]=tempm->use_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi1->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi1->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi1->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi1->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi1->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==temp_lag[1]->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==tempi1->ic_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;i<PASS2_OFFSETS;i++)
if (o[i]==temp_lag[1]->ic_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;i<PASS2_OFFSETS+2;i++)
if (!lea_s[i])
o[j++]=o[i];
for (;j<2;j++)
o[j]=MAX_I8;
l->ESI_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);
}