Files
TempleOS-Rijn/LT/Compiler/OptPass1.CPZ
T
2018-09-08 21:45:20 +02:00

1541 lines
45 KiB
Plaintext

#define FBO1_NOT_CONST 0
#define FBO1_INT 1
#define FBO1_DOUBLE 2
BoolU8 FixupBinaryOp1(IntermediateCode *tempi,
IntermediateCode *tempi1,IntermediateCode *tempi2,
BoolU4 *is_unsigned)
{
ClassStruct *tempc=tempi->ic_class,*tempc1,*tempc2;
tempc1=tempi1->ic_class;
while (tempc1->return_class)
tempc1=tempc1->return_class;
tempc2=tempi2->ic_class;
while (tempc2->return_class)
tempc2=tempc2->return_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 (!(tempi->ic_flags&ICF_USE_INT)) {
if (tempi1->ic_opcode==EC_IMM) {
tempi1->ic_data><(double)=tempi1->ic_data;
tempi1->ic_class=sys_internal_types[IT_DOUBLE];
tempi1->ic_opcode=EC_DOUBLE;
} else
if (tempc1->sub_type!=IT_DOUBLE)
tempi1->ic_flags|=ICF_R_TO_DOUBLE;
if (tempi2->ic_opcode==EC_IMM) {
tempi2->ic_data><(double)=tempi2->ic_data;
tempi2->ic_class=sys_internal_types[IT_DOUBLE];
tempi2->ic_opcode=EC_DOUBLE;
} else
if (tempc2->sub_type!=IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_DOUBLE;
}
if (tempi1->ic_opcode==EC_DOUBLE &&
tempi2->ic_opcode==EC_DOUBLE &&
!(tempi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
return FBO1_DOUBLE;
} else
return FBO1_NOT_CONST;
}
tempi->ic_flags&=~ICF_USE_INT;
*is_unsigned=tempc1->sub_type&1 || tempc2->sub_type&1;
if (tempi1->ic_opcode==EC_IMM &&
tempi2->ic_opcode==EC_IMM &&
!(tempi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
return FBO1_INT;
} else
return FBO1_NOT_CONST;
}
BoolU8 FixupBinaryOp2(IntermediateCode **tempi1,IntermediateCode **tempi2)
{
IntermediateCode *tempii1=*tempi1,
*tempii2=*tempi2;
if (tempii1->ic_opcode==EC_IMM &&
!(tempii1->ic_flags & ICF_R_TO_DOUBLE))
return TRUE;
if (tempii2->ic_opcode==EC_IMM &&
!(tempii2->ic_flags & ICF_R_TO_DOUBLE)) {
*tempi1=tempii2;
*tempi2=tempii1;
return TRUE;
}
return FALSE;
}
BoolU8 FixupUnaryOp(IntermediateCode *tempi,
IntermediateCode *tempi1,
BoolU4 *is_unsigned)
{
ClassStruct *tempc,*tempc1;
tempc1=tempi1->ic_class;
while (tempc1->return_class)
tempc1=tempc1->return_class;
tempi->ic_class=tempc1;
tempc=tempi->ic_class;
if (tempc->sub_type==IT_DOUBLE) {
if (!(tempi->ic_flags&ICF_USE_INT)) {
if (tempi1->ic_opcode==EC_IMM) {
tempi1->ic_data><(double)=tempi1->ic_data;
tempi1->ic_class=sys_internal_types[IT_DOUBLE];
tempi1->ic_opcode=EC_DOUBLE;
} else
if (tempc1->sub_type!=IT_DOUBLE)
tempi1->ic_flags|=ICF_R_TO_DOUBLE;
}
if (tempi1->ic_opcode==EC_DOUBLE) {
tempi->ic_flags|=tempi1->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
return FBO1_DOUBLE;
} else
return FBO1_NOT_CONST;
}
tempi->ic_flags&=~ICF_USE_INT;
*is_unsigned=tempc1->sub_type&1;
if (tempi1->ic_opcode==EC_IMM) {
tempi->ic_flags|=tempi1->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
return FBO1_INT;
} else
return FBO1_NOT_CONST;
}
I8 CmpOffsetToReg(I8 offset,I8 *register_offsets)
{
I8 i;
for (i=0;i<NUM_REGS;i++)
if (offset==register_offsets[i])
return i;
return -1;
}
void OptMissing(LexStruct *lx,I8 pass,IntermediateCode *tempi)
{
coutln "Pass:",pass," Missing IC handler";
CbPutIc(tempi);
PrsExcept(lx,"ST_OPT_INTERNAL_ERROR");
}
IntermediateCode opt_nop;
ParseStack *OptStart(LexStruct *lx,IntermediateCode **temp_lag)
{
I8 i;
ParseStack *ps=MAlloc(sizeof(ParseStack));
CbInitInPtrs(&lx->cb);
ps->ptr=0;
for (i=0;i<4;i++)
temp_lag[i]=&opt_nop;
return ps;
}
LTextern CP_OPTNEXT BoolU4 OptNext(IntermediateCode *tempi,
IntermediateCode **temp_lag);
LTextern CP_OPTNEXT2 BoolU4 OptNext2(IntermediateCode *tempi,
IntermediateCode **temp_lag);
LTextern CP_OPTNEXT3 BoolU4 OptNext3(IntermediateCode *tempi,
IntermediateCode **temp_lag);
void OptEnd(LexStruct *lx,I8 pass,ParseStack *ps)
{
if (ps->ptr>2) {
PrintF("Pass:%d Stack:%08X\r\n",pass,ps->ptr);
PrsExcept(lx,"ST_OPT_INTERNAL_ERROR");
}
Free(ps);
}
IntermediateCode *OptLag(LexStruct *lx,IntermediateCode *tempi)
{
do {
if (tempi==lx->cb.cb_in_ptr)
return NULL;
else
tempi-=sizeof(IntermediateCode);
} while (tempi->ic_opcode<=EC_END_EXP);
return tempi;
}
IntermediateCode *OptLag1(LexStruct *lx,IntermediateCode *tempi)
{
do {
if (tempi==lx->cb.cb_in_ptr)
return NULL;
else
tempi-=sizeof(IntermediateCode);
} while (tempi->ic_opcode==EC_NOP||tempi->ic_opcode==EC_NOP1);
return tempi;
}
IntermediateCode *OptLead1(LexStruct *lx,IntermediateCode *tempi)
{
nounusedwarn lx;
do {
tempi+=sizeof(IntermediateCode);
if (tempi->ic_opcode==EC_NULL)
return NULL;
} while (tempi->ic_opcode==EC_NOP||tempi->ic_opcode==EC_NOP1);
return tempi;
}
extern void OptBrNotZero(LexStruct *lx,IntermediateCode *tempi);
IntermediateCode *OptBrZero(LexStruct *lx,IntermediateCode *tempi)
{
CbMiscStruct *templ_true,*templ_false;
IntermediateCode *tempii=OptLag(lx,tempi),*tempii2;
switch (tempii->ic_opcode) {
case EC_NOT:
tempi->ic_opcode=EC_BR_NOT_ZERO;
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->p1c=tempii->p1c;
tempi->p1t=tempii->p1t;
tempii->ic_opcode=EC_NOP;
tempii->ic_flags=0;
return OptBrNotZero(lx,tempi);
case EC_EQUAL_EQUAL:
tempi->ic_opcode=EC_BR_NOT_EQUAL;
break;
case EC_NOT_EQUAL:
tempi->ic_opcode=EC_BR_EQUAL_EQUAL;
break;
case EC_LESS:
tempi->ic_opcode=EC_BR_GREATER_EQUAL;
break;
case EC_GREATER:
tempi->ic_opcode=EC_BR_LESS_EQUAL;
break;
case EC_LESS_EQUAL:
tempi->ic_opcode=EC_BR_GREATER;
break;
case EC_GREATER_EQUAL:
tempi->ic_opcode=EC_BR_LESS;
break;
case EC_OR_OR:
tempi->ic_opcode=EC_BR_OR_OR_ZERO;
break;
case EC_AND_AND:
tempi->ic_opcode=EC_BR_AND_AND_ZERO;
break;
case EC_AND:
tempi->ic_opcode=EC_BR_AND_ZERO;
break;
case EC_CALL_END:
tempii2=OptLag(lx,tempii);
switch (tempii2->ic_opcode) {
case EC_BT:
tempii2->ic_opcode=EC_BR_NOT_BT;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_BTS:
tempii2->ic_opcode=EC_BR_NOT_BTS;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_BTR:
tempii2->ic_opcode=EC_BR_NOT_BTR;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_BTC:
tempii2->ic_opcode=EC_BR_NOT_BTC;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_LBTS:
tempii2->ic_opcode=EC_BR_NOT_LBTS;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_LBTR:
tempii2->ic_opcode=EC_BR_NOT_LBTR;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_LBTC:
tempii2->ic_opcode=EC_BR_NOT_LBTC;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
}
break;
}
if (tempi->ic_opcode!=EC_BR_ZERO) {
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->p1c=tempii->p1c;
tempi->p2c=tempii->p2c;
tempi->p1t=tempii->p1t;
tempi->p2t=tempii->p2t;
tempii->ic_opcode=EC_NOP;
tempii->ic_flags=0;
templ_true=tempi->ic_data;
if (tempi->ic_opcode==EC_BR_AND_AND_ZERO) {
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempii=tempi->p1t+sizeof(IntermediateCode);
tempii->ic_data=templ_true;
tempii->p1t=tempi->p1t;
tempii->p1c=tempi->p1c;
tempii->ic_opcode=EC_BR_ZERO;
OptBrZero(lx,tempii);
tempii=tempi->p2t+sizeof(IntermediateCode);
tempii->p1t=tempi->p2t;
tempii->p1c=tempi->p2c;
tempii->ic_data=templ_true;
tempii->ic_opcode=EC_BR_ZERO;
return OptBrZero(lx,tempii);
} else if (tempi->ic_opcode==EC_BR_OR_OR_ZERO) {
templ_false=CbMiscNew(lx,CBMT_LABEL);
tempi->ic_opcode=EC_LABEL;
tempi->ic_flags=0;
tempi->ic_data=templ_false;
tempii=tempi->p1t+sizeof(IntermediateCode);
tempii->p1t=tempi->p1t;
tempii->p1c=tempi->p1c;
tempii->ic_data=templ_false;
tempii->ic_opcode=EC_BR_NOT_ZERO;
OptBrNotZero(lx,tempii);
tempii=tempi->p2t+sizeof(IntermediateCode);
tempii->p1t=tempi->p2t;
tempii->p1c=tempi->p2c;
tempii->ic_data=templ_true;
tempii->ic_opcode=EC_BR_ZERO;
return OptBrZero(lx,tempii);
}
}
return tempi;
}
IntermediateCode *OptBrNotZero(LexStruct *lx,IntermediateCode *tempi)
{
CbMiscStruct *templ_true,*templ_false;
IntermediateCode *tempii=OptLag(lx,tempi),*tempii2;
switch (tempii->ic_opcode) {
case EC_NOT:
tempi->ic_opcode=EC_BR_ZERO;
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->p1c=tempii->p1c;
tempi->p1t=tempii->p1t;
tempii->ic_opcode=EC_NOP;
tempii->ic_flags=0;
return OptBrZero(lx,tempi);
case EC_EQUAL_EQUAL:
tempi->ic_opcode=EC_BR_EQUAL_EQUAL;
break;
case EC_NOT_EQUAL:
tempi->ic_opcode=EC_BR_NOT_EQUAL;
break;
case EC_LESS:
tempi->ic_opcode=EC_BR_LESS;
break;
case EC_GREATER:
tempi->ic_opcode=EC_BR_GREATER;
break;
case EC_LESS_EQUAL:
tempi->ic_opcode=EC_BR_LESS_EQUAL;
break;
case EC_GREATER_EQUAL:
tempi->ic_opcode=EC_BR_GREATER_EQUAL;
break;
case EC_OR_OR:
tempi->ic_opcode=EC_BR_OR_OR_NOT_ZERO;
break;
case EC_AND_AND:
tempi->ic_opcode=EC_BR_AND_AND_NOT_ZERO;
break;
case EC_AND:
tempi->ic_opcode=EC_BR_AND_NOT_ZERO;
break;
case EC_CALL_END:
tempii2=OptLag(lx,tempii);
switch (tempii2->ic_opcode) {
case EC_BT:
tempii2->ic_opcode=EC_BR_BT;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_BTS:
tempii2->ic_opcode=EC_BR_BTS;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_BTR:
tempii2->ic_opcode=EC_BR_BTR;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_BTC:
tempii2->ic_opcode=EC_BR_BTC;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_LBTS:
tempii2->ic_opcode=EC_BR_LBTS;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_LBTR:
tempii2->ic_opcode=EC_BR_LBTR;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
case EC_LBTC:
tempii2->ic_opcode=EC_BR_LBTC;
tempii2->ic_data=tempi->ic_data;
tempii->ic_opcode=EC_CALL_END2;
tempi->ic_opcode=EC_NOP;
return tempii;
}
break;
}
if (tempi->ic_opcode!=EC_BR_NOT_ZERO) {
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->p1c=tempii->p1c;
tempi->p2c=tempii->p2c;
tempi->p1t=tempii->p1t;
tempi->p2t=tempii->p2t;
tempii->ic_opcode=EC_NOP;
tempii->ic_flags=0;
templ_true=tempi->ic_data;
if (tempi->ic_opcode==EC_BR_OR_OR_NOT_ZERO) {
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempii=tempi->p1t+sizeof(IntermediateCode);
tempii->p1t=tempi->p1t;
tempii->p1c=tempi->p1c;
tempii->ic_data=templ_true;
tempii->ic_opcode=EC_BR_NOT_ZERO;
OptBrNotZero(lx,tempii);
tempii=tempi->p2t+sizeof(IntermediateCode);
tempii->p1t=tempi->p2t;
tempii->p1c=tempi->p2c;
tempii->ic_data=templ_true;
tempii->ic_opcode=EC_BR_NOT_ZERO;
return OptBrNotZero(lx,tempii);
} else if (tempi->ic_opcode==EC_BR_AND_AND_NOT_ZERO) {
templ_false=CbMiscNew(lx,CBMT_LABEL);
tempi->ic_opcode=EC_LABEL;
tempi->ic_flags=0;
tempi->ic_data=templ_false;
tempii=tempi->p1t+sizeof(IntermediateCode);
tempii->p1t=tempi->p1t;
tempii->p1c=tempi->p1c;
tempii->ic_data=templ_false;
tempii->ic_opcode=EC_BR_ZERO;
OptBrZero(lx,tempii);
tempii=tempi->p2t+sizeof(IntermediateCode);
tempii->p1t=tempi->p2t;
tempii->p1c=tempi->p2c;
tempii->ic_data=templ_true;
tempii->ic_opcode=EC_BR_NOT_ZERO;
return OptBrNotZero(lx,tempii);
}
}
return tempi;
}
IntermediateCode *CmpOptPass1(LexStruct *lx,ClassStruct *fun_class,BoolU4 combined)
{
/*
Simplify CONST arithmetic.
Sets the class throughout Expression trees.
Returns the type of an Expression for use
in int<-->double conversions of function
parameters.
*/
I8 code,i;
BoolU4 is_unsigned;
ClassStruct *tempc,*tempc1,*tempc2,*tempc3,*tempcc;
IntermediateCode *tempi,*tempi1,*tempi2,*tempi3,*tempi_push,
*temp_lag[4],*last_with_class=NULL,*tempii;
ParseStack *ps=OptStart(lx,temp_lag);
if (combined)
tempi=lx->cb.cb_in_ptr;
else
tempi=CbGetIc1(&lx->cb);
while (code=tempi->ic_opcode) {
OptNext(tempi,temp_lag);
tempc=tempi->ic_class;
tempi->original_class=tempc;
tempi_push=tempi;
switch (cmp_param_cnt[code]) {
case 9:
ps->ptr-=tempi->ic_data>>2;
break;
case 3:
tempi3=PrsPop(ps);
tempc3=tempi3->ic_class;
tempi->p3t=tempi3;
tempi->p3c=PrsPop(ps);
case 2:
tempi2=PrsPop(ps);
tempc2=tempi2->ic_class;
tempi->p2t=tempi2;
tempi->p2c=PrsPop(ps);
case 1:
tempi1=PrsPop(ps);
tempc1=tempi1->ic_class;
tempi->p1t=tempi1;
tempi->p1c=PrsPop(ps);
break;
}
if (Bt(not_constant_bitmap,code))
lx->flags|=LF_NOT_CONSTANT;
switch (code) {
case EC_IMM:
case EC_DOUBLE:
case EC_STR_CONST:
case EC_RBP:
case EC_FS:
case EC_GS:
break;
case EC_PUSH_CMP:
tempi1=temp_lag[1];
if (tempi1->ic_opcode==EC_AND_AND)
tempi1=temp_lag[2];
tempi->ic_class=tempi1->ic_class;
tempi->original_class=tempi->ic_class;
tempi->ic_data=0;
if (tempi->ic_class->sub_type==IT_DOUBLE)
tempi->ic_flags|=ICF_USE_DOUBLE;
break;
case EC_COM:
if (tempc->sub_type==IT_DOUBLE) {
if (tempi1->ic_opcode==EC_DOUBLE) {
tempi->ic_data><(double)=~tempi1->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
tempi->ic_flags|=tempi1->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
}
break;
}
if (tempi1->ic_opcode==EC_IMM) {
tempi->ic_data=~tempi1->ic_data;
tempi->ic_opcode=EC_IMM;
tempi->ic_flags|=tempi1->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_NOT:
if (tempc->sub_type==IT_DOUBLE) {
if (tempi1->ic_opcode==EC_DOUBLE) {
tempi->ic_data><(double)=!tempi1->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
tempi->ic_flags|=tempi1->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
}
break;
}
if (tempi1->ic_opcode==EC_IMM) {
tempi->ic_data=!tempi1->ic_data;
tempi->ic_opcode=EC_IMM;
tempi->ic_flags|=tempi1->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_UNARY_MINUS:
if (i=FixupUnaryOp(tempi,tempi1,&is_unsigned)) {
if (i==FBO1_INT) {
tempi->ic_data=-tempi1->ic_data><(I8);
tempi->ic_opcode=EC_IMM;
} else {
if (tempi->ic_flags&ICF_USE_INT) {
tempi->ic_data=-tempi1->ic_data><(double);
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=-tempi1->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
}
}
if (tempc1->type&HTT_INTERNAL_TYPE && tempc1->sub_type& 1)
tempi->ic_class=sys_internal_types[tempc1->sub_type-1];
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_DEREF:
case EC__PP:
case EC__MM:
case EC_PP_:
case EC_MM_:
break;
case EC_SHL_CONST:
case EC_SHR_CONST:
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_POWER:
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_R_TO_DOUBLE;
if (tempc2->sub_type!=IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_DOUBLE;
if (tempc->sub_type!=IT_DOUBLE)
tempi->ic_flags|=ICF_R_TO_INT|ICF_USE_DOUBLE;
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_SHL:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)<<tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)<<tempi2->ic_data><(I8);
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=tempi1->ic_data><(double) << tempi2->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
} else if (tempi2->ic_opcode==EC_IMM) {
tempi->ic_flags|=tempi2->ic_flags;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_data=tempi2->ic_data;
tempi->ic_opcode=EC_SHL_CONST;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_SHR:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)>>tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)>>tempi2->ic_data><(I8);
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=tempi1->ic_data><(double) >> tempi2->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
} else if (tempi2->ic_opcode==EC_IMM) {
tempi->ic_flags|=tempi2->ic_flags;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_data=tempi2->ic_data;
tempi->ic_opcode=EC_SHR_CONST;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_MUL:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)*tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)*tempi2->ic_data><(I8);
tempi->ic_opcode=EC_IMM;
} else {
if (tempi->ic_flags&ICF_USE_INT) {
tempi->ic_data=tempi1->ic_data><(double)*
tempi2->ic_data><(double);
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=tempi1->ic_data><(double)*
tempi2->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
}
} else {
if (tempi2->ic_opcode==EC_IMM) {
tempcc=tempi->p1c;
tempii=tempi2;
tempi2=tempi1;
tempi1=tempii;
} else
tempcc=tempi->p2c;
if (tempi1->ic_opcode==EC_IMM) {
i=tempi1->ic_data;
switch (i) {
case 0:
break;
case 1:
tempi2->ic_flags|=tempi->ic_flags|tempi1->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi2->p1c=tempi->p1c;
tempi2->p1t=tempi->p1t;
tempi2->original_class=tempi->original_class;
tempi_push=tempi2;
break;
default:
if (Bsf(i)==Bsr(i)) {
tempi->ic_flags|=tempi1->ic_flags;
tempi->p1c=tempcc;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
tempi->ic_data=Bsf(i);
tempi->ic_opcode=EC_SHL_CONST;
}
break;
}
}
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_DIV:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (!tempi2->ic_data) PrsExcept(lx,"ST_DIVIDE_BY_ZERO");
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)/tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)/tempi2->ic_data><(I8);
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=tempi1->ic_data><(double)/
tempi2->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
} else {
if (tempi2->ic_opcode==EC_IMM) {
i=tempi2->ic_data;
switch (i) {
case 0:
PrsExcept(lx,"ST_DIVIDE_BY_ZERO");
break;
case 1:
tempi1->ic_flags|=tempi2->ic_flags|tempi->ic_flags;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi1->p1c=tempi->p1c;
tempi1->p1t=tempi->p1t;
tempi1->original_class=tempi->original_class;
tempi_push=tempi1;
break;
default:
if (Bsf(i)==Bsr(i)) {
tempi->ic_flags|=tempi2->ic_flags;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_data=Bsf(i);
tempi->ic_opcode=EC_SHR_CONST;
}
break;
}
}
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_MOD:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (!tempi2->ic_data) PrsExcept(lx,"ST_DIVIDE_BY_ZERO");
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)%tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)%tempi2->ic_data><(I8);
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=tempi1->ic_data><(double)%
tempi2->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
} else {
if (tempi2->ic_opcode==EC_IMM) {
i=tempi2->ic_data;
switch (i) {
case 0:
PrsExcept(lx,"ST_DIVIDE_BY_ZERO");
break;
default:
if (i>0 && Bsf(i)==Bsr(i)) {
tempi2->ic_data=i-1;
tempi->ic_opcode=EC_AND;
}
break;
}
}
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_AND:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data&tempi2->ic_data;
if (i==FBO1_INT)
tempi->ic_opcode=EC_IMM;
else
tempi->ic_opcode=EC_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_OR:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data|tempi2->ic_data;
if (i==FBO1_INT)
tempi->ic_opcode=EC_IMM;
else
tempi->ic_opcode=EC_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_XOR:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data^tempi2->ic_data;
if (i==FBO1_INT)
tempi->ic_opcode=EC_IMM;
else
tempi->ic_opcode=EC_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_ADD:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
tempi->ic_data=tempi1->ic_data+tempi2->ic_data;
tempi->ic_opcode=EC_IMM;
} else {
if (tempi->ic_flags&ICF_USE_INT) {
tempi->ic_data=tempi1->ic_data><(double)*
tempi2->ic_data><(double);
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=tempi1->ic_data><(double)+
tempi2->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
}
} else {
if (tempi1->ic_opcode==EC_IMM) {
/******* we got problems--class needs to propigate back
if (!tempi1->ic_data) {
tempi2->ic_flags|=tempi1->ic_flags|tempi->ic_flags;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi2->p1c=tempi->p1c;
tempi2->p1t=tempi->p1t;
tempi2->original_class=tempi->original_class;
tempi_push=tempi2;
} else
*******/
// we got problems--class needs to propigate back
if (tempi2->ic_opcode==EC_ADD||
tempi2->ic_opcode==EC_SUB) {
if (tempi2->p1t->ic_opcode==EC_IMM) {
tempi2->ic_flags|=tempi->ic_flags;
if (tempi2->ic_opcode==EC_ADD)
tempi2->p1t->ic_data+=tempi1->ic_data;
else
tempi2->p1t->ic_data-=tempi1->ic_data;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi2->p1c=tempi->p1c;
tempi2->p1t=tempi->p1t;
tempi2->original_class=tempi->original_class;
tempi_push=tempi2;
} else if (tempi2->p2t->ic_opcode==EC_IMM) {
tempi2->ic_flags|=tempi->ic_flags;
if (tempi2->ic_opcode==EC_ADD)
tempi2->p2t->ic_data+=tempi1->ic_data;
else
tempi2->p2t->ic_data-=tempi1->ic_data;
tempi1->ic_opcode=EC_NOP;
tempi1->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi2->p1c=tempi->p1c;
tempi2->p1t=tempi->p1t;
tempi2->original_class=tempi->original_class;
tempi_push=tempi2;
}
}
} else if (tempi2->ic_opcode==EC_IMM) {
/******* we got problems--class needs to propigate back
if (!tempi2->ic_data) {
tempi1->ic_flags|=tempi2->ic_flags|tempi->ic_flags;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi1->p1c=tempi->p1c;
tempi1->p1t=tempi->p1t;
tempi1->original_class=tempi->original_class;
tempi_push=tempi1;
} else
*******/
// we got problems--class needs to propigate back
if (tempi1->ic_opcode==EC_ADD ||
tempi1->ic_opcode==EC_SUB) {
if (tempi1->p1t->ic_opcode==EC_IMM) {
tempi1->ic_flags|=tempi->ic_flags;
if (tempi1->ic_opcode==EC_ADD)
tempi1->p1t->ic_data+=tempi2->ic_data;
else
tempi1->p1t->ic_data-=tempi2->ic_data;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi1->p1c=tempi->p1c;
tempi1->p1t=tempi->p1t;
tempi1->original_class=tempi->original_class;
tempi_push=tempi1;
} else if (tempi1->p2t->ic_opcode==EC_IMM) {
tempi1->ic_flags|=tempi->ic_flags;
if (tempi1->ic_opcode==EC_ADD)
tempi1->p2t->ic_data+=tempi2->ic_data;
else
tempi1->p2t->ic_data-=tempi2->ic_data;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi1->p1c=tempi->p1c;
tempi1->p1t=tempi->p1t;
tempi1->original_class=tempi->original_class;
tempi_push=tempi1;
}
}
}
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_SUB:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
tempi->ic_data=tempi1->ic_data-tempi2->ic_data;
tempi->ic_opcode=EC_IMM;
} else {
tempi->ic_data><(double)=tempi1->ic_data><(double)-
tempi2->ic_data><(double);
tempi->ic_opcode=EC_DOUBLE;
}
} else {
if (tempi2->ic_opcode==EC_IMM && !tempi2->ic_data) {
tempi1->ic_flags|=tempi2->ic_flags|tempi->ic_flags;
tempi2->ic_opcode=EC_NOP;
tempi2->ic_flags=0;
tempi->ic_opcode=EC_NOP;
tempi->ic_flags=0;
tempi1->p1c=tempi->p1c;
tempi1->p1t=tempi->p1t;
tempi1->original_class=tempi->original_class;
tempi_push=tempi1;
}
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_EQUAL_EQUAL:
if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data==tempi2->ic_data;
tempi->ic_opcode=EC_IMM;
} else
if (tempi->ic_class->sub_type==IT_DOUBLE)
tempi->ic_flags|=ICF_USE_DOUBLE;
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
if (tempi_push->ic_flags & ICF_PUSH_CMP)
tempi->ic_class=tempi->original_class;
else
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_NOT_EQUAL:
if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data!=tempi2->ic_data;
tempi->ic_opcode=EC_IMM;
} else
if (tempi->ic_class->sub_type==IT_DOUBLE)
tempi->ic_flags|=ICF_USE_DOUBLE;
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
if (tempi_push->ic_flags & ICF_PUSH_CMP)
tempi->ic_class=tempi->original_class;
else
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_LESS:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)<tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)<tempi2->ic_data><(I8);
} else {
tempi->ic_data=tempi1->ic_data><(double)<
tempi2->ic_data><(double);
}
tempi->ic_opcode=EC_IMM;
} else {
if (is_unsigned)
tempi->ic_flags|=ICF_USE_UNSIGNED;
if (tempi->ic_class->sub_type==IT_DOUBLE)
tempi->ic_flags|=ICF_USE_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
if (tempi_push->ic_flags & ICF_PUSH_CMP)
tempi->ic_class=tempi->original_class;
else
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_GREATER:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)>tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)>tempi2->ic_data><(I8);
} else {
tempi->ic_data=tempi1->ic_data><(double)>
tempi2->ic_data><(double);
}
tempi->ic_opcode=EC_IMM;
} else {
if (is_unsigned)
tempi->ic_flags|=ICF_USE_UNSIGNED;
if (tempi->ic_class->sub_type==IT_DOUBLE)
tempi->ic_flags|=ICF_USE_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
if (tempi_push->ic_flags & ICF_PUSH_CMP)
tempi->ic_class=tempi->original_class;
else
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_LESS_EQUAL:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)<=tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)<=tempi2->ic_data><(I8);
} else {
tempi->ic_data=tempi1->ic_data><(double)<=
tempi2->ic_data><(double);
}
tempi->ic_opcode=EC_IMM;
} else {
if (is_unsigned)
tempi->ic_flags|=ICF_USE_UNSIGNED;
if (tempi->ic_class->sub_type==IT_DOUBLE)
tempi->ic_flags|=ICF_USE_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
if (tempi_push->ic_flags & ICF_PUSH_CMP)
tempi->ic_class=tempi->original_class;
else
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_GREATER_EQUAL:
if (i=FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
if (i==FBO1_INT) {
if (is_unsigned)
tempi->ic_data=tempi1->ic_data><(U8)>=tempi2->ic_data><(U8);
else
tempi->ic_data=tempi1->ic_data><(I8)>=tempi2->ic_data><(I8);
} else {
tempi->ic_data=tempi1->ic_data><(double)>=
tempi2->ic_data><(double);
}
tempi->ic_opcode=EC_IMM;
} else {
if (is_unsigned)
tempi->ic_flags|=ICF_USE_UNSIGNED;
if (tempi->ic_class->sub_type==IT_DOUBLE)
tempi->ic_flags|=ICF_USE_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
if (tempi_push->ic_flags & ICF_PUSH_CMP)
tempi->ic_class=tempi->original_class;
else
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_AND_AND:
if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data&&tempi2->ic_data;
tempi->ic_opcode=EC_IMM;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_OR_OR:
if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data||tempi2->ic_data;
tempi->ic_opcode=EC_IMM;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_XOR_XOR:
if (FixupBinaryOp1(tempi,tempi1,tempi2,&is_unsigned)) {
tempi->ic_data=tempi1->ic_data^^tempi2->ic_data;
tempi->ic_opcode=EC_IMM;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else if (is_unsigned)
tempi_push->original_class=sys_internal_types[IT_U8];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
tempi->ic_class=sys_internal_types[IT_I8];
break;
case EC_COLON:
if (tempc2->sub_type>tempc3->sub_type)
tempi->ic_class=tempc2;
else
tempi->ic_class=tempc3;
tempc=tempi->ic_class;
if (tempc->sub_type==IT_DOUBLE) {
if (tempc2->sub_type!=IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_DOUBLE;
if (tempc3->sub_type!=IT_DOUBLE)
tempi3->ic_flags|=ICF_R_TO_DOUBLE;
}
if (!tempi_push->ic_class->ptr_cnt) {
if (tempi_push->ic_class->sub_type==IT_DOUBLE)
tempi_push->original_class=sys_internal_types[IT_DOUBLE];
else
tempi_push->original_class=sys_internal_types[IT_I8];
}
break;
case EC_MUL_EQUAL:
if (tempi2->ic_opcode==EC_IMM &&
tempc->sub_type!=IT_DOUBLE &&
tempc2->sub_type!=IT_DOUBLE) {
if (i=tempi2->ic_data) {
if (Bsf(i)==Bsr(i)) {
tempi2->ic_data=Bsf(i);
tempi->ic_opcode=EC_SHL_EQUAL;
}
}
}
if (tempc->sub_type==IT_DOUBLE) {
if (tempc2->sub_type!=IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_DOUBLE;
} else {
if (tempc2->sub_type==IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_INT;
}
break;
case EC_DIV_EQUAL:
if (tempi2->ic_opcode==EC_IMM &&
tempc->sub_type!=IT_DOUBLE &&
tempc2->sub_type!=IT_DOUBLE) {
if (i=tempi2->ic_data) {
if (Bsf(i)==Bsr(i)) {
tempi2->ic_data=Bsf(i);
tempi->ic_opcode=EC_SHR_EQUAL;
}
} else
PrsExcept(lx,"ST_DIVIDE_BY_ZERO");
}
if (tempc->sub_type==IT_DOUBLE) {
if (tempc2->sub_type!=IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_DOUBLE;
} else {
if (tempc2->sub_type==IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_INT;
}
break;
case EC_MOD_EQUAL:
if (tempi2->ic_opcode==EC_IMM &&
tempc->sub_type!=IT_DOUBLE &&
tempc2->sub_type!=IT_DOUBLE) {
if (i=tempi2->ic_data) {
if (i>0 && Bsf(i)==Bsr(i)) {
tempi2->ic_data=i-1;
tempi->ic_opcode=EC_AND_EQUAL;
}
} else
PrsExcept(lx,"ST_DIVIDE_BY_ZERO");
}
if (tempc->sub_type==IT_DOUBLE) {
if (tempc2->sub_type!=IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_DOUBLE;
} else {
if (tempc2->sub_type==IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_INT;
}
break;
case EC_ADD_EQUAL:
case EC_SUB_EQUAL:
case EC_ASSIGN:
if (tempc->sub_type==IT_DOUBLE) {
if (tempc2->sub_type!=IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_DOUBLE;
} else {
if (tempc2->sub_type==IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_INT;
}
break;
case EC_SHL_EQUAL:
case EC_SHR_EQUAL:
case EC_AND_EQUAL:
case EC_OR_EQUAL:
case EC_XOR_EQUAL:
if (tempc2->sub_type==IT_DOUBLE)
tempi2->ic_flags|=ICF_R_TO_INT;
break;
case EC_ENTER:
case EC_LEAVE:
tempi->ic_data=-fun_class->size;
break;
case EC_ADD_RSP:
if (temp_lag[1]->ic_opcode==EC_ADD_RSP) {
tempi->ic_data+=temp_lag[1]->ic_data;
tempi->ic_flags|=temp_lag[1]->ic_flags;
temp_lag[1]->ic_opcode=EC_NOP;
temp_lag[1]->ic_flags=0;
}
break;
case EC_CALL:
case EC_CALL_INDIRECT:
case EC_CALL_INDIRECT2:
case EC_CALL_EXTERN:
case EC_CLI:
case EC_STI:
case EC_WBINVD:
case EC_INVD:
case EC_ENABLE_CACHE:
case EC_DISABLE_CACHE:
case EC_GET_FLAGS:
case EC_GET_BASE_PTR:
case EC_GET_STACK_PTR:
case EC_RETURN_START:
case EC_RETURN_END:
case EC_ABSOLUTE_ADDRESS:
case EC_GET_LABEL:
case EC_TYPE:
case EC_RDTSC:
case EC_SET_FLAGS:
case EC_SET_BASE_PTR:
case EC_SET_STACK_PTR:
case EC_SET_RAX:
case EC_BSF:
case EC_BSR:
case EC_PREEMPT:
case EC_ABSI8:
case EC_REMQUE:
case EC_INPD:
case EC_INPW:
case EC_INP:
case EC_STRLEN:
case EC_BT:
case EC_BTS:
case EC_BTR:
case EC_BTC:
case EC_LBTS:
case EC_LBTR:
case EC_LBTC:
case EC_INSQUE:
case EC_INSQUE_REV:
case EC_OUTPD:
case EC_OUTPW:
case EC_OUTP:
case EC_SWITCH:
case EC_MEMCPY:
case EC_MEMSET:
break;
case EC_BR_ZERO:
if (combined)
tempi_push=OptBrZero(lx,tempi);
break;
case EC_BR_NOT_ZERO:
if (combined)
tempi_push=OptBrNotZero(lx,tempi);
break;
case EC_BR_NOT_EQUAL:
case EC_BR_EQUAL_EQUAL:
case EC_BR_GREATER_EQUAL:
case EC_BR_LESS_EQUAL:
case EC_BR_GREATER:
case EC_BR_LESS:
case EC_BR_OR_OR_NOT_ZERO:
case EC_BR_OR_OR_ZERO:
case EC_BR_AND_AND_NOT_ZERO:
case EC_BR_AND_AND_ZERO:
case EC_BR_AND_NOT_ZERO:
case EC_BR_AND_ZERO:
case EC_BR_BT:
case EC_BR_BTS:
case EC_BR_BTR:
case EC_BR_BTC:
case EC_BR_NOT_BT:
case EC_BR_NOT_BTS:
case EC_BR_NOT_BTR:
case EC_BR_NOT_BTC:
case EC_BR_LBTS:
case EC_BR_LBTR:
case EC_BR_LBTC:
case EC_BR_NOT_LBTS:
case EC_BR_NOT_LBTR:
case EC_BR_NOT_LBTC:
break;
case EC_NOP:
if (combined && tempi->ic_flags&ICF_PUSH_RESULT) {
tempii=tempi;
do tempii-=sizeof(IntermediateCode);
while (tempii->ic_opcode==EC_NOP);
tempii->ic_flags|=ICF_PUSH_RESULT;
tempi->ic_flags&=~ICF_PUSH_RESULT;
}
break;
case EC_NOP1:
ps->ptr+=tempi->ic_data<<1;
break;
case EC_LABEL:
tempii=temp_lag[1];
if (tempii->ic_opcode==EC_JMP) {
if (tempii->ic_data==tempi->ic_data) {
tempii->ic_opcode=EC_NOP;
tempi->ic_flags|=tempii->ic_flags;
}
} else if (tempii->ic_opcode==EC_LABEL) {
tempii=temp_lag[2];
if (tempii->ic_opcode==EC_JMP) {
if (tempii->ic_data==tempi->ic_data) {
tempii->ic_opcode=EC_NOP;
tempi->ic_flags|=tempii->ic_flags;
}
}
}
break;
case EC_NULL:
case EC_ADDRESS:
case EC_QUESTION:
case EC_RET:
case EC_END_EXP:
case EC_CALL_START:
case EC_CALL_END:
case EC_CALL_END2:
case EC_PUSH_REGS:
case EC_POP_REGS:
case EC_IRQ:
case EC_JMP:
break;
default:
OptMissing(lx,1,tempi);
}
if (cmp_result_cnt[tempi_push->ic_opcode]) {
PrsPush(ps,tempi->original_class);
PrsPush(ps,tempi_push);
}
if (tempi->ic_class) {
if (code!=EC_RETURN_END && code>EC_END_EXP)
last_with_class=tempi;
}
if (combined)
tempi+=sizeof(IntermediateCode);
else
tempi=CbGetIc1(&lx->cb);
}
OptEnd(lx,1,ps);
/*
This is for determining type conversions
for passing parameters to functions.
*/
return last_with_class;
}