TempleOSTS_140317.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:46:02 +02:00
1 parent 2d2a65d572
commit 7ef616a20e
1416 files changed
+223873 -53917

No files matched your search

File diff suppressed because it is too large. Load diff
+743
View File
@@ -0,0 +1,743 @@
U0 ICAddEct(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,
I64 t2,I64 r2,I64 d2,I64 t3,I64 r3,I64 d3,I64 op,I64 ip)
{
I64 i,temp,result_reg=REG_RAX;
Bool swap=FALSE;
if (r3!=result_reg) {
swap^=TRUE;
SwapU64(&t2,&t3);
SwapU64(&r2,&r3);
SwapU64(&d2,&d3);
}
if (t2&RT_MASK>=RT_I64 && r2!=result_reg &&
TY_REG<=t2&TY_MASK<=TY_RIP_DISP32) {
if (t1&TY_MASK==TY_REG && !(r2==r1 && TY_REG<=t2&TY_MASK<=TY_SIB))
result_reg=r1;
ICMov(tempi,TY_REG+RT_I64,result_reg,0,t3,r3,d3,ip);
i=ICModr1(result_reg,t2,r2,d2);
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+op);
ICModr2(tempi,i,d2,ip+4);
} else {
if (t2&TY_MASK==TY_REG)
temp=r2;
else
temp=REG_RCX;
if (t1&TY_MASK==TY_REG)
result_reg=r1;
if (temp==result_reg)
result_reg=REG_RDX;
if (swap ^^ tempi->ic_flags & ICF_A1_FIRST) {
if (r3==temp && TY_REG<=t3&TY_MASK<=TY_SIB)
temp=REG_RCX;
ICMov(tempi,TY_REG+RT_I64,temp,0,t2,r2,d2,ip);
ICMov(tempi,TY_REG+RT_I64,result_reg,0,t3,r3,d3,ip);
} else {
if (r2==result_reg && TY_REG<=t2&TY_MASK<=TY_SIB)
result_reg=REG_RDX;
ICMov(tempi,TY_REG+RT_I64,result_reg,0,t3,r3,d3,ip);
ICMov(tempi,TY_REG+RT_I64,temp,0,t2,r2,d2,ip);
}
i=0x48;
if (result_reg>7)
i+=4;
if (temp>7)
i++;
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICU24(tempi,0xC00000+i+(temp&7)<<16+(result_reg&7)<<19+op<<8);
}
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,result_reg,0,ip);
}
U0 ICAddSubEctImm(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,
I64 t2,I64 r2,I64 d2,I64 d,I64 op,I64 ip)
{
I64 i,r;
if (op.u8[0]==0x2B) {
op=0x0003;
d=-d;
}
if (t1&TY_MASK==TY_REG) {
if (t2&TY_MASK!=TY_REG) {
ICMov(tempi,t1,r1,d1,t2,r2,d2,ip);
t2=t1;
r2=r1;
d2=d1;
}
if (r1==r2) {
if (r1>7)
i=0x49;
else
i=0x48;
if (!d &&
(op.u8[0]==0x03||op.u8[0]==0x2B||
op.u8[0]==0x33||op.u8[0]==0x0B))
return;
else if (d==1 && op.u8[0]==0x03) {
ICU24(tempi,0xC0FF00+op.u8[1]<<19+i+(r1&7)<<16);
return;
} else if (d==-1 && op.u8[0]==0x03) {
ICU24(tempi,0xC8FF00+i+(r1&7)<<16);
return;
} else if (MIN_I8<=d<=MAX_I8) {
ICU24(tempi,0xC08300+op.u8[1]<<19+i+(r1&7)<<16);
ICU8(tempi,d);
return;
} else if (MIN_I32<=d<=MAX_I32) {
ICU24(tempi,0xC08100+op.u8[1]<<19+i+(r1&7)<<16);
ICU32(tempi,d);
return;
}
}
if (op.u8[0]==0x03 && MIN_I32<=d<=MAX_I32 &&
!Bt(&non_ptr_vars_mask,r2)) {
i=ICModr1(r1,TY_DISP+RT_I64,r2,d);
i.u8[1]|=0x48;
ICU24(tempi,i.u8[2]<<16+0x8D00+i.u8[1]);
ICModr2(tempi,i,d,ip+4);
return;
}
}
switch (t1>>4) {
case TY_REG>>4:
case TY_DISP>>4:
case TY_SIB>>4:
case TY_RIP_DISP32>>4:
if (t1!=t2 || r1!=r2 || d1!=d2) {
ICMov(tempi,t1,r1,d1,t2,r2,d2,ip);
t2=t1;
r2=r1;
d2=d1;
}
if (!d &&
(op.u8[0]==0x03||op.u8[0]==0x2B||
op.u8[0]==0x33||op.u8[0]==0x0B))
return;
r=op.u8[1]; //not a reg but a slash val
if (op.u8[0]==0x03 && d==-1) //add -1
r=1; //Decrement slash val
if (op.u8[0]==0x03 && (d==1 || d==-1)) { //Add
i=ICModr1(r,t1,r1,d1);
if (t1!=TY_REG && tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
switch (t1&RT_MASK) {
case RT_I8:
case RT_U8:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xFE);
break;
case RT_I16:
case RT_U16:
ICOpSizeRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xFF);
break;
default:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xFF);
}
ICModr2(tempi,i,d1,ip+4);
return;
}
if (MIN_I8<=d<=MAX_I8 ||
t1&(RT_MASK-1)==RT_I8) {
i=ICModr1(r,t1,r1,d1);
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
switch (t1&RT_MASK) {
case RT_I8:
case RT_U8:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x80);
break;
case RT_I16:
case RT_U16:
ICOpSizeRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x83);
break;
default:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x83);
}
ICModr2(tempi,i,d1,ip+5);
ICU8(tempi,d);
return;
}
if (MIN_I32<=d<=MAX_I32 ||
t1&RT_MASK<RT_I64) {
i=ICModr1(r,t1,r1,d1);
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
switch (t1&RT_MASK) {
case RT_I16:
case RT_U16:
ICOpSizeRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x81);
break;
default:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x81);
}
if (i.u8[0]!=MDR_RIP_REL)
ICModr2(tempi,i,d1,);
else {
if (t1&(RT_MASK-1)==RT_I16)
ICU32(tempi,d1-(ip+tempi->ic_cnt+6));
else
ICU32(tempi,d1-(ip+tempi->ic_cnt+8));
tempi->ic_flags&=~ICF_CODE_FINAL;
}
if (t1&(RT_MASK-1)==RT_I16)
ICU16(tempi,d);
else
ICU32(tempi,d);
return;
}
break;
case TY_STK>>4:
ICAddSubEctImm(tempi,TY_REG+RT_I64,REG_RAX,0,t2,r2,d2,d,op,ip);
ICPushRegs(tempi,1<<REG_RAX);
return;
}
ICAddEct(tempi,t1,r1,d1,TY_IMM+RT_I64,0,d,t2,r2,d2,op.u8[0],ip);
}
U0 ICSub(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,
I64 t2,I64 r2,I64 d2,I64 t3,I64 r3,I64 d3,I64 ip)
{
I64 i=0x48,op=0x2B;
Bool swap=FALSE;
if (r3!=REG_RAX) {
swap=TRUE;
SwapU64(&t2,&t3);
SwapU64(&r2,&r3);
SwapU64(&d2,&d3);
}
if (t2&RT_MASK>=RT_I64 && r2.u8[0]!=REG_RAX && (t2&TY_MASK!=TY_SIB || r2.u8[1]&15!=REG_RAX) &&
TY_REG<=t2&TY_MASK<=TY_RIP_DISP32) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
if (!swap) {
op=0x03;
ICU24(tempi,0xD8F748);
}
i=ICModr1(REG_RAX,t2,r2,d2);
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+op);
ICModr2(tempi,i,d2,ip+4);
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,REG_RAX,0,ip);
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
if (t3&TY_MASK!=TY_REG || t3&RT_MASK<RT_I64) {
if (swap) {
swap=FALSE;
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
r3=REG_RCX;
r2=REG_RAX;
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
r2=REG_RCX;
r3=REG_RAX;
}
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
r2=REG_RCX;
}
} else {
if (t3&TY_MASK!=TY_REG || t3&RT_MASK<RT_I64) {
if (swap) {
swap=FALSE;
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
r2=REG_RAX;
r3=REG_RCX;
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
r3=REG_RAX;
r2=REG_RCX;
}
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
r2=REG_RCX;
}
}
if (swap) {
op=0x03;
ICU24(tempi,0xD9F748);
}
if (r3>7)
i++;
if (r2>7)
i+=4;
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICU24(tempi,0xC00000+i+(r3&7)<<16+(r2&7)<<19+op<<8);
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,r2,0,ip);
}
}
U0 ICMul(CIntermediateCode *tempi,I64 ip)
{
I64 i,r2,r=REG_RAX,j;
CICArg *a1,*a2;
if (tempi->a1.type&TY_MASK==TY_IMM) {
a1=&tempi->a2;
a2=&tempi->a1;
tempi->ic_flags|=ICF_A1_FIRST;
} else {
a1=&tempi->a1;
a2=&tempi->a2;
}
i=a2->disp;
if (!(tempi->ic_class->raw_type&1) &&
a2->type&TY_MASK==TY_IMM && MIN_I32<=i<=MAX_I32) {
if (tempi->r.type==TY_REG+RT_I64) {
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,a1->type,a1->reg,a1->disp,ip);
r=tempi->r.reg;
} else
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a1->type,a1->reg,a1->disp,ip);
if (r>7)
j=0xC0004D;
else
j=0xC00048;
if (MIN_I8<=i<=MAX_I8)
ICU32(tempi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
else {
ICU24(tempi,0x6900+j+(r&7)<<16+(r&7)<<19);
ICU32(tempi,i);
}
} else {
if (tempi->ic_class->raw_type&1)
i=0xE0F748;
else
i=0xE8F748;
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
r2=REG_RCX;
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a2->type,a2->reg,a2->disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a2->type,a2->reg,a2->disp,ip);
if (a1->type&TY_MASK!=TY_REG ||
a1->type&RT_MASK<RT_I64) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
r2=REG_RCX;
} else
r2=a1->reg;
}
if (r2>7) {
i++;
r2&=7;
}
ICU24(tempi,i+r2<<16);
}
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,r,0,ip);
}
U0 ICMulEqual(CIntermediateCode *tempi,I64 ip)
{
I64 i=tempi->a2.disp,r=REG_RAX,j;
if (!(tempi->ic_class->raw_type&1) &&
tempi->a2.type&TY_MASK==TY_IMM && MIN_I32<=i<=MAX_I32) {
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->a1.type==TY_REG+RT_I64)
r=tempi->a1.reg;
else
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
if (r>7)
j=0xC0004D;
else
j=0xC00048;
if (MIN_I8<=i<=MAX_I8)
ICU32(tempi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
else {
ICU24(tempi,0x6900+j+(r&7)<<16+(r&7)<<19);
ICU32(tempi,i);
}
ICMov(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,r,0,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,TY_DISP+tempi->a1.type_pointed,REG_RCX,0,ip);
r=REG_RBX;
if (MIN_I8<=i<=MAX_I8)
ICU32(tempi,i<<24+0xDB6B48);
else {
ICU24(tempi,0xDB6948);
ICU32(tempi,i);
}
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,REG_RCX,0,TY_REG+RT_I64,REG_RBX,0,ip);
}
} else {
if (tempi->ic_class->raw_type&1)
i=0xE3F748;
else
i=0xEBF748;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
}
ICU24(tempi,i);
ICMov(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
}
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,TY_DISP+tempi->a1.type_pointed,REG_RCX,0,ip);
ICU24(tempi,i);
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,REG_RCX,0,TY_REG+RT_I64,REG_RAX,0,ip);
}
}
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,r,0,ip);
}
U0 ICDiv(CIntermediateCode *tempi,I64 ip)
{
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
}
if (tempi->ic_class->raw_type&1) {
ICZero(tempi,REG_RDX);
ICU24(tempi,0xF1F748);
} else {
ICU16(tempi,0x9948);
ICU24(tempi,0xF9F748);
}
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICDivEqual(CIntermediateCode *tempi,Bool is_mod,I64 ip)
{
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
}
if (tempi->ic_class->raw_type&1) {
ICZero(tempi,REG_RDX);
ICU24(tempi,0xF1F748);
} else {
ICU16(tempi,0x9948);
ICU24(tempi,0xF9F748);
}
if (is_mod)
ICMov(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,REG_RDX,0,ip);
else
ICMov(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICU24(tempi,0xD98748); //xchg bx,cx
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
}
//dangerous might clobber RBX in Mov, but it doesn't
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,TY_DISP+tempi->a1.type_pointed,REG_RBX,0,ip);
if (tempi->ic_class->raw_type&1) {
ICZero(tempi,REG_RDX);
ICU24(tempi,0xF1F748);
} else {
ICU16(tempi,0x9948);
ICU24(tempi,0xF9F748);
}
if (is_mod)
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,REG_RBX,0,TY_REG+RT_I64,REG_RDX,0,ip);
else
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,REG_RBX,0,TY_REG+RT_I64,REG_RAX,0,ip);
}
if (tempi->r.type&TY_MASK) {
if (is_mod)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RDX,0,ip);
else
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RAX,0,ip);
}
}
U0 ICMod(CIntermediateCode *tempi,I64 ip)
{
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
}
if (tempi->ic_class->raw_type&1) {
ICZero(tempi,REG_RDX);
ICU24(tempi,0xF1F748);
} else {
ICU16(tempi,0x9948);
ICU24(tempi,0xF9F748);
}
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RDX,0,ip);
}
U0 ICAddSubEctEqual(CIntermediateCode *tempi,I64 type_pointed,I64 t1,I64 r1,I64 d1,
I64 t2,I64 r2,I64 d2,I64 t3,I64 r3,I64 d3,I64 op,I64 ip)
{
Bool done;
I64 result_reg,temp,i;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (t3&TY_MASK==TY_IMM) {
ICAddSubEctImm(tempi,
t2&TY_MASK+type_pointed,r2,d2,t2&TY_MASK+type_pointed,r2,d2,d3,op,ip);
if (t1&TY_MASK)
ICMov(tempi,t1,r1,d1,t2&TY_MASK+type_pointed,r2,d2,ip);
return;
} else {
done=FALSE;
if (type_pointed>=RT_I64) {
if (!(t1&TY_MASK) &&
TY_REG<=t2&TY_MASK<=TY_RIP_DISP32) {
if (t3&TY_MASK==TY_REG)
temp=r3;
else {
temp=REG_RCX;
ICMov(tempi,TY_REG+RT_I64,temp,0,t3,r3,d3,ip);
}
i=ICModr1(temp,t2&TY_MASK+type_pointed,r2,d2);
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+op.u8[5]);
ICModr2(tempi,i,d2,ip+4);
return;
}
if (t3&RT_MASK>=RT_I64 &&
TY_REG<=t3&TY_MASK<=TY_RIP_DISP32) {
if (t2&TY_MASK==TY_REG)
result_reg=r2;
else {
result_reg=REG_RCX;
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
}
i=ICModr1(result_reg,t3&TY_MASK+type_pointed,r3,d3);
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+op.u8[0]);
ICModr2(tempi,i,d3,ip+4);
ICMov(tempi,t2&TY_MASK+type_pointed,r2,d2,TY_REG+RT_I64,result_reg,0,ip);
done=TRUE;
}
}
if (!done) {
if (tempi->ic_flags & ICF_A1_FIRST) {
if (t2&TY_MASK==TY_REG && r2!=REG_RAX)
result_reg=r2;
else {
result_reg=REG_RCX;
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2&TY_MASK+type_pointed,r2,d2,ip);
}
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
if (t2&TY_MASK==TY_REG && r2!=REG_RAX)
result_reg=r2;
else {
result_reg=REG_RCX;
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2&TY_MASK+type_pointed,r2,d2,ip);
}
}
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
if (result_reg>7)
ICU8(tempi,0x4C);
else
ICU8(tempi,0x48);
ICU16(tempi,0xC000+op.u8[0]+(result_reg&7)<<11);
ICMov(tempi,t2&TY_MASK+type_pointed,r2,d2,TY_REG+RT_I64,result_reg,0,ip);
}
}
} else {
done=FALSE;
if (t3&TY_MASK==TY_IMM && op.u8[2]) {
if (!d3.u32[1]) {
if (tempi->ic_flags&ICF_NO_DEPEND_RESULT &&
t2&TY_MASK==TY_REG && d3(U64)<=MAX_I8) {
ICSlashOp(tempi,TY_DISP+type_pointed,r2,0,0x838000+op.u8[4],ip);
ICU8(tempi,d3);
done=TRUE;
} else if (op.u8[2]==0x24) { //AND
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,TY_DISP+type_pointed,REG_RCX,0,ip);
result_reg=REG_RAX;
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICU16(tempi,op.u8[3]<<8+0x40);
ICU32(tempi,d3);
ICMov(tempi,TY_DISP+type_pointed,REG_RCX,0,TY_REG+RT_I64,result_reg,0,ip);
done=TRUE;
} else if (type_pointed&RT_MASK<RT_I64) { //OR/XOR
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,TY_DISP+type_pointed,REG_RCX,0,ip);
result_reg=REG_RAX;
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
if (d3.u16[1]) {
ICU16(tempi,op.u8[3]<<8+0x40);
ICU32(tempi,d3);
} else if (d3.u8[1]) {
ICU24(tempi,op.u8[3]<<16+0x4000+OC_OP_SIZE_PREFIX);
ICU16(tempi,d3);
} else {
ICU16(tempi,op.u8[2]<<8+0x40);
ICU8(tempi,d3);
}
ICMov(tempi,TY_DISP+type_pointed,REG_RCX,0,TY_REG+RT_I64,result_reg,0,ip);
done=TRUE;
}
}
}
if (!done) {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t3,r3,d3,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
}
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,TY_DISP+type_pointed,REG_RCX,0,ip);
result_reg=REG_RBX;
if (tempi->ic_flags&ICF_LOCK)
ICU8(tempi,OC_LOCK_PREFIX);
ICU8(tempi,0x48);
ICU16(tempi,0xC000+op.u8[0]+(result_reg&7)<<11);
ICMov(tempi,TY_DISP+type_pointed,REG_RCX,0,TY_REG+RT_I64,result_reg,0,ip);
}
}
if (t1&TY_MASK)
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,result_reg,0,ip);
}
U0 ICShift(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,
I64 t2,I64 r2,I64 d2,I64 t3,I64 r3,I64 d3,I64 us,I64 is,I64 ip)
{
I64 i=0x48,result_reg;
if (tempi->ic_class->raw_type&1 || tempi->ic_flags & ICF_USE_UNSIGNED)
is=us;
if (t1&TY_MASK==TY_REG) {
result_reg=r1;
if (result_reg>7)
i++;
} else
result_reg=REG_RAX;
if (t3&TY_MASK==TY_IMM) {
ICMov(tempi,TY_REG+RT_I64,result_reg,0,t2,r2,d2,ip);
if (d3==1)
ICU24(tempi,i+is.u16[2]<<8+(result_reg&7)<<16);
else {
ICU24(tempi,i+is.u16[0]<<8+(result_reg&7)<<16);
ICU8(tempi,d3);
}
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,result_reg,0,t2,r2,d2,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t3,r3,d3,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t3,r3,d3,ip);
ICMov(tempi,TY_REG+RT_I64,result_reg,0,t2,r2,d2,ip);
}
ICU24(tempi,i+is.u16[1]<<8+(result_reg&7)<<16);
}
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,result_reg,0,ip);
}
U0 ICShiftEqual(CIntermediateCode *tempi,I64 type_pointed,I64 t1,I64 r1,I64 d1,
I64 t2,I64 r2,I64 d2,I64 t3,I64 r3,I64 d3,I64 us,I64 is,I64 ip)
{
I64 result_reg;
if (tempi->ic_class->raw_type&1 || tempi->ic_flags & ICF_USE_UNSIGNED)
is=us;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->ic_flags & ICF_A1_FIRST) {
if (t2&TY_MASK==TY_REG)
result_reg=r2;
else {
result_reg=REG_RAX;
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t2&TY_MASK+type_pointed,r2,d2,ip);
}
if (t3&TY_MASK!=TY_IMM)
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t3,r3,d3,ip);
} else {
if (t3&TY_MASK!=TY_IMM)
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t3,r3,d3,ip);
if (t2&TY_MASK==TY_REG)
result_reg=r2;
else {
result_reg=REG_RAX;
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,t2&TY_MASK+type_pointed,r2,d2,ip);
}
}
if (result_reg>7)
ICU8(tempi,0x49);
else
ICU8(tempi,0x48);
if (t3&TY_MASK==TY_IMM) {
if (d3==1)
ICU16(tempi,is.u16[2]+(result_reg&7)<<8);
else {
ICU16(tempi,is.u16[0]+(result_reg&7)<<8);
ICU8(tempi,d3);
}
} else
ICU16(tempi,is.u16[1]+(result_reg&7)<<8);
ICMov(tempi,t2&TY_MASK+type_pointed,r2,d2,TY_REG+RT_I64,result_reg,0,ip);
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,t2,r2,d2,ip);
if (t3&TY_MASK!=TY_IMM)
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t3,r3,d3,ip);
} else {
if (t3&TY_MASK!=TY_IMM)
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t3,r3,d3,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,t2,r2,d2,ip);
}
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,TY_DISP+type_pointed,REG_RDX,0,ip);
result_reg=REG_RAX;
ICU8(tempi,0x48);
if (t3&TY_MASK==TY_IMM) {
if (d3==1)
ICU16(tempi,is.u16[2]+(result_reg&7)<<8);
else {
ICU16(tempi,is.u16[0]+(result_reg&7)<<8);
ICU8(tempi,d3);
}
} else
ICU16(tempi,is.u16[1]+(result_reg&7)<<8);
ICMov(tempi,TY_DISP+type_pointed,REG_RDX,0,TY_REG+RT_I64,result_reg,0,ip);
}
if (t1&TY_MASK)
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,result_reg,0,ip);
}
+836
View File
@@ -0,0 +1,836 @@
U0 ICUnaries(CIntermediateCode *tempi,I64 op,I64 ip)
{
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICSlashOp(tempi,TY_REG+RT_I64,REG_RAX,0,op,ip);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICNot(CIntermediateCode *tempi,I64 ip)
{
I64 i;
if (tempi->a1.type&RT_MASK<=RT_U8 &&
TY_DISP<=tempi->a1.type&TY_MASK<=TY_RIP_DISP32) {
i=ICModr1(tempi,tempi->a1.type,tempi->a1.reg,tempi->a1.disp);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xF6); //TEST ?,0xFF
ICModr2(tempi,i,tempi->a1.disp,ip+5);
ICU8(tempi,0xFF);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICTest(tempi,REG_RAX);
}
ICU24(tempi,0xC0940F); //SETZ AL
ICU32(tempi,0xC0B60F48); //MOVZX RAX,AL
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_U64,REG_RAX,0,ip);
}
U0 ICAndAnd(CIntermediateCode *tempi,I64 ip)
{
I64 r2;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->a1.type&TY_MASK!=TY_REG ||
tempi->a1.reg==REG_RAX) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r2=REG_RDX;
} else
r2=tempi->a1.reg;
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->a1.type&TY_MASK!=TY_REG ||
tempi->a1.reg==REG_RAX) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r2=REG_RDX;
} else
r2=tempi->a1.reg;
}
ICZero(tempi,REG_RAX);
ICTest(tempi,r2);
ICU16(tempi,0x0874);
ICTest(tempi,REG_RCX);
ICU16(tempi,0x0374);
ICU24(tempi,0xC0FF48);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICOrOr(CIntermediateCode *tempi,I64 ip)
{
I64 i=0x48,r2;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->a1.type&TY_MASK!=TY_REG ||
tempi->a1.reg==REG_RAX) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r2=REG_RDX;
} else
r2=tempi->a1.reg;
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->a1.type&TY_MASK!=TY_REG ||
tempi->a1.reg==REG_RAX) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r2=REG_RDX;
} else
r2=tempi->a1.reg;
}
if (r2>7) {
i++;
r2&=7;
}
ICZero(tempi,REG_RAX);
ICU24(tempi,0xC80B00+i+r2<<16);
ICU16(tempi,0x0374);
ICU24(tempi,0xC0FF48);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICXorXor(CIntermediateCode *tempi,I64 ip)
{
I64 r2;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->a1.type&TY_MASK!=TY_REG) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r2=REG_RDX;
} else
r2=tempi->a1.reg;
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->a1.type&TY_MASK!=TY_REG) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r2=REG_RDX;
} else
r2=tempi->a1.reg;
}
ICZero(tempi,REG_RBX);
ICTest(tempi,r2);
ICU16(tempi,0x0374);
ICU24(tempi,0xC3FF48);
ICZero(tempi,REG_RAX);
ICTest(tempi,REG_RCX);
ICU16(tempi,0x0374);
ICU24(tempi,0xC0FF48);
ICU24(tempi,0xC33348);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICCmp(CIntermediateCode *tempi,I64 us,I64 is,I64 ip)
{
I64 r1,d1,r2,i=0x48,j=tempi->a2.disp;
if (tempi->a2.type&TY_MASK==TY_IMM && MIN_I32<=j<=MAX_I32) {
if (!(tempi->ic_flags&(ICF_POP_CMP|ICF_PUSH_CMP)) &&
tempi->a1.type&TY_MASK==TY_DISP && //TODO
tempi->a1.type&RT_MASK>=RT_I64 && tempi->a1.reg!=REG_RAX) {
r1=tempi->a1.reg;
d1=tempi->a1.disp;
ICZero(tempi,REG_RAX);
if (r1>7)
i++;
if (MIN_I8<=j<=MAX_I8)
i+=0x388300;
else
i+=0x388100;
if (!d1) {
ICU24(tempi,0x000000+i+(r1&7)<<16);
} else if (MIN_I8<=d1<=MAX_I8) {
ICU24(tempi,0x400000+i+(r1&7)<<16);
ICU8(tempi,d1);
} else {
ICU24(tempi,0x800000+i+(r1&7)<<16);
ICU32(tempi,d1);
}
if (MIN_I8<=j<=MAX_I8)
ICU8(tempi,j);
else
ICU32(tempi,j);
} else {
if (tempi->ic_flags & ICF_POP_CMP) {
ICPopRegs(tempi,1<<REG_RCX);
r1=REG_RCX;
} else {
if (tempi->a1.type&TY_MASK==TY_REG &&
tempi->a1.reg!=REG_RAX)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r1=REG_RCX;
}
}
ICZero(tempi,REG_RAX);
if (r1>7)
i++;
if (MIN_I8<=j<=MAX_I8) {
ICU24(tempi,0xF88300+i+(r1&7)<<16);
ICU8(tempi,j);
} else {
ICU24(tempi,0xF88100+i+(r1&7)<<16);
ICU32(tempi,j);
}
}
if (tempi->ic_flags & ICF_PUSH_CMP)
ICPush(tempi,TY_IMM+RT_I64,0,j,ip);
if (tempi->ic_class->raw_type&1 || tempi->ic_flags & ICF_USE_UNSIGNED)
is=us;
ICU16(tempi,0x300+is);
ICU24(tempi,0xC0FF48);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->ic_flags & ICF_POP_CMP) {
ICPopRegs(tempi,1<<REG_RCX);
r1=REG_RCX;
} else {
if (tempi->a1.type&TY_MASK==TY_REG &&
tempi->a1.reg!=REG_RAX)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r1=REG_RCX;
}
}
if (tempi->a2.type&TY_MASK==TY_REG &&
tempi->a2.reg!=REG_RAX)
r2=tempi->a2.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
r2=REG_RDX;
}
} else {
if (tempi->a2.type&TY_MASK==TY_REG &&
tempi->a2.reg!=REG_RAX)
r2=tempi->a2.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
r2=REG_RCX;
}
if (tempi->ic_flags & ICF_POP_CMP) {
ICPopRegs(tempi,1<<REG_RDX);
r1=REG_RDX;
} else {
if (tempi->a1.type&TY_MASK==TY_REG &&
tempi->a1.reg!=REG_RAX)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r1=REG_RDX;
}
}
}
ICZero(tempi,REG_RAX);
if (r2>7)
i++;
if (r1>7)
i+=4;
if (tempi->ic_flags & ICF_PUSH_CMP)
ICPushRegs(tempi,1<<r2);
ICU24(tempi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
if (tempi->ic_class->raw_type&1 || tempi->ic_flags & ICF_USE_UNSIGNED)
is=us;
ICU16(tempi,0x300+is);
ICU24(tempi,0xC0FF48);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
}
U0 ICBitOps(CIntermediateCode *tempi,CICArg *a1,CICArg *a2,CIntermediateCode *tempi2,
I64 op,I64 op_imm,I64 ip)
{ //TODO:not fully utilizing Modr
Bool no_depend=ToBool(tempi2->ic_flags&ICF_NO_DEPEND_RESULT);
I64 r1,t2,r2,d2,i=0x48;
if (tempi->ic_flags & ICF_NOT_ADDR) {
t2=a2->type&TY_MASK+RT_I64; //TODO: check overflow
r2=a2->reg;
d2=a2->disp;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (a1->type&TY_MASK==TY_REG &&
(a1->reg!=REG_RAX||no_depend))
r1=a1->reg;
else if (a1->type&TY_MASK!=TY_IMM || a1->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
r1=REG_RCX;
} else
r1=0;
if (!(TY_REG<=t2&TY_MASK<=TY_RIP_DISP32) ||
!(r2.u8[0]!=REG_RAX&&(t2&TY_MASK!=TY_SIB||r2.u8[1]&15!=REG_RAX)||no_depend)) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,t2,r2,d2,ip);
t2=TY_REG+RT_I64;
r2=REG_RDX;
d2=0;
}
} else {
if (!(TY_REG<=t2&TY_MASK<=TY_RIP_DISP32) ||
!(r2.u8[0]!=REG_RAX&&(t2&TY_MASK!=TY_SIB||r2.u8[1]&15!=REG_RAX)||no_depend)) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,ip);
t2=TY_REG+RT_I64;
r2=REG_RCX;
d2=0;
}
if (a1->type&TY_MASK==TY_REG &&
(a1->reg!=REG_RAX||no_depend))
r1=a1->reg;
else if (a1->type&TY_MASK!=TY_IMM || a1->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a1->type,a1->reg,a1->disp,ip);
r1=REG_RDX;
} else
r1=0;
}
} else {
t2=TY_DISP+RT_I64;
d2=0;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (a1->type&TY_MASK==TY_REG &&
(a1->reg!=REG_RAX||no_depend))
r1=a1->reg;
else if (a1->type&TY_MASK!=TY_IMM || a1->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
r1=REG_RCX;
} else
r1=0;
if (a2->type&TY_MASK==TY_REG &&
(a2->reg!=REG_RAX||no_depend))
r2=a2->reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a2->type,a2->reg,a2->disp,ip);
r2=REG_RDX;
}
} else {
if (a2->type&TY_MASK==TY_REG &&
(a2->reg!=REG_RAX||no_depend))
r2=a2->reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a2->type,a2->reg,a2->disp,ip);
r2=REG_RCX;
}
if (a1->type&TY_MASK==TY_REG &&
(a1->reg!=REG_RAX||no_depend))
r1=a1->reg;
else if (a1->type&TY_MASK!=TY_IMM || a1->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a1->type,a1->reg,a1->disp,ip);
r1=REG_RDX;
} else
r1=0;
}
}
if (!no_depend)
ICZero(tempi,REG_RAX);
if (tempi->ic_flags&ICF_LOCK) {
if (op!=0xA30F)
ICU8(tempi,OC_LOCK_PREFIX);
}
if (a1->type&TY_MASK==TY_IMM && a1->disp<32)
t2=t2&TY_MASK+RT_U32;
i=ICModr1(r1,t2,r2,d2);
ICRex(tempi,i.u8[1]);
if (a1->type&TY_MASK==TY_IMM && a1->disp<64) {
ICU24(tempi,i.u8[2]<<16+op_imm);
ICModr2(tempi,i,d2,ip+5);
ICU8(tempi,a1->disp);
} else {
ICU24(tempi,i.u8[2]<<16+op);
ICModr2(tempi,i,d2,ip+4);
}
if (!no_depend) {
ICU32(tempi,0xD08348);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,REG_RAX,0,ip);
}
}
U0 ICPreempt(CIntermediateCode *tempi,I64 ip)
{
CIntermediateCode *tempi2=tempi->next;
if (tempi->a1.type&TY_MASK==TY_IMM) {
ICZero(tempi,REG_RBX);
ICU32(tempi,0x1B8B4864);
if (!(tempi2->ic_flags&ICF_NO_DEPEND_RESULT))
ICZero(tempi,REG_RAX);
if (tempi->a1.disp)
ICU24(tempi,0x6BBA0F);
else
ICU24(tempi,0x73BA0F);
ICU16(tempi,CTask.task_flags+TASKf_PREEMPT<<8);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
if (!(tempi2->ic_flags&ICF_NO_DEPEND_RESULT))
ICZero(tempi,REG_RAX);
ICZero(tempi,REG_RBX);
ICU32(tempi,0x1B8B4864);
ICTest(tempi,REG_RCX);
ICU16(tempi,0x0774);
ICU24(tempi,0x6BBA0F);
ICU16(tempi,CTask.task_flags+TASKf_PREEMPT<<8);
ICU16(tempi,0x05EB);
ICU24(tempi,0x73BA0F);
ICU16(tempi,CTask.task_flags+TASKf_PREEMPT<<8);
}
if (!(tempi2->ic_flags&ICF_NO_DEPEND_RESULT))
ICU32(tempi,0xD08348);
}
U0 ICToUpper(CIntermediateCode *tempi,I64 ip)
{
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICU32(tempi,0x61F88348);
ICU16(tempi,0x0A7C);
ICU32(tempi,0x7AF88348);
ICU16(tempi,0x047F);
ICU32(tempi,0xE0C08348);
}
U0 ICToI64(CLex *lx,CIntermediateCode *tempi,I64 ip)
{
ICFCvt(lx,tempi,REG_RAX,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,TRUE,CN_MAIN,ip);
}
U0 ICToF64(CLex *lx,CIntermediateCode *tempi,I64 ip)
{
ICFCvt(lx,tempi,REG_RAX,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,FALSE,CN_MAIN,ip);
}
U0 ICToBool(CLex *,CIntermediateCode *tempi,I64 ip)
{
I64 r;
if (tempi->a1.type&TY_MASK==TY_REG)
r=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r=REG_RAX;
}
ICTest(tempi,r);
ICU24(tempi,0xC0950F); //SETNZ AL
ICU32(tempi,0xC0B60F48); //MOVZX RAX,AL
}
U0 ICPreIncDec(CIntermediateCode *tempi,I64 op,I64 ip)
{
I64 r;
CHashClass *tempc=tempi->ic_class,*tempc1=tempc-1;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempc->ptr_cnt && tempc1->size!=1) {
ICAddSubEctImm(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,op,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
} else {
if (tempi->a1.type&TY_MASK==TY_REG)
r=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r=REG_RCX;
}
if (tempc->ptr_cnt &&
tempc1->size!=1) {
ICAddSubEctImm(tempi,TY_DISP+tempi->a1.type_pointed,r,0,
TY_DISP+tempi->a1.type_pointed,r,0,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,
TY_DISP+tempi->a1.type_pointed,r,0,op,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_DISP+tempi->a1.type_pointed,r,0,ip);
}
}
U0 ICPostIncDec(CIntermediateCode *tempi,I64 op,I64 ip)
{
I64 r;
CHashClass *tempc=tempi->ic_class,*tempc1=tempc-1;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->r.type&TY_MASK) {
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
}
if (tempc->ptr_cnt &&
tempc1->size!=1) {
ICAddSubEctImm(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,op,ip);
} else {
if (tempi->a1.type&TY_MASK==TY_REG &&
!(tempi->r.type&TY_MASK==TY_REG && tempi->r.reg==tempi->a1.reg))
r=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
r=REG_RCX;
}
if (tempi->r.type&TY_MASK) {
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_DISP+tempi->a1.type_pointed,r,0,ip);
}
if (tempc->ptr_cnt &&
tempc1->size!=1) {
ICAddSubEctImm(tempi,TY_DISP+tempi->a1.type_pointed,r,0,
TY_DISP+tempi->a1.type_pointed,r,0,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,
TY_DISP+tempi->a1.type_pointed,r,0,op,ip);
}
}
U0 ICDerefPostIncDec(CIntermediateCode *tempi,I64 op,I64 ip)
{
I64 t,r;
CHashClass *tempc1=tempi->ic_class;
t=tempi->r.type&RT_MASK;
if (t>tempi->a1.type_pointed)
t=tempi->a1.type_pointed;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->a1.type&TY_MASK==TY_REG)
r=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,ip);
r=REG_RDX;
}
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_DISP+t,r,0,ip);
if (tempc1->size!=1) {
ICAddSubEctImm(tempi,tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,
tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,
tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,op,ip);
} else {
if (tempi->a1.type&TY_MASK==TY_REG)
r=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,ip);
r=REG_RCX;
}
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
TY_DISP+RT_I64,r,0,ip);
if (tempc1->size!=1) {
ICAddSubEctImm(tempi,TY_DISP+RT_I64,r,0,
TY_DISP+RT_I64,r,0,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,TY_DISP+RT_I64,r,0,op,ip);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_DISP+t,REG_RDX,0,ip);
}
}
U0 ICAssignPostIncDec(CIntermediateCode *tempi,I64 op,I64 ip)
{
CHashClass *tempc1=tempi->ic_class2-1;
I64 r;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->a1.type&TY_MASK==TY_REG)
r=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,ip);
r=REG_RDX;
}
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,r,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempc1->size!=1 || tempi->a1.type&TY_MASK==TY_STK) {
ICAddSubEctImm(tempi,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,r,0,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,op,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
TY_DISP+RT_I64,REG_RDX,0,ip);
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,REG_RCX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempc1->size!=1) {
ICAddSubEctImm(tempi,TY_DISP+RT_I64,REG_RDX,0,
TY_REG+RT_I64,REG_RCX,0,
tempc1->size,op.u16[3],ip);
} else
ICSlashOp(tempi,TY_DISP+RT_I64,REG_RDX,0,op,ip);
}
}
U0 ICCmpAndBranch(CIntermediateCode *tempi,Bool has_result,I64 ip,
I64 us,I64 is,I64 not_us,I64 not_is,
U8 *buf,I64 ip2)
{
I64 r1,r2,i=0x48,j,t1,t2,result_reg;
Bool short_jmp,done;
CLexCodeMisc *lb;
CICArg *a1=&tempi->a1,*a2=&tempi->a2,*swap;
j=a1->disp;
if (a1->type&TY_MASK==TY_IMM && MIN_I32<=j<=MAX_I32) {
swap=a1; a1=a2; a2=swap;
us=not_us;
is=not_is;
}
if (tempi->ic_class->raw_type&1 || tempi->ic_flags & ICF_USE_UNSIGNED)
is=us;
j=a2->disp;
if (a2->type&TY_MASK==TY_IMM && MIN_I32<=j<=MAX_I32) {
if (!has_result && TY_REG<=a1->type&TY_MASK<=TY_RIP_DISP32)
ICAddSubEctImm(tempi,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
j,0x073B,ip2);
else {
if (a1->type&TY_MASK==TY_REG)
r1=a1->reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a1->type,a1->reg,a1->disp,ip2);
r1=REG_RDX;
}
if (!j) {
if (is.u8[2]==0x7C) {
ICTest(tempi,r1);
is=0x78880F;
} else if (is.u8[2]==0x7D) {
ICTest(tempi,r1);
is=0x79890F;
} else if (is.u8[2]==0x74 || is.u8[2]==0x75)
ICTest(tempi,r1);
else {
if (r1>7)
i++;
ICU24(tempi,0xF88300+i+(r1&7)<<16);
ICU8(tempi,j);
}
} else {
if (r1>7)
i++;
if (MIN_I8<=j<=MAX_I8) {
ICU24(tempi,0xF88300+i+(r1&7)<<16);
ICU8(tempi,j);
} else {
ICU24(tempi,0xF88100+i+(r1&7)<<16);
ICU32(tempi,j);
}
}
}
if (has_result) {
if (!swap) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,TY_IMM+RT_I64,0,j,ip2);
result_reg=REG_RCX;
} else
result_reg=r1;
}
} else {
done=FALSE;
t1=a1->type;
r1=a1->reg;
r2=a2->reg;
t2=a2->type;
if (t2&RT_MASK>=RT_I64 && !has_result &&
TY_DISP<=t2&TY_MASK<=TY_RIP_DISP32) {
if (t1&TY_MASK!=TY_REG || t1&RT_MASK<RT_I64) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a1->type,a1->reg,a1->disp,ip2);
r1=REG_RAX;
}
i=ICModr1(r1,t2,r2,a2->disp);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x3B);
ICModr2(tempi,i,a2->disp,ip2+4);
done=TRUE;
} else if (t1&RT_MASK>=RT_I64 &&
TY_REG<=t1&TY_MASK<=TY_RIP_DISP32) {
if (t2&TY_MASK!=TY_REG || t2&RT_MASK<RT_I64) {
if (t1&TY_MASK==TY_REG && r1==REG_RAX) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a2->type,a2->reg,a2->disp,ip2);
r2=REG_RCX;
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a2->type,a2->reg,a2->disp,ip2);
r2=REG_RAX;
}
}
i=ICModr1(r2,t1,r1,a1->disp);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x39);
ICModr2(tempi,i,a1->disp,ip2+4);
if (has_result)
result_reg=r2;
done=TRUE;
}
if (!done) {
if (tempi->ic_flags & ICF_A1_FIRST) {
if (a1->type&TY_MASK==TY_REG)
r1=a1->reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a1->type,a1->reg,a1->disp,ip2);
r1=REG_RAX;
}
if (a2->type&TY_MASK==TY_REG)
r2=a2->reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a2->type,a2->reg,a2->disp,ip2);
r2=REG_RCX;
}
} else {
if (a2->type&TY_MASK==TY_REG)
r2=a2->reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a2->type,a2->reg,a2->disp,ip2);
r2=REG_RAX;
}
if (a1->type&TY_MASK==TY_REG)
r1=a1->reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip2);
r1=REG_RCX;
}
}
if (r2>7)
i++;
if (r1>7)
i+=4;
ICU24(tempi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
if (has_result)
result_reg=r2;
}
}
ip+=tempi->ic_cnt;
lb=OptLabelFwd(tempi->ic_data);
short_jmp=ToBool(tempi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP) {
if(tempi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
if (MIN_I8<=i<=MAX_I8)
short_jmp=TRUE;
}
if (short_jmp) {
tempi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP) {
if(tempi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tempi,i<<8+is.u8[2]);
} else {
tempi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(ip+6);
if (lb->flags&CMF_POP_CMP) {
if(tempi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tempi,is.u16[0]);
ICU32(tempi,i);
}
if (has_result)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,TY_REG+RT_I64,result_reg,0,ip2);
}
U0 ICTestAndBranch(CIntermediateCode *tempi,I64 ip,I64 is,U8 *buf,I64 ip2)
{
I64 i;
Bool short_jmp;
CLexCodeMisc *lb;
if (tempi->a1.type&TY_MASK!=TY_REG) {
if (tempi->a1.type&RT_MASK<=RT_U8 &&
TY_DISP<=tempi->a1.type&TY_MASK<=TY_RIP_DISP32) {
i=ICModr1(tempi,tempi->a1.type,tempi->a1.reg,tempi->a1.disp);
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xF6);
ICModr2(tempi,i,tempi->a1.disp,ip2+5);
ICU8(tempi,0xFF);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
ICTest(tempi,REG_RAX);
}
} else
ICTest(tempi,tempi->a1.reg);
ip+=tempi->ic_cnt;
lb=OptLabelFwd(tempi->ic_data);
short_jmp=ToBool(tempi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (MIN_I8<=i<=MAX_I8)
short_jmp=TRUE;
}
if (short_jmp) {
tempi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,i<<8+is.u8[2]);
} else {
tempi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(ip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,is.u16[0]);
ICU32(tempi,i);
}
}
U0 ICFlagBranch(CIntermediateCode *tempi,I64 ip,I64 is,U8 *buf)
{
I64 i;
Bool short_jmp;
CLexCodeMisc *lb;
ip+=tempi->ic_cnt;
lb=OptLabelFwd(tempi->ic_data);
short_jmp=ToBool(tempi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (MIN_I8<=i<=MAX_I8)
short_jmp=TRUE;
}
if (short_jmp) {
tempi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,i<<8+is.u8[2]);
} else {
tempi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(ip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,is.u16[0]);
ICU32(tempi,i);
}
}
+919
View File
@@ -0,0 +1,919 @@
U0 ICAndBranch(CIntermediateCode *tempi,I64 ip,I64 is,U8 *buf,I64 ip2)
{
U64 i;
I64 it,t1,r1,d1,r2;
Bool short_jmp,swap,override;
CLexCodeMisc *lb;
CICArg *a1,*a2;
if (tempi->a1.type&TY_MASK==TY_IMM) {
swap=TRUE;
a1=&tempi->a2;
a2=&tempi->a1;
} else {
swap=FALSE;
a1=&tempi->a1;
a2=&tempi->a2;
}
if (a2->type&TY_MASK==TY_IMM && a2->disp>MAX_U32)
override=TRUE;
else
override=FALSE;
if (a1->type&RT_MASK<a2->type&RT_MASK)
it=a1->type&RT_MASK;
else
it=a2->type&RT_MASK;
i=a2->disp;
if (a2->type&TY_MASK==TY_IMM && i<=MAX_U32) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,a1->type,a1->reg,a1->disp,ip2);
if (i<=MAX_U8)
ICU16(tempi,i<<8+0xA8);
else if (i<=MAX_U16)
ICU32(tempi,i<<16+0xA900+OC_OP_SIZE_PREFIX);
else {
ICU8(tempi,0xA9);
ICU32(tempi,i);
}
} else {
t1=TY_REG+it;
d1=0;
if ((tempi->ic_flags&ICF_A1_FIRST ^^swap)&&!override) {
if (a1->type&TY_MASK==TY_REG) {
r1=a1->reg;
swap=TRUE;
} else {
r1=REG_RCX;
swap=FALSE;
}
if (a2->type&TY_MASK==TY_REG) {
r2=a2->reg;
swap=FALSE;
} else
r2=REG_RDX;
if (swap) {
if (a1->type&TY_MASK!=TY_REG || r1!=a1->reg)
ICMov(tempi,TY_REG+RT_I64,r1,0,a1->type,a1->reg,a1->disp,ip2);
if (TY_REG<=a2->type&TY_MASK<=TY_RIP_DISP32) {
t1=a2->type&TY_MASK+it;
r2=a2->reg;
d1=a2->disp;
} else
ICMov(tempi,TY_REG+RT_I64,r2,0,a2->type,a2->reg,a2->disp,ip2);
i=ICModr1(r1,t1,r2,d1);
} else {
if (TY_REG<=a1->type&TY_MASK<=TY_RIP_DISP32) {
t1=a1->type&TY_MASK+it;
r1=a1->reg;
d1=a1->disp;
} else
ICMov(tempi,TY_REG+RT_I64,r1,0,a1->type,a1->reg,a1->disp,ip2);
if (a2->type&TY_MASK!=TY_REG || r2!=a2->reg)
ICMov(tempi,TY_REG+RT_I64,r2,0,a2->type,a2->reg,a2->disp,ip2);
i=ICModr1(r2,t1,r1,d1);
}
} else {
if (a2->type&TY_MASK==TY_REG) {
r2=a2->reg;
swap=FALSE;
} else {
r2=REG_RDX;
swap=TRUE;
}
if (a1->type&TY_MASK==TY_REG) {
r1=a1->reg;
swap=TRUE;
} else
r1=REG_RCX;
if (override)
swap=FALSE;
if (swap) {
if (TY_REG<=a2->type&TY_MASK<=TY_RIP_DISP32) {
t1=a2->type&TY_MASK+it;
r2=a2->reg;
d1=a2->disp;
} else
ICMov(tempi,TY_REG+RT_I64,r2,0,a2->type,a2->reg,a2->disp,ip2);
if (a1->type&TY_MASK!=TY_REG || r1!=a1->reg)
ICMov(tempi,TY_REG+RT_I64,r1,0,a1->type,a1->reg,a1->disp,ip2);
i=ICModr1(r1,t1,r2,d1);
} else {
if (a2->type&TY_MASK!=TY_REG || r2!=a2->reg)
ICMov(tempi,TY_REG+RT_I64,r2,0,a2->type,a2->reg,a2->disp,ip2);
if (TY_REG<=a1->type&TY_MASK<=TY_RIP_DISP32) {
t1=a1->type&TY_MASK+it;
r1=a1->reg;
d1=a1->disp;
} else
ICMov(tempi,TY_REG+RT_I64,r1,0,a1->type,a1->reg,a1->disp,ip2);
i=ICModr1(r2,t1,r1,d1);
}
}
switch (it) {
case RT_I8:
case RT_U8:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x84);
break;
case RT_U16:
case RT_I16:
ICOpSizeRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x85);
break;
default:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0x85);
}
ICModr2(tempi,i,d1,ip2+4);
}
ip+=tempi->ic_cnt;
lb=OptLabelFwd(tempi->ic_data);
short_jmp=ToBool(tempi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (MIN_I8<=i<=MAX_I8)
short_jmp=TRUE;
}
if (short_jmp) {
tempi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,i<<8+is.u8[2]);
} else {
tempi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(ip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,is.u16[0]);
ICU32(tempi,i);
}
}
U0 ICAssign(CIntermediateCode *tempi,I64 ip)
{
CIntermediateCode *tempi1;
if (tempi->ic_flags & ICF_NOT_ADDR) {
ICMov(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->r.type&TY_MASK) {
if (tempi->a1.type&TY_MASK==TY_REG)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
else
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
}
} else {
if (tempi->a1.type&TY_MASK==TY_REG) {
if (!(tempi1=OptLag1(tempi)) ||
tempi1->ic_code!=IC_ADD_CONST ||
tempi1->r.type!=TY_REG+RT_I64 || tempi1->r.reg!=tempi->a1.reg ||
tempi1->a1.type!=TY_REG+RT_I64 || tempi1->a1.reg!=tempi->a1.reg ||
(tempi->a2.type&TY_MASK==TY_REG||tempi->a2.type&TY_MASK==TY_DISP) &&
tempi->a2.reg==tempi->a1.reg ||
tempi->r.type&TY_MASK ||
tempi1->ic_flags&~ICG_NO_CVT_MASK) {
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
tempi->ic_flags=(tempi->ic_flags|tempi1->ic_flags)&~ICF_CODE_FINAL|ICF_DONT_RESTORE;
tempi->a1.disp=tempi1->ic_data;
OptSetNOP1(tempi1); //This better not be last pass!
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
}
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,REG_RCX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
}
}
}
U0 ICBrBitOps(CIntermediateCode *tempi,I64 ip,I64 op,I64 op_imm,I64 is,U8 *buf,I64 ip2)
{
I64 i,t,r1,r2,d1,d2,t1,t2;
CICArg *a1=&tempi->a1,*a2=&tempi->a2;
Bool short_jmp;
CLexCodeMisc *lb;
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (tempi->ic_flags & ICF_A1_FIRST) {
if (!(tempi->ic_flags&ICF_SWAP) && a1->type&TY_MASK!=TY_REG && (a1->type&TY_MASK!=TY_IMM || a1->disp>63) ||
tempi->ic_flags&ICF_SWAP && a1->type&TY_MASK==TY_IMM && a1->disp<64 ||
a1->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip2);
t1=TY_REG+RT_I64;
r1=REG_RCX;
d1=0;
} else {
t1=a1->type;
if (t1&TY_MASK==TY_IMM && a1->disp<64)
r1=0;
else
r1=a1->reg;
d1=a1->disp;
}
if (tempi->ic_flags&ICF_SWAP && a2->type&TY_MASK!=TY_REG && (a2->type&TY_MASK!=TY_IMM || a2->disp>63) ||
!(tempi->ic_flags&ICF_SWAP) && a2->type&TY_MASK==TY_IMM && a2->disp<64 ||
a2->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a2->type,a2->reg,a2->disp,ip2);
t2=TY_REG+RT_I64;
r2=REG_RDX;
d2=0;
} else {
t2=a2->type;
if (t2&TY_MASK==TY_IMM && a2->disp<64)
r2=0;
else
r2=a2->reg;
d2=a2->disp;
}
} else {
if (tempi->ic_flags&ICF_SWAP && a2->type&TY_MASK!=TY_REG && (a2->type&TY_MASK!=TY_IMM ||a2->disp>63)||
!(tempi->ic_flags&ICF_SWAP) && a2->type&TY_MASK==TY_IMM && a2->disp<64 ||
a2->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a2->type,a2->reg,a2->disp,ip2);
t2=TY_REG+RT_I64;
r2=REG_RCX;
d2=0;
} else {
t2=a2->type;
if (t2&TY_MASK==TY_IMM && a2->disp<64)
r2=0;
else
r2=a2->reg;
d2=a2->disp;
}
if (!(tempi->ic_flags&ICF_SWAP) && a1->type&TY_MASK!=TY_REG && (a1->type&TY_MASK!=TY_IMM || a1->disp>63) ||
tempi->ic_flags&ICF_SWAP && a1->type&TY_MASK==TY_IMM && a1->disp<64||
a1->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a1->type,a1->reg,a1->disp,ip2);
t1=TY_REG+RT_I64;
r1=REG_RDX;
d1=0;
} else {
t1=a1->type;
if (t1&TY_MASK==TY_IMM && a1->disp<64)
r1=0;
else
r1=a1->reg;
d1=a1->disp;
}
}
} else {
t1=TY_DISP+RT_I64;
t2=TY_DISP+RT_I64;
d1=0;
d2=0;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (a1->type&TY_MASK==TY_REG)
r1=a1->reg;
else if (tempi->ic_flags&ICF_SWAP || a1->type&TY_MASK!=TY_IMM || a1->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip2);
r1=REG_RCX;
} else
r1=0;
if (a2->type&TY_MASK==TY_REG)
r2=a2->reg;
else if (!(tempi->ic_flags&ICF_SWAP) || a2->type&TY_MASK!=TY_IMM || a2->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a2->type,a2->reg,a2->disp,ip2);
r2=REG_RDX;
} else
r2=0;
} else {
if (a2->type&TY_MASK==TY_REG)
r2=a2->reg;
else if (!(tempi->ic_flags&ICF_SWAP) || a2->type&TY_MASK!=TY_IMM || a2->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a2->type,a2->reg,a2->disp,ip2);
r2=REG_RCX;
} else
r2=0;
if (a1->type&TY_MASK==TY_REG)
r1=a1->reg;
else if (tempi->ic_flags&ICF_SWAP || a1->type&TY_MASK!=TY_IMM || a1->disp>63) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,a1->type,a1->reg,a1->disp,ip2);
r1=REG_RDX;
} else
r1=0;
}
}
if (tempi->ic_flags&ICF_LOCK && op!=0xA30F)
ICU8(tempi,OC_LOCK_PREFIX);
if (tempi->ic_flags&ICF_SWAP) {
if (a2->type&TY_MASK==TY_IMM && a2->disp<32) {
if (op==0xA30F && a2->disp<8) {
t=t1&TY_MASK+RT_U8;
op_imm=0xF6; //TEST
} else
t=t1&TY_MASK+RT_U32;
} else
t=t1;
i=ICModr1(r2,t,r1,d1);
SwapU64(&a1,&a2);
} else {
if (a1->type&TY_MASK==TY_IMM && a1->disp<32) {
if (op==0xA30F && a1->disp<8) {
t=t2&TY_MASK+RT_U8;
op_imm=0xF6; //TEST
} else
t=t2&TY_MASK+RT_U32;
} else
t=t2;
i=ICModr1(r1,t,r2,d2);
}
ICRex(tempi,i.u8[1]);
if (op_imm==0xF6) { //TEST
ICU16(tempi,i.u8[2]<<8+op_imm);
ICModr2(tempi,i,a2->disp,ip2+5);
ICU8(tempi,1<<a1->disp);
if (is==0x72820F)
is=0x75850F;
else
is=0x74840F;
} else if (a1->type&TY_MASK==TY_IMM && a1->disp<64) {
ICU24(tempi,i.u8[2]<<16+op_imm);
ICModr2(tempi,i,a2->disp,ip2+5);
ICU8(tempi,a1->disp);
} else {
ICU24(tempi,i.u8[2]<<16+op);
ICModr2(tempi,i,a2->disp,ip2+4);
}
ip+=tempi->ic_cnt;
lb=OptLabelFwd(tempi->ic_data);
short_jmp=ToBool(tempi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (MIN_I8<=i<=MAX_I8)
short_jmp=TRUE;
}
if (short_jmp) {
tempi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,i<<8+is.u8[2]);
} else {
tempi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(ip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tempi,is.u16[0]);
ICU32(tempi,i);
}
}
U0 ICQueInit(CIntermediateCode *tempi,I64 ip2)
{
I64 r1;
if (tempi->a1.type==TY_REG+RT_I64)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
r1=REG_RAX;
}
ICMov(tempi,TY_DISP+RT_I64,r1,0,TY_REG+RT_I64,r1,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,r1,sizeof(U8 *),TY_REG+RT_I64,r1,0,ip2);
}
U0 ICQueIns(CIntermediateCode *tempi,I64 ip2)
{
I64 r1,r2;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->a1.type==TY_REG+RT_I64 && tempi->a1.reg!=REG_RAX)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
r1=REG_RDX;
}
if (tempi->a2.type==TY_REG+RT_I64)
r2=tempi->a2.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
r2=REG_RAX;
}
} else {
if (tempi->a2.type==TY_REG+RT_I64 && tempi->a2.reg!=REG_RDX)
r2=tempi->a2.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
r2=REG_RAX;
}
if (tempi->a1.type==TY_REG+RT_I64)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
r1=REG_RDX;
}
}
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,TY_DISP+RT_I64,r1,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,r1,0,TY_REG+RT_I64,r2,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,r2,0,TY_REG+RT_I64,REG_RBX,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,r2,sizeof(U8 *),TY_REG+RT_I64,r1,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,REG_RBX,sizeof(U8 *),TY_REG+RT_I64,r2,0,ip2);
}
U0 ICQueInsRev(CIntermediateCode *tempi,I64 ip2)
{
I64 r1,r2;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->a1.type==TY_REG+RT_I64 && tempi->a1.reg!=REG_RAX)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
r1=REG_RDX;
}
if (tempi->a2.type==TY_REG+RT_I64)
r2=tempi->a2.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
r2=REG_RAX;
}
} else {
if (tempi->a2.type==TY_REG+RT_I64 && tempi->a2.reg!=REG_RDX)
r2=tempi->a2.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
r2=REG_RAX;
}
if (tempi->a1.type==TY_REG+RT_I64)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
r1=REG_RDX;
}
}
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,TY_DISP+RT_I64,r1,sizeof(U8 *),ip2);
ICMov(tempi,TY_DISP+RT_I64,REG_RBX,0,TY_REG+RT_I64,r2,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,r2,0,TY_REG+RT_I64,r1,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,r2,sizeof(U8 *),TY_REG+RT_I64,REG_RBX,0,ip2);
ICMov(tempi,TY_DISP+RT_I64,r1,sizeof(U8 *),TY_REG+RT_I64,r2,0,ip2);
}
U0 ICQueRem(CIntermediateCode *tempi,I64 ip2)
{
I64 r1;
if (tempi->a1.type==TY_REG+RT_I64)
r1=tempi->a1.reg;
else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
r1=REG_RAX;
}
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,TY_DISP+RT_I64,r1,0,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,TY_DISP+RT_I64,r1,sizeof(U8 *),ip2);
ICU24(tempi,0x1A8948);
ICU32(tempi,sizeof(U8 *)<<24+0x538948);
}
U0 ICMinMax(CIntermediateCode *tempi,I64 op,I64 ip2)
{
I64 r1,i1=0x48;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->a1.type==TY_REG+RT_I64 && tempi->a1.reg!=REG_RAX) {
r1=tempi->a1.reg;
if (r1>7) {
i1++;
r1&=7;
}
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
} else {
if (tempi->a2.reg==REG_RAX && TY_REG<=tempi->a2.type&TY_MASK<=TY_SIB) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
r1=REG_RDX;
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
if (tempi->a2.type==TY_REG+RT_I64) {
r1=tempi->a2.reg;
if (r1>7) {
i1++;
r1&=7;
}
} else {
r1=REG_RDX;
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
}
}
}
} else {
if (tempi->a2.type==TY_REG+RT_I64 && tempi->a2.reg!=REG_RAX) {
r1=tempi->a2.reg;
if (r1>7) {
i1++;
r1&=7;
}
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
} else {
if (tempi->a1.reg==REG_RAX && TY_REG<=tempi->a1.type&TY_MASK<=TY_SIB) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
r1=REG_RDX;
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
if (tempi->a1.type==TY_REG+RT_I64) {
r1=tempi->a1.reg;
if (r1>7) {
i1++;
r1&=7;
}
} else {
r1=REG_RDX;
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
}
}
}
}
ICU24(tempi,0xC03B00+r1<<16+i1);
ICU32(tempi,0xC0000F00+op<<16+r1<<24+i1);
}
U0 ICSqr(CIntermediateCode *tempi,I64 op,I64 ip2)
{
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
ICSlashOp(tempi,TY_REG+RT_I64,REG_RAX,0,op,ip2);
}
U0 ICModU64(CIntermediateCode *tempi,I64 ip2)
{
I64 t1,r1,d1;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->a1.reg!=REG_RAX && tempi->a1.reg!=REG_RDX && TY_REG<=tempi->a1.type&TY_MASK<=TY_SIB &&
tempi->a1.type&RT_MASK>=RT_I64) {
t1=tempi->a1.type;
r1=tempi->a1.reg;
d1=tempi->a1.disp;
} else {
t1=TY_REG+RT_I64;
r1=REG_RBX;
d1=0;
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
}
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
if (tempi->a1.reg!=REG_RAX && tempi->a1.reg!=REG_RDX && TY_REG<=tempi->a1.type&TY_MASK<=TY_SIB &&
tempi->a1.type&RT_MASK>=RT_I64) {
t1=tempi->a1.type;
r1=tempi->a1.reg;
d1=tempi->a1.disp;
} else {
t1=TY_REG+RT_I64;
r1=REG_RBX;
d1=0;
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
}
}
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,TY_DISP+RT_I64,REG_RCX,0,ip2);
ICZero(tempi,REG_RDX);
ICSlashOp(tempi,t1,r1,d1,SLASH_OP_DIV,ip2);
ICMov(tempi,TY_DISP+RT_I64,REG_RCX,0,TY_REG+RT_I64,REG_RAX,0,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
TY_REG+RT_I64,REG_RDX,0,ip2);
}
U0 ICSwap(CIntermediateCode *tempi,I64 ip2)
{
I64 r1,r2;
if (tempi->a1.type&TY_MASK==TY_REG)
r1=tempi->a1.reg;
else
r1=REG_RAX;
if (tempi->a2.type&TY_MASK==TY_REG)
r2=tempi->a2.reg;
else
r2=REG_RAX;
if (tempi->ic_flags & ICF_A1_FIRST) {
if (r1==r2) {
if (r2==REG_RAX)
r2=REG_RBX;
else
r1=REG_RAX;
}
ICMov(tempi,TY_REG+RT_I64,r1,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
ICMov(tempi,TY_REG+RT_I64,r2,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
} else {
if (r1==r2) {
if (r1==REG_RAX)
r1=REG_RBX;
else
r2=REG_RAX;
}
ICMov(tempi,TY_REG+RT_I64,r2,0,tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
ICMov(tempi,TY_REG+RT_I64,r1,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
}
switch (tempi->ic_code) {
case IC_SWAP_U8:
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,TY_DISP+RT_U8,r1,0,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,TY_DISP+RT_U8,r2,0,ip2);
ICMov(tempi,TY_DISP+RT_U8,r2,0,TY_REG+RT_I64,REG_RCX,0,ip2);
ICMov(tempi,TY_DISP+RT_U8,r1,0,TY_REG+RT_I64,REG_RDX,0,ip2);
break;
case IC_SWAP_U16:
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,TY_DISP+RT_U16,r1,0,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,TY_DISP+RT_U16,r2,0,ip2);
ICMov(tempi,TY_DISP+RT_U16,r2,0,TY_REG+RT_I64,REG_RCX,0,ip2);
ICMov(tempi,TY_DISP+RT_U16,r1,0,TY_REG+RT_I64,REG_RDX,0,ip2);
break;
case IC_SWAP_U32:
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,TY_DISP+RT_U32,r1,0,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,TY_DISP+RT_U32,r2,0,ip2);
ICMov(tempi,TY_DISP+RT_U32,r2,0,TY_REG+RT_I64,REG_RCX,0,ip2);
ICMov(tempi,TY_DISP+RT_U32,r1,0,TY_REG+RT_I64,REG_RDX,0,ip2);
break;
case IC_SWAP_U64:
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,TY_DISP+RT_U64,r1,0,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,TY_DISP+RT_U64,r2,0,ip2);
ICMov(tempi,TY_DISP+RT_U64,r2,0,TY_REG+RT_I64,REG_RCX,0,ip2);
ICMov(tempi,TY_DISP+RT_U64,r1,0,TY_REG+RT_I64,REG_RDX,0,ip2);
break;
}
}
U0 ICAndEqual(CIntermediateCode *tempi,I64 ip2)
{
I64 i,bit;
if (tempi->a2.type&TY_MASK==TY_IMM &&
tempi->a1.type&TY_MASK!=TY_STK &&
tempi->ic_flags&ICF_NO_DEPEND_RESULT) {
i=~tempi->a2.disp;
bit=Bsf(i);
if (0<=bit==Bsr(i)) {
tempi->a2.disp=bit;
tempi->a2.reg=0;
tempi->a1.type=tempi->a1.type&TY_MASK+RT_I64;
ICBitOps(tempi,&tempi->a2,&tempi->a1,tempi,
0xB30F,0x30BA0F,ip2);
return;
}
}
ICAddSubEctEqual(tempi,tempi->a1.type_pointed,
tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,0x210425240423,ip2);
}
U0 ICOrEqual(CIntermediateCode *tempi,I64 ip2)
{
I64 i,bit;
if (tempi->a2.type&TY_MASK==TY_IMM &&
tempi->a1.type&TY_MASK!=TY_STK &&
tempi->ic_flags&ICF_NO_DEPEND_RESULT) {
i=tempi->a2.disp;
bit=Bsf(i);
if (0<=bit==Bsr(i) && i>MAX_I8) {
tempi->a2.disp=bit;
tempi->a2.reg=0;
tempi->a1.type=tempi->a1.type&TY_MASK+RT_I64;
ICBitOps(tempi,&tempi->a2,&tempi->a1,tempi,
0xAB0F,0x28BA0F,ip2);
return;
}
}
ICAddSubEctEqual(tempi,tempi->a1.type_pointed,
tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,0x09010D0C010B,ip2);
}
U0 ICXorEqual(CIntermediateCode *tempi,I64 ip2)
{
I64 i,bit;
if (tempi->a2.type&TY_MASK==TY_IMM &&
tempi->a1.type&TY_MASK!=TY_STK &&
tempi->ic_flags&ICF_NO_DEPEND_RESULT) {
i=tempi->a2.disp;
bit=Bsf(i);
if (0<=bit==Bsr(i)) {
tempi->a2.disp=bit;
tempi->a2.reg=0;
tempi->a1.type=tempi->a1.type&TY_MASK+RT_I64;
ICBitOps(tempi,&tempi->a2,&tempi->a1,tempi,
0xBB0F,0x38BA0F,ip2);
return;
}
}
ICAddSubEctEqual(tempi,tempi->a1.type_pointed,
tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,0x310635340633,ip2);
}
U0 ICSwitch(CIntermediateCode *tempi,I64 ip,Bool nobound,CLex *lx,U8 *buf,I64 ip2)
{
I64 i,j,cnt,min,max,begin,r;
CLexCodeMisc *lb;
Bool short_jmp;
CExeAbsAddr *tempa;
if (tempi->a1.type&TY_MASK!=TY_REG || tempi->a1.reg&7==REG_RSP)
r=REG_RDX;
else
r=tempi->a1.reg;
if (nobound)
ICMov(tempi,TY_REG+RT_I64,r,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
else {
if (tempi->a2.type&TY_MASK==TY_IMM) {
j=tempi->a2.disp;
ICMov(tempi,TY_REG+RT_I64,r,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
if (MIN_I8<=j<=MAX_I8) {
i=0xF88348+(r&7)<<16;
if (r>7) i++;
ICU24(tempi,i);
ICU8(tempi,j);
} else if (MIN_I32<=j<=MAX_I32) {
i=0xF88148+(r&7)<<16;
if (r>7) i++;
ICU24(tempi,i);
ICU32(tempi,j);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
i=0xC13B48+(r&7)<<19;
if (r>7) i+=4;
ICU24(tempi,i);
}
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,r,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip2);
ICMov(tempi,TY_REG+RT_I64,r,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip2);
}
i=0xC13B48+(r&7)<<19;
if (r>7) i+=4;
ICU24(tempi,i);
}
ip+=tempi->ic_cnt;
lb=tempi->ic_data(CLexCodeMisc *)->dft;
short_jmp=ToBool(tempi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(ip+2);
if (MIN_I8<=i<=MAX_I8)
short_jmp=TRUE;
}
if (short_jmp) {
tempi->ic_flags|=ICF_SHORT_JMP;
ICU16(tempi,(lb->addr-(ip+2))<<8+0x73);
} else {
tempi->ic_flags&=~ICF_SHORT_JMP;
ICU16(tempi,0x830F);
ICU32(tempi,lb->addr-(ip+6));
}
}
lb=tempi->ic_data;
begin=lb->begin->addr;
if (!buf && begin!=INVALID_PTR) {
min=MAX_I64;
max=MIN_I64;
for (i=0;i<lb->range;i++) {
if (lb->jmp_table[i]->addr==INVALID_PTR) {
min=MIN_I64;
max=MAX_I64;
break;
} else {
j=lb->jmp_table[i]->addr-begin;
min=MinI64(min,j);
max=MaxI64(max,j);
}
}
if (MIN_I8<=min<=max<=MAX_I8)
lb->flags|=CMF_I8_JMP_TABLE;
else if (MIN_U8<=min<=max<=MAX_U8)
lb->flags|=CMF_U8_JMP_TABLE;
else if (MIN_I16<=min<=max<=MAX_I16)
lb->flags|=CMF_I16_JMP_TABLE;
else if (MIN_U16<=min<=max<=MAX_U16)
lb->flags|=CMF_U16_JMP_TABLE;
}
if (lb->flags&CMF_I8_JMP_TABLE) {
if (r<8)
ICU8(tempi,0x48);
else
ICU8(tempi,0x49);
ICU24(tempi,0x98BE0F+(r&7)<<16);
cnt=1;
} else if (lb->flags&CMF_U8_JMP_TABLE) {
if (r<8)
cnt=2;
else {
ICU8(tempi,0x49);
cnt=1;
}
ICU24(tempi,0x98B60F+(r&7)<<16);
} else if (lb->flags&CMF_I16_JMP_TABLE) {
if (r<8)
ICU8(tempi,0x48);
else
ICU8(tempi,0x4A);
ICU32(tempi,0x451CBF0F+(r&7)<<27);
cnt=0;
} else if (lb->flags&CMF_U16_JMP_TABLE) {
if (r<8)
cnt=1;
else {
ICU8(tempi,0x4A);
cnt=0;
}
ICU32(tempi,0x451CB70F+(r&7)<<27);
} else {
if (r<8)
cnt=2;
else {
ICU8(tempi,0x42);
cnt=1;
}
ICU24(tempi,0x851C8B+(r&7)<<19);
}
if (buf && lx->flags&LF_AOT_COMPILE) {
tempa=CAlloc(sizeof(CExeAbsAddr));
tempa->next=lx->a->abss;
tempa->type=EAT_ADD_U32;
lx->a->abss=tempa;
tempa->ip=ip2+tempi->ic_cnt;
ICU32(tempi,lb->addr+lx->a->ip);
} else
ICU32(tempi,lb->addr+buf);
if (lb->flags&(CMF_I8_JMP_TABLE|CMF_U8_JMP_TABLE|CMF_I16_JMP_TABLE|CMF_U16_JMP_TABLE)) {
ICU16(tempi,0xC381); //ADD EBX,0x12345678
if (buf && lx->flags&LF_AOT_COMPILE) {
tempa=CAlloc(sizeof(CExeAbsAddr));
tempa->next=lx->a->abss;
tempa->type=EAT_ADD_U32;
lx->a->abss=tempa;
tempa->ip=ip2+tempi->ic_cnt;
ICU32(tempi,begin+lx->a->ip);
} else
ICU32(tempi,begin+buf);
} else
cnt+=6;
ICU16(tempi,0xE3FF); //JMP EBX
for (i=0;i<cnt;i++) //Code must always shrink, not expand
ICU8(tempi,OC_NOP);
tempi->ic_flags&=~ICF_CODE_FINAL;
}
U0 ICLocalVarInit(CIntermediateCode *tempi)
{
ICU24(tempi,0xC48B48);
ICU16(tempi,0x5748);
ICU24(tempi,0xF88B48);
ICU24(tempi,0xC1C748);
ICU32(tempi,tempi->ic_data);
ICU16(tempi,sys_var_init_val<<8+0xB0);
ICU16(tempi,0xAAF3);
ICU16(tempi,0x5F48);
}
+654
View File
@@ -0,0 +1,654 @@
#define CN_A2 0
#define CN_A1 1
#define CN_MAIN 2
#define CN_R 3
U0 CmpNoteFloatOp(CLex *lx,CIntermediateCode *tempi,Bool dont_pushable,Bool dont_popable,I64 pos)
{
Bool link=FALSE;
if (lx->pass==7 && lx->last_float_op_ic && lx->last_dont_popable && dont_pushable) {
nobound_switch (pos) {
case CN_A2:
if (lx->last_float_op_ic!=tempi && lx->dont_push_float)
link=TRUE;
break;
case CN_A1:
if (lx->last_float_op_ic!=tempi && lx->dont_push_float)
link=TRUE;
break;
case CN_MAIN:
if (lx->last_float_op_ic!=tempi) {
if (lx->dont_push_float) {
if (!(tempi->ic_flags & ICF_A1_FIRST))
tempi->ic_flags|=ICF_ALTERNATE_TEMPLATE;
else
tempi->ic_flags&=~ICF_ALTERNATE_TEMPLATE;
link=TRUE;
}
} else {
if (lx->last_float_op_pos==CN_A1 ^^ !(tempi->ic_flags & ICF_A1_FIRST))
tempi->ic_flags|=ICF_ALTERNATE_TEMPLATE;
else
tempi->ic_flags&=~ICF_ALTERNATE_TEMPLATE;
link=TRUE;
}
break;
case CN_R:
if (lx->last_float_op_ic==tempi && lx->last_float_op_pos==CN_MAIN)
link=TRUE;
break;
}
if (link) {
if (!Bts(&lx->last_float_op_ic->ic_flags,ICf_DONT_POP_FLOAT0+lx->last_ic_float_op_num))
lx->last_float_op_ic->ic_flags&=~ICF_CODE_FINAL;
if (!Bts(&tempi->ic_flags,ICf_DONT_PUSH_FLOAT0+lx->cur_ic_float_op_num))
tempi->ic_flags&=~ICF_CODE_FINAL;
}
}
lx->last_float_op_ic=tempi;
lx->last_dont_pushable=dont_pushable;
lx->last_dont_popable=dont_popable;
lx->last_ic_float_op_num=lx->cur_ic_float_op_num++;
lx->last_float_op_pos=pos;
if (lx->cur_ic_float_op_num>4)
throw('Compiler');
}
U0 CmpSetFloatOpPushPop(CLex *lx,CIntermediateCode *tempi,Bool *dont_push_float,Bool *dont_pop_float)
{
if (lx->pass==7) {
*dont_push_float=FALSE;
*dont_pop_float =FALSE;
tempi->ic_flags&=~ICF_CODE_FINAL;
} else {
*dont_push_float=Bt(&tempi->ic_flags,ICf_DONT_PUSH_FLOAT0+lx->cur_ic_float_op_num);
*dont_pop_float=Bt(&tempi->ic_flags,ICf_DONT_POP_FLOAT0+lx->cur_ic_float_op_num);
}
}
U0 ICCopyTemplate(CLex *lx,CIntermediateCode *tempi,I64 op,
Bool off_the_record,Bool dont_pushable,Bool dont_popable,I64 pos)
{
Bool dont_push_float,dont_pop_float,alt;
U8 *ptr;
I64 i=0;
if (!off_the_record) {
if (tempi->ic_flags&ICF_ALTERNATE_TEMPLATE)
alt=TRUE;
else
alt=FALSE;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
} else {
dont_push_float=FALSE;
dont_pop_float=FALSE;
alt=FALSE;
}
if (alt && dont_push_float && !dont_pop_float) {
ptr=cmp_templates_dont_push2[op];
i=cmp_templates_dont_push2[op+1]-ptr;
}
if (!i) {
if (dont_push_float) {
if (dont_pop_float) {
ptr=cmp_templates_dont_push_pop[op];
i=cmp_templates_dont_push_pop[op+1]-ptr;
} else {
ptr=cmp_templates_dont_push[op];
i=cmp_templates_dont_push[op+1]-ptr;
}
} else {
if (dont_pop_float) {
ptr=cmp_templates_dont_pop[op];
i=cmp_templates_dont_pop[op+1]-ptr;
} else {
ptr=cmp_templates[op];
i=cmp_templates[op+1]-ptr;
}
}
}
MemCpy(&tempi->ic_body[tempi->ic_cnt],ptr,i);
if (!off_the_record)
CmpNoteFloatOp(lx,tempi,dont_pushable,dont_popable,pos);
tempi->ic_cnt+=i;
}
U0 ICFCvt(CLex *lx,CIntermediateCode *tempi,I64 r1,I64 t2,I64 r2,I64 d2,Bool to_int,I64 pos,I64 ip)
{
I64 rsp_size=0,op1,op2;
Bool dont_push_float,dont_pop_float;
if (to_int) {
op1=SLASH_OP_FLD;
op2=SLASH_OP_FISTTP;
} else {
op1=SLASH_OP_FILD;
op2=SLASH_OP_FSTP;
}
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (!dont_push_float) {
if (!(t2&RT_MASK>=RT_I64 &&
(t2&TY_MASK==TY_DISP ||
t2&TY_MASK==TY_RIP_DISP32 ||
t2&TY_MASK==TY_SIB))) {
ICPush(tempi,t2,r2,d2,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size=8;
} else {
if (!dont_pop_float) {
rsp_size=8;
ICAddRSP(tempi,-8);
}
}
ICSlashOp(tempi,t2,r2,d2,op1,ip);
} else {
if (!dont_pop_float) {
rsp_size=8;
ICAddRSP(tempi,-8);
}
}
if (to_int)
CmpNoteFloatOp(lx,tempi,TRUE,FALSE,pos);
else
CmpNoteFloatOp(lx,tempi,FALSE,TRUE,pos);
if (dont_pop_float) {
if (rsp_size)
ICAddRSP(tempi,rsp_size);
} else {
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,ip);
ICPop(tempi,TY_REG+RT_I64,r1,0,ip);
}
}
U0 ICFCvt2(CLex *lx,CIntermediateCode *tempi,I64 r1,I64 t2,I64 r2,I64 d2,Bool to_int,I64 ip)
{
I64 rsp_size=0,op1,op2;
if (to_int) {
op1=SLASH_OP_FLD;
op2=SLASH_OP_FISTTP;
} else {
op1=SLASH_OP_FILD;
op2=SLASH_OP_FSTP;
}
if (!(t2&RT_MASK>=RT_I64 &&
(t2&TY_MASK==TY_DISP ||
t2&TY_MASK==TY_RIP_DISP32 ||
t2&TY_MASK==TY_SIB))) {
ICPush(tempi,t2,r2,d2,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size=8;
} else {
rsp_size=8;
ICAddRSP(tempi,-8);
}
ICSlashOp(tempi,t2,r2,d2,op1,ip);
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,ip);
ICPop(tempi,TY_REG+RT_I64,r1,0,ip);
lx->last_dont_pushable=lx->last_dont_popable=FALSE; //TODO: might improve this
}
U0 ICFUnaryMinus(CLex *lx,CIntermediateCode *tempi,U8 *buf2,I64 ip)
{
CICArg *a1=&tempi->a1;
I64 rsp_size=0,builtin1=0,t1,r1,d1;
Bool dont_push_float,dont_pop_float;
if (lx->flags&LF_AOT_COMPILE)
buf2=lx->a->ip;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (!dont_push_float) {
if (a1->type&RT_MASK>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type;
r1=a1->reg;
d1=a1->disp;
} else {
if (a1->type&TY_MASK==TY_IMM) {
if (!(builtin1=ICBuiltInFloatConst(a1->disp(F64)))) {
t1=TY_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=LCCFloatConstFind(lx,a1->disp(F64))+buf2;
}
} else {
ICPush(tempi,a1->type,a1->reg,a1->disp,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
if (builtin1)
ICU16(tempi,builtin1);
else
ICSlashOp(tempi,t1,r1,d1,SLASH_OP_FLD,ip);
}
if (!dont_pop_float && !rsp_size) {
rsp_size=8;
ICAddRSP(tempi,-8);
}
ICU16(tempi,0xE0D9); //FCHS
CmpNoteFloatOp(lx,tempi,TRUE,TRUE,CN_MAIN);
if (dont_pop_float) {
if (rsp_size)
ICAddRSP(tempi,rsp_size);
} else {
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,ip);
ICPop(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,ip);
}
}
U0 ICFMod(CLex *lx,CIntermediateCode *tempi,I64 ip)
{ //for MOD
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (tempi->ic_flags&ICF_ALTERNATE_TEMPLATE)
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
else
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
}
}
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_MAIN); //TODO: unpushable,unpop? Not sure
if (!dont_pop_float)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICFPow(CLex *lx,CIntermediateCode *tempi,U8 *buf,I64 ip)
{ //for POW
I64 i;
CExeImportExport *tempe;
CHashExport *tempex=HashFind("SYS_POW",lx->htc.hash_table_lst,HTT_EXPORT_SYS_SYM);
if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
}
if (lx->flags&LF_AOT_COMPILE) {
if (!tempex) {
tempex=CAlloc(sizeof(CHashExport));
tempex->str=StrNew("SYS_POW");
tempex->type=HTT_EXPORT_SYS_SYM|HTF_UNRESOLVED|HTF_IMPORT;
HashAdd(tempex,lx->htc.glbl_hash_table);
}
if (tempex->type&HTF_IMPORT) {
if (GetOpt(OPTf_USE_IMM64)) {
ICU16(tempi,0xBB48);
ICU64(tempi,0);
if (buf) {
tempe=CAlloc(sizeof(CExeImportExport));
tempe->type=EIT_IMM_U64;
tempe->ip=ip+tempi->ic_cnt-8;
tempe->next=tempex->ie_lst;
tempex->ie_lst=tempe;
}
ICU16(tempi,0xD3FF);
} else {
ICU8(tempi,0xE8);
ICU32(tempi,-(ip+tempi->ic_cnt+4));
if (buf) {
tempe=CAlloc(sizeof(CExeImportExport));
tempe->type=EIT_REL_I32;
tempe->ip=ip+tempi->ic_cnt-4;
tempe->next=tempex->ie_lst;
tempex->ie_lst=tempe;
}
}
} else { //Kernel
if (tempex->type&HTF_UNRESOLVED)
throw('Compiler');
else {
i=tempex->val-(ip+tempi->ic_cnt+5);
if (!(MIN_I32<=i<=MAX_I32)) {
throw('Compiler');
// ICU16(tempi,0xBB48);
// ICU64(tempi,tempex->val);
// ICU16(tempi,0xD3FF);
} else {
ICU8(tempi,0xE8);
ICU32(tempi,i);
}
}
}
} else {
i=tempex->val-(ip+tempi->ic_cnt+5);
if (!(MIN_I32<=i<=MAX_I32)) {
ICU16(tempi,0xBB48);
ICU64(tempi,tempex->val);
ICU16(tempi,0xD3FF);
} else {
ICU8(tempi,0xE8);
ICU32(tempi,i);
}
}
tempi->ic_flags&=~ICF_CODE_FINAL;
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICFOp(CLex *lx,CIntermediateCode *tempi,I64 op,U8 *buf2,I64 ip)
{ //for ADD,SUB,DIV,MUL
CICArg *a1,*a2;
Bool dont_push_float,dont_pop_float,alt;
I64 rsp_size=0,builtin1=0,builtin2=0,
t1,r1,d1,t2,r2,d2;
if (tempi->ic_flags&ICF_ALTERNATE_TEMPLATE) {
a1=&tempi->a2;
a2=&tempi->a1;
alt=TRUE;
} else {
a1=&tempi->a1;
a2=&tempi->a2;
alt=FALSE;
}
if (lx->flags&LF_AOT_COMPILE)
buf2=lx->a->ip;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64)))) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
} else {
if (tempi->ic_flags & ICF_A1_FIRST^^alt) {
if (a2->type&TY_MASK!=TY_STK) {
if (a1->type&RT_MASK>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type;
r1=a1->reg;
d1=a1->disp;
} else {
if (a1->type&TY_MASK==TY_IMM) {
if (!(builtin1=ICBuiltInFloatConst(a1->disp(F64)))) {
t1=TY_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=LCCFloatConstFind(lx,a1->disp(F64))+buf2;
}
} else {
ICPush(tempi,a1->type,a1->reg,a1->disp,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64)))) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
if (r1==REG_RSP+REG_RSP<<8)
d1+=8;
}
}
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
a1->type,a1->reg,a1->disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
} else {
if (a1->type&TY_MASK!=TY_STK) {
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64)))) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
if (a1->type&RT_MASK>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type;
r1=a1->reg;
d1=a1->disp;
} else {
if (a1->type&TY_MASK==TY_IMM) {
if (!(builtin1=ICBuiltInFloatConst(a1->disp(F64)))) {
t1=TY_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=LCCFloatConstFind(lx,a1->disp(F64))+buf2;
}
} else {
ICPush(tempi,a1->type,a1->reg,a1->disp,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
if (r2==REG_RSP+REG_RSP<<8)
d2+=8;
}
}
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
a1->type,a1->reg,a1->disp,ip);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
}
}
if (!dont_pop_float && !rsp_size) {
rsp_size=8;
ICAddRSP(tempi,-8);
}
if (!dont_push_float) {
if (builtin2 && !builtin1) {
alt=!alt;
SwapU64(&t1,&t2);
SwapU64(&r1,&r2);
SwapU64(&d1,&d2);
SwapU64(&builtin1,&builtin2);
}
if (builtin1)
ICU16(tempi,builtin1);
else
ICSlashOp(tempi,t1,r1,d1,SLASH_OP_FLD,ip);
}
if (alt)
switch (op.u8[0]) {
case 4: //FSUB
op=SLASH_OP_FSUBR;
break;
case 6: //FDIV
op=SLASH_OP_FDIVR;
break;
}
if (builtin2) {
ICU16(tempi,builtin2);
ICU16(tempi,op.u16[2]);
} else
ICSlashOp(tempi,t2,r2,d2,op,ip);
CmpNoteFloatOp(lx,tempi,TRUE,TRUE,CN_MAIN);
if (dont_pop_float) {
if (rsp_size)
ICAddRSP(tempi,rsp_size);
} else {
if (rsp_size==8)
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,ip);
else if (rsp_size>8) {
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,SLASH_OP_FSTP,ip);
ICAddRSP(tempi,rsp_size-8);
}
ICPop(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,ip);
}
}
U0 ICFCmp(CLex *lx,CIntermediateCode *tempi,I64 op,I64 ip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (tempi->ic_flags&ICF_ALTERNATE_TEMPLATE) {
if (tempi->ic_flags&ICF_POP_CMP)
ICPopRegs(tempi,1<<REG_RAX);
else
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
} else
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
if (tempi->ic_flags & ICF_A1_FIRST) {
if (tempi->ic_flags&ICF_POP_CMP)
ICPopRegs(tempi,1<<REG_RDX);
else
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
if (tempi->ic_flags&ICF_POP_CMP)
ICPopRegs(tempi,1<<REG_RDX);
else
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
}
}
if (tempi->ic_flags&ICF_PUSH_CMP)
ICPushRegs(tempi,1<<REG_RAX);
ICCopyTemplate(lx,tempi,op,FALSE,TRUE,FALSE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICFModEqual(CLex *lx,CIntermediateCode *tempi,I64 ip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (tempi->ic_flags & ICF_NOT_ADDR) {
if (dont_push_float) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,FALSE,ip);
} else if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
}
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_MAIN); //TODO: unpushable,unpop? Not sure
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,TRUE,ip);
ICMov(tempi,tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type&TY_MASK+tempi->a1.type_pointed,tempi->a1.reg,tempi->a1.disp,ip);
} else {
if (dont_push_float) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
TY_DISP+tempi->a1.type_pointed,REG_RCX,0,ip);
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,FALSE,ip);
} else if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
TY_DISP+tempi->a1.type_pointed,REG_RCX,0,ip);
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
TY_DISP+tempi->a1.type_pointed,REG_RCX,0,ip);
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
}
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_MAIN); //TODO: unpushable,unpop? Not sure
if (tempi->a1.type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,TRUE,ip);
ICMov(tempi,TY_DISP+tempi->a1.type_pointed,REG_RCX,0,TY_REG+RT_I64,REG_RAX,0,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
}
+759
View File
@@ -0,0 +1,759 @@
U0 ICFOpEqual(CLex *lx,CIntermediateCode *tempi,I64 op,U8 *buf2,I64 ip)
{ //for ADD,SUB,DIV,MUL
CICArg *a1=&tempi->a1,
*a2=&tempi->a2;
Bool dont_push_float,dont_pop_float,p1_mem;
I64 rsp_size=0,builtin2=0,
t1,r1,d1,t2,r2,d2;
if (lx->flags&LF_AOT_COMPILE)
buf2=lx->a->ip;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (dont_pop_float)
throw('Compiler');
if (tempi->ic_flags & ICF_NOT_ADDR) {
p1_mem=FALSE;
if (dont_push_float) {
if (a1->type_pointed!=RT_F64) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a1->type&TY_MASK+a1->type_pointed,a1->reg,a1->disp,ip);
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,FALSE,ip);
ICPush(tempi,TY_REG+RT_I64,REG_RAX,0,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
} else {
if (a1->type_pointed>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type_pointed+a1->type&TY_MASK;
r1=a1->reg;
d1=a1->disp;
p1_mem=TRUE;
} else {
ICPush(tempi,a1->type_pointed+a1->type&TY_MASK,a1->reg,a1->disp,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
} else if (tempi->ic_flags & ICF_A1_FIRST) {
if (a1->type_pointed!=RT_F64 || a2->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
a1->type&TY_MASK+a1->type_pointed,a1->reg,a1->disp,ip);
if (a1->type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
} else {
if (a1->type_pointed>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type_pointed+a1->type&TY_MASK;
r1=a1->reg;
d1=a1->disp;
p1_mem=TRUE;
} else {
ICPush(tempi,a1->type_pointed+a1->type&TY_MASK,a1->reg,a1->disp,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64)))) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
if (r1==REG_RSP+REG_RSP<<8)
d1+=8;
}
}
}
} else {
if (a1->type_pointed!=RT_F64 || a1->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
a1->type&TY_MASK+a1->type_pointed,a1->reg,a1->disp,ip);
if (a1->type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
} else {
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64)))) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
if (a1->type_pointed>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type_pointed+a1->type&TY_MASK;
r1=a1->reg;
d1=a1->disp;
p1_mem=TRUE;
} else {
ICPush(tempi,a1->type_pointed+a1->type&TY_MASK,a1->reg,a1->disp,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
if (r2==REG_RSP+REG_RSP<<8)
d2+=8;
}
}
}
if (!rsp_size && !(p1_mem && a1->type_pointed==RT_F64)) {
rsp_size=8;
ICAddRSP(tempi,-8);
}
if (!dont_push_float) {
if (builtin2)
ICU16(tempi,builtin2);
else
ICSlashOp(tempi,t2,r2,d2,SLASH_OP_FLD,ip);
}
switch (op.u8[0]) {
case 4: //FSUB
op=SLASH_OP_FSUBR;
break;
case 6: //FDIV
op=SLASH_OP_FDIVR;
break;
}
ICSlashOp(tempi,t1,r1,d1,op,ip);
CmpNoteFloatOp(lx,tempi,TRUE,FALSE,CN_MAIN);
if (p1_mem && a1->type_pointed==RT_F64) {
ICSlashOp(tempi,t1,r1,d1,SLASH_OP_FSTP,ip);
if (rsp_size)
ICAddRSP(tempi,rsp_size);
} else {
if (rsp_size==8)
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,ip);
else if (rsp_size>8) {
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,SLASH_OP_FSTP,ip);
ICAddRSP(tempi,rsp_size-8);
}
if (a1->type_pointed!=RT_F64) {
ICPop(tempi,TY_REG+RT_I64,REG_RAX,0,ip);
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,TRUE,ip);
ICMov(tempi,a1->type&TY_MASK+a1->type_pointed,a1->reg,a1->disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else
ICPop(tempi,a1->type_pointed+a1->type&TY_MASK,a1->reg,a1->disp,ip);
}
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
a1->type&TY_MASK+a1->type_pointed,a1->reg,a1->disp,ip);
} else {
if (a1->type_pointed>=RT_I64)
p1_mem=TRUE;
else
p1_mem=FALSE;
if (dont_push_float) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
if (a1->type_pointed!=RT_F64) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
TY_DISP+a1->type_pointed,REG_RCX,0,ip);
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,FALSE,ip);
ICPush(tempi,TY_REG+RT_I64,REG_RAX,0,ip);
} else
ICPush(tempi,a1->type_pointed+TY_DISP,REG_RCX,0,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
} else if (tempi->ic_flags & ICF_A1_FIRST) {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
if (a1->type_pointed!=RT_F64 || a2->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
TY_DISP+a1->type_pointed,REG_RCX,0,ip);
if (a1->type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
} else {
ICPush(tempi,TY_DISP+a1->type_pointed,REG_RCX,0,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64)))) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
if (r1==REG_RSP+REG_RSP<<8)
d1+=8;
}
}
}
} else {
if (a1->type_pointed!=RT_F64 || a1->type&TY_MASK==TY_STK) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
TY_DISP+a1->type_pointed,REG_RCX,0,ip);
if (a1->type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RDX,TY_REG+RT_I64,REG_RDX,0,FALSE,ip);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
} else {
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64)))) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,a1->type,a1->reg,a1->disp,ip);
ICPush(tempi,TY_DISP+a1->type_pointed,REG_RCX,0,ip);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
if (r2==REG_RSP+REG_RSP<<8)
d2+=8;
}
}
if (!rsp_size && !(p1_mem && a1->type_pointed==RT_F64)) {
rsp_size=8;
ICAddRSP(tempi,-8);
}
if (!dont_push_float) {
if (builtin2)
ICU16(tempi,builtin2);
else
ICSlashOp(tempi,t2,r2,d2,SLASH_OP_FLD,ip);
}
switch (op.u8[0]) {
case 4: //FSUB
op=SLASH_OP_FSUBR;
break;
case 6: //FDIV
op=SLASH_OP_FDIVR;
break;
}
ICSlashOp(tempi,t1,r1,d1,op,ip);
CmpNoteFloatOp(lx,tempi,TRUE,FALSE,CN_MAIN);
if (p1_mem && a1->type_pointed==RT_F64) {
ICSlashOp(tempi,TY_DISP+a1->type_pointed,REG_RCX,0,SLASH_OP_FSTP,ip);
if (rsp_size)
ICAddRSP(tempi,rsp_size);
} else {
if (rsp_size==8)
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,ip);
else if (rsp_size>8) {
ICSlashOp(tempi,TY_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,SLASH_OP_FSTP,ip);
ICAddRSP(tempi,rsp_size-8);
}
ICPop(tempi,TY_REG+RT_I64,REG_RAX,0,ip);
if (a1->type_pointed!=RT_F64)
ICFCvt2(lx,tempi,REG_RAX,TY_REG+RT_I64,REG_RAX,0,TRUE,ip);
ICMov(tempi,TY_DISP+a1->type_pointed,REG_RCX,0,TY_REG+RT_I64,REG_RAX,0,ip);
}
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
}
U0 ICFCmpAndBranch(CLex *lx,CIntermediateCode *tempi,I64 ip,
I64 us,I64 not_us,U8 *buf,I64 ip2)
{
CICArg *a1,*a2;
Bool dont_push_float,dont_pop_float,alt,short_jmp;
I64 i,rsp_size=0,builtin1=0,builtin2=0,
t1,r1,d1,t2,r2,d2;
CLexCodeMisc *lb;
U8 *buf2;
if (tempi->ic_flags&ICF_ALTERNATE_TEMPLATE) {
a1=&tempi->a2;
a2=&tempi->a1;
alt=TRUE;
} else {
a1=&tempi->a1;
a2=&tempi->a2;
alt=FALSE;
}
if (lx->flags&LF_AOT_COMPILE)
buf2=lx->a->ip;
else
buf2=buf;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (tempi->ic_flags&ICF_POP_CMP && alt) {
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
} else {
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64))) ||
tempi->ic_flags&ICF_PUSH_CMP) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip2);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
}
} else {
if (tempi->ic_flags & ICF_A1_FIRST^^alt) {
if (a2->type&TY_MASK!=TY_STK) {
if (tempi->ic_flags&ICF_POP_CMP) {
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
} else {
if (a1->type&RT_MASK>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type;
r1=a1->reg;
d1=a1->disp;
} else {
if (a1->type&TY_MASK==TY_IMM) {
if (!(builtin1=ICBuiltInFloatConst(a1->disp(F64)))) {
t1=TY_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=LCCFloatConstFind(lx,a1->disp(F64))+buf2;
}
} else {
ICPush(tempi,a1->type,a1->reg,a1->disp,ip2);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
}
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64))) ||
tempi->ic_flags&ICF_PUSH_CMP) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip2);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
if (r1==REG_RSP+REG_RSP<<8)
d1+=8;
}
}
} else {
if (tempi->ic_flags&ICF_POP_CMP)
ICPopRegs(tempi,1<<REG_RDX);
else
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
a1->type,a1->reg,a1->disp,ip2);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip2);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
} else {
if (a1->type&TY_MASK!=TY_STK) {
if (a2->type&RT_MASK>=RT_I64 &&
(a2->type&TY_MASK==TY_DISP ||
a2->type&TY_MASK==TY_RIP_DISP32 ||
a2->type&TY_MASK==TY_SIB)) {
t2=a2->type;
r2=a2->reg;
d2=a2->disp;
} else {
if (a2->type&TY_MASK==TY_IMM) {
if (!(builtin2=ICBuiltInFloatConst(a2->disp(F64))) ||
tempi->ic_flags&ICF_PUSH_CMP) {
t2=TY_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=LCCFloatConstFind(lx,a2->disp(F64))+buf2;
}
} else {
ICPush(tempi,a2->type,a2->reg,a2->disp,ip2);
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
if (tempi->ic_flags&ICF_POP_CMP) {
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
if (r2==REG_RSP+REG_RSP<<8)
d1+=8;
} else {
if (a1->type&RT_MASK>=RT_I64 &&
(a1->type&TY_MASK==TY_DISP ||
a1->type&TY_MASK==TY_RIP_DISP32 ||
a1->type&TY_MASK==TY_SIB)) {
t1=a1->type;
r1=a1->reg;
d1=a1->disp;
} else {
if (a1->type&TY_MASK==TY_IMM) {
if (!(builtin1=ICBuiltInFloatConst(a1->disp(F64)))) {
t1=TY_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=LCCFloatConstFind(lx,a1->disp(F64))+buf2;
}
} else {
ICPush(tempi,a1->type,a1->reg,a1->disp,ip2);
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
if (r2==REG_RSP+REG_RSP<<8)
d2+=8;
}
}
}
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
a2->type,a2->reg,a2->disp,ip2);
if (tempi->ic_flags&ICF_POP_CMP)
ICPopRegs(tempi,1<<REG_RDX);
else
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
a1->type,a1->reg,a1->disp,ip2);
ICU16(tempi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=TY_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
}
}
if (!dont_push_float) {
if (builtin1)
ICU16(tempi,builtin1);
else
ICSlashOp(tempi,t1,r1,d1,SLASH_OP_FLD,ip2);
}
if (!alt)
us=not_us;
if (builtin2)
ICU16(tempi,builtin2);
else
ICSlashOp(tempi,t2,r2,d2,SLASH_OP_FLD,ip2);
if (tempi->ic_flags&ICF_PUSH_CMP) {
t2=TY_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
if (!rsp_size) {
rsp_size=8;
ICAddRSP(tempi,-8);
} else if (rsp_size==16)
d2=8;
if (alt) {
ICU16(tempi,0xF1DF); //FCOMIP
ICSlashOp(tempi,t2,r2,d2,SLASH_OP_FSTP,ip2);
} else {
ICU16(tempi,0xF1DB); //FCOMI
ICSlashOp(tempi,t2,r2,d2,SLASH_OP_FSTP,ip2);
ICU32(tempi,0xF7D9C0DD); //FFREE,FINCSTP
}
} else {
ICU16(tempi,0xF1DF); //FCOMIP
ICU32(tempi,0xF7D9C0DD); //FFREE,FINCSTP
}
CmpNoteFloatOp(lx,tempi,TRUE,FALSE,CN_MAIN);
if (tempi->ic_flags&ICF_PUSH_CMP) {
if (r2.u8[0]==REG_RSP) {
while (d2 && rsp_size) {
ICU8(tempi,0x5B); //POP RBX (Dont change flags)
rsp_size-=8;
d2-=8;
}
} else {
while (rsp_size) {
ICU8(tempi,0x5B); //POP RBX (Dont change flags)
rsp_size-=8;
}
ICPush(tempi,t2,r2,d2,ip2);
}
} else {
while (rsp_size) {
ICU8(tempi,0x5B); //POP RBX (Dont change flags)
rsp_size-=8;
}
}
ip+=tempi->ic_cnt;
lb=OptLabelFwd(tempi->ic_data);
short_jmp=ToBool(tempi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP) {
if(tempi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
if (MIN_I8<=i<=MAX_I8)
short_jmp=TRUE;
}
if (short_jmp) {
tempi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(ip+2);
if (lb->flags&CMF_POP_CMP) {
if(tempi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tempi,i<<8+us.u8[2]);
} else {
tempi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(ip+6);
if (lb->flags&CMF_POP_CMP) {
if(tempi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tempi,us.u16[0]);
ICU32(tempi,i);
}
}
U0 ICFMul(CLex *lx,CIntermediateCode *tempi,U8 *buf,I64 ip)
{
if (tempi->a1.type&TY_MASK==TY_IMM &&
tempi->a1.type_pointed&RT_MASK==RT_F64 &&
tempi->a1.disp(F64)==1.0) {
CmpNoteFloatOp(lx,tempi,FALSE,FALSE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
} else if (tempi->a2.type&TY_MASK==TY_IMM &&
tempi->a2.type_pointed&RT_MASK==RT_F64 &&
tempi->a2.disp(F64)==1.0) {
CmpNoteFloatOp(lx,tempi,FALSE,FALSE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
} else
ICFOp(lx,tempi,SLASH_OP_FMUL,buf,ip);
}
U0 ICFDiv(CLex *lx,CIntermediateCode *tempi,U8 *buf,I64 ip)
{
if (tempi->a2.type&TY_MASK==TY_IMM &&
tempi->a2.type_pointed&RT_MASK==RT_F64 &&
tempi->a2.disp(F64)==1.0) {
CmpNoteFloatOp(lx,tempi,FALSE,FALSE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
} else
ICFOp(lx,tempi,SLASH_OP_FDIV,buf,ip);
}
U0 ICFAdd(CLex *lx,CIntermediateCode *tempi,U8 *buf,I64 ip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (tempi->a1.type&TY_MASK==TY_IMM &&
!tempi->a1.disp) {
if (dont_push_float) {
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else if (dont_pop_float) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_MAIN);
} else {
CmpNoteFloatOp(lx,tempi,TRUE,TRUE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a2.type,tempi->a2.reg,tempi->a2.disp,ip);
}
} else if (tempi->a2.type&TY_MASK==TY_IMM &&
!tempi->a2.disp) {
if (dont_push_float) {
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else if (dont_pop_float) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_MAIN);
} else {
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
CmpNoteFloatOp(lx,tempi,TRUE,TRUE,CN_MAIN);
}
} else
ICFOp(lx,tempi,SLASH_OP_FADD,buf,ip);
}
U0 ICFSub(CLex *lx,CIntermediateCode *tempi,U8 *buf,I64 ip)
{
Bool dont_push_float,dont_pop_float;
if (tempi->a2.type&TY_MASK==TY_IMM &&
!tempi->a2.disp) {
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_MAIN);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else if (dont_pop_float) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICCopyTemplate(lx,tempi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_MAIN);
} else {
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
CmpNoteFloatOp(lx,tempi,TRUE,TRUE,CN_MAIN);
}
} else
ICFOp(lx,tempi,SLASH_OP_FSUB,buf,ip);
}
U0 ICFPreIncDec(CLex *lx,CIntermediateCode *tempi,I64 op,I64 ip)
{
if (tempi->ic_flags & ICF_NOT_ADDR) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,ip);
ICCopyTemplate(lx,tempi,op,FALSE,TRUE,TRUE,CN_MAIN);
ICMov(tempi,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
TY_DISP+RT_I64,REG_RCX,0,ip);
ICCopyTemplate(lx,tempi,op,FALSE,TRUE,TRUE,CN_MAIN);
ICMov(tempi,TY_DISP+RT_I64,REG_RCX,0,
TY_REG+RT_I64,REG_RAX,0,ip);
}
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
U0 ICFPostIncDec(CLex *lx,CIntermediateCode *tempi,I64 op,I64 ip)
{
if (tempi->ic_flags & ICF_NOT_ADDR) {
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type&TY_MASK+RT_I64,tempi->a1.reg,tempi->a1.disp,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
TY_REG+RT_I64,REG_RAX,0,ip);
ICCopyTemplate(lx,tempi,op,FALSE,TRUE,TRUE,CN_MAIN);
ICMov(tempi,tempi->a1.type,tempi->a1.reg,tempi->a1.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
TY_DISP+RT_I64,REG_RCX,0,ip);
if (tempi->r.type&TY_MASK)
ICMov(tempi,TY_REG+RT_I64,REG_RDX,0,
TY_REG+RT_I64,REG_RAX,0,ip);
ICCopyTemplate(lx,tempi,op,FALSE,TRUE,TRUE,CN_MAIN);
ICMov(tempi,TY_DISP+RT_I64,REG_RCX,0,
TY_REG+RT_I64,REG_RAX,0,ip);
}
if (tempi->r.type&TY_MASK)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RDX,0,ip);
}
U0 ICFTemplateFun(CLex *lx,CIntermediateCode *tempi,I64 op,I64 ip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(lx,tempi,&dont_push_float,&dont_pop_float);
if (!dont_push_float)
ICMov(tempi,TY_REG+RT_I64,REG_RAX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICCopyTemplate(lx,tempi,op,FALSE,TRUE,TRUE,CN_MAIN);
if (tempi->r.type&TY_MASK && !(tempi->ic_flags & ICF_R_TO_F64) &&
!(tempi->ic_flags & ICF_R_TO_INT))
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_REG+RT_I64,REG_RAX,0,ip);
}
+677
View File
@@ -0,0 +1,677 @@
/*Intermediate Code
To
Machine Code
RAX,RBX,RCX and RDX can be clobbered by
each intermediate code's output code.
However, intermediate codes must be
coupled together based on the arg and
result type specifications in the
$LK,"CICArg",A="MN:CICArg"$. RAX is the most common reg
for coupling intermediate codes.
Internal calculations take place on
64-bit vals, so anything which has
found it's way into a reg has been
sign or zero extended to 64-bits.
*/
U0 ICU8(CIntermediateCode *tempi,U8 b)
{
tempi->ic_body[tempi->ic_cnt++]=b;
}
U0 ICRex(CIntermediateCode *tempi,U8 b)
{
if (b)
tempi->ic_body[tempi->ic_cnt++]=b;
}
U0 ICOpSizeRex(CIntermediateCode *tempi,U8 b)
{
tempi->ic_body[tempi->ic_cnt++]=OC_OP_SIZE_PREFIX;
if (b)
tempi->ic_body[tempi->ic_cnt++]=b;
}
U0 ICU16(CIntermediateCode *tempi,U16 w)
{
*(&tempi->ic_body[tempi->ic_cnt])(U16)=w;
tempi->ic_cnt+=2;
}
U0 ICU24(CIntermediateCode *tempi,U32 d)
{//Writes extra harmless overhanging byte.
*(&tempi->ic_body[tempi->ic_cnt])(U32)=d;
tempi->ic_cnt+=3;
}
U0 ICU32(CIntermediateCode *tempi,U32 d)
{
*(&tempi->ic_body[tempi->ic_cnt])(U32)=d;
tempi->ic_cnt+=4;
}
U0 ICU64(CIntermediateCode *tempi,U64 q)
{
*(&tempi->ic_body[tempi->ic_cnt])(U64)=q;
tempi->ic_cnt+=8;
}
CIntermediateCode *ICLastIns(CIntermediateCode *tempi)
{
if (tempi->ic_last_cnt>=0)
return tempi;
else if (!tempi->ic_cnt &&(tempi=OptLag1(tempi)) && tempi->ic_last_cnt>=0)
return tempi;
else
return NULL;
}
U0 ICAddRSP(CIntermediateCode *tempi,I64 i,Bool optimize=TRUE)
{
I64 j,last_cnt;
CIntermediateCode *tempil1;
if (optimize && (tempil1=ICLastIns(tempi))) {
j=tempil1->ic_cnt;
if (tempil1->ic_last_cnt==j-4 &&
tempil1->ic_body[j-3]==0x83 &&
tempil1->ic_body[j-4]==0x48) {
if (tempil1->ic_body[j-2]==0xEC)
j=-tempil1->ic_body[j-1](I8);
else if (tempil1->ic_body[j-2]==0xC4)
j=tempil1->ic_body[j-1](I8);
else
j=0;
} else if (tempil1->ic_last_cnt==j-7 &&
tempil1->ic_body[j-6]==0x81 &&
tempil1->ic_body[j-7]==0x48) {
if (tempil1->ic_body[j-5]==0xEC)
j=-tempil1->ic_body[j-4](I32);
else if (tempil1->ic_body[j-5]==0xC4)
j=tempil1->ic_body[j-4](I32);
else
j=0;
} else
j=0;
if (j) {
if (tempi==tempil1) {
tempi->ic_cnt=tempi->ic_last_cnt;
i+=j;
} else if (!(tempi->ic_flags&ICF_PREVIOUS_DELETED)) {
tempil1->ic_flags|=ICF_DEL_PREVIOUS_INS;
tempi->ic_flags=tempi->ic_flags&~ICF_CODE_FINAL|ICF_PREVIOUS_DELETED;
i+=j;
}
}
}
last_cnt=tempi->ic_cnt;
if (i>0) {
if (i<=MAX_I8)
ICU32(tempi,0xC48348+i<<24);
else if (i<=MAX_I32) {
ICU24(tempi,0xC48148);
ICU32(tempi,i);
} else
throw('Compiler');
} else if (i<0) {
i=-i;
if (i<=MAX_I8)
ICU32(tempi,0xEC8348+i<<24);
else if (i<=MAX_I32) {
ICU24(tempi,0xEC8148);
ICU32(tempi,i);
} else
throw('Compiler');
}
if (optimize && tempi->ic_cnt>last_cnt)
tempi->ic_last_cnt=last_cnt;
}
extern U0 ICMov(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,I64 t2,I64 r2,I64 d2,I64 ip);
#define MDR_REG 0
#define MDR_INDIRECT_REG 1
#define MDR_D8_INDIRECT_REG 2
#define MDR_D32_INDIRECT_REG 3
#define MDR_SIB_INDIRECT_REG 4
#define MDR_SIB_D8_INDIRECT_REG 5
#define MDR_SIB_D32_INDIRECT_REG 6
#define MDR_RIP_REL 7
I64 ICModr1(I64 r,I64 t2,I64 r2,I64 d2)
{
//result.u8[0] is type
//result.u8[1] is REX
//result.u8[2] is ModR
//result.u8[3] is SIB
I64 result=0;
if (t2&TY_MASK>TY_RIP_DISP32) {
"Callers:%P;%P\n",Caller,Caller(2);
throw('Compiler');
}
if (t2&RT_MASK<RT_I64)
result.u8[1]=0x40;
else
result.u8[1]=0x48;
if (r>7) {
result.u8[1]+=4;
r&=7;
}
switch (t2>>4) {
case TY_REG>>4:
if (r2>7) {
result.u8[1]++;
r2&=7;
}
result.u8[2]=0xC0+r<<3+r2;
result.u8[0]=MDR_REG;
if (result.u8[1]==0x40 &&
(t2&RT_MASK>=RT_I16 ||
r<4 && r2<4))
result.u8[1]=0;
break;
case TY_DISP>>4:
if (r2>7) {
result.u8[1]++;
r2&=7;
}
if (!d2 && r2!=REG_RBP) {
result.u8[2]=r<<3+r2;
result.u8[0]=MDR_INDIRECT_REG;
} else if (MIN_I8<=d2<=MAX_I8) {
result.u8[2]=0x40+r<<3+r2;
result.u8[0]=MDR_D8_INDIRECT_REG;
} else {
result.u8[2]=0x80+r<<3+r2;
result.u8[0]=MDR_D32_INDIRECT_REG;
}
if (result.u8[1]==0x40 &&
(t2&RT_MASK>=RT_I16 ||
r<4))
result.u8[1]=0;
break;
case TY_SIB>>4:
if (7<r2.u8[0]<REG_NONE)
result.u8[1]++;
if (r2.u8[1]&15>7)
result.u8[1]+=2;
if (r2.u8[0]==REG_NONE) {
result.u8[3]=5+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
result.u8[2]=4+r<<3;
result.u8[0]=MDR_SIB_D32_INDIRECT_REG;
} else {
result.u8[3]=r2.u8[0]&7+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
if (!d2 && r2.u8[0]&7!=REG_RBP) {
result.u8[2]=4+r<<3;
result.u8[0]=MDR_SIB_INDIRECT_REG;
} else if (MIN_I8<=d2<=MAX_I8) {
result.u8[2]=0x44+r<<3;
result.u8[0]=MDR_SIB_D8_INDIRECT_REG;
} else {
result.u8[2]=0x84+r<<3;
result.u8[0]=MDR_SIB_D32_INDIRECT_REG;
}
}
if (result.u8[1]==0x40 &&
(t2&RT_MASK>=RT_I16 ||
r<4))
result.u8[1]=0;
break;
case TY_RIP_DISP32>>4:
result.u8[2]=0x05+r<<3;
result.u8[0]=MDR_RIP_REL;
if (result.u8[1]==0x40 &&
(t2&RT_MASK>=RT_I16 ||
r<4))
result.u8[1]=0;
break;
}
return result;
}
U0 ICModr2(CIntermediateCode *tempi,I64 i,I64 d,I64 ip=0)
{//t=0 means no SIB
nobound_switch (i.u8[0]) {
case MDR_REG:
break;
case MDR_INDIRECT_REG:
break;
case MDR_D8_INDIRECT_REG:
ICU8(tempi,d);
break;
case MDR_D32_INDIRECT_REG:
ICU32(tempi,d);
break;
case MDR_SIB_INDIRECT_REG:
ICU8(tempi,i.u8[3]);
break;
case MDR_SIB_D8_INDIRECT_REG:
ICU8(tempi,i.u8[3]);
ICU8(tempi,d);
break;
case MDR_SIB_D32_INDIRECT_REG:
ICU8(tempi,i.u8[3]);
ICU32(tempi,d);
break;
case MDR_RIP_REL:
ICU32(tempi,d-(ip+tempi->ic_cnt));
tempi->ic_flags&=~ICF_CODE_FINAL;
break;
}
}
#define SLASH_OP_INC 0x0003000000FFFE00
#define SLASH_OP_DEC 0x052B000000FFFE01
#define SLASH_OP_NOT 0x0000000000F7F602
#define SLASH_OP_NEG 0x0000000000F7F603
#define SLASH_OP_MUL 0x0000000000F7F604
#define SLASH_OP_IMUL 0x0000000000F7F605
#define SLASH_OP_DIV 0x0000000000F7F606
#define SLASH_OP_MOV 0x0000000000898800
#define SLASH_OP_PUSH 0x0000000000FFFF06
#define SLASH_OP_POP 0x00000000008F8F00
#define SLASH_OP_FADD 0x0000C1DE01DCDC00
#define SLASH_OP_FSUB 0x0000E9DE01DCDC04
#define SLASH_OP_FSUBR 0x0000E1DE01DCDC05
#define SLASH_OP_FMUL 0x0000C9DE01DCDC01
#define SLASH_OP_FDIV 0x0000F9DE01DCDC06
#define SLASH_OP_FDIVR 0x0000F1DE01DCDC07
#define SLASH_OP_FLD 0x0000000001DDDD00
#define SLASH_OP_FSTP 0x0000000001DDDD03
#define SLASH_OP_FISTTP 0x0000000001DDDD01
#define SLASH_OP_FILD 0x0000000001DFDF05
U0 ICSlashOp(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,I64 op,I64 ip)
{
I64 i;
if (t1&TY_MASK==TY_REG && !op.u8[3])
t1=t1&(TY_MASK|1)+RT_I64; //Set to 64 bit, preserving signed/unsigned
i=ICModr1(op.u8[0],t1,r1,d1);
if (tempi->ic_flags&ICF_LOCK && op!=SLASH_OP_MOV && t1&TY_MASK!=TY_REG)
ICU8(tempi,OC_LOCK_PREFIX);
switch (t1&RT_MASK) {
case RT_I8:
case RT_U8:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+op.u8[1]);
break;
case RT_I16:
case RT_U16:
ICOpSizeRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+op.u8[2]);
break;
default:
if (i.u8[1]!=0x48 || !op.u8[3])
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+op.u8[2]);
}
ICModr2(tempi,i,d1,ip+4);
}
U0 ICPush(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,I64 ip)
{
switch (t1>>4) {
case TY_REG>>4:
if (r1>7)
ICU16(tempi,0x5049+(r1&7)<<8);
else
ICU8(tempi,0x50+r1);
return;
case TY_IMM>>4:
if (MIN_I8<=d1<=MAX_I8)
ICU16(tempi,0x6A+d1<<8);
else if (MIN_I32<=d1<=MAX_I32) {
ICU8(tempi,0x68);
ICU32(tempi,d1);
} else {
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,t1,r1,d1,ip);
ICU8(tempi,0x50+REG_RBX);
}
return;
case TY_STK>>4:
return;
case TY_DISP>>4:
case TY_SIB>>4:
case TY_RIP_DISP32>>4:
switch (t1&RT_MASK) {
case RT_I64:
case RT_U64:
case RT_F64:
ICSlashOp(tempi,t1,r1,d1,SLASH_OP_PUSH,ip);
return;
}
break;
}
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,t1,r1,d1,ip);
ICU16(tempi,0x5048+REG_RBX<<8);
}
U0 ICPushRegs(CIntermediateCode *tempi,I64 mask)
{
I64 i;
for (i=0;i<NUM_REGS;i++) {
if (Bt(&mask,i)) {
if (i>7)
ICU16(tempi,0x5049+(i&7)<<8);
else
ICU8(tempi,0x50+i);
}
}
}
U0 ICPop(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,I64 ip)
{
switch (t1>>4) {
case TY_NULL>>4:
ICAddRSP(tempi,8);
break;
case TY_REG>>4:
if (r1>7)
ICU16(tempi,0x5849+(r1&7)<<8);
else
ICU8(tempi,0x58+r1);
break;
case TY_DISP>>4:
case TY_RIP_DISP32>>4:
case TY_SIB>>4:
if (t1&RT_MASK<RT_I64) {
ICU8(tempi,0x58+REG_RBX);
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,REG_RBX,0,ip);
} else
ICSlashOp(tempi,t1,r1,d1,SLASH_OP_POP,ip);
break;
default:
ICU8(tempi,0x58+REG_RBX);
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,REG_RBX,0,ip);
}
}
U0 ICPopRegs(CIntermediateCode *tempi,I64 mask)
{
I64 i;
for (i=NUM_REGS-1;i>=0;i--) {
if (Bt(&mask,i)) {
if (i>7)
ICU16(tempi,0x5849+(i&7)<<8);
else
ICU8(tempi,0x58+i);
}
}
}
U0 ICZero(CIntermediateCode *tempi,I64 r)
{
if (r>7) {
r&=7;
ICU24(tempi,0xC0334D+r<<16+r<<19);
} else
ICU16(tempi,0xC033+r<<8+r<<11);
}
U0 ICTest(CIntermediateCode *tempi,I64 r)
{
I64 i=0xC08548; //TEST R,R
if (r>7) {
i+=5;
r&=7;
}
ICU24(tempi,i+r<<16+r<<19);
}
I64 ICBuiltInFloatConst(F64 d)
{ //Returns 2-byte opcode for FLD const or zero
if (!d)
return 0xEED9;
else if (d==1.0)
return 0xE8D9;
else if (GetOpt(OPTf_NO_BUILTIN_CONST))
return 0;
else if (d==ã)
return 0xEBD9;
else if (d==log2_10)
return 0xE9D9;
else if (d==log2_e)
return 0xEAD9;
else if (d==log10_2)
return 0xECD9;
else if (d==loge_2)
return 0xEDD9;
else
return 0;
}
U0 ICMov(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,I64 t2,I64 r2,I64 d2,I64 ip)
{
I64 i,j,last_cnt=tempi->ic_cnt;
CIntermediateCode *tempil1;
Bool old_lock=Btr(&tempi->ic_flags,ICf_LOCK);
switch (t1>>4) {
case TY_REG>>4:
if (t2&TY_MASK==TY_IMM) {
if (!d2)
ICZero(tempi,r1);
else if (0<=d2<=MAX_U8) {
ICZero(tempi,r1);
if (r1>7)
ICU24(tempi,d2<<16+(0xB0+r1&7)<<8+0x41);
else if (r1>3)
ICU24(tempi,d2<<16+(0xB0+r1)<<8+0x40);
else
ICU16(tempi,d2<<8+0xB0+r1);
} else if (MIN_I8<=d2<0) {
if (r1>7) {
r1&=7;
ICU24(tempi,d2<<16+(0xB0+r1)<<8+0x41);
ICU32(tempi,0xC0BE0F4D+r1<<24+r1<<27);
} else {
if (r1>3)
ICU24(tempi,d2<<16+(0xB0+r1)<<8+0x40);
else
ICU16(tempi,d2<<8+0xB0+r1);
ICU32(tempi,0xC0BE0F48+r1<<24+r1<<27);
}
} else if (0<=d2<=MAX_U32) {
if (r1>7) {
r1&=7;
ICU16(tempi,(0xB8+r1)<<8+0x41);
ICU32(tempi,d2);
} else {
ICU8(tempi,0xB8+r1);
ICU32(tempi,d2);
}
} else if (MIN_I32<=d2<0) {
if (r1>7) {
r1&=7;
ICU16(tempi,(0xB8+r1)<<8+0x41);
ICU32(tempi,d2);
ICU24(tempi,0xC0634D+r1<<16+r1<<19);
} else {
ICU8(tempi,0xB8+r1);
ICU32(tempi,d2);
ICU24(tempi,0xC06348+r1<<16+r1<<19);
}
} else {
i=0xB848;
if (r1>7) {
i++;
r1&=7;
}
ICU16(tempi,i+r1<<8);
ICU64(tempi,d2);
}
} else if (t2&TY_MASK==TY_STK)
ICPop(tempi,t1,r1,d1,ip);
else {
if (r1==r2 && t2&TY_MASK==TY_REG)
goto move_done;
if (t2&TY_MASK==TY_REG) {
t2=TY_REG+RT_I64;
if (tempil1=ICLastIns(tempi)) {
i=tempil1->ic_cnt;
j=0x48+(r1>7);
if (r2>7) j+=4;
if (tempil1->ic_last_cnt==i-3 &&
tempil1->ic_body[i-2]==0x8B &&
tempil1->ic_body[i-1]==0xC0+r1&7+(r2&7)<<3 &&
tempil1->ic_body[i-3]==j ) {
goto move_done;
}
}
}
i=ICModr1(r1,t2,r2,d2);
if (t2&RT_MASK!=RT_U32)
i|=0x4800;
ICRex(tempi,i.u8[1]);
switch (t2&RT_MASK) {
case RT_I8:
ICU24(tempi,i.u8[2]<<16+0xBE0F);
break;
case RT_I16:
ICU24(tempi,i.u8[2]<<16+0xBF0F);
break;
case RT_I32:
ICU16(tempi,i.u8[2]<<8+0x63);
break;
case RT_U8:
ICU24(tempi,i.u8[2]<<16+0xB60F);
break;
case RT_U16:
ICU24(tempi,i.u8[2]<<16+0xB70F);
break;
default:
ICU16(tempi,i.u8[2]<<8+0x8B);
}
ICModr2(tempi,i,d2,ip+4);
}
break;
case TY_STK>>4:
if (t1&RT_MASK<t2&RT_MASK)
ICPush(tempi,t2&TY_MASK+t1&RT_MASK,r2,d2,ip);
else
ICPush(tempi,t2,r2,d2,ip);
break;
case TY_DISP>>4:
case TY_RIP_DISP32>>4:
case TY_SIB>>4:
if (t2&TY_MASK==TY_IMM &&
(t1&RT_MASK<RT_I64 || (MIN_I32<=d2<=MAX_I32))) {
i=ICModr1(0,t1,r1,d1);
switch (t1&RT_MASK) {
case RT_I8:
case RT_U8:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xC6);
break;
case RT_U16:
case RT_I16:
ICOpSizeRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xC7);
break;
default:
ICRex(tempi,i.u8[1]);
ICU16(tempi,i.u8[2]<<8+0xC7);
}
if (i.u8[0]!=MDR_RIP_REL)
ICModr2(tempi,i,d1,);
else {
i=d1-(ip+tempi->ic_cnt+4);
switch (t1&RT_MASK) {
case RT_I8:
case RT_U8:
i--;
break;
case RT_I16:
case RT_U16:
i-=2;
break;
default:
i-=4;
}
ICU32(tempi,i);
tempi->ic_flags&=~ICF_CODE_FINAL;
}
switch (t1&RT_MASK) {
case RT_I8:
case RT_U8:
ICU8(tempi,d2);
break;
case RT_I16:
case RT_U16:
ICU16(tempi,d2);
break;
default:
ICU32(tempi,d2);
}
} else {
if (t2&TY_MASK==TY_REG)
ICSlashOp(tempi,t1,r1,d1,r2+SLASH_OP_MOV,ip);
else {
ICMov(tempi,TY_REG+RT_I64,REG_RBX,0,t2,r2,d2,ip);
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,REG_RBX,0,ip);
}
}
break;
}
move_done:
BEqu(&tempi->ic_flags,ICf_LOCK,old_lock);
if (tempi->ic_cnt>last_cnt>tempi->ic_last_cnt)
tempi->ic_last_cnt=last_cnt;
}
U0 ICLea(CIntermediateCode *tempi,I64 t1,I64 r1,I64 d1,I64 t2,I64 r2,I64 d2,CLex *lx,U8 *buf,I64 ip)
{
I64 i;
CExeAbsAddr *tempa;
switch (t1>>4) {
case TY_REG>>4:
i=ICModr1(r1,t2,r2,d2);
i.u8[1]|=0x48;
ICU24(tempi,i.u8[2]<<16+0x8D00+i.u8[1]);
ICModr2(tempi,i,d2,ip+4);
break;
case TY_STK>>4:
if (t2&TY_MASK==TY_RIP_DISP32) {
ICU8(tempi,0x68);
ICU32(tempi,d2);
if (lx->flags&LF_AOT_COMPILE && buf && !(lx->flags&LF_NO_ABSS)) {
tempa=CAlloc(sizeof(CExeAbsAddr));
tempa->next=lx->a->abss;
tempa->type=EAT_ADD_U32;
lx->a->abss=tempa;
tempa->ip=ip+tempi->ic_cnt-4;
}
tempi->ic_flags&=~ICF_CODE_FINAL;
} else {
ICLea(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,lx,buf,ip);
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,REG_RCX,0,ip);
}
break;
default:
ICLea(tempi,TY_REG+RT_I64,REG_RCX,0,t2,r2,d2,lx,buf,ip);
ICMov(tempi,t1,r1,d1,TY_REG+RT_I64,REG_RCX,0,ip);
}
}
U0 ICDeref(CIntermediateCode *tempi,I64 ip)
{
I64 t;
t=tempi->r.type&RT_MASK;
if (t>tempi->a1.type_pointed)
t=tempi->a1.type_pointed;
if (tempi->a1.type&TY_MASK==TY_REG)
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_DISP+t,tempi->a1.reg,tempi->a1.disp,ip);
else {
ICMov(tempi,TY_REG+RT_I64,REG_RCX,0,
tempi->a1.type,tempi->a1.reg,tempi->a1.disp,ip);
ICMov(tempi,tempi->r.type,tempi->r.reg,tempi->r.disp,
TY_DISP+t,REG_RCX,0,ip);
}
}
+77
View File
@@ -0,0 +1,77 @@
#help_index "Compiler/Lex"
#help_file "::/Doc/Lex"
public extern CLex *LexNew(U8 *buf=NULL,I64 flags=0,U8 *filename=NULL);
public extern U0 LexDel(CLex *lx);
public extern I64 LexSize(CLex *lx);
public extern U0 LexPutToken(CLex *lx);
public extern I64 LexGetChar(CLex *lx);
public extern U0 LexSkipEol(CLex *lx);
public extern U0 LexPush(CLex *lx);
public extern U0 LexPop(CLex *lx);
public extern I64 Lex(CLex *lx);
public extern U8 *LexExtStr(CLex *lx,I64 *_size=NULL);
public extern U0 LexPutLine(CLex *lx,U8 *start);
public extern U0 LexPutPos(CLex *lx);
public extern I64 PrsKeyWord(CLex *lx);
public extern U0 LexWarn(CLex *lx,U8 *str=NULL);
public extern U0 LexExcept(CLex *lx,U8 *str=NULL);
public extern U8 *LexExpression2Bin(CLex *lx,I64 *_type=NULL);
public extern U8 *LexStatement2Bin(CLex *lx,I64 *_type,I64 cmp_flags=CMPF_PRS_SEMICOLON);
public extern I64 IsLexExpression2Bin(CLex *lx,U8 **ex); //FALSE=no err
public extern I64 LexExpression(CLex *lx);
public extern I64 MemberMetaData(U8 *st,CMemberLst *ml);
extern U0 MemberLstDel(CHashClass *c);
public extern CMemberLstMeta *MemberMetaFind(U8 *st,CMemberLst *ml);
public extern CMemberLst *MemberFind(U8 *needle_str,CHashClass *haystack_class);
public extern CMemberLst *MemberFind2(CHashClass *needle_class,CHashClass *haystack_class);
public extern U0 LexAttachDoc(CLex *lx,CLexFile *tempf=NULL,
CDoc *doc=NULL,U8 *abs_filename=NULL,CDocEntry *doc_e=NULL,I64 col=0);
public extern CHashClass *OptClassFwd(CHashClass *tempc);
#help_index "Compiler/Directive"
#help_file "::/Doc/Directives"
public extern U0 StreamPrint(U8 *fmt,...);
public extern I64 StreamExePrint(U8 *fmt,...);
public extern Bool OTrace(Bool val);
public extern I64 OTraceMask(I64 i=0b1001111101);
public extern Bool OptEqu(I64 num,Bool val);
public extern Bool OptOn(I64 num);
public extern Bool OptOff(I64 num);
public extern Bool GetOpt(I64 num);
public extern Bool CTrace(Bool val);
public extern Bool Echo(Bool val);
public extern U0 ImportHashTable(CHashTable *tempht);
public extern I64 IncludeDepth();
#help_index "Hash"
extern CHashSrcSym *HashEntryImportCopy(CHashSrcSym *temph);
extern U0 HashTableImport(CHashTable *src,CHashTable *dst);
public extern I64 HashEntrySize(CHashSrcSym *temph);
public extern I64 HashEntrySize2(CHashSrcSym *temph);
public extern I64 HashTableSize2(CHashTable *table);
#help_index "Compiler;Cmd Line (Typically)"
public extern I64 Cmp(U8 *filename,U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv=0);
#help_index "Compiler"
public extern I64 ExePutS(U8 *buf,U8 *filename=NULL,Bool just_load=FALSE,
CLexHashTableContext *htc=NULL);
public extern I64 ExePrint(U8 *fmt,...);
public extern I64 ExeFile(U8 *name,Bool just_load=FALSE);
public extern I64 ExePutS2(U8 *buf,U8 *filename=NULL,Bool just_load=FALSE);
public extern I64 ExePrint2(U8 *fmt,...);
public extern I64 ExeFile2(U8 *name,Bool just_load=FALSE);
extern CHashTable *asm_hash;
extern U0 CmpInit(Bool first);
extern I64 compiled_lines,compiled_funs,compiled_bytes;
//The following is for benchmarking
extern Bool cmp_do_not_write_to_dsk;
#help_index "Debugging/Dump"
public extern U0 Ui(U8 *buf,U8 **_ip,I64 seg_size=64,I64 *_jmp_dst=NULL,Bool just_ins=FALSE);
public extern U8 *U(U8 *ip,I64 cnt=20,I64 seg_size=64);
public extern I64 Un(U8 *ip,I64 cnt=0x80,I64 seg_size=64);
#help_index ""
+526
View File
@@ -0,0 +1,526 @@
asm {
USE64
// ************************************
CMP_TEMPLATES::
DU32 @@05,@@10,@@15,@@25,@@30,
@@35,@@40,@@45,@@55,@@60,
@@75,@@80,@@85,@@90,@@95,
@@100,@@105,@@110,@@115,@@125,
@@135;
@@05: //INC
PUSH RAX
FLD1
FADD ST0,U64 [RSP]
FSTP U64 [RSP]
POP RAX
@@10: //DEC
PUSH RAX
FLD1
FSUBR ST0,U64 [RSP]
FSTP U64 [RSP]
POP RAX
@@15: //MOD
PUSH RDX
PUSH RAX
MOV RBX,RSP
FLD U64 [RBX]
FLD U64 8[RBX]
@@20: FPREM
FSTSW
TEST AX,0x400
JNZ @@20
FSTP U64 [RBX]
FFREE ST0
FINCSTP
POP RAX
ADD RSP,8
@@25: //LESS
PUSH RDX
PUSH RAX
FLD U64 [RSP]
FLD U64 8[RSP]
FCOMIP ST0,ST1
MOV RAX,0
ADC RAX,0
FFREE ST0
FINCSTP
ADD RSP,16
@@30: //GREATER
PUSH RDX
PUSH RAX
FLD U64 8[RSP]
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,0
ADC RAX,0
FFREE ST0
FINCSTP
ADD RSP,16
@@35: //LESS_EQUAL
PUSH RDX
PUSH RAX
FLD U64 8[RSP]
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,1
SBB RAX,0
FFREE ST0
FINCSTP
ADD RSP,16
@@40: //GREATER_EQUAL
PUSH RDX
PUSH RAX
FLD U64 [RSP]
FLD U64 8[RSP]
FCOMIP ST0,ST1
MOV RAX,1
SBB RAX,0
FFREE ST0
FINCSTP
ADD RSP,16
@@45: //StrLen
MOV RDX,RAX
@@50: MOV BL,U8 [RAX]
INC RAX
TEST BL,BL
JNZ @@50
SUB RAX,RDX
DEC RAX
@@55: //RDTSC
RDTSC
SHL RDX,32
ADD RAX,RDX
@@60: //SignI64
TEST RAX,RAX
JZ @@70
JS @@65
MOV RAX,1
JMP @@70
@@65: MOV RAX,-1
@@70:
@@75:
@@80:
@@85:
MOV EAX,HPET_MAIN_CNT
MOV RAX,U64 [RAX]
@@90: //Sqr
PUSH RAX
FLD U64 [RSP]
FMUL ST0,ST0
FSTP U64 [RSP]
POP RAX
@@95: //Abs
PUSH RAX
FLD U64 [RSP]
FABS
FSTP U64 [RSP]
POP RAX
@@100: //Sqrt
PUSH RAX
FLD U64 [RSP]
FSQRT
FSTP U64 [RSP]
POP RAX
@@105: //Sin
PUSH RAX
FLD U64 [RSP]
FSIN
FSTP U64 [RSP]
POP RAX
@@110: //Cos
PUSH RAX
FLD U64 [RSP]
FCOS
FSTP U64 [RSP]
POP RAX
@@115: //Tan
PUSH RAX
FLD U64 [RSP]
@@120: FPTAN
FSTSW
TEST AX,0x400
JNZ @@120
FFREE ST0
FINCSTP
FSTP U64 [RSP]
POP RAX
@@125: //Atan
PUSH RAX
FLD U64 [RSP]
FLD1
@@130: FPATAN
FSTSW
TEST AX,0x400
JNZ @@130
FSTP U64 [RSP]
POP RAX
@@135:
// ************************************
CMP_TEMPLATES_DONT_POP::
DU32 @@05,@@10,@@15,@@20,@@25,
@@30,@@35,@@40,@@45,@@50,
@@55,@@60,@@65,@@70,@@75,
@@80,@@85,@@90,@@95,@@105,
@@115;
@@05: //INC
PUSH RAX
FLD1
FADD ST0,U64 [RSP]
FST U64 [RSP]
POP RAX
@@10: //DEC
PUSH RAX
FLD1
FSUBR ST0,U64 [RSP]
FST U64 [RSP]
POP RAX
@@15:
@@20:
@@25:
@@30:
@@35:
@@40:
@@45:
@@50:
@@55:
@@60:
PUSH RAX
FLD U64 [RSP]
ADD RSP,8
@@65:
@@70: //Sqr
PUSH RAX
FLD U64 [RSP]
FMUL ST0,ST0
ADD RSP,8
@@75: //Abs
PUSH RAX
FLD U64 [RSP]
FABS
ADD RSP,8
@@80: //Sqrt
PUSH RAX
FLD U64 [RSP]
FSQRT
ADD RSP,8
@@85: //Sin
PUSH RAX
FLD U64 [RSP]
FSIN
ADD RSP,8
@@90: //Cos
PUSH RAX
FLD U64 [RSP]
FCOS
ADD RSP,8
@@95: //Tan
PUSH RAX
FLD U64 [RSP]
@@100: FPTAN
FSTSW
TEST AX,0x400
JNZ @@100
FFREE ST0
FINCSTP
ADD RSP,8
@@105: //Atan
PUSH RAX
FLD U64 [RSP]
FLD1
@@110: FPATAN
FSTSW
TEST AX,0x400
JNZ @@110
ADD RSP,8
@@115:
// ************************************
CMP_TEMPLATES_DONT_PUSH::
DU32 @@05,@@10,@@15,@@20,@@30,
@@35,@@40,@@50,@@55,@@60,
@@65,@@70,@@75,@@80,@@85,
@@90,@@95,@@100,@@105,@@115,
@@125;
@@05: //INC
SUB RSP,8
FLD1
FADDP ST1,ST0
FSTP U64 [RSP]
POP RAX
@@10: //DEC
SUB RSP,8
FLD1
FSUBP ST1,ST0
FSTP U64 [RSP]
POP RAX
@@15:
@@20: //LESS
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,0
JZ @@25
MOV RAX,1
SBB RAX,0
@@25: FFREE ST0
FINCSTP
ADD RSP,8
@@30: //GREATER
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,0
ADC RAX,0
FFREE ST0
FINCSTP
ADD RSP,8
@@35: //LESS_EQUAL
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,1
SBB RAX,0
FFREE ST0
FINCSTP
ADD RSP,8
@@40: //GREATER_EQUAL
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,1
JZ @@45
MOV RAX,0
ADC RAX,0
@@45: FFREE ST0
FINCSTP
ADD RSP,8
@@50:
@@55:
@@60:
@@65: //FSTP
SUB RSP,8
FSTP U64 [RSP]
POP RAX
@@70:
@@75:
@@80: //Sqr
SUB RSP,8
FMUL ST0,ST0
FSTP U64 [RSP]
POP RAX
@@85: //Abs
SUB RSP,8
FABS
FSTP U64 [RSP]
POP RAX
@@90: //Sqrt
SUB RSP,8
FSQRT
FSTP U64 [RSP]
POP RAX
@@95: //Sin
SUB RSP,8
FSIN
FSTP U64 [RSP]
POP RAX
@@100: //Cos
SUB RSP,8
FCOS
FSTP U64 [RSP]
POP RAX
@@105: //Tan
SUB RSP,8
@@110: FPTAN
FSTSW
TEST AX,0x400
JNZ @@110
FFREE ST0
FINCSTP
FSTP U64 [RSP]
POP RAX
@@115: //Atan
SUB RSP,8
FLD1
@@120: FPATAN
FSTSW
TEST AX,0x400
JNZ @@120
FSTP U64 [RSP]
POP RAX
@@125:
// ************************************
CMP_TEMPLATES_DONT_PUSH_POP::
DU32 @@05,@@10,@@15,@@20,@@25,
@@30,@@35,@@40,@@45,@@50,
@@55,@@60,@@65,@@70,@@75,
@@80,@@85,@@90,@@95,@@100,
@@110;
@@05: //INC
SUB RSP,8
FLD1
FADDP ST1,ST0
FST U64 [RSP]
POP RAX
@@10: //DEC
SUB RSP,8
FLD1
FSUBP ST1,ST0
FST U64 [RSP]
POP RAX
@@15:
@@20:
@@25:
@@30:
@@35:
@@40:
@@45:
@@50:
@@55:
@@60:
@@65:
@@70: //Sqr
FMUL ST0,ST0
@@75: //Abs
FABS
@@80: //Sqrt
FSQRT
@@85: //Sin
FSIN
@@90: //Cos
FCOS
@@95: //Tan
FPTAN
FSTSW
TEST AX,0x400
JNZ @@95
FFREE ST0
FINCSTP
@@100: //Atan
FLD1
@@105: FPATAN
FSTSW
TEST AX,0x400
JNZ @@105
@@110:
// ************************************
CMP_TEMPLATES_DONT_PUSH2::
DU32 @@05,@@10,@@15,@@20,@@25,
@@35,@@45,@@50,@@55,@@60,
@@65,@@70,@@75,@@80,@@85,
@@90,@@95,@@100,@@105,@@110,
@@115;
@@05:
@@10:
@@15:
@@20: //LESS
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,0
ADC RAX,0
FFREE ST0
FINCSTP
ADD RSP,8
@@25: //GREATER
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,0
JZ @@30
MOV RAX,1
SBB RAX,0
@@30: FFREE ST0
FINCSTP
ADD RSP,8
@@35: //LESS_EQUAL
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,1
JZ @@40
MOV RAX,0
ADC RAX,0
@@40: FFREE ST0
FINCSTP
ADD RSP,8
@@45: //GREATER_EQUAL
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,1
SBB RAX,0
FFREE ST0
FINCSTP
ADD RSP,8
@@50:
@@55:
@@60:
@@65:
@@70:
@@75:
@@80:
@@85:
@@90:
@@95:
@@100:
@@105:
@@110:
@@115:
}
+391
View File
@@ -0,0 +1,391 @@
//Intermediate compiler codes
#define IC_END 0x00
#define IC_NOP1 0x01
#define IC_END_EXP 0x02
#define IC_NOP2 0x03
#define IC_LABEL 0x04
#define IC_CALL_START 0x05
#define IC_CALL_END 0x06
#define IC_CALL_END2 0x07
#define IC_RETURN_VAL 0x08
#define IC_RETURN_VAL2 0x09
#define IC_IMM_U64 0x0A
#define IC_IMM_F64 0x0B
#define IC_STR_CONST 0x0C
#define IC_ABS_ADDR 0x0D
#define IC_ADDR_IMPORT 0x0E
#define IC_HEAP_GLBL 0x0F
#define IC_SIZEOF 0x10
#define IC_TYPE 0x11
#define IC_GET_LABEL 0x12
#define IC_RBP 0x13
#define IC_REG 0x14
#define IC_FS 0x15
#define IC_MOV_FS 0x16
#define IC_GS 0x17
#define IC_MOV_GS 0x18
#define IC_LEA 0x19
#define IC_MOV 0x1A
#define IC_TO_I64 0x1B
#define IC_TO_F64 0x1C
#define IC_TO_BOOL 0x1D
#define IC_TOUPPER 0x1E
#define IC_HOLYC_TYPECAST 0x1F
#define IC_ADDR 0x20
#define IC_COM 0x21
#define IC_NOT 0x22
#define IC_UNARY_MINUS 0x23
#define IC_DEREF 0x24
#define IC_DEREF_PP 0x25
#define IC_DEREF_MM 0x26
#define IC__PP 0x27
#define IC__MM 0x28
#define IC_PP_ 0x29
#define IC_MM_ 0x2A
#define IC_SHL 0x2B
#define IC_SHR 0x2C
#define IC_SHL_CONST 0x2D
#define IC_SHR_CONST 0x2E
#define IC_POWER 0x2F
#define IC_MUL 0x30
#define IC_DIV 0x31
#define IC_MOD 0x32
#define IC_AND 0x33
#define IC_OR 0x34
#define IC_XOR 0x35
#define IC_ADD 0x36
#define IC_SUB 0x37
#define IC_ADD_CONST 0x38
#define IC_SUB_CONST 0x39
#define IC_EQUAL_EQUAL 0x3A
#define IC_NOT_EQUAL 0x3B
#define IC_LESS 0x3C
#define IC_GREATER 0x3D
#define IC_LESS_EQUAL 0x3E
#define IC_GREATER_EQUAL 0x3F
#define IC_PUSH_CMP 0x40
#define IC_AND_AND 0x41
#define IC_OR_OR 0x42
#define IC_XOR_XOR 0x43
#define IC_ASSIGN 0x44
#define IC_ASSIGN_PP 0x45
#define IC_ASSIGN_MM 0x46
#define IC_SHL_EQUAL 0x47
#define IC_SHR_EQUAL 0x48
#define IC_MUL_EQUAL 0x49
#define IC_DIV_EQUAL 0x4A
#define IC_MOD_EQUAL 0x4B
#define IC_AND_EQUAL 0x4C
#define IC_OR_EQUAL 0x4D
#define IC_XOR_EQUAL 0x4E
#define IC_ADD_EQUAL 0x4F
#define IC_SUB_EQUAL 0x50
#define IC_JMP 0x51
#define IC_SUB_CALL 0x52
#define IC_SWITCH 0x53
#define IC_NOBOUND_SWITCH 0x54
#define IC_ADD_RSP 0x55
#define IC_ADD_RSP1 0x56
#define IC_ENTER 0x57
#define IC_PUSH_REGS 0x58
#define IC_POP_REGS 0x59
#define IC_LEAVE 0x5A
#define IC_RET 0x5B
#define IC_CALL 0x5C
#define IC_CALL_INDIRECT 0x5D
#define IC_CALL_INDIRECT2 0x5E
#define IC_CALL_IMPORT 0x5F
#define IC_CALL_EXTERN 0x60
#define IC_ASM 0x61
#define IC_PREEMPT 0x62
#define IC_PUSH 0x63
#define IC_POP 0x64
#define IC_CLFLUSH 0x65
#define IC_INVLPG 0x66
#define IC_IN_U8 0x67
#define IC_IN_U16 0x68
#define IC_IN_U32 0x69
#define IC_OUT_U8 0x6A
#define IC_OUT_U16 0x6B
#define IC_OUT_U32 0x6C
#define IC_GET_RFLAGS 0x6D
#define IC_CARRY 0x6E
#define IC_SET_RFLAGS 0x6F
#define IC_GET_RAX 0x70
#define IC_SET_RAX 0x71
#define IC_GET_RBP 0x72
#define IC_SET_RBP 0x73
#define IC_GET_RSP 0x74
#define IC_SET_RSP 0x75
#define IC_RIP 0x76
#define IC_RDTSC 0x77
#define IC_HPET 0x78
#define IC_BT 0x79
#define IC_BTS 0x7A
#define IC_BTR 0x7B
#define IC_BTC 0x7C
#define IC_LBTS 0x7D
#define IC_LBTR 0x7E
#define IC_LBTC 0x7F
#define IC_BSF 0x80
#define IC_BSR 0x81
#define IC_QUE_INIT 0x82
#define IC_QUE_INS 0x83
#define IC_QUE_INS_REV 0x84
#define IC_QUE_REM 0x85
#define IC_STRLEN 0x86
#define IC_BR_ZERO 0x87
#define IC_BR_NOT_ZERO 0x88
#define IC_BR_CARRY 0x89
#define IC_BR_NOT_CARRY 0x8A
#define IC_BR_NOT_EQUAL 0x8B
#define IC_BR_EQUAL_EQUAL 0x8C
#define IC_BR_GREATER_EQUAL 0x8D
#define IC_BR_LESS_EQUAL 0x8E
#define IC_BR_GREATER 0x8F
#define IC_BR_LESS 0x90
#define IC_BR_NOT_EQUAL2 0x91
#define IC_BR_EQUAL_EQUAL2 0x92
#define IC_BR_GREATER_EQUAL2 0x93
#define IC_BR_LESS_EQUAL2 0x94
#define IC_BR_GREATER2 0x95
#define IC_BR_LESS2 0x96
#define IC_BR_AND_ZERO 0x97
#define IC_BR_AND_NOT_ZERO 0x98
#define IC_BR_MM_ZERO 0x99
#define IC_BR_MM_NOT_ZERO 0x9A
#define IC_BR_AND_AND_ZERO 0x9B
#define IC_BR_AND_AND_NOT_ZERO 0x9C
#define IC_BR_OR_OR_ZERO 0x9D
#define IC_BR_OR_OR_NOT_ZERO 0x9E
#define IC_BR_BT 0x9F
#define IC_BR_BTS 0xA0
#define IC_BR_BTR 0xA1
#define IC_BR_BTC 0xA2
#define IC_BR_LBTS 0xA3
#define IC_BR_LBTR 0xA4
#define IC_BR_LBTC 0xA5
#define IC_BR_NOT_BT 0xA6
#define IC_BR_NOT_BTS 0xA7
#define IC_BR_NOT_BTR 0xA8
#define IC_BR_NOT_BTC 0xA9
#define IC_BR_NOT_LBTS 0xAA
#define IC_BR_NOT_LBTR 0xAB
#define IC_BR_NOT_LBTC 0xAC
#define IC_SWAP_U8 0xAD
#define IC_SWAP_U16 0xAE
#define IC_SWAP_U32 0xAF
#define IC_SWAP_U64 0xB0
#define IC_ABS_I64 0xB1
#define IC_SIGN_I64 0xB2
#define IC_MIN_I64 0xB3
#define IC_MIN_U64 0xB4
#define IC_MAX_I64 0xB5
#define IC_MAX_U64 0xB6
#define IC_MOD_U64 0xB7
#define IC_SQR_I64 0xB8
#define IC_SQR_U64 0xB9
#define IC_SQR 0xBA
#define IC_ABS 0xBB
#define IC_SQRT 0xBC
#define IC_SIN 0xBD
#define IC_COS 0xBE
#define IC_TAN 0xBF
#define IC_ATAN 0xC0
#define IC_NUM_ENTRIES 0xC1
//Don't forget $LK,"IC_INIT_TABLE",A="FA:::/Compiler/CmpInit.CPP,IC_INIT_TABLE"$
#define KW_INCLUDE 0
#define KW_DEFINE 1
#define KW_UNION 2
#define KW_CATCH 3
#define KW_CLASS 4
#define KW_TRY 5
#define KW_IF 6
#define KW_ELSE 7
#define KW_FOR 8
#define KW_WHILE 9
#define KW_EXTERN 10
#define KW__EXTERN 11
#define KW_RETURN 12
#define KW_SIZEOF 13
#define KW__INTERN 14
#define KW_DO 15
#define KW_ASM 16
#define KW_GOTO 17
#define KW_EXE 18
#define KW_BREAK 19
#define KW_SWITCH 20
#define KW_NOBOUND_SWITCH 21
#define KW_SUB_SWITCH_START 22
#define KW_SUB_SWITCH_END 23
#define KW_CASE 24
#define KW_DFT 25
#define KW_PUBLIC 26
#define KW_OFFSET 27
#define KW_IMPORT 28
#define KW__IMPORT 29
#define KW_IFDEF 30
#define KW_IFNDEF 31
#define KW_IFAOT 32
#define KW_IFJIT 33
#define KW_ENDIF 34
#define KW_ASSERT 35
#define KW_REG 36
#define KW_NOREG 37
#define KW_LASTCLASS 38
#define KW_NOUNUSEDWARN 39
#define KW_HELP_INDEX 40
#define KW_HELP_FILE 41
#define KW_STATIC 42
#define KW_LOCK 43
#define KW_DEFINED 44
#define KW_INTERRUPT 45
#define KW_HASERRCODE 46
#define KW_ARGPOP 47
#define KW_NOARGPOP 48
#define AKW_ALIGN 64
#define AKW_MODULE_ORG 65
#define AKW_I0 66
#define AKW_I8 67
#define AKW_I16 68
#define AKW_I32 69
#define AKW_I64 70
#define AKW_U0 71
#define AKW_U8 72
#define AKW_U16 73
#define AKW_U32 74
#define AKW_U64 75
#define AKW_F64 76
#define AKW_DU8 77
#define AKW_DU16 78
#define AKW_DU32 79
#define AKW_DU64 80
#define AKW_DUP 81
#define AKW_USE16 82
#define AKW_USE32 83
#define AKW_USE64 84
#define AKW_IMPORT 85
#define AKW_LIST 86
#define AKW_NOLIST 87
#define AKW_BINFILE 88
#define KW_NUM_KEYWORDS 89
#define CMP_TEMPLATE_INC 0x00
#define CMP_TEMPLATE_DEC 0x01
#define CMP_TEMPLATE_MOD 0x02
#define CMP_TEMPLATE_LESS 0x03
#define CMP_TEMPLATE_GREATER 0x04
#define CMP_TEMPLATE_LESS_EQUAL 0x05
#define CMP_TEMPLATE_GREATER_EQUAL 0x06
#define CMP_TEMPLATE_STRLEN 0x07
#define CMP_TEMPLATE_RDTSC 0x08
#define CMP_TEMPLATE_SIGN_I64 0x09
#define CMP_TEMPLATE_FSTP 0x0A
#define CMP_TEMPLATE_FLD 0x0B
#define CMP_TEMPLATE_HPET 0x0C
#define CMP_TEMPLATE_SQR 0x0D
#define CMP_TEMPLATE_ABS 0x0E
#define CMP_TEMPLATE_SQRT 0x0F
#define CMP_TEMPLATE_SIN 0x10
#define CMP_TEMPLATE_COS 0x11
#define CMP_TEMPLATE_TAN 0x12
#define CMP_TEMPLATE_ATAN 0x13
#define ASSOCF_LEFT 1
#define ASSOCF_RIGHT 2
#define ASSOC_MASK 3
#define PREC_NULL 0x00
#define PREC_TERM 0x04
#define PREC_UNARY_POST 0x08
#define PREC_UNARY_PRE 0x0C
#define PREC_EXP 0x10
#define PREC_MUL 0x14
#define PREC_AND 0x18
#define PREC_XOR 0x1C
#define PREC_OR 0x20
#define PREC_ADD 0x24
#define PREC_CMP 0x28
#define PREC_CMP2 0x2C
#define PREC_AND_AND 0x30
#define PREC_XOR_XOR 0x34
#define PREC_OR_OR 0x38
#define PREC_ASSIGN 0x3C
#define PREC_MAX 0x40
//Function/static/public flags
#define FSF_PUBLIC 0x01
#define FSF_ASM 0x02
#define FSF_STATIC 0x04
#define FSF_INTERRUPT (1<<Ff_INTERRUPT)
#define FSF_HASERRCODE (1<<Ff_HASERRCODE)
#define FSF_ARGPOP (1<<Ff_ARGPOP)
#define FSF_NOARGPOP (1<<Ff_NOARGPOP)
#define FSG_FUN_FLAGS1 (FSF_INTERRUPT|FSF_HASERRCODE|FSF_ARGPOP|FSF_NOARGPOP)
#define FSG_FUN_FLAGS2 (FSG_FUN_FLAGS1|FSF_PUBLIC)
//Byte 0
#define PRS0_NULL 0x000000
#define PRS0__EXTERN 0x000001
#define PRS0__INTERN 0x000002
#define PRS0__IMPORT 0x000003
#define PRS0_EXTERN 0x000004
#define PRS0_IMPORT 0x000005
#define PRS0_TYPECAST 0x000006
//Byte 1
#define PRS1B_NULL 0
#define PRS1_NULL 0x000000
#define PRS1B_LOCAL_VAR 1
#define PRS1_LOCAL_VAR 0x000100
#define PRS1B_FUN_ARG 2
#define PRS1_FUN_ARG 0x000200
#define PRS1B_CLASS 3
#define PRS1_CLASS 0x000300
#define PRS1B_STATIC_LOCAL_VAR 4
#define PRS1_STATIC_LOCAL_VAR 0x000400
#define PRSF_UNION 0x010000
class COptReg
{
I64 offset;
CMemberLst *m;
};
#define CMPF_ASM_BLK 1
#define CMPF_ONE_ASM_INS 2
#define CMPF_LEX_FIRST 4
#define CMPF_PRS_SEMICOLON 8
+45
View File
@@ -0,0 +1,45 @@
import U0 DocLoad(CDoc *doc,U8 *src2,I64 size);
import CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL);
import U0 DocDel(CDoc *doc);
import CDocEntry *DocPutLine(CDoc *doc,CDocEntry *doc_e);
import I64 DocSize(CDoc *doc);
import U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e);
import U0 Who(U8 *flags=NULL,CHashTable *h=NULL,
U8 *outname=NULL,U8 mapfile_drv=0,U8 *index=NULL,CDoc *_doc=NULL);
extern I64 LexExpression(CLex *lx);
extern Bool IsLexExpression2Bin(CLex *lx,U8 **_ex);
extern I64 PrsUnaryTerm(CLex *lx,CPrsStk *ps,CMemberLst **_local_var,CArrayDim **_tempad,
I64 *max_prec,I64 *unary_pre_prec,I64 *paren_prec);
extern I64 PrsUnaryModifier(CLex *lx,CPrsStk *ps,CMemberLst **_local_var,CArrayDim **_tempad,I64 *unary_post_prec);
extern CExe *CmpJoin(CLex *lx,I64 cmp_flags,U8 *map_name=NULL,U8 mapfile_drv=0);
extern U0 CmpFixUpJITAsm(CLex *lx,CExe *tempx);
extern U0 CmpFixUpAOTAsm(CLex *lx,CExe *tempx);
extern U0 PrsStreamBlk(CLex *lx);
extern CHashClass *PrsClass(CLex *lx,I64 keyword,I64 fsp_flags,Bool is_extern);
extern CHashClass *PrsType(CLex *lx,CHashClass **tempc1,
I64 *_mode,CMemberLst *tempm,U8 **_ident,CHashFun **_fun_ptr,
CHashExport **_tempex,CArrayDim *tempad,I64 fsp_flags);
extern U0 PrsVarInit2(CLex *lx,U8 **_dst,CHashClass *tempc,CArrayDim *tempad,U8 *data_addr_ip,U8 **_base,Bool data_heap,I64 pass);
extern CHashFun *PrsFunJoin(CLex *lx,CHashClass *temp_return,U8 *name,I64 fsp_flags);
extern Bool PrsStatement(CLex *lx,I64 try_cnt=0,
CLexCodeMisc *lb_break=NULL,I64 cmp_flags=CMPF_PRS_SEMICOLON);
extern CIntermediateCode *OptPass012(CLex *lx);
extern CLexCodeMisc *OptLabelFwd(CLexCodeMisc *lb);
extern U0 OptPass3(CLex *lx,COptReg *reg_offsets);
extern U0 OptPass4(CLex *lx,COptReg *reg_offsets,I64 *_type);
extern U0 OptPass5(CLex *lx);
extern U0 OptPass6(CLex *lx);
extern I64 OptPass789(CLex *lx,COptReg *reg_offsets,U8 *buf,CDbgInfo **_dbg);
extern I64 PrsKeyWord(CLex *lx);
extern I64 HashEntrySize2(CHashSrcSym *temph);
extern U0 LexWarn(CLex *lx,U8 *str=NULL);
extern U0 LexExcept(CLex *lx,U8 *str=NULL);
extern CHashSrcSym *HashEntryImportCopy(CHashSrcSym *temph);
extern U0 HashTableImport(CHashTable *src,CHashTable *dst);
_extern CMP_TEMPLATES U32 cmp_templates[1];
_extern CMP_TEMPLATES_DONT_POP U32 cmp_templates_dont_pop[1];
_extern CMP_TEMPLATES_DONT_PUSH U32 cmp_templates_dont_push[1];
_extern CMP_TEMPLATES_DONT_PUSH_POP U32 cmp_templates_dont_push_pop[1];
_extern CMP_TEMPLATES_DONT_PUSH2 U32 cmp_templates_dont_push2[1];
+21
View File
@@ -0,0 +1,21 @@
CHashTable *asm_hash;
Bool cmp_do_not_write_to_dsk;
CHashClass *sys_internal_types[RT_NUM_IT];
CIntermediateCode opt_nop;
U32 *dual_U16_tokens1,*dual_U16_tokens2,*dual_U16_tokens3;
U32 *binary_ops_table;
U8 *cmp_arg_cnt,*cmp_result_cnt;
U8 *ic_bitmap_deref,*ic_bitmap_assign,*ic_bitmap_not_const,*ic_bitmap_cmp,*ic_bitmap_fpop;
I64 num_stk_temps,num_reg_vars,num_non_ptr_vars;
I64 stk_temps_mask,reg_vars_mask,non_ptr_vars_mask;
U8 *to_stk_temps_map_odd;
U8 *to_stk_temps_map_even;
U8 *to_reg_vars_map,*to_non_ptr_vars_map;
I64 compiled_lines,compiled_funs,compiled_bytes;
//Unassembler
CInstruction **unasm_table;
I64 unasm_table_entries;
I64 uasm_ins64_mask,uasm_signed_arg_mask,uasm_mem_mask;
+574
View File
@@ -0,0 +1,574 @@
#define NUM_INTERNAL_TYPES 17
class CInternalType
{
U8 type,size,name[8];
};
CInternalType internal_types_table[NUM_INTERNAL_TYPES]={
{RT_I0,0,"I0i"},{RT_I0,0,"I0"},{RT_U0,0,"U0i"},{RT_U0,0,"U0"},
{RT_I8,1,"I8i"},{RT_I8,1,"I8"},{RT_I8,1,"Bool"},
{RT_U8,1,"U8i"},{RT_U8,1,"U8"},
{RT_I16,2,"I16i"},{RT_U16,2,"U16i"},
{RT_I32,4,"I32i"},{RT_U32,4,"U32i"},
{RT_I64,8,"I64i"},{RT_U64,8,"U64i"},
{RT_F64,8,"F64i"},{RT_F64,8,"F64"},
};
U0 AsmPrsInsFlags(CLex *lx,CInstruction *tempi)
{
I64 i;
while (TRUE) {
switch (lx->token) {
case TK_IDENT:
if ((i=DefineMatch(lx->cur_str,"ST_OPCODE_MODIFIERS"))>=0) {
tempi->opcode_modifier=i;
break;
} else
return;
case TK_INTEGER:
if (lx->cur_i64==16)
tempi->flags|=IEF_OP_SIZE16;
else if (lx->cur_i64==32)
tempi->flags|=IEF_OP_SIZE32;
else
return;
break;
case '+':
tempi->flags|=IEF_PLUS_OPCODE;
case '/':
if (Lex(lx)==TK_INTEGER && lx->cur_i64<8)
tempi->slash_val=lx->cur_i64;
else if (lx->token==TK_IDENT) {
if (!StrCmp(lx->cur_str,"R"))
tempi->slash_val=SV_R_REG;
else if (!StrCmp(lx->cur_str,"I"))
tempi->slash_val=SV_I_REG;
else
return;
} else
return;
break;
case '!': tempi->flags|=IEF_DONT_SWITCH_MODES; break;
case '&': tempi->flags|=IEF_DFT; break;
case ':': tempi->flags|=IEF_STI; break;
case '-': tempi->flags|=IEF_NO_REX; break;
case '~': tempi->flags|=IEF_40_REX; break;
case '=': tempi->flags|=IEF_48_REX; break;
case '`': tempi->flags|=IEF_REX_ONLY_R8_R15; break;
case '^': tempi->flags|=IEF_REX_XOR_LIKE; break;
case '$$': tempi->flags|=IEF_ENDING_ZERO; break;
default:
return;
}
Lex(lx);
}
}
U0 AsmHashLoad()
{
I64 i,j,size,size1;
CInternalType *tempit;
CLex *lx;
CHashGeneric *temph;
CHashReg *tempr;
CHashOpcode *tempo,*tempo1;
CInstruction *tempi;
CHashClass *tempc;
asm_hash=HashTableNew(2048);
size1=offset(CHashOpcode.ins)+sizeof(CInstruction)<<5;
tempo=MAlloc(size1);
lx=LexNew(FileRead("OpCodes.TXT"),,"OpCodes.TXT.Z");
lx->htc.hash_table_lst=NULL;
Lex(lx);
while (lx->token) {
if (lx->token!=TK_IDENT)
LexExcept(lx,"expecting identifier at ");
i=LstMatch(lx->cur_str,"R8\0R16\0R32\0R64\0SEG\0FSTK\0MM\0XMM\0OPCODE\0KEYWORD\0ASM_KEYWORD\0");
if (i<0)
LexExcept(lx,"Unknown Statement");
Lex(lx); //skip keyword
if (lx->token!=TK_IDENT)
LexExcept(lx,"expecting identifier at ");
switch (i) {
case 8: //OPCODE
MemSet(tempo,0,size1);
tempo->type=HTT_OPCODE;
tempo->instruction_entry_cnt=0;
tempo->str=lx->cur_str;
lx->cur_str=0;
Lex(lx); //Skip OPCODE
while (lx->token && lx->token!=';') {
tempi=&tempo->ins[tempo->instruction_entry_cnt];
tempi->ins_entry_num=tempo->instruction_entry_cnt++;
tempi->slash_val=SV_NONE; //Not zero!!
while (lx->token==TK_INTEGER) {
tempi->opcode[tempi->opcode_cnt++]=lx->cur_i64;
Lex(lx);
}
if (lx->token==',')
Lex(lx);
else if (lx->token!=';')
LexExcept(lx,"expecting ',' at ");
AsmPrsInsFlags(lx,tempi);
tempi->arg1=0;
tempi->arg2=0;
if (lx->token==TK_IDENT) {
j=DefineMatch(lx->cur_str,"ST_ARG_TYPES");
tempi->arg1=j;
if (ARGT_REL8<=j<=ARGT_REL32 ||
ARGT_MOFFS8<=j<=ARGT_MOFFS64)
tempi|=IEF_NO_REX;
if (Lex(lx)==TK_IDENT) {
j=DefineMatch(lx->cur_str,"ST_ARG_TYPES");
Lex(lx);
tempi->arg2=j;
if (ARGT_REL8<=j<=ARGT_REL32 ||
ARGT_MOFFS8<=j<=ARGT_MOFFS64)
tempi|=IEF_NO_REX;
}
}
}
size=offset(CHashOpcode.ins)+
sizeof(CInstruction)*tempo->instruction_entry_cnt;
tempo1=MAlloc(size);
MemCpy(tempo1,tempo,size);
tempo1->use_cnt=0;
if (HashFind(tempo1->str,asm_hash,HTT_OPCODE))
LexExcept(lx,"Duplicate OPCODE entry ");
HashAdd(tempo1,asm_hash);
break;
case 9: //KEYWORD
case 10: //ASM_KEYWORD
temph=CAlloc(sizeof(CHashGeneric));
temph->str=lx->cur_str;
lx->cur_str=NULL;
Lex(lx); //skip keyword name
if (lx->token!=TK_INTEGER)
LexExcept(lx,"expecting integer at ");
temph->user_data0=lx->cur_i64;
if (i==9)
temph->type=HTT_KEYWORD;
else
temph->type=HTT_ASM_KEYWORD;
HashAdd(temph,asm_hash);
Lex(lx); //Skip INT
break;
case REGT_R8:
case REGT_R16:
case REGT_R32:
case REGT_R64:
case REGT_SEG:
case REGT_FSTK:
case REGT_MM:
case REGT_XMM:
tempr=CAlloc(sizeof(CHashReg));
tempr->str=lx->cur_str;
lx->cur_str=NULL;
Lex(lx); //skip keyword name
if (lx->token!=TK_INTEGER)
LexExcept(lx,"expecting integer at ");
tempr->type=HTT_REG;
tempr->reg_type=i;
tempr->reg_num=lx->cur_i64;
HashAdd(tempr,asm_hash);
Lex(lx); //Skip INT
break;
}
if (lx->token!=';')
LexExcept(lx,"missing ';' at");
Lex(lx); //Skip ';'
}
Free(tempo);
LexDel(lx);
for (i=0;i<NUM_INTERNAL_TYPES;i++) {
tempit=&internal_types_table[i];
tempc=PrsClassNew;
tempc->type=HTT_INTERNAL_TYPE;
tempc->raw_type=tempit->type;
Bts(&tempc->flags,Cf_INTERNAL_TYPE);
tempc->size=tempit->size;
tempc->str=AStrNew(tempit->name);
HashAdd(tempc,asm_hash);
sys_internal_types[tempc->raw_type]=tempc;
}
adam_task->hash_table->next=asm_hash;
}
U0 CmpLoadDefines()
{
DefineLstLoad("ST_IT_TYPES","I0\0U0\0I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0F64\0uF64\0");
DefineLstLoad("ST_TY_TYPES","NULL\0IMM\0REG\0DISP\0SIB\0RIP\0STK\0");
DefineLstLoad("ST_U8_REGS","AL\0CL\0DL\0BL\0AH\0CH\0DH\0BH\0"
"R8u8\0R9u8\0R10u8\0R11u8\0R12u8\0R13u8\0R14u8\0R15u8\0");
DefineLstLoad("ST_U8_REX_REGS","AL\0CL\0DL\0BL\0RSPu8\0RBPu8\0RSIu8\0RDIu8\0"
"R8u8\0R9u8\0R10u8\0R11u8\0R12u8\0R13u8\0R14u8\0R15u8\0");
DefineLstLoad("ST_U16_REGS","AX\0CX\0DX\0BX\0SP\0BP\0SI\0DI\0"
"R8u16\0R9u16\0R10u16\0R11u16\0R12u16\0R13u16\0R14u16\0R15u16\0");
DefineLstLoad("ST_U32_REGS","EAX\0ECX\0EDX\0EBX\0ESP\0EBP\0ESI\0EDI\0"
"R8u32\0R9u32\0R10u32\0R11u32\0R12u32\0R13u32\0R14u32\0R15u32\0");
DefineLstLoad("ST_U64_REGS","RAX\0RCX\0RDX\0RBX\0RSP\0RBP\0RSI\0RDI\0"
"R8\0R9\0R10\0R11\0R12\0R13\0R14\0R15\0");
DefineLstLoad("ST_MM_REGS","MM0\0MM1\0MM2\0MM3\0MM4\0MM5\0MM6\0MM7\0");
DefineLstLoad("ST_XMM_REGS","XMM0\0XMM1\0XMM2\0XMM3\0XMM4\0XMM5\0XMM6\0XMM7\0");
DefineLstLoad("ST_OPCODE_MODIFIERS","NO\0CB\0CW\0CD\0CP\0IB\0IW\0ID\0");
DefineLstLoad("ST_ARG_TYPES",
"NO\0REL8\0REL16\0REL32\0UIMM8\0UIMM16\0UIMM32\0UIMM64\0"
"R8\0R16\0R32\0R64\0"
"IMM8\0IMM16\0IMM32\0IMM64\0RM8\0RM16\0RM32\0RM64\0"
"M8\0M16\0M32\0M64\0"
"M1632\0M16N32\0M16N16\0M32N32\0"
"MOFFS8\0MOFFS16\0MOFFS32\0MOFFS64\0"
"AL\0AX\0EAX\0RAX\0CL\0DX\0 \0SREG\0"
"SS\0DS\0ES\0FS\0GS\0CS\0ST0\0STI\0"
"MM\0MM32\0MM64\0XMM\0XMM32\0XMM64\0XMM128\0XMM0\0");
DefineLstLoad("ST_SEG_REGS","ES\0CS\0SS\0DS\0FS\0GS\0");
DefineLstLoad("ST_FSTK_REGS","ST0\0ST1\0ST2\0ST3\0ST4\0ST5\0ST6\0ST7\0");
DefineLstLoad("ST_INTERMEDIATE_CODE",
/*
[arg_cnt][result_cnt][deref/assign/cmp][fpop][nonconst]
'9' arg_cnt means var
'*' means it is a dereference instruction
'=' means it is an assignment instruction
'^' means it is a compare instruction
'N' means not const. Sets LF_NOT_CONST
which means an expression contains mem
accesses or things which might change.
*/
"00...END\0"
"00...NOP1\0"
"10...END_EXP\0"
"00...NOP2\0"
"00...LABEL\0"
"00...CALL_START\0"
"01...CALL_END\0"
"00...CALL_END2\0"
"10...RETURN_VAL\0"
"00...RETURN_VAL2\0"
"01...IMM_U64\0"
"01...IMM_F64\0"
"01..NSTR_CONST\0"
"01..NABS_ADDR\0"
"01..NADDR_IMPORT\0"
"01..NHEAP_GLBL\0"
"01...SIZEOF\0"
"01...TYPE\0"
"01..NGET_LABEL\0"
"01..NRBP\0"
"01..NREG\0"
"00..NFS\0"
"01..NMOV_FS\0"
"00..NGS\0"
"01..NMOV_GS\0"
"01..NLEA\0"
"01..NMOV\0"
"10...TO_I64\0"
"10...TO_F64\0"
"10...TO_BOOL\0"
"10...TOUPPER\0"
"11...HOLYC_TYPECAST\0"
"11..NADDR\0"
"11...COM\0"
"11...NOT\0"
"11...UNARY_MINUS\0"
"11*.NDEREF\0"
"11*.NDEREF_PP\0"
"11*.NDEREF_MM\0"
"11*PN_PP\0"
"11*PN_MM\0"
"11*PNPP_\0"
"11*PNMM_\0"
"21...SHL\0"
"21...SHR\0"
"11=..SHL_CONST\0"
"11=..SHR_CONST\0"
"21...POWER\0"
"21.P.MUL\0"
"21.P.DIV\0"
"21...MOD\0"
"21...AND\0"
"21...OR\0"
"21...XOR\0"
"21.P.ADD\0"
"21.P.SUB\0"
"11=..ADD_CONST\0"
"11=..SUB_CONST\0"
"21^..EQUAL_EQUAL\0"
"21^..NOT_EQUAL\0"
"21^..LESS\0"
"21^..GREATER\0"
"21^..LESS_EQUAL\0"
"21^..GREATER_EQUAL\0"
"01...PUSH_CMP\0"
"21...AND_AND\0"
"21...OR_OR\0"
"21...XOR_XOR\0"
"21=.NASSIGN\0"
"21=.NASSIGN_PP\0"
"21=.NASSIGN_MM\0"
"21=.NSHL_EQUAL\0"
"21=.NSHR_EQUAL\0"
"21=.NMUL_EQUAL\0"
"21=.NDIV_EQUAL\0"
"21=.NMOD_EQUAL\0"
"21=.NAND_EQUAL\0"
"21=.NOR_EQUAL\0"
"21=.NXOR_EQUAL\0"
"21=.NADD_EQUAL\0"
"21=.NSUB_EQUAL\0"
"00...JMP\0"
"00...SUB_CALL\0"
"20...SWITCH\0"
"20...NOBOUND_SWITCH\0"
"90...ADD_RSP\0"
"90...ADD_RSP1\0"
"00...ENTER\0"
"00=..PUSH_REGS\0"
"00=..POP_REGS\0"
"00...LEAVE\0"
"00...RET\0"
"00..NCALL\0"
"00..NCALL_INDIRECT\0"
"00..NCALL_INDIRECT2\0"
"00..NCALL_IMPORT\0"
"00..NCALL_EXTERN\0"
"00..NASM\0"
"10..NPREEMPT\0"
"10..NPUSH\0"
"00..NPOP\0"
"10..NCLFLUSH\0"
"10..NINVLPG\0"
"10..NIN_U8\0"
"10..NIN_U16\0"
"10..NIN_U32\0"
"20..NOUT_U8\0"
"20..NOUT_U16\0"
"20..NOUT_U32\0"
"00..NGET_RFLAGS\0"
"00..NCARRY\0"
"10..NSET_RFLAGS\0"
"00..NGET_RAX\0"
"10..NSET_RAX\0"
"00..NGET_RBP\0"
"10..NSET_RBP\0"
"00..NGET_RSP\0"
"10..NSET_RSP\0"
"01..NRIP\0"
"00..NRDTSC\0"
"00..NHPET\0"
"20..NBT\0"
"20..NBTS\0"
"20..NBTR\0"
"20..NBTC\0"
"20..NLBTS\0"
"20..NLBTR\0"
"20..NLBTC\0"
"10..NBSF\0"
"10..NBSR\0"
"10..NQUE_INIT\0"
"20..NQUE_INS\0"
"20..NQUE_INS_REV\0"
"10..NQUE_REM\0"
"10..NSTRLEN\0"
"10...BR_ZERO\0"
"10...BR_NOT_ZERO\0"
"00...BR_CARRY\0"
"00...BR_NOT_CARRY\0"
"20...BR_NOT_EQUAL\0"
"20...BR_EQUAL_EQUAL\0"
"20...BR_GREATER_EQUAL\0"
"20...BR_LESS_EQUAL\0"
"20...BR_GREATER\0"
"20...BR_LESS\0"
"21...BR_2NOT_EQUAL\0"
"21...BR_2EQUAL_EQUAL\0"
"21...BR_2GREATER_EQUAL\0"
"21...BR_2LESS_EQUAL\0"
"21...BR_2GREATER\0"
"21...BR_2LESS\0"
"20...BR_AND_ZERO\0"
"20...BR_AND_NOT_ZERO\0"
"10..NBR_MM_ZERO\0"
"10..NBR_MM_NOT_ZERO\0"
"20...BR_AND_AND_ZERO\0"
"20...BR_AND_AND_NOT_ZERO\0"
"20...BR_OR_OR_ZERO\0"
"20...BR_OR_OR_NOT_ZERO\0"
"20..NBR_BT\0"
"20..NBR_BTS\0"
"20..NBR_BTR\0"
"20..NBR_BTC\0"
"20..NBR_LBTS\0"
"20..NBR_LBTR\0"
"20..NBR_LBTC\0"
"20..NBR_NOT_BT\0"
"20..NBR_NOT_BTS\0"
"20..NBR_NOT_BTR\0"
"20..NBR_NOT_BTC\0"
"20..NBR_NOT_LBTS\0"
"20..NBR_NOT_LBTR\0"
"20..NBR_NOT_LBTC\0"
"20..NSWAP_U8\0"
"20..NSWAP_U16\0"
"20..NSWAP_U32\0"
"20..NSWAP_U64\0"
"10...ABS_I64\0"
"10...SIGN_I64\0"
"20...MIN_I64\0"
"20...MIN_U64\0"
"20...MAX_I64\0"
"20...MAX_U64\0"
"20...MOD_U64\0"
"10...SQRI64\0"
"10...SQRU64\0"
"11.P.SQR\0"
"11.P.ABS\0"
"11.P.SQRT\0"
"11.P.SIN\0"
"11.P.COS\0"
"11.P.TAN\0"
"11.P.ATAN\0"
);$AN,"Anchor for adding intermediate codes",A="IC_INIT_TABLE"$
}
U0 CmpFillTables()
{
U8 *st;
I64 i,k;
U32 *d;
ic_bitmap_assign =CAlloc((IC_NUM_ENTRIES+7)>>3);
ic_bitmap_deref =CAlloc((IC_NUM_ENTRIES+7)>>3);
ic_bitmap_cmp =CAlloc((IC_NUM_ENTRIES+7)>>3);
ic_bitmap_not_const =CAlloc((IC_NUM_ENTRIES+7)>>3);
ic_bitmap_fpop =CAlloc((IC_NUM_ENTRIES+7)>>3);
cmp_arg_cnt =CAlloc(IC_NUM_ENTRIES);
cmp_result_cnt =CAlloc(IC_NUM_ENTRIES);
st=Define("ST_INTERMEDIATE_CODE");
for (i=0;i<IC_NUM_ENTRIES;i++) {
cmp_arg_cnt[i]=*st-'0';
cmp_result_cnt[i]=st[1]-'0';
if (st[2]=='*')
Bts(ic_bitmap_deref,i);
else if (st[2]=='=')
Bts(ic_bitmap_assign,i);
else if (st[2]=='^')
Bts(ic_bitmap_cmp,i);
if (st[3]=='P')
Bts(ic_bitmap_fpop,i);
if (st[4]=='N')
Bts(ic_bitmap_not_const,i);
st+=StrLen(st)+1;
//See $LK,"ICPut",A="FF:::/Compiler/ICLCC.CPP,ST_INTERMEDIATE_CODE"$.
}
to_reg_vars_map=CAlloc(NUM_REGS*sizeof(U8));
num_reg_vars=0;
reg_vars_mask=REG_VARS_MASK;
for (i=0;i<NUM_REGS;i++)
if (Bt(&reg_vars_mask,i))
to_reg_vars_map[num_reg_vars++]=i;
to_non_ptr_vars_map=CAlloc(NUM_REGS*sizeof(U8));
num_non_ptr_vars=0;
non_ptr_vars_mask=REG_NON_PTR_MASK;
for (i=0;i<NUM_REGS;i++)
if (Bt(&non_ptr_vars_mask,i))
to_non_ptr_vars_map[num_non_ptr_vars++]=i;
to_stk_temps_map_odd=CAlloc(NUM_REGS*sizeof(U8));
to_stk_temps_map_even=CAlloc(NUM_REGS*sizeof(U8));
num_stk_temps=0;
stk_temps_mask=REG_STK_TEMPS_MASK;
for (i=0;i<NUM_REGS;i++)
if (Bt(&stk_temps_mask,i))
to_stk_temps_map_even[num_stk_temps++]=i;
k=num_stk_temps;
for (i=0;i<NUM_REGS;i++)
if (Bt(&stk_temps_mask,i))
to_stk_temps_map_odd[--k]=i;
dual_U16_tokens1=d=CAlloc(sizeof(U32)*TK_NUM_TK);
d['!']=TK_NOT_EQUAL<<16+'=';
d['&']=TK_AND_AND<<16+'&';
d['*']=TK_MUL_EQUAL<<16+'=';
d['+']=TK_PLUS_PLUS<<16+'+';
d['-']=TK_DEREFERENCE<<16+'>';
d['/']='*';
d[':']=TK_DBL_COLON<<16+':';
d['<']=TK_LESS_EQUAL<<16+'=';
d['=']=TK_EQUAL_EQUAL<<16+'=';
d['>']=TK_GREATER_EQUAL<<16+'=';
d['^']=TK_XOR_EQUAL<<16+'=';
d['|']=TK_OR_OR<<16+'|';
d['%']=TK_MOD_EQUAL<<16+'=';
dual_U16_tokens2=d=CAlloc(sizeof(U32)*TK_NUM_TK);
d['&']=TK_AND_EQUAL<<16+'=';
d['+']=TK_ADD_EQUAL<<16+'=';
d['-']=TK_MINUS_MINUS<<16+'-';
d['/']='/';
d['<']=TK_SHL<<16+'<';
d['>']=TK_SHR<<16+'>';
d['^']=TK_XOR_XOR<<16+'^';
d['|']=TK_OR_EQUAL<<16+'=';
dual_U16_tokens3=d=CAlloc(sizeof(U32)*TK_NUM_TK);
d['-']=TK_SUB_EQUAL<<16+'=';
d['/']=TK_DIV_EQUAL<<16+'=';
binary_ops_table=d=CAlloc(sizeof(U32)*TK_NUM_TK);
d['`'] =(PREC_EXP+ASSOCF_RIGHT)<<16+IC_POWER;
d[TK_SHL] =(PREC_EXP+ASSOCF_LEFT)<<16+IC_SHL;
d[TK_SHR] =(PREC_EXP+ASSOCF_LEFT)<<16+IC_SHR;
d['*'] =PREC_MUL<<16+IC_MUL;
d['/'] =(PREC_MUL+ASSOCF_LEFT)<<16+IC_DIV;
d['%'] =(PREC_MUL+ASSOCF_LEFT)<<16+IC_MOD;
d['&'] =PREC_AND<<16+IC_AND;
d['^'] =PREC_XOR<<16+IC_XOR;
d['|'] =PREC_OR<<16+IC_OR;
d['+'] =PREC_ADD<<16+IC_ADD;
d['-'] =(PREC_ADD+ASSOCF_LEFT)<<16+IC_SUB;
d['<'] =PREC_CMP<<16+IC_LESS;
d['>'] =PREC_CMP<<16+IC_GREATER;
d[TK_LESS_EQUAL] =PREC_CMP<<16+IC_LESS_EQUAL;
d[TK_GREATER_EQUAL] =PREC_CMP<<16+IC_GREATER_EQUAL;
d[TK_EQUAL_EQUAL] =PREC_CMP2<<16+IC_EQUAL_EQUAL;
d[TK_NOT_EQUAL] =PREC_CMP2<<16+IC_NOT_EQUAL;
d[TK_AND_AND] =PREC_AND_AND<<16+IC_AND_AND;
d[TK_XOR_XOR]=PREC_XOR_XOR<<16+IC_XOR_XOR;
d[TK_OR_OR] =PREC_OR_OR<<16+IC_OR_OR;
d['='] =(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_ASSIGN;
d[TK_SHL_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHL_EQUAL;
d[TK_SHR_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHR_EQUAL;
d[TK_MUL_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MUL_EQUAL;
d[TK_DIV_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_DIV_EQUAL;
d[TK_MOD_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MOD_EQUAL;
d[TK_AND_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_AND_EQUAL;
d[TK_OR_EQUAL] =(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_OR_EQUAL;
d[TK_XOR_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_XOR_EQUAL;
d[TK_ADD_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_ADD_EQUAL;
d[TK_SUB_EQUAL]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SUB_EQUAL;
}
+735
View File
@@ -0,0 +1,735 @@
U0 StreamPrint(U8 *fmt,...)
//Inserts text into the stream of
//characters being compiled. Called
//from withing #exe{} block.
{
U8 *buf=SPrintJoin(NULL,fmt,argc,argv),*st;
CLex *lx=Fs->last_lex;
CStreamBlk *tempe=lx->last_stream_blk;
if (tempe!=&lx->next_stream_blk) {
st=MPrint("%s%s",tempe->body,buf);
Free(tempe->body);
tempe->body=st;
} else
PrintErr("No exe{} blk\n");
Free(buf);
}
U8 *LexStatement2Bin(CLex *lx,I64 *_type,I64 cmp_flags=0)
{
I64 size,i,j,k,*result=INVALID_PTR;
CLexCodeCtrl *tempcbh;
if (_type) *_type=RT_I64;
Btr(&lx->flags,Lf_OPT_TRACE_PRESENT);
if (lx->a_depth==2)
LCCPush(lx);
LCCInit(lx);
if (!PrsStatement(lx,,,cmp_flags)) {
if (lx->lcc.lcc_root.next!=&lx->lcc.lcc_root) {
LCCAdd(lx,IC_RETURN_VAL2,0,NULL);
LCCAdd(lx,IC_RET,0,0);
if (result=LCCCompile(lx,&size,NULL,_type)) {
if (lx->flags&LF_AOT_COMPILE) {
j=lx->a->ip;
k=(size+7)>>3;
for (i=0;i<k;i++)
AsmStoreCodeU64(lx,result[i]);
Free(result);
result=j;
}
}
} //TODO: else del misc?
} else //TODO: too dangerous to del Misc?
QueDel(&lx->lcc.lcc_root.next);
if (lx->a_depth==2) {
progress1++;
tempcbh=LCCPopNoFree(lx);
LCCAppend(lx,tempcbh);
}
return result;
}
CExe *CmpJoin(CLex *lx,I64 cmp_flags,U8 *map_name=NULL,U8 mapfile_drv=0)
{
CAsmCtrl *a,*old_a=lx->a;
I64 i,j,l;
U8 *buf;
CAsmCodeBlk *tempc;
CExeImportExport *tempe;
Bool okay=TRUE;
CLexHashTableContext *htc=MAlloc(sizeof(CLexHashTableContext));
CExe *result=CAlloc(sizeof(CExe)),*parent;
if (parent=lx->exe) {
result->parent_exe=parent;
QueIns(result,parent->last);
} else
QueInit(result);
lx->exe=result;
result->next_ie=result->last_ie=&result->next_ie;
lx->a=a=CAlloc(sizeof(CAsmCtrl));
lx->a_depth++;
a->cb=CAlloc(sizeof(CAsmCodeBlk));
a->max_align=1;
a->module_org=INVALID_PTR;
MemCpy(htc,&lx->htc,sizeof(CLexHashTableContext));
if (lx->htc.fun)
lx->htc.glbl_hash_table=HashTableNew(128);
else
lx->htc.glbl_hash_table=HashTableNew(2048);
if (lx->flags&LF_AOT_COMPILE) {
lx->htc.define_hash_table=lx->htc.glbl_hash_table;
if (lx->a_depth<=1)
lx->htc.glbl_hash_table->next=asm_hash;
else
lx->htc.glbl_hash_table->next=htc->glbl_hash_table;
} else
lx->htc.glbl_hash_table->next=Fs->hash_table;
lx->htc.hash_table_lst=lx->htc.local_hash_table=HashTableNew(16);
lx->htc.local_hash_table->next=lx->htc.glbl_hash_table;
lx->htc.local_var_lst=lx->htc.fun; //HolyC local vars
lx->htc.fun=NULL;
try {
if (cmp_flags&CMPF_LEX_FIRST)
Lex(lx);
if (!(cmp_flags&CMPF_ONE_ASM_INS))
cmp_flags|=CMPF_PRS_SEMICOLON;
if (lx->flags&LF_AOT_COMPILE) {
while (lx->token!=TK_EOF) {
buf=LexStatement2Bin(lx,NULL,cmp_flags);
if (buf!=INVALID_PTR) {
tempe=CAlloc(sizeof(CExeImportExport));
tempe->type=EIT_MAIN;
tempe->ip=buf;
QueIns(tempe,result->last_ie);
}
if (cmp_flags&CMPF_ASM_BLK)
break;
}
} else
PrsStatement(lx,,,cmp_flags);
AsmGlblsResolve(lx,result);
} catch {
if (Fs->except_ch=='Compiler' && !(cmp_flags&CMPF_ASM_BLK)) {
LexPutPos(lx);
Fs->catch_except=TRUE;
}
okay=FALSE;
}
if (!okay) {
if (lx->error_cnt<1)
lx->error_cnt=1;
lx->exe=result->parent_exe;
Free(result);
LinkedLstDel(a->cb);
result=NULL;
} else {
if (map_name && !cmp_do_not_write_to_dsk)
Who("-r",lx->htc.glbl_hash_table,map_name,mapfile_drv);
HashTableDel(lx->htc.local_hash_table);
HashTableDel(lx->htc.glbl_hash_table);
if (!a->num_ex_U8s)
result->buf=NULL;
else {
if (lx->flags&LF_AOT_COMPILE)
result->buf=MAlloc(a->num_ex_U8s);
else {
if (a->module_org==INVALID_PTR)
result->buf=MAlloc(a->num_ex_U8s,Fs->code_heap);
else
result->buf=a->module_org;
}
result->ex_U8s=a->num_ex_U8s;
tempc=a->cb;
j=0;
l=a->num_ex_U8s;
while (tempc) {
i=l;
if (i>ASM_CODE_BLK_SIZE)
i=ASM_CODE_BLK_SIZE;
MemCpy(result->buf+j,tempc->body,i);
j+=i;
l-=i;
tempc=tempc->next;
}
}
LinkedLstDel(a->cb);
result->abss=a->abss;
result->heap_glbls=a->heap_glbls;
result->max_align =a->max_align;
result->module_org=a->module_org;
}
lx->exe=parent;
MemCpy(&lx->htc,htc,sizeof(CLexHashTableContext));
Free(htc);
Free(a);
lx->a=old_a;
lx->a_depth--;
return result;
}
CExe *CmpBuf(U8 *buf,U8 *map_name=NULL,
I64 *error_cnt=NULL, I64 *warning_cnt=NULL,U8 mapfile_drv=0)
{
CLex *lx;
CExe *result=NULL;
lx=LexNew(buf,LF_DONT_FREE_BUF);
lx->flags|=LF_AOT_COMPILE;
QueIns(lx,Fs->last_lex);
result=CmpJoin(lx,CMPF_LEX_FIRST,map_name,mapfile_drv);
if (error_cnt) *error_cnt=lx->error_cnt;
if (warning_cnt) *warning_cnt=lx->warning_cnt;
QueRem(lx);
if (result)
LexDel(lx);
return result;
}
U0 CmpFixUpJITAsm(CLex *lx,CExe *tempx)
{
I64 i,ip2=tempx->buf+tempx->ip,*str=NULL;
U8 *ptr;
CLexCodeMisc *g_lb;
CExeAbsAddr *tempa,*tempa1;
CExeImportExport *tempe,*tempe1;
CHashExport *tempex;
tempa=tempx->abss;
while (tempa) {
tempa1=tempa->next;
ptr=ip2+tempa->ip;
nobound_switch (tempa->type) {
case EAT_ADD_U8: *ptr(U8 *) +=ip2; break;
case EAT_SUB_U8: *ptr(U8 *) -=ip2; break;
case EAT_ADD_U16: *ptr(U16 *)+=ip2; break;
case EAT_SUB_U16: *ptr(U16 *)-=ip2; break;
case EAT_ADD_U32: *ptr(U32 *)+=ip2; break;
case EAT_SUB_U32: *ptr(U32 *)-=ip2; break;
case EAT_ADD_U64: *ptr(I64 *)+=ip2; break;
case EAT_SUB_U64: *ptr(I64 *)-=ip2; break;
}
Free(tempa);
tempa=tempa1;
}
tempe=tempx->next_ie;
while (tempe!=&tempx->next_ie) {
tempe1=tempe->next;
if (tempe->str) {
Free(str);
str=tempe->str;
}
switch (tempe->type) {
case EIT_REL_EXPORT:
case EIT_IMM_EXPORT:
tempex=CAlloc(sizeof(CHashExport));
tempex->str=str;
str=NULL;
tempex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
if (tempe->type==EIT_IMM_EXPORT)
tempex->val=tempe->ip;
else
tempex->val=tempe->ip+ip2;
tempex->src_link=tempe->src_link;
tempe->src_link=NULL;
HashAdd(tempex,Fs->hash_table);
SysSymImportsResolve(tempex->str);
break;
case EIT_REL_I8...EIT_IMM_U64:
if (tempe->str) {
if (tempe->flags&EIF_GOTO_LABEL) {
if(!(g_lb=LCCGoToLabelFind(lx,str)))
"Unresolved Reference:%s\n",str;
else {
g_lb->use_cnt++;
g_lb=OptLabelFwd(g_lb);
i=g_lb->addr+tempx->buf;
}
tempex=NULL;
} else {
if (!(tempex=HashFind(str,Fs->hash_table,HTG_ALL-HTT_IMPORT_SYS_SYM)))
"Unresolved Reference:%s\n",str;
else {
if (tempex->type & HTT_FUN)
i=tempex(CHashFun *)->executable_addr;
else if (tempex->type & HTT_GLBL_VAR)
i=tempex(CHashGlblVar *)->data_addr;
else
i=tempex->val;
}
g_lb=NULL;
}
}
if (tempex || g_lb) {
ptr=tempe->ip+ip2;
nobound_switch (tempe->type) {
case EIT_REL_I8:
if (!(MIN_I8<=i-ptr-1<=MAX_I8))
LexExcept(lx,"branch out of range at ");
*ptr(U8 *) =i-ptr-1;
break;
case EIT_IMM_U8:
*ptr(U8 *) =i;
break;
case EIT_REL_I16:
if (!(MIN_I16<=i-ptr-2<=MAX_I16))
LexExcept(lx,"branch out of range at ");
*ptr(U16 *)=i-ptr-2;
break;
case EIT_IMM_U16:
*ptr(U16 *)=i;
break;
case EIT_REL_I32:
if (!(MIN_I32<=i-ptr-4<=MAX_I32))
LexExcept(lx,"branch out of range at ");
*ptr(U32 *)=i-ptr-4;
break;
case EIT_IMM_U32:
*ptr(U32 *)=i;
break;
case EIT_REL_I64:
*ptr(I64 *)=i-ptr-8;
break;
case EIT_IMM_U64:
*ptr(I64 *)=i;
break;
}
}
break;
}
Free(tempe->src_link);
Free(tempe);
tempe=tempe1;
}
Free(str);
if (!lx->a_depth && Bt(&lx->opts,OPTf_COMPILE_TRACE))
Un(ip2,tempx->ex_U8s,64);
QueRem(tempx);
Free(tempx);
}
U0 CmpFixUpAOTAsm(CLex *lx,CExe *tempx)
{
CAsmCtrl *a=lx->a;
I64 i,ip2=tempx->ip+lx->a->ip;
U8 *ptr;
CLexCodeMisc *g_lb=NULL;
CExeAbsAddr *tempa,*tempa1;
CExeImportExport *tempe,*tempe1;
tempa=tempx->abss;
while (tempa) {
tempa1=tempa->next;
tempa->next=a->abss;
ptr=tempx->buf+tempx->ip+tempa->ip;
nobound_switch (tempa->type) {
case EAT_ADD_U8:
*ptr(U8 *)+=ip2;
break;
case EAT_SUB_U8:
*ptr(U8 *)-=ip2;
break;
case EAT_ADD_U16:
*ptr(U16 *)+=ip2;
break;
case EAT_SUB_U16:
*ptr(U16 *)-=ip2;
break;
case EAT_ADD_U32:
*ptr(U32 *)+=ip2;
break;
case EAT_SUB_U32:
*ptr(U32 *)-=ip2;
break;
case EAT_ADD_U64:
*ptr(I64 *)+=ip2;
break;
case EAT_SUB_U64:
*ptr(I64 *)-=ip2;
break;
}
a->abss=tempa;
tempa->ip+=ip2;
tempa=tempa1;
}
tempe=tempx->next_ie;
while (tempe!=&tempx->next_ie) {
tempe1=tempe->next;
QueRem(tempe);
if (EIT_REL_I8<=tempe->type<=EIT_IMM_U64) {
if (tempe->str) {
if (tempe->flags&EIF_GOTO_LABEL) {
if(!(g_lb=LCCGoToLabelFind(lx,tempe->str)))
"Unresolved Reference:%s\n",tempe->str;
else {
g_lb->use_cnt++;
g_lb=OptLabelFwd(g_lb);
}
} else
g_lb=NULL;
}
} else
g_lb=NULL;
ptr=tempx->buf+tempx->ip+tempe->ip;
if (g_lb) {
i=g_lb->addr+tempx->buf;
nobound_switch (tempe->type) {
case EIT_REL_I8:
if (!(MIN_I8<=i-ptr-1<=MAX_I8))
LexExcept(lx,"branch out of range at ");
*ptr(U8 *) =i-ptr-1;
break;
case EIT_IMM_U8:
*ptr(U8 *) =i;
break;
case EIT_REL_I16:
if (!(MIN_I16<=i-ptr-2<=MAX_I16))
LexExcept(lx,"branch out of range at ");
*ptr(U16 *)=i-ptr-2;
break;
case EIT_IMM_U16:
*ptr(U16 *)=i;
break;
case EIT_REL_I32:
if (!(MIN_I32<=i-ptr-4<=MAX_I32))
LexExcept(lx,"branch out of range at ");
*ptr(U32 *)=i-ptr-4;
break;
case EIT_IMM_U32:
*ptr(U32 *)=i;
break;
case EIT_REL_I64:
*ptr(I64 *)=i-ptr-8;
break;
case EIT_IMM_U64:
*ptr(I64 *)=i;
break;
}
Free(tempe->src_link);
Free(tempe);
} else {
switch (tempe->type) {
sub_switch_start:
case EIT_REL_EXPORT:
case EIT_IMM_EXPORT:
case EIT_IMM_U8:
case EIT_IMM_U16:
case EIT_IMM_U32:
case EIT_IMM_U64:
break;
case EIT_REL_I8:
*ptr(U8 *) -=ip2;
break;
case EIT_REL_I16:
*ptr(U16 *)-=ip2;
break;
case EIT_REL_I32:
*ptr(U32 *)-=ip2;
break;
case EIT_REL_I64:
*ptr(I64 *)-=ip2;
break;
sub_switch_end:
tempe->ip+=ip2;
break;
}
tempe->exe=NULL;
QueIns(tempe,tempx->parent_exe->last_ie);
}
tempe=tempe1;
}
}
I64 Cmp(U8 *filename,U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv=0)
{ //Compile file, returns err_cnt
U8 *ptr,*fbuf=NULL,*fbuf2=NULL,*fbuf3=NULL,
*patch_table=MAlloc(0x20000);
CExe *tempx;
I64 i,cnt,size=0,error_cnt=0,warning_cnt=0,ex_U8s=0;
CBinFile *bfh;
CExeImportExport *tempe,*tempe1;
CExeAbsAddr *tempa,*tempa1;
CExeHeapGlblRef *temphgr,*temphgr1;
CExeHeapGlbl *temphg,*temphg1;
fbuf=DftExt(filename,"PRJ.Z");
fbuf2=MPrint("#include \"%s\"",fbuf);
if (map_name)
fbuf3=DftExt(map_name,"MAP.Z");
if (tempx=CmpBuf(fbuf2,fbuf3,&error_cnt,&warning_cnt,mapfile_drv)) {
ex_U8s=tempx->ex_U8s;
ptr=patch_table;
//See $LK,"CBinFilePatchTableWithoutOrg",A="MN:CBinFilePatchTableWithoutOrg"$
*ptr++=EIT_MODULE_ALIGNMENT; //See $LK,"Load",A="MN:Load"$() and $LK,"BinRep",A="MN:BinRep"$()
*ptr(U32 *)++=tempx->max_align;
*ptr++=0;
if (tempx->module_org!=INVALID_PTR) {
//See $LK,"CBinFilePatchTableWithOrg",A="MN:CBinFilePatchTableWithOrg"$
*ptr++=EIT_MODULE_ORG;
*ptr(U32 *)++=tempx->module_org;
*ptr++=0;
}
cnt=0;
tempa=tempx->abss;
while (tempa) {
if (!(tempa->type&1))
cnt++;
tempa=tempa->next;
}
if (cnt) {
*ptr++=EIT_ABS_ADDR;
*ptr(U32 *)++=cnt;
*ptr++=0;
tempa=tempx->abss;
while (tempa) {
tempa1=tempa->next;
if (!(tempa->type&1))
*ptr(U32 *)++ =tempa->ip;
Free(tempa);
tempa=tempa1;
}
}
temphg=tempx->heap_glbls;
while (temphg) {
temphg1=temphg->next;
cnt=0;
temphgr=temphg->references;
while (temphgr) {
cnt++;
temphgr=temphgr->next;
}
if (cnt) {
*ptr++=EIT_HEAP_GLBL;
*ptr(U32 *)++=cnt;
if (temphg->str) {
i=StrLen(temphg->str);
MemCpy(ptr,temphg->str,i+1);
Free(temphg->str);
ptr+=i+1;
} else
*ptr++=0;
*ptr(I64 *)++=temphg->size;
temphgr=temphg->references;
while (temphgr) {
temphgr1=temphgr->next;
*ptr(U32 *)++=temphgr->ip;
Free(temphgr);
temphgr=temphgr1;
}
}
Free(temphg);
temphg=temphg1;
}
//Do exports first
tempe=tempx->next_ie;
while (tempe!=&tempx->next_ie) {
tempe1=tempe->next;
if (tempe->type<=EIT_IMM_EXPORT) {
QueRem(tempe);
*ptr++=tempe->type;
*ptr(U32 *)++=tempe->ip;
if (tempe->str) {
i=StrLen(tempe->str);
MemCpy(ptr,tempe->str,i+1);
Free(tempe->str);
ptr+=i+1;
} else
*ptr++=0;
Free(tempe->src_link);
Free(tempe);
}
tempe=tempe1;
}
//Do imports second
tempe=tempx->next_ie;
while (tempe!=&tempx->next_ie) {
tempe1=tempe->next;
QueRem(tempe);
*ptr++=tempe->type;
if (tempe->exe)
tempe->ip+=tempe->exe->ip2;
*ptr(U32 *)++=tempe->ip;
if (tempe->str) {
i=StrLen(tempe->str);
MemCpy(ptr,tempe->str,i+1);
Free(tempe->str);
ptr+=i+1;
} else
*ptr++=0;
Free(tempe->src_link);
Free(tempe);
tempe=tempe1;
}
*ptr++=EIT_END;
MemSet(ptr,0,16);
i=ptr-patch_table;
//Needs 16 ALIGN
size=(sizeof(CBinFile)+ex_U8s+i+15)&-16;
bfh=MAlloc(size);
bfh->jmp=0xEB+256*(sizeof(CBinFile)-2);
#assert sizeof(CBinFile)-2<=MAX_I8
bfh->type=0; //Reserved. Allow other types, maybe. Must be 16 bytes, anyway.
bfh->loader_patch_table_offset=sizeof(CBinFile)+ex_U8s;
bfh->file_size=size;
MemCpy(bfh(U8 *)+sizeof(CBinFile),tempx->buf,ex_U8s);
MemCpy(bfh(U8 *)+sizeof(CBinFile)+ex_U8s,patch_table,size-ex_U8s-sizeof(CBinFile));
Free(fbuf2);
if (out_name)
fbuf2=DftExt(out_name,"BIN.Z");
else
fbuf2=ChgExt(fbuf,"BIN.Z");
if (!cmp_do_not_write_to_dsk)
FileWrite(fbuf2,bfh,size);
Free(bfh);
Free(tempx->buf);
QueDel(tempx);
Free(tempx);
}
Free(patch_table);
Free(fbuf);
Free(fbuf2);
Free(fbuf3);
Print("Errs:%d Warns:%d Code:%X Size:%X\n",error_cnt,warning_cnt,ex_U8s,size);
return error_cnt;
}
I64 ExePutS(U8 *buf,U8 *filename=NULL,Bool just_load=FALSE,CLexHashTableContext *htc=NULL)
{
I64 result;
Bool okay=TRUE;
CLex *lx;
if (!filename)
filename=sys_temp_filename;
lx=LexNew(buf,LF_DONT_FREE_BUF,filename);
if (just_load)
lx->flags|=LF_JUST_LOAD;
if (Fs->last_lex!=&Fs->next_lex) {
lx->opts=Fs->last_lex->opts;
if (htc) {
lx->flags=lx->flags &~LF_ASM_EXPRESSIONS |
htc->old_flags&LF_ASM_EXPRESSIONS;
MemCpy(&lx->htc,htc,sizeof(CLexHashTableContext));
}
}
QueIns(lx,Fs->last_lex);
try {
Lex(lx);
result=ExeCmdLine(lx);
} catch {
if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
Fs->catch_except=TRUE;
okay=FALSE;
result=0;
}
}
QueRem(lx);
if (okay)
LexDel(lx); //TODO: can crash
return result;
}
I64 ExePrint(U8 *fmt,...)
{
I64 result;
U8 *buf=SPrintJoin(NULL,fmt,argc,argv);
result=ExePutS(buf);
Free(buf);
return result;
}
I64 ExeFile(U8 *name,Bool just_load=FALSE)
{
I64 result;
U8 *name2=DftExt(name,"CPP.Z"),
*st=MPrint("#include \"%s\";",name2);
result=ExePutS(st,name,just_load);
Free(st);
Free(name2);
return result;
}
I64 ExePutS2(U8 *buf,U8 *filename=NULL,Bool just_load=FALSE)
{ //throws exceptions
I64 result;
CLex *lx;
if (!filename)
filename=sys_temp_filename;
lx=LexNew(buf,LF_DONT_FREE_BUF,filename);
if (just_load)
lx->flags|=LF_JUST_LOAD;
if (Fs->last_lex!=&Fs->next_lex)
lx->opts=Fs->last_lex->opts;
QueIns(lx,Fs->last_lex);
Lex(lx);
result=ExeCmdLine(lx);
QueRem(lx);
LexDel(lx);
return result;
}
I64 ExePrint2(U8 *fmt,...)
{ //throws exceptions
I64 result;
U8 *buf=SPrintJoin(NULL,fmt,argc,argv);
result=ExePutS2(buf);
Free(buf);
return result;
}
I64 ExeFile2(U8 *name,Bool just_load=FALSE)
{ //throws exceptions
I64 result;
U8 *name2=DftExt(name,"CPP.Z"),
*st=MPrint("#include \"%s\";",name2);
result=ExePutS2(st,name,just_load);
Free(st);
Free(name2);
return result;
}
I64 StreamExePrint(U8 *fmt,...)
{//Suppose you want a value from the stream to be used in an #exe block...
U8 *buf=SPrintJoin(NULL,fmt,argc,argv);
I64 result=0;
CLexHashTableContext *htc;
CLex *lx=Fs->last_lex;
if (lx==&Fs->next_lex)
PrintErr("Not Compiling\n");
else {
if (!(lx->flags&LF_EXE_BLK))
LexExcept(lx,"StreamExePrint only allowed in AOT compiled #exe{} mode.");
if (htc=lx->htc.next)
result=ExePutS(buf,,,htc);
}
Free(buf);
return result;
}
U0 CmpInit()
{
compiled_lines=0;
compiled_funs=0;
compiled_bytes=0;
cmp_do_not_write_to_dsk=FALSE;
CmpLoadDefines;
CmpFillTables;
MemSet(&opt_nop,0,sizeof(CIntermediateCode));
QueInit(&opt_nop);
opt_nop.ic_class=sys_internal_types[RT_I64];
opt_nop.ic_code=IC_NOP1;
AsmHashLoad;
UnasmHashLoad;
}
CmpInit;
Binary file not shown.
+498
View File
@@ -0,0 +1,498 @@
$LK,"AsmGlblsResolve ",A="FL:D:/Compiler/Assembler.CPP.Z,286",BI=1$00000082C8 0001 0000000404 Funct Export Res
$LK,"AsmHashLoad ",A="FL:D:/Compiler/CmpInit.CPP.Z,68",BI=2$0000029492 0001 00000005BF Funct Export Res
$LK,"AsmLexExpression ",A="FL:D:/Compiler/Assembler.CPP.Z,191",BI=3$0000007EA0 0004 00000000B7 Funct Export Res
$LK,"AsmLineLst ",A="FL:D:/Compiler/Assembler.CPP.Z,31",BI=4$0000007908 0001 0000000146 Funct Export Res
$LK,"AsmLocalsResolve ",A="FL:D:/Compiler/Assembler.CPP.Z,252",BI=5$00000081A0 0003 0000000127 Funct Export Res
$LK,"AsmMakeArgMask ",A="FL:D:/Compiler/Assembler.CPP.Z,572",BI=6$0000008C30 0002 0000000444 Funct Export Res
$LK,"AsmPrsInsFlags ",A="FL:D:/Compiler/CmpInit.CPP.Z,18",BI=7$0000029252 0001 000000023B Funct Export Res
$LK,"AsmResolve ",A="FL:D:/Compiler/Assembler.CPP.Z,211",BI=8$0000007F58 0002 0000000245 Funct Export Res
$LK,"AsmStoreCodeU32 ",A="FL:D:/Compiler/Assembler.CPP.Z,92",BI=9$0000007B58 0001 0000000145 Funct Export Res
$LK,"AsmStoreCodeU64 ",A="FL:D:/Compiler/Assembler.CPP.Z,131",BI=10$0000007CA0 0005 0000000146 Funct Export Res
$LK,"AsmStoreCodeU8 ",A="FL:D:/Compiler/Assembler.CPP.Z,63",BI=11$0000007A50 001D 0000000103 Funct Export Res
$LK,"AsmStoreCodeU8At ",A="FL:D:/Compiler/Assembler.CPP.Z,170",BI=12$0000007DE8 0007 00000000B7 Funct Export Res
$LK,"AsmStoreNum ",A="FL:D:/Compiler/Assembler.CPP.Z,666",BI=13$0000009078 0004 00000004A6 Funct Export Res
$LK,"AsmUnresolvedAdd ",A="FL:D:/Compiler/Assembler.CPP.Z,1",BI=14$00000077F8 0004 000000010C Funct Export Res
$LK,"CInternalType ",A="FL:D:/Compiler/CmpInit.CPP.Z,4"$007FC80928 0002 000000000A Class
$LK,"CMP_TEMPLATES ",A="FL:D:/Compiler/CmpAsm.CPP.Z,5"$0000000000 0001 ExportSysSym Export
$LK,"CMP_TEMPLATES_DONT_POP ",A="FL:D:/Compiler/CmpAsm.CPP.Z,179"$000000018B 0001 ExportSysSym Export
$LK,"CMP_TEMPLATES_DONT_PUSH ",A="FL:D:/Compiler/CmpAsm.CPP.Z,268"$0000000257 0001 ExportSysSym Export
$LK,"CMP_TEMPLATES_DONT_PUSH2 ",A="FL:D:/Compiler/CmpAsm.CPP.Z,459"$0000000421 0001 ExportSysSym Export
$LK,"CMP_TEMPLATES_DONT_PUSH_POP",A="FL:D:/Compiler/CmpAsm.CPP.Z,395"$0000000391 0001 ExportSysSym Export
$LK,"CN_A1 ",A="FL:D:/Compiler/BackF1a.CPP.Z,2"$1 0006 0000000008 DefineStr
$LK,"CN_A2 ",A="FL:D:/Compiler/BackF1a.CPP.Z,1"$0 0005 0000000008 DefineStr
$LK,"CN_MAIN ",A="FL:D:/Compiler/BackF1a.CPP.Z,3"$2 0022 0000000008 DefineStr
$LK,"CN_R ",A="FL:D:/Compiler/BackF1a.CPP.Z,4"$3 0003 0000000008 DefineStr
$LK,"COptMemberVar ",A="FL:D:/Compiler/OptLib.CPP.Z,572"$007FC9EFB0 0005 0000000028 Class
$LK,"CSubSwitch ",A="FL:D:/Compiler/StmtParser.CPP.Z,1367"$007FC9C050 0004 0000000020 Class
$LK,"CSwitchCase ",A="FL:D:/Compiler/StmtParser.CPP.Z,1372"$007FD7B8B8 0004 0000000020 Class
$LK,"CTrace ",A="FL:D:/Compiler/ICLCC.CPP.Z,33",BI=15$0000002878 0000 0000000017 Funct Export Res
$LK,"CVI2 ",A="FL:D:/Compiler/StmtParser.CPP.Z,217"$007FC9C330 0003 0000000010 Class
$LK,"Cmp ",A="FL:D:/Compiler/CmpMain.CPP.Z,448",BI=16$000002C002 0000 0000000589 Funct Export Res
$LK,"CmpBuf ",A="FL:D:/Compiler/CmpMain.CPP.Z,175",BI=17$000002B6F2 0001 00000000B6 Funct Export Res
$LK,"CmpF1PushPop ",A="FL:D:/Compiler/OptLib.CPP.Z,554",BI=18$000000C04E 0002 0000000031 Funct Export Res
$LK,"CmpF2PushPop ",A="FL:D:/Compiler/OptLib.CPP.Z,560",BI=19$000000C086 0005 0000000074 Funct Export Res
$LK,"CmpFillTables ",A="FL:D:/Compiler/CmpInit.CPP.Z,445",BI=20$000002A962 0001 000000051A Funct Export Res
$LK,"CmpFixUpAOTAsm ",A="FL:D:/Compiler/CmpMain.CPP.Z,314",BI=21$000002BC22 0000 00000003DD Funct Export Res
$LK,"CmpFixUpJITAsm ",A="FL:D:/Compiler/CmpMain.CPP.Z,192",BI=22$000002B7AA 0000 0000000473 Funct Export Res
$LK,"CmpInit ",A="FL:D:/Compiler/CmpMain.CPP.Z,717",BI=23$000002CA8A 0001 0000000081 Funct Export Res
$LK,"CmpJoin ",A="FL:D:/Compiler/CmpMain.CPP.Z,53",BI=24$000002B06A 0001 0000000682 Funct Export Res
$LK,"CmpLoadDefines ",A="FL:D:/Compiler/CmpInit.CPP.Z,205",BI=25$0000029A52 0001 0000000F0A Funct Export Res
$LK,"CmpNoteFloatOp ",A="FL:D:/Compiler/BackF1a.CPP.Z,6",BI=26$000001B4EE 000E 000000020D Funct Export Res
$LK,"CmpOffset2Reg ",A="FL:D:/Compiler/OptLib.CPP.Z,83",BI=27$000000B406 0005 0000000046 Funct Export Res
$LK,"CmpPmt ",A="FL:D:/Compiler/Lex.CPP.Z,1",BI=28$0000003998 0001 000000023E Funct Export Res
$LK,"CmpRawType ",A="FL:D:/Compiler/OptLib.CPP.Z,534",BI=29$000000BFEE 0006 0000000025 Funct Export Res
$LK,"CmpRawTypePointed ",A="FL:D:/Compiler/OptLib.CPP.Z,543",BI=30$000000C016 0005 0000000033 Funct Export Res
$LK,"CmpSetFloatOpPushPop ",A="FL:D:/Compiler/BackF1a.CPP.Z,57",BI=31$000001B6FE 000C 0000000075 Funct Export Res
$LK,"Echo ",A="FL:D:/Compiler/ICLCC.CPP.Z,38",BI=32$0000002890 0000 0000000017 Funct Export Res
$LK,"ExeFile ",A="FL:D:/Compiler/CmpMain.CPP.Z,649",BI=33$000002C78A 0000 000000007B Funct Export Res
$LK,"ExeFile2 ",A="FL:D:/Compiler/CmpMain.CPP.Z,688",BI=34$000002C91A 0000 0000000079 Funct Export Res
$LK,"ExePrint ",A="FL:D:/Compiler/CmpMain.CPP.Z,640",BI=35$000002C73A 0000 0000000049 Funct Export Res
$LK,"ExePrint2 ",A="FL:D:/Compiler/CmpMain.CPP.Z,679",BI=36$000002C8D2 0000 0000000047 Funct Export Res
$LK,"ExePutS ",A="FL:D:/Compiler/CmpMain.CPP.Z,605",BI=37$000002C592 0003 00000001A1 Funct Export Res
$LK,"ExePutS2 ",A="FL:D:/Compiler/CmpMain.CPP.Z,660",BI=38$000002C80A 0002 00000000C8 Funct Export Res
$LK,"FBO1_F64 ",A="FL:D:/Compiler/OptLib.CPP.Z,94"$2 0002 0000000008 DefineStr
$LK,"FBO1_INT ",A="FL:D:/Compiler/OptLib.CPP.Z,93"$1 0013 0000000008 DefineStr
$LK,"FBO1_NOT_CONST ",A="FL:D:/Compiler/OptLib.CPP.Z,92"$0 0004 0000000008 DefineStr
$LK,"GetOpt ",A="FL:D:/Compiler/ICLCC.CPP.Z,16",BI=39$00000027F0 0004 000000002C Funct Export Res
$LK,"HashEntryImportCopy ",A="FL:D:/Compiler/Hash1b.CPP.Z,1",BI=40$00000072B0 0002 0000000157 Funct Export Res
$LK,"HashEntrySize ",A="FL:D:/Compiler/Hash1b.CPP.Z,67",BI=41$00000074D8 0000 0000000103 Funct Export Res
$LK,"HashEntrySize2 ",A="FL:D:/Compiler/Hash1b.CPP.Z,98",BI=42$00000075E0 0002 00000001A4 Funct Export Res
$LK,"HashTableImport ",A="FL:D:/Compiler/Hash1b.CPP.Z,40",BI=43$0000007408 0000 00000000CD Funct Export Res
$LK,"HashTableSize2 ",A="FL:D:/Compiler/Hash1b.CPP.Z,135",BI=44$0000007788 0000 000000006F Funct Export Res
$LK,"ICAddEct ",A="FL:D:/Compiler/Back1a.CPP.Z,1",BI=45$000001F156 0005 00000002F3 Funct Export Res
$LK,"ICAddRSP ",A="FL:D:/Compiler/BackLib.CPP.Z,72",BI=46$0000019E96 0017 00000002A7 Funct Export Res
$LK,"ICAddSubEctEqual ",A="FL:D:/Compiler/Back1a.CPP.Z,506",BI=47$0000020A56 0005 0000000673 Funct Export Res
$LK,"ICAddSubEctImm ",A="FL:D:/Compiler/Back1a.CPP.Z,57",BI=48$000001F44E 000D 000000067F Funct Export Res
$LK,"ICAndAnd ",A="FL:D:/Compiler/Back1b.CPP.Z,30",BI=49$00000216F6 0001 000000014B Funct Export Res
$LK,"ICAndBranch ",A="FL:D:/Compiler/Back1c.CPP.Z,1",BI=50$000002398E 0002 00000006E4 Funct Export Res
$LK,"ICAndEqual ",A="FL:D:/Compiler/Back1c.CPP.Z,676",BI=51$000002586E 0001 000000010D Funct Export Res
$LK,"ICArgPut ",A="FL:D:/Compiler/ICLCC.CPP.Z,93",BI=52$0000002AA8 0003 00000002D3 Funct Export Res
$LK,"ICAssign ",A="FL:D:/Compiler/Back1c.CPP.Z,159",BI=53$0000024076 0001 0000000301 Funct Export Res
$LK,"ICAssignPostIncDec ",A="FL:D:/Compiler/Back1b.CPP.Z,535",BI=54$0000022D4E 0002 0000000210 Funct Export Res
$LK,"ICBitOps ",A="FL:D:/Compiler/Back1b.CPP.Z,244",BI=55$0000021FEE 0007 00000004F1 Funct Export Res
$LK,"ICBrBitOps ",A="FL:D:/Compiler/Back1c.CPP.Z,208",BI=56$000002437E 0008 00000009FB Funct Export Res
$LK,"ICBuiltInFloatConst ",A="FL:D:/Compiler/BackLib.CPP.Z,424",BI=57$000001A9CE 000F 00000000BD Funct Export Res
$LK,"ICClassPut ",A="FL:D:/Compiler/ICLCC.CPP.Z,68",BI=58$00000029D0 0001 00000000D3 Funct Export Res
$LK,"ICCmp ",A="FL:D:/Compiler/Back1b.CPP.Z,124",BI=59$0000021B06 0006 00000004E6 Funct Export Res
$LK,"ICCmpAndBranch ",A="FL:D:/Compiler/Back1b.CPP.Z,577",BI=60$0000022F5E 000C 0000000737 Funct Export Res
$LK,"ICCopyTemplate ",A="FL:D:/Compiler/BackF1a.CPP.Z,69",BI=61$000001B776 0013 000000021D Funct Export Res
$LK,"ICDeref ",A="FL:D:/Compiler/BackLib.CPP.Z,661",BI=62$000001B42E 0001 00000000B9 Funct Export Res
$LK,"ICDerefPostIncDec ",A="FL:D:/Compiler/Back1b.CPP.Z,492",BI=63$0000022B56 0002 00000001F1 Funct Export Res
$LK,"ICDiv ",A="FL:D:/Compiler/Back1a.CPP.Z,414",BI=64$0000020586 0001 00000000F1 Funct Export Res
$LK,"ICDivEqual ",A="FL:D:/Compiler/Back1a.CPP.Z,433",BI=65$000002067E 0002 00000002DE Funct Export Res
$LK,"ICFAdd ",A="FL:D:/Compiler/BackF1b.CPP.Z,634",BI=66$000001EB16 0001 00000001FF Funct Export Res
$LK,"ICFCmp ",A="FL:D:/Compiler/BackF1a.CPP.Z,549",BI=67$000001CAEE 0004 000000018B Funct Export Res
$LK,"ICFCmpAndBranch ",A="FL:D:/Compiler/BackF1b.CPP.Z,325",BI=68$000001DF4E 0004 00000009F7 Funct Export Res
$LK,"ICFCvt ",A="FL:D:/Compiler/BackF1a.CPP.Z,115",BI=69$000001B996 000C 000000017F Funct Export Res
$LK,"ICFCvt2 ",A="FL:D:/Compiler/BackF1a.CPP.Z,163",BI=70$000001BB16 0010 0000000116 Funct Export Res
$LK,"ICFDiv ",A="FL:D:/Compiler/BackF1b.CPP.Z,622",BI=71$000001EA66 0001 00000000A9 Funct Export Res
$LK,"ICFMod ",A="FL:D:/Compiler/BackF1a.CPP.Z,241",BI=72$000001BE0E 0001 0000000145 Funct Export Res
$LK,"ICFModEqual ",A="FL:D:/Compiler/BackF1a.CPP.Z,589",BI=73$000001CC7E 0001 00000003D7 Funct Export Res
$LK,"ICFMul ",A="FL:D:/Compiler/BackF1b.CPP.Z,604",BI=74$000001E946 0001 000000011B Funct Export Res
$LK,"ICFOp ",A="FL:D:/Compiler/BackF1a.CPP.Z,350",BI=75$000001C24E 0004 000000089D Funct Export Res
$LK,"ICFOpEqual ",A="FL:D:/Compiler/BackF1b.CPP.Z,1",BI=76$000001D056 0004 0000000EF7 Funct Export Res
$LK,"ICFPostIncDec ",A="FL:D:/Compiler/BackF1b.CPP.Z,717",BI=77$000001EF4E 0002 0000000151 Funct Export Res
$LK,"ICFPow ",A="FL:D:/Compiler/BackF1a.CPP.Z,271",BI=78$000001BF56 0001 00000002F7 Funct Export Res
$LK,"ICFPreIncDec ",A="FL:D:/Compiler/BackF1b.CPP.Z,695",BI=79$000001EE3E 0002 000000010A Funct Export Res
$LK,"ICFSub ",A="FL:D:/Compiler/BackF1b.CPP.Z,672",BI=80$000001ED16 0001 0000000124 Funct Export Res
$LK,"ICFTemplateFun ",A="FL:D:/Compiler/BackF1b.CPP.Z,745",BI=81$000001F0A6 0007 00000000AA Funct Export Res
$LK,"ICFUnaryMinus ",A="FL:D:/Compiler/BackF1a.CPP.Z,190",BI=82$000001BC2E 0001 00000001E0 Funct Export Res
$LK,"ICFlagBranch ",A="FL:D:/Compiler/Back1b.CPP.Z,805",BI=83$0000023886 0004 0000000106 Funct Export Res
$LK,"ICLastIns ",A="FL:D:/Compiler/BackLib.CPP.Z,62",BI=84$0000019E56 0002 0000000040 Funct Export Res
$LK,"ICLea ",A="FL:D:/Compiler/BackLib.CPP.Z,627",BI=85$000001B27E 0004 00000001AA Funct Export Res
$LK,"ICLocalVarInit ",A="FL:D:/Compiler/Back1c.CPP.Z,909",BI=86$000002628E 0001 0000000078 Funct Export Res
$LK,"ICMinMax ",A="FL:D:/Compiler/Back1c.CPP.Z,497",BI=87$0000025146 0004 00000002AB Funct Export Res
$LK,"ICMod ",A="FL:D:/Compiler/Back1a.CPP.Z,487",BI=88$000002095E 0001 00000000F1 Funct Export Res
$LK,"ICModU64 ",A="FL:D:/Compiler/Back1c.CPP.Z,576",BI=89$0000025446 0001 00000001B7 Funct Export Res
$LK,"ICModr1 ",A="FL:D:/Compiler/BackLib.CPP.Z,143",BI=90$000001A13E 0017 00000002FE Funct Export Res
$LK,"ICModr2 ",A="FL:D:/Compiler/BackLib.CPP.Z,234",BI=91$000001A43E 0016 00000000A6 Funct Export Res
$LK,"ICMov ",A="FL:D:/Compiler/BackLib.CPP.Z,447",BI=92$000001AA8E 019A 00000007EC Funct Export Res
$LK,"ICMul ",A="FL:D:/Compiler/Back1a.CPP.Z,289",BI=93$000001FEC6 0001 00000002B8 Funct Export Res
$LK,"ICMulEqual ",A="FL:D:/Compiler/Back1a.CPP.Z,346",BI=94$000002017E 0001 0000000406 Funct Export Res
$LK,"ICNot ",A="FL:D:/Compiler/Back1b.CPP.Z,10",BI=95$00000215F6 0001 00000000FF Funct Export Res
$LK,"ICOpSizeRex ",A="FL:D:/Compiler/BackLib.CPP.Z,31",BI=96$0000019D6E 0006 0000000040 Funct Export Res
$LK,"ICOrEqual ",A="FL:D:/Compiler/Back1c.CPP.Z,699",BI=97$000002597E 0001 000000010D Funct Export Res
$LK,"ICOrOr ",A="FL:D:/Compiler/Back1b.CPP.Z,59",BI=98$0000021846 0001 0000000162 Funct Export Res
$LK,"ICPop ",A="FL:D:/Compiler/BackLib.CPP.Z,365",BI=99$000001A7D6 0009 00000000EA Funct Export Res
$LK,"ICPopRegs ",A="FL:D:/Compiler/BackLib.CPP.Z,392",BI=100$000001A8C6 000C 0000000057 Funct Export Res
$LK,"ICPostIncDec ",A="FL:D:/Compiler/Back1b.CPP.Z,452",BI=101$0000022956 0002 00000001FF Funct Export Res
$LK,"ICPreIncDec ",A="FL:D:/Compiler/Back1b.CPP.Z,415",BI=102$0000022776 0004 00000001DB Funct Export Res
$LK,"ICPreempt ",A="FL:D:/Compiler/Back1b.CPP.Z,348",BI=103$00000224E6 0001 0000000122 Funct Export Res
$LK,"ICPush ",A="FL:D:/Compiler/BackLib.CPP.Z,314",BI=104$000001A62E 001F 000000014E Funct Export Res
$LK,"ICPushRegs ",A="FL:D:/Compiler/BackLib.CPP.Z,352",BI=105$000001A77E 0006 0000000054 Funct Export Res
$LK,"ICPut ",A="FL:D:/Compiler/ICLCC.CPP.Z,138",BI=106$0000002D80 0008 00000003B2 Funct Export Res
$LK,"ICQueInit ",A="FL:D:/Compiler/Back1c.CPP.Z,385",BI=107$0000024D7E 0001 0000000070 Funct Export Res
$LK,"ICQueIns ",A="FL:D:/Compiler/Back1c.CPP.Z,399",BI=108$0000024DEE 0001 0000000162 Funct Export Res
$LK,"ICQueInsRev ",A="FL:D:/Compiler/Back1c.CPP.Z,440",BI=109$0000024F56 0001 0000000162 Funct Export Res
$LK,"ICQueRem ",A="FL:D:/Compiler/Back1c.CPP.Z,481",BI=110$00000250BE 0001 0000000088 Funct Export Res
$LK,"ICRex ",A="FL:D:/Compiler/BackLib.CPP.Z,25",BI=111$0000019D3E 0016 000000002D Funct Export Res
$LK,"ICShift ",A="FL:D:/Compiler/Back1a.CPP.Z,644",BI=112$00000210CE 0004 00000001A3 Funct Export Res
$LK,"ICShiftEqual ",A="FL:D:/Compiler/Back1a.CPP.Z,677",BI=113$0000021276 0002 000000030E Funct Export Res
$LK,"ICSlashOp ",A="FL:D:/Compiler/BackLib.CPP.Z,286",BI=114$000001A4E6 0027 0000000143 Funct Export Res
$LK,"ICSqr ",A="FL:D:/Compiler/Back1c.CPP.Z,569",BI=115$00000253F6 0002 000000004A Funct Export Res
$LK,"ICSub ",A="FL:D:/Compiler/Back1a.CPP.Z,211",BI=116$000001FACE 0001 00000003F5 Funct Export Res
$LK,"ICSwap ",A="FL:D:/Compiler/Back1c.CPP.Z,618",BI=117$00000255FE 0001 000000026E Funct Export Res
$LK,"ICSwitch ",A="FL:D:/Compiler/Back1c.CPP.Z,745",BI=118$0000025B96 0002 00000006F2 Funct Export Res
$LK,"ICTest ",A="FL:D:/Compiler/BackLib.CPP.Z,414",BI=119$000001A97E 000C 000000004E Funct Export Res
$LK,"ICTestAndBranch ",A="FL:D:/Compiler/Back1b.CPP.Z,757",BI=120$0000023696 0002 00000001EC Funct Export Res
$LK,"ICToBool ",A="FL:D:/Compiler/Back1b.CPP.Z,400",BI=121$00000226FE 0001 0000000075 Funct Export Res
$LK,"ICToF64 ",A="FL:D:/Compiler/Back1b.CPP.Z,395",BI=122$00000226BE 0001 000000003D Funct Export Res
$LK,"ICToI64 ",A="FL:D:/Compiler/Back1b.CPP.Z,390",BI=123$000002267E 0001 000000003D Funct Export Res
$LK,"ICToUpper ",A="FL:D:/Compiler/Back1b.CPP.Z,379",BI=124$000002260E 0001 000000006B Funct Export Res
$LK,"ICU16 ",A="FL:D:/Compiler/BackLib.CPP.Z,38",BI=125$0000019DAE 0092 0000000029 Funct Export Res
$LK,"ICU24 ",A="FL:D:/Compiler/BackLib.CPP.Z,44",BI=126$0000019DDE 0063 0000000026 Funct Export Res
$LK,"ICU32 ",A="FL:D:/Compiler/BackLib.CPP.Z,50",BI=127$0000019E06 0054 0000000026 Funct Export Res
$LK,"ICU64 ",A="FL:D:/Compiler/BackLib.CPP.Z,56",BI=128$0000019E2E 0009 0000000028 Funct Export Res
$LK,"ICU8 ",A="FL:D:/Compiler/BackLib.CPP.Z,20",BI=129$0000019D16 0063 0000000028 Funct Export Res
$LK,"ICUnaries ",A="FL:D:/Compiler/Back1b.CPP.Z,1",BI=130$0000021586 0002 0000000069 Funct Export Res
$LK,"ICXorEqual ",A="FL:D:/Compiler/Back1c.CPP.Z,722",BI=131$0000025A8E 0001 0000000107 Funct Export Res
$LK,"ICXorXor ",A="FL:D:/Compiler/Back1b.CPP.Z,91",BI=132$00000219AE 0001 0000000155 Funct Export Res
$LK,"ICZero ",A="FL:D:/Compiler/BackLib.CPP.Z,405",BI=133$000001A91E 0017 000000005E Funct Export Res
$LK,"ImportHashTable ",A="FL:D:/Compiler/ICLCC.CPP.Z,42",BI=134$00000028A8 0000 00000000F1 Funct Export Res
$LK,"IncludeDepth ",A="FL:D:/Compiler/ICLCC.CPP.Z,62",BI=135$00000029A0 0000 0000000030 Funct Export Res
$LK,"InstEntriesCompare ",A="FL:D:/Compiler/Unassembler.CPP.Z,1",BI=136$0000000718 0001 00000002A9 Funct Export Res
$LK,"InstEntryFind ",A="FL:D:/Compiler/Unassembler.CPP.Z,73",BI=137$00000009C8 0002 00000003C9 Funct Export Res
$LK,"IsLexExpression2Bin ",A="FL:D:/Compiler/ExpParser.CPP.Z,1154",BI=138$000000F016 0000 0000000029 Funct Export Res
$LK,"LCCAdd ",A="FL:D:/Compiler/ICLCC.CPP.Z,220",BI=139$00000031B0 00A9 000000009F Funct Export Res
$LK,"LCCAppend ",A="FL:D:/Compiler/ICLCC.CPP.Z,259",BI=140$00000032D8 0003 00000000A6 Funct Export Res
$LK,"LCCCompile ",A="FL:D:/Compiler/ICLCC.CPP.Z,376",BI=141$0000003708 0006 000000028B Funct Export Res
$LK,"LCCDel ",A="FL:D:/Compiler/ICLCC.CPP.Z,319",BI=142$00000034F8 0001 0000000164 Funct Export Res
$LK,"LCCFloatConstFind ",A="FL:D:/Compiler/ICLCC.CPP.Z,297",BI=143$0000003430 000F 00000000C6 Funct Export Res
$LK,"LCCGoToLabelFind ",A="FL:D:/Compiler/ICLCC.CPP.Z,285",BI=144$00000033D8 0005 0000000057 Funct Export Res
$LK,"LCCHeaderPut ",A="FL:D:/Compiler/ICLCC.CPP.Z,362",BI=145$0000003660 000A 00000000A2 Funct Export Res
$LK,"LCCInit ",A="FL:D:/Compiler/ICLCC.CPP.Z,212",BI=146$0000003170 000A 000000003A Funct Export Res
$LK,"LCCMiscNew ",A="FL:D:/Compiler/ICLCC.CPP.Z,276",BI=147$0000003380 0021 0000000055 Funct Export Res
$LK,"LCCPop ",A="FL:D:/Compiler/ICLCC.CPP.Z,254",BI=148$00000032B8 0008 000000001A Funct Export Res
$LK,"LCCPopNoFree ",A="FL:D:/Compiler/ICLCC.CPP.Z,247",BI=149$0000003288 0003 000000002E Funct Export Res
$LK,"LCCPush ",A="FL:D:/Compiler/ICLCC.CPP.Z,240",BI=150$0000003250 000E 0000000037 Funct Export Res
$LK,"LCCQuePut ",A="FL:D:/Compiler/ICLCC.CPP.Z,202",BI=151$0000003138 0001 0000000037 Funct Export Res
$LK,"Lex ",A="FL:D:/Compiler/Lex.CPP.Z,742",BI=152$0000005668 00E6 0000001866 Funct Export Res
$LK,"LexAttachDoc ",A="FL:D:/Compiler/Lex.CPP.Z,378",BI=153$0000004AF0 0001 0000000163 Funct Export Res
$LK,"LexBackupLastChar ",A="FL:D:/Compiler/Lex.CPP.Z,132",BI=154$0000003F8C 0003 0000000041 Funct Export Res
$LK,"LexDel ",A="FL:D:/Compiler/Lex.CPP.Z,67",BI=155$0000003D10 0004 00000000A5 Funct Export Res
$LK,"LexDocRead ",A="FL:D:/Compiler/Lex.CPP.Z,361",BI=156$0000004A68 0001 0000000087 Funct Export Res
$LK,"LexDollar ",A="FL:D:/Compiler/Lex.CPP.Z,143",BI=157$0000003FD4 0003 0000000070 Funct Export Res
$LK,"LexExcept ",A="FL:D:/Compiler/Lex.CPP.Z,1615",BI=158$00000071E8 00AE 00000000C1 Funct Export Res
$LK,"LexExpression ",A="FL:D:/Compiler/ExpParser.CPP.Z,1159",BI=159$000000F046 0007 000000003F Funct Export Res
$LK,"LexExpression2Bin ",A="FL:D:/Compiler/ExpParser.CPP.Z,1136",BI=160$000000EF7E 0004 0000000094 Funct Export Res
$LK,"LexExtStr ",A="FL:D:/Compiler/Lex.CPP.Z,1532",BI=161$0000006ED0 0004 00000000C5 Funct Export Res
$LK,"LexGetChar ",A="FL:D:/Compiler/Lex.CPP.Z,157",BI=162$0000004044 0030 000000094F Funct Export Res
$LK,"LexInStr ",A="FL:D:/Compiler/Lex.CPP.Z,644",BI=163$0000005338 0001 000000032A Funct Export Res
$LK,"LexIncludeStr ",A="FL:D:/Compiler/Lex.CPP.Z,334",BI=164$00000049C4 0003 0000000091 Funct Export Res
$LK,"LexNew ",A="FL:D:/Compiler/Lex.CPP.Z,37",BI=165$0000003BD8 0004 0000000136 Funct Export Res
$LK,"LexPop ",A="FL:D:/Compiler/Lex.CPP.Z,435",BI=166$0000004CE0 0004 0000000074 Funct Export Res
$LK,"LexPush ",A="FL:D:/Compiler/Lex.CPP.Z,423",BI=167$0000004C58 000F 0000000081 Funct Export Res
$LK,"LexPutLine ",A="FL:D:/Compiler/Lex.CPP.Z,1557",BI=168$0000006F98 0003 000000009B Funct Export Res
$LK,"LexPutPos ",A="FL:D:/Compiler/Lex.CPP.Z,1585",BI=169$0000007038 0003 00000000CA Funct Export Res
$LK,"LexPutToken ",A="FL:D:/Compiler/Lex.CPP.Z,109",BI=170$0000003E58 0001 000000012B Funct Export Res
$LK,"LexSize ",A="FL:D:/Compiler/Lex.CPP.Z,89",BI=171$0000003DB8 0000 000000009B Funct Export Res
$LK,"LexSkipEol ",A="FL:D:/Compiler/Lex.CPP.Z,327",BI=172$0000004994 0004 000000002B Funct Export Res
$LK,"LexStatement2Bin ",A="FL:D:/Compiler/CmpMain.CPP.Z,18",BI=173$000002AF2A 0001 000000013C Funct Export Res
$LK,"LexWarn ",A="FL:D:/Compiler/Lex.CPP.Z,1599",BI=174$0000007108 0009 00000000D9 Funct Export Res
$LK,"MDR_D32_INDIRECT_REG ",A="FL:D:/Compiler/BackLib.CPP.Z,137"$3 0002 0000000008 DefineStr
$LK,"MDR_D8_INDIRECT_REG ",A="FL:D:/Compiler/BackLib.CPP.Z,136"$2 0002 0000000008 DefineStr
$LK,"MDR_INDIRECT_REG ",A="FL:D:/Compiler/BackLib.CPP.Z,135"$1 0002 0000000008 DefineStr
$LK,"MDR_REG ",A="FL:D:/Compiler/BackLib.CPP.Z,134"$0 0002 0000000008 DefineStr
$LK,"MDR_RIP_REL ",A="FL:D:/Compiler/BackLib.CPP.Z,141"$7 0004 0000000008 DefineStr
$LK,"MDR_SIB_D32_INDIRECT_REG ",A="FL:D:/Compiler/BackLib.CPP.Z,140"$6 0003 0000000008 DefineStr
$LK,"MDR_SIB_D8_INDIRECT_REG ",A="FL:D:/Compiler/BackLib.CPP.Z,139"$5 0002 0000000008 DefineStr
$LK,"MDR_SIB_INDIRECT_REG ",A="FL:D:/Compiler/BackLib.CPP.Z,138"$4 0002 0000000008 DefineStr
$LK,"MemberAdd ",A="FL:D:/Compiler/Lex.CPP.Z,504",BI=175$0000004E90 0004 00000001BA Funct Export Res
$LK,"MemberFind ",A="FL:D:/Compiler/Lex.CPP.Z,469",BI=176$0000004DE0 0005 0000000067 Funct Export Res
$LK,"MemberFind2 ",A="FL:D:/Compiler/Lex.CPP.Z,489",BI=177$0000004E48 0001 0000000044 Funct Export Res
$LK,"MemberLstCopy ",A="FL:D:/Compiler/Lex.CPP.Z,589",BI=178$0000005148 0001 000000011F Funct Export Res
$LK,"MemberLstDel ",A="FL:D:/Compiler/Lex.CPP.Z,552",BI=179$0000005050 0001 00000000F3 Funct Export Res
$LK,"MemberLstNew ",A="FL:D:/Compiler/StmtParser.CPP.Z,78",BI=180$000000F1F6 0003 000000002A Funct Export Res
$LK,"MemberLstSize ",A="FL:D:/Compiler/Lex.CPP.Z,617",BI=181$0000005268 0002 00000000CF Funct Export Res
$LK,"MemberMetaData ",A="FL:D:/Compiler/Lex.CPP.Z,447",BI=182$0000004D58 0000 0000000041 Funct Export Res
$LK,"MemberMetaFind ",A="FL:D:/Compiler/Lex.CPP.Z,458",BI=183$0000004DA0 0000 0000000040 Funct Export Res
$LK,"NUM_INTERNAL_TYPES ",A="FL:D:/Compiler/CmpInit.CPP.Z,1"$17 0002 0000000008 DefineStr
$LK,"OTrace ",A="FL:D:/Compiler/ICLCC.CPP.Z,21",BI=184$0000002820 0000 0000000017 Funct Export Res
$LK,"OTraceMask ",A="FL:D:/Compiler/ICLCC.CPP.Z,26",BI=185$0000002838 0000 0000000039 Funct Export Res
$LK,"OptBrNotZero ",A="FL:D:/Compiler/OptLib.CPP.Z,362",BI=186$000000BB46 0004 0000000403 Funct Export Res
$LK,"OptBrZero ",A="FL:D:/Compiler/OptLib.CPP.Z,213",BI=187$000000B73E 0006 0000000403 Funct Export Res
$LK,"OptClassFwd ",A="FL:D:/Compiler/OptLib.CPP.Z,9",BI=188$000000B266 0013 000000002B Funct Export Res
$LK,"OptEqu ",A="FL:D:/Compiler/ICLCC.CPP.Z,1",BI=189$0000002790 0005 000000002E Funct Export Res
$LK,"OptFixSizeOf ",A="FL:D:/Compiler/OptLib.CPP.Z,510",BI=190$000000BF4E 0003 000000009B Funct Export Res
$LK,"OptFixupBinaryOp1 ",A="FL:D:/Compiler/OptLib.CPP.Z,96",BI=191$000000B44E 0013 00000001CB Funct Export Res
$LK,"OptFixupBinaryOp2 ",A="FL:D:/Compiler/OptLib.CPP.Z,162",BI=192$000000B61E 0001 0000000054 Funct Export Res
$LK,"OptFixupUnaryOp ",A="FL:D:/Compiler/OptLib.CPP.Z,178",BI=193$000000B676 0003 00000000C8 Funct Export Res
$LK,"OptFree ",A="FL:D:/Compiler/OptLib.CPP.Z,33",BI=194$000000B316 0023 0000000024 Funct Export Res
$LK,"OptIC4 ",A="FL:D:/Compiler/OptPass4.CPP.Z,1",BI=195$0000017ABE 0001 00000005CD Funct Export Res
$LK,"OptIC6 ",A="FL:D:/Compiler/OptPass6.CPP.Z,1",BI=196$00000193D6 0001 0000000128 Funct Export Res
$LK,"OptLabelFwd ",A="FL:D:/Compiler/OptLib.CPP.Z,1",BI=197$000000B23E 0010 0000000028 Funct Export Res
$LK,"OptLag ",A="FL:D:/Compiler/OptLib.CPP.Z,40",BI=198$000000B33E 000E 000000002A Funct Export Res
$LK,"OptLag1 ",A="FL:D:/Compiler/OptLib.CPP.Z,51",BI=199$000000B36E 0006 0000000031 Funct Export Res
$LK,"OptLag2 ",A="FL:D:/Compiler/OptLib.CPP.Z,62",BI=200$000000B3A6 0003 000000002A Funct Export Res
$LK,"OptLead1 ",A="FL:D:/Compiler/OptLib.CPP.Z,73",BI=201$000000B3D6 0004 0000000030 Funct Export Res
$LK,"OptMVCompare ",A="FL:D:/Compiler/OptLib.CPP.Z,577",BI=202$000000C0FE 0001 000000001A Funct Export Res
$LK,"OptOff ",A="FL:D:/Compiler/ICLCC.CPP.Z,11",BI=203$00000027D8 0000 0000000016 Funct Export Res
$LK,"OptOn ",A="FL:D:/Compiler/ICLCC.CPP.Z,6",BI=204$00000027C0 0000 0000000016 Funct Export Res
$LK,"OptPass012 ",A="FL:D:/Compiler/OptPass012.CPP.Z,24",BI=205$0000013C8E 0000 00000027CC Funct Export Res
$LK,"OptPass3 ",A="FL:D:/Compiler/OptPass3.CPP.Z,1",BI=206$000001645E 0000 0000001659 Funct Export Res
$LK,"OptPass4 ",A="FL:D:/Compiler/OptPass4.CPP.Z,171",BI=207$000001808E 0000 0000000F05 Funct Export Res
$LK,"OptPass5 ",A="FL:D:/Compiler/OptPass5.CPP.Z,1",BI=208$0000018F96 0000 000000043F Funct Export Res
$LK,"OptPass6 ",A="FL:D:/Compiler/OptPass6.CPP.Z,111",BI=209$0000019826 0000 00000004EA Funct Export Res
$LK,"OptPass6Lag ",A="FL:D:/Compiler/OptPass6.CPP.Z,28",BI=210$00000194FE 0001 0000000327 Funct Export Res
$LK,"OptPass789 ",A="FL:D:/Compiler/OptPass789.CPP.Z,1",BI=211$0000026306 0000 0000002E9E Funct Export Res
$LK,"OptSetNOP1 ",A="FL:D:/Compiler/OptLib.CPP.Z,17",BI=212$000000B296 0079 000000003A Funct Export Res
$LK,"OptSetNOP2 ",A="FL:D:/Compiler/OptLib.CPP.Z,25",BI=213$000000B2D6 000D 000000003C Funct Export Res
$LK,"PE_CHECK_BINARY_OPS1 ",A="FL:D:/Compiler/ExpParser.CPP.Z,43"$5 0001 0000000008 DefineStr
$LK,"PE_CHECK_BINARY_OPS2 ",A="FL:D:/Compiler/ExpParser.CPP.Z,44"$6 0001 0000000008 DefineStr
$LK,"PE_DEREFERENCE ",A="FL:D:/Compiler/ExpParser.CPP.Z,42"$4 0003 0000000008 DefineStr
$LK,"PE_DO_BINARY_OP ",A="FL:D:/Compiler/ExpParser.CPP.Z,46"$8 0001 0000000008 DefineStr
$LK,"PE_DO_UNARY_OP ",A="FL:D:/Compiler/ExpParser.CPP.Z,45"$7 0001 0000000008 DefineStr
$LK,"PE_MAYBE_MODIFIERS ",A="FL:D:/Compiler/ExpParser.CPP.Z,40"$2 000A 0000000008 DefineStr
$LK,"PE_POP_ALL1 ",A="FL:D:/Compiler/ExpParser.CPP.Z,49"$11 0001 0000000008 DefineStr
$LK,"PE_POP_ALL2 ",A="FL:D:/Compiler/ExpParser.CPP.Z,50"$12 0001 0000000008 DefineStr
$LK,"PE_POP_HIGHER ",A="FL:D:/Compiler/ExpParser.CPP.Z,47"$9 0001 0000000008 DefineStr
$LK,"PE_PUSH_LOWER ",A="FL:D:/Compiler/ExpParser.CPP.Z,48"$10 0001 0000000008 DefineStr
$LK,"PE_UNARY_MODIFIERS ",A="FL:D:/Compiler/ExpParser.CPP.Z,41"$3 0009 0000000008 DefineStr
$LK,"PE_UNARY_TERM1 ",A="FL:D:/Compiler/ExpParser.CPP.Z,38"$0 0001 0000000008 DefineStr
$LK,"PE_UNARY_TERM2 ",A="FL:D:/Compiler/ExpParser.CPP.Z,39"$1 0003 0000000008 DefineStr
$LK,"ParenWarning ",A="FL:D:/Compiler/ExpParser.CPP.Z,1",BI=214$000000C11E 0004 000000004C Funct Export Res
$LK,"PrsAddOp ",A="FL:D:/Compiler/ExpParser.CPP.Z,52",BI=215$000000C266 0002 00000001EE Funct Export Res
$LK,"PrsArrayDims ",A="FL:D:/Compiler/StmtParser.CPP.Z,345",BI=216$000000FC7E 0001 000000012D Funct Export Res
$LK,"PrsAsmArg ",A="FL:D:/Compiler/Assembler.CPP.Z,430",BI=217$0000008808 0002 0000000424 Funct Export Res
$LK,"PrsAsmBlk ",A="FL:D:/Compiler/Assembler.CPP.Z,1281",BI=218$000000A97E 0002 00000008C0 Funct Export Res
$LK,"PrsAsmDefine ",A="FL:D:/Compiler/Assembler.CPP.Z,1192",BI=219$000000A61E 0004 000000029D Funct Export Res
$LK,"PrsAsmImm ",A="FL:D:/Compiler/Assembler.CPP.Z,396",BI=220$00000086D0 0006 0000000131 Funct Export Res
$LK,"PrsAsmInstruction ",A="FL:D:/Compiler/Assembler.CPP.Z,784",BI=221$0000009526 0001 00000010F3 Funct Export Res
$LK,"PrsBinFile ",A="FL:D:/Compiler/Assembler.CPP.Z,1265",BI=222$000000A8BE 0001 00000000BB Funct Export Res
$LK,"PrsClass ",A="FL:D:/Compiler/StmtParser.CPP.Z,822",BI=223$0000010CF6 0002 000000023E Funct Export Res
$LK,"PrsClassNew ",A="FL:D:/Compiler/StmtParser.CPP.Z,1",BI=224$000000F086 0003 00000000B7 Funct Export Res
$LK,"PrsDoWhile ",A="FL:D:/Compiler/StmtParser.CPP.Z,1306",BI=225$000001204E 0001 0000000137 Funct Export Res
$LK,"PrsDotDotDot ",A="FL:D:/Compiler/StmtParser.CPP.Z,382",BI=226$000000FDAE 0001 0000000111 Funct Export Res
$LK,"PrsExpression ",A="FL:D:/Compiler/ExpParser.CPP.Z,298",BI=227$000000CABE 0010 0000000149 Funct Export Res
$LK,"PrsExpression2 ",A="FL:D:/Compiler/ExpParser.CPP.Z,102",BI=228$000000C456 0001 0000000667 Funct Export Res
$LK,"PrsFor ",A="FL:D:/Compiler/StmtParser.CPP.Z,1330",BI=229$0000012186 0001 0000000162 Funct Export Res
$LK,"PrsFun ",A="FL:D:/Compiler/StmtParser.CPP.Z,944",BI=230$000001110E 0001 00000003B7 Funct Export Res
$LK,"PrsFunCall ",A="FL:D:/Compiler/ExpParser.CPP.Z,409",BI=231$000000CF5E 0003 000000082D Funct Export Res
$LK,"PrsFunJoin ",A="FL:D:/Compiler/StmtParser.CPP.Z,883",BI=232$0000010F36 0005 00000001D6 Funct Export Res
$LK,"PrsFunNew ",A="FL:D:/Compiler/StmtParser.CPP.Z,43",BI=233$000000F13E 0001 00000000B7 Funct Export Res
$LK,"PrsGlblInit ",A="FL:D:/Compiler/StmtParser.CPP.Z,305",BI=234$000000FABE 0002 000000007C Funct Export Res
$LK,"PrsGlblVarLst ",A="FL:D:/Compiler/StmtParser.CPP.Z,1006",BI=235$00000114C6 0007 0000000962 Funct Export Res
$LK,"PrsIf ",A="FL:D:/Compiler/StmtParser.CPP.Z,1256",BI=236$0000011E2E 0001 000000012C Funct Export Res
$LK,"PrsKeyWord ",A="FL:D:/Compiler/StmtParser.CPP.Z,85",BI=237$000000F226 000C 0000000040 Funct Export Res
$LK,"PrsNoUnusedWarn ",A="FL:D:/Compiler/StmtParser.CPP.Z,1578",BI=238$0000012B7E 0001 000000008F Funct Export Res
$LK,"PrsOffsetOf ",A="FL:D:/Compiler/ExpParser.CPP.Z,379",BI=239$000000CE16 0002 0000000148 Funct Export Res
$LK,"PrsPop ",A="FL:D:/Compiler/ExpParser.CPP.Z,13",BI=240$000000C196 0017 0000000022 Funct Export Res
$LK,"PrsPop2 ",A="FL:D:/Compiler/ExpParser.CPP.Z,23",BI=241$000000C1F6 0001 000000002D Funct Export Res
$LK,"PrsPopDeref ",A="FL:D:/Compiler/ExpParser.CPP.Z,28",BI=242$000000C226 0004 000000003F Funct Export Res
$LK,"PrsPush ",A="FL:D:/Compiler/ExpParser.CPP.Z,8",BI=243$000000C16E 0017 0000000028 Funct Export Res
$LK,"PrsPush2 ",A="FL:D:/Compiler/ExpParser.CPP.Z,18",BI=244$000000C1BE 0004 0000000033 Funct Export Res
$LK,"PrsSizeOf ",A="FL:D:/Compiler/ExpParser.CPP.Z,331",BI=245$000000CC0E 0001 0000000207 Funct Export Res
$LK,"PrsStatement ",A="FL:D:/Compiler/StmtParser.CPP.Z,1689",BI=246$000001307E 0004 0000000C09 Funct Export Res
$LK,"PrsStaticInit ",A="FL:D:/Compiler/StmtParser.CPP.Z,314",BI=247$000000FB3E 0002 000000013E Funct Export Res
$LK,"PrsStreamBlk ",A="FL:D:/Compiler/StmtParser.CPP.Z,1592",BI=248$0000012C0E 0000 00000001B2 Funct Export Res
$LK,"PrsSwitch ",A="FL:D:/Compiler/StmtParser.CPP.Z,1379",BI=249$00000122EE 0002 000000088F Funct Export Res
$LK,"PrsTryBlk ",A="FL:D:/Compiler/StmtParser.CPP.Z,1628",BI=250$0000012DC6 0001 00000002B7 Funct Export Res
$LK,"PrsType ",A="FL:D:/Compiler/StmtParser.CPP.Z,417",BI=251$000000FEC6 0002 000000034B Funct Export Res
$LK,"PrsUnaryModifier ",A="FL:D:/Compiler/ExpParser.CPP.Z,981",BI=252$000000E71E 0000 0000000859 Funct Export Res
$LK,"PrsUnaryTerm ",A="FL:D:/Compiler/ExpParser.CPP.Z,618",BI=253$000000D78E 0000 0000000F8E Funct Export Res
$LK,"PrsVarInit ",A="FL:D:/Compiler/StmtParser.CPP.Z,106",BI=254$000000F2F6 0001 00000004C8 Funct Export Res
$LK,"PrsVarInit2 ",A="FL:D:/Compiler/StmtParser.CPP.Z,223",BI=255$000000F7BE 0004 00000002FE Funct Export Res
$LK,"PrsVarLst ",A="FL:D:/Compiler/StmtParser.CPP.Z,506",BI=256$0000010216 0006 0000000ADC Funct Export Res
$LK,"PrsWhile ",A="FL:D:/Compiler/StmtParser.CPP.Z,1284",BI=257$0000011F5E 0001 00000000EF Funct Export Res
$LK,"SLASH_OP_DEC ",A="FL:D:/Compiler/BackLib.CPP.Z,266"$0x052B0000 0006 0000000018 DefineStr
$LK,"SLASH_OP_DIV ",A="FL:D:/Compiler/BackLib.CPP.Z,271"$0x00000000 0001 0000000018 DefineStr
$LK,"SLASH_OP_FADD ",A="FL:D:/Compiler/BackLib.CPP.Z,275"$0x0000C1DE 0002 0000000018 DefineStr
$LK,"SLASH_OP_FDIV ",A="FL:D:/Compiler/BackLib.CPP.Z,279"$0x0000F9DE 0002 0000000018 DefineStr
$LK,"SLASH_OP_FDIVR ",A="FL:D:/Compiler/BackLib.CPP.Z,280"$0x0000F1DE 0003 0000000018 DefineStr
$LK,"SLASH_OP_FILD ",A="FL:D:/Compiler/BackLib.CPP.Z,284"$0x00000000 0002 0000000018 DefineStr
$LK,"SLASH_OP_FISTTP ",A="FL:D:/Compiler/BackLib.CPP.Z,283"$0x00000000 0002 0000000018 DefineStr
$LK,"SLASH_OP_FLD ",A="FL:D:/Compiler/BackLib.CPP.Z,281"$0x00000000 0008 0000000018 DefineStr
$LK,"SLASH_OP_FMUL ",A="FL:D:/Compiler/BackLib.CPP.Z,278"$0x0000C9DE 0002 0000000018 DefineStr
$LK,"SLASH_OP_FSTP ",A="FL:D:/Compiler/BackLib.CPP.Z,282"$0x00000000 000D 0000000018 DefineStr
$LK,"SLASH_OP_FSUB ",A="FL:D:/Compiler/BackLib.CPP.Z,276"$0x0000E9DE 0002 0000000018 DefineStr
$LK,"SLASH_OP_FSUBR ",A="FL:D:/Compiler/BackLib.CPP.Z,277"$0x0000E1DE 0003 0000000018 DefineStr
$LK,"SLASH_OP_IMUL ",A="FL:D:/Compiler/BackLib.CPP.Z,270"$0x00000000 0001 0000000018 DefineStr
$LK,"SLASH_OP_INC ",A="FL:D:/Compiler/BackLib.CPP.Z,265"$0x00030000 0004 0000000018 DefineStr
$LK,"SLASH_OP_MOV ",A="FL:D:/Compiler/BackLib.CPP.Z,272"$0x00000000 0002 0000000018 DefineStr
$LK,"SLASH_OP_MUL ",A="FL:D:/Compiler/BackLib.CPP.Z,269"$0x00000000 0001 0000000018 DefineStr
$LK,"SLASH_OP_NEG ",A="FL:D:/Compiler/BackLib.CPP.Z,268"$0x00000000 0001 0000000018 DefineStr
$LK,"SLASH_OP_NOT ",A="FL:D:/Compiler/BackLib.CPP.Z,267"$0x00000000 0001 0000000018 DefineStr
$LK,"SLASH_OP_POP ",A="FL:D:/Compiler/BackLib.CPP.Z,274"$0x00000000 0001 0000000018 DefineStr
$LK,"SLASH_OP_PUSH ",A="FL:D:/Compiler/BackLib.CPP.Z,273"$0x00000000 0001 0000000018 DefineStr
$LK,"StrMatchBits ",A="FL:D:/Compiler/Unassembler.CPP.Z,226",BI=258$0000000EA8 0002 0000000073 Funct Export Res
$LK,"StreamExePrint ",A="FL:D:/Compiler/CmpMain.CPP.Z,699",BI=259$000002C99A 0000 00000000EC Funct Export Res
$LK,"StreamPrint ",A="FL:D:/Compiler/CmpMain.CPP.Z,1",BI=260$000002AE82 0000 00000000A8 Funct Export Res
$LK,"U ",A="FL:D:/Compiler/Unassembler.CPP.Z,647",BI=261$00000025E0 0000 00000000CF Funct Export Res
$LK,"Ui ",A="FL:D:/Compiler/Unassembler.CPP.Z,239",BI=262$0000000F20 0002 00000016C0 Funct Export Res
$LK,"Un ",A="FL:D:/Compiler/Unassembler.CPP.Z,663",BI=263$00000026B0 0008 00000000DA Funct Export Res
$LK,"UnasmHashLoad ",A="FL:D:/Compiler/Unassembler.CPP.Z,188",BI=264$0000000D98 0001 0000000110 Funct Export Res
$LK,"UndefinedExtern ",A="FL:D:/Compiler/StmtParser.CPP.Z,94",BI=265$000000F266 0001 0000000048 Funct Export Res
$LK,"UnusedExternWarning ",A="FL:D:/Compiler/StmtParser.CPP.Z,100",BI=266$000000F2AE 0004 0000000043 Funct Export Res
$LK,"asm_hash ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,2"$00000004E0 000D 0000000008 GlbVar Export
$LK,"asm_seg_prefixes ",A="FL:D:/Compiler/Assembler.CPP.Z,782"$0000009520 0001 0000000006 GlbVar Export
$LK,"binary_ops_table ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,8"$0000000648 0002 0000000008 GlbVar Export
$LK,"cmp_arg_cnt ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,8"$0000000650 0009 0000000008 GlbVar Export
$LK,"cmp_do_not_write_to_dsk ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,3"$00000004E8 0003 0000000001 GlbVar Export
$LK,"cmp_result_cnt ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,9"$0000000658 0005 0000000008 GlbVar Export
$LK,"cmp_templates ",A="FL:D:/Compiler/CmpExts.CPP.Z,42"$0000000000 0002 0000000004 GlbVar Export
$LK,"cmp_templates_dont_pop ",A="FL:D:/Compiler/CmpExts.CPP.Z,43"$000000018B 0002 0000000004 GlbVar Export
$LK,"cmp_templates_dont_push ",A="FL:D:/Compiler/CmpExts.CPP.Z,44"$0000000257 0002 0000000004 GlbVar Export
$LK,"cmp_templates_dont_push2 ",A="FL:D:/Compiler/CmpExts.CPP.Z,46"$0000000421 0002 0000000004 GlbVar Export
$LK,"cmp_templates_dont_push_pop",A="FL:D:/Compiler/CmpExts.CPP.Z,45"$0000000391 0002 0000000004 GlbVar Export
$LK,"compiled_bytes ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,16"$00000006E8 0002 0000000008 GlbVar Export
$LK,"compiled_funs ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,15"$00000006E0 0002 0000000008 GlbVar Export
$LK,"compiled_lines ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,15"$00000006D8 0003 0000000008 GlbVar Export
$LK,"doc_type_flags_src_code ",A="FL:D:/Compiler/Lex.CPP.Z,353"$0000004A60 0001 0000000008 GlbVar Export
$LK,"dual_U16_tokens1 ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,6"$0000000630 0002 0000000008 GlbVar Export
$LK,"dual_U16_tokens2 ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,6"$0000000638 0002 0000000008 GlbVar Export
$LK,"dual_U16_tokens3 ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,7"$0000000640 0002 0000000008 GlbVar Export
$LK,"ic_bitmap_assign ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,9"$0000000668 0003 0000000008 GlbVar Export
$LK,"ic_bitmap_cmp ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,9"$0000000678 0004 0000000008 GlbVar Export
$LK,"ic_bitmap_deref ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,9"$0000000660 0004 0000000008 GlbVar Export
$LK,"ic_bitmap_fpop ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,10"$0000000680 0005 0000000008 GlbVar Export
$LK,"ic_bitmap_not_const ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,9"$0000000670 0003 0000000008 GlbVar Export
$LK,"internal_types_table ",A="FL:D:/Compiler/CmpInit.CPP.Z,8"$00000291A8 0001 00000000AA GlbVar Export
$LK,"lex_zeros ",A="FL:D:/Compiler/Lex.CPP.Z,130"$0000003F88 000A 0000000004 GlbVar Export
$LK,"non_ptr_vars_mask ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,12"$00000006B0 0006 0000000008 GlbVar Export
$LK,"num_non_ptr_vars ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,11"$0000000698 0005 0000000008 GlbVar Export
$LK,"num_reg_vars ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,10"$0000000690 0006 0000000008 GlbVar Export
$LK,"num_stk_temps ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,10"$0000000688 0004 0000000008 GlbVar Export
$LK,"opt_nop ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,5"$0000000550 000B 00000000E0 GlbVar Export
$LK,"reg_vars_mask ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,11"$00000006A8 0002 0000000008 GlbVar Export
$LK,"stk_temps_mask ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,11"$00000006A0 0003 0000000008 GlbVar Export
$LK,"sys_internal_types ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,4"$00000004F0 0067 0000000060 GlbVar Export
$LK,"to_non_ptr_vars_map ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,15"$00000006D0 0004 0000000008 GlbVar Export
$LK,"to_reg_vars_map ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,14"$00000006C8 0004 0000000008 GlbVar Export
$LK,"to_stk_temps_map_even ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,14"$00000006C0 0007 0000000008 GlbVar Export
$LK,"to_stk_temps_map_odd ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,13"$00000006B8 0007 0000000008 GlbVar Export
$LK,"uasm_ins64_mask ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,20"$0000000700 000D 0000000008 GlbVar Export
$LK,"uasm_mem_mask ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,21"$0000000710 0003 0000000008 GlbVar Export
$LK,"uasm_signed_arg_mask ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,20"$0000000708 0003 0000000008 GlbVar Export
$LK,"unasm_table ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,19"$00000006F0 0006 0000000008 GlbVar Export
$LK,"unasm_table_entries ",A="FL:D:/Compiler/CmpGlbls.CPP.Z,20"$00000006F8 0003 0000000008 GlbVar Export
ÈŒȂȂà‚ë‚ö‚ÿ‚ƒ
ƒƒƒƒ/ƒ3ƒ9ƒGƒdƒqƒ€ƒ…ƒ‘ƒ–ƒ�ƒ©ƒ®ƒ±ƒ»ƒ³ƒËƒÔƒãƒÛƒóƒüƒ„„„„'„0„9„@„D„I„T„a„o„‹„—„—„¯„À„À„Ç„ã„ï„÷„
……%….…5…9…D…I…P…m…š…¡…¥…§…²…¾…Â…×…Ù…ê…ô…ÿ… ††'†C†C†G†L†Ì†4DÍ’”’”¨”»”ÔÑ”ñ”ü”••$•7•H•N•c•�•�•–•›•£•«•±•ɕܕç•ë•õ•
––– –!–3–3–:–>–B–P–c–g–p–…–‰–‰–œ–¯–µ–¹––ß–ã–ã–ã–ã–è–ú– ——&—A—Q—a—f—f—f—r—z—‚—ˆ—�—¥—³—½—Ë—Ñ—Ó—Ó—Ó—Ó—Ó—Ó—Ó—Ó—Ó—ß—ç—ï—õ—
˜˜˜˜,˜2˜2˜2˜D˜J˜V˜\˜i˜„˜”˜ ˜¦˜³˜ŘÓ˜ò˜™Qš`¿Ó ~ ~®~°~»~Ã~Î~Ù~ä~æ~þ~þ~%(W� ?yyy#y*y.yRyeyly}yŽy™y°y»y½yÈyÙyäyûyzzzzz%z,z6zNz˜ü � �¸�¿�Æ�É�Ò�Õ�Ø�Ü�á�‚î�‚‚!‚$‚&‚6‚?‚H‚N‚Q‚b‚y‚Š‚•‚Ç‚ˆ<š0Œ0ŒJŒQŒ\Œ{Œ�ŒŸŒ±ŒÃŒÕŒâŒâŒçŒîŒ���6�E�T�c�r����Ÿ�Ÿ�µ�Ç�Ë�Ù�è�í�í�ô�
ŽŽŽ3ŽKŽKŽKŽaŽlŽ‚Ž�Ž¢Ž§Ž¿ŽÄŽÜŽðŽõŽ
��'�,�D�I�a�f�~�€�™�ª�ª�¬�Â�É�ß�ß�ú��*�B�X�X�t�ØDR’R’f’f’Œ’Œ’©’­’²’²’²’¾’ÒӒؒؒؒݒݒó’ú’␍““$“4“=“?“?“?“?“F“M“T“[“b“i“p“w“~“~“€“€“†“‹“�”´ÓüXX{ˆ�‘š§³¾ÉÑÜäçóû€;€5€K€T€‰€u€™€™€±€¼€Ø€ß€�<�<�<�<��� ¬\ƒX{X{n{u{|{Š{›{­{¯{¶{¼{Ì{×{á{ì{|||| |0|:|D|K|V|k|s|s|‰|‰|‰|�|
¬ƒª | |¶|½|Ä|Ò|ã|õ|÷|þ|}} })}4}K}N}P}b}i}y}ƒ}�}”}Ÿ}³}»}»}Ñ}Ñ}Ñ}æ} „?\PzPzizpzwz~z„z”zŸz©z´zËzÎzÐzëzõzÿz{{#{+{+{A{A{S{ dª¿è}è}~~~"~,~7~?~N~X~[~~�~‘~‘~Ÿ~␍àšx�x���¤�»�Ç�Ò�ä�ä�‘0‘<‘C‘I‘U‘_‘f‘m‘q‘s‘y‘…‘�‘–‘�‘¡‘¡‘«‘°‘»‘͑͑þ‘ ’+’2’8’D’N’U’\’`’b’h’t’~’…’Œ’�’�’�’«’»’Í’Í’þ’ “+“2“8“D“N“U“\“`“b“h“t“~“…“Œ“�“�“š“ª“¼“¼“í“ô“ú“””””"”$”*”6”@”G”N”R”R”\”s”Œ”˜”œ”œ”Ÿ”¨”•ˆ øwøw+x7x?xGxKxOxZx^xbxfxnxsxwxˆx™x›xŸx°xÁxÎxáxèxòxòxòxòxy$!&x(‚(Š(�(„À]ÀÀÀ3ÀCÀcÀuÀ�À¨À¨ÀÒÀÚÀÞÀäÀîÀôÀÁ
ÁÁÁÁ!Á&Á0Á3Á:Á@ÁGÁMÁQÁVÁ`ÁqÁxÁÁ�Á…ÁŽÁ˜Á›ÁŸÁ¤Á§ÁªÁµÁ»ÁÂÁËÁäÁõÁþÁÂÂÂÂ#Â-Â7Â>ÂEÂGÂNÂUÂZÂ^ÂkÂrÂ}ܥ٬ÂÁÂÒÂÛÂäÂìÂõÂûÂÿÂÃÃÃÃ*Ã4ÃIÃSÃ\ÃuÆÃ�ØàéïóøþÃÈÃÒÃîÃýÃÄÄ&Ä5ÄKÄnÄwĒĦĦÄÇÄÐÄÙÄâÄéÄòÄûÄÅ␍Å-Å1Å‹ÅT¯Àò¶ò¶··+·1·O·^·m·|·Š·•·˜·¨·(*0NÀNÀ\ÀtÀyÀyÀÀ<0;†À†ÀšÀ¨À®ÀÆÀÌÀæÀìÀòÀòÀúÀ½?b©b©p©€©�© ©°©À©Ó©æ©ó©ªª-ª?ªAªSªUªgªgªyªyª‹ª©ª®ª¾ªÔªܪæªþª««)«1«;«S«X«h«x«Ž«–« «¸«Ä«Ì«Ö«æ«ë«¬ ¬¬ ¬)¬3¬=¬G¬Q¬[¬e¬o¬y¬ƒ¬™¬£¬­¬·¬Á¬ˬÕ¬߬é¬ÿ¬ ­­)­3­=­G­Q­[­e­o­y­ƒ­�­—­¡­«­µ­¿­É­Ó­Ý­ç­ñ­û­®®®#®-®7®A®K®U®|®(:À"¼"¼@¼K¼\¼_¼c¼l¼s¼�¼�¼¦¼¦¼µ¼·¼·¼ƼȼȼؼÚ¼Ú¼ê¼ì¼ì¼ù¼û¼û¼½
½
½½½½*½*½8½<½@½E½I½V½]½k½½ˆ½޽œ½µ½·½»½ŽŽʽʽʽϽϽÞ½ç½ï½¾¾¾&¾1¾6¾6¾9¾>¾>¾Z¾f¾s¾u¾u¾y¾{¾{¾—¾£¾¯¾±¾±¾´¾¶¾¶¾þžžȾȾѾ×¾ܾø¾ø¾ø¾ø¾ø¾ø¾ø¾ø¾ú¾ú¾ ¿ ¿ ¿¿¿¿*¿,¿,¿;¿;¿?¿?¿G¿c¿g¿l¿ÿ¿øÀ:ª·ª·Ä·Ï·Ó·Ü·ã·ê·¸¸"¸4¸F¸U¸d¸u¸„¸„¸‹¸�¸˜¸¥¸¬¸µ¸¼¸À¸à¸à¸à¸ì¸ð¸ó¸û¸
¹¹ ¹'¹8¹C¹H¹H¹U¹[¹j¹�¹ƒ¹޹›¹ª¹­¹¯¹ǹÞ¹à¹î¹ð¹þ¹ºº º ºº%º;º;ºPº^ºiºnºnºqºvºvº’º º­º¯º¯º³ºµºµºѺߺëºíºíºðºòºòºÿº»»»»»»»␍»»»#»C»P»^»e»¼XÍߊʊʎʙʤʯʶʻÊÀÊ×ÊèÊöÊÿÊË Ë Ëø5¯j°j°r°�°…°’°Ÿ°³°°â°ï°±#±C±Q±m±±—±®±¹±Ú±ø±²"²-²H²a²a²|²¥²¿²Ú²ì²û²
³
³³(³9³L³\³i³t³ƒ³£³£³¯³¯³¯³À³ͳÔ³ó³ü³ ´␍´´ ´8´P´Y´i´q´v´‰´­´½´Í´Ø´ì´ñ´ù´ µ!µ,µ_µyµyµ‘µ µ¨µ·µÀµȵÚµùµ&¶>¶V¶n¶†¶˜¶¯¶¸¶Á¶Ó¶á¶å¶ì¶ÐͽRšRšVšeštštšƒšƒš’š’š¡š¡š°š°š¿šΚÝšñšìšìšûš
››››(›\©Ü9î´î´µµNµ_µ_µzµ€µ…µ…µ µ¦µ«µ«µ´µµεÕµÛµàµ#¶-¶4¶:¶<¶<¶O¶U¶U¶U¶Z¶v¶…¶—¶œ¶œ¶œ¶£¶ª¶±¶ƶͶé¶é¶û¶DS`´´´"´/´9´D´L´ %˜9˜9«9Ñ9å90:‘:”:ª:¼:Ã:Ê:Þ:å:ï:ø:; ;,;/;H;K;P;g;s;;ƒ;‘;˜;›;Ö;4 î¿î¿÷¿ü¿À ÀÀÀ< *ÀÀ À$À2À;ÀBÀDÀIÀ @9Eþ¶þ¶·"·&·*·/·1·M·i·i·s· &*�(š(¢(§(!<‰”ŠÇŠÇ£Ç²ÇÆÇÕÇÛÇáÇäÇÈ"<°»ÉÉ3ÉBÉVÉcÉiÉoÉrÉ“É#4€‰:Ç:ÇPÇcÇrÇxÇ{ǃÇ$4§°ÒÈÒÈèÈûÈÉÉÉÉ%œ]€’Å’ÅšÅžÅ³ÅÆÅÙÅöÅÆ Æ1ÆXÆoÆoƑƠƩƶƽÆïÆüÆÇÇÇÇ+Ç/Ç3Ç&\”§
È
È'È7ÈDÈNÈeȂȠȦȯȽÈÃÈÆÈÒÈ'$ð'ù'(((¬(°r°r¾rÉrØrßrçrïr÷rÿr
sss&s-s5s;s@sOsTsZsZsjsys~s„s‰s‘s“s¢s§sçsçsésþstt)ŒCbØtØtèt u uuuuu u u'uRuZuZueueusuƒuƒu‘u—u—u¯u¯uµuÛu*¤b‡àuàuðuùu vv%v1v=vIv`v`vovzvƒvŠv“v½vÂvÔvãvïvww-w-w/wBwDw^wjwmw„w+|(Ctt"t,t9tGtLtYtgtgt~t‡t—t™tœtžt±tºtºt½tÂtÇtÕt,T‡˜ˆwˆwšw�w¦w¯w½wÂwËwÎwÓwáwêw÷w-ð9VñVñ€ñƒñ†ñŒñ‘ñ¨ñ¿ñÖñèñò5ò8òQòhòzò‡òšò­ò²òºòÄòÌòÌòÓòÜòÜòçòó)ó/óHóaócó}óƒóœóµó½óÈóÈóÒóÒóäó"ô7ôIô.H„–ž–žµžÑžÖž÷žŸ$ŸBŸVŸnŸuŸzŸ›Ÿ¹ŸÈŸåŸöŸ␍       ) , 6 < Y \ \ \ a g ƒ ‘ � ¦ º  Ë ç ò þ ¡¡¡*¡/¡/¡=¡/8ú„V
V
ˆ
“
Æ
 
Ì
ú
ÿ
ÿ
 ␍  4 ; I K S m ˆ š § ¿ Ó Ø ß      / M _ l „ š  º º Å Ì Þ á ã é ␍␍ ␍7␍I␍L␍N␍T␍p␍p␍p␍‚␍‚␍�␍š␍»␍×␍×␍Ü␍à␍ü␍#@JN^qˆ‹�±»ÒÖìÿ+5IS\s}“�´¸¸¸ÃÊÝõ÷"9?QYz‘‘‘··É0x9ÓNôNô„ô‹ô“ôœô­ôºôÏôÒôÕôÙôâôðôúôÿô
õ'õ,õ9õeõjõwõ—õœõ«õ×õßõäõùõ%ö-ö2ö2öEöXöhölö‹öœö¡ö¡öÃöÃöÃöÃöÃöÓöèöëöîöòöòö÷ö÷ ÷$÷-÷:÷B÷]÷o÷|÷‡÷¥÷¥÷¥÷²÷É÷Ë÷Ë÷Ë÷Ø÷ï÷ñ÷ñ÷þ÷øø&ø+ø4øKø]øoø�ø�ø�øšø±ø³ø³ø³øÀø×øÙøÙøæøýøýøùùù'ùAùSùeùƒùƒùƒù�ù§ù©ù©ù¶ùÍùÍùâùäùëù␍ú+ú0ú7úEúOúQúQúQúmúuúwúwú™úÍú1„;öö
-LRYxz™¥µÔÚááéñü9A2ˆŸŽ9Ž9¬9¾9Ä9Ë9Ò9Ô9×9Þ9å9å9:: : :#:7:H:H:P:t:”:µ:º:Û:à:ì:÷:ü: ; ;C;T;Y;_;a;g;j;{;€;ƒ;‹;”;¯;Ï;æ;ù;þ;<$<7<<<S<f<k<o<‘<¬<Ì<ß<ä<õ<ú<ý<ÿ<= ==!='=/=/=9=B=Y=l=q=u=—=²=Ò=å=ê=>%><>O>T>X>z>�>�>¨>¨>¨>¶>Î>Ð>Ð>Ð>Þ>ö>ø>ø>???0?0?9?F?\?|?–?�?§?º?¾?¾?¾?Å?Ë?å?ì?ö?@@@0@7@A@O@Z@Z@r@3l¤»nXnX„X�X¦X³X½XÌXåXéXïXYY Y!Y!YRY@Y!YqY{Y4Ä]Ѝ*¨*±*Ø*Æ*¸*ù* +û**+M+M+]+b+b+v+{+{+—+œ+œ+¼+Á+Á+Õ+Ú+Ú+÷+÷+,),O,o,�,“,¥,µ,µ,µ,µ,µ,{-5ÔŸÐv@v@Š@©@•@Ï@Ü@è@î@(A-AYAYA^AtA†AœA²AåAôA,BBGBTB€B…B¬B´BÎBºBéBCîB"CC6CCCoCoCoCoCwC6¸AN-N-d-o-z-†-‘-“-¼-Â-Â-é-ö-!.L.F.:.d.†.ž.‹.±.ª.Ð.½.ä.ñ./5///#/A/T/T/T/^/7°ô\î î  4 < G V _ c n y Ž “ ­ Ì Ò × ê  !6!<!D!G!L!_!‰!Ÿ!¥!­!°!»!Ð!Õ!ò!"" " "$"*"-"8"C"X"]"w"–"œ"¡"¬"Á"Ê"Ï"î"ö"û"##$#&#E#M#X#m#r#Œ#«#±#¶#¶#¶#¶#Ã#Ê#ß#ß#÷#$$"$:$N$_$i$k$$�$•$ $Í$Í$Í$ß$8ÔÐ�~C~CœC¬C·CÂCD.DLDvD|D‚DŠDŒD”D¯D²D½DÉDE5ESE}EƒE‰E‘E–EžE¹E¼EÇEÓEØEFDFbFŒF’F˜F F¢FªFÅFÈFÓFßF$GKGiG“G™GŸG§G¬G´GÏGÒGÝGéGéGîGôGúGH
HH'H6HeH�H•HšH¬H»HíHII%I*I<IKIzI¤IªI¯IÁIÐIÿI)J/J4J4J4JEJPJ[J�J™J¤J¬J¹J¹J¾JÑJèJíJK+K6K>KKKKKPKcKpKzKŽK¥K¾KÐKÝKLL3LALCLWLnLnLwLƒL™L²LÅLÑLäLèLèLèLïLôLMM*M,M1MDMPM]MgMgMyM9l¨¿ΩΩÒ©å©å©ÿ©ªªª)ª)ª@ª@ªWªWªnªnª…ª‡ª‡ª‹ª:tD]Ð)Ð)Þ)è)ï)** *␍**#*4*Q*S*c*c*h*j*q*£*;ð|ô(2etŠ®³·¿È×Þçì19;Zbqx„‰�˜ž ¬¼ÁÃãééñú (/1PWWWkƒ‘¤œ¼ÁÌÓÛáãïÿ&,,8HMRrx}‰™ž ÀÆÍÕÛÝéùþ  & & & . 7 7 A A Y ‰ � ¡ ¯  º Ú Ú ì <àAõ^/^/|/„/’/–/¼/Ç/Ï/×/ë/ó/ó/÷/)0b0P0G0z00Š0•0—0¶0¼0Å0Ì0Ô0Ü0è0ð0ø0 111"1B1J1L1V1e1…1�1�1¯1·1·1·1Â1Ë1ß1ç1ð1ð1õ1ù122 2202L2h2‡2Š2Ÿ2¬2À2Ó2×2ä2
3&393X3^3`33‚3‚3—3¤3¸3Ë3Ö3Ú3å3ð3û344'4*454@4E4d4j4o4z4…4‡4¦4©4´4¿4Á4à4æ4æ4æ4ð4ð4û4,575757575@5L5b5{5Ž5•5¡5¨5¨5»5¿5¿5¿5Æ5Ë5Þ5å5ñ5ø5ø5666)606<6C6C6P6Z6Z6ƒ6ƒ6•6=ÈEsv·v·¢·¥·ª···¼·ηзÔ·Ø·Û·î·¸)¸2¸=¸D¸]¸¸„¸�¸¿¸ĸ˸丹¹!¹C¹C¹C¹X¹r¹�¹“¹>T•¦.´.´B´O´^´^´j´p´š´°´œ´Ç´¼´ß´ç´?¼ìV+V+n+r+€+�+š+¦+±+³+Ü+â+â+,3,, ,U,Z,�,†,’,�,Ÿ,È,Î,Î,á,ú,ô,è,---;-;-G-@\ž±††”›ºÙÛú'/:<GRqwAè±ç~~“ž¥Òñó?MU`bmxx}ª¯Üáè&13RqqŒš¢­¯ºÅÅå   3 T T T \ B¨z ëë4ëEëQëhëoëˆë€ë ëÀë¬ëÌëÝëâëìïëì,ìCìJìcì[ì{ì›ì‡ì§ì¸ìÎìºìæìóìóì í ííC°%MîÊîÊ ËË%Ë,Ë;Ë@Ë_Ë_Ëd˃ˈË�˞ˠ˿˿ËÞËóËàËÿËÌÌ/Ì/Ì/Ì/Ì>ÌWÌPÌoÌyÌDlE\NßNßlß߆ß�ߔߘߚߡߨ߬߬ߴßÍß×ß×ßëßößàààà)à:àKàbàfàoàsàxà‰à¦à¦à´àÈàÍàæà÷àûàûàûàá.áCáJá]áaáfáqá‚á“áªá²á»á¿áÄáÕáçá÷á â␍â&â9â=â=â=âHâYâjâ�â…âŽâ’â—â¨âÅâÅâÓâçâìâããã,ã,ã,ã1ã@ãBãaãaã€ã‹ã‘ã§ã¸ã½ãÒãÝãîãÿãää#ä'ä,ä=äVäVädäxäzä“ä¤ä¨ä¨ä¯äÂäÆäØäÝäèäùä
å!å)å2å6å;åLåbårå†å‹å¤å·å»åÍåÍåÍåÍåååÒåñåææ!æ,æ2æHæYæYæYæ`æsæŒæŒæŒæ›æ›æ®æÅæÐæáæææìæöæøæçç çç+ç-ç8çMçYç[çfçrç‚ç‰ç�çšç¢ç¦çªç¬ç±ç¹ç½çÏçÑçÖçÞçâçäçäçíçúçè0èJèVèbèièiè|è€è€è€è‡èŒè¦è²è¾èÅèÅèÜèÞèãèýè éééé)é3é3éEéEÐs£–¹–¹À¹ùʹйÖ¹عÞ¹ä¹ä¹ö¹ººº"º5ºDºXº^º`ºgºmºwºwºˆºŠº‘º—º¡º¡º¡º¸ºʺѺàºâºôº»»»F|£¾»»@»C»J»P»V»X»^»d»k»x»…»˜»¥»´»º»¼»»Ì»Û»í»ü»¼,¼G@nzfêfê€êŒêžê´êÕêÂêíêëëëHˆñ¾¾&¾8¾?¾F¾e¾j¾‰¾޾¨¾•¾Ǿ´¾Ó¾è¾Õ¾¿ô¾¿¿%¿,¿K¿K¿S¿IM�~Ì~̨̖̳ÌÛ̺ÌçÌÍ2ÍÍ>ÍXÍXÍwÍŒÍy͹͘ÍÅÍßÍßÍñÍ Î Î8ÎEÎ~΃ΊθΩÎÄÎâÎîÎ Ï␍Ï;Ï,ÏGÏeÏzÏgφϴϥÏÀÏÚÏÚÏìÏÐ!Ð.ÐMÐMÐUÐJX\nFéFé`élé~é”éµé¢éÍéÞéðéê'êê?êWêWêaêK,^%NÂNÂt‡Â�–Â�£¥¬³¶¶ÂÈÂÈÂÛÂæÂñÂÃÃ*Ã2Ã;ÃCÃHÃYÃoÃÑÖðÃÈÃÌÃÌÃÑÃýÃÄÄ.Ä?ÄVÄ^ÄgÄoÄtąėħĹĻÄÕÄíÄñÄñÄüÄ␍ÅÅ5Å=ÅFÅNÅSÅdÅzŊŜšŻÅÓÅ×ÅêÅêÅêÅÆïÅ"ÆÆ/Æ;ÆAÆYÆqÆvƋƖƧƸÆÏÆׯàÆèÆíÆþÆÇ Ç2Ç4ÇNÇfÇjÇjÇudžǗǮǶǿÇÇÇÌÇÝÇóÇÈÈÈ4ÈLÈPÈcÈcÈcÈ{ÈhțȈȨȴȺÈÒÈêÈêÈêÈöÈüÈÉÉ$É4ÉKÉbÉyÉ�É�ɤÉÀÉÀÉÀÉáÉáÉïÉñÉñÉÿÉÿÉÊÊ!Ê<ÊKÊRÊbÊdÊ�ʉʦʷÊÒÊÒÊëÊL EVÐVÐtÐ{ЂÐ�ЕЮЮÐÂÐÛÐÛÐæÐêÐõÐÑüÐ)Ñ?ÑMÑcÑgÑlÑ~Ñ�ѦѽÑÂÑÊÑÎÑÓÑúÑÒÒÒ$ÒaÒ@ÒmÒŠÒŠÒ©Ò´ÒºÒÐÒáÒæÒøÒ Ó Ó7Ó<ÓDÓHÓJÓqÓ‡Ó‹Ó–Ó§Ó¸ÓÏÓ×ÓÜÓàÓåÓöÓ ÔÔ.Ô3ÔLÔ]ÔaÔsÔsÔsÔsÔxÔ§Ô”ÔÔÔ³ÔàÔýÔÕÕ$Õ5Õ:ÕEÕVÕgÕ~Õ†Õ‹Õ�Õ”Õ¥Õ·ÕÅÕÙÕÛÕôÕÖ Ö Ö ÖÖ,ÖCÖZÖ_ÖgÖkÖmÖ”ÖªÖ®Ö»Ö»Ö»Ö»ÖÎÖÔÖÞÖåÖøÖ××+×+×9×;×;×I×I×_×o×}הק׬×È×Ð×ì×üרØ/Ø'ØTØ}Ø}Ø}ØŠØÃØÈØÓØÙØäØÙÙ
Ù&Ù<ÙJÙbÙxÙ|ٌ٫Ù×ÙÇÙãÙÚÚ Ú*Ú0ÚFÚWÚ\ÚrڈڌڗڨڹÚÐÚØÚÝÚáÚæÚ÷Ú␍ÛÛ/Û4ÛMÛ^ÛbÛtÛtÛtÛtÛyÛ¨Û•Û´ÛãÛÓÛïÛ ÜÜÜ3ÜDÜIÜTÜeÜvÜ�Ü•ÜšÜžÜ£Ü´ÜÆÜÔÜèÜêÜÝÝÝÝ7ÝMÝcÝgÝtÝtÝt݇Ý�ݗݞݱÝÈÝÈÝÈÝäÝäÝòÝôÝôÝÞÞÞ(Þ6ÞQÞdÞiÞ…Þ�Þ©Þ¹ÞÇÞäÞßß␍ß-ß-ß-ßMßM€ÍéNïNïhï�ïsïœï©ï¼ïÕïÎïíïðòïðð$ð1ðDð]ðVðiðiðvð•ð•ðŸðNL^V¿V¿z¿’¿­¿™¿Í¿¹¿Ù¿ï¿Û¿Àû¿À'À,À8ÀHÀOÀ\ÀgÀsÀ~À†À‹À—ÀœÀ°À·À»ÀÆÀËÀÖÀïÀøÀÁ ÁÁ$Á(Á(Á-ÁFÁKÁdÁyÁ‹Á�Á›Á£Á£Á£Á¥Á¾ÁÓÁÞÁèÁóÁõÁÂÂÂÂ␍Â-ÂMÂOh·Í>î>îXî|î_îˆî¡îšî¹îÎî»îáîÚîíîïÿîïï ï>ï>ïHïPl ·íí4í@íWíhíoíˆí€í íÀí¬íÌíÝíóíßí îîî0î0î:îQLéø¦ð¦ðÄðÖðÝðüðüðñ!ñ.ñ'ñFñPñRܾñ.¼.¼P¼W¼b¼x¼x¼м•¼ ¼±¼¼Ù¼ݼâ¼æ¼è¼ù¼ ½½)½+½D½S½W½W½W½j½½½‹½‘½›½¦½´½»½ʽ̽â½ü½ü½¾S�%E†8†8¤8¬8¸8Î8ã8ñ8ü8 999999)949J9L9Q9_9j9w9~9Œ9T8>HVžVž_žkžŠž�ž‘ž‘ž–žU˜s•~²~²°²Ó²Ó²æ²ê² ³³"³"³/³7³?³T³`³q³v³‡³›³ ³¢³»³Ó³Õ³Õ³î³´´(´V<�˜ŽbŽb—b¢b­b¸bÃbÍbëböbcW0ñ9FQFQbQhQsQ„Q‰Q�Q’Q–Q–Q¶Q»QñQÝQýQRR"R;R'RGRNRSR]R`RdRiR‚RnRŽRŽRŽR“R¤R©R¯R²R¶R¶RÖRÛRSýRS6S"SBSXSDSdSkSpSvSyS}SS˜S„S¤S¤S¤S¤S¼SåSñSX\çú^ ^ l s ’ ± ³ Ò ñ ÿ 



*
I
O
Y¸@jFTFT^TiTŒT¤T©T®T²T´TºTÀTÖTÃTâTâTUUU%UHU`UeUjUnUpUvU|U’UUžUžU±U¹UËUåUÞUñUýUZ|�ê>¡>¡V¡^¡k¡‹¡�¡¤¡®¡´¡º¡¾¡¡ä¡ä¡ë¡î¡ó¡¢¢¢3¢7¢<¢<¢C¢F¢K¢W¢e¢i¢z¢‰¢�¢�¢ž¢¢¢¢¢´¢Ä¢È¢Í¢Í¢á¢ä¢ð¢ú¢£'£2£6£;£q£ˆ£“£—£¨£³£·£¹£Ä£È£È£È£Ö£â£æ£è£è£ó£÷£¤¤¤¤¤¤<¤[àê>¤>¤R¤h¤h¤h¤j¤j¤q¤s¤s¤z¤|¤|¤‰¤‹¤‹¤˜¤Ÿ¤¡¤¡¤®¤µ¤·¤·¤ϤÔ¤Ô¤Ô¤ä¤\à¿sŽªŽªĪͪÛªýªýª««9«A«n«s«œ«¹«Õ«Û«ß«¬(¬-¬V¬p¬–¬­¬³¬·¬Ьجݬî¬ö¬­­ ­8­@­_­d­u­}­œ­¡­©­¯­³­·­É­Ñ­Ý­ñ­ö­®␍®®#®6®C®W®b®k®�®îì®ñ®ñ®ñ®¯¯¯#¯E¯E¯\¯a¯a¯x¯z¯z¯ޝ�¯�¯§¯©¯©¯À¯¯¯Ù¯Ù¯ê¯ï¯ï¯ÿ¯$°6°;°;°;°;°B°v°‡°¥°¥°¥°²°ɰ˰˰˰ذï°ñ°ñ°þ°±±*±,±E±c±c±c±g±i±i±i±n±p±p±u±u±±„±„±¢±¢±¢±ª±¬±¬±¬±´±¶±¶±¾±¾±À±DZã±å±ø± ² ² ² ² ² ²7²?²?²z²]ô!ZÆþÆþäþçþùþÿÿ ÿÿÿÿ ÿ2ÿdÿkÿ–ÿ›ÿ¼ÿ¼ÿÈÿÐÿßÿKSXalt{š ¿Áàë!'..47;Ll~^ Zž~~–�¯âíù((4<K…‡´¼¼éî␍(.=RT_g‚‡�›£®µâ"O^W„‰�¯ÎÐï)1LLLxx„_`
öö2N[r…�’±¹Ä×Ðïõ`, &n�n�}���¨�¨�®�al»Ò~Y~Y”Y Y¶YÃYÇYÖYõYùYÿYZZ/Z1Z1ZbZPZ1Z�Z‹Zb�;[FF\biu…¥ª±ÑÓóÿ/4;;;ADHPhs~ž¨c|mˆÖ§Ö§ö§¨¨"¨'¨'¨F¨S¨U¨U¨U¨U¨b¨j¨}¨‘¨“¨“¨›¨®¨®¨À¨dDˆ•ƨƨÔ¨ߨ権©©©©©e°ÄìV)V)n)y)„)²)‘)Ê)Ñ)*ä)Ø)**/*Z*_*k*’*—*™*¸*¾*Ú*Ë*ò*ù*+ ++.+0+I+I+I+U+f¤ŸÄv'v'Ž'™'¤'Þ'¾'²'((1(1(>(w(|(ˆ(“(•(´(º(Á(â(Ô(È(ö(ø()))E)E)E)Q)gŒ\{æ$æ$ú$ý$%%"%1%1%E%R%]%b%‚%‘%™%¤%¬%·%Â%Í%Ø%ã%î%î%&&&h¨:`.¦.¦N¦p¦p¦�¦Ÿ¦¤¦¤¦³¦Ŧߦç¦î¦ð¦§ § § §␍§␍§␍§␍§+§+§+§+§=§?§?§?§?§R§]§|§iD`m~§~§Œ§”§›§º§ǧǧʧ̧Ò§jŠÊ€-€-�-•-¾-­-©-Î-Û-å-õ-õ- ..*.1.:.Q.Q.g.g.}.}.“.“.©.©.¿.¿.Õ.Õ.ë.ë.////////F/F/]/]/t/t/‹/‹/¢/¢/º/Â/Í/Þ/é/ú/ý/ÿ/00021kH��~M~M’MžM´M MÀMÂMÔMæMîMl´�¸îMîMN NN!N6N#NBNHNHNTNlNYNxN{N}N‹N�N¥N’N±N´N´NÀNÕNÂNáNçNçNúN␍O O3OFOPOm´¸áVOVOlOsO„O‰OžO‹OªO°O°O¼OÔOÁOàOãOåOóOøO␍PúOPPP(P=P*PIPOPOPbPuPˆP›P®P¸PnPáñ¾P¾PÒPÞPôPàPQQQ(Q3Q>QFQo( >�>�M�e�e�k�p”„¥ÎÎü+/88=J`Š�³»ÀÇÝóõ !E_qq¥èvv¨¼ÄÏÖÝæèë
,.5PW`be„„„’œ©ÉËåíí (-4JQlnu�¦½ÀÈÕõ÷5LLr„r€:æ¤æ¤
¥¥)¥>¥\¥g¥…¥…¥…¥’¥ª¥¬¥¬¥¬¥¹¥Ñ¥Ó¥Ó¥á¥î¥¦¦¦)¦s,9@öSöST
T)T8T@TtHÓ!ÎúÎúöúûûûû,ûCûZûšû¶ûÐûÕûÚûåûüûüü.üDüXü]ühüˆü�ü�üªüÄüÌüÔüÙüóü␍ýýý"ý<ýDýIýiýnýqý‹ý¥ý­ýµý·ýÑýëýóýûýýýþ þ þ$þ)þ4þ4þ?þ?þKþKþ]þ�þ³þ³þÃþuøj¤þUþUV V+V0V<VGVLVSVXVcVhVhV‡V¦V¨V­V¸V½V½VÜVûV"W"W5WHW[WnWsWsW†W™W¬W¿WÄWÄW×WêWýWXXX%X8XKX^X^X^XlXv é�–[–[´[Ø[Þ[å[å[ì[ \\'\?\+\K\Z\l\u\}\…\Ÿ\±\º\Â\Ê\ã\Ï\ï\] ]]]3] ]S]?]_]u]a]•]�]¡]³]½]Å]Å]Î]Ö]ì]^^&^*^*^1^6^T^V^[^f^|^|^|^€^Œ^­^»^É^Ö^÷^____._=_L_O_s_w_�_¡_È_Ì_ï_ó_ó_ó_ù_``*`0`;`G`I`Q`W`p`{`‰`“`¬`¯`·`Ã`Å`Í`Ð`é`ë`÷`ù`aa a8aDaYa^apaa˜a©a©a´a¿a×aãaøaýabb7bHbHbNbYbabobvbˆbw8ž¨~©~©’©—©�©¡©¥©Ä©Ì©xÐõ%–6–6¸6Î6Ú6ø67!787K7V7X7x7€7€7�7�7—7£7¹7Î7Ý7è7û78888 88%8<8>8C8R8]8j8t8t8‚8yL�Ÿþ&þ&'')'?'+'K'M'T'_'k's'z$‹�¾&¾&Ò&ó&û&{$†‹~&~&’&³&»&|<{†&&/&&;&F&Q&\&g&s&y&}(&,®�®�½�Ì�Ñ�×�~(,2Þ�Þ�ë�ù�þ�ž(28žžž!ž&ž,ž€(8>.ž.ž<žKžPžVž�$��%�8�>�‚4
††­š¹ÏÈçïƒlÒéŽZŽZ¤Z°ZÆZÓZ×ZæZÿZ[ [([[9[;[;[l[Z[;[‹[•[„”[|®®ÂÉÛú&(GYx~……�• «³»ÆÑÜû…4•ž©©,©2©6©U©v©v©|©†`*>¨(¨(¶(À(Í(â(ä(ë(ö(û()()*)C)F)H)H)™)‡(>D ) )©)³)Í)Ð)ˆ0I6FPPZZdvƒ†ˆ‘žž¸¿¿Ùàöö"888HHZZhvŒŒÅþ  " 0 C C v © ¯ ¯ ¯ Á ‰ÜI¼È È â å ô ô 





"
+
6
<
K
^
c
x
ƒ
�
�
Á
Ì
õ
' - 2 = [ b g { µ º À Æ Í Ò Ò Ø Þ ã ã û ! ' , J Q Q Q V Y _ e l q q w } ‚ ‚ ˜ ² À Õ Û ë ÷ ý ␍␍␍.␍5␍5␍5␍5␍5␍5␍;␍@␍D␍F␍I␍T␍`␍c␍e␍i␍i␍n␍n␍␍‘␍Š$‚‡ðð$ð9ð?ð‹`Üð°1°1Ð1ß1è1ñ1õ1ù122 2 22!2(2@2C2O2ŒTØ2Ø2æ2ó2333,393G3Y3d3r3x3~3�x»77-797C7I7S7Y7c7q7{7�7—7�7§7­7·7¾7Ê7Ð7Ù78888"87878:8D8Y8^8n8y8~8’8¥8¯8Ä8Ë8Ù8â8ê8ø8 99*97979D9D9L9“9޼?jø4ø4555"5/525L5L5L5R5V5^5i5}5‰5‹5‹5”5–5–5Ÿ5¡5¡5ª5¬5¬5µ5µ5¾5Ä5Ç5Ñ5â5è5ô5ô5\6�h)?0404@4G4S4Y4a4o4‚4Ž4¥4²4²4µ4Ã4Ó4ê4î4ö4�@)Ø3Ø3ì3ó3ÿ3 44 4#4'4/4‘Hjx`6`6u6|6�6�6¤6ª6¶6Ç6Ç6Î67’0ÔÜp1p1~1ˆ1“1ž1¤1ª1“4€3€3”3 3®3²3Ê3Í3Õ3”$þ¸2¸2Á2Í2Ò2•,÷þˆ2ˆ2–2�2­2°2¶2–,ð÷P2P2^2j2z2�2‡2—8ÊÔ8181F1M1W1d1g1i1o1˜h æühVhV…V”V”V”V®V®V½V½VÃVÅVÅVËVÍVÍVÓVÕVÕVÜVàVåVåVåVåVåVåVíVWW WWW$W1WFWHWcWeW€W…W W¥W«W«WÀWÃWêW÷W XX/X/X8X=X[XIXaXpXuX|X…X˜X X¨X­X­X­X¶XÏXÕXÕXîXüXY,Y.Y6Y<YDYIYIYOYOYXYiYkY€Y‚YŠY�Y˜Y�Y�Y£Y£Y¬Y»YÏYÑYÙYßYçYìYìYìYìYúYZZ$Z$Z,Z2Z:Z?ZHZPZYZ_ZeZgZgZgZoZoZ}Z‘Z•Z—Z£Z¥ZÀZÆZÎZÓZÜZçZêZðZöZÿZ[[[[ [C[`[f[n[s[|[~[~[ƒ[…[�[�[¨[º[¿[Ë[Ñ[Ô[ë[í[ð[\\ \\#\1\7\?\D\L\Q\Q\Z\g\l\t\‹\•\½\½\Ã\È\È\Î\Ó\Ó\Ù\Þ\Þ\ä\é\é\ï\ô\ô\ú\ÿ\ÿ\]
]
]
]]]+]9]S]i]i]k]k]t]z]]]]‡]‡]�]Ÿ]²]´]´]½]Ã]È]È]È]Ð]Ò]Ò]Û]Û]Û]ä]ó]^ ^ ^^^^^ ^&^&^.^7^=^I^I^P^d^f^i^n^v^~^ƒ^ƒ^‰^�^’^¡^¦^°^º^º^Ç^î^î^ô^__ _&_4_C_[_a_f_f_k_~_Š_’_¢_ª_³_Á_È_Ê_Ó_Ó_Ù_ç_ó_``-`3`5`H`M`M`j`j`|`‚`‹`‘`š`¨`­`­`À`Æ`È`Ó`å`ø`ø` aa*a/a;aAaDa[a]a`apaza}a}aŒaŸa±a¶aÂaÈaËaâaäaça÷aûabbbbb!b)b.b.b4b4bBbHbNbXbbb…bˆbŠb”b”b–bžb£b¨b­b­b³b»bÀbÀbÅbÐbÕbÚbåbêbcccc!c&c+c0c5c5c:c?c[c�c“c›c›c©c¯cµc¿cÉcìcïcñcûc
dddddd%d%d*d*d0d8d=d=dBdMdRdWd\dkdkd|d‚d‚d�d–dœd¦d°dÓdÖdØdâdñdödödödþde eeee e$e$e)e4e9e>eCeReReceieiewe}eƒe�e—eºe½e¿eÉeØeÝeÝeÝeåeêeóeøeøeþef f ffff,f2f8fBfLfofrftf~f�f’f’f’fšfŸf¨f­f­f³f»fÀfÀfÍfÓfÓfáfçfíf÷fg$g'g)g3gBgGgGgGgOgTg]gbgbglgtgygygygg‰g�g£g¨g¨g®g¸g¾gÃgÃgÉg×gàgègðgõgõgûg hh&h3h:hBhJhXhXh]h]hhhhhhhlhqhqhwh{h€hˆhŽh�h™h¨h°hµh»h»hÃhÉh×hâhçhíhõhúhúhúhúhúhúhúhúhúhúhii"i(i0i5i:iCiNiWi_idididijiriwiwi{i€i€i‰i—i£i°i¶i¶i¿iÓiÓiÙiâiöiöiÿijjj$j$j-j-j-j2j7j7j?jDjDjajoj{j„jŠj”jœj¡j¡j¡jµj¾jÄjÖjàjàjèjèjðjòjòj kkk k k k&k*k,k,k,k,k1k7k=kAkÎn™Äz§ðJðJK'K,K3KBKBKJK]KaKfK{K}K€K„K‹KŸK£K¯K¶KºKÁKÉKËKÓKàKîKöKøKûK LL#L+L3LALELSLš<„�Œ?Œ?š?¡?¬?´?»?Á?Ç?Ç?Í?›hCY== ='=3=:=F=N=W=[=i=r=€=Œ=•=ž=§=­=µ=œTizhJhJ~JŠJ’J–J©J·J½JÉJÑJÜJâJåJïJ�H��Ô?Ô?î?õ?þ?
@ @'@-@3@5@5@D@žPO_èqèqöqrrr'r,rIrOrVr]rkrwr©rŸ<‡’FðFðVðgðpðvðzð…ð Xp‚~ï~ï”ï¢ï¨ï®ï¿ïÍïÛïíïñï÷ïððð¡tüÐnÐnînònönþno ooo!o%o-o6oBoWohooovovo€oƒo•o¢¸�GD@D@Z@f@f@|@ƒ@…@¡@¡@¡@¨@²@¶@º@½@½@Æ@Ê@à@à@A"A3ACAYA^AaAfAfAfA~A…A’A™A¬A´A¼AÁAÁAÙAåAíAòAòA
BB B$B$B<BHBQBYBaBmBƒBŽB±BµBÃBËBÐBÐBèBC CC C%C%CDCPCaCfC~CŠC™CžC­CºC¿C¿C¿CÂCÇCÇCÇCæCòCDDD␍D␍D␍DD)D0D?DHDPDWDcDlDtD|DƒD‡D’D�D£D±D¿D¿DÅDÍDæDëDëDþDEEEEE␍E␍EEEE%E)E<EDEDEDEDEDESESExE�E�E…E“I£˜„æ8S8S\S_ScSpSyS„S�S˜S¢SÊSÊSÖSØSØSäSéSéSõSúSúST T TTTT(T-T-T9T>T>T>T@T@TYTgT{T‹T‹T�T�T™TŸT¤T¤T¤T¦T¦T¯T¾TËTÍTÍTÙTßTäTäTäTæTèTèTïTïTïTøTUUUU#U)U.U.U4U@U@UKUWUdUyU�U‡U‡U˜U˜U¡U¤UbV¤XN`ÄIÄIåIìIûIþIJ
JJJJ,JBJIJUJ¥ˆ%CØ;Ø;ô;<␍<<!<0<F<l<‚<“<š<¨<º<Ð<Ð<â<÷<ÿ<==¦@³¿àLàLðL÷LM!M/M:MBMLMTM§@§³XLXLhLoLŽL£L©L¶LÀLÙL¨€1˜o˜o®o·oÂoÛoÛoÞoíoóoüoþop␍ppp p&p)p)p3p©H1?8p8pApGpbpgp’p”p±p×pÞpïpqªdm‚X>X>a>h>|>�>•>³>¸>Ö>Ø>ö>ø>?#?,?.?B?R?ƒ?«`Ym¸=¸=Ê=Ñ=Ó=ß=æ=õ=> >>>0><>F>I>S>¬,GN”I”I¢I«I¹I¿I­œ5*¯*¯L¯V¯b¯g¯w¯}¯’¯¦¯´¯¯Ù¯á¯ë¯ú¯°°°°°°°+°5°@°I°Q°T°f°®P?Oqqq'q3qNqSqsquq�q«q«q³qºqáq¯Ðø(�N�N°N´NõNO O#OBOPOPOUOYO`OkOvOƒOŒOŒO‘O–O�O¨OµO·OÄOÆOÈOÈOÈOÐOÐOÐOØOàOèOðOôOþOJP°`ÕéàMàMöMöMúMÿMNNNN$N*N*N;N=NGN±LéøHNHN\N`NeNpNpNzN€N€N„NŒN²€MiHQHQ\QkQoQxQ†Q•Q¤Q¿Q¿QRR RRR&R5RJRMRRR[RgR³¤(MPPPPdPhPqPtP}P†P˜P˜PÁPÅPÊPÍPÖPæPíPðPøPûPQQQ Q'Q7Q7QCQ´,NUöñöñòòòò òµ|i„hRhRzR|R€R‰R•R¡R¶R¶RâRæRëR÷R
SSS"S%S-S7S<¿ÊXMXMlMpMuMMŠM�M‘M™M·<ÊÕ M M´M¸M½MÇMÑMÔMØMàM¸$ (*(2(7(¹,!8(F(W(h(k(q(º`jþF»F»`»i»‰»‰»�»—»Ÿ»§»¯»µ»Â»Â»È»Í»Í»Ó»Ø»Ø»Þ»ã»ã»é»î»î»ô»ù»ù»ÿ»¼¼
¼¼¼¼¼¼ ¼%¼%¼=¼P¼V¼[¼[¼d¼ˆ¼ˆ¼ˆ¼�¼‘¼‘¼˜¼š¼š¼¡¼£¼£¼ª¼¬¼¬¼³¼µ¼µ¼¼¼Â¼Ä¼Ä¼Ë¼Ñ¼Ó¼Ó¼Ú¼à¼à¼è¼î¼ô¼ü¼ü¼ü¼ü¼½½½ ½(½0½8½>½V½e½o½r½r½|½‚½ˆ½ˆ½Œ½”½›½£½«½¯½µ½½½Ä½Ì½Ô½Ø½Þ½é½ï½ü½¾¾¾¾!¾)¾1¾5¾;¾C¾J¾R¾Z¾^¾d¾o¾t¾Š¾›¾ ¾£¾I¿»dÕj>·>·X·a·�·�·‡·�·—·Ÿ·§·­·º·º·À·Å·Å·Ë·Ð·Ð·Ö·Û·Û·á·æ·æ·ì·ñ·ñ·÷·ü·ü·¸¸¸␍¸¸¸¸¸¸5¸H¸N¸S¸S¸\¸€¸€¸€¸‡¸‰¸‰¸�¸’¸’¸™¸›¸›¸¢¸¤¸¤¸«¸­¸­¸´¸º¸¼¸¼¸Ã¸É¸Ë¸Ë¸Ò¸Ø¸Ø¸à¸æ¸ì¸ô¸ô¸ô¸ô¸¹¹¹¹ ¹(¹0¹6¹N¹]¹g¹j¹j¹t¹z¹€¹€¹„¹Œ¹“¹—¹Ÿ¹§¹­¹µ¹¼¹Ä¹Ì¹Ð¹Ö¹á¹ç¹ô¹ººººº!º)º-º3º;ºBºJºRºVº\ºgºlº‚º“º˜º›ºA»¼0 f²f²t²~²†²‹²‘²½$�'Ÿ'¸'¾'¾pþN¿N¿b¿x¿…¿�¿”¿›¿¢¿«¿º¿¼¿¼¿Ð¿Ò¿Û¿á¿á¿á¿á¿é¿¿`¢N´N´l´p´}´´Œ´Ž´š´š´§´©´¶´¸´Ä´Ä´Ú´ã´ã´î´õ´µµµµµ(µ/µ>µIµOµTµVµbµbµiµµ‹µ‘µ—µ�µ¡µ¡µÎµÕµëµ÷µýµ ÀP¢²4¶7¶:¶G¶M¶M¶Z¶]¶`¶f¶h¶r¶Á”²Óv¶v¶’¶ž¶¢¶¦¶­¶´¶Ã¶Î¶Ô¶Ù¶Û¶ç¶î¶ö¶ü¶·····$·*·0·2·2·>·Â,!(³³ ³-³3³5³:³Ã¸«¾z¾zØzçzçzêzózÿzÿz { {A{S{e{i{y{™{«{±{Ä{Í{Ñ{×{à{à{|||"|@|R|X|k|}|‰|‹|—|Ÿ|£|©|²|²|²|²|Ä|Ú|à|ì|}}}}1}8}8}8}F}T}^}a}o}y}|}Ž}“}˜}¨}«}°}À}Ã}Ç}Ð}Ø}ê}ò}û}~~#~8~?~G~Y~_~n~~~†~†~†~”~¢~¬~¯~½~Ç~Ê~Ü~á~æ~ö~ù~þ~&8@IITkƒ‡“«³¹ÅÎÒÚãããü€
€!€*€2€8€>€>€>€E€W€c€k€q€w€w€y€‹€Ä|Ö“Ö“ä“ù“” ”-”a”}”�”£”©”µ”¾”Æ”ΔД֔ܔè”ð”ö”ø”þ”Å0 >²>²L²S²[²`²f²Æ<(3>³>³G³G³U³Y³`³c³h³Ç<3>n³n³w³w³…³‰³—³š³Ÿ³È<>I¦³¦³¯³¯³½³Á³È³Ë³Ð³É8ISֳֳ߳߳â³ð³þ³´´Ê AEþÀþÀ ÁÁË$ Ø'á'é'î'Ì$ À'É'Ñ'Ö'ÍT)Ž<Ž<«<³<Å<á<ì<þ<===&=)=7=V=V=k=m=m=y=�=…=’=’=ž=¦=ª=·=·=·=Ä=Ê=Û=Û=à=ø=> >>>">">'>?>N>S>Y>d>i>i>w>€>Œ>”>œ>¤>§>­>²>»>Í>Ö>ç>÷>÷>ü>? ??????? ?#?*?5?o?†?“?›?£?¯?»?Á?È?Ñ?Õ?Ø?ä?ê?ñ?ö?ö?@@@!@!@)@1@:@I@N@N@U@`@f@n@t@@„@„@“@ž@°@¶@¾@Ä@É@Ô@æ@ì@ô@ú@ÿ@ÿ@AA$A*A,A<ABABAdA‹A�A�A¤AªAÀAÑA×AÜAõAûA BBB!B&B&B:B@BVBgBmBrB‹B‘B¡B©B±B·B¼B¼BÒBØBîBÿBC
CC C0C8C@CFCMCRCRChCnC„C•C›C�C¬C²C¼CÄCÌCÒCÙCÙCÙCëCôCDDDDD(D0DADTD[DaDiDoDD…D�D“D“D“D˜D˜D˜D˜D˜D·DÃDÈDÈDÞDçDòDûDEEEE,E2EHEYE_EdEvE|E�EšE¸E¸E½E½EÉEÑEÔEÚEàEåEåE FFF)F/F5F5FFFdFdFiFiFuF}F€F‡F�F’F’F²FºFÊFÐF×FõFG G$G,G/G6G<GTG\GtG|GG†GŒGŒGŒG«G»GÇGÏGÒGÙGßGïGþG
H%H-H0H7H=HUHaH|H„H‡HŽH”H”H”H”H™H™H²HÈHÎHæHùHÿHIII!I=ICIOIWIZIaIgI�I˜I¨I®IµIµIµIºIºIÛIñI÷IJ"J(J-JXJ^JqJºJÖJÞJäJéJéJKKK&K&K+K+KEKQK]KhKhKmKmK‡K“KŸKªKªK¯K¯KÅKËK×KÝKâKôKúKÿKLL&L,L2L9LLLWL`LlLtLwL}LƒLˆLœL«L³LËLÓLÖLÜLâLúLM"M<MDMGMMMSMSMdMmMyM�M„M‹M‘M–M¨M·M¿M×MßMâMéMïMNN.NHNPNSNZN`N`NpNyN…N�N�N–NœN¡NµNÄNÌNæNîNñN÷NýNOO?O[OcOfOlOrOrOƒOŒO˜O O£OªO°OµOÇOÖOÞOùOPP PP)P1PSPpPxP{P‚PˆPˆPˆPˆPˆP�P�P£P©PµP»PÀPÒPØPÝPëP÷PQ QQQQ$Q)Q;QJQRQjQrQuQ|Q‚QšQ¢QÁQÛQãQæQíQóQóQóQR␍RR!R$R+R1R6RHRWRcR~R†R‰R�R–R®RºRÜRùRSS SSSSSSSS)SDSJSUSZSZSmSƒS‰S”S–S–S©SÌSÒSÝSÝSïSøS TT T0T0T5T5THT^TdTrT�T†T†T™T¯TµTÃTÒT×T×TíTóTU(U*URUXU]UiUrU�U�U†U†UœU¢U¿U×UÙUVV VV!V0V0V5V5VKVQVnV†VˆV°V¶V»VÇVÐVßVßVäVäVúVWW5W7W_WeWgWsW|W‡W‡W‡W‡WŒWšW£W´W¶WÈWÕWÕWÕWåWõWúWX*X+X0XEXbXrX–X¦X¬X¬X¬X±X¶XËXÞXY,Y2Y4Y9YJYYY‹Y“Y™Y›Y Y§Y§Y°YÂYÕYÞYíYíYòY÷YZZZZ%Z0Z0ZQZXZ^ZfZqZwZ‡Z�Z•Z Z¦Z¦Z«Z°Z·Z¾ZÅZÌZÕZäZäZäZéZéZéZûZ[[[[%[-[3[3[3[8[8[C[T[W[c[l[x[[…[Š[Š[•[¦[©[µ[¾[Ê[Ñ[×[Ü[Ü[Ü[Ü[á[æ[æ[í[ñ[ñ[ý[\ \ \\\(\/\5\D\O\Z\`\i\m\m\y\‚\…\…\�\’\¤\«\±\¹\Ä\Ï\Õ\ß\â\æ\æ\î\õ\ø\ú\] ]]]] ]"]:]A]L]W]Z]`]e]e]l]p]p]|]…]ˆ]ˆ]“]•]§]®]´]Ã]Î]Ù]ß]è]ì]ì]ø]^^^^^#^*^0^8^C^N^T^^^a^e^e^m^t^w^y^„^ˆ^‘^”^”^Ÿ^¡^¹^À^Ë^Ö^Ù^ß^ä^ä^ö^ú^ú^_____ _1_8_>_P_[_f_l_q_q_|_�_�_Œ_‘_‘_‘_‘_‘_‘_‘_–_›_›_¦_©_­_´_¹_¾_Ã_Ã_×_Ü_Ü_é_í_þ_`
``%`)`)`6`B`J`P```d`u`‡`’`–`–`£`«`³`¹`¹`¹`¹`¹`»`»`É`Ð`Ý`é`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`÷`ù`ù`aa"a"a6aDa_aaamazaza’aŸaªa³a¼aÇaÎaÎaØaØaÛaía bbbZdÎt Z^d^d{dƒd†d”d¢d·dÀdØdîde ee e2e5e@eIeUehe™ete©e½eÎeÚeèeff<fMfOfVf‹f‹fŽf“f–f–f�f´f»fÈfÍfÜféfüfüfgg4g4gLgQgQgagigygƒg“g�g­g¹g¾g¾gÎgÖgægðgh
hh&h+h+h+h?hMhWh\hih~h~hƒh�hœh¡h§h¬h¬h±h»hÊhÏhÕhÚhÚhàhæhëhëhúh ii&i2iEiMiSi\isi‡i˜i¥iªiÂiÕiìiùijjj"j+j4j4j9j9j9j9j9jEjEjEjNjgj|j„jŸj°j½j¿jÓjØjØjØjãjñjöjöjýj kk(k4kFkRkXkgkkktk}kšk¦k¬k²kÅkÍkÕkll l"l0l0l5l5l<lJlOlblnlzl€l„l�l’l’l’l’l’lªl¯l¯l¯l¯l¯lÀlÀlÀlÀlÀlÀlÀlÀlÀlÀlÉlâl÷lÿlm+m8m:mNmZm_m_m_mhm‚mŽmµmÁmÁmÆmÆmÆmÆmÆmÆmÆmÆmÛmàmàmàmñmümnnn,n5nFnJnbnrnzn‚n·nÀnÄnÜnìnìnìnìnìnoGoPoToZo_ohoqovovovovo…o™o·oÂoÇoÍoÒoÒoåoùo p*p2p8p8p=p=pLp`p~p‰pŽp”p™p™p¬pÀpæpñpùpÿpÿpqqq q&q;qCq^qoq|q~q�q�q�q�q�q�q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q£q²qÁqÌqÎqÎq×qÙqÙqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqíqïqïqr rrrr1rarpr|r’r¬r¯r¹rÅrër s+sOsQsdsjs­s­s°sÀsÈsãsôs÷st t+tCtCtntqt€t”tµtÆtâtÎtþtu.uau_uIu:uouououruwuzu”u¢uÐuòuòuv v/vCvdvuv‘v}v­vËvþvüvæv×v w w wwwww+wLwXw·zÏð«ãހހ§€«€¶€½€È€Ü€Ü€ç€ø€ÿ€ ��%�-�>�>�G�L�T�h�v�…���£�£���Ì�ë�ë�ÿ�‚‚ ‚‚‚"‚*‚*‚4‚<‚<‚<‚M‚M‚M‚Q‚Y‚_‚d‚d‚h‚p‚t‚z‚‚‚‹‚ ‚°‚º‚͂҂ڂڂ߂߂æ‚ò‚ƒƒ!ƒ)ƒ/ƒBƒGƒOƒUƒUƒZƒaƒlƒ”ƒŸƒ®ƒ¸ƒÀƒƃ؃Þƒãƒãƒãƒãƒãƒãƒãƒãƒãƒîƒúƒ„„„%„8„=„E„J„R„W„W„W„_„g„p„x„}„…„Š„‘„œ„Ąτׄæ„ð„…… …………+…3…F…N…V…k…m…x…€…•…•…±…¹…À…Æ…Ê…Î…Ý…î…†††-†9†>†J†U†Z†Z†{†•†š†¢†±†¹†Á†Ö†Û†æ†î†‡‡‡*‡6‡>‡S‡_‡d‡p‡{‡€‡€‡€‡€‡€‡€‡‹‡‹‡‹‡‹‡‹‡‹‡‹‡‹‡‹‡‹‡‹‡‹‡–‡¶‡Ó‡ã‡é‡ñ‡ˆ ˆˆˆˆ#ˆ6ˆ<ˆDˆLˆNˆnˆvˆˆ‡ˆ�ˆ”ˆ™ˆ ˆ«ˆÓˆÞˆæˆõˆÿˆ‰‰%‰*‰*‰*‰3‰<‰?‰I‰W‰i‰k‰}‰�‰�‰�‰š‰Ÿ‰¼‰Á‰Á‰ʉωωωωωωωωωωωωωωωωωωωωωωÚ‰æ‰ò‰Š%Š-ŠMŠRŠZŠaŠnŠvŠŠ‡ŠŽŠ“Š“Š›Š£Š¿ŠÇŠÊŠÌŠÜпппŠèŠûŠ ‹‹‹‹ ‹ ‹(‹-‹5‹<‹I‹b‹i‹n‹†‹�‹«‹Ä‹Ì‹Ù‹ò‹ù‹ù‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹þ‹ŒŒŒ+Œ0Œ0Œ8Œ@ŒMŒRŒRŒRŒVŒ[Œ[ŒkŒpŒpŒpŒ†Œ’Œ¤Œ·Œ½ŒÅŒÚŒáŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒéŒëŒëŒ� ��� �*�1�?�L�L�L�P�[�y�‡�“�Ðø{–�–�¬�·�¾�É�Ô�ë�ö�ý� � �&�&�5�O�V�_�f�i�u�~�…�ˆ���£�­�¿�Å�Ñ�æ�í�õ�‘‘‘‘‘+‘9‘C‘F‘T‘^‘a‘s‘x‘}‘�‘�‘•‘¥‘¨‘¬‘µ‘½‘Ï‘בבבí‘÷‘ ’’’0’7’?’Q’W’f’w’w’~’~’~’Œ’š’¤’§’µ’¿’Â’Ô’Ù’Þ’î’ñ’ö’“ “ “““0“8“8“D“R“R“U“`“~“Œ“Õ“Ñ´oØ&˜&˜@˜X˜_˜f˜q˜�˜¢˜¥˜®˜µ˜½˜Иá˜í˜Line truncated
d!d(d3dKdQdTdidndyd„džd¹dÍdîdþde eee'e-eNeReXe`eeemeŽe’e˜e e¥e¥e²e¸eÓe¿eßeãeéeñeöeff!f)f8fSf?f_fcfifqfvf—f›f¡f©f©f®f»fÁfâfæfìfôfüfg!g'g/g/g<gBgcgggmgug}gžg¢g¨g°g°g°gÅgÅgÅgÅgÐgÚgãghh h%h6hJhOhOhZhbhjhsh“h h¯h¾hØhÝhÝhèhðhýhii i:iLi^iiininiyi�i¤i°iÁiÆi×iëiëióiëi jjj j$j$j3j8j8jIjNjNj_jdjdjwj†j‹j‹jžj­j²j²jÔjÙjÙjûjkk"k'k'kIkNkNkkk’k—k—k¹k¾k¾kÛklll)l.l.lKlrlwlwl™lžlžl»lâlçlçl mmm)m.m.m.mImNmNmNmimnmnmnm‰mŽmŽm©m®m®m®mÉmÎmÎmÎmémîmîmîm nnn n$n$n5n:n:nFnQnfnknknwn�n•n¸n¿nÉnÎnßnénþn oo o*o2o7o7o;o?oFoPoZoZomorororovo�o˜o˜o»oÀoÀoÈoÜoåoÿo pp"p-p?pKpTpYpYpYpjp‡p’pœp§p¬p·p¿pÄpÄpÏp×pàpëpûpq+q?qDqDqOqbqlqwq˜q¤qµqºqËqÏqÔqÔqäqïq÷qüqrr r9rKr]rhrmrxr€r…r�r�r¨rÂrÔrærærærærërðrðrür␍s3sQsQs[sosys{s‡s�s¬s½sÇsÒsõst(t3tKt[t`t`tktptptxtƒtˆtˆt�t›t t t¨tÆt°tÞtãtãtët uót!u&u:u&uRuWuWuduiuiuquvuvu‚u“u¥uªuªu¾uªuÖuÛuÛuãuèuèuûuvvvvv2vBvGvGvavqvvvvv�v v¥v¥v¿vÏvÔvëvÔvwwwwwTwBwwlwqw­w›wqwÅwÊwÊwÙwéwîwîwýw␍xxx!x/x4x\xJx4xtxyx¡x�xyx¹x¾xæxÔx¾xþxyy y
yJyZy_y_yzyfy¤y´y¹y¹yÅyÊyÊyÖyÛyÛyîyþyzzz&z+z+z>zNzSzSzfzvz{z{zƒzˆzˆz�z•z•z�z¢z¢zªz¯z¯zÂzÇzÇzÚzßz-{{ {ßz:{?{�{{{i{?{š{Ÿ{Ÿ{®{É{Î{Î{ß{ú{ÿ{ÿ{||#|#|+|0|0|8|=|=|E|J|J|‚|p|Q|¡|¼|Á|Á|ù|ç|È|}3}8}j}X}8}‚}‡}¹}§}‡}Ñ}Ö}ð}Ö}~␍~*~␍~B~G~G~S~l~|~�~³~µ~Ë~Ñ~í~ú~+mJy����’’¥°º¿ÊÔÙÙóøø€€€€%€0€5€I€5€U€`€e€e€p€~€ƒ€ƒ€Ž€™€ž€ž€¯€´€´€Å€Ê€Ê€ä€ï€ô€ü€ô€�␍�!�␍�-�2�:�2�F�K�_�K�k�p�p�„�p�����•�¡�•�´�¹�¹�Å�¹�Ø�Ý�Ý�é�Ý�ü�‚‚␍‚‚ ‚%‚9‚%‚E‚Q‚\‚g‚l‚€‚l‚Œ‚˜‚£‚®‚³‚Ç‚³‚Ó‚ä‚é‚é‚ñ‚ö‚ö‚þ‚ƒƒ ƒƒƒƒ ƒ ƒ(ƒ-ƒ-ƒ8ƒ=ƒ=ƒHƒMƒMƒXƒ]ƒ]ƒhƒmƒmƒxƒ}ƒ}ƒˆƒ�ƒ�ƒ˜ƒ�ƒ±ƒ�ƒ½ƒȃÓƒÞƒãƒãƒíƒòƒòƒüƒ„„ „„„„ „ „'„,„,„9„>„>„K„P„P„P„P„P„X„]„]„e„j„j„r„w„w„„„„„„Œ„‘„¥„‘„±„„DŽDŽل䄅 … …*…C…/…O…Z…e…j…j…|…‡…§…¬…Â…Í…æ…Ò…ò…ý…†␍†␍† †*†J†O†e†p†‰†u†•† †«†°†°†Ö††â†‡‡‡(‡-‡H‡4‡h‡T‡t‡Їv‡ª‡–‡¶‡Á‡ƇƇì‡؇ø‡ˆˆ3ˆ>ˆCˆ^ˆJˆ~ˆjˆŠˆ ˆŒˆÀˆ¬ˆ̈׈܈܈‰îˆ‰.‰3‰I‰T‰Y‰t‰`‰”‰€‰ ‰¶‰¢‰Ö‰‰â‰í‰ò‰ò‰ŠŠŠŠŠŠŠ Š%Š%Š%Š/Š1Š1Š;ŠHŠhŠjŠjŠtŠtŠtŠtŠtŠtŠtŠvŠvŠ�Š“ŠžŠžŠ«Š±Š¸ŠÊΊÙŠäŠéŠ‹
‹*‹2‹[‹S‹s‹s‹s‹{‹„‹Š‹•‹•‹£‹¶‹¶‹΋؋싌ŒŒ'Œ7ŒLŒ^ŒnŒnŒ–Œ�ŒŸŒ¥Œ«Œ«ŒºŒÌŒÐŒÕŒÜŒìŒ � ��&�-�2�2�6�A�M�[�ˆ�‘�¢�°�ã�ï�ô�
Ž"Ž.Ž?ŽDŽUŽtŽ¢ŽÈŽËŽÛŽÝŽÝŽáŽ� � ���J�j�j�j�¤‘Ô0–²–²Ÿ²¥²­²¼²Ë²Ð²Õ0!Ö²Ö²ä²ê²î²ý² ³³Ö,ÁÁ'Á1ÁAÁLÁLÁjÁר4ffÂfÂ|ƒ†ªªÂÇÂÚÂíÂÃÃÃ#Ã1ÃDÃWÃ_Ã_ÃaÃaÃaÃtÃvÃvÃvÃ}Ã�ãããõÃÁÃÔÃêÃïÃöÃýÃÄ%Ä,Ä,Ä/ÄTÄØ¤Y~~ü~ü˜üžü¥ü­üµü¸üÃü×üÞüáüãüìüýüýüýýý!ý/ý2ý5ý<ý@ýHýVýhýnývý«ýÙH®<ˆˆ ˆJˆRˆRˆ`ˆsˆŒˆ�ˆ«ˆ«ˆ«ˆ³ˆµˆµˆ½ˆ¿ˆ¿ˆÇˆÉˆÉˆÑˆÑˆÚˆàˆåˆåˆîˆúˆþˆ‰ ‰‰‰‰ ‰%‰*‰*‰/‰;‰S‰r‰u‰Š‰©‰©‰©‰±‰³‰³‰³‰»‰½‰½‰½‰Å‰Ç‰Ç‰Ç‰Ï‰Ñ‰Ñ‰Ü‰Ü‰â‰ç‰î‰ù‰ Š Š Š ŠŠŠ+Š+Š6Š:Š@ŠXŠfŠyЅТХЬоЯŠÏŠÚŠÚŠåŠëŠðŠ÷Š‹‹‹‹%‹+‹@‹H‹N‹p‹|‹‚‹‡‹Ž‹™‹™‹ž‹°‹¶‹¸‹¸‹¿‹Ê‹Õ‹Õ‹Õ‹Õ‹,ŒÚ8Ë~©~©˜©Ÿ©¬©·©¼©Â©Ô©Ú©ò©ø©ª*ª5ª;ª]ª]ªmª‚ª„ª‡ª“ª›ª£ª«ª¹ª¿ªÅªÑªÑªÓªåªëªðªðª««%«%«8«E«J«J«a«j«…«•«£«®«¾«Ë«Ø«â«î«û«ý«ý«¬
¬
¬¬¬¬ ¬$¬$¬,¬1¬1¬7¬<¬<¬C¬H¬H¬O¬T¬T¬_¬d¬d¬o¬t¬t¬¬„¬„¬�¬�¬¤¬«¬±¬´¬»¬¾¬É¬Ð¬Ó¬å¬ç¬í¬ø¬ø¬ø¬­­/­?­P­V­g­m­r­|­�­ž­­­³­Ä­Ï­Ù­è­õ­û­® ®!®'®8®C®I®Y®Y®i®|®ˆ®�® ®§®­®¾®É®Î®ë®¯¯¯*¯<¯G¯V¯X¯j¯r¯w¯~¯‚¯�¯š¯ ¯¨¯®¯¹¯¿¯Á¯Î¯Û¯å¯
°
°°>²Û4¨ñ¦¦8¦<¦T¦\¦d¦n¦r¦y¦¦“¦›¦ ¦£¦®¦¹¦Á¦Ì¦×¦Ù¦ñ¦ø¦ÿ¦
§§§"§-§/§;§D§D§Z§{§�§‡§˜§ž§§§¹§¿§¿§Ç§Ë§Ö§Û§í§ø§ü§
¨ ¨¨ ¨ ¨ ¨0¨0¨5¨G¨M¨»¨Ü˜Œ®ІІކð†ô†ü†‡‡‡"‡-‡8‡=‡U‡\‡c‡n‡y‡{‡†‡‘‡“‡Ÿ‡ª‡µ‡¾‡Æ‡Æ‡Ê‡ˆÝp¨&•&•C•J•R•]•u•••—•¡•¼•Ò•à•ä•–– –"–;–E–V–X–i–i–p–w–€–…–Š–‘–˜–²–¹–É–Í–Í–×–í–ñ–ñ–——+—+—2—=—D—M—X—_—h—s—z—z—…—£—§—°—Ú—Ú—à—ç—ö—þ— ˜˜˜˜+˜+˜+˜=˜E˜k˜y˜y˜}˜’˜š˜ª˜µ˜Ê˜Ï˜Ý˜ì˜ô˜™␍™™™™"™1™3™B™D™S™U™d™k™q™…™�™›™¢™¦™¶™Á™Æ™ä™ì™ú™šš␍šš"š&šBšJšUš[š[š[šdšošš¡š©š´šÃšËšÖšÛšãšîšúšþš ›› ›(›3›3›3›3›A›P›m›y›�›‘›¡›¿›Ã›ò›Ø›œœ œœ"œ1œ9œGœNœRœTœcœkœyœ€œ„œ„œ†œ˜œ˜œªœªœªœ°œ¼œÎœÖœîœ�(�,�J�Q�X�c�y�{�‚�•���«�²��¸�Ë�Ó�á�è�ì�ì�ì�ì�ú�žžž*ž5ž9ž9ž>žFžJžYž[žjžlž{ž}žŒž“ž™ž­žµžÃžÊžÎžÞžéžîž ŸŸ"Ÿ)Ÿ-Ÿ5ŸCŸJŸNŸjŸrŸ}ŸƒŸƒŸƒŸŒŸ¡Ÿ»ŸËŸÖŸëŸðŸûŸ  - 5 @ O W b g o z † Š • š ¬ ´ ¿ ¿ ¿ ¿ Ó ã ø ¡ ¡¡.¡C¡P¡T¡b¡w¡‡¡ž¡·¡Ð¡Ò¡Ý¡å¡å¡î¡¢¢+¢D¢]¢_¢j¢r¢r¢r¢Œ¢š¢¨¢½¢Ú¢é¢£££,£@£Z£Z£^£t£ƒ£ž£©£À£È£È£ê£ê£ý£¤!¤6¤V¤e¤‘¤Ÿ¤µ¤Î¤Þ¤ö¤ö¤¥¥¥2¥J¥S¥S¥S¥_¥p¥ˆ¥‘¥‘¥˜¥¡¥§¥³¥¦ÞPñ¾¨¾¨Ð¨å¨ö¨ ©©©(©0©A©G©y©ß6sö ö ␍.␍3␍;␍C␍K␍X␍^␍e␍k␍p␍x␍”␍š␍œ␍ž␍«␍«␍­␍É␍Ï␍Ñ␍Ó␍à␍à␍à␍å␍î␍÷␍ù␍ $/6=Igny�—ŸŸ³ÃËÎ4à¸+†ð†ð�ð¤ð§ð¶ðºð¾ðÌðÐðØðÜðêðîðöðúðñ ñññ&ñ*ñ2ñ6ñ9ñ=ñáp2N N d o z ˆ “ ™ ª ° Á Ç Ó ê ê ü ␍!! !1!7!…!âœ~¡®ý®ýÊýÏýÖýàýæýñýþ þþþ!þ+þ1þ<þLþTþdþkþsþ{þƒþ‹þ�þ›þ©þ©þ¿þã”*K¾Ê¾ÊÆÊÊÊÖÊçÊéÊùÊËË!Ë,ËSËSËlËpË}Ë}ˇˎˡ˪˸ËÉËåËêËÌä f*VÄVÄxĀĆĎÄ�Ä�ġġġĩıÄÃÄÃÄçÄéÄéÄÅÅÅÅÅ/Å4Å4Å4ÅIÅKÅXÅZÅgÅiÅvÅ~ņÅ�ŜũūſÅÌÅÌÅÌÅÕÅçÅúÅÆÆ
ÆÆÆ,Æ,Æ,Æ7ÆAÆYÆ^Æ^Æ^ÆlÆrÆwÆƊƜƧƬƬƳƷÆÅÆÌÆÕÆÜÆîÆõÆüÆÇ!Ç&Ç&Ç&Ç&Ç.Ç9ÇGÇGÇgÇgÇgÇnÇ|Ç‹ÇžÇ±Ç³Ç³Ç³ÇÆÇÆÇÍÇÔÇÙÇßÇñÇûÇÈ?ÈEÈEÈYÈ^ÈpÈwȃȕȢȭȴȸȸȸȸÈÃÈÍÈÛÈýÈÉ%É/É/É=ÉgÉzɋɢɵɺɺɺÉÂÉÍÉßÉêÉïÉïÉïÉÊ.Ê4Ê4Ê4Ê?ÊIÊUÊ`ÊbÊbÊbÊgÊsÊsʽÊå¤2W†!†!ž!°!¶!Â!Í!Û!ç!þ! ""+"1"7"="P"V"_"e"w"}"ˆ"�"ž"«"è"æ°î,:MRpv{��–¥ªÔßòù0<Wo‹”£«¸ÁÆ×
+=MS^gm³ŽÃþÙ1ÅçT™j^Ï^Ï|ςυώϘϰÏÀÏÉÏÏÏÓÏ×ÏÙÏñÏÐÐÐÐÐÐ"Ð&Ð&ÐIÐMÐSÐSÐZÐ|БФзнÐÄÐÏÐÙÐÝÐàÐçÐíÐóÐøÐ ÑÑÑÑ(Ñ*Ñ<Ñ>ÑCÑPÑRÑdÑdÑdÑdÑdцёÑ�Ñ·Ñ·ÑÌÑØÑõÑÒ3Ò8ÒOÒTÒbÒyÒ~Ò„Ò•ÒªÒ°ÒÀÒÍÒåÒìÒøÒÓÓÓÓÓ"Ó%Ó(ÓAÓGÓ[ÓaÓhÓsÓsÓxÓ…Ó’Ó’Ó˜Ó¦Ó½ÓÃÓÆÓÉÓÐÓ×ÓÞÓÞÓãÓðÓýÓýÓÔÔ(Ô.Ô1Ô4Ô;Ô;ÔLÔQÔ^ÔkÔkÔrÔ|ÔƒÔ‰Ô�Ô›Ô¯Ô¯ÔÉÔÎÔÕÔÝÔäÔóÔ÷ÔÕÕÕFÕQÕXÕ`ÕyÕ�Õ�Õ¨ÕªÕÂÕ×ÕÞÕÖÖ7Ö9ÖCÖeÖeÖeÖ~֌ֲֶ֚֋×ès°66Zafnˆ‘“  ¢¼ÂÄÆÓÓÓÓ׿ïøÿ#'9LRfkxxŒ“𡝏ØÞâçìïùü éœ+N>ñ>ñHñ_ñnñrñvñ„ñˆñ�ñ”ñ¢ñ¦ñ®ñ²ñÀñÄñÌñÐñÞñâñêñîñññõñê41:¾ú¾úÖúûûãúáú2û:ûëøîèÆÆãîî))9BIPYYaeƒ�›¡¬ÎÎáìòùþþ'.@EEUZZZmr…‹’§»»ÀÀÐÕÕÚáéðòú#*-OOWfqxzŽ ¥ªªª½ÂÑØßô␍␍+0DKPP\k}ŒŸ£²ÀÎÝú
07>NP^np~‹›¢·¾ÊÛòô ␍␍,<DFZov†’³ºÆçççïúþ
#=BIT]ejjy†”Ÿª¸¾ÄÊÓÚìù␍24=HJVw}ƒ‰’£ÍÖàí -BBOTfllll(ì€è..L^dp‡‡™ŸªºÆÏÕÛæô ␍  * * Z í4U^&ò&ò4òTòZò`ò`òfòîH*8~+~+Œ+–+ +°+µ+»+Ç+É+Û+Û+Ý+␍,ïˆ{™ÎÎ(Î=ÎGÎPÎRÎYÎiÎtÎvÎ€Î€Î†Î—ÎšÎšÎ»ÎÆÎÈÎáÎèÎìÎøÎ Ï^Ïð$␍–Á–ÁŸÁ³Á¸Áñ$öÁöÁÿÁÂ#Âòp4&Â&Â4Â>ÂGÂNÂUÂ_Â_ÂeÂó$␍nÁnÁ|Á�Á–Áô$¾Á¾ÁÌÁëÁñÁõÐK{ÌÌ"Ì7ÌFÌJÌXÌ^ÌmÌmÌ|̇̒Ì�̴̤ÌÞÌäÌéÌíÌýÌýÌÍÍ Í@ÍKÍMÍfÍjÍxÍ}Í}Í„Í�ͫ͘ÍÎöø™Ó~0~0œ0Ÿ0¥0¹0Á0Ò0ß0å0ê0ê0÷0111$171>1J1V1V1d1w1‚1†1—1—1—1œ1œ1¨1·1Ê1Ð1Õ1é1ï1÷1 222 2-23292>2D2J2Q2]2d2f2k2s2u2z2†2ˆ2�2•2—2œ2¤2¦2«2³2µ2º2Ä2Æ2Ë2Õ2Õ2Õ2å2å2å2ü23333 393?3J3N3T3_3x3ƒ3Ž3”3¡3¦3«3«3À3È3Ð3î3ù34
44"4'4,4A4H4Q4]4c4o4s4x4ˆ4“4ž4 4¦4³4¸4½4Ö4á4ì4ì4ò4ÿ4555(535>5D5Q5Q5U5Z5Z5k5m5m5€5‚5‚5•5—5—5ª5¬5¬5¿5Á5Á5Ó5Ó5Ù5Þ5Þ5õ5 6þ566%6,646G6I6b6b6|66�6�6Ÿ6¯6»6Ò6ì6ñ677(7-7-737G7Y7d7l7t7x7†7Œ7‘7‘7—7«7»7À7À7Æ7Ì7Ñ7Ñ7Ñ7×7æ7ù78
8888888(848N8d8p8p8v8ƒ8…8�8œ8«8¾8¾8Ë8×8×8×8×8Û8à8ñ89999 92979E9Q9W9d9d9{9‹9‹9Ÿ9«9­9¶9Â9Ù9Ù9ß9ì9î9:: : : : : :‡<÷Œ:Y>û>û^ûfûjûxû~û„û±ûÇûÛûéûüüüü%üDüMü]ü_üfüfülülü|üø 8\,,,*,6,F,^,d,r,ƒ,‹,’,¨,Î,è,õ,----+-M-T-Z-h-p-†-‘-—-�-À-ù,c*î"î" ###.#@#F#Q#h#w#‚#†#‘#�#¨#´#Ë#â#õ# $!$1$1$C$I$Z$`$p$p$ˆ$ˆ$­$­$²$²$¸$Ä$Ñ$Ý$ò$ %%#%5%A%X%p%‘%‘%š%Ÿ%Ÿ%Ÿ%Ÿ%¯%¸%À%Å%Ó%á%ñ%ö%ö%&&&&&(&:&@&L&\&g&q&u&~&—&š&ª&·&Ç&×&Þ&ä&ð&ø&'
''!'''4'?'E'U'e'e'’'´'À'È'Ó'Ú'å'ç'ò'ò'(((((.(4(B(O(\(f(j(s(Œ(�(Ÿ(¦(«(«(¿(¿(Ä(È(Ø(á(ó(ù(û(û( )))&),)8)H)H)H)M)e)e)t)w)‹)©)´)Ý)ï)ú) ****.*>*V*]*a*g*o*z*}+ú\™Æ-Æ-â-é-..#.....3.>.J.U.c.s.ƒ.Š.‘.¦.».».Ï.ç.ô./////=/K/R/Y/n/ƒ/ƒ/—/¤/²/Â/È/Ù/Ù/ß/í/þ/ 00}0ût¡úÆþÆþèþóþúþÿÿÿÿ ÿ ÿ'ÿ.ÿ5ÿ;ÿAÿHÿJÿSÿ_ÿeÿ‹ÿ’ÿ•ÿ¥ÿ­ÿ²ÿ²ÿ¹ÿ¿ÿÐÿÖÿÜÿåÿçÿîÿîÿóÿýÿ )@CR^kkkkqƒ‰š»Ïãêôü "2===Qeuxü|Õpçç@çGçVçaç‡ç‡ç�ç’ç’ç™çÃçÍçÍçÜçëçè è èè!è1è7èUè`èbè{è�èŒèœè®è·èÂèÇèÍèÔèùèþè éééé+éBéBéQéWékéréyé~é‰é�é—é½éÆéÍéÒéÝéééøé êêê%ê7ê7êNêUê]êmêê…êŽêŽê�ê£ê·êÀêÐêßêôêýê␍ë ë+ë?ë`ëwë{ë‡ëžëºëÌëÒëÝëéëùë ìììì)ì-ì9ìPìlì~ì„ì�ì›ì«ì»ìÍìÓìÓìØìÚìÚìßìßìîìôìúìúìþìwïý¼jՎ׎׬׷×Â×è×è×ê×þ× ØØ Ø/Ø>ØKØKØQØVØ[ØnØ�ØŒØ�آسػØÂØÝØëØëØëØöØÙýØ#ÙÙ-Ù/ÙKÙ7ÙSÙaÙaÙcÙÙنٌٕٜٟٶÙÁÙÕÙÈÙÝÙãÙìÙìÙìÙÿÙÚÚ Ú ÚÚ,Ú5Ú5Ú5Ú5ÚQÚhÚnÚsÚsÚˆÚŽÚ“Ú“ÚŸÚ¼ÚÚÚßÚäÚäÚðÚ␍ÛÛ+Û3Û8Û>ÛCÛCÛJÛQÛtÛ‘Û“Û°ÛÅÛÅÛËÛËÛßÛèÛèÛÜ Ü%Ü9ÜDÜLÜTÜdÜ{Ü{܋܋Ü�Ü£ÜËÜÔÜÔÜÖÜÝÜâÜâÜöÜÝÝÝÝ#Ý7ÝIÝTÝbÝkÝpݗݠݫݰݷݿÝÒÝçÝìÝóÝÞÞÞ.Þ5Þ;ÞDÞDÞgÞnÞsÞ�Þ‘ÞŸÞŸÞ¥Þ¬ÞµÞµÞÈÞÚÞÝÞÝÞîÞöÞþÞ
ß'ß.ß;ß=ßDßXßgßgßgߎߎߎߢߢ߷ßÂßÔßáßìßúßààà5àHàJàYànàpà~à“à“à™à¢à¢à¶à¼àÎàÎàâàåàðàá ááá!á(á3á8áMáRálá�á�á�áƒáŠá‘á¥á³áÈáÈáÎáÕáÞáãáâ␍â␍ââââ;â;âOâRâXâaâiâtâ†âŒâ—â—â«â®â´â½âÅâÐâââèâóâóâã
ãããã=ãPãeãkãvãˆãŽã–ã–ã–ã–ã¡ãçþÈjØöòöòó#ó*ó3óCóUó\óbóhómó’óŸó¢ó«ó½óÃóÈóëóþóôô ô&ô4ô:ôFôPôUô\ôuôôˆô˜ôšô¡ô¦ô®ôÍôÛôçôõ õ'õ1õ@õFõLõRõXõnõ�õ£õ¯õÆõÑõÚõíõúõöö0ö=öHö]ö€ö’ö©ö²ö¸öÄöÉöÐöçöòöÿö÷÷÷#÷%÷3÷B÷T÷T÷\÷÷Š÷¾÷ÿXß1¾÷¾÷é÷ó÷øø#ø1ø8øGøNøVøløtø‡øœø¬ø¶ø¸øÈøØøáøçøìøóøúøùùùù ù&ù@ùHùbùwù„ù‡ù�ù“ù¥ù´ù¿ùÇùÞù÷ùûùú úú%ú,ú0ú9ú;úMúdúrúxú|ú~ú‹ú‹ú‹ú�ú¤úªúªú¼úú68@FShv||||‰‹– §³¾ÄÎÕææñûû␍#).55V\k~„‡���•›���®¸½½ÒÜÜðùÿ ':>>FLR\cjs……ª®µ»ÊÝãçîôúúü␍CTTkx|„™¹¹¿ÂÆÌÌÞï 15FJPikq~€Œª±¼ßêðöü !2:>OSYrtz‡‰•³¹¿ÅÎÕå 055<CUZZZtv�’¬²º¾Åèîô   $ 0 5 5 < @ G U W _ d l w } ‰ Ž ” ™ ¡ ¦ µ Ð à í ü 

6
6
=
R
W
`
m
r
y
~
~
…
‰
�
ž
 
¨
¬
°
º
Æ
Í
Ñ
Ù
á
é
ø
      A A O U Z ^ c c c c i k k Ž ” š · ¹ ¹ ¹ Ä Ä Ä É ì ò h^ ^ t † Œ — ¥ ± È È Ú à ë û   ! M Dâ﨨±¼ÇÒÝèóþ  X»ÍšÉšÉ´ÉÇÉÉÉÓÉàÉõÉ÷É ÊÊ(Ê(Ê/Ê2ʆÊT‚®‚®œ®¯®¹®À®Ì®å®î®ò®¯ ¯*¯P‡—à%à%÷%␍&&$&;&V&h&l&¯&pï‡  9DT�¤¸¿ÇÏØàèêòú'?HH}§°Òì 3?acjqq—×W—×&388GTVV^^^m†Ÿ¸ººÁÁÏÒßíüLSSS[x†¤­Òàú3A]{{{†‰¸ÏÕæïñþ␍@BIZcesuƒ…““³³³³ÀÓæ-59AESackos{‰——±¼Òä&07P\c||Ž“•›¬½ÌÓäíïýÿ␍AA^elo{~Œ�ž¢°´´ÍÔÙçøÿ5HWYhjyƒƒ‘š°·Üá
:?MO]f€‚„‹œ¥§µ·ÅÇÕÕõõõõõ ;`y~~~ ¥¥¥ÅÊÊÊéîîõøý8LQQY\a€œ°µµ¼¿Äãÿ3@BQZtvv{vœžž¡ßßßþþþ $ $ $ F K K K k p p p � ” ” ¯ ½ ¿ Î × ñ ó ó ø ó     \ \ \ g g ‘ ‘ » Ó ë ö !!1!I!]!w!y!Š!¤!»!Â!à%P—§°&°&É&Ë&Ò&è&ø&þ&'-'0'B'Š'¨¼â˜␍˜␍¨␍ª␍µ␍À␍Ñ␍Ü␍ç␍ò␍û␍ 2=FOVcw~€„†ž¨ (^dfòfòjò‚ò”ò®ò
(dj®ò®ò¼òÐò×òñò
+35
View File
@@ -0,0 +1,35 @@
#exe {OptOn(OPTf_WARN_PAREN);};
#exe {OptOn(OPTf_WARN_DUP_TYPES);};
#exe {OptOn(OPTf_KEEP_PRIVATE);};
#include "/Kernel/Adam1a.HPP"
#exe {OptOn(OPTf_EXTERNS_TO_IMPORTS);};
#include "/Compiler/CmpDefs.HPP"
#include "/Kernel/Adam1b.HPP"
#include "/Kernel/Adam1c.HPP"
#exe {OptOff(OPTf_EXTERNS_TO_IMPORTS);};
#exe {OptOff(OPTf_KEEP_PRIVATE);};
#include "CmpAsm"
#include "CmpExts"
#include "CmpGlbls"
#include "Unassembler"
#include "ICLCC"
#include "Lex"
#include "Hash1b"
#include "Assembler"
#include "OptLib"
#include "ExpParser"
#include "StmtParser"
#include "OptPass012"
#include "OptPass3"
#include "OptPass4"
#include "OptPass5"
#include "OptPass6"
#include "BackLib"
#include "BackF1a"
#include "BackF1b"
#include "Back1a"
#include "Back1b"
#include "Back1c"
#include "OptPass789"
#include "CmpInit"
#include "CmpMain"
File diff suppressed because it is too large. Load diff
+151
View File
@@ -0,0 +1,151 @@
CHashSrcSym *HashEntryImportCopy(CHashSrcSym *temph)
{ //Actually this imports, not copies!!
CHashSrcSym *result=MAllocIdentical(temph);
result->str=MAllocIdentical(temph->str);
result->use_cnt=0;
result->src_link=NULL;
result->index=NULL;
result->ie_lst=NULL;
result->debug=NULL;
if (temph->type & (HTT_FUN | HTT_CLASS)) {
result(CHashClass *)->member_lst =MemberLstCopy(temph);
result(CHashClass *)->member_lst2=temph(CHashClass *)->member_lst2;
if (temph->type & HTT_FUN) {
if (Bt(&temph(CHashFun *)->flags,Ff_INTERNAL)) {
result->import_name=NULL;
LBtr(&result(CHashFun *)->flags,Cf_EXTERN);
} else {
result->import_name=MAllocIdentical(temph->import_name);
result->type|=HTF_IMPORT;
LBts(&result(CHashFun *)->flags,Cf_EXTERN);
}
}
} else if (temph->type & (HTT_EXPORT_SYS_SYM | HTT_GLBL_VAR)) {
result->import_name=MAllocIdentical(temph->import_name);
result->type|=HTF_IMPORT;
if (temph->type&HTT_EXPORT_SYS_SYM) {
result->type|=HTF_UNRESOLVED;
result(CHashExport *)->val=0;
} else {
result(CHashGlblVar *)->dim.next=LinkedLstCopy(temph(CHashGlblVar *)->dim.next);
result(CHashGlblVar *)->flags|=GVF_IMPORT|GVF_ALIAS;
if (temph(CHashGlblVar *)->fun_ptr)
result(CHashGlblVar *)->fun_ptr=HashEntryImportCopy(temph(CHashGlblVar *)->fun_ptr-temph(CHashGlblVar *)->fun_ptr->ptr_cnt)(CHashFun *)+temph(CHashGlblVar *)->fun_ptr->ptr_cnt;
}
} else if (temph->type&HTT_DEFINE_STR)
result(CHashDefineStr *)->data=MAllocIdentical(temph(CHashDefineStr *)->data);
return result;
}
U0 HashTableImport(CHashTable *src,CHashTable *dst)
{
I64 i;
CHashSrcSym *temph,*temph1,*temph2;
if (!src) return;
for (i=0;i<=src->mask;i++) {
temph=src->body[i];
while (temph) {
if (temph->type & HTG_SRC_SYM) {
//Only add first in lst
temph2=src->body[i];
while (temph2!=temph)
if (!StrCmp(temph->str,temph2->str) &&
temph2->type & temph->type & HTG_SRC_SYM ||
temph->type & HTT_EXPORT_SYS_SYM)
break;
else
temph2=temph2->next;
if (temph2==temph && (temph1=HashEntryImportCopy(temph)))
HashAdd(temph1,dst);
}
temph=temph->next;
}
}
}
I64 HashEntrySize(CHashSrcSym *temph)
{
CDbgInfo *dbg;
CBinFile *bfh;
switch (HashTypeNum(temph)) {
case HTt_DEFINE_STR:
return MSize(temph(CHashDefineStr *)->data);
case HTt_GLBL_VAR:
case HTt_CLASS:
case HTt_INTERNAL_TYPE:
return temph(CHashClass *)->size;
case HTt_FUN:
if (dbg=temph->debug)
return dbg->body[dbg->max_line+1-dbg->min_line]-dbg->body[0];
else
return -1;
case HTt_FILE:
return MSize(temph(CHashGeneric *)->user_data0);
case HTt_MODULE:
if (StrCmp(temph->str,KERNEL_MODULE_NAME))
return MSize(temph(CHashGeneric *)->user_data0);
else {
bfh=sys_boot_base-sizeof(CBinFile);
return bfh->file_size;
}
case HTt_WORD:
return StrLen(temph->str);
}
return -1;
}
I64 HashEntrySize2(CHashSrcSym *temph)
{
CDbgInfo *dbg;
I64 result=MSize2(temph);
if (!(temph->type&HTT_DICT_WORD))
result+=MSize2(temph->str);
if (temph->type & HTG_SRC_SYM) {
result+=MSize2(temph->src_link);
result+=MSize2(temph->index);
result+=MSize2(temph->import_name);
result+=LinkedLstSize(temph->ie_lst);
if (temph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM))
result+=MSize2(temph->debug);
if (temph->type & HTT_CLASS)
result+=MemberLstSize(temph);
else if (temph->type & HTT_FUN) {
result+=MemberLstSize(temph);
if (dbg=temph->debug)
//This should be $LK,"MSize",A="MN:MSize"$() but it would crash on AOT .BIN.Z file funs.
result+=dbg->body[dbg->max_line+1-dbg->min_line]-dbg->body[0];
} else if (temph->type&HTT_DEFINE_STR)
result+=MSize2(temph(CHashDefineStr *)->data);
else if (temph->type & HTT_GLBL_VAR) {
result+=LinkedLstSize(temph(CHashGlblVar *)->dim.next);
if (!(temph(CHashGlblVar *)->flags&GVF_ALIAS))
result+=MSize2(temph(CHashGlblVar *)->data_addr);
if (temph(CHashGlblVar *)->fun_ptr)
result+=HashEntrySize2(temph(CHashGlblVar *)->fun_ptr-temph(CHashGlblVar *)->fun_ptr->ptr_cnt);
}
} else if (temph->type & HTT_FILE)
result+=MSize2(temph(CHashGeneric *)->user_data0);
else if (temph->type & HTT_MODULE &&
StrCmp(temph->str,KERNEL_MODULE_NAME))
result+=MSize2(temph(CHashGeneric *)->user_data0);
return result;
}
I64 HashTableSize2(CHashTable *tempht)
{
I64 i,result=0;
CHashSrcSym *temph;
if (!tempht)
return 0;
for (i=0;i<=tempht->mask;i++) {
temph=tempht->body[i];
while (temph) {
result+=HashEntrySize2(temph);
temph=temph->next;
}
}
result+=MSize2(tempht->body);
result+=MSize2(tempht);
return result;
}
+442
View File
@@ -0,0 +1,442 @@
Bool OptEqu(I64 num,Bool val) {
return BEqu(&Fs->last_lex->opts,num,val);
}
//Turn on compiler option
Bool OptOn(I64 num) {
return OptEqu(num,ON);
}
//Turn off compiler option
Bool OptOff(I64 num) {
return OptEqu(num,OFF);
}
//Get state of compiler option
Bool GetOpt(I64 num) {
return Bt(&Fs->last_lex->opts,num);
}
//Displays intermediate code after passes through optimization
Bool OTrace(Bool val) {
return OptEqu(OPTf_OPT_TRACE,val);
}
//Ctrls which optimizer passes are displayed
I64 OTraceMask(I64 i=0b1001111101) {
I64 old=Fs->last_lex->pass_trace_mask;
Fs->last_lex->pass_trace_mask=i;
return old;
}
//Displays assembly code output
Bool CTrace(Bool val) {
return OptEqu(OPTf_COMPILE_TRACE,val);
}
//Displays text as it is being compiled
Bool Echo(Bool val) {
return OptEqu(OPTf_ECHO,val);
}
U0 ImportHashTable(CHashTable *src)
{ //called from #exe {} in AOT modules
// See $LK,"::/Kernel/AOT.HPP"$.
CLex *lx=Fs->last_lex;
if (lx==&Fs->next_lex)
PrintErr("Not Compiling\n");
else {
if (!(lx->flags&LF_EXE_BLK))
LexExcept(lx,"import_hash_table only allowed in AOT compiled "
"#exe{} mode.");
while (src) {
if (lx->htc.next && lx->htc.next->glbl_hash_table)
HashTableImport(src,lx->htc.next->glbl_hash_table);
else if (lx->htc.glbl_hash_table)
HashTableImport(src,lx->htc.glbl_hash_table);
src=src->next;
}
}
}
I64 IncludeDepth()
{
CLex *lx=Fs->last_lex;
return lx->cur_lfn-&lx->lfns;
}
U0 ICClassPut(CHashClass *c)
{
I64 i;
if (!c) return;
if (c->ptr_cnt>4) {
PrintErr("put_class ptrcnt=%d\n",c->ptr_cnt);
while (TRUE)
//TODO:
Yield;
}
for (i=0;i<c->ptr_cnt;i++)
'*';
c-=c->ptr_cnt;
if (c->str)
"%s",c->str;
else {
PrintErr("put_class str=NULL\n");
while (TRUE)
//TODO:
Yield;
}
'' CH_SPACE;
}
U0 ICArgPut(CICArg *a)
{
if (a->type_pointed)
"%Z %Z %Z ",
a->type&RT_MASK,"ST_IT_TYPES",
a->type_pointed&RT_MASK,"ST_IT_TYPES",
a->type>>4,"ST_TY_TYPES";
else
"%Z %Z ",
a->type&RT_MASK,"ST_IT_TYPES",
a->type>>4,"ST_TY_TYPES";
switch (a->type>>4) {
case TY_STK>>4:
"STK";
break;
case TY_IMM>>4:
"#%X",a->disp;
break;
case TY_REG>>4:
"%Z",a->reg,"ST_U64_REGS";
break;
case TY_DISP>>4:
"%X[%Z]",a->disp,a->reg,"ST_U64_REGS";
break;
case TY_RIP_DISP32>>4:
"[%X]",a->disp;
break;
case TY_SIB>>4:
if (a->disp)
"%X",a->disp;
if (a->reg==REG_RIP)
'[';
else
"[%Z+",a->reg&15,"ST_U64_REGS";
"%Z",a->reg>>8&15,"ST_U64_REGS";
switch (a->reg>>14) {
case 0: "]"; break;
case 1: "*2]"; break;
case 2: "*4]"; break;
case 3: "*8]"; break;
}
break;
}
}
U0 ICPut(CIntermediateCode *tempi)
{
I64 opcode=tempi->ic_code,i;
if (opcode>=IC_END_EXP && opcode!=IC_NOP2) {
"%15ts %016X ",
DefineSub(opcode,"ST_INTERMEDIATE_CODE")+5,
tempi->ic_data;
if (tempi->r.type&TY_MASK) {
ICArgPut(&tempi->r);
"<-";
}
if (tempi->a1.type&TY_MASK)
ICArgPut(&tempi->a1);
',';
if (tempi->a2.type&TY_MASK)
ICArgPut(&tempi->a2);
'' CH_SPACE;
ICClassPut(tempi->ic_class);
if (tempi->ic_flags & ICF_LOCK)
"$$BROWN$$lock$$FG$$ ";
if (tempi->ic_flags & ICF_A2_TO_F64)
"$$LTBLUE$$a2d$$FG$$ ";
if (tempi->ic_flags & ICF_A2_TO_INT)
"$$GREEN$$a2i$$FG$$ ";
if (tempi->ic_flags & ICF_A1_TO_F64)
"$$LTBLUE$$a1d$$FG$$ ";
if (tempi->ic_flags & ICF_A1_TO_INT)
"$$GREEN$$a1i$$FG$$ ";
if (tempi->ic_flags & ICF_R_TO_F64)
"$$LTBLUE$$rd$$FG$$ ";
if (tempi->ic_flags & ICF_R_TO_INT)
"$$GREEN$$ri$$FG$$ ";
if (tempi->ic_flags & ICF_USE_F64)
"[F64] ";
if (tempi->ic_flags & ICF_USE_UNSIGNED)
"[unsigned] ";
if (tempi->ic_flags & ICF_USE_INT)
"[int] ";
if (tempi->ic_flags & ICF_NO_DEPEND_RESULT)
"-DEP ";
if (tempi->ic_flags & ICF_DEPEND_RESULT)
"+DEP ";
if (tempi->ic_flags & ICF_NOT_ADDR)
"NOT_ADDR ";
if (tempi->ic_flags & ICF_PUSH_RESULT)
"PUSH ";
if (tempi->ic_flags & ICF_PUSH_CMP)
"PUSH_CMP ";
if (tempi->ic_flags & ICF_POP_CMP)
"POP_CMP ";
if (tempi->ic_flags & ICF_DEL_PREVIOUS_INS)
"DELINS ";
for (i=0;i<3;i++) {
if (Bt(&tempi->ic_flags,ICf_DONT_PUSH_FLOAT0+i))
"DONT_PUSH#%d ",i;
if (Bt(&tempi->ic_flags,ICf_DONT_POP_FLOAT0+i))
"DONT_POP#%d ",i;
}
if (tempi->ic_flags & ICF_ALTERNATE_TEMPLATE)
"ALT_TEMP ";
NewLine;
}
}
U0 LCCQuePut(CLex *lx)
{
CIntermediateCode *tempi=lx->lcc.lcc_root.next;
while (tempi->ic_code) {
if (tempi->ic_flags&ICF_TRACE)
ICPut(tempi);
tempi=tempi->next;
}
}
U0 LCCInit(CLex *lx)
{
CLexCodeCtrl *tempcbh=&lx->lcc;
QueInit(&tempcbh->lcc_root.next);
QueInit(&tempcbh->lcc_next_misc);
tempcbh->lcc_root.ic_code=IC_END;
}
CIntermediateCode *LCCAdd(CLex *lx,
I64 opcode_and_precedence,I64 arg, CHashClass *c,I64 flags=0)
{
CIntermediateCode *tempi=MAlloc(sizeof(CIntermediateCode));
tempi->ic_code=opcode_and_precedence.u16[0];
tempi->ic_precedence=opcode_and_precedence.u16[1];
tempi->ic_data=arg;
tempi->ic_class=c;
if (Bt(&lx->opts,OPTf_OPT_TRACE)) {
Bts(&lx->flags,Lf_OPT_TRACE_PRESENT);
flags|=ICF_TRACE;
}
if (lx->lock_cnt)
flags|=ICF_LOCK;
tempi->ic_flags=flags;
tempi->ic_line=lx->last_line_num;
QueIns(tempi,lx->lcc.lcc_root.last);
return tempi;
}
U0 LCCPush(CLex *lx)
{
CLexCodeCtrl *tempcbh=MAlloc(sizeof(CLexCodeCtrl));
MemCpy(tempcbh,&lx->lcc,sizeof(CLexCodeCtrl));
lx->lcc.lcc_next=tempcbh;
}
CLex *LCCPopNoFree(CLex *lx)
{
CLexCodeCtrl *tempcbh=lx->lcc.lcc_next;
MemCpy(&lx->lcc,tempcbh,sizeof(CLexCodeCtrl));
return tempcbh;
}
U0 LCCPop(CLex *lx)
{
Free(LCCPopNoFree(lx));
}
U0 LCCAppend(CLex *lx, CLexCodeCtrl *tempcbh)
{
if (tempcbh->lcc_root.next!=&lx->lcc.lcc_root.next) {
lx->lcc.lcc_root.last->next=tempcbh->lcc_root.next;
tempcbh->lcc_root.next->last=lx->lcc.lcc_root.last;
lx->lcc.lcc_root.last=tempcbh->lcc_root.last;
tempcbh->lcc_root.last->next=&lx->lcc.lcc_root.next;
}
if (tempcbh->lcc_next_misc!=&lx->lcc.lcc_next_misc) {
lx->lcc.lcc_last_misc->next=tempcbh->lcc_next_misc;
tempcbh->lcc_next_misc->last=lx->lcc.lcc_last_misc;
lx->lcc.lcc_last_misc=tempcbh->lcc_last_misc;
tempcbh->lcc_last_misc->next=&lx->lcc.lcc_next_misc;
}
Free(tempcbh);
}
CLexCodeMisc *LCCMiscNew(CLex *lx,I64 ty)
{
CLexCodeMisc *result=CAlloc(sizeof(CLexCodeMisc));
result->addr=INVALID_PTR;
result->type=ty;
QueIns(result,lx->lcc.lcc_last_misc);
return result;
}
CLexCodeMisc *LCCGoToLabelFind(CLex *lx,U8 *name)
{
CLexCodeMisc *mc=lx->lcc.lcc_next_misc;
while (mc!=&lx->lcc.lcc_next_misc) {
if ((mc->type==CMT_GOTO_LABEL||mc->type==CMT_ASM_LABEL) &&
!StrCmp(mc->str,name))
return mc;
mc=mc->next;
}
return NULL;
}
I64 LCCFloatConstFind(CLex *lx,F64 d)
{
I64 i;
CLexCodeMisc *mc=lx->lcc.lcc_next_misc;
while (mc!=&lx->lcc.lcc_next_misc) {
if (mc->type==CMT_FLOAT_CONSTS) {
for (i=0;i<mc->num_consts;i++)
if (mc->float_consts[i]==d)
return mc->addr+i*sizeof(F64);
if (mc->num_consts<CM_MAX_CONSTS) {
mc->float_consts[mc->num_consts++]=d;
return mc->addr+i*sizeof(F64);
}
}
mc=mc->next;
}
mc=LCCMiscNew(lx,CMT_FLOAT_CONSTS);
mc->float_consts=MAlloc(CM_MAX_CONSTS*sizeof(F64));
mc->float_consts[mc->num_consts++]=d;
return mc->addr;
}
U0 LCCDel(CLex *lx,CLexCodeCtrl *lcc)
{
CLexCodeMisc *mc,*mc1;
U8 *undef=NULL;
QueDel(&lcc->lcc_root.next);
mc=lcc->lcc_next_misc;
while (mc!=&lcc->lcc_next_misc) {
mc1=mc->next;
switch (mc->type) {
case CMT_GOTO_LABEL:
case CMT_ASM_LABEL:
if (!(mc->flags&CMF_DEFINED)) {
undef=mc->str;
mc->str=NULL;
} else if (!mc->use_cnt) {
PrintWarn("Unused label %s\n",mc->str);
LexWarn(lx,"Unused label at ");
}
break;
case CMT_JMP_TABLE:
Free(mc->jmp_table);
break;
case CMT_FLOAT_CONSTS:
Free(mc->float_consts);
break;
case CMT_ARRAY_DIM:
LinkedLstDel(mc->dim);
break;
case CMT_HASH_ENTRY:
HashDel(mc->h);
break;
}
Free(mc->str);
Free(mc);
mc=mc1;
}
if (undef) {
PrintErr("Undefined goto label %s\n",undef);
Free(undef);
LexExcept(lx,"Undefined goto label at ");
}
}
U0 LCCHeaderPut(CLex *lx,I64 pass,Bool put)
{
if (Bt(&lx->flags,Lf_OPT_TRACE_PRESENT)) {
if (put) {
if (Bt(&lx->pass_trace_mask,pass-1)) {
"$$IV,1$$Pass %d:$$IV,0$$\n",pass-1;
LCCQuePut(lx);
}
} else if (Bt(&lx->pass_trace_mask,pass))
"$$IV,1$$Pass %d:$$IV,0$$\n",pass;
}
lx->pass=pass;
}
U8 *LCCCompile(CLex *lx,I64 *_code_size,CDbgInfo **_dbg,I64 *_type)
{
U8 *result;
CLexCodeMisc *lb;
I64 i,code_size,last_code_size;
COptReg reg_offsets[NUM_REGS];
if (_dbg) *_dbg=NULL;
LCCHeaderPut(lx,1,TRUE);
OptPass012(lx);
LCCHeaderPut(lx,2,TRUE);
OptPass012(lx);
LCCHeaderPut(lx,3,TRUE);
OptPass3(lx,reg_offsets);
LCCHeaderPut(lx,4,TRUE);
OptPass4(lx,reg_offsets,_type);
LCCHeaderPut(lx,5,TRUE);
OptPass5(lx);
LCCHeaderPut(lx,6,TRUE);
OptPass6(lx);
LCCHeaderPut(lx,7,TRUE);
lb=lx->lcc.lcc_next_misc;
while (lb!=&lx->lcc.lcc_next_misc) {
if (lb->type==CMT_JMP_TABLE) {
for (i=0;i<lb->range;i++)
lb->jmp_table[i]=OptLabelFwd(lb->jmp_table[i]);
lb->dft=OptLabelFwd(lb->dft);
}
lb=lb->next;
}
LCCHeaderPut(lx,7,FALSE);
code_size=OptPass789(lx,reg_offsets,NULL,NULL);
do {
last_code_size=code_size;
LCCHeaderPut(lx,8,FALSE);
code_size=OptPass789(lx,reg_offsets,NULL,NULL);
if (code_size>last_code_size) {
"Pass:8 Code Size\n";
LexExcept(lx,"Compiler Optimization Error at ");
}
} while (code_size<last_code_size);
if (lx->flags&LF_AOT_COMPILE)
result=MAlloc(code_size);
else
result=MAlloc(code_size,Fs->code_heap);
LCCHeaderPut(lx,9,FALSE);
code_size=OptPass789(lx,reg_offsets,result,_dbg);
compiled_bytes+=code_size;
LCCDel(lx,&lx->lcc);
if (Bt(&lx->opts,OPTf_COMPILE_TRACE)) {
if (lx->flags&LF_AOT_COMPILE) {
if (lx->a->seg_size==16)
Un(result,code_size,16);
else if (lx->a->seg_size==64)
Un(result,code_size,64);
else
Un(result,code_size,32);
} else
Un(result,code_size,64);
}
if (_code_size) *_code_size=code_size;
return result;
}
+1630
View File
File diff suppressed because it is too large. Load diff
+1429
View File
File diff suppressed because it is too large. Load diff
+580
View File
@@ -0,0 +1,580 @@
CLexCodeMisc *OptLabelFwd(CLexCodeMisc *lb)
{
CLexCodeMisc *lb1;
while (lb1=lb->fwd)
lb=lb1;
return lb;
}
CHashClass *OptClassFwd(CHashClass *tempc)
{
CHashClass *tempc1;
while (tempc1=tempc->fwd_class)
tempc=tempc1;
return tempc;
}
U0 OptSetNOP1(CIntermediateCode *tempi)
{
tempi->ic_code=IC_NOP1;
tempi->ic_flags=0;
tempi->a1.type=TY_NULL+tempi->a1.type&RT_MASK;
tempi->r.type =TY_NULL+tempi->r.type &RT_MASK;
}
U0 OptSetNOP2(CIntermediateCode *tempi,I64 stk_delta=1)
{
tempi->ic_code=IC_NOP2;
tempi->ic_data=stk_delta;
tempi->a1.type=TY_NULL+tempi->a1.type&RT_MASK;
tempi->r.type =TY_NULL+tempi->r.type &RT_MASK;
}
CIntermediateCode *OptFree(CIntermediateCode *tempi)
{ //We might access freed entries in CICTreeLinks
QueRem(tempi);
Free(tempi);
return NULL;
}
CIntermediateCode *OptLag(CIntermediateCode *tempi)
{
do {
if (!tempi->ic_code)
return NULL;
else
tempi=tempi->last;
} while (tempi->ic_code<=IC_END_EXP);
return tempi;
}
CIntermediateCode *OptLag1(CIntermediateCode *tempi)
{
do {
if (!tempi->ic_code)
return NULL;
else
tempi=tempi->last;
} while (tempi->ic_code==IC_NOP1||tempi->ic_code==IC_NOP2);
return tempi;
}
CIntermediateCode *OptLag2(CIntermediateCode *tempi)
{
do {
if (!tempi->ic_code)
return NULL;
else
tempi=tempi->last;
} while (tempi->ic_code<IC_END_EXP);
return tempi;
}
CIntermediateCode *OptLead1(CIntermediateCode *tempi)
{
do {
tempi=tempi->next;
if (!tempi->ic_code)
return NULL;
} while (tempi->ic_code==IC_NOP1||tempi->ic_code==IC_NOP2);
return tempi;
}
I64 CmpOffset2Reg(I64 offset,COptReg *reg_offsets)
{
I64 i;
for (i=0;i<NUM_REGS;i++)
if (offset==reg_offsets[i].offset)
return i;
return -1;
}
#define FBO1_NOT_CONST 0
#define FBO1_INT 1
#define FBO1_F64 2
Bool OptFixupBinaryOp1(CIntermediateCode *tempi,
CIntermediateCode *tempi1,CIntermediateCode *tempi2,
Bool *is_unsigned)
{
CHashClass *tempc=tempi->ic_class,*tempc1,*tempc2;
if (tempi1->ic_flags&ICF_R_TO_INT)
tempc1=sys_internal_types[RT_I64];
else if (tempi1->ic_flags&ICF_R_TO_F64)
tempc1=sys_internal_types[RT_F64];
else {
tempc1=OptClassFwd(tempi1->ic_class);
}
if (tempi2->ic_flags&ICF_R_TO_INT)
tempc2=sys_internal_types[RT_I64];
else if (tempi2->ic_flags&ICF_R_TO_F64)
tempc2=sys_internal_types[RT_F64];
else {
tempc2=OptClassFwd(tempi2->ic_class);
}
if (tempc1->raw_type>tempc2->raw_type)
tempc=tempi->ic_class=tempc1;
else
tempc=tempi->ic_class=tempc2;
if (tempc->raw_type==RT_F64) {
if (tempi1->ic_code==IC_IMM_U64) {
tempi1->ic_data(F64)=tempi1->ic_data;
tempi1->ic_class=sys_internal_types[RT_F64];
tempi1->ic_code=IC_IMM_F64;
tempi1->ic_flags&=~ICF_R_TO_F64;
} else
if (tempc1->raw_type!=RT_F64)
tempi1->ic_flags|=ICF_R_TO_F64;
if (tempi2->ic_code==IC_IMM_U64) {
tempi2->ic_data(F64)=tempi2->ic_data;
tempi2->ic_class=sys_internal_types[RT_F64];
tempi2->ic_code=IC_IMM_F64;
tempi2->ic_flags&=~ICF_R_TO_F64;
} else
if (tempc2->raw_type!=RT_F64)
tempi2->ic_flags|=ICF_R_TO_F64;
if (tempi1->ic_code==IC_IMM_F64 &&
tempi2->ic_code==IC_IMM_F64 &&
!(tempi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags;
OptSetNOP1(tempi1);
OptSetNOP1(tempi2);
return FBO1_F64;
} else
return FBO1_NOT_CONST;
}
*is_unsigned=tempc1->raw_type&1 || tempc2->raw_type&1;
if (tempi1->ic_code==IC_IMM_U64 &&
tempi2->ic_code==IC_IMM_U64 &&
!(tempi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
tempi->ic_flags|=tempi1->ic_flags|tempi2->ic_flags;
OptSetNOP1(tempi1);
OptSetNOP1(tempi2);
return FBO1_INT;
} else
return FBO1_NOT_CONST;
}
Bool OptFixupBinaryOp2(CIntermediateCode **tempi1,CIntermediateCode **tempi2)
{
CIntermediateCode *tempii1=*tempi1,
*tempii2=*tempi2;
if (tempii1->ic_code==IC_IMM_U64 &&
!(tempii1->ic_flags & ICF_R_TO_F64))
return TRUE;
if (tempii2->ic_code==IC_IMM_U64 &&
!(tempii2->ic_flags & ICF_R_TO_F64)) {
*tempi1=tempii2;
*tempi2=tempii1;
return TRUE;
}
return FALSE;
}
Bool OptFixupUnaryOp(CIntermediateCode *tempi,
CIntermediateCode *tempi1,
Bool *is_unsigned)
{
CHashClass *tempc,*tempc1;
tempc1=OptClassFwd(tempi1->ic_class);
tempi->ic_class=tempc1;
tempc=tempi->ic_class;
if (tempc->raw_type==RT_F64) {
if (tempi1->ic_code==IC_IMM_U64) {
tempi1->ic_data(F64)=tempi1->ic_data;
tempi1->ic_class=sys_internal_types[RT_F64];
tempi1->ic_code=IC_IMM_F64;
tempi1->ic_flags&=~ICF_R_TO_F64;
} else
if (tempc1->raw_type!=RT_F64)
tempi1->ic_flags|=ICF_R_TO_F64;
if (tempi1->ic_code==IC_IMM_F64) {
tempi->ic_flags|=tempi1->ic_flags;
OptSetNOP1(tempi1);
return FBO1_F64;
} else
return FBO1_NOT_CONST;
}
*is_unsigned=tempc1->raw_type&1;
if (tempi1->ic_code==IC_IMM_U64) {
tempi->ic_flags|=tempi1->ic_flags;
OptSetNOP1(tempi1);
return FBO1_INT;
} else
return FBO1_NOT_CONST;
}
extern U0 OptBrNotZero(CLex *lx,CIntermediateCode *tempi);
CIntermediateCode *OptBrZero(CLex *lx,CIntermediateCode *tempi)
{
CLexCodeMisc *lb_true,*lb_false;
CIntermediateCode *tempii=OptLag(tempi),*tempii2;
switch (tempii->ic_code) {
case IC_NOT:
tempi->ic_code=IC_BR_NOT_ZERO;
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->t.a1c=tempii->t.a1c;
tempi->t.a1t=tempii->t.a1t;
OptFree(tempii);
return OptBrNotZero(lx,tempi);
case IC_EQUAL_EQUAL:
tempi->ic_code=IC_BR_NOT_EQUAL;
break;
case IC_NOT_EQUAL:
tempi->ic_code=IC_BR_EQUAL_EQUAL;
break;
case IC_LESS:
tempi->ic_code=IC_BR_GREATER_EQUAL;
break;
case IC_GREATER:
tempi->ic_code=IC_BR_LESS_EQUAL;
break;
case IC_LESS_EQUAL:
tempi->ic_code=IC_BR_GREATER;
break;
case IC_GREATER_EQUAL:
tempi->ic_code=IC_BR_LESS;
break;
case IC_OR_OR:
tempi->ic_code=IC_BR_OR_OR_ZERO;
break;
case IC_AND_AND:
tempi->ic_code=IC_BR_AND_AND_ZERO;
break;
case IC_AND:
tempi->ic_code=IC_BR_AND_ZERO;
break;
case IC_MM_:
if (lx->pass==2 && !(tempii->ic_flags&ICF_R_TO_F64) &&
tempii->ic_class->raw_type!=RT_F64)
tempi->ic_code=IC_BR_MM_ZERO;
break;
case IC_CALL_END:
tempii2=OptLag(tempii);
switch (tempii2->ic_code) {
sub_switch_start:
case IC_CARRY:
tempii2->ic_code=IC_BR_NOT_CARRY;
break;
case IC_BT:
tempii2->ic_code=IC_BR_NOT_BT;
break;
case IC_BTS:
tempii2->ic_code=IC_BR_NOT_BTS;
break;
case IC_BTR:
tempii2->ic_code=IC_BR_NOT_BTR;
break;
case IC_BTC:
tempii2->ic_code=IC_BR_NOT_BTC;
break;
case IC_LBTS:
tempii2->ic_code=IC_BR_NOT_LBTS;
tempii2->ic_flags|=ICF_LOCK;
break;
case IC_LBTR:
tempii2->ic_code=IC_BR_NOT_LBTR;
tempii2->ic_flags|=ICF_LOCK;
break;
case IC_LBTC:
tempii2->ic_code=IC_BR_NOT_LBTC;
tempii2->ic_flags|=ICF_LOCK;
break;
sub_switch_end:
tempii2->ic_data=tempi->ic_data;
tempii->ic_code=IC_CALL_END2;
OptSetNOP1(tempi);
return tempii;
}
break;
}
if (tempi->ic_code!=IC_BR_ZERO) {
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->t.a1c=tempii->t.a1c;
tempi->t.a2c=tempii->t.a2c;
tempi->t.a1t=tempii->t.a1t;
tempi->t.a2t=tempii->t.a2t;
OptFree(tempii);
if (tempi->ic_flags&ICF_PUSH_CMP &&
IC_BR_NOT_EQUAL<=tempi->ic_code<=IC_BR_LESS &&
!(tempi->ic_flags&ICF_USE_F64)) {
tempi->ic_code+=IC_BR_NOT_EQUAL2-IC_BR_NOT_EQUAL;
tempi->ic_flags&=~ICF_PUSH_CMP;
tempii =tempi->next; //IC_PUSH_CMP instruction
while (tempii->ic_code!=IC_PUSH_CMP)
tempii=tempii->next;
tempii->t.a1t=tempi;
OptSetNOP1(tempii);
}
lb_true=tempi->ic_data;
if (tempi->ic_code==IC_BR_AND_AND_ZERO) {
tempii=tempi->t.a1t->next;
tempii->ic_data=lb_true;
tempii->t.a1t=tempi->t.a1t;
tempii->t.a1c=tempi->t.a1c;
tempii->ic_code=IC_BR_ZERO;
OptBrZero(lx,tempii);
tempii=tempi->t.a2t->next;
tempii->t.a1t=tempi->t.a2t;
tempii->t.a1c=tempi->t.a2c;
tempii->ic_data=lb_true;
tempii->ic_code=IC_BR_ZERO;
tempii=OptBrZero(lx,tempii);
OptSetNOP1(tempi);
} else if (tempi->ic_code==IC_BR_OR_OR_ZERO) {
lb_false=LCCMiscNew(lx,CMT_LABEL);
tempi->ic_code=IC_LABEL;
tempi->ic_flags=0;
tempi->ic_data=lb_false;
tempii=tempi->t.a1t->next;
tempii->t.a1t=tempi->t.a1t;
tempii->t.a1c=tempi->t.a1c;
tempii->ic_data=lb_false;
tempii->ic_code=IC_BR_NOT_ZERO;
OptBrNotZero(lx,tempii);
tempii=tempi->t.a2t->next;
tempii->t.a1t=tempi->t.a2t;
tempii->t.a1c=tempi->t.a2c;
tempii->ic_data=lb_true;
tempii->ic_code=IC_BR_ZERO;
tempii=OptBrZero(lx,tempii);
} else
tempii=tempi;
if (tempi->ic_flags&ICF_POP_CMP && tempi->t.a1t->ic_code==IC_NOP1) {
tempi->t.a1t=tempi->t.a1t->t.a1t;
tempi->ic_flags&=~ICF_POP_CMP;
}
return tempii;
}
return tempi;
}
CIntermediateCode *OptBrNotZero(CLex *lx,CIntermediateCode *tempi)
{
CLexCodeMisc *lb_true,*lb_false;
CIntermediateCode *tempii=OptLag(tempi),*tempii2;
switch (tempii->ic_code) {
case IC_NOT:
tempi->ic_code=IC_BR_ZERO;
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->t.a1c=tempii->t.a1c;
tempi->t.a1t=tempii->t.a1t;
OptFree(tempii);
return OptBrZero(lx,tempi);
case IC_EQUAL_EQUAL:
tempi->ic_code=IC_BR_EQUAL_EQUAL;
break;
case IC_NOT_EQUAL:
tempi->ic_code=IC_BR_NOT_EQUAL;
break;
case IC_LESS:
tempi->ic_code=IC_BR_LESS;
break;
case IC_GREATER:
tempi->ic_code=IC_BR_GREATER;
break;
case IC_LESS_EQUAL:
tempi->ic_code=IC_BR_LESS_EQUAL;
break;
case IC_GREATER_EQUAL:
tempi->ic_code=IC_BR_GREATER_EQUAL;
break;
case IC_OR_OR:
tempi->ic_code=IC_BR_OR_OR_NOT_ZERO;
break;
case IC_AND_AND:
tempi->ic_code=IC_BR_AND_AND_NOT_ZERO;
break;
case IC_AND:
tempi->ic_code=IC_BR_AND_NOT_ZERO;
break;
case IC_MM_:
if (lx->pass==2 && !(tempii->ic_flags&ICF_R_TO_F64) &&
tempii->ic_class->raw_type!=RT_F64)
tempi->ic_code=IC_BR_MM_NOT_ZERO;
break;
case IC_CALL_END:
tempii2=OptLag(tempii);
switch (tempii2->ic_code) {
sub_switch_start:
case IC_CARRY:
tempii2->ic_code=IC_BR_CARRY;
break;
case IC_BT:
tempii2->ic_code=IC_BR_BT;
break;
case IC_BTS:
tempii2->ic_code=IC_BR_BTS;
break;
case IC_BTR:
tempii2->ic_code=IC_BR_BTR;
break;
case IC_BTC:
tempii2->ic_code=IC_BR_BTC;
break;
case IC_LBTS:
tempii2->ic_code=IC_BR_LBTS;
tempii2->ic_flags|=ICF_LOCK;
break;
case IC_LBTR:
tempii2->ic_code=IC_BR_LBTR;
tempii2->ic_flags|=ICF_LOCK;
break;
case IC_LBTC:
tempii2->ic_code=IC_BR_LBTC;
tempii2->ic_flags|=ICF_LOCK;
break;
sub_switch_end:
tempii2->ic_data=tempi->ic_data;
tempii->ic_code=IC_CALL_END2;
OptSetNOP1(tempi);
return tempii;
}
break;
}
if (tempi->ic_code!=IC_BR_NOT_ZERO) {
tempi->ic_class=tempii->ic_class;
tempi->ic_flags|=tempii->ic_flags;
tempi->t.a1c=tempii->t.a1c;
tempi->t.a2c=tempii->t.a2c;
tempi->t.a1t=tempii->t.a1t;
tempi->t.a2t=tempii->t.a2t;
OptFree(tempii);
if (tempi->ic_flags&ICF_PUSH_CMP &&
IC_BR_NOT_EQUAL<=tempi->ic_code<=IC_BR_LESS &&
!(tempi->ic_flags&ICF_USE_F64)) {
tempi->ic_code+=IC_BR_NOT_EQUAL2-IC_BR_NOT_EQUAL;
tempi->ic_flags&=~ICF_PUSH_CMP;
tempii =tempi->next; //IC_PUSH_CMP instruction
while (tempii->ic_code!=IC_PUSH_CMP)
tempii=tempii->next;
tempii->t.a1t=tempi;
OptSetNOP1(tempii);
}
lb_true=tempi->ic_data;
if (tempi->ic_code==IC_BR_OR_OR_NOT_ZERO) {
tempii=tempi->t.a1t->next;
tempii->t.a1t=tempi->t.a1t;
tempii->t.a1c=tempi->t.a1c;
tempii->ic_data=lb_true;
tempii->ic_code=IC_BR_NOT_ZERO;
OptBrNotZero(lx,tempii);
tempii=tempi->t.a2t->next;
tempii->t.a1t=tempi->t.a2t;
tempii->t.a1c=tempi->t.a2c;
tempii->ic_data=lb_true;
tempii->ic_code=IC_BR_NOT_ZERO;
tempii=OptBrNotZero(lx,tempii);
OptSetNOP1(tempi);
} else if (tempi->ic_code==IC_BR_AND_AND_NOT_ZERO) {
lb_false=LCCMiscNew(lx,CMT_LABEL);
tempi->ic_code=IC_LABEL;
tempi->ic_flags=0;
tempi->ic_data=lb_false;
tempii=tempi->t.a1t->next;
tempii->t.a1t=tempi->t.a1t;
tempii->t.a1c=tempi->t.a1c;
tempii->ic_data=lb_false;
tempii->ic_code=IC_BR_ZERO;
OptBrZero(lx,tempii);
tempii=tempi->t.a2t->next;
tempii->t.a1t=tempi->t.a2t;
tempii->t.a1c=tempi->t.a2c;
tempii->ic_data=lb_true;
tempii->ic_code=IC_BR_NOT_ZERO;
tempii=OptBrNotZero(lx,tempii);
} else
tempii=tempi;
if (tempi->ic_flags&ICF_POP_CMP && tempi->t.a1t->ic_code==IC_NOP1) {
tempi->t.a1t=tempi->t.a1t->t.a1t;
tempi->ic_flags&=~ICF_POP_CMP;
}
return tempii;
}
return tempi;
}
U0 OptFixSizeOf(CIntermediateCode *tempi1,CIntermediateCode *tempi_push,CHashClass *tempcc)
{
if (tempi1->ic_code==IC_MUL &&
tempi1->t.a2t->ic_code==IC_SIZEOF) {
tempi1->t.a2t->ic_code=IC_IMM_U64;
tempi1->t.a2t->ic_class=tempcc;
tempi_push->ic_class=tempcc;
if (tempcc->ptr_cnt) {
tempcc--;
if (tempcc->size==1)
goto here;
tempi1->t.a2t->ic_data=tempcc->size;
} else {
here:
if (tempi_push==tempi1)
tempi1->t.a2t->ic_data=1;
else {
OptSetNOP1(tempi1->t.a2t);
OptSetNOP1(tempi1);
}
}
}
}
I64 CmpRawType(CHashClass *tempc)
{
if (tempc) {
tempc=OptClassFwd(tempc);
return tempc->raw_type;
}
return 0;
}
I64 CmpRawTypePointed(CHashClass *tempc)
{
if (tempc) {
if (tempc->ptr_cnt)
tempc--;
tempc=OptClassFwd(tempc);
return tempc->raw_type;
}
return 0;
}
U0 CmpF1PushPop(CIntermediateCode *tempi,CIntermediateCode *tempi2)
{
if (Bt(ic_bitmap_fpop,tempi2->ic_code)|| tempi2->ic_flags&ICF_R_TO_F64)
Bts(&tempi->ic_flags,ICf_DONT_PUSH_FLOAT0);
}
U0 CmpF2PushPop(CIntermediateCode *tempi,CIntermediateCode *tempi1,CIntermediateCode *tempi2)
{
if ((tempi2->ic_code==IC_MOV || tempi2->ic_code==IC_IMM_F64) &&
!(tempi2->ic_flags&ICF_R_TO_F64) &&
(Bt(ic_bitmap_fpop,tempi1->ic_code) || tempi1->ic_flags&ICF_R_TO_F64))
Bts(&tempi->ic_flags,ICf_DONT_PUSH_FLOAT0);
else if ((Bt(ic_bitmap_fpop,tempi2->ic_code) || tempi2->ic_flags&ICF_R_TO_F64)&&
!(tempi1->ic_flags&ICF_R_TO_F64))
Bts(&tempi->ic_flags,ICf_DONT_PUSH_FLOAT0);
}
class COptMemberVar
{
I64 score,offset_start,offset_end,lea_balance;
CMemberLst *m;
};
I64 OptMVCompare(COptMemberVar *mv1,COptMemberVar *mv2)
{
return mv2->score-mv1->score;
}
File diff suppressed because it is too large. Load diff
+601
View File
@@ -0,0 +1,601 @@
U0 OptPass3(CLex *lx,COptReg *reg_offsets)
{
CHashClass *tempc,*tempc1,*tempc2;
CLexCodeMisc *lb;
CIntermediateCode *tempi,*tempi1,*tempi2,*tempi_next,
*tempil1,*tempil2;
I64 code,i,j,l,member_cnt,used_reg_mask=0;
CMemberLst *tempm;
COptMemberVar *mv=NULL;
CPrsStk *ps=lx->ps;
ps->ptr=0;
ps->ptr2=0;
for (i=0;i<NUM_REGS;i++) {
reg_offsets[i].offset=MAX_I64;
reg_offsets[i].m=NULL;
}
if (lx->htc.fun) {
member_cnt=lx->htc.fun->member_cnt;
if (Bt(&lx->htc.fun->flags,Ff_DOT_DOT_DOT))
member_cnt+=2;
mv=CAlloc(member_cnt*sizeof(COptMemberVar));
member_cnt=0;
tempm=lx->htc.fun->member_lst;
while (tempm) {
tempc=OptClassFwd(tempm->member_class);
if (0<=tempm->reg<NUM_REGS) {
if (Bts(&used_reg_mask,tempm->reg))
PrintWarn("Reg in use\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
lx->cur_lfn->name,lx->cur_lfn->line_num,tempm->str,lx->htc.fun->str);
reg_offsets[tempm->reg].offset=tempm->offset;
reg_offsets[tempm->reg].m=tempm;
} else if (tempc->raw_type!=RT_F64 && tempm->reg!=REG_NONE ||
tempm->reg==REG_ALLOC) {
if (tempm->reg==REG_ALLOC)
mv[member_cnt].score=MAX_I64/2; //big but not too big
mv[member_cnt].offset_start=tempm->offset;
mv[member_cnt].offset_end=tempm->offset+MaxI64(1,tempm->size);
mv[member_cnt++].m=tempm;
} else {
if (tempm->reg==REG_ALLOC)
PrintWarn("Can't reg var\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
lx->cur_lfn->name,lx->cur_lfn->line_num,tempm->str,lx->htc.fun->str);
}
tempm=tempm->next;
}
} else
member_cnt=0;
tempi=lx->lcc.lcc_root.next;
while (code=tempi->ic_code) {
tempi_next=tempi->next;
if (code==IC_NOP1)
OptFree(tempi);
else {
if (tempil1=OptLag(tempi)) {
if (!(tempil2=OptLag(tempil1)))
tempil2=&opt_nop;
} else
tempil1=tempil2=&opt_nop;
tempc=tempi->ic_class;
nobound_switch (cmp_arg_cnt[code]) {
case 9:
ps->ptr-=tempi->ic_data>>3;
break;
case 2:
tempi2=PrsPop(ps);
if (tempi2->ic_flags&ICF_R_TO_F64)
tempc2=sys_internal_types[RT_F64];
else if (tempi2->ic_flags & ICF_R_TO_INT)
tempc2=sys_internal_types[RT_I64];
else
tempc2=tempi->t.a2c;
tempi->a2.type=TY_STK+CmpRawType(tempc2);
tempi->a2.type_pointed=CmpRawTypePointed(tempc2);
tempi->ic_flags|=ICF_A2_WAS_STK;
case 1:
tempi1=PrsPop(ps);
if (tempi1->ic_flags&ICF_R_TO_F64)
tempc1=sys_internal_types[RT_F64];
else if (tempi1->ic_flags & ICF_R_TO_INT)
tempc1=sys_internal_types[RT_I64];
else
tempc1=tempi->t.a1c;
tempi->a1.type=TY_STK+CmpRawType(tempc1);
tempi->a1.type_pointed=CmpRawTypePointed(tempc1);
tempi->ic_flags|=ICF_A1_WAS_STK;
break;
case 0: //nobound_switch
break;
}
if (cmp_result_cnt[code]) {
tempi->r.type=TY_STK+CmpRawType(tempc);
tempi->r.type_pointed=CmpRawTypePointed(tempc);
tempi->ic_flags|=ICF_R_WAS_STK;
PrsPush(ps,tempi);
}
nobound_switch (code) {
case IC_IMM_F64:
tempi->ic_flags&=~ICF_R_TO_F64;
if (tempi->ic_flags&ICF_R_TO_INT) {
tempi->ic_data=ToI64(tempi->ic_data(F64));
tempi->ic_flags&=~ICF_R_TO_INT;
tempi->ic_code=IC_IMM_U64;
}
break;
case IC_IMM_U64:
tempi->ic_flags&=~ICF_R_TO_INT;
if (tempi->ic_flags&ICF_R_TO_F64) {
tempi->ic_data(F64)=ToF64(tempi->ic_data);
tempi->ic_flags&=~ICF_R_TO_F64;
tempi->ic_code=IC_IMM_F64;
}
break;
case IC_RBP:
tempi->ic_code=IC_REG;
tempi->a1.reg=REG_RBP;
break;
case IC_DEREF:
tempi->a1.type_pointed=tempi->r.type&RT_MASK;
if (tempi1->ic_code==IC_LEA) {
tempi->ic_flags|=tempi1->ic_flags;
tempi->a1.reg=tempi1->a1.reg;
tempi->a1.disp=tempi1->a1.disp;
tempi->a1.type=TY_DISP+tempi->r.type&RT_MASK;
tempi->a1.type_pointed=tempi->r.type_pointed;
tempi->ic_code=IC_MOV;
OptFree(tempi1);
if (tempi->a1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tempi->a1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
} else if (tempil1->ic_code==IC_ADD_CONST) {
if (tempil2->ic_code==IC_REG) {
tempi->ic_flags|=tempil2->ic_flags|tempil1->ic_flags;
tempi->a1.reg=tempil2->a1.reg;
tempi->a1.disp=tempi->ic_data;
tempi->a1.type=TY_DISP+tempi->r.type&RT_MASK;
tempi->a1.type_pointed=tempi->r.type_pointed;
tempi->ic_code=IC_MOV;
OptFree(tempil2);
OptFree(tempil1);
}
}
break;
case IC__PP:
case IC__MM:
case IC_PP_:
case IC_MM_:
tempi->r.type_pointed=CmpRawTypePointed(tempi->t.a1c);
case IC_DEREF_PP:
case IC_DEREF_MM:
if (tempi1->ic_code==IC_LEA &&
tempi1->a1.type&TY_MASK==TY_DISP &&
tempi1->a1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tempi1->a1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
tempi->a1.type_pointed=tempi->r.type&RT_MASK;
break;
case IC_MUL:
case IC_DIV:
if (tempc->raw_type==RT_F64) {
CmpF2PushPop(tempi,tempi1,tempi2);
break;
}
break;
case IC_ADD:
if (tempc->raw_type==RT_F64) {
CmpF2PushPop(tempi,tempi1,tempi2);
break;
}
if (OptFixupBinaryOp2(&tempi1,&tempi2)) {
tempi->ic_flags|=tempi1->ic_flags;
if (tempi->t.a1t!=tempi2)
tempi->t.a1c=tempi->t.a2c;
tempi->ic_data=tempi1->ic_data;
tempi->ic_code=IC_ADD_CONST;
tempi->a1.type_pointed=tempi->r.type&RT_MASK;
tempi->a2.type=TY_NULL;
OptFree(tempi1);
if (tempil2->ic_code==IC_REG &&
tempil2->a1.reg==REG_RBP) {
tempi->ic_flags|=tempil2->ic_flags;
tempi->ic_code=IC_LEA;
tempi->a1.reg=REG_RBP;
tempi->a1.type=TY_DISP+tempi->a1.type&RT_MASK;
tempi->a1.disp=tempi->ic_data;
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start<=tempi->ic_data<mv[i].offset_end) {
mv[i].lea_balance++;
mv[i].score++;
break;
}
OptFree(tempil2);
}
}
break;
case IC_SUB:
if (tempc->raw_type==RT_F64) {
CmpF2PushPop(tempi,tempi1,tempi2);
break;
}
if (tempi2->ic_code==IC_IMM_U64) {
tempi->ic_flags|=tempi2->ic_flags;
tempi->ic_data=tempi2->ic_data;
tempi->ic_code=IC_SUB_CONST;
tempi->a2.type=TY_NULL;
OptFree(tempi2);
}
break;
case IC_LESS:
case IC_GREATER:
case IC_LESS_EQUAL:
case IC_GREATER_EQUAL:
if (tempi->ic_flags&ICF_USE_F64)
CmpF2PushPop(tempi,tempi1,tempi2);
break;
case IC_MUL_EQUAL:
case IC_DIV_EQUAL:
case IC_ADD_EQUAL:
case IC_SUB_EQUAL:
if (tempc->raw_type==RT_F64)
CmpF1PushPop(tempi,tempi2);
case IC_ASSIGN_PP:
case IC_ASSIGN_MM:
case IC_ASSIGN:
case IC_SHL_EQUAL:
case IC_SHR_EQUAL:
case IC_MOD_EQUAL:
case IC_AND_EQUAL:
case IC_OR_EQUAL:
case IC_XOR_EQUAL:
if (tempi1->ic_code==IC_LEA &&
tempi1->a1.type&TY_MASK==TY_DISP &&
tempi1->a1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tempi1->a1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
tempi->a1.type_pointed=tempi->r.type&RT_MASK;
tempi->r.type_pointed=CmpRawTypePointed(tempi->t.a1c);
break;
case IC_RETURN_VAL:
case IC_RETURN_VAL2:
if (tempc) {
if (tempc->raw_type==RT_F64 && tempil1->ic_class->raw_type!=RT_F64)
tempil1->ic_flags|=ICF_R_TO_F64;
else if (tempc->raw_type!=RT_F64 && tempil1->ic_class->raw_type==RT_F64)
tempil1->ic_flags|=ICF_R_TO_INT;
}
break;
case IC_SQR:
case IC_ABS:
case IC_SQRT:
case IC_SIN:
case IC_COS:
case IC_TAN:
case IC_ATAN:
if (tempc->raw_type==RT_F64)
CmpF1PushPop(tempi,tempi1);
break;
case IC_NOBOUND_SWITCH:
case IC_SWITCH:
lb=OptLabelFwd(tempi->ic_data(CLexCodeMisc *)->dft);
lb->use_cnt++;
break;
case IC_BR_NOT_EQUAL:
case IC_BR_EQUAL_EQUAL:
if ((tempi1->ic_code==IC_IMM_U64 || tempi1->ic_code==IC_IMM_F64) && !tempi1->ic_data) {
OptFree(tempi1);
MemCpy(&tempi->a1,&tempi->a2,sizeof(CICArg));
tempi->a2.type=TY_NULL;
if (code==IC_BR_EQUAL_EQUAL)
code=tempi->ic_code=IC_BR_ZERO;
else
code=tempi->ic_code=IC_BR_NOT_ZERO;
tempi1=tempi2;
tempc1=tempc2;
} else if ((tempi2->ic_code==IC_IMM_U64 || tempi2->ic_code==IC_IMM_F64) && !tempi2->ic_data) {
OptFree(tempi2);
tempi->a2.type=TY_NULL;
if (code==IC_BR_EQUAL_EQUAL)
code=tempi->ic_code=IC_BR_ZERO;
else
code=tempi->ic_code=IC_BR_NOT_ZERO;
} else
goto here1;
case IC_BR_ZERO:
case IC_BR_NOT_ZERO:
if (tempi1->ic_code==IC_IMM_U64 || tempi1->ic_code==IC_IMM_F64) {
if (code==IC_BR_ZERO ^^ tempi1->ic_data) {
OptFree(tempi1);
tempi->a1.type=TY_NULL;
tempi->ic_code=IC_JMP;
} else {
OptFree(tempi1);
tempi=OptFree(tempi);
break;
}
}
goto here1;
case IC_BR_AND_ZERO:
if (tempi1->ic_code==IC_IMM_U64) {
i=Bsr(tempi1->ic_data);
if (0<=i==Bsf(tempi1->ic_data)) {
tempi1->ic_data=i;
tempi->ic_flags|=ICF_NOT_ADDR;
tempi->ic_code=IC_BR_NOT_BT;
goto here1;
}
}
if (tempi2->ic_code==IC_IMM_U64) {
i=Bsr(tempi2->ic_data);
if (0<=i==Bsf(tempi2->ic_data)) {
tempi2->ic_data=i;
tempi->ic_flags|=ICF_SWAP|ICF_NOT_ADDR;
tempi->ic_code=IC_BR_NOT_BT;
}
}
goto here1;
case IC_BR_AND_NOT_ZERO:
if (tempi1->ic_code==IC_IMM_U64) {
i=Bsr(tempi1->ic_data);
if (0<=i==Bsf(tempi1->ic_data)) {
tempi1->ic_data=i;
tempi->ic_flags|=ICF_NOT_ADDR;
tempi->ic_code=IC_BR_BT;
goto here1;
}
}
if (tempi2->ic_code==IC_IMM_U64) {
i=Bsr(tempi2->ic_data);
if (0<=i==Bsf(tempi2->ic_data)) {
tempi2->ic_data=i;
tempi->ic_flags|=ICF_SWAP|ICF_NOT_ADDR;
tempi->ic_code=IC_BR_BT;
}
}
goto here1;
case IC_BR_MM_ZERO:
case IC_BR_MM_NOT_ZERO:
if (tempi1->ic_code==IC_LEA &&
tempi1->a1.type&TY_MASK==TY_DISP &&
tempi1->a1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tempi1->a1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
tempi->a1.type_pointed=CmpRawType(tempc);
goto here1;
case IC_BR_GREATER_EQUAL:
case IC_BR_LESS_EQUAL:
case IC_BR_GREATER:
case IC_BR_LESS:
if (tempi->ic_flags&ICF_USE_F64)
CmpF2PushPop(tempi,tempi1,tempi2);
case IC_BR_CARRY:
case IC_BR_NOT_CARRY:
case IC_BR_GREATER_EQUAL2:
case IC_BR_LESS_EQUAL2:
case IC_BR_GREATER2:
case IC_BR_LESS2:
case IC_BR_NOT_EQUAL2:
case IC_BR_EQUAL_EQUAL2:
case IC_GET_LABEL:
case IC_BR_BT:
case IC_BR_BTS:
case IC_BR_BTR:
case IC_BR_BTC:
case IC_BR_NOT_BT:
case IC_BR_NOT_BTS:
case IC_BR_NOT_BTR:
case IC_BR_NOT_BTC:
case IC_BR_LBTS:
case IC_BR_LBTR:
case IC_BR_LBTC:
case IC_BR_NOT_LBTS:
case IC_BR_NOT_LBTR:
case IC_BR_NOT_LBTC:
case IC_JMP:
case IC_SUB_CALL:
here1:
if (tempi->ic_flags&ICF_PUSH_CMP)
lb=tempi->ic_data;
else
lb=OptLabelFwd(tempi->ic_data);
lb->use_cnt++;
break;
case IC_NOP1:
tempi=OptFree(tempi);
break;
case IC_NOP2:
ps->ptr+=tempi->ic_data;
break;
case IC_SHL_CONST:
case IC_SHR_CONST:
case IC_ENTER:
case IC_ADD_RSP:
case IC_ADD_RSP1:
case IC_CALL:
case IC_CALL_INDIRECT:
case IC_CALL_INDIRECT2:
case IC_CALL_EXTERN:
case IC_CALL_IMPORT:
case IC_PUSH:
case IC_POP:
case IC_INVLPG:
case IC_CLFLUSH:
case IC_GET_RFLAGS:
case IC_CARRY:
case IC_RDTSC:
case IC_HPET:
case IC_SET_RFLAGS:
case IC_GET_RBP:
case IC_SET_RBP:
case IC_GET_RSP:
case IC_GET_RAX:
case IC_SET_RSP:
case IC_SET_RAX:
case IC_ABS_ADDR:
case IC_HEAP_GLBL:
case IC_ADDR_IMPORT:
case IC_TYPE:
case IC_BT:
case IC_BTS:
case IC_BTR:
case IC_BTC:
case IC_LBTS:
case IC_LBTR:
case IC_LBTC:
case IC_BSF:
case IC_BSR:
case IC_PREEMPT:
case IC_SIGN_I64:
case IC_TOUPPER:
case IC_TO_I64:
case IC_TO_F64:
case IC_TO_BOOL:
case IC_ABS_I64:
case IC_MIN_I64:
case IC_MAX_I64:
case IC_MIN_U64:
case IC_MAX_U64:
case IC_MOD_U64:
case IC_SQR_I64:
case IC_SQR_U64:
case IC_SWAP_U8:
case IC_SWAP_U16:
case IC_SWAP_U32:
case IC_SWAP_U64:
case IC_QUE_INIT:
case IC_QUE_INS:
case IC_QUE_INS_REV:
case IC_QUE_REM:
case IC_IN_U32:
case IC_IN_U16:
case IC_IN_U8:
case IC_STRLEN:
case IC_OUT_U32:
case IC_OUT_U16:
case IC_OUT_U8:
case IC_ASM:
case IC_STR_CONST:
case IC_FS:
case IC_GS:
case IC_MOV_FS:
case IC_MOV_GS:
case IC_RIP:
case IC_PUSH_CMP:
case IC_REG:
case IC_COM:
case IC_HOLYC_TYPECAST:
case IC_NOT:
case IC_UNARY_MINUS:
case IC_POWER:
case IC_SHL:
case IC_SHR:
case IC_MOD:
case IC_AND:
case IC_OR:
case IC_XOR:
case IC_EQUAL_EQUAL:
case IC_NOT_EQUAL:
case IC_AND_AND:
case IC_OR_OR:
case IC_XOR_XOR:
case IC_LEAVE:
case IC_RET:
case IC_ADDR:
case IC_END:
case IC_END_EXP:
case IC_CALL_END:
case IC_CALL_END2:
case IC_CALL_START:
case IC_PUSH_REGS:
case IC_POP_REGS:
case IC_LABEL:
break;
default:
"Pass:%d Missing IC handler\n",lx->pass;
ICPut(tempi);
LexExcept(lx,"Compiler Optimization Error at ");
}
}
tempi=tempi_next;
}
if (lx->htc.fun) {
lx->htc.fun->used_reg_mask=lx->htc.fun->used_reg_mask&~(REG_VARS_MASK|REG_NON_PTR_MASK)|used_reg_mask;
if (!Bt(&lx->opts,OPTf_NO_REG_VAR) &&
!(lx->flags & LF_NO_REG_OPT)) {
QSort(mv,member_cnt,sizeof(COptMemberVar),&OptMVCompare);
while (member_cnt && !mv[member_cnt-1].score)
member_cnt--;
j=0;
for (i=0;i<member_cnt;i++) {
if (!mv[i].lea_balance && mv[i].offset_start) {//addr operator cancels
mv[j].m=mv[i].m;
mv[j].offset_start=mv[i].offset_start;
mv[j++].offset_end=mv[i].offset_end;
} else {
if (mv[i].m->reg==REG_ALLOC)
PrintWarn("Can't reg var\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
lx->cur_lfn->name,lx->cur_lfn->line_num,mv[i].m->str,lx->htc.fun->str);
}
}
if (j>0) {
if (Bt(&lx->flags,Lf_OPT_TRACE_PRESENT))
"Fun:%s\n",lx->htc.fun->str;
if (j>num_reg_vars) {
l=0;
for (i=0;i<j && l<num_non_ptr_vars;i++) {
tempm=mv[i].m;
tempc=OptClassFwd(tempm->member_class);
if (!tempc->ptr_cnt && !tempm->dim.next) {
while (l<num_non_ptr_vars &&
Bts(&lx->htc.fun->used_reg_mask,to_non_ptr_vars_map[l]))
l++;
if (l<num_non_ptr_vars) {
tempm->reg=to_non_ptr_vars_map[l++];
reg_offsets[tempm->reg].offset=mv[i].offset_start;
reg_offsets[tempm->reg].m=tempm;
if (Bt(&lx->flags,Lf_OPT_TRACE_PRESENT))
"Reg %Z Var \"%s\" %08X[RBP]\n",tempm->reg,"ST_U64_REGS",
tempm->str,reg_offsets[tempm->reg].offset;
mv[i].offset_start=0; //flag as reg var
if (tempm->size<8 && !StrIMatch("Bool",tempm->member_class->str) &&
tempm->member_class->type&HTT_INTERNAL_TYPE)
PrintWarn("Using 64-bit reg var.\n "
"$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
lx->cur_lfn->name,lx->cur_lfn->line_num,
tempm->str,lx->htc.fun->str);
}
}
}
}
l=0;
for (i=0;i<j && l<num_reg_vars;i++) {
tempm=mv[i].m;
//if not just flagged as reg var
if (mv[i].offset_start && (!mv[i].m->dim.next||
tempm->offset>0 && StrCmp(tempm->str,"argv"))) {
while (l<num_reg_vars &&
Bts(&lx->htc.fun->used_reg_mask,to_reg_vars_map[l]))
l++;
if (l<num_reg_vars) {
tempm->reg=to_reg_vars_map[l++];
reg_offsets[tempm->reg].offset=mv[i].offset_start;
reg_offsets[tempm->reg].m=tempm;
if (Bt(&lx->flags,Lf_OPT_TRACE_PRESENT))
"Reg %Z Var \"%s\" %08X[RBP]\n",tempm->reg,"ST_U64_REGS",
tempm->str,reg_offsets[tempm->reg].offset;
if (tempm->size<8 && !StrIMatch("Bool",tempm->member_class->str) &&
tempm->member_class->type&HTT_INTERNAL_TYPE)
PrintWarn("Using 64-bit reg var.\n "
"$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
lx->cur_lfn->name,lx->cur_lfn->line_num,
tempm->str,lx->htc.fun->str);
}
}
}
}
}
Free(mv);
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",lx->pass,ps->ptr;
LexExcept(lx,"Compiler Optimization Error at ");
}
}
+738
View File
@@ -0,0 +1,738 @@
Bool OptIC4(CIntermediateCode *tempi)
{
I64 i,ty,pt,ty1,pt1;
CIntermediateCode *tempil1,*tempil2;
if (tempi->ic_code<IC_IMM_U64) return FALSE;
tempil1=tempi;
if (!(tempil2=OptLag1(tempil1)))
return FALSE;
if (tempil2->r.type&TY_MASK==TY_STK &&
!(tempil2->ic_flags&ICF_PUSH_RESULT)) {
if (tempil1->ic_code==IC_ADD_CONST &&
tempil1->a1.type&TY_MASK==TY_STK) {
if ((tempil2->ic_code==IC_REG ||
tempil2->ic_code==IC_MOV) &&
tempil2->a1.type&TY_MASK==TY_REG) {
i=tempil1->ic_data;
if (MIN_I32<=i<=MAX_I32 &&
!Bt(&non_ptr_vars_mask,tempil2->a1.reg)) {
tempil1->ic_flags|=tempil2->ic_flags&ICG_NO_CVT_MASK;
tempil1->ic_code=IC_LEA;
tempil1->a1.type=TY_DISP+tempil1->a1.type&RT_MASK;
tempil1->a1.reg=tempil2->a1.reg;
tempil1->a1.disp=i;
OptFree(tempil2);
return TRUE;
}
} else if (tempil2->ic_code==IC_SHL_CONST &&
tempil2->a1.type&TY_MASK==TY_REG) {
i=tempil1->ic_data;
if (MIN_I32<=i<=MAX_I32 &&
tempil2->a1.reg!=REG_RSP &&
1<=tempil2->ic_data<=3) {
tempil1->ic_flags|=tempil2->ic_flags&ICG_NO_CVT_MASK;
tempil1->ic_code=IC_LEA;
tempil1->a1.type=TY_SIB+tempil1->a1.type&RT_MASK;
tempil1->a1.reg=tempil2->a1.reg<<8+REG_NONE;
if (tempil2->ic_data==1)
tempil1->a1.reg|=0x4000;
else if (tempil2->ic_data==2)
tempil1->a1.reg|=0x8000;
else
tempil1->a1.reg|=0xC000;
tempil1->a1.disp=i;
OptFree(tempil2);
return TRUE;
}
}
}
if (tempil2->ic_code==IC_MOV ||
tempil2->ic_code==IC_REG) {
if (tempil1->a2.type&TY_MASK==TY_STK) {
if (tempil2->ic_flags & ICF_R_TO_INT) {
if (tempil2->a1.type&TY_MASK==TY_IMM)
tempil2->a1.disp=tempil2->a1.disp(F64);
else
tempil1->ic_flags|=ICF_A2_TO_INT;
} else if (tempil2->ic_flags&ICF_R_TO_F64) {
if (tempil2->a1.type&TY_MASK==TY_IMM)
tempil2->a1.disp(F64)=tempil2->a1.disp;
else
tempil1->ic_flags|=ICF_A2_TO_F64;
}
ty=tempil1->a2.type&RT_MASK;
ty1=tempil2->a1.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
ty1=tempil2->r.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
tempil1->a2.type=tempil2->a1.type&TY_MASK+ty;
pt=tempil1->a2.type_pointed;
pt1=tempil2->a1.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
pt1=tempil2->r.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
tempil1->a2.type_pointed=pt;
tempil1->a2.reg=tempil2->a1.reg;
tempil1->a2.disp=tempil2->a1.disp;
tempil1->ic_flags|=tempil2->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tempil2);
return TRUE;
}
if (tempil1->a1.type&TY_MASK==TY_STK) {
if (tempil2->ic_flags & ICF_R_TO_INT) {
if (tempil2->a1.type&TY_MASK==TY_IMM)
tempil2->a1.disp=tempil2->a1.disp(F64);
else
tempil1->ic_flags|=ICF_A1_TO_INT;
} else if (tempil2->ic_flags&ICF_R_TO_F64) {
if (tempil2->a1.type&TY_MASK==TY_IMM) {
if (tempil2->a1.type&1) //signed/unsigned
tempil2->a1.disp(F64)=tempil2->a1.disp(U64);
else
tempil2->a1.disp(F64)=tempil2->a1.disp(I64);
} else
tempil1->ic_flags|=ICF_A1_TO_F64;
}
ty=tempil1->a1.type&RT_MASK;
ty1=tempil2->a1.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
ty1=tempil2->r.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
tempil1->a1.type=tempil2->a1.type&TY_MASK+ty;
pt=tempil1->a1.type_pointed;
pt1=tempil2->a1.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
pt1=tempil2->r.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
tempil1->a1.type_pointed=pt;
tempil1->a1.reg=tempil2->a1.reg;
tempil1->a1.disp=tempil2->a1.disp;
tempil1->ic_flags|=tempil2->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tempil2);
return TRUE;
}
}
if (tempil1->ic_code==IC_DEREF) {
if (tempil2->ic_code==IC_ADD_CONST &&
tempil2->a1.type&TY_MASK==TY_REG &&
tempil1->a1.type&TY_MASK==TY_STK) {
i=tempil2->ic_data;
if (MIN_I32<=i<=MAX_I32 &&
!Bt(&non_ptr_vars_mask,tempil2->a1.reg)) {
tempil1->ic_flags|=tempil2->ic_flags;
tempil1->ic_code=IC_MOV;
tempil1->a1.type=TY_DISP+tempil1->a1.type_pointed;
tempil1->a1.reg=tempil2->a1.reg;
tempil1->a1.disp=i;
OptSetNOP2(tempil2,-1);
return TRUE;
}
}
if (tempil2->ic_code==IC_LEA &&
tempil1->a1.type&TY_MASK==TY_STK) {
tempil1->ic_flags|=tempil2->ic_flags;
tempil1->ic_code=IC_MOV;
tempil1->a1.type=tempil2->a1.type&TY_MASK+tempil1->a1.type_pointed;
tempil1->a1.reg=tempil2->a1.reg;
tempil1->a1.disp=tempil2->a1.disp;
OptFree(tempil2);
return TRUE;
}
}
}
if (tempil1->ic_code==IC_DEREF) {
if (tempil1->a1.type&TY_MASK==TY_REG) {
tempil1->a1.type=TY_DISP+tempil1->a1.type_pointed;
tempil1->a1.disp=0;
tempil1->ic_code=IC_MOV;
return TRUE;
}
}
return FALSE;
}
U0 OptPass4(CLex *lx,COptReg *reg_offsets,I64 *_type)
{
CHashClass *tempc,*tempc1,*tempc2,*tempc3;
CIntermediateCode *tempi,*tempi1,*tempi2,*tempi3,*tempil1,*tempil2,*tempil3,*tempi_next;
I64 code,i;
Bool dead_code=FALSE;
CLexCodeMisc *lb;
CPrsStk *ps=lx->ps;
ps->ptr=0;
ps->ptr2=0;
if (_type)
*_type=RT_I64;
tempi=lx->lcc.lcc_root.next;
while (code=tempi->ic_code) {
tempi_next=tempi->next;
if (dead_code&&code!=IC_LABEL) {
if (code==IC_JMP||code==IC_SUB_CALL) {
lb=OptLabelFwd(tempi->ic_data);
if (lb->use_cnt>0)
lb->use_cnt--;
}
tempi=OptFree(tempi);
} else {
tempc=tempi->ic_class;
tempi1=tempi2=tempi3=&opt_nop;
if (tempil1=OptLag2(tempi)) {
if (tempil2=OptLag2(tempil1)) {
if (!(tempil3=OptLag2(tempil2)))
tempil3=&opt_nop;
} else
tempil2=tempil3=&opt_nop;
} else
tempil1=tempil2=tempil3=&opt_nop;
nobound_switch (cmp_arg_cnt[code]) {
case 9:
ps->ptr-=tempi->ic_data>>3;
break;
case 3:
tempi3=PrsPop(ps);
tempc3=tempi3->ic_class;
case 2:
tempi2=PrsPop(ps);
tempc2=tempi2->ic_class;
case 1:
tempi1=PrsPop(ps);
tempc1=tempi1->ic_class;
break;
case 0: //nobound_switch
break;
}
nobound_switch (code) {
case IC_IMM_U64:
case IC_TYPE:
tempi->a1.type=TY_IMM+RT_I64;
tempi->a1.disp=tempi->ic_data;
tempi->ic_code=IC_MOV;
break;
case IC_IMM_F64:
tempi->a1.type=TY_IMM+RT_I64;
tempi->a1.disp=tempi->ic_data;
tempi->a1.type_pointed=RT_F64;
tempi->ic_code=IC_MOV;
break;
case IC_MOV:
if (tempi->a1.type&TY_MASK==TY_DISP &&
tempi->a1.reg==REG_RBP) {
i=CmpOffset2Reg(tempi->a1.disp,reg_offsets);
if (i>=0) {
tempi->a1.type=TY_REG+tempi->a1.type&RT_MASK;
tempi->a1.reg=i;
tempi->a1.disp=0;
}
}
break;
case IC_DEREF:
if (tempi1->ic_code==IC_LEA) {
if (tempi1->a1.type&TY_MASK==TY_DISP &&
tempi1->a1.reg==REG_RBP) {
i=CmpOffset2Reg(tempi1->a1.disp,reg_offsets);
if (i>=0) {
tempi->ic_flags|=tempi1->ic_flags;
tempi->ic_code=IC_REG;
tempi->a1.type=TY_REG+tempi->a1.type&RT_MASK;
tempi->a1.reg=i;
tempi->a1.disp=0;
OptFree(tempi1);
}
}
} else if ((tempi1->ic_code==IC_ABS_ADDR ||
tempi1->ic_code==IC_MOV &&
tempi1->a1.type==TY_IMM+RT_I64 &&
0<=tempi1->a1.disp<=MAX_I32) &&
!(tempi1->ic_flags&ICF_NO_RIP)) {
if (tempi1->ic_code==IC_ABS_ADDR)
tempi->a1.disp=tempi1->ic_data;
else
tempi->a1.disp=tempi1->a1.disp;
tempi->ic_flags|=tempi1->ic_flags;
tempi->ic_code=IC_MOV;
tempi->a1.type=TY_RIP_DISP32+tempi->a1.type_pointed;
tempi->a1.reg=REG_RIP;
OptFree(tempi1);
}
break;
case IC_BR_MM_ZERO:
case IC_BR_MM_NOT_ZERO:
//(branch ++ to zero is unlikely)
case IC_DEREF_PP:
case IC_DEREF_MM:
case IC__PP:
case IC__MM:
case IC_PP_:
case IC_MM_:
if (tempi1->ic_code==IC_LEA) {
if (tempi1->a1.type&TY_MASK==TY_DISP &&
tempi1->a1.reg==REG_RBP) {
i=CmpOffset2Reg(tempi1->a1.disp,reg_offsets);
if (i>=0) {
tempi->ic_flags|=tempi1->ic_flags;
tempi->a1.type=TY_REG+tempi->a1.type&RT_MASK;
tempi->a1.reg=i;
tempi->a1.disp=0;
tempi->ic_flags|=ICF_NOT_ADDR;
OptSetNOP2(tempi1);
} else
goto p4_lea_gone;
} else {
p4_lea_gone:
tempi->ic_flags|=tempi1->ic_flags;
tempi->a1.type=tempi1->a1.type;
tempi->a1.reg=tempi1->a1.reg;
tempi->a1.disp=tempi1->a1.disp;
tempi->ic_flags|=ICF_NOT_ADDR;
OptSetNOP2(tempi1);
}
} else if ((tempi1->ic_code==IC_ABS_ADDR ||
tempi1->ic_code==IC_MOV &&
tempi1->a1.type==TY_IMM+RT_I64 &&
0<=tempi1->a1.disp<=MAX_I32) &&
!(tempi1->ic_flags&ICF_NO_RIP)) {
tempi->ic_flags|=tempi1->ic_flags;
if (tempi1->ic_code==IC_ABS_ADDR)
tempi->a1.disp=tempi1->ic_data;
else
tempi->a1.disp=tempi1->a1.disp;
tempi->a1.type=TY_RIP_DISP32+tempi->a1.type_pointed;
tempi->a1.reg=REG_RIP;
tempi->ic_flags|=ICF_NOT_ADDR;
OptFree(tempi1);
}
break;
case IC_ADD:
if (tempi1->ic_code==IC_MOV && tempi1->a1.type==TY_REG+RT_I64 ||
tempi1->ic_code==IC_REG) {
if (tempi2->ic_code==IC_MOV && tempi2->a1.type==TY_REG+RT_I64 ||
tempi2->ic_code==IC_REG) {
if (tempi2->a1.reg!=REG_RSP) {
tempi->a1.disp=0;
tempi->a1.reg=tempi1->a1.reg+tempi2->a1.reg<<8;
goto p4_sib;
} else if (tempi1->a1.reg!=REG_RSP) {
tempi->a1.disp=0;
tempi->a1.reg=tempi2->a1.reg+tempi1->a1.reg<<8;
p4_sib:
tempi->ic_flags|=(tempi1->ic_flags|tempi2->ic_flags)&ICG_NO_CVT_MASK;
OptSetNOP2(tempi1);
OptFree(tempi2);
tempi->ic_code=IC_LEA;
tempi->a1.type=TY_SIB+RT_I64;
tempi->a1.type_pointed=RT_I64;
tempi->a2.type=TY_NULL+tempi->a2.type&RT_MASK;
}
} else if (tempi2->ic_code==IC_SHL_CONST && tempi2->a1.type==TY_REG+RT_I64 &&
tempi2->ic_data<=3) {
if (tempi2->a1.reg!=REG_RSP) {
tempi->a1.disp=0;
tempi->a1.reg=tempi1->a1.reg+tempi2->a1.reg<<8;
if (tempi2->ic_data==1)
tempi->a1.reg|=0x4000;
else if (tempi2->ic_data==2)
tempi->a1.reg|=0x8000;
else
tempi->a1.reg|=0xC000;
goto p4_sib;
}
}
} else if (tempi1->ic_code==IC_LEA && tempi1->a1.type&TY_MASK==TY_DISP) {
if (tempi1->a1.reg==REG_RBP && CmpOffset2Reg(tempi1->a1.disp,reg_offsets)>=0)
break;
if (tempi2->ic_code==IC_MOV && tempi2->a1.type==TY_REG+RT_I64 ||
tempi2->ic_code==IC_REG) {
if (tempi2->a1.reg!=REG_RSP) {
tempi->a1.disp=tempi1->a1.disp;
tempi->a1.reg=tempi1->a1.reg+tempi2->a1.reg<<8;
goto p4_sib;
} else if (tempi1->a1.reg!=REG_RSP) {
tempi->a1.disp=tempi1->a1.disp;
tempi->a1.reg=tempi2->a1.reg+tempi1->a1.reg<<8;
goto p4_sib;
}
} else if (tempi2->ic_code==IC_SHL_CONST && tempi2->a1.type==TY_REG+RT_I64 &&
tempi2->ic_data<=3) {
if (tempi2->a1.reg!=REG_RSP) {
tempi->a1.disp=tempi1->a1.disp;
tempi->a1.reg=tempi1->a1.reg+tempi2->a1.reg<<8;
if (tempi2->ic_data==1)
tempi->a1.reg|=0x4000;
else if (tempi2->ic_data==2)
tempi->a1.reg|=0x8000;
else
tempi->a1.reg|=0xC000;
goto p4_sib;
}
}
}
break;
case IC_ASSIGN_PP:
case IC_ASSIGN_MM:
//this val was stashed during pass012 for pointer arithmetic
tempi->ic_class2=tempi->t.class2;
case IC_ASSIGN:
case IC_SHL_EQUAL:
case IC_SHR_EQUAL:
case IC_MUL_EQUAL:
case IC_DIV_EQUAL:
case IC_MOD_EQUAL:
case IC_AND_EQUAL:
case IC_OR_EQUAL:
case IC_XOR_EQUAL:
case IC_ADD_EQUAL:
case IC_SUB_EQUAL:
if (tempi1->ic_code==IC_LEA) {
if (TY_DISP<=tempi1->a1.type&TY_MASK<=TY_SIB) {
if (tempi1->a1.type&TY_MASK==TY_DISP && tempi1->a1.reg==REG_RBP) {
i=CmpOffset2Reg(tempi1->a1.disp,reg_offsets);
if (i>=0) {
tempi->ic_flags|=tempi1->ic_flags;
tempi->a1.type=TY_REG+tempi->a1.type&RT_MASK;
tempi->a1.reg=i;
tempi->a1.disp=0;
OptSetNOP2(tempi1);
} else {
tempi->ic_flags|=tempi1->ic_flags;
tempi->a1.type=TY_DISP+tempi->a1.type&RT_MASK;
tempi->a1.reg=REG_RBP;
tempi->a1.disp=tempi1->a1.disp;
OptSetNOP2(tempi1);
}
} else {
tempi->a1.type=tempi1->a1.type&TY_MASK+tempi->a1.type&RT_MASK;
tempi->ic_flags|=tempi1->ic_flags;
tempi->a1.reg=tempi1->a1.reg;
tempi->a1.disp=tempi1->a1.disp;
OptSetNOP2(tempi1);
}
tempi->ic_flags|=ICF_NOT_ADDR;
}
} else if ((tempi1->ic_code==IC_ABS_ADDR ||
tempi1->ic_code==IC_MOV &&
tempi1->a1.type==TY_IMM+RT_I64 &&
0<=tempi1->a1.disp<=MAX_I32) &&
!(tempi1->ic_flags&ICF_NO_RIP)) {
tempi->ic_flags|=tempi1->ic_flags;
if (tempi1->ic_code==IC_ABS_ADDR)
tempi->a1.disp=tempi1->ic_data;
else
tempi->a1.disp=tempi1->a1.disp;
tempi->a1.type=TY_RIP_DISP32+tempi->a1.type&RT_MASK;
tempi->a1.reg=REG_RIP;
tempi->ic_flags|=ICF_NOT_ADDR;
OptSetNOP2(tempi1);
}
break;
case IC_RETURN_VAL:
case IC_RETURN_VAL2:
if (!tempi->ic_class) {
if (_type) {
tempil1=tempi;
while (tempil1=OptLag1(tempil1))
if (tempil1->ic_class) {
if (tempil1->ic_flags & ICF_R_TO_F64)
*_type=RT_F64;
else if (tempil1->ic_flags & ICF_R_TO_INT)
*_type=RT_I64;
else
*_type=tempil1->ic_class->raw_type;
break;
}
}
tempi->ic_class=sys_internal_types[RT_I64];
} else if (_type)
*_type=tempi->ic_class->raw_type;
break;
case IC_NOP1:
tempi=OptFree(tempi);
break;
case IC_BR_BT:
case IC_BR_BTS:
case IC_BR_BTR:
case IC_BR_BTC:
case IC_BR_NOT_BT:
case IC_BR_NOT_BTS:
case IC_BR_NOT_BTR:
case IC_BR_NOT_BTC:
case IC_BR_LBTS:
case IC_BR_LBTR:
case IC_BR_LBTC:
case IC_BR_NOT_LBTS:
case IC_BR_NOT_LBTR:
case IC_BR_NOT_LBTC:
case IC_BT:
case IC_BTS:
case IC_BTR:
case IC_BTC:
case IC_LBTS:
case IC_LBTR:
case IC_LBTC:
if (!(tempi->ic_flags&ICF_NOT_ADDR)) {
if (tempi2->ic_code==IC_ADDR) {
if (tempi2->a1.type&TY_MASK==TY_STK &&
tempi2->r.type&TY_MASK==TY_STK) {
if (tempil2=OptLag1(tempi2)) {
if (tempil2->ic_code==IC_LEA) {
if (TY_IMM<=tempil2->a1.type&TY_MASK<TY_STK) {
if (tempi2) {
tempi->ic_flags|=tempi2->ic_flags;
OptFree(tempi2);
}
tempi->ic_flags|=tempil2->ic_flags|ICF_NOT_ADDR;
tempi->a2.type=tempil2->a1.type;
tempi->a2.reg =tempil2->a1.reg;
tempi->a2.disp=tempil2->a1.disp;
OptFree(tempil2);
}
break;
} else if (tempil2->ic_code!=IC_ABS_ADDR &&
!(tempil2->ic_code==IC_MOV &&
tempil2->a1.type==TY_IMM+RT_I64 &&
0<=tempil2->a1.disp<=MAX_I32) ||
tempil2->ic_flags&ICF_NO_RIP)
tempil2=NULL;
else {
if (tempil2->ic_code==IC_ABS_ADDR)
tempi->a2.disp=tempil2->ic_data;
else
tempi->a2.disp=tempil2->a1.disp;
}
}
} else {
if (tempi2->a1.type==TY_IMM+RT_I64 &&
0<=tempi2->a1.disp<=MAX_I32 &&
!(tempi2->ic_flags&ICF_NO_RIP)) {
tempil2=tempi2;
tempi2=NULL;
tempi->a2.disp=tempil2->a1.disp;
} else
tempil2=NULL;
}
if (tempil2) {
if (tempi2) {
tempi->ic_flags|=tempi2->ic_flags;
OptFree(tempi2);
}
tempi->ic_flags|=tempil2->ic_flags|ICF_NOT_ADDR;
tempi->a2.type=TY_RIP_DISP32+tempi->a2.type&RT_MASK;
tempi->a2.reg=REG_RIP;
OptFree(tempil2);
}
} else if (tempi2->ic_code==IC_MOV &&
tempi2->r.type&TY_MASK==TY_STK &&
tempi2->a1.type==TY_IMM+RT_I64 &&
0<=tempi2->a1.disp<=MAX_I32 &&
!(tempi2->ic_flags&ICF_NO_RIP)) {
tempi->a2.disp=tempi2->a1.disp;
tempi->ic_flags|=tempi2->ic_flags|ICF_NOT_ADDR;
tempi->a2.type=TY_RIP_DISP32+tempi->a2.type&RT_MASK;
tempi->a2.reg=REG_RIP;
OptFree(tempi2);
}
}
break;
case IC_BR_NOT_EQUAL2:
case IC_BR_EQUAL_EQUAL2:
case IC_BR_GREATER_EQUAL2:
case IC_BR_LESS_EQUAL2:
case IC_BR_GREATER2:
case IC_BR_LESS2:
case IC_BR_ZERO:
case IC_BR_NOT_ZERO:
case IC_BR_CARRY:
case IC_BR_NOT_CARRY:
case IC_BR_NOT_EQUAL:
case IC_BR_EQUAL_EQUAL:
case IC_BR_GREATER_EQUAL:
case IC_BR_LESS_EQUAL:
case IC_BR_GREATER:
case IC_BR_LESS:
lb=tempi->ic_data;
if (tempi->ic_flags&ICF_PUSH_CMP) {
lb->flags|=CMF_POP_CMP;
lb->fwd=NULL;
}
break;
case IC_LABEL:
lb=tempi->ic_data;
if (lb->use_cnt)
dead_code=FALSE;
break;
case IC_JMP:
case IC_RET:
dead_code=TRUE;
break;
case IC_NOP2:
ps->ptr+=tempi->ic_data;
break;
case IC_CALL_END:
case IC_END_EXP:
if (tempi->a1.type&TY_MASK==TY_STK) {
if (tempil1->r.type&TY_MASK==TY_STK &&
!(tempil1->ic_flags&ICF_PUSH_RESULT)) {
tempi->a1.type=TY_REG+tempi->a1.type&RT_MASK;
tempi->a1.reg=REG_RAX;
tempi->a1.disp=0;
tempil1->r.type=TY_REG+tempil1->r.type&RT_MASK;
tempil1->r.reg=REG_RAX;
tempil1->r.disp=0;
}
}
break;
case IC_STR_CONST:
case IC_FS:
case IC_GS:
case IC_MOV_FS:
case IC_MOV_GS:
case IC_RIP:
case IC_RBP:
case IC_REG:
case IC_COM:
case IC_HOLYC_TYPECAST:
case IC_NOT:
case IC_UNARY_MINUS:
case IC_PUSH_CMP:
case IC_ADD_CONST:
case IC_SUB_CONST:
case IC_ENTER:
case IC_ADD_RSP:
case IC_ADD_RSP1:
case IC_CALL:
case IC_CALL_INDIRECT:
case IC_CALL_INDIRECT2:
case IC_CALL_EXTERN:
case IC_CALL_IMPORT:
case IC_PUSH:
case IC_POP:
case IC_INVLPG:
case IC_CLFLUSH:
case IC_GET_RFLAGS:
case IC_CARRY:
case IC_RDTSC:
case IC_HPET:
case IC_SET_RFLAGS:
case IC_GET_RBP:
case IC_SET_RBP:
case IC_GET_RSP:
case IC_GET_RAX:
case IC_SET_RSP:
case IC_SET_RAX:
case IC_SHL_CONST:
case IC_LEA:
case IC_SHR_CONST:
case IC_POWER:
case IC_SHL:
case IC_SHR:
case IC_MUL:
case IC_DIV:
case IC_MOD:
case IC_AND:
case IC_OR:
case IC_XOR:
case IC_SUB:
case IC_EQUAL_EQUAL:
case IC_NOT_EQUAL:
case IC_LESS:
case IC_GREATER:
case IC_LESS_EQUAL:
case IC_GREATER_EQUAL:
case IC_AND_AND:
case IC_OR_OR:
case IC_XOR_XOR:
case IC_GET_LABEL:
case IC_ABS_ADDR:
case IC_HEAP_GLBL:
case IC_ADDR_IMPORT:
case IC_BSF:
case IC_BSR:
case IC_PREEMPT:
case IC_SIGN_I64:
case IC_TOUPPER:
case IC_TO_I64:
case IC_TO_F64:
case IC_TO_BOOL:
case IC_SQR:
case IC_ABS:
case IC_SQRT:
case IC_SIN:
case IC_COS:
case IC_TAN:
case IC_ATAN:
case IC_ABS_I64:
case IC_MIN_I64:
case IC_MAX_I64:
case IC_MIN_U64:
case IC_MAX_U64:
case IC_MOD_U64:
case IC_SQR_I64:
case IC_SQR_U64:
case IC_SWAP_U8:
case IC_SWAP_U16:
case IC_SWAP_U32:
case IC_SWAP_U64:
case IC_QUE_INIT:
case IC_QUE_INS:
case IC_QUE_INS_REV:
case IC_QUE_REM:
case IC_IN_U32:
case IC_IN_U16:
case IC_IN_U8:
case IC_STRLEN:
case IC_OUT_U32:
case IC_OUT_U16:
case IC_OUT_U8:
case IC_NOBOUND_SWITCH:
case IC_SWITCH:
case IC_END:
case IC_ADDR:
case IC_CALL_START:
case IC_LEAVE:
case IC_PUSH_REGS:
case IC_POP_REGS:
case IC_ASM:
case IC_BR_AND_NOT_ZERO:
case IC_BR_AND_ZERO:
case IC_SUB_CALL:
case IC_CALL_END2:
break;
default:
"Pass:%d Missing IC handler\n",lx->pass;
ICPut(tempi);
LexExcept(lx,"Compiler Optimization Error at ");
}
if (tempi) {
while (OptIC4(tempi));
code=tempi->ic_code;
if (cmp_result_cnt[code])
PrsPush(ps,tempi);
}
}
tempi=tempi_next;
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",lx->pass,ps->ptr;
LexExcept(lx,"Compiler Optimization Error at ");
}
}
+122
View File
@@ -0,0 +1,122 @@
U0 OptPass5(CLex *lx)
{
CIntermediateCode *tempi,*tempi1;
I64 code,i,ty,pt,ty1,pt1;
CPrsStk *ps=lx->ps;
ps->ptr=0;
ps->ptr2=0;
tempi=lx->lcc.lcc_root.next;
while (code=tempi->ic_code) {
if (code>IC_NOP2) {
if (tempi->ic_flags&ICF_TRACE) {
if (Bt(&lx->pass_trace_mask,5)) {
"%2d:",ps->ptr;
ICPut(tempi);
}
}
if (cmp_arg_cnt[code]==9)
ps->ptr-=tempi->ic_data>>3;
if (code==IC_PUSH_REGS) {
for (i=0;i<NUM_REGS;i++)
if (Bt(&tempi->ic_data,i))
ps->ptr++;
} else if (code==IC_POP_REGS) {
for (i=0;i<NUM_REGS;i++)
if (Bt(&tempi->ic_data,i))
ps->ptr--;
}
if (tempi->a2.type&TY_MASK==TY_STK) {
tempi1=PrsPop(ps);
if (tempi1->ic_code==IC_MOV ||
tempi1->ic_code==IC_REG) {
if (tempi1->ic_flags & ICF_R_TO_INT) {
if (tempi1->a1.type&TY_MASK==TY_IMM)
tempi1->a1.disp=tempi1->a1.disp(F64);
else
tempi->ic_flags|=ICF_A2_TO_INT;
} else if (tempi1->ic_flags&ICF_R_TO_F64) {
if (tempi1->a1.type&TY_MASK==TY_IMM)
tempi1->a1.disp(F64)=tempi1->a1.disp;
else
tempi->ic_flags|=ICF_A2_TO_F64;
}
ty=tempi->a2.type&RT_MASK;
ty1=tempi1->a1.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
ty1=tempi1->r.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
tempi->a2.type=tempi1->a1.type&TY_MASK+ty;
pt=tempi->a2.type_pointed;
pt1=tempi1->a1.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
pt1=tempi1->r.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
tempi->a2.type_pointed=pt;
tempi->a2.reg=tempi1->a1.reg;
tempi->a2.disp=tempi1->a1.disp;
tempi->ic_flags|=tempi1->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tempi1);
}
}
if (tempi->a1.type&TY_MASK==TY_STK) {
tempi1=PrsPop(ps);
if (tempi1->ic_code==IC_MOV ||
tempi1->ic_code==IC_REG) {
if (tempi1->ic_flags & ICF_R_TO_INT) {
if (tempi1->a1.type&TY_MASK==TY_IMM)
tempi1->a1.disp=tempi1->a1.disp(F64);
else
tempi->ic_flags|=ICF_A1_TO_INT;
} else if (tempi1->ic_flags&ICF_R_TO_F64) {
if (tempi1->a1.type&TY_MASK==TY_IMM) {
if (tempi1->a1.type & 1) //signed/unsigned
tempi1->a1.disp(F64)=tempi1->a1.disp(U64);
else
tempi1->a1.disp(F64)=tempi1->a1.disp(I64);
} else
tempi->ic_flags|=ICF_A1_TO_F64;
}
ty=tempi->a1.type&RT_MASK;
ty1=tempi1->a1.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
ty1=tempi1->r.type&RT_MASK;
if (ty1 && ty1<ty)
ty=ty1;
tempi->a1.type=tempi1->a1.type&TY_MASK+ty;
pt=tempi->a1.type_pointed;
pt1=tempi1->a1.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
pt1=tempi1->r.type_pointed;
if (pt1 && pt1<pt && pt!=RT_F64)
pt=pt1;
tempi->a1.type_pointed=pt;
tempi->a1.reg=tempi1->a1.reg;
tempi->a1.disp=tempi1->a1.disp;
tempi->ic_flags|=tempi1->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tempi1);
}
}
if (tempi->r.type&TY_MASK==TY_STK)
PrsPush(ps,tempi);
}
tempi=tempi->next;
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",lx->pass,ps->ptr;
LexExcept(lx,"Compiler Optimization Error at ");
}
}
+215
View File
@@ -0,0 +1,215 @@
Bool OptIC6(CIntermediateCode *tempi)
{
CIntermediateCode *tempil1;
if (tempi->ic_code<IC_IMM_U64 || !(tempil1=OptLag1(tempi)))
return FALSE;
if (tempil1->ic_code==IC_ADD_CONST && tempi->ic_code==IC_DEREF &&
tempi->ic_flags&ICF_A1_WAS_STK && tempi->a1.type&TY_MASK==TY_REG &&
tempil1->r.type&TY_MASK==TY_REG && MIN_I32<=tempil1->ic_data<=MAX_I32 &&
!Bt(&non_ptr_vars_mask,tempil1->a1.reg)) {
if (tempil1->a1.type&TY_MASK==TY_REG) {
tempi->ic_flags=tempi->ic_flags&~ICF_A1_WAS_STK | tempil1->ic_flags;
tempi->ic_code=IC_MOV;
tempi->a1.type=TY_DISP+tempi->a1.type_pointed;
tempi->a1.reg=tempil1->a1.reg;
tempi->a1.disp=tempil1->ic_data;
OptSetNOP2(tempil1,-1);
} else {
tempil1->ic_code=IC_MOV;
tempi->ic_code=IC_MOV;
tempi->a1.type=TY_DISP+tempi->a1.type_pointed;
tempi->a1.disp=tempil1->ic_data;
}
return TRUE;
}
return FALSE;
}
U0 OptPass6Lag(CLex *lx,
CPrsStk *ps,CIntermediateCode *tempi,I64 *i_,I64 num_stk,
I64 *_clobbered_reg_mask,I64 fun_num)
{
I64 i=*i_,j,k,l,code,clobbered_reg_mask=*_clobbered_reg_mask;
CHashFun *tempf;
code=tempi->ic_code;
if (tempi->ic_flags&ICF_TRACE && Bt(&lx->pass_trace_mask,6)) {
"%2d:",i;
ICPut(tempi);
}
if (code==IC_CALL_START) {
k=MinI64(i,num_stk);
j=0;
if (fun_num&1)
for (l=0;l<k;l++)
Bts(&j,to_stk_temps_map_odd[l]);
else
for (l=0;l<k;l++)
Bts(&j,to_stk_temps_map_even[l]);
if (tempf=tempi->ic_data) {
if (Bt(&tempf->flags,Ff_INTERNAL))
j=0;
else {
j&=tempf->clobbered_reg_mask;
clobbered_reg_mask|=tempf->clobbered_reg_mask;
}
}
tempi->ic_data=j;
PrsPush(ps,i);
PrsPush(ps,j);
} else if (code==IC_CALL_END) {
tempi->ic_data=PrsPop(ps);
i=PrsPop(ps);
} else if (code==IC_CALL_END2) {
ps->ptr--;
i=PrsPop(ps);
}
if (cmp_arg_cnt[code]==9)
i-=tempi->ic_data>>3;
if (tempi->a2.type&TY_MASK==TY_STK) {
i--;
if (i<num_stk) {
tempi->a2.type=TY_REG+tempi->a2.type&RT_MASK;
if (fun_num&1)
tempi->a2.reg=to_stk_temps_map_odd[i];
else
tempi->a2.reg=to_stk_temps_map_even[i];
tempi->a2.disp=0;
}
}
if (tempi->a1.type&TY_MASK==TY_STK) {
i--;
if (i<num_stk) {
tempi->a1.type=TY_REG+tempi->a1.type&RT_MASK;
if (fun_num&1)
tempi->a1.reg=to_stk_temps_map_odd[i];
else
tempi->a1.reg=to_stk_temps_map_even[i];
tempi->a1.disp=0;
}
}
if (tempi->r.type&TY_MASK==TY_STK && !(tempi->ic_flags & ICF_PUSH_RESULT)) {
i++;
if (i<=num_stk) {
tempi->r.type=TY_REG+tempi->r.type&RT_MASK;
if (fun_num&1) {
tempi->r.reg=to_stk_temps_map_odd[i-1];
Bts(&clobbered_reg_mask,to_stk_temps_map_odd[i-1]);
} else {
tempi->r.reg=to_stk_temps_map_even[i-1];
Bts(&clobbered_reg_mask,to_stk_temps_map_even[i-1]);
}
tempi->r.disp=0;
}
}
while (OptIC6(tempi));
if (tempi->r.type&RT_MASK!=RT_F64 && !(tempi->ic_flags&ICF_USE_F64))
tempi->ic_flags|=ICF_USE_INT;
*i_=i;
*_clobbered_reg_mask=clobbered_reg_mask;
}
U0 OptPass6(CLex *lx)
{
CIntermediateCode *tempi,*tempil1,*tempil2,*tempil3,*tempif1,*tempif2,*old_tempil2;
I64 i=0,code,num_stk,clobbered_reg_mask=REG_ALWAYS_CLOBBERED_MASK,fun_num=0;
CPrsStk *ps=lx->ps;
ps->ptr=0;
ps->ptr2=0;
if (lx->htc.fun)
fun_num=compiled_funs++;
if (Bt(&lx->opts,OPTf_NO_REG_VAR) || lx->flags&LF_NO_REG_OPT)
num_stk=0;
else
num_stk=num_stk_temps;
tempi=lx->lcc.lcc_root.next;
old_tempil2=NULL;
tempil1=tempil2=tempil3=&opt_nop;
while (code=tempi->ic_code) {
if ( code>=IC_END_EXP && code!=IC_NOP2) {
if ( tempil1->ic_code>=IC_END_EXP && tempil1->ic_code!=IC_NOP2) {
if (tempil2->ic_code>=IC_END_EXP && tempil2->ic_code!=IC_NOP2)
tempil3=tempil2;
tempil2=tempil1;
}
tempil1=tempi;
}
if (tempil2->ic_code==IC_END_EXP && code!=IC_RETURN_VAL2 && code!=IC_NOP1 &&
!(tempil3->ic_flags&(ICF_R_TO_F64|ICF_R_TO_INT|ICF_PUSH_RESULT|ICF_DEPEND_RESULT))) {
tempil3->ic_flags|=ICF_NO_DEPEND_RESULT;
tempil3->r.type=TY_NULL+tempil3->r.type&RT_MASK;
tempil2->ic_flags|=ICF_NO_DEPEND_RESULT;
tempil2->r.type=TY_NULL+tempil2->r.type&RT_MASK;
}
if (code>IC_NOP2) {
if (tempi->a2.type&TY_MASK==TY_STK) {
if (tempil2->r.type&TY_MASK==TY_STK &&
!(tempil2->ic_flags&ICF_PUSH_RESULT)) {
tempif2=NULL;
if (tempi->ic_code==IC_ASSIGN &&
tempi->ic_flags&ICF_NOT_ADDR &&
tempil2->ic_code!=IC_CALL_END &&
tempil2->ic_code!=IC_CALL_END2 &&
tempil2->ic_code!=IC_SET_RAX &&
!(tempi->ic_flags&
(ICF_A2_TO_F64|ICF_A2_TO_INT)) &&
!(tempil2->ic_flags&
(ICF_R_TO_F64|ICF_R_TO_INT))) {
if (tempif1=OptLead1(tempi)) //predict NO_DEPEND
if (tempif2=OptLead1(tempif1))
if (tempif1->ic_code==IC_END_EXP &&
tempif2->ic_code!=IC_RETURN_VAL2) {
tempil2->r.type =tempi->a1.type&TY_MASK+tempi->a1.type_pointed;
tempil2->r.type_pointed=tempi->a1.type_pointed;
tempil2->r.reg =tempi->a1.reg;
tempil2->r.disp =tempi->a1.disp;
tempil2->ic_flags=tempil2->ic_flags&~(ICF_NO_DEPEND_RESULT|ICF_R_WAS_STK)|
tempi->ic_flags&~(ICF_NOT_ADDR|ICF_A1_WAS_STK|ICF_A2_WAS_STK)|ICF_DEPEND_RESULT;
old_tempil2=NULL;
OptSetNOP1(tempi);
} else
tempif2=NULL;
}
if (!tempif2) {
tempi->a2.type=TY_REG+tempi->a2.type&RT_MASK;
tempi->a2.reg=REG_RAX;
tempi->a2.disp=0;
tempil2->r.type=TY_REG+tempil2->r.type&RT_MASK;
tempil2->r.reg=REG_RAX;
tempil2->r.disp=0;
}
}
} else if (tempi->a1.type&TY_MASK==TY_STK &&
tempil2->r.type&TY_MASK==TY_STK &&
!(tempil2->ic_flags&ICF_PUSH_RESULT)) {
tempi->a1.type=TY_REG+tempi->a1.type&RT_MASK;
tempi->a1.reg=REG_RAX;
tempi->a1.disp=0;
tempil2->r.type=TY_REG+tempil2->r.type&RT_MASK;
tempil2->r.reg=REG_RAX;
tempil2->r.disp=0;
}
if (tempi->ic_flags & ICF_PUSH_RESULT)
tempi->r.type==TY_STK+tempi->r.type&RT_MASK;
}
if (old_tempil2!=tempil2) {
if (tempil2->ic_code>IC_NOP2)
OptPass6Lag(lx,ps,tempil2,&i,num_stk,&clobbered_reg_mask,fun_num);
old_tempil2=tempil2;
}
tempi=tempi->next;
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",lx->pass,ps->ptr;
LexExcept(lx,"Compiler Optimization Error at ");
}
if (lx->htc.fun) {
lx->htc.fun->used_reg_mask&=~REG_STK_TEMPS_MASK;
lx->htc.fun->used_reg_mask|=clobbered_reg_mask;
lx->htc.fun->clobbered_reg_mask=clobbered_reg_mask;
if (Bt(&lx->flags,Lf_OPT_TRACE_PRESENT) &&
Bt(&lx->pass_trace_mask,6)) {
"Used Reg Mask:%04X\n",lx->htc.fun->used_reg_mask;
"Clobbered Reg Mask:%04X\n",clobbered_reg_mask;
}
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+678
View File
@@ -0,0 +1,678 @@
I64 InstEntriesCompare(CInstruction *tempi1,CInstruction *tempi2)
{
I64 i1,i2,j=0,result=0,oc_cnt1=tempi1->opcode_cnt,oc_cnt2=tempi2->opcode_cnt;
if (tempi1->flags&IEF_STI)
oc_cnt1--;
if (tempi2->flags&IEF_STI)
oc_cnt2--;
while (TRUE) {
if (j<oc_cnt1 && j<oc_cnt2) {
if (result=tempi1->opcode[j]-tempi2->opcode[j])
return result;
j++;
} else {
if (result=oc_cnt1-oc_cnt2)
return result;
if (tempi1->flags&IEF_STI)
i1=tempi1->opcode[j]>>3&7;
else
i1=tempi1->slash_val;
if (tempi2->flags&IEF_STI)
i2=tempi2->opcode[j]>>3&7;
else
i2=tempi2->slash_val;
if (result=i1-i2) return result;
if (tempi1->flags&IEF_STI && tempi2->flags&IEF_STI) {
i1=tempi1->opcode[j]&7;
i2=tempi2->opcode[j]&7;
if (result=i1-i2) return result;
}
if (tempi1->flags&IEF_STI)
return 1;
if (tempi2->flags&IEF_STI)
return -1;
i1=tempi1->flags & IEF_OP_SIZE32;
i2=tempi2->flags & IEF_OP_SIZE32;
if (result=i1-i2) return result;
i1=Bt(&uasm_ins64_mask,tempi1->arg1) || Bt(&uasm_ins64_mask,tempi1->arg2);
i2=Bt(&uasm_ins64_mask,tempi2->arg1) || Bt(&uasm_ins64_mask,tempi2->arg2);
if (result=i1-i2) return result;
i1=tempi1->flags & IEF_48_REX;
i2=tempi2->flags & IEF_48_REX;
if (result=i1-i2) return result;
i1=tempi1->arg2==ARGT_IMM64 || tempi1->arg2==ARGT_UIMM64;
i2=tempi2->arg2==ARGT_IMM64 || tempi2->arg2==ARGT_UIMM64;
return i1-i2;
}
}
}
/*
U0 DumpUnasmIns(CInstruction *tempi)
{
CHashOpcode *tempo=tempi(U8 *)-tempi->ins_entry_num*sizeof(CInstruction)-offset(CHashOpcode.ins);
"%10s:%02d,%02d SV:%02d\n",tempo->str,tempi->arg1,tempi->arg2,tempi->slash_val;
}
U0 DumpUnasmTable()
{
I64 k;
for (k=0;k<unasm_table_entries;k++)
DumpUnasmIns(unasm_table[k]);
}
*/
CInstruction *InstEntryFind(U8 *ip,I64 opsize)
{//Binary Search
I64 i,j,n,m,k,a1,a2,o1,o2,oc_cnt,sv;
CInstruction *tempi;
i=0;
j=unasm_table_entries-1;
while (TRUE) {
k=(i+j)>>1; //binary search
tempi=unasm_table[k];
//DumpUnasmIns(tempi);
m=0;
n=0;
while (TRUE) {
a1=tempi->arg1;
a2=tempi->arg2;
oc_cnt=tempi->opcode_cnt;
if (tempi->flags&IEF_STI)
oc_cnt--;
if (n<oc_cnt) {
o1=ip[n];
if (n==tempi->opcode_cnt-1 && tempi->flags & IEF_PLUS_OPCODE)
o1&=-8;
o2=tempi->opcode[n++];
if (m=o1-o2)
break;
} else {
if (tempi->flags&IEF_STI)
sv=tempi->opcode[tempi->opcode_cnt-1]>>3&7;
else
sv=tempi->slash_val;
if (sv<8) {
if (!(m=ip[n]>>3&7-sv)) {
if ((Bt(&uasm_mem_mask,a1) || Bt(&uasm_mem_mask,a2)) &&
ip[n]&0xC0==0xC0) {
m=1;
break;
} else if (tempi->flags&IEF_STI) {
if (ip[n]&0xC0!=0xC0) {
m=-1;
break;
}
if (a1!=ARGT_STI && a2!=ARGT_STI)
m=ip[n]&0x7-tempi->opcode[tempi->opcode_cnt-1]&7;
break;
}
if (opsize==16) {
if (tempi->flags & IEF_OP_SIZE32) {
m=-1;
break;
}
} else {
if (tempi->flags & IEF_OP_SIZE16) {
m=1;
break;
}
}
if (opsize==64||a1==ARGT_M64||a2==ARGT_M64||tempi->flags&IEF_NO_REX) {
if (!Bt(&uasm_ins64_mask,a1) && !Bt(&uasm_ins64_mask,a2) && !(tempi->flags&IEF_48_REX))
m=1;
} else {
if (Bt(&uasm_ins64_mask,a1) || Bt(&uasm_ins64_mask,a2) || tempi->flags&IEF_48_REX)
m=-1;
}
}
} else {
m=0;
if (opsize==16) {
if (tempi->flags & IEF_OP_SIZE32) {
m=-1;
break;
}
} else {
if (tempi->flags & IEF_OP_SIZE16) {
m=1;
break;
}
}
if (opsize==64 || a1==ARGT_M64 || a2==ARGT_M64) {
if (!Bt(&uasm_ins64_mask,a1) && !Bt(&uasm_ins64_mask,a2) && !(tempi->flags&IEF_48_REX)&&
!(a2==ARGT_NO &&
(ARGT_UIMM8<=a1<=ARGT_UIMM64 ||
ARGT_IMM8<=a1<=ARGT_IMM64 ) ))
m=1;
else if (tempi->arg2==ARGT_IMM64 || tempi->arg2==ARGT_UIMM64) {
if (a2!=ARGT_IMM64&&a2!=ARGT_UIMM64)
m=1;
} else if (a2==ARGT_IMM64||a2==ARGT_UIMM64)
m=-1;
} else {
if (Bt(&uasm_ins64_mask,a1) || Bt(&uasm_ins64_mask,a2) || tempi->flags&IEF_48_REX)
m=-1;
}
}
break;
}
}
if (m>0) {
if (k==i) {
k=j;
break;
} else
i=k;
} else if (m<0) {
if (k-i<=1) {
k=i;
break;
} else
j=k;
} else
break;
}
return unasm_table[k];
}
U0 UnasmHashLoad()
{
CHashOpcode *temph;
CInstruction *tempi;
I64 cnt=0,j,k;
unasm_table=NULL;
unasm_table_entries=0;
uasm_ins64_mask=0x0880888880+1<<ARGT_ST0+1<<ARGT_STI;
uasm_signed_arg_mask=1<<ARGT_REL8+1<<ARGT_REL16+1<<ARGT_REL32+
1<<ARGT_IMM8+1<<ARGT_IMM16+1<<ARGT_IMM32+1<<ARGT_IMM64;
uasm_mem_mask=1<<ARGT_M8+1<<ARGT_M16+1<<ARGT_M32+1<<ARGT_M64;
temph=asm_hash->next_added;
while (temph!=asm_hash) {
if (temph->type==HTT_OPCODE)
cnt+=temph->instruction_entry_cnt;
temph=temph->next_added;
}
unasm_table_entries=cnt;
j=0;
unasm_table=MAlloc(cnt*sizeof(U8 *));
temph=asm_hash->next_added;
while (temph!=asm_hash) {
if (temph->type==HTT_OPCODE) {
tempi=&temph->ins;
for (k=0;k<temph->instruction_entry_cnt;k++) {
unasm_table[j++]=tempi;
tempi++;
}
}
temph=temph->next_added;
}
QSortI64(unasm_table,cnt,&InstEntriesCompare);
}
I64 StrMatchBits(U8 *st)
{
if (StrMatch("8",st))
return 8;
if (StrMatch("16",st))
return 16;
if (StrMatch("32",st))
return 32;
if (StrMatch("64",st))
return 64;
return 0;
}
U0 Ui(U8 *buf,U8 **_ip,I64 seg_size=64,I64 *_jmp_dst=NULL,Bool just_ins=FALSE)
//Unassembles one instruction
{
I64 i,disp,imm,opsize,opadd,
a1,a2,reloced_a1,reloced_a2,
a1_size=0,a2_size=0,reloced_a1_size,reloced_a2_size,
ModrM=-1,SIB=-1,scale,r1,r2,
Mod=-1,RM1=-1,RM2=-1,REX=-1,REX_r=0,REX_x=0,REX_b=0;
Bool cont;
CInstruction *tempi,*tempi2;
CHashOpcode *tempo;
U8 *ip=*_ip,*ptr,*reloced_a1_st,*reloced_a2_st,*bin_data_area1,*bin_data_area2,
line1[512],line2[512],a1_st[512],a2_st[512],seg_overrides[32];
if (_jmp_dst) *_jmp_dst=-1;
if (seg_size==16) {
opsize=16;
opadd=16;
} else if (seg_size==32) {
opsize=32;
opadd=32;
} else {
opsize=32;
opadd=64;
}
*a1_st=0;
*a2_st=0;
if (!IsRaw && PutSrcLink(ip,1,line1))
CatPrint(line1,"\n");
else
*line1=0;
SPrint(line1+StrLen(line1),"%24tp ",ip);
bin_data_area1=line1+StrLen(line1);
for (i=0;i<6;i++)
CatPrint(line1,"%02X",ip[i]);
CatPrint(line1," ");
SPrint(line2,"%24tp ",ip+6);
bin_data_area2=line2+StrLen(line2);
for (i=6;i<12;i++)
CatPrint(line2,"%02X",ip[i]);
*seg_overrides=0;
cont=TRUE;
do {
switch (*ip++) {
case 0x2E: if (StrLen(seg_overrides)<24) CatPrint(seg_overrides,"CS:"); break;
case 0x36: if (StrLen(seg_overrides)<24) CatPrint(seg_overrides,"SS:"); break;
case 0x3E: if (StrLen(seg_overrides)<24) CatPrint(seg_overrides,"DS:"); break;
case 0x26: if (StrLen(seg_overrides)<24) CatPrint(seg_overrides,"ES:"); break;
case 0x64: if (StrLen(seg_overrides)<24) CatPrint(seg_overrides,"FS:"); break;
case 0x65: if (StrLen(seg_overrides)<24) CatPrint(seg_overrides,"GS:"); break;
case OC_OP_SIZE_PREFIX:
if (opsize==16)
opsize=32;
else
opsize=16;
break;
case OC_ADDR_SIZE_PREFIX:
if (opadd==16)
opadd=32;
else
opadd=16;
break;
sub_switch_start:
case 0x48...0x4F:
opsize=64;
case 0x40...0x47:
sub_switch_end:
REX=*(ip-1);
REX_b=Bt(&REX,0)<<3;
REX_x=Bt(&REX,1)<<3;
REX_r=Bt(&REX,2)<<3;
break;
default:
cont=FALSE;
}
} while (cont);
ip--;
tempi=InstEntryFind(ip,opsize);
if (opsize==32 && seg_size==64) {
tempi2=InstEntryFind(ip,64);
if (tempi2!=tempi &&
tempi2->flags&IEF_REX_ONLY_R8_R15 ||
tempi2->flags&IEF_REX_XOR_LIKE&& ip[1]>>3&7==ip[1]&7)
tempi=tempi2;
}
ip+=tempi->opcode_cnt;
tempo=tempi(U8 *)-tempi->ins_entry_num*sizeof(CInstruction)-offset(CHashOpcode.ins);
if (just_ins)
*line1=0;
CatPrint(line1,tempo->str);
a1=tempi->arg1;
a2=tempi->arg2;
if (a1_size=StrMatchBits(DefineSub(a1,"ST_ARG_TYPES"))) {
if (Bt(&uasm_signed_arg_mask,a1))
CatPrint(a1_st,"I%d ",a1_size);
else
CatPrint(a1_st,"U%d ",a1_size);
}
if (a2_size=StrMatchBits(DefineSub(a2,"ST_ARG_TYPES"))) {
if (Bt(&uasm_signed_arg_mask,a2))
CatPrint(a2_st,"I%d ",a2_size);
else
CatPrint(a2_st,"U%d ",a2_size);
}
if (tempi->flags & IEF_PLUS_OPCODE) {
ip--;
RM1=*ip++ - tempi->opcode[tempi->opcode_cnt-1]+REX_b;
ptr=NULL;
if (ARGT_R8<=a1<=ARGT_R64) {
if (a1_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (a1_size==16)
ptr="ST_U16_REGS";
else if (a1_size==32)
ptr="ST_U32_REGS";
else if (a1_size==64)
ptr="ST_U64_REGS";
if (ptr)
CatPrint(a1_st,"%Z",RM1,ptr);
} else {
if (a2_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (a2_size==16)
ptr="ST_U16_REGS";
else if (a2_size==32)
ptr="ST_U32_REGS";
else if (a2_size==64)
ptr="ST_U64_REGS";
if (ptr)
CatPrint(a2_st,"%Z",RM1,ptr);
}
}
if (ARGT_RM8<=a1<=ARGT_RM64 ||
ARGT_M8<=a1<=ARGT_M64 ||
ARGT_RM8<=a2<=ARGT_RM64 ||
ARGT_M8<=a2<=ARGT_M64) {
if (ARGT_RM8<=a2<=ARGT_RM64 ||
ARGT_M8<=a2<=ARGT_M64) {
reloced_a1=a2;
reloced_a2=a1;
reloced_a1_size=a2_size;
reloced_a2_size=a1_size;
reloced_a1_st=a2_st;
reloced_a2_st=a1_st;
} else {
reloced_a1=a1;
reloced_a2=a2;
reloced_a1_size=a1_size;
reloced_a2_size=a2_size;
reloced_a1_st=a1_st;
reloced_a2_st=a2_st;
}
CatPrint(reloced_a1_st,seg_overrides);
ModrM=*ip++;
Mod=ModrM>>6 & 3;
RM1=ModrM & 7+REX_b;
RM2=ModrM>>3 & 7+REX_r;
if (Mod<3 && RM1&7==4)
SIB=*ip++;
if (Mod==1) {
disp=*ip(U8 *)++;
CatPrint(reloced_a1_st,"%02X",disp);
} else if (Mod==2) {
disp=*ip(U32 *)++;
CatPrint(reloced_a1_st,"%08X",disp);
}
if (tempi->slash_val<8)
RM2=-1;
else {
ptr=NULL;
if (reloced_a2==ARGT_SREG) {
if (RM2<=5)
ptr="ST_SEG_REGS";
} else if (!(ARGT_IMM8<=reloced_a2<=ARGT_IMM64) &&
!(ARGT_UIMM8<=reloced_a2<=ARGT_UIMM64)) {
if (reloced_a2_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (reloced_a2_size==16)
ptr="ST_U16_REGS";
else if (reloced_a2_size==32)
ptr="ST_U32_REGS";
else if (reloced_a2_size==64)
ptr="ST_U64_REGS";
}
if (ptr)
CatPrint(reloced_a2_st,"%Z",RM2,ptr);
}
if (RM1&7==5 && !Mod) {
disp=*ip(I32 *)++;
if (seg_size==64) {
disp+=ip;
if (reloced_a2==ARGT_IMM8 || reloced_a2==ARGT_UIMM8)
disp++;
else if (reloced_a2==ARGT_IMM16 || reloced_a2==ARGT_UIMM16)
disp+=2;
else if (reloced_a2==ARGT_IMM32 || reloced_a2==ARGT_UIMM32)
disp+=4;
else if (reloced_a2==ARGT_IMM64 || reloced_a2==ARGT_UIMM64)
disp+=8;
}
CatPrint(reloced_a1_st,"[%X]",disp);
RM1=-1;
} else {
if (Mod<3) {
if (RM1&7==4) {
RM1=-1;
r1=SIB & 7+REX_b;
r2=SIB>>3 & 7+REX_x;
scale=SIB>>6 &3;
if (scale==3)
scale=8;
else if (scale==2)
scale=4;
else if (scale==1)
scale=2;
else
scale=1;
if (seg_size==64)
ptr="ST_U64_REGS";
else
ptr="ST_U32_REGS";
if (r1==REG_RBP && !Mod) {
disp=*ip(U32 *)++;
CatPrint(reloced_a1_st,"%08X[%Z*%d]",disp,r2,ptr,scale);
} else if (r2==4)
CatPrint(reloced_a1_st,"[%Z]",r1,ptr);
else
CatPrint(reloced_a1_st,"[%Z+%Z*%d]",r1,ptr,r2,ptr,scale);
} else {
if (opadd==16)
ptr="ST_U16_REGS";
else if (opadd==32)
ptr="ST_U32_REGS";
else
ptr="ST_U64_REGS";
CatPrint(reloced_a1_st,"[%Z]",RM1,ptr);
}
} else {
ptr=NULL;
if (reloced_a1_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (reloced_a1_size==16)
ptr="ST_U16_REGS";
else if (reloced_a1_size==32)
ptr="ST_U32_REGS";
else if (reloced_a1_size==64)
ptr="ST_U64_REGS";
if (ptr)
CatPrint(reloced_a1_st,DefineSub(RM1,ptr));
}
}
}
switch (a1) {
case ARGT_IMM8:
case ARGT_UIMM8:
imm=*ip(U8 *)++;
CatPrint(a1_st,"%02X",imm);
if (tempi->opcode[0]==0xCD && (ptr=DefineSub(imm,"ST_INT_NAMES")))
CatPrint(a1_st," %s",ptr);
break;
case ARGT_IMM16:
case ARGT_UIMM16:
CatPrint(a1_st,"%04X",*ip(U16 *)++);
break;
case ARGT_IMM32:
case ARGT_UIMM32:
CatPrint(a1_st,"%08X",*ip(U32 *)++);
break;
case ARGT_IMM64:
case ARGT_UIMM64:
CatPrint(a1_st,"%016X",*ip(I64 *)++);
break;
case ARGT_REL8:
disp=*ip(I8 *)++;
disp+=ip;
if (IsDbg)
CatPrint(a1_st,"%p ",disp);
else
CatPrint(a1_st,"%P ",disp);
if (_jmp_dst) *_jmp_dst=disp;
break;
case ARGT_REL16:
disp=*ip(I16 *)++;
disp+=ip;
if (IsDbg)
CatPrint(a1_st,"%p ",disp);
else
CatPrint(a1_st,"%P ",disp);
if (_jmp_dst) *_jmp_dst=disp;
break;
case ARGT_REL32:
disp=*ip(I32 *)++;
disp+=ip;
if (IsDbg)
CatPrint(a1_st,"%p ",disp);
else
CatPrint(a1_st,"%P ",disp);
if (_jmp_dst) *_jmp_dst=disp;
break;
case ARGT_MOFFS8...ARGT_MOFFS64:
CatPrint(a1_st,seg_overrides);
if (a1_size==8)
disp=*ip(U8 *)++;
else if (opadd==16)
disp=*ip(U16 *)++;
else
disp=*ip(U32 *)++;
CatPrint(a1_st,"[%X]",disp);
break;
case ARGT_AL ... ARGT_DX:
case ARGT_SS ... ARGT_ST0:
CatPrint(a1_st,"%z",a1-ARGT_AL,
"AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
break;
case ARGT_STI:
ip--;
CatPrint(a1_st,"%Z",*ip++ - tempi->opcode[tempi->opcode_cnt-1],"ST_FSTK_REGS");
break;
}
switch (a2) {
case ARGT_IMM8:
case ARGT_UIMM8:
CatPrint(a2_st,"%02X",*ip(U8 *)++);
break;
case ARGT_IMM16:
case ARGT_UIMM16:
CatPrint(a2_st,"%04X",*ip(U16 *)++);
break;
case ARGT_IMM32:
case ARGT_UIMM32:
CatPrint(a2_st,"%08X",*ip(U32 *)++);
break;
case ARGT_IMM64:
case ARGT_UIMM64:
CatPrint(a2_st,"%016X",*ip(I64 *)++);
break;
case ARGT_MOFFS8...ARGT_MOFFS64:
CatPrint(a2_st,seg_overrides);
if (a2_size==8)
disp=*ip(U8 *)++;
else if (opadd==16)
disp=*ip(U16 *)++;
else
disp=*ip(U32 *)++;
CatPrint(a2_st,"[%X]",disp);
break;
case ARGT_AL ... ARGT_DX:
case ARGT_SS ... ARGT_ST0:
CatPrint(a2_st,"%z",a2-ARGT_AL,
"AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
break;
case ARGT_STI:
ip--;
CatPrint(a2_st,"%Z",*ip++ - tempi->opcode[tempi->opcode_cnt-1],"ST_FSTK_REGS");
break;
}
if (tempi->flags&IEF_ENDING_ZERO)
ip++;
if (*a1_st)
CatPrint(line1,"\t%s",a1_st);
if (*a2_st)
CatPrint(line1,",%s",a2_st);
CatPrint(line1,"\n");
CatPrint(line2,"\n");
if (!just_ins) {
for (i=ip-(*_ip)(I64);i<6;i++) {
bin_data_area1[i<<1]=CH_SPACE;
bin_data_area1[i<<1+1]=CH_SPACE;
}
for (i=ip-(*_ip)(I64);i<12;i++) {
bin_data_area2[(i-6)<<1]=CH_SPACE;
bin_data_area2[(i-6)<<1+1]=CH_SPACE;
}
}
StrCpy(buf,line1);
if (!just_ins && ip-(*_ip)(I64)>6)
CatPrint(buf,line2);
*_ip=ip;
}
U8 *U(U8 *ip,I64 cnt=20,I64 seg_size=64)
//Unassembles a num of instructions.
{
I64 i;
U8 buf[1024];
if (seg_size==16)
PrintWarn("16-bit unassembly is not well supported.\n");
"$$HL,1$$";
for (i=0;i<cnt;i++) {
Ui(buf,&ip,seg_size);
"%s",buf;
}
"$$HL,0$$";
return ip;
}
I64 Un(U8 *ip,I64 cnt=0x80,I64 seg_size=64)
//Unassembles a num of bytes
{
I64 i=0;
U8 buf[1024],*end_ip=ip(I64)+cnt;
if (seg_size==16)
PrintWarn("16-bit unassembly is not well supported.\n");
"$$HL,1$$";
while (ip<end_ip) {
Ui(buf,&ip,seg_size);
"%s",buf;
i++;
}
"$$HL,0$$";
return i;
}