Initial (manual) import

This commit is contained in:
minexew committed 2017-01-22 20:26:44 +01:00
1 parent f39611c506
commit 895fe109de
661 files changed
+245862

No files matched your search

File diff suppressed because it is too large. Load diff
+209
View File
@@ -0,0 +1,209 @@
U0 AsmPrsInsFlags(CCmpCtrl *cc,CInst *tmpins)
{
I64 i;
while (TRUE) {
switch (cc->token) {
case TK_IDENT:
if ((i=LstMatch(cc->cur_str,"NO\0CB\0CW\0CD\0CP\0IB\0IW\0ID\0"))>=0) {
tmpins->opcode_modifier=i;
break;
} else
return;
case TK_I64:
if (cc->cur_i64==16)
tmpins->flags|=IEF_OP_SIZE16;
else if (cc->cur_i64==32)
tmpins->flags|=IEF_OP_SIZE32;
else
return;
break;
case '+':
tmpins->flags|=IEF_PLUS_OPCODE;
case '/':
if (Lex(cc)==TK_I64 && cc->cur_i64<8)
tmpins->slash_val=cc->cur_i64;
else if (cc->token==TK_IDENT) {
if (!StrCmp(cc->cur_str,"R"))
tmpins->slash_val=SV_R_REG;
else if (!StrCmp(cc->cur_str,"I"))
tmpins->slash_val=SV_I_REG;
else
return;
} else
return;
break;
case '!': tmpins->flags|=IEF_DONT_SWITCH_MODES; break;
case '&': tmpins->flags|=IEF_DFT; break;
case '%': tmpins->flags|=IEF_NOT_IN_64_BIT; break;
case '=': tmpins->flags|=IEF_48_REX; break;
case '`': tmpins->flags|=IEF_REX_ONLY_R8_R15; break;
case '^': tmpins->flags|=IEF_REX_XOR_LIKE; break;
case '*': tmpins->flags|=IEF_STI_LIKE; break;
case '$$': tmpins->flags|=IEF_ENDING_ZERO; break;
default:
return;
}
Lex(cc);
}
}
U0 AsmHashLoad()
{//See $LK,"::/Compiler/OpCodes.DD"$.
I64 i,j,size,size_max;
CInternalType *tmpit;
CCmpCtrl *cc;
CHashGeneric *tmph;
CHashReg *tmpr;
CHashOpcode *tmpo,*tmpo2,*tmpo_max;
CInst *tmpins;
CHashClass *tmpc;
cmp.size_arg_mask[0]=0x3FF0FFFFFE;
cmp.size_arg_mask[1]=0x1110111112;
cmp.size_arg_mask[2]=0x2220222224;
cmp.size_arg_mask[4]=0x0440444448;
cmp.size_arg_mask[8]=0x0880888880;
cmp.asm_hash=HashTableNew(1024);
size_max=offset(CHashOpcode.ins)+sizeof(CInst)<<5;
tmpo_max=MAlloc(size_max);
cc=CmpCtrlNew(FileRead("OpCodes.DD"),,"OpCodes.DD.Z");
cc->htc.hash_table_lst=NULL;
Lex(cc);
while (cc->token) {
if (cc->token!=TK_IDENT)
LexExcept(cc,"Expecting identifier at ");
i=LstMatch(cc->cur_str,"NONE\0R8\0R16\0R32\0R64\0SEG\0FSTK\0"
"MM\0XMM\0OPCODE\0KEYWORD\0ASM_KEYWORD\0");
if (i<=0)
LexExcept(cc,"Unknown Stmt");
Lex(cc); //skip keyword
if (cc->token!=TK_IDENT)
LexExcept(cc,"Expecting identifier at ");
switch (i) {
case REGT_R8...REGT_XMM:
tmpr=CAlloc(sizeof(CHashReg));
tmpr->str=cc->cur_str;
cc->cur_str=NULL;
Lex(cc); //skip keyword name
if (cc->token!=TK_I64)
LexExcept(cc,"Expecting int at ");
tmpr->type=HTT_REG;
tmpr->reg_type=i;
tmpr->reg_num=cc->cur_i64;
HashAdd(tmpr,cmp.asm_hash);
Lex(cc); //Skip INT
break;
case: //OPCODE
if (cc->token!=TK_IDENT)
LexExcept(cc,"Expecting opcode at ");
MemSet(tmpo_max,0,size_max);
tmpo_max->type=HTT_OPCODE;
tmpo_max->inst_entry_cnt=0;
tmpo_max->str=cc->cur_str;
cc->cur_str=0;
Lex(cc); //Skip OPCODE
while (cc->token && cc->token!=';' && cc->token!=':') {
tmpins=&tmpo_max->ins[tmpo_max->inst_entry_cnt];
tmpins->ins_entry_num=tmpo_max->inst_entry_cnt++;
tmpins->slash_val=SV_NONE; //Not zero!!
while (cc->token==TK_I64) {
tmpins->opcode[tmpins->opcode_cnt++]=cc->cur_i64;
Lex(cc);
}
if (cc->token==',')
Lex(cc);
else if (cc->token!=';')
LexExcept(cc,"Expecting ',' at ");
AsmPrsInsFlags(cc,tmpins);
tmpins->uasm_slash_val=tmpins->slash_val;
if (tmpins->flags&IEF_STI_LIKE && tmpins->slash_val!=SV_I_REG)
tmpins->uasm_slash_val=SV_STI_LIKE;
tmpins->arg1=tmpins->arg2=tmpins->size1=tmpins->size2=0;
if (cc->token==TK_IDENT) {
j=DefineMatch(cc->cur_str,"ST_ARG_TYPES");
tmpins->arg1=j;
if (Bt(&cmp.size_arg_mask[1],j))
tmpins->size1=8;
else if (Bt(&cmp.size_arg_mask[2],j))
tmpins->size1=16;
else if (Bt(&cmp.size_arg_mask[4],j))
tmpins->size1=32;
else if (Bt(&cmp.size_arg_mask[8],j))
tmpins->size1=64;
if (Lex(cc)==TK_IDENT) {
j=DefineMatch(cc->cur_str,"ST_ARG_TYPES");
Lex(cc);
tmpins->arg2=j;
if (Bt(&cmp.size_arg_mask[1],j))
tmpins->size2=8;
else if (Bt(&cmp.size_arg_mask[2],j))
tmpins->size2=16;
else if (Bt(&cmp.size_arg_mask[4],j))
tmpins->size2=32;
else if (Bt(&cmp.size_arg_mask[8],j))
tmpins->size2=64;
}
}
}
size=offset(CHashOpcode.ins)+sizeof(CInst)*tmpo_max->inst_entry_cnt;
tmpo=MAlloc(size);
MemCpy(tmpo,tmpo_max,size);
tmpo->use_cnt=0;
if (HashFind(tmpo->str,cmp.asm_hash,HTT_OPCODE))
LexExcept(cc,"Duplicate OPCODE entry ");
HashAdd(tmpo,cmp.asm_hash);
//Parse aliases.
if (cc->token==':') {
while (Lex(cc)==TK_IDENT) {
tmpo2=MAllocIdent(tmpo);
tmpo2->str=cc->cur_str;
cc->cur_str=0;
tmpo2->oc_flags|=OCF_ALIAS;
if (HashFind(tmpo2->str,cmp.asm_hash,HTT_OPCODE))
LexExcept(cc,"Duplicate OPCODE ALIAS entry ");
HashAdd(tmpo2,cmp.asm_hash);
}
}
break;
case: //KEYWORD
case: //ASM_KEYWORD
tmph=CAlloc(sizeof(CHashGeneric));
tmph->str=cc->cur_str;
cc->cur_str=NULL;
Lex(cc); //skip keyword name
if (cc->token!=TK_I64)
LexExcept(cc,"Expecting int at ");
tmph->user_data0=cc->cur_i64;
if (i==10)
tmph->type=HTT_KEYWORD;
else
tmph->type=HTT_ASM_KEYWORD;
HashAdd(tmph,cmp.asm_hash);
Lex(cc); //Skip INT
break;
}
if (cc->token!=';')
LexExcept(cc,"Missing ';' at");
Lex(cc); //Skip ';'
}
Free(tmpo_max);
CmpCtrlDel(cc);
for (i=0;i<INTERNAL_TYPES_NUM;i++) {
tmpit=&internal_types_table[i];
tmpc=PrsClassNew;
tmpc->type=HTT_INTERNAL_TYPE;
tmpc->raw_type=tmpit->type;
Bts(&tmpc->flags,Cf_INTERNAL_TYPE);
tmpc->size=tmpit->size;
tmpc->str=AStrNew(tmpit->name);
HashAdd(tmpc,cmp.asm_hash);
cmp.internal_types[tmpc->raw_type]=tmpc;
}
adam_task->hash_table->next=cmp.asm_hash;
}
+175
View File
@@ -0,0 +1,175 @@
U0 AOTStoreCodeU8(CCmpCtrl *cc,U8 b)
{
CAOTCtrl *aotc=cc->aotc;
I64 i=aotc->rip>>AOT_BIN_BLK_BITS;
CAOTBinBlk *tmpbin=aotc->bin;
while (i--)
if (!(tmpbin=tmpbin->next)) {
i=aotc->rip>>AOT_BIN_BLK_BITS+1;
tmpbin=&aotc->bin;
while (i--) {
if (!tmpbin->next)
tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
tmpbin=tmpbin->next;
}
break;
}
tmpbin->body[aotc->rip++ & (AOT_BIN_BLK_SIZE-1)]=b;
if (aotc->lst) {
if (aotc->lst_col>=24) {
'\n';
aotc->lst_col=0;
}
"%02X ",b;
aotc->lst_col+=3;
}
if (aotc->rip>aotc->num_bin_U8s)
aotc->num_bin_U8s=aotc->rip;
}
U0 AOTStoreCodeU32(CCmpCtrl *cc,U32 d)
{
CAOTCtrl *aotc=cc->aotc;
I64 i=aotc->rip>>AOT_BIN_BLK_BITS,j=(aotc->rip+sizeof(U32))>>AOT_BIN_BLK_BITS;
U32 *_d;
CAOTBinBlk *tmpbin;
if (i!=j)
for (i=0;i<sizeof(U32);i++)
AOTStoreCodeU8(cc,d.u8[i]);
else {
tmpbin=aotc->bin;
while (i--)
if (!(tmpbin=tmpbin->next)) {
i=aotc->rip>>AOT_BIN_BLK_BITS+1;
tmpbin=&aotc->bin;
while (i--) {
if (!tmpbin->next)
tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
tmpbin=tmpbin->next;
}
break;
}
_d=tmpbin->body+ aotc->rip&(AOT_BIN_BLK_SIZE-1);
*_d=d;
aotc->rip+=sizeof(U32);
if (aotc->lst) {
if (aotc->lst_col>=24) {
'\n';
aotc->lst_col=0;
}
"%08X ",d;
aotc->lst_col+=9;
}
if (aotc->rip>aotc->num_bin_U8s)
aotc->num_bin_U8s=aotc->rip;
}
}
U0 AOTStoreCodeU64(CCmpCtrl *cc,U64 q)
{
CAOTCtrl *aotc=cc->aotc;
I64 i=aotc->rip>>AOT_BIN_BLK_BITS,
j=(aotc->rip+sizeof(I64))>>AOT_BIN_BLK_BITS, *_q;
CAOTBinBlk *tmpbin;
if (i!=j)
for (i=0;i<sizeof(I64);i++)
AOTStoreCodeU8(cc,q.u8[i]);
else {
tmpbin=aotc->bin;
while (i--)
if (!(tmpbin=tmpbin->next)) {
i=aotc->rip>>AOT_BIN_BLK_BITS+1;
tmpbin=&aotc->bin;
while (i--) {
if (!tmpbin->next)
tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
tmpbin=tmpbin->next;
}
break;
}
_q=tmpbin->body+ aotc->rip&(AOT_BIN_BLK_SIZE-1);
*_q=q;
aotc->rip+=sizeof(I64);
if (aotc->lst) {
if (aotc->lst_col>=24) {
'\n';
aotc->lst_col=0;
}
"%016X ",q;
aotc->lst_col+=17;
}
if (aotc->rip>aotc->num_bin_U8s)
aotc->num_bin_U8s=aotc->rip;
}
}
U0 AOTStoreCodeU8At(CCmpCtrl *cc,I64 rip,...)
{
CAOTCtrl *aotc=cc->aotc;
CAOTBinBlk *tmpbin;
I64 i,j;
for (j=0;j<argc;j++) {
i=rip>>AOT_BIN_BLK_BITS+1;
tmpbin=&aotc->bin;
while (i--) {
if (!tmpbin->next) {
tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
tmpbin->next->next=NULL;
}
tmpbin=tmpbin->next;
}
tmpbin->body[rip++ & (AOT_BIN_BLK_SIZE-1)]=argv[j];
}
if (rip>aotc->num_bin_U8s)
aotc->num_bin_U8s=rip;
}
I64 AsmLexExpression(CCmpCtrl *cc)
{
U8 *machine_code;
I64 res=0;
cc->asm_undef_hash=NULL;
cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);
cc->abs_cnts=0;
if (!IsLexExpression2Bin(cc,&machine_code))
LexSkipEol(cc);
else {
if (cc->abs_cnts.externs)
LexExcept(cc,"Extern Not Allowed at ");
if (cc->flags & CCF_UNRESOLVED)
LexExcept(cc,"Undefined sym at ");
res=Call(machine_code);
Free(machine_code);
}
return res;
}
U0 AsmLineLst(CCmpCtrl *cc)
{
CAOTCtrl *aotc=cc->aotc;
CLexFile *tmpf=cc->lex_include_stk;
CDocEntry *doc_e=tmpf->line_start,*doc_e2;
if (aotc->lst && aotc->lst_last_lfn==tmpf && doc_e) {
if (doc_e2=aotc->lst_last_line) {
if (tmpf->flags& LFSF_DOC) {
while (doc_e2->y<doc_e->y) {
"%h*c%08X ",24-aotc->lst_col,CH_SPACE,aotc->lst_last_rip;
aotc->lst_col=0;
doc_e2=LexPutLine(cc,doc_e2);
}
} else {
while (*doc_e2(U8 *) && doc_e2!=doc_e) {
"%h*c%08X ",24-aotc->lst_col,CH_SPACE,aotc->lst_last_rip;
aotc->lst_col=0;
doc_e2=LexPutLine(cc,doc_e2);
}
}
aotc->lst_last_line=doc_e2;
} else
aotc->lst_last_line=doc_e;
} else {
aotc->lst_last_line=NULL;
aotc->lst_last_lfn=tmpf;
}
aotc->lst_last_rip=aotc->rip;
}
+217
View File
@@ -0,0 +1,217 @@
U0 AsmResolve(CCmpCtrl *cc,CAsmUnresolvedRef *tmpu,U8 *label,Bool undefined)
{
CAOTImportExport *tmpie;
CAsmUndefHash *tmpauh;
I64 res=Call(tmpu->machine_code);
if (undefined) {
tmpauh=tmpu->asm_undef_hash;
while (tmpauh) {
if (tmpauh->hash->type & HTF_UNRESOLVED) {
tmpie=CAlloc(sizeof(CAOTImportExport));
tmpie->next=tmpauh->hash->ie_lst;
tmpauh->hash->ie_lst=tmpie;
tmpie->rip=tmpu->rip;
tmpie->aot=cc->aot;
tmpie->type=tmpu->type;
}
tmpauh=tmpauh->next; //Technically, more than one won't work.
}
} else if (!(tmpu->type&IEF_IMM_NOT_REL)) {
res-=tmpu->rel_rip;
if (tmpu->type==IET_REL_I8 && !(I8_MIN<=res<=I8_MAX) ||
tmpu->type==IET_REL_I16 && !(I16_MIN<=res<=I16_MAX)) {
PrintErr("Branch out of range at line:%04d %s\n",
tmpu->line_num,label);
LexExcept(cc);
}
if (tmpu->U8_avail && tmpu->type>IET_IMM_U8 && -124<=res<=123)
PrintWarn("could use I8 displacement at line:%04d %s %s\n",
tmpu->line_num,cc->aotc->last_label,label);
}
AOTStoreCodeU8At(cc,tmpu->rip,res.u8[0]);
if (tmpu->type>=IET_REL_I16) {
AOTStoreCodeU8At(cc,tmpu->rip+1,res.u8[1]);
if (tmpu->type>=IET_REL_I32) {
AOTStoreCodeU8At(cc,tmpu->rip+2,res.u8[2],res.u8[3]);
if (tmpu->type>=IET_REL_I64)
AOTStoreCodeU8At(cc,tmpu->rip+4,res.u8[4],res.u8[5],
res.u8[6],res.u8[7]);
}
}
}
U0 AOTLocalsResolve(CCmpCtrl *cc)
{
CAOTCtrl *aotc=cc->aotc;
CAsmUnresolvedRef *tmpu=aotc->local_unresolved,*tmpu1;
CAsmUndefHash *tmpauh;
Bool undefined;
U8 *label=NULL;
while (tmpu) {
undefined=FALSE;
tmpu1=tmpu->next;
tmpauh=tmpu->asm_undef_hash;
while (tmpauh) {
if (tmpauh->hash->type & HTF_UNRESOLVED) {
PrintErr("Undefined sym at line:%04d %s %s\n",
tmpu->line_num,aotc->last_label,tmpauh->hash->str);
LexExcept(cc);
}
label=tmpauh->hash->str;
tmpauh=tmpauh->next;
}
if (!undefined)
AsmResolve(cc,tmpu,label,FALSE);
Free(tmpu->machine_code);
LinkedLstDel(tmpu->asm_undef_hash);
Free(tmpu);
tmpu=tmpu1;
}
HashTableDel(cc->htc.local_hash_table);
cc->htc.hash_table_lst=cc->htc.local_hash_table=HashTableNew(16);
cc->htc.local_hash_table->next=cc->htc.glbl_hash_table;
aotc->local_unresolved=NULL;
}
U0 AOTGlblsResolve(CCmpCtrl *cc,CAOT *tmpaot)
{
CAOTCtrl *aotc=cc->aotc;
CHashFun *tmpf;
CAsmUnresolvedRef *tmpu=aotc->glbl_unresolved,*tmpu1;
I64 i,j;
CAOTImportExport *tmpie,*tmpie1;
CAsmUndefHash *tmpauh;
CHashExport *tmpex;
U8 *label;
Bool undefined;
CExternUsage *tmpeu,*tmpeu8;
while (tmpu) {
label=NULL;
undefined=FALSE;
tmpu1=tmpu->next;
tmpauh=tmpu->asm_undef_hash;
while (tmpauh) {
if (tmpauh->hash->type & HTF_UNRESOLVED) {
tmpex=tmpauh->hash;
if (tmpex->type & HTT_EXPORT_SYS_SYM&& tmpex->type & HTF_UNRESOLVED &&
!(tmpex->type & HTF_IMPORT) &&
(tmpf=HashFind(tmpex->str,cc->htc.hash_table_lst,HTT_FUN)) &&
!Bt(&tmpf->flags,Cf_EXTERN)) {
tmpex->val=tmpf->exe_addr;
tmpex->type&=~HTF_UNRESOLVED;
label=tmpauh->hash->str;
} else {
if (!(tmpex->type & HTF_IMPORT)) {
if (cc->htc.local_var_lst) {
tmpex->type|=HTF_GOTO_LABEL;
tmpex->use_cnt++;
} else {
PrintErr("Undefined sym at line:%04d %s\n",
tmpu->line_num,tmpex->str);
LexExcept(cc);
}
} else if (undefined) {
PrintErr("Two imports in same expression "
"not allowed at line:%04d %s\n",
tmpu->line_num,tmpex->str);
LexExcept(cc);
}
undefined=TRUE;
}
} else
label=tmpauh->hash->str;
tmpauh=tmpauh->next;
}
AsmResolve(cc,tmpu,label,undefined);
Free(tmpu->machine_code);
LinkedLstDel(tmpu->asm_undef_hash);
Free(tmpu);
tmpu=tmpu1;
}
for (i=0;i<=cc->htc.glbl_hash_table->mask;i++) {
tmpex=cc->htc.glbl_hash_table->body[i];
while (tmpex) {
if (tmpex->type & (HTF_IMPORT|HTF_GOTO_LABEL)) {
if (tmpex->use_cnt && (tmpie=tmpex->ie_lst)) {
if (tmpex->type&HTF_GOTO_LABEL)
tmpie->flags|=IEF_GOTO_LABEL;
if (tmpex->import_name)
tmpie->str=StrNew(tmpex->import_name);
else
tmpie->str=StrNew(tmpex->str);
do {
tmpie1=tmpie->next;
QueIns(tmpie,tmpaot->last_ie);
} while (tmpie=tmpie1);
tmpex->ie_lst=NULL;
}
} else if (tmpex->type & (HTF_EXPORT|HTF_RESOLVE)) {
if (tmpex->type & HTF_UNRESOLVED) {
PrintErr("Undefined sym at %s\n",tmpex->str);
LexExcept(cc);
}
if (tmpex->type & HTF_RESOLVE) {
tmpf=tmpex;
tmpeu=tmpf->ext_lst;
while (tmpeu) {
tmpeu8=tmpeu->next;
j=tmpf->exe_addr-(tmpeu->rip+4);
AOTStoreCodeU8At(cc,tmpeu->rip,j.u8[0],j.u8[1],j.u8[2],j.u8[3]);
Free(tmpeu);
tmpeu=tmpeu8;
}
}
if (tmpex->type & HTF_EXPORT) {
tmpie=CAlloc(sizeof(CAOTImportExport));
tmpie->type=IET_REL32_EXPORT;
if (tmpex->type & HTT_FUN)
tmpie->rip=tmpf->exe_addr;
else if (tmpex->type & HTT_GLBL_VAR)
tmpie->rip=tmpex(CHashGlblVar *)->data_addr_rip;
else
tmpie->rip=tmpex->val;
tmpie->aot=cc->aot;
if (tmpex->type & HTF_IMM)
tmpie->type++;
tmpie->str=StrNew(tmpex->str);
tmpie->src_link=StrNew(tmpex->src_link);
QueIns(tmpie,tmpaot->last_ie);
}
}
tmpex=tmpex->next;
}
}
}
U0 AsmUnresolvedAdd(CCmpCtrl *cc,U8 *machine_code,I64 type,I64 rip,I64 rel_rip,
CAsmUndefHash *local_asm_undef_hash,CAsmUndefHash *glbl_asm_undef_hash,
I64 line_num,Bool U8_avail)
{
CAsmUnresolvedRef *tmpu=MAlloc(sizeof(CAsmUnresolvedRef));
tmpu->machine_code=machine_code;
tmpu->type=type;
tmpu->rip=rip;
tmpu->rel_rip=rel_rip;
tmpu->aot=cc->aot;
tmpu->imm_flag=FALSE;
tmpu->line_num=line_num;
tmpu->U8_avail=U8_avail;
tmpu->str=NULL;
if (local_asm_undef_hash) {
tmpu->asm_undef_hash=local_asm_undef_hash;
tmpu->next=cc->aotc->local_unresolved;
cc->aotc->local_unresolved=tmpu;
} else {
tmpu->asm_undef_hash=glbl_asm_undef_hash;
tmpu->next=cc->aotc->glbl_unresolved;
cc->aotc->glbl_unresolved=tmpu;
if (glbl_asm_undef_hash->hash->type & HTF_IMPORT) {
tmpu->str=StrNew(glbl_asm_undef_hash->hash->str);
if (glbl_asm_undef_hash->hash->type & HTF_IMM)
tmpu->imm_flag=TRUE;
}
}
}
+658
View File
@@ -0,0 +1,658 @@
U0 ICAddEct(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,I64 op,I64 rip)
{
I64 i,tmp,res_reg=REG_RAX;
Bool swap=FALSE;
if (r3!=res_reg) {
swap^=TRUE;
SwapI64(&t2,&t3);
SwapI64(&r2,&r3);
SwapI64(&d2,&d3);
}
if (t2.raw_type>=RT_I64 && r2!=res_reg && t2&MDG_REG_DISP_SIB_RIP) {
if (t1&MDF_REG && !(r2==r1 && t2&MDG_REG_DISP_SIB))
res_reg=r1;
ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
i=ICModr1(res_reg,t2,r2,d2);
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+op);
ICModr2(tmpi,i,,d2,rip);
} else {
if (t2&MDF_REG)
tmp=r2;
else
tmp=REG_RCX;
if (t1&MDF_REG)
res_reg=r1;
if (tmp==res_reg)
res_reg=REG_RDX;
if (swap) {
if (r3==tmp && t3&MDG_REG_DISP_SIB)
tmp=REG_RCX;
ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t2,r2,d2,rip);
ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
} else {
if (r2==res_reg && t2&MDG_REG_DISP_SIB)
res_reg=REG_RDX;
ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t2,r2,d2,rip);
}
i=0x48;
if (res_reg>7)
i+=4;
if (tmp>7)
i++;
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICU24(tmpi,0xC00000+i+(tmp&7)<<16+(res_reg&7)<<19+op<<8);
}
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
}
U0 ICAddSubEctImm(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
CICType t2,I64 r2,I64 d2,I64 d,I64 op,I64 rip)
{
I64 i;
if (op.u8[0]==0x2B) {
op=0x0003;
d=-d;
}
if (t1&MDF_REG) {
if (!(t2&MDF_REG)) {
ICMov(tmpi,t1,r1,d1,t2,r2,d2,rip);
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(tmpi,0xC0FF00+op.u8[1]<<19+i+(r1&7)<<16);
return;
} else if (d==-1 && op.u8[0]==0x03) {
ICU24(tmpi,0xC8FF00+i+(r1&7)<<16);
return;
} else if (I8_MIN<=d<=I8_MAX) {
ICU24(tmpi,0xC08300+op.u8[1]<<19+i+(r1&7)<<16);
ICU8(tmpi,d);
return;
} else if (I32_MIN<=d<=I32_MAX) {
ICU24(tmpi,0xC08100+op.u8[1]<<19+i+(r1&7)<<16);
ICU32(tmpi,d);
return;
}
}
if (op.u8[0]==0x03 && I32_MIN<=d<=I32_MAX &&
!Bt(&cmp.non_ptr_vars_mask,r2)) {
i=ICModr1(r1,MDF_DISP+RT_I64,r2,d);
i.u8[1]|=0x48;
ICU24(tmpi,i.u8[2]<<16+0x8D00+i.u8[1]);
ICModr2(tmpi,i,,d,rip);
return;
}
}
switch (Bsr(t1)) {
case MDf_REG:
case MDf_DISP:
case MDf_SIB:
case MDf_RIP_DISP32:
if (t1!=t2 || r1!=r2 || d1!=d2) {
ICMov(tmpi,t1,r1,d1,t2,r2,d2,rip);
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;
if (op.u8[0]==0x03 && d==-1) //add -1
op.u8[1]=1; //Decrement slash val
if (op.u8[0]==0x03 && (d==1 || d==-1)) { //Add
i=ICModr1(op.u8[1],t1,r1,d1);
if (!(t1&MDF_REG) && tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
switch (t1.raw_type) {
case RT_I8:
case RT_U8:
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0xFE);
break;
case RT_I16:
case RT_U16:
ICOpSizeRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0xFF);
break;
default:
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0xFF);
}
ICModr2(tmpi,i,,d1,rip);
return;
}
if (I8_MIN<=d<=I8_MAX || t1&(RTG_MASK-RTF_UNSIGNED)==RT_I8) {
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_IMM_U8+op.u8[1],rip+1);
ICU8(tmpi,d);
return;
}
if (I32_MIN<=d<=I32_MAX || t1.raw_type<RT_I64) {
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_IMM_U32+op.u8[1],rip);
if (t1&(RTG_MASK-RTF_UNSIGNED)==RT_I16)
ICU16(tmpi,d);
else
ICU32(tmpi,d);
return;
}
break;
case MDf_STK:
ICAddSubEctImm(tmpi,MDF_REG+RT_I64,REG_RAX,0,t2,r2,d2,d,op,rip);
ICPushRegs(tmpi,1<<REG_RAX);
return;
}
ICAddEct(tmpi,t1,r1,d1,MDF_IMM+RT_I64,0,d,t2,r2,d2,op.u8[0],rip);
}
U0 ICSub(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,I64 rip)
{
I64 i=0x48,op=0x2B;
Bool swap=FALSE;
if (r3!=REG_RAX) {
swap=TRUE;
SwapI64(&t2,&t3);
SwapI64(&r2,&r3);
SwapI64(&d2,&d3);
}
if (t2.raw_type>=RT_I64 && r2.u8[0]!=REG_RAX &&
(!(t2&MDF_SIB) || r2.u8[1]&15!=REG_RAX) && t2&MDG_REG_DISP_SIB_RIP) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
if (!swap) {
op=0x03;
ICU24(tmpi,0xD8F748);
}
i=ICModr1(REG_RAX,t2,r2,d2);
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+op);
ICModr2(tmpi,i,,d2,rip);
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RAX,0,rip);
} else {
if (!(t3&MDF_REG) || t3.raw_type<RT_I64) {
if (swap) {
swap=FALSE;
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
r2=REG_RAX;
r3=REG_RCX;
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
r3=REG_RAX;
r2=REG_RCX;
}
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
r2=REG_RCX;
}
if (swap) {
op=0x03;
ICU24(tmpi,0xD9F748);
}
if (r3>7)
i++;
if (r2>7)
i+=4;
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICU24(tmpi,0xC00000+i+(r3&7)<<16+(r2&7)<<19+op<<8);
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,r2,0,rip);
}
}
U0 ICMul(CIntermediateCode *tmpi,I64 rip)
{
I64 i,r2,r=REG_RAX,j;
CICArg *arg1,*arg2;
Bool alt;
if (tmpi->arg1.type&MDF_IMM) {
arg1=&tmpi->arg2;
arg2=&tmpi->arg1;
alt=TRUE;
} else {
arg1=&tmpi->arg1;
arg2=&tmpi->arg2;
alt=FALSE;
}
i=arg2->disp;
if (!(tmpi->ic_class->raw_type&RTF_UNSIGNED) &&
arg2->type&MDF_IMM && I32_MIN<=i<=I32_MAX) {
if (tmpi->res.type==MDF_REG+RT_I64) {
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
arg1->type,arg1->reg,arg1->disp,rip);
r=tmpi->res.reg;
} else
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,arg1->reg,arg1->disp,rip);
if (r>7)
j=0xC0004D;
else
j=0xC00048;
if (I8_MIN<=i<=I8_MAX)
ICU32(tmpi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
else {
ICU24(tmpi,0x6900+j+(r&7)<<16+(r&7)<<19);
ICU32(tmpi,i);
}
} else {
if (tmpi->ic_class->raw_type&RTF_UNSIGNED)
i=0xE0F748;
else
i=0xE8F748;
if (alt) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,arg1->reg,arg1->disp,rip);
r2=REG_RCX;
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,arg2->reg,arg2->disp,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,arg2->reg,arg2->disp,rip);
if (!(arg1->type&MDF_REG) || arg1->type.raw_type<RT_I64) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
arg1->type,arg1->reg,arg1->disp,rip);
r2=REG_RCX;
} else
r2=arg1->reg;
}
if (r2>7) {
i++;
r2&=7;
}
ICU24(tmpi,i+r2<<16);
}
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,r,0,rip);
}
U0 ICMulEqu(CIntermediateCode *tmpi,I64 rip)
{
I64 i=tmpi->arg2.disp,r=REG_RAX,j;
if (!(tmpi->ic_class->raw_type&RTF_UNSIGNED) &&
tmpi->arg2.type&MDF_IMM && I32_MIN<=i<=I32_MAX) {
if (tmpi->ic_flags & ICF_BY_VAL) {
if (tmpi->arg1.type==MDF_REG+RT_I64)
r=tmpi->arg1.reg;
else
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (r>7)
j=0xC0004D;
else
j=0xC00048;
if (I8_MIN<=i<=I8_MAX)
ICU32(tmpi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
else {
ICU24(tmpi,0x6900+j+(r&7)<<16+(r&7)<<19);
ICU32(tmpi,i);
}
ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,r,0,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
r=REG_RBX;
if (I8_MIN<=i<=I8_MAX)
ICU32(tmpi,i<<24+0xDB6B48);
else {
ICU24(tmpi,0xDB6948);
ICU32(tmpi,i);
}
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
MDF_REG+RT_I64,REG_RBX,0,rip);
}
} else {
if (tmpi->ic_class->raw_type&RTF_UNSIGNED)
i=0xE3F748;
else
i=0xEBF748;
if (tmpi->ic_flags & ICF_BY_VAL) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICU24(tmpi,i);
ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
ICU24(tmpi,i);
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
}
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,r,0,rip);
}
U0 ICDiv(CIntermediateCode *tmpi,I64 rip)
{
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
ICZero(tmpi,REG_RDX);
ICU24(tmpi,0xF1F748);
} else {
ICU16(tmpi,0x9948);
ICU24(tmpi,0xF9F748);
}
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICDivEqu(CIntermediateCode *tmpi,Bool is_mod,I64 rip)
{
if (tmpi->ic_flags & ICF_BY_VAL) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
ICZero(tmpi,REG_RDX);
ICU24(tmpi,0xF1F748);
} else {
ICU16(tmpi,0x9948);
ICU24(tmpi,0xF9F748);
}
if (is_mod)
ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RDX,0,rip);
else
ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
//dangerous might clobber RBX in Mov, but it doesn't
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+tmpi->arg1_type_pointed_to,
REG_RBX,0,rip);
if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
ICZero(tmpi,REG_RDX);
ICU24(tmpi,0xF1F748);
} else {
ICU16(tmpi,0x9948);
ICU24(tmpi,0xF9F748);
}
if (is_mod)
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RBX,0,
MDF_REG+RT_I64,REG_RDX,0,rip);
else
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RBX,0,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
if (tmpi->res.type.mode) {
if (is_mod)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RDX,0,rip);
else
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
}
U0 ICMod(CIntermediateCode *tmpi,I64 rip)
{
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
ICZero(tmpi,REG_RDX);
ICU24(tmpi,0xF1F748);
} else {
ICU16(tmpi,0x9948);
ICU24(tmpi,0xF9F748);
}
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RDX,0,rip);
}
U0 ICAddSubEctEqu(CIntermediateCode *tmpi,U8 type_pointed_to,
CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,
CICType t3,I64 r3,I64 d3,I64 op,I64 rip)
{
Bool done;
I64 res_reg,tmp,i;
if (tmpi->ic_flags & ICF_BY_VAL) {
if (t3&MDF_IMM) {
ICAddSubEctImm(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,t2&MDG_MASK+
type_pointed_to,r2,d2,d3,op,rip);
if (t1.mode)
ICMov(tmpi,t1,r1,d1,t2&MDG_MASK+type_pointed_to,r2,d2,rip);
return;
} else {
done=FALSE;
if (type_pointed_to>=RT_I64) {
if (!t1.mode && t2&MDG_REG_DISP_SIB_RIP) {
if (t3&MDF_REG)
tmp=r3;
else {
tmp=REG_RCX;
ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t3,r3,d3,rip);
}
i=ICModr1(tmp,t2&MDG_MASK+type_pointed_to,r2,d2);
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+op.u8[5]);
ICModr2(tmpi,i,,d2,rip);
return;
}
if (t3.raw_type>=RT_I64 && t3&MDG_REG_DISP_SIB_RIP) {
if (t2&MDF_REG)
res_reg=r2;
else {
res_reg=REG_RCX;
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
}
i=ICModr1(res_reg,t3&MDG_MASK+type_pointed_to,r3,d3);
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+op.u8[0]);
ICModr2(tmpi,i,,d3,rip);
ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
MDF_REG+RT_I64,res_reg,0,rip);
done=TRUE;
}
}
if (!done) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
if (t2&MDF_REG && r2!=REG_RAX)
res_reg=r2;
else {
res_reg=REG_RCX;
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
t2&MDG_MASK+type_pointed_to,r2,d2,rip);
}
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
if (res_reg>7)
ICU8(tmpi,0x4C);
else
ICU8(tmpi,0x48);
ICU16(tmpi,0xC000+op.u8[0]+(res_reg&7)<<11);
ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
MDF_REG+RT_I64,res_reg,0,rip);
}
}
} else {
done=FALSE;
if (t3&MDF_IMM && op.u8[2]) {
if (!d3.u32[1]) {
if (tmpi->ic_flags&ICF_RES_NOT_USED &&
t2&MDF_REG && d3(U64)<=I8_MAX) {
ICSlashOp(tmpi,MDF_DISP+type_pointed_to,r2,0,0x838000+op.u8[4],rip);
ICU8(tmpi,d3);
done=TRUE;
} else if (op.u8[2]==0x24) {//AND
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
MDF_DISP+type_pointed_to,REG_RCX,0,rip);
res_reg=REG_RAX;
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICU16(tmpi,op.u8[3]<<8+0x40);
ICU32(tmpi,d3);
ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
MDF_REG+RT_I64,res_reg,0,rip);
done=TRUE;
} else if (type_pointed_to<RT_I64) {//OR/XOR
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
MDF_DISP+type_pointed_to,REG_RCX,0,rip);
res_reg=REG_RAX;
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
if (d3.u16[1]) {
ICU16(tmpi,op.u8[3]<<8+0x40);
ICU32(tmpi,d3);
} else if (d3.u8[1]) {
ICU24(tmpi,op.u8[3]<<16+0x4000+OC_OP_SIZE_PREFIX);
ICU16(tmpi,d3);
} else {
ICU16(tmpi,op.u8[2]<<8+0x40);
ICU8(tmpi,d3);
}
ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
MDF_REG+RT_I64,res_reg,0,rip);
done=TRUE;
}
}
}
if (!done) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
MDF_DISP+type_pointed_to,REG_RCX,0,rip);
res_reg=REG_RBX;
if (tmpi->ic_flags&ICF_LOCK)
ICU8(tmpi,OC_LOCK_PREFIX);
ICU8(tmpi,0x48);
ICU16(tmpi,0xC000+op.u8[0]+(res_reg&7)<<11);
ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
MDF_REG+RT_I64,res_reg,0,rip);
}
}
if (t1.mode)
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
}
U0 ICShift(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,
I64 us,I64 is,I64 rip)
{
I64 i=0x48,res_reg;
if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
tmpi->ic_flags & ICF_USE_UNSIGNED)
is=us;
if (t1&MDF_REG) {
res_reg=r1;
if (res_reg>7)
i++;
} else
res_reg=REG_RAX;
if (t3&MDF_IMM) {
ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t2,r2,d2,rip);
if (d3==1)
ICU24(tmpi,i+is.u16[2]<<8+(res_reg&7)<<16);
else {
ICU24(tmpi,i+is.u16[0]<<8+(res_reg&7)<<16);
ICU8(tmpi,d3);
}
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t2,r2,d2,rip);
ICU24(tmpi,i+is.u16[1]<<8+(res_reg&7)<<16);
}
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
}
U0 ICShiftEqu(CIntermediateCode *tmpi,U8 type_pointed_to,
CICType t1,I64 r1,I64 d1,
CICType t2,I64 r2,I64 d2,
CICType t3,I64 r3,I64 d3,I64 us,I64 is,I64 rip)
{
I64 res_reg;
if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
tmpi->ic_flags & ICF_USE_UNSIGNED)
is=us;
if (tmpi->ic_flags & ICF_BY_VAL) {
if (!(t3&MDF_IMM))
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
if (t2&MDF_REG)
res_reg=r2;
else {
res_reg=REG_RAX;
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
t2&MDG_MASK+type_pointed_to,r2,d2,rip);
}
if (res_reg>7)
ICU8(tmpi,0x49);
else
ICU8(tmpi,0x48);
if (t3&MDF_IMM) {
if (d3==1)
ICU16(tmpi,is.u16[2]+(res_reg&7)<<8);
else {
ICU16(tmpi,is.u16[0]+(res_reg&7)<<8);
ICU8(tmpi,d3);
}
} else
ICU16(tmpi,is.u16[1]+(res_reg&7)<<8);
ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
MDF_REG+RT_I64,res_reg,0,rip);
} else {
if (!(t3&MDF_IMM))
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,t2,r2,d2,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+type_pointed_to,REG_RDX,0,rip);
res_reg=REG_RAX;
ICU8(tmpi,0x48);
if (t3&MDF_IMM) {
if (d3==1)
ICU16(tmpi,is.u16[2]+(res_reg&7)<<8);
else {
ICU16(tmpi,is.u16[0]+(res_reg&7)<<8);
ICU8(tmpi,d3);
}
} else
ICU16(tmpi,is.u16[1]+(res_reg&7)<<8);
ICMov(tmpi,
MDF_DISP+type_pointed_to,REG_RDX,0,MDF_REG+RT_I64,res_reg,0,rip);
}
if (t1.mode)
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
}
+719
View File
@@ -0,0 +1,719 @@
U0 ICUnaries(CIntermediateCode *tmpi,I64 op,I64 rip)
{
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICNot(CIntermediateCode *tmpi,I64 rip)
{
I64 i;
if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {
i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0xF6); //TEST ?,0xFF
ICModr2(tmpi,i,,tmpi->arg1.disp,rip+1);
ICU8(tmpi,0xFF);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICTest(tmpi,REG_RAX);
}
ICU24(tmpi,0xC0940F); //SETZ AL
ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_U64,REG_RAX,0,rip);
}
U0 ICAndAnd(CIntermediateCode *tmpi,I64 rip)
{
I64 r2;
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r2=REG_RDX;
} else
r2=tmpi->arg1.reg;
ICZero(tmpi,REG_RAX);
ICTest(tmpi,r2);
ICU16(tmpi,0x0874);
ICTest(tmpi,REG_RCX);
ICU16(tmpi,0x0374);
ICU24(tmpi,0xC0FF48);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICOrOr(CIntermediateCode *tmpi,I64 rip)
{
I64 i=0x48,r2;
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r2=REG_RDX;
} else
r2=tmpi->arg1.reg;
if (r2>7) {
i++;
r2&=7;
}
ICZero(tmpi,REG_RAX);
ICU24(tmpi,0xC80B00+i+r2<<16);
ICU16(tmpi,0x0374);
ICU24(tmpi,0xC0FF48);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICXorXor(CIntermediateCode *tmpi,I64 rip)
{
I64 r2;
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (!(tmpi->arg1.type&MDF_REG)) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r2=REG_RDX;
} else
r2=tmpi->arg1.reg;
ICZero(tmpi,REG_RBX);
ICTest(tmpi,r2);
ICU16(tmpi,0x0374);
ICU24(tmpi,0xC3FF48);
ICZero(tmpi,REG_RAX);
ICTest(tmpi,REG_RCX);
ICU16(tmpi,0x0374);
ICU24(tmpi,0xC0FF48);
ICU24(tmpi,0xC33348);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICCmp(CIntermediateCode *tmpi,I64 us,I64 is,I64 rip)
{
I64 r1,d1,r2,i=0x48,j=tmpi->arg2.disp;
if (tmpi->arg2.type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
if (!(tmpi->ic_flags&(ICF_POP_CMP|ICF_PUSH_CMP)) &&
tmpi->arg1.type&MDF_DISP && //TODO
tmpi->arg1.type.raw_type>=RT_I64 && tmpi->arg1.reg!=REG_RAX) {
r1=tmpi->arg1.reg;
d1=tmpi->arg1.disp;
ICZero(tmpi,REG_RAX);
if (r1>7)
i++;
if (I8_MIN<=j<=I8_MAX)
i+=0x388300;
else
i+=0x388100;
if (!d1) {
ICU24(tmpi,0x000000+i+(r1&7)<<16);
} else if (I8_MIN<=d1<=I8_MAX) {
ICU24(tmpi,0x400000+i+(r1&7)<<16);
ICU8(tmpi,d1);
} else {
ICU24(tmpi,0x800000+i+(r1&7)<<16);
ICU32(tmpi,d1);
}
if (I8_MIN<=j<=I8_MAX)
ICU8(tmpi,j);
else
ICU32(tmpi,j);
} else {
if (tmpi->ic_flags & ICF_POP_CMP) {
ICPopRegs(tmpi,1<<REG_RCX);
r1=REG_RCX;
} else {
if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)
r1=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r1=REG_RCX;
}
}
ICZero(tmpi,REG_RAX);
if (r1>7)
i++;
if (I8_MIN<=j<=I8_MAX) {
ICU24(tmpi,0xF88300+i+(r1&7)<<16);
ICU8(tmpi,j);
} else {
ICU24(tmpi,0xF88100+i+(r1&7)<<16);
ICU32(tmpi,j);
}
}
if (tmpi->ic_flags & ICF_PUSH_CMP)
ICPush(tmpi,MDF_IMM+RT_I64,0,j,rip);
if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
tmpi->ic_flags & ICF_USE_UNSIGNED)
is=us;
ICU16(tmpi,0x300+is);
ICU24(tmpi,0xC0FF48);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
} else {
if (tmpi->arg2.type&MDF_REG && tmpi->arg2.reg!=REG_RAX)
r2=tmpi->arg2.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
r2=REG_RCX;
}
if (tmpi->ic_flags & ICF_POP_CMP) {
ICPopRegs(tmpi,1<<REG_RDX);
r1=REG_RDX;
} else {
if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)
r1=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r1=REG_RDX;
}
}
ICZero(tmpi,REG_RAX);
if (r2>7)
i++;
if (r1>7)
i+=4;
if (tmpi->ic_flags & ICF_PUSH_CMP)
ICPushRegs(tmpi,1<<r2);
ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
tmpi->ic_flags & ICF_USE_UNSIGNED)
is=us;
ICU16(tmpi,0x300+is);
ICU24(tmpi,0xC0FF48);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
}
U0 ICBitOps(CIntermediateCode *tmpi,CICArg *arg1,CICArg *arg2,
CIntermediateCode *tmpi2,I64 op,I64 op_imm,I64 rip)
{//TODO:not fully utilizing Modr
Bool res_not_used=ToBool(tmpi2->ic_flags&ICF_RES_NOT_USED);
I64 r1,t2,r2,d2,i=0x48;
if (tmpi->ic_flags & ICF_BY_VAL) {
t2=arg2->type&MDG_MASK+RT_I64; //TODO: check overflow
r2=arg2->reg;
d2=arg2->disp;
if (!(t2&MDG_REG_DISP_SIB_RIP) || !(r2.u8[0]!=REG_RAX&&(!(t2&MDF_SIB) ||
r2.u8[1]&15!=REG_RAX) || res_not_used)) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
t2=MDF_REG+RT_I64;
r2=REG_RCX;
d2=0;
}
if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))
r1=arg1->reg;
else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);
r1=REG_RDX;
} else
r1=0;
} else {
t2=MDF_DISP+RT_I64;
d2=0;
if (arg2->type&MDF_REG && (arg2->reg!=REG_RAX||res_not_used))
r2=arg2->reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip);
r2=REG_RCX;
}
if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))
r1=arg1->reg;
else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);
r1=REG_RDX;
} else
r1=0;
}
if (!res_not_used)
ICZero(tmpi,REG_RAX);
if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)
ICU8(tmpi,OC_LOCK_PREFIX);
if (arg1->type&MDF_IMM && arg1->disp<32)
t2=t2&MDG_MASK+RT_U32;
i=ICModr1(r1,t2,r2,d2);
ICRex(tmpi,i.u8[1]);
if (arg1->type&MDF_IMM && arg1->disp<64) {
ICU24(tmpi,i.u8[2]<<16+op_imm);
ICModr2(tmpi,i,,d2,rip+1);
ICU8(tmpi,arg1->disp);
} else {
ICU24(tmpi,i.u8[2]<<16+op);
ICModr2(tmpi,i,,d2,rip);
}
if (!res_not_used) {
ICU24(tmpi,0xC0920F); //SETC AL
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
}
U0 ICToUpper(CIntermediateCode *tmpi,I64 rip)
{
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICU32(tmpi,0x61F88348);
ICU16(tmpi,0x0A7C);
ICU32(tmpi,0x7AF88348);
ICU16(tmpi,0x047F);
ICU32(tmpi,0xE0C08348);
}
U0 ICToI64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
{
ICFCvt(cc,tmpi,REG_RAX,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,TRUE,CN_INST,rip);
}
U0 ICToF64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
{
ICFCvt(cc,tmpi,REG_RAX,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,FALSE,CN_INST,rip);
}
U0 ICToBool(CCmpCtrl *,CIntermediateCode *tmpi,I64 rip)
{
I64 r;
if (tmpi->arg1.type&MDF_REG)
r=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r=REG_RAX;
}
ICTest(tmpi,r);
ICU24(tmpi,0xC0950F); //SETNZ AL
ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL
}
U0 ICPreIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
{
I64 r;
CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;
if (tmpi->ic_flags & ICF_BY_VAL) {
if (tmpc->ptr_stars_cnt && tmpc1->size!=1) {
ICAddSubEctImm(tmpi,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);
} else
ICSlashOp(tmpi,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
} else {
if (tmpi->arg1.type&MDF_REG)
r=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r=REG_RCX;
}
if (tmpc->ptr_stars_cnt &&
tmpc1->size!=1) {
ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
tmpc1->size,op.u16[3],rip);
} else
ICSlashOp(tmpi,
MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);
}
}
U0 ICPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
{
I64 r;
CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;
if (tmpi->ic_flags & ICF_BY_VAL) {
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (tmpc->ptr_stars_cnt && tmpc1->size!=1)
ICAddSubEctImm(tmpi,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);
else
ICSlashOp(tmpi,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
} else {
if (tmpi->arg1.type&MDF_REG &&
!(tmpi->res.type&MDF_REG && tmpi->res.reg==tmpi->arg1.reg))
r=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r=REG_RCX;
}
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);
if (tmpc->ptr_stars_cnt && tmpc1->size!=1)
ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
MDF_DISP+tmpi->arg1_type_pointed_to,r,0,tmpc1->size,op.u16[3],rip);
else
ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);
}
}
U0 ICDerefPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
{
CICType t;
I64 r;
CHashClass *tmpc1=tmpi->ic_class;
t=tmpi->res.type.raw_type;
if (t>tmpi->arg1_type_pointed_to)
t=tmpi->arg1_type_pointed_to;
if (tmpi->ic_flags & ICF_BY_VAL) {
if (tmpi->arg1.type&MDF_REG)
r=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r=REG_RDX;
}
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_DISP+t,r,0,rip);
if (tmpc1->size!=1)
ICAddSubEctImm(tmpi,
tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,
tmpc1->size,op.u16[3],rip);
else
ICSlashOp(tmpi,tmpi->arg1.type&MDG_MASK+RT_I64,
tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
} else {
if (tmpi->arg1.type&MDF_REG)
r=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r=REG_RCX;
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r,0,rip);
if (tmpc1->size!=1)
ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,r,0,MDF_DISP+RT_I64,r,0,
tmpc1->size,op.u16[3],rip);
else
ICSlashOp(tmpi,MDF_DISP+RT_I64,r,0,op,rip);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_DISP+t,REG_RDX,0,rip);
}
}
U0 ICAssignPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
{
CHashClass *tmpc1=tmpi->ic_class2-1;
I64 r;
if (tmpi->ic_flags & ICF_BY_VAL) {
if (tmpi->arg1.type&MDF_REG)
r=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
r=REG_RDX;
}
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpc1->size!=1 || tmpi->arg1.type&MDF_STK)
ICAddSubEctImm(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
MDF_REG+RT_I64,r,0,tmpc1->size,op.u16[3],rip);
else
ICSlashOp(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_I64,REG_RDX,0,rip);
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpc1->size!=1)
ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,REG_RDX,0,
MDF_REG+RT_I64,REG_RCX,0,tmpc1->size,op.u16[3],rip);
else
ICSlashOp(tmpi,MDF_DISP+RT_I64,REG_RDX,0,op,rip);
}
}
U0 ICCmpAndBranch(CIntermediateCode *tmpi,Bool has_res,I64 rip,
I64 us,I64 is,I64 not_us,I64 not_is,U8 *buf,I64 rip2)
{
I64 r1,r2,i=0x48,j,res_reg;
CICType t1,t2;
Bool short_jmp,swap,done;
CCodeMisc *lb;
CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;
j=arg1->disp;
if (arg1->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
SwapI64(&arg1,&arg2);
swap=TRUE;
us=not_us;
is=not_is;
} else
swap=FALSE;
if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
tmpi->ic_flags & ICF_USE_UNSIGNED)
is=us;
j=arg2->disp;
if (arg2->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
if (!has_res && arg1->type&MDG_REG_DISP_SIB_RIP)
ICAddSubEctImm(tmpi,arg1->type,arg1->reg,arg1->disp,
arg1->type,arg1->reg,arg1->disp,j,0x073B,rip2);
else {
if (arg1->type&MDF_REG)
r1=arg1->reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
arg1->reg,arg1->disp,rip2);
r1=REG_RDX;
}
if (!j) {
if (is.u8[2]==0x7C) {
ICTest(tmpi,r1);
is=0x78880F;
} else if (is.u8[2]==0x7D) {
ICTest(tmpi,r1);
is=0x79890F;
} else if (is.u8[2]==0x74 || is.u8[2]==0x75)
ICTest(tmpi,r1);
else {
if (r1>7)
i++;
ICU24(tmpi,0xF88300+i+(r1&7)<<16);
ICU8(tmpi,j);
}
} else {
if (r1>7)
i++;
if (I8_MIN<=j<=I8_MAX) {
ICU24(tmpi,0xF88300+i+(r1&7)<<16);
ICU8(tmpi,j);
} else {
ICU24(tmpi,0xF88100+i+(r1&7)<<16);
ICU32(tmpi,j);
}
}
}
if (has_res) {
if (!swap) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_IMM+RT_I64,0,j,rip2);
res_reg=REG_RCX;
} else
res_reg=r1;
}
} else {
done=FALSE;
t1=arg1->type;
r1=arg1->reg;
r2=arg2->reg;
t2=arg2->type;
if (t2.raw_type>=RT_I64 && !has_res && t2&MDG_DISP_SIB_RIP) {
if (!(t1&MDF_REG) || t1.raw_type<RT_I64) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,
arg1->reg,arg1->disp,rip2);
r1=REG_RAX;
}
i=ICModr1(r1,t2,r2,arg2->disp);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0x3B);
ICModr2(tmpi,i,,arg2->disp,rip2);
done=TRUE;
} else if (t1.raw_type>=RT_I64 && t1&MDG_REG_DISP_SIB_RIP) {
if (!(t2&MDF_REG) || t2.raw_type<RT_I64) {
if (t1&MDF_REG && r1==REG_RAX) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,
arg2->reg,arg2->disp,rip2);
r2=REG_RCX;
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip2);
r2=REG_RAX;
}
}
i=ICModr1(r2,t1,r1,arg1->disp);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0x39);
ICModr2(tmpi,i,,arg1->disp,rip2);
if (has_res)
res_reg=r2;
done=TRUE;
}
if (!done) {
if (arg2->type&MDF_REG)
r2=arg2->reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip2);
r2=REG_RAX;
}
if (arg1->type&MDF_REG)
r1=arg1->reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
arg1->reg,arg1->disp,rip2);
r1=REG_RCX;
}
if (r2>7)
i++;
if (r1>7)
i+=4;
ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
if (has_res)
res_reg=r2;
}
}
rip+=tmpi->ic_cnt;
lb=OptLabelFwd(tmpi->ic_data);
short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP) {
if(tmpi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
if (I8_MIN<=i<=I8_MAX)
short_jmp=TRUE;
}
if (short_jmp) {
tmpi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP) {
if(tmpi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tmpi,i<<8+is.u8[2]);
} else {
tmpi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(rip+6);
if (lb->flags&CMF_POP_CMP) {
if(tmpi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tmpi,is.u16[0]);
ICU32(tmpi,i);
}
if (has_res)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,res_reg,0,rip2);
}
U0 ICTestAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)
{
I64 i;
Bool short_jmp;
CCodeMisc *lb;
if (!(tmpi->arg1.type&MDF_REG)) {
if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {
i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0xF6);
ICModr2(tmpi,i,,tmpi->arg1.disp,rip2+1);
ICU8(tmpi,0xFF);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
ICTest(tmpi,REG_RAX);
}
} else
ICTest(tmpi,tmpi->arg1.reg);
rip+=tmpi->ic_cnt;
lb=OptLabelFwd(tmpi->ic_data);
short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (I8_MIN<=i<=I8_MAX)
short_jmp=TRUE;
}
if (short_jmp) {
tmpi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,i<<8+is.u8[2]);
} else {
tmpi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(rip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,is.u16[0]);
ICU32(tmpi,i);
}
}
U0 ICFlagBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf)
{
I64 i;
Bool short_jmp;
CCodeMisc *lb;
rip+=tmpi->ic_cnt;
lb=OptLabelFwd(tmpi->ic_data);
short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (I8_MIN<=i<=I8_MAX)
short_jmp=TRUE;
}
if (short_jmp) {
tmpi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,i<<8+is.u8[2]);
} else {
tmpi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(rip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,is.u16[0]);
ICU32(tmpi,i);
}
}
+771
View File
@@ -0,0 +1,771 @@
U0 ICAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)
{
U64 i;
I64 it,t1,r1,d1,r2;
Bool short_jmp,swap,override;
CCodeMisc *lb;
CICArg *arg1,*arg2;
if (tmpi->arg1.type&MDF_IMM) {
swap=TRUE;
arg1=&tmpi->arg2;
arg2=&tmpi->arg1;
} else {
swap=FALSE;
arg1=&tmpi->arg1;
arg2=&tmpi->arg2;
}
if (arg2->type&MDF_IMM && arg2->disp>U32_MAX)
override=TRUE;
else
override=FALSE;
if (arg1->type.raw_type<arg2->type.raw_type)
it=arg1->type.raw_type;
else
it=arg2->type.raw_type;
i=arg2->disp;
if (arg2->type&MDF_IMM && i<=U32_MAX) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,arg1->reg,arg1->disp,rip2);
if (i<=U8_MAX)
ICU16(tmpi,i<<8+0xA8);
else if (i<=U16_MAX)
ICU32(tmpi,i<<16+0xA900+OC_OP_SIZE_PREFIX);
else {
ICU8(tmpi,0xA9);
ICU32(tmpi,i);
}
} else {
t1=MDF_REG+it;
d1=0;
if (swap && !override) {
if (arg1->type&MDF_REG) {
r1=arg1->reg;
swap=TRUE;
} else {
r1=REG_RCX;
swap=FALSE;
}
if (arg2->type&MDF_REG) {
r2=arg2->reg;
swap=FALSE;
} else
r2=REG_RDX;
if (swap) {
if (!(arg1->type&MDF_REG) || r1!=arg1->reg)
ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
if (arg2->type&MDG_REG_DISP_SIB_RIP) {
t1=arg2->type&MDG_MASK+it;
r2=arg2->reg;
d1=arg2->disp;
} else
ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
i=ICModr1(r1,t1,r2,d1);
} else {
if (arg1->type&MDG_REG_DISP_SIB_RIP) {
t1=arg1->type&MDG_MASK+it;
r1=arg1->reg;
d1=arg1->disp;
} else
ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
if (!(arg2->type&MDF_REG) || r2!=arg2->reg)
ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
i=ICModr1(r2,t1,r1,d1);
}
} else {
if (arg2->type&MDF_REG) {
r2=arg2->reg;
swap=FALSE;
} else {
r2=REG_RDX;
swap=TRUE;
}
if (arg1->type&MDF_REG) {
r1=arg1->reg;
swap=TRUE;
} else
r1=REG_RCX;
if (override)
swap=FALSE;
if (swap) {
if (arg2->type&MDG_REG_DISP_SIB_RIP) {
t1=arg2->type&MDG_MASK+it;
r2=arg2->reg;
d1=arg2->disp;
} else
ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
if (!(arg1->type&MDF_REG) || r1!=arg1->reg)
ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
i=ICModr1(r1,t1,r2,d1);
} else {
if (!(arg2->type&MDF_REG) || r2!=arg2->reg)
ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
if (arg1->type&MDG_REG_DISP_SIB_RIP) {
t1=arg1->type&MDG_MASK+it;
r1=arg1->reg;
d1=arg1->disp;
} else
ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
i=ICModr1(r2,t1,r1,d1);
}
}
switch (it) {
case RT_I8:
case RT_U8:
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0x84);
break;
case RT_U16:
case RT_I16:
ICOpSizeRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0x85);
break;
default:
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+0x85);
}
ICModr2(tmpi,i,,d1,rip2);
}
rip+=tmpi->ic_cnt;
lb=OptLabelFwd(tmpi->ic_data);
short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (I8_MIN<=i<=I8_MAX)
short_jmp=TRUE;
}
if (short_jmp) {
tmpi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,i<<8+is.u8[2]);
} else {
tmpi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(rip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,is.u16[0]);
ICU32(tmpi,i);
}
}
U0 ICAssign(CIntermediateCode *tmpi,I64 rip)
{
CIntermediateCode *tmpi1;
if (tmpi->ic_flags & ICF_BY_VAL) {
ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
} else {
if (tmpi->arg1.type&MDF_REG) {
if (!(tmpi1=OptLag1(tmpi)) || tmpi1->ic_code!=IC_ADD_CONST ||
tmpi1->res.type!=MDF_REG+RT_I64 || tmpi1->res.reg!=tmpi->arg1.reg ||
tmpi1->arg1.type!=MDF_REG+RT_I64 ||
tmpi1->arg1.reg!=tmpi->arg1.reg ||
(tmpi->arg2.type&MDF_REG || tmpi->arg2.type&MDF_DISP) &&
tmpi->arg2.reg==tmpi->arg1.reg ||
tmpi->res.type.mode || tmpi1->ic_flags&~ICG_NO_CVT_MASK) {
ICMov(tmpi,
MDF_DISP+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
} else {
tmpi->ic_flags=(tmpi->ic_flags|tmpi1->ic_flags)&
~ICF_CODE_FINAL|ICF_DONT_RESTORE;
tmpi->arg1.disp=tmpi1->ic_data;
OptSetNOP1(tmpi1); //This better not be last pass!
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
}
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
}
}
}
U0 ICBrBitOps(CIntermediateCode *tmpi,I64 rip,
I64 op,I64 op_imm,I64 is,U8 *buf,I64 rip2)
{
I64 i,t,r1,r2,d1,d2,t1,t2;
CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;
Bool short_jmp;
CCodeMisc *lb;
if (tmpi->ic_flags & ICF_BY_VAL) {
if (tmpi->ic_flags&ICF_SWAP && !(arg2->type&MDF_REG) &&
(!(arg2->type&MDF_IMM) ||arg2->disp>63)||
!(tmpi->ic_flags&ICF_SWAP) && arg2->type&MDF_IMM &&
arg2->disp<64 || arg2->type&MDF_STK) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);
t2=MDF_REG+RT_I64;
r2=REG_RCX;
d2=0;
} else {
t2=arg2->type;
if (t2&MDF_IMM && arg2->disp<64)
r2=0;
else
r2=arg2->reg;
d2=arg2->disp;
}
if (!(tmpi->ic_flags&ICF_SWAP) && !(arg1->type&MDF_REG) &&
(!(arg1->type&MDF_IMM) || arg1->disp>63) ||
tmpi->ic_flags&ICF_SWAP && arg1->type&MDF_IMM &&
arg1->disp<64 || arg1->type&MDF_STK) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);
t1=MDF_REG+RT_I64;
r1=REG_RDX;
d1=0;
} else {
t1=arg1->type;
if (t1&MDF_IMM && arg1->disp<64)
r1=0;
else
r1=arg1->reg;
d1=arg1->disp;
}
} else {
t1=MDF_DISP+RT_I64;
t2=MDF_DISP+RT_I64;
d1=0;
d2=0;
if (arg2->type&MDF_REG)
r2=arg2->reg;
else if (!(tmpi->ic_flags&ICF_SWAP) || !(arg2->type&MDF_IMM) ||
arg2->disp>63) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);
r2=REG_RCX;
} else
r2=0;
if (arg1->type&MDF_REG)
r1=arg1->reg;
else if (tmpi->ic_flags&ICF_SWAP ||
!(arg1->type&MDF_IMM) || arg1->disp>63) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);
r1=REG_RDX;
} else
r1=0;
}
if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)
ICU8(tmpi,OC_LOCK_PREFIX);
if (tmpi->ic_flags&ICF_SWAP) {
if (arg2->type&MDF_IMM && arg2->disp<32) {
if (op==0xA30F && arg2->disp<8) {
t=t1&MDG_MASK+RT_U8;
op_imm=0xF6; //TEST
} else
t=t1&MDG_MASK+RT_U32;
} else
t=t1;
i=ICModr1(r2,t,r1,d1);
SwapI64(&arg1,&arg2);
} else {
if (arg1->type&MDF_IMM && arg1->disp<32) {
if (op==0xA30F && arg1->disp<8) {
t=t2&MDG_MASK+RT_U8;
op_imm=0xF6; //TEST
} else
t=t2&MDG_MASK+RT_U32;
} else
t=t2;
i=ICModr1(r1,t,r2,d2);
}
ICRex(tmpi,i.u8[1]);
if (op_imm==0xF6) {//TEST
ICU16(tmpi,i.u8[2]<<8+op_imm);
ICModr2(tmpi,i,,arg2->disp,rip2+1);
ICU8(tmpi,1<<arg1->disp);
if (is==0x72820F)
is=0x75850F;
else
is=0x74840F;
} else if (arg1->type&MDF_IMM && arg1->disp<64) {
ICU24(tmpi,i.u8[2]<<16+op_imm);
ICModr2(tmpi,i,,arg2->disp,rip2+1);
ICU8(tmpi,arg1->disp);
} else {
ICU24(tmpi,i.u8[2]<<16+op);
ICModr2(tmpi,i,,arg2->disp,rip2);
}
rip+=tmpi->ic_cnt;
lb=OptLabelFwd(tmpi->ic_data);
short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
if (I8_MIN<=i<=I8_MAX)
short_jmp=TRUE;
}
if (short_jmp) {
tmpi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,i<<8+is.u8[2]);
} else {
tmpi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(rip+6);
if (lb->flags&CMF_POP_CMP)
i+=8;
ICU16(tmpi,is.u16[0]);
ICU32(tmpi,i);
}
}
U0 ICQueInit(CIntermediateCode *tmpi,I64 rip2)
{
I64 r1;
if (tmpi->arg1.type==MDF_REG+RT_I64)
r1=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
r1=REG_RAX;
}
ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r1,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);
}
U0 ICQueIns(CIntermediateCode *tmpi,I64 rip2)
{
I64 r1,r2;
if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)
r2=tmpi->arg2.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
r2=REG_RAX;
}
if (tmpi->arg1.type==MDF_REG+RT_I64)
r1=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
r1=REG_RDX;
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r2,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,REG_RBX,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);
}
U0 ICQueInsRev(CIntermediateCode *tmpi,I64 rip2)
{
I64 r1,r2;
if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)
r2=tmpi->arg2.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
r2=REG_RAX;
}
if (tmpi->arg1.type==MDF_REG+RT_I64)
r1=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
r1=REG_RDX;
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);
ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,0,MDF_REG+RT_I64,r2,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,r1,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,REG_RBX,0,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);
}
U0 ICQueRem(CIntermediateCode *tmpi,I64 rip2)
{
I64 r1;
if (tmpi->arg1.type==MDF_REG+RT_I64)
r1=tmpi->arg1.reg;
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
r1=REG_RAX;
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);
ICU24(tmpi,0x1A8948);
ICU32(tmpi,sizeof(U8 *)<<24+0x538948);
}
U0 ICMinMax(CIntermediateCode *tmpi,I64 op,I64 rip2)
{
I64 r1,i1=0x48;
if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RAX) {
r1=tmpi->arg2.reg;
if (r1>7) {
i1++;
r1&=7;
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
} else {
if (tmpi->arg1.reg==REG_RAX && tmpi->arg1.type&MDG_REG_DISP_SIB) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
r1=REG_RDX;
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
if (tmpi->arg1.type==MDF_REG+RT_I64) {
r1=tmpi->arg1.reg;
if (r1>7) {
i1++;
r1&=7;
}
} else {
r1=REG_RDX;
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
}
}
}
ICU24(tmpi,0xC03B00+r1<<16+i1);
ICU32(tmpi,0xC0000F00+op<<16+r1<<24+i1);
}
U0 ICSqr(CIntermediateCode *tmpi,I64 op,I64 rip2)
{
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip2);
}
U0 ICModU64(CIntermediateCode *tmpi,I64 rip2)
{
CICType t1;
I64 r1,d1;
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
if (tmpi->arg1.reg!=REG_RAX && tmpi->arg1.reg!=REG_RDX &&
tmpi->arg1.type&MDG_REG_DISP_SIB &&
tmpi->arg1.type.raw_type>=RT_I64) {
t1=tmpi->arg1.type;
r1=tmpi->arg1.reg;
d1=tmpi->arg1.disp;
} else {
t1=MDF_REG+RT_I64;
r1=REG_RBX;
d1=0;
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip2);
ICZero(tmpi,REG_RDX);
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_DIV,rip2);
ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip2);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
MDF_REG+RT_I64,REG_RDX,0,rip2);
}
U0 ICSwap(CIntermediateCode *tmpi,I64 rip2)
{
I64 r1,r2;
if (tmpi->arg1.type&MDF_REG)
r1=tmpi->arg1.reg;
else
r1=REG_RAX;
if (tmpi->arg2.type&MDF_REG)
r2=tmpi->arg2.reg;
else
r2=REG_RAX;
if (r1==r2) {
if (r1==REG_RAX)
r1=REG_RBX;
else
r2=REG_RAX;
}
ICMov(tmpi,MDF_REG+RT_I64,r2,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
ICMov(tmpi,MDF_REG+RT_I64,r1,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
switch (tmpi->ic_code) {
case IC_SWAP_U8:
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U8,r1,0,rip2);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U8,r2,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U8,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U8,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
break;
case IC_SWAP_U16:
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U16,r1,0,rip2);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U16,r2,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U16,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U16,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
break;
case IC_SWAP_U32:
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U32,r1,0,rip2);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U32,r2,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U32,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U32,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
break;
case IC_SWAP_I64:
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U64,r1,0,rip2);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U64,r2,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U64,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
ICMov(tmpi,MDF_DISP+RT_U64,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
break;
}
}
U0 ICAndEqu(CIntermediateCode *tmpi,I64 rip2)
{
I64 i,bit;
if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
tmpi->ic_flags&ICF_RES_NOT_USED) {
i=~tmpi->arg2.disp;
bit=Bsf(i);
if (0<=bit==Bsr(i)) {
tmpi->arg2.disp=bit;
tmpi->arg2.reg=0;
tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xB30F,0x30BA0F,rip2);
return;
}
}
ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x210425240423,rip2);
}
U0 ICOrEqu(CIntermediateCode *tmpi,I64 rip2)
{
I64 i,bit;
if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
tmpi->ic_flags&ICF_RES_NOT_USED) {
i=tmpi->arg2.disp;
bit=Bsf(i);
if (0<=bit==Bsr(i) && i>I8_MAX) {
tmpi->arg2.disp=bit;
tmpi->arg2.reg=0;
tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xAB0F,0x28BA0F,rip2);
return;
}
}
ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x09010D0C010B,rip2);
}
U0 ICXorEqu(CIntermediateCode *tmpi,I64 rip2)
{
I64 i,bit;
if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
tmpi->ic_flags&ICF_RES_NOT_USED) {
i=tmpi->arg2.disp;
bit=Bsf(i);
if (0<=bit==Bsr(i)) {
tmpi->arg2.disp=bit;
tmpi->arg2.reg=0;
tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xBB0F,0x38BA0F,rip2);
return;
}
}
ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x310635340633,rip2);
}
U0 ICSwitch(CIntermediateCode *tmpi,I64 rip,
Bool nobound,CCmpCtrl *cc,U8 *buf,I64 rip2)
{
I64 i,j,cnt,min,max,begin,r;
CCodeMisc *lb;
Bool short_jmp;
CAOTAbsAddr *tmpa;
if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg&7==REG_RSP)
r=REG_RDX;
else
r=tmpi->arg1.reg;
if (nobound)
ICMov(tmpi,MDF_REG+RT_I64,r,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
else {
if (tmpi->arg2.type&MDF_IMM) {
j=tmpi->arg2.disp;
ICMov(tmpi,MDF_REG+RT_I64,r,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
if (I8_MIN<=j<=I8_MAX) {
i=0xF88348+(r&7)<<16;
if (r>7) i++;
ICU24(tmpi,i);
ICU8(tmpi,j);
} else if (I32_MIN<=j<=I32_MAX) {
i=0xF88148+(r&7)<<16;
if (r>7) i++;
ICU24(tmpi,i);
ICU32(tmpi,j);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
i=0xC13B48+(r&7)<<19;
if (r>7) i+=4;
ICU24(tmpi,i);
}
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
ICMov(tmpi,MDF_REG+RT_I64,r,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
i=0xC13B48+(r&7)<<19;
if (r>7) i+=4;
ICU24(tmpi,i);
}
rip+=tmpi->ic_cnt;
lb=tmpi->ic_data(CCodeMisc *)->dft;
short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(rip+2);
if (I8_MIN<=i<=I8_MAX)
short_jmp=TRUE;
}
if (short_jmp) {
tmpi->ic_flags|=ICF_SHORT_JMP;
ICU16(tmpi,(lb->addr-(rip+2))<<8+0x73);
} else {
tmpi->ic_flags&=~ICF_SHORT_JMP;
ICU16(tmpi,0x830F);
ICU32(tmpi,lb->addr-(rip+6));
}
}
lb=tmpi->ic_data;
begin=lb->begin->addr;
if (!buf && begin!=INVALID_PTR) {
min=I64_MAX;
max=I64_MIN;
for (i=0;i<lb->range;i++) {
if (lb->jmp_table[i]->addr==INVALID_PTR) {
min=I64_MIN;
max=I64_MAX;
break;
} else {
j=lb->jmp_table[i]->addr-begin;
min=MinI64(min,j);
max=MaxI64(max,j);
}
}
if (I8_MIN<=min<=max<=I8_MAX)
lb->flags|=CMF_I8_JMP_TABLE;
else if (U8_MIN<=min<=max<=U8_MAX)
lb->flags|=CMF_U8_JMP_TABLE;
else if (I16_MIN<=min<=max<=I16_MAX)
lb->flags|=CMF_I16_JMP_TABLE;
else if (U16_MIN<=min<=max<=U16_MAX)
lb->flags|=CMF_U16_JMP_TABLE;
}
if (lb->flags&CMF_I8_JMP_TABLE) {
if (r<8)
ICU8(tmpi,0x48);
else
ICU8(tmpi,0x49);
ICU24(tmpi,0x98BE0F+(r&7)<<16);
cnt=1;
} else if (lb->flags&CMF_U8_JMP_TABLE) {
if (r<8)
cnt=2;
else {
ICU8(tmpi,0x49);
cnt=1;
}
ICU24(tmpi,0x98B60F+(r&7)<<16);
} else if (lb->flags&CMF_I16_JMP_TABLE) {
if (r<8)
ICU8(tmpi,0x48);
else
ICU8(tmpi,0x4A);
ICU32(tmpi,0x451CBF0F+(r&7)<<27);
cnt=0;
} else if (lb->flags&CMF_U16_JMP_TABLE) {
if (r<8)
cnt=1;
else {
ICU8(tmpi,0x4A);
cnt=0;
}
ICU32(tmpi,0x451CB70F+(r&7)<<27);
} else {
if (r<8)
cnt=2;
else {
ICU8(tmpi,0x42);
cnt=1;
}
ICU24(tmpi,0x851C8B+(r&7)<<19);
}
if (buf && cc->flags&CCF_AOT_COMPILE) {
tmpa=CAlloc(sizeof(CAOTAbsAddr));
tmpa->next=cc->aotc->abss;
tmpa->type=AAT_ADD_U32;
cc->aotc->abss=tmpa;
tmpa->rip=rip2+tmpi->ic_cnt;
ICU32(tmpi,lb->addr+cc->aotc->rip);
} else
ICU32(tmpi,lb->addr+buf);
if (lb->flags&(CMF_I8_JMP_TABLE|CMF_U8_JMP_TABLE|
CMF_I16_JMP_TABLE|CMF_U16_JMP_TABLE)) {
ICU16(tmpi,0xC381); //ADD EBX,0x12345678
if (buf && cc->flags&CCF_AOT_COMPILE) {
tmpa=CAlloc(sizeof(CAOTAbsAddr));
tmpa->next=cc->aotc->abss;
tmpa->type=AAT_ADD_U32;
cc->aotc->abss=tmpa;
tmpa->rip=rip2+tmpi->ic_cnt;
ICU32(tmpi,begin+cc->aotc->rip);
} else
ICU32(tmpi,begin+buf);
} else
cnt+=6;
ICU16(tmpi,0xE3FF); //JMP EBX
for (i=0;i<cnt;i++) //Code must always shrink, not expand
ICU8(tmpi,OC_NOP);
tmpi->ic_flags&=~ICF_CODE_FINAL;
}
U0 ICLocalVarInit(CIntermediateCode *tmpi)
{
ICU24(tmpi,0xC48B48);
ICU16(tmpi,0x5748);
ICU24(tmpi,0xF88B48);
ICU24(tmpi,0xC1C748);
ICU32(tmpi,tmpi->ic_data);
ICU16(tmpi,sys_var_init_val<<8+0xB0);
ICU24(tmpi,0xAA48F3);
ICU16(tmpi,0x5F48);
}
+607
View File
@@ -0,0 +1,607 @@
#define CN_A2 0
#define CN_A1 1
#define CN_INST 2
#define CN_RES 3
U0 CmpNoteFloatOp(CCmpCtrl *cc,CIntermediateCode *tmpi,
Bool dont_pushable,Bool dont_popable,I64 pos)
{
Bool link=FALSE;
if (cc->pass==7 && cc->last_float_op_ic &&
cc->last_dont_popable && dont_pushable) {
switch [pos] {
case CN_A2:
if (cc->last_float_op_ic!=tmpi && cc->dont_push_float)
link=TRUE;
break;
case CN_A1:
if (cc->last_float_op_ic!=tmpi && cc->dont_push_float)
link=TRUE;
break;
case CN_INST:
if (cc->last_float_op_ic!=tmpi) {
if (cc->dont_push_float) {
if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG &&
cc->last_float_op_ic->res.reg!=REG_R8)
tmpi->ic_flags|=ICF_ALT_TEMPLATE;
else
tmpi->ic_flags&=~ICF_ALT_TEMPLATE;
link=TRUE;
}
} else {
if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG &&
cc->last_float_op_pos!=CN_A1)
tmpi->ic_flags|=ICF_ALT_TEMPLATE;
else
tmpi->ic_flags&=~ICF_ALT_TEMPLATE;
link=TRUE;
}
break;
case CN_RES:
if (cc->last_float_op_ic==tmpi && cc->last_float_op_pos==CN_INST)
link=TRUE;
break;
}
if (link) {
if (!Bts(&cc->last_float_op_ic->ic_flags,
ICf_DONT_POP_FLOAT0+cc->last_ic_float_op_num))
cc->last_float_op_ic->ic_flags&=~ICF_CODE_FINAL;
if (!Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0+cc->cur_ic_float_op_num))
tmpi->ic_flags&=~ICF_CODE_FINAL;
}
}
cc->last_float_op_ic=tmpi;
cc->last_dont_pushable=dont_pushable;
cc->last_dont_popable=dont_popable;
cc->last_ic_float_op_num=cc->cur_ic_float_op_num++;
cc->last_float_op_pos=pos;
if (cc->cur_ic_float_op_num>4)
throw('Compiler');
}
U0 CmpSetFloatOpPushPop(CCmpCtrl *cc,CIntermediateCode *tmpi,
Bool *dont_push_float,Bool *dont_pop_float)
{
if (cc->pass==7) {
*dont_push_float=FALSE;
*dont_pop_float =FALSE;
tmpi->ic_flags&=~ICF_CODE_FINAL;
} else {
*dont_push_float=Bt(&tmpi->ic_flags,
ICf_DONT_PUSH_FLOAT0+cc->cur_ic_float_op_num);
*dont_pop_float=Bt(&tmpi->ic_flags,
ICf_DONT_POP_FLOAT0+cc->cur_ic_float_op_num);
}
}
U0 ICCopyTemplate(CCmpCtrl *cc,CIntermediateCode *tmpi,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 (tmpi->ic_flags&ICF_ALT_TEMPLATE)
alt=TRUE;
else
alt=FALSE;
CmpSetFloatOpPushPop(cc,tmpi,&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(&tmpi->ic_body[tmpi->ic_cnt],ptr,i);
if (!off_the_record)
CmpNoteFloatOp(cc,tmpi,dont_pushable,dont_popable,pos);
tmpi->ic_cnt+=i;
}
U0 ICFCvt(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 r1,
CICType t2,I64 r2,I64 d2,Bool to_int,I64 pos,I64 rip)
{
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(cc,tmpi,&dont_push_float,&dont_pop_float);
if (!dont_push_float) {
if (!(t2.raw_type>=RT_I64 && t2&MDG_DISP_SIB_RIP)) {
ICPush(tmpi,t2,r2,d2,rip);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size=8;
} else {
if (!dont_pop_float) {
rsp_size=8;
ICAddRSP(tmpi,-8);
}
}
ICSlashOp(tmpi,t2,r2,d2,op1,rip);
} else {
if (!dont_pop_float) {
rsp_size=8;
ICAddRSP(tmpi,-8);
}
}
if (to_int)
CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,pos);
else
CmpNoteFloatOp(cc,tmpi,FALSE,TRUE,pos);
if (dont_pop_float) {
if (rsp_size)
ICAddRSP(tmpi,rsp_size);
} else {
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,rip);
ICPop(tmpi,MDF_REG+RT_I64,r1,0,rip);
}
}
U0 ICFCvt2(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 r1,
CICType t2,I64 r2,I64 d2,Bool to_int,I64 rip)
{
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.raw_type>=RT_I64 && t2&MDG_DISP_SIB_RIP)) {
ICPush(tmpi,t2,r2,d2,rip);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size=8;
} else {
rsp_size=8;
ICAddRSP(tmpi,-8);
}
ICSlashOp(tmpi,t2,r2,d2,op1,rip);
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,rip);
ICPop(tmpi,MDF_REG+RT_I64,r1,0,rip);
cc->last_dont_pushable=cc->last_dont_popable=FALSE; //TODO: improve this
}
U0 ICFUnaryMinus(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf2,I64 rip)
{
CICArg *arg1=&tmpi->arg1;
I64 rsp_size=0,builtin1=0,t1,r1,d1;
Bool dont_push_float,dont_pop_float;
if (cc->flags&CCF_AOT_COMPILE)
buf2=cc->aotc->rip;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (!dont_push_float) {
if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
t1=arg1->type;
r1=arg1->reg;
d1=arg1->disp;
} else {
if (arg1->type&MDF_IMM) {
if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
t1=MDF_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
if (builtin1)
ICU16(tmpi,builtin1);
else
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip);
}
if (!dont_pop_float && !rsp_size) {
rsp_size=8;
ICAddRSP(tmpi,-8);
}
ICU16(tmpi,0xE0D9); //FCHS
CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
if (dont_pop_float) {
if (rsp_size)
ICAddRSP(tmpi,rsp_size);
} else {
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
ICPop(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,rip);
}
}
U0 ICFMod(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
{//for MOD
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (tmpi->ic_flags&ICF_ALT_TEMPLATE)
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
else
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
}
//TODO: unpushable,unpop? Not sure
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
if (!dont_pop_float)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICFPow(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
{//for POW
I64 i;
CAOTImportExport *tmpie;
CHashExport *tmpex=HashFind("SYS_POW",
cc->htc.hash_table_lst,HTT_EXPORT_SYS_SYM);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (cc->flags&CCF_AOT_COMPILE) {
if (!tmpex) {
tmpex=CAlloc(sizeof(CHashExport));
tmpex->str=StrNew("SYS_POW");
tmpex->type=HTT_EXPORT_SYS_SYM|HTF_UNRESOLVED|HTF_IMPORT;
HashAdd(tmpex,cc->htc.glbl_hash_table);
}
if (tmpex->type&HTF_IMPORT) {
if (GetOption(OPTf_USE_IMM64)) {
ICU16(tmpi,0xBB48);
ICU64(tmpi,0);
if (buf) {
tmpie=CAlloc(sizeof(CAOTImportExport));
tmpie->type=IET_IMM_I64;
tmpie->rip=rip+tmpi->ic_cnt-8;
tmpie->next=tmpex->ie_lst;
tmpex->ie_lst=tmpie;
}
ICU16(tmpi,0xD3FF);
} else {
ICU8(tmpi,0xE8);
ICU32(tmpi,-(rip+tmpi->ic_cnt+4));
if (buf) {
tmpie=CAlloc(sizeof(CAOTImportExport));
tmpie->type=IET_REL_I32;
tmpie->rip=rip+tmpi->ic_cnt-4;
tmpie->next=tmpex->ie_lst;
tmpex->ie_lst=tmpie;
}
}
} else {//Kernel
if (tmpex->type&HTF_UNRESOLVED)
throw('Compiler');
else {
i=tmpex->val-(rip+tmpi->ic_cnt+5);
if (!(I32_MIN<=i<=I32_MAX)) {
throw('Compiler');
// ICU16(tmpi,0xBB48);
// ICU64(tmpi,tmpex->val);
// ICU16(tmpi,0xD3FF);
} else {
ICU8(tmpi,0xE8);
ICU32(tmpi,i);
}
}
}
} else {
i=tmpex->val-(rip+tmpi->ic_cnt+5);
if (!(I32_MIN<=i<=I32_MAX)) {
ICU16(tmpi,0xBB48);
ICU64(tmpi,tmpex->val);
ICU16(tmpi,0xD3FF);
} else {
ICU8(tmpi,0xE8);
ICU32(tmpi,i);
}
}
tmpi->ic_flags&=~ICF_CODE_FINAL;
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICFOp(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,U8 *buf2,I64 rip)
{//for ADD,SUB,DIV,MUL
CICArg *arg1,*arg2;
Bool dont_push_float,dont_pop_float,alt;
I64 rsp_size=0,builtin1=0,builtin2=0,t1,r1,d1,t2,r2,d2;
if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
arg1=&tmpi->arg2;
arg2=&tmpi->arg1;
alt=TRUE;
} else {
arg1=&tmpi->arg1;
arg2=&tmpi->arg2;
alt=FALSE;
}
if (cc->flags&CCF_AOT_COMPILE)
buf2=cc->aotc->rip;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
} else {
if (alt) {
if (!(arg2->type&MDF_STK)) {
if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
t1=arg1->type;
r1=arg1->reg;
d1=arg1->disp;
} else {
if (arg1->type&MDF_IMM) {
if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
t1=MDF_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
t2=MDF_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(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
arg1->reg,arg1->disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip);
ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
} else {
if (!(arg1->type&MDF_STK)) {
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
t1=arg1->type;
r1=arg1->reg;
d1=arg1->disp;
} else {
if (arg1->type&MDF_IMM) {
if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
t1=MDF_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
t1=MDF_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(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
arg1->reg,arg1->disp,rip);
ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
}
}
if (!dont_pop_float && !rsp_size) {
rsp_size=8;
ICAddRSP(tmpi,-8);
}
if (!dont_push_float) {
if (builtin2 && !builtin1) {
alt=!alt;
SwapI64(&t1,&t2);
SwapI64(&r1,&r2);
SwapI64(&d1,&d2);
SwapI64(&builtin1,&builtin2);
}
if (builtin1)
ICU16(tmpi,builtin1);
else
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip);
}
if (alt)
switch (op.u8[0]) {
case 4: op=SLASH_OP_FSUBR; break;
case 6: op=SLASH_OP_FDIVR; break;
}
if (builtin2) {
ICU16(tmpi,builtin2);
ICU16(tmpi,op.u16[2]);
} else
ICSlashOp(tmpi,t2,r2,d2,op,rip);
CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
if (dont_pop_float) {
if (rsp_size)
ICAddRSP(tmpi,rsp_size);
} else {
if (rsp_size==8)
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
else if (rsp_size>8) {
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
SLASH_OP_FSTP,rip);
ICAddRSP(tmpi,rsp_size-8);
}
ICPop(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,rip);
}
}
U0 ICFCmp(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
if (tmpi->ic_flags&ICF_POP_CMP)
ICPopRegs(tmpi,1<<REG_RAX);
else
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
} else
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
if (tmpi->ic_flags&ICF_POP_CMP)
ICPopRegs(tmpi,1<<REG_RDX);
else
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
}
if (tmpi->ic_flags&ICF_PUSH_CMP)
ICPushRegs(tmpi,1<<REG_RAX);
ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,FALSE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICFModEqu(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (tmpi->ic_flags & ICF_BY_VAL) {
if (dont_push_float) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
}
//TODO: unpushable,unpop? Not sure
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
} else {
if (dont_push_float) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,tmpi->arg1.type,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,tmpi->arg1.type,
tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
}
//TODO: unpushable,unpop? Not sure
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
MDF_REG+RT_I64,REG_RAX,0,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
}
+631
View File
@@ -0,0 +1,631 @@
U0 ICFOpEqu(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,U8 *buf2,I64 rip)
{//for ADD,SUB,DIV,MUL
CICArg *arg1=&tmpi->arg1,
*arg2=&tmpi->arg2;
Bool dont_push_float,dont_pop_float,p1_mem;
I64 rsp_size=0,builtin2=0,
t1,r1,d1,t2,r2,d2;
if (cc->flags&CCF_AOT_COMPILE)
buf2=cc->aotc->rip;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (dont_pop_float)
throw('Compiler');
if (tmpi->ic_flags & ICF_BY_VAL) {
p1_mem=FALSE;
if (dont_push_float) {
if (tmpi->arg1_type_pointed_to!=RT_F64) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
arg1->reg,arg1->disp,rip);
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
} else {
if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;
r1=arg1->reg;
d1=arg1->disp;
p1_mem=TRUE;
} else {
ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
arg1->reg,arg1->disp,rip);
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
} else {
if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
arg1->reg,arg1->disp,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
} else {
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;
r1=arg1->reg;
d1=arg1->disp;
p1_mem=TRUE;
} else {
ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
arg1->reg,arg1->disp,rip);
t1=MDF_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 && tmpi->arg1_type_pointed_to==RT_F64)) {
rsp_size=8;
ICAddRSP(tmpi,-8);
}
if (!dont_push_float) {
if (builtin2)
ICU16(tmpi,builtin2);
else
ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);
}
switch (op.u8[0]) {
case 4: op=SLASH_OP_FSUBR; break;
case 6: op=SLASH_OP_FDIVR; break;
}
ICSlashOp(tmpi,t1,r1,d1,op,rip);
CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FSTP,rip);
if (rsp_size)
ICAddRSP(tmpi,rsp_size);
} else {
if (rsp_size==8)
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
else if (rsp_size>8) {
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
SLASH_OP_FSTP,rip);
ICAddRSP(tmpi,rsp_size-8);
}
if (tmpi->arg1_type_pointed_to!=RT_F64) {
ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
ICMov(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,arg1->reg,
arg1->disp,MDF_REG+RT_I64,REG_RAX,0,rip);
} else
ICPop(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
arg1->reg,arg1->disp,rip);
}
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
arg1->reg,arg1->disp,rip);
} else {
if (tmpi->arg1_type_pointed_to>=RT_I64)
p1_mem=TRUE;
else
p1_mem=FALSE;
if (dont_push_float) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,arg1->reg,arg1->disp,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
} else
ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
} else {
if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
arg1->reg,arg1->disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
} else {
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
arg1->reg,arg1->disp,rip);
ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
t1=MDF_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 && tmpi->arg1_type_pointed_to==RT_F64)) {
rsp_size=8;
ICAddRSP(tmpi,-8);
}
if (!dont_push_float) {
if (builtin2)
ICU16(tmpi,builtin2);
else
ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);
}
switch (op.u8[0]) {
case 4: op=SLASH_OP_FSUBR; break;
case 6: op=SLASH_OP_FDIVR; break;
}
ICSlashOp(tmpi,t1,r1,d1,op,rip);
CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {
ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,
REG_RCX,0,SLASH_OP_FSTP,rip);
if (rsp_size)
ICAddRSP(tmpi,rsp_size);
} else {
if (rsp_size==8)
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
else if (rsp_size>8) {
ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
SLASH_OP_FSTP,rip);
ICAddRSP(tmpi,rsp_size-8);
}
ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
if (tmpi->arg1_type_pointed_to!=RT_F64)
ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
}
U0 ICFCmpAndBranch(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip,
I64 us,I64 not_us,U8 *buf,I64 rip2)
{
CICArg *arg1,*arg2;
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;
CCodeMisc *lb;
U8 *buf2;
if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
arg1=&tmpi->arg2;
arg2=&tmpi->arg1;
alt=TRUE;
} else {
arg1=&tmpi->arg1;
arg2=&tmpi->arg2;
alt=FALSE;
}
if (cc->flags&CCF_AOT_COMPILE)
buf2=cc->aotc->rip;
else
buf2=buf;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
if (tmpi->ic_flags&ICF_POP_CMP && alt) {
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
} else {
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
tmpi->ic_flags&ICF_PUSH_CMP) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
}
} else {
if (alt) {
if (!(arg2->type&MDF_STK)) {
if (tmpi->ic_flags&ICF_POP_CMP) {
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
} else {
if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
t1=arg1->type;
r1=arg1->reg;
d1=arg1->disp;
} else {
if (arg1->type&MDF_IMM) {
if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
t1=MDF_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
rsp_size+=8;
}
}
}
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
tmpi->ic_flags&ICF_PUSH_CMP) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
t2=MDF_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 (tmpi->ic_flags&ICF_POP_CMP)
ICPopRegs(tmpi,1<<REG_RDX);
else
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
arg1->reg,arg1->disp,rip2);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip2);
ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
} else {
if (!(arg1->type&MDF_STK)) {
if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
t2=arg2->type;
r2=arg2->reg;
d2=arg2->disp;
} else {
if (arg2->type&MDF_IMM) {
if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
tmpi->ic_flags&ICF_PUSH_CMP) {
t2=MDF_RIP_DISP32+RT_I64;
r2=REG_RIP;
d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
rsp_size+=8;
}
}
if (tmpi->ic_flags&ICF_POP_CMP) {
t1=MDF_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 (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
t1=arg1->type;
r1=arg1->reg;
d1=arg1->disp;
} else {
if (arg1->type&MDF_IMM) {
if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
t1=MDF_RIP_DISP32+RT_I64;
r1=REG_RIP;
d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
}
} else {
ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);
t1=MDF_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(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
arg2->reg,arg2->disp,rip2);
if (tmpi->ic_flags&ICF_POP_CMP)
ICPopRegs(tmpi,1<<REG_RDX);
else
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
arg1->reg,arg1->disp,rip2);
ICU16(tmpi,0x5052); //PUSH EDX PUSH EAX
rsp_size=16;
t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
}
}
}
if (!dont_push_float) {
if (builtin1)
ICU16(tmpi,builtin1);
else
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip2);
}
if (!alt)
us=not_us;
if (builtin2)
ICU16(tmpi,builtin2);
else
ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip2);
if (tmpi->ic_flags&ICF_PUSH_CMP) {
t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
if (!rsp_size) {
rsp_size=8;
ICAddRSP(tmpi,-8);
} else if (rsp_size==16)
d2=8;
if (alt) {
ICU16(tmpi,0xF1DF); //FCOMIP
ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);
} else {
ICU16(tmpi,0xF1DB); //FCOMI
ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);
ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP
}
} else {
ICU16(tmpi,0xF1DF); //FCOMIP
ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP
}
CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
if (tmpi->ic_flags&ICF_PUSH_CMP) {
if (r2.u8[0]==REG_RSP) {
while (d2 && rsp_size) {
ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
rsp_size-=8;
d2-=8;
}
} else {
while (rsp_size) {
ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
rsp_size-=8;
}
ICPush(tmpi,t2,r2,d2,rip2);
}
} else {
while (rsp_size) {
ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
rsp_size-=8;
}
}
rip+=tmpi->ic_cnt;
lb=OptLabelFwd(tmpi->ic_data);
short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
if (!buf && lb->addr!=INVALID_PTR) {
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP) {
if(tmpi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
if (I8_MIN<=i<=I8_MAX)
short_jmp=TRUE;
}
if (short_jmp) {
tmpi->ic_flags|=ICF_SHORT_JMP;
i=lb->addr-(rip+2);
if (lb->flags&CMF_POP_CMP) {
if(tmpi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tmpi,i<<8+us.u8[2]);
} else {
tmpi->ic_flags&=~ICF_SHORT_JMP;
i=lb->addr-(rip+6);
if (lb->flags&CMF_POP_CMP) {
if(tmpi->ic_flags&ICF_PUSH_CMP)
i+=4;
else
i+=8;
}
ICU16(tmpi,us.u16[0]);
ICU32(tmpi,i);
}
}
U0 ICFMul(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
{
if (tmpi->arg1.type&MDF_IMM && tmpi->arg1.type&RTG_MASK==RT_F64 &&
tmpi->arg1.disp(F64)==1.0) {
CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
} else if (tmpi->arg2.type&MDF_IMM &&
tmpi->arg2.type&RTG_MASK==RT_F64&& tmpi->arg2.disp(F64)==1.0) {
CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
} else
ICFOp(cc,tmpi,SLASH_OP_FMUL,buf,rip);
}
U0 ICFDiv(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
{
if (tmpi->arg2.type&MDF_IMM && tmpi->arg2.type&RTG_MASK==RT_F64 &&
tmpi->arg2.disp(F64)==1.0) {
CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
} else
ICFOp(cc,tmpi,SLASH_OP_FDIV,buf,rip);
}
U0 ICFAdd(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (tmpi->arg1.type&MDF_IMM && !tmpi->arg1.disp) {
if (dont_push_float) {
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
} else if (dont_pop_float) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
} else {
CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
}
} else if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {
if (dont_push_float) {
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
} else if (dont_pop_float) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
} else {
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
}
} else
ICFOp(cc,tmpi,SLASH_OP_FADD,buf,rip);
}
U0 ICFSub(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
{
Bool dont_push_float,dont_pop_float;
if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (dont_push_float) {
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
} else if (dont_pop_float) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
} else {
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
}
} else
ICFOp(cc,tmpi,SLASH_OP_FSUB,buf,rip);
}
U0 ICFPreIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
{
if (tmpi->ic_flags & ICF_BY_VAL) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);
ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
}
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
U0 ICFPostIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
{
if (tmpi->ic_flags & ICF_BY_VAL) {
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);
if (tmpi->res.type.mode)
ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
}
if (tmpi->res.type.mode)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RDX,0,rip);
}
U0 ICFTemplateFun(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
{
Bool dont_push_float,dont_pop_float;
CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
if (!dont_push_float)
ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
if (tmpi->res.type.mode && !(tmpi->ic_flags & ICF_RES_TO_F64) &&
!(tmpi->ic_flags & ICF_RES_TO_INT))
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_REG+RT_I64,REG_RAX,0,rip);
}
+708
View File
@@ -0,0 +1,708 @@
/*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
res 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 *tmpi,U8 b)
{
tmpi->ic_body[tmpi->ic_cnt++]=b;
}
U0 ICRex(CIntermediateCode *tmpi,U8 b)
{
if (b)
tmpi->ic_body[tmpi->ic_cnt++]=b;
}
U0 ICOpSizeRex(CIntermediateCode *tmpi,U8 b)
{
tmpi->ic_body[tmpi->ic_cnt++]=OC_OP_SIZE_PREFIX;
if (b)
tmpi->ic_body[tmpi->ic_cnt++]=b;
}
U0 ICU16(CIntermediateCode *tmpi,U16 w)
{
*(&tmpi->ic_body[tmpi->ic_cnt])(U16)=w;
tmpi->ic_cnt+=2;
}
U0 ICU24(CIntermediateCode *tmpi,U32 d)
{//Writes extra harmless overhanging byte.
*(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;
tmpi->ic_cnt+=3;
}
U0 ICU32(CIntermediateCode *tmpi,U32 d)
{
*(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;
tmpi->ic_cnt+=4;
}
U0 ICU64(CIntermediateCode *tmpi,U64 q)
{
*(&tmpi->ic_body[tmpi->ic_cnt])(U64)=q;
tmpi->ic_cnt+=8;
}
U0 ICAddRSP(CIntermediateCode *tmpi,I64 i,Bool optimize=TRUE)
{
I64 j,last_start;
CIntermediateCode *tmpil1;
if (optimize) {
tmpil1=tmpi;
if (tmpi->ic_last_start<0 && !tmpi->ic_cnt &&
(tmpil1=OptLag1(tmpi)) && tmpil1->ic_last_start<0)
tmpil1=NULL;
if (tmpil1) {
j=tmpil1->ic_cnt;
if (tmpil1->ic_last_start==j-4 && tmpil1->ic_body[j-3]==0x83 &&
tmpil1->ic_body[j-4]==0x48) {
if (tmpil1->ic_body[j-2]==0xEC)
j=-tmpil1->ic_body[j-1](I8);
else if (tmpil1->ic_body[j-2]==0xC4)
j=tmpil1->ic_body[j-1](I8);
else
j=0;
} else if (tmpil1->ic_last_start==j-7 && tmpil1->ic_body[j-6]==0x81 &&
tmpil1->ic_body[j-7]==0x48) {
if (tmpil1->ic_body[j-5]==0xEC)
j=-tmpil1->ic_body[j-4](I32);
else if (tmpil1->ic_body[j-5]==0xC4)
j=tmpil1->ic_body[j-4](I32);
else
j=0;
} else
j=0;
if (j) {
if (tmpi==tmpil1) {
tmpi->ic_cnt=tmpi->ic_last_start;
i+=j;
} else if (!(tmpi->ic_flags&ICF_PREV_DELETED)) {
tmpil1->ic_flags|=ICF_DEL_PREV_INS;
tmpi->ic_flags=tmpi->ic_flags&~ICF_CODE_FINAL|ICF_PREV_DELETED;
i+=j;
}
}
}
}
last_start=tmpi->ic_cnt;
if (i>0) {
if (i<=I8_MAX)
ICU32(tmpi,0xC48348+i<<24);
else if (i<=I32_MAX) {
ICU24(tmpi,0xC48148);
ICU32(tmpi,i);
} else
throw('Compiler');
} else if (i<0) {
i=-i;
if (i<=I8_MAX)
ICU32(tmpi,0xEC8348+i<<24);
else if (i<=I32_MAX) {
ICU24(tmpi,0xEC8148);
ICU32(tmpi,i);
} else
throw('Compiler');
}
if (optimize && tmpi->ic_cnt>last_start)
tmpi->ic_last_start=last_start;
}
extern U0 ICMov(CIntermediateCode *tmpi,
CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip);
#define MODR_REG 0
#define MODR_INDIRECT_REG 1
#define MODR_D8_INDIRECT_REG 2
#define MODR_D32_INDIRECT_REG 3
#define MODR_SIB_INDIRECT_REG 4
#define MODR_SIB_D8_INDIRECT_REG 5
#define MODR_SIB_D32_INDIRECT_REG 6
#define MODR_RIP_REL 7
#define MODR_RIP_REL_IMM_U32 8
I64 ICModr1(I64 r,CICType t2,I64 r2,I64 d2)
{//res.u8[0] is type
//res.u8[1] is REX
//res.u8[2] is ModR
//res.u8[3] is SIB
I64 res=0;
if (t2.raw_type<RT_I64)
res.u8[1]=0x40;
else
res.u8[1]=0x48;
if (r>7) {
res.u8[1]+=4;
r&=7;
}
switch (Bsr(t2)) {
case MDf_REG:
if (r2>7) {
res.u8[1]++;
r2&=7;
}
res.u8[2]=0xC0+r<<3+r2;
res.u8[0]=MODR_REG;
if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4 && r2<4))
res.u8[1]=0;
break;
case MDf_DISP:
if (r2>7) {
res.u8[1]++;
r2&=7;
}
if (!d2 && r2!=REG_RBP) {
res.u8[2]=r<<3+r2;
res.u8[0]=MODR_INDIRECT_REG;
} else if (I8_MIN<=d2<=I8_MAX) {
res.u8[2]=0x40+r<<3+r2;
res.u8[0]=MODR_D8_INDIRECT_REG;
} else {
res.u8[2]=0x80+r<<3+r2;
res.u8[0]=MODR_D32_INDIRECT_REG;
}
if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
res.u8[1]=0;
break;
case MDf_SIB:
if (7<r2.u8[0]<REG_NONE)
res.u8[1]++;
if (r2.u8[1]&15>7)
res.u8[1]+=2;
if (r2.u8[0]==REG_NONE) {
res.u8[3]=5+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
res.u8[2]=4+r<<3;
res.u8[0]=MODR_SIB_D32_INDIRECT_REG;
} else {
res.u8[3]=r2.u8[0]&7+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
if (!d2 && r2.u8[0]&7!=REG_RBP) {
res.u8[2]=4+r<<3;
res.u8[0]=MODR_SIB_INDIRECT_REG;
} else if (I8_MIN<=d2<=I8_MAX) {
res.u8[2]=0x44+r<<3;
res.u8[0]=MODR_SIB_D8_INDIRECT_REG;
} else {
res.u8[2]=0x84+r<<3;
res.u8[0]=MODR_SIB_D32_INDIRECT_REG;
}
}
if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
res.u8[1]=0;
break;
case MDf_RIP_DISP32:
res.u8[2]=0x05+r<<3;
res.u8[0]=MODR_RIP_REL;
if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
res.u8[1]=0;
break;
}
return res;
}
U0 ICModr2(CIntermediateCode *tmpi,I64 i,CICType t=0,I64 d,I64 rip=0)
{
switch [i.u8[0]] {
case MODR_REG:
break;
case MODR_INDIRECT_REG:
break;
case MODR_D8_INDIRECT_REG:
ICU8(tmpi,d);
break;
case MODR_D32_INDIRECT_REG:
ICU32(tmpi,d);
break;
case MODR_SIB_INDIRECT_REG:
ICU8(tmpi,i.u8[3]);
break;
case MODR_SIB_D8_INDIRECT_REG:
ICU8(tmpi,i.u8[3]);
ICU8(tmpi,d);
break;
case MODR_SIB_D32_INDIRECT_REG:
ICU8(tmpi,i.u8[3]);
ICU32(tmpi,d);
break;
case MODR_RIP_REL_IMM_U32:
switch (t.raw_type) {
case RT_I8:
case RT_U8:
d--;
break;
case RT_I16:
case RT_U16:
d-=2;
break;
default:
d-=4;
}
case MODR_RIP_REL:
ICU32(tmpi,d-(rip+4+tmpi->ic_cnt));
tmpi->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_IMM_U8 0x0000000000838000
#define SLASH_OP_IMM_U32 0x0000000000818300
#define SLASH_OP_MUL 0x0000000000F7F604
#define SLASH_OP_IMUL 0x0000000000F7F605
#define SLASH_OP_DIV 0x0000000000F7F606
#define SLASH_OP_MOV 0x0000000000898800
#define SLASH_OP_MOV_IMM 0x0000000000C7C600
#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 *tmpi,CICType t1,I64 r1,I64 d1,I64 op,I64 rip)
{
I64 i;
if (t1&MDF_REG && !op.u8[3])
t1=t1&(MDG_MASK|RTF_UNSIGNED)+RT_I64; //Set to 64 bit,preserving unsigned
i=ICModr1(op.u8[0],t1,r1,d1);
if (tmpi->ic_flags&ICF_LOCK && !(t1&MDF_REG) &&
op&~7!=SLASH_OP_MOV && op!=SLASH_OP_MOV_IMM)
ICU8(tmpi,OC_LOCK_PREFIX);
switch (t1.raw_type) {
case RT_I8:
case RT_U8:
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+op.u8[1]);
break;
case RT_I16:
case RT_U16:
ICOpSizeRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+op.u8[2]);
break;
default:
if (i.u8[1]!=0x48 || !op.u8[3])
ICRex(tmpi,i.u8[1]);
ICU16(tmpi,i.u8[2]<<8+op.u8[2]);
}
if (i.u8[0]==MODR_RIP_REL&& (op==SLASH_OP_MOV_IMM || op&~7==SLASH_OP_IMM_U32))
i.u8[0]=MODR_RIP_REL_IMM_U32;
ICModr2(tmpi,i,t1,d1,rip);
}
U0 ICPush(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)
{
switch (Bsr(t1)) {
case MDf_REG:
if (r1>7)
ICU16(tmpi,0x5049+(r1&7)<<8);
else
ICU8(tmpi,0x50+r1);
return;
case MDf_IMM:
if (I8_MIN<=d1<=I8_MAX)
ICU16(tmpi,0x6A+d1<<8);
else if (I32_MIN<=d1<=I32_MAX) {
ICU8(tmpi,0x68);
ICU32(tmpi,d1);
} else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);
ICU8(tmpi,0x50+REG_RBX);
}
return;
case MDf_STK:
return;
case MDf_DISP:
case MDf_SIB:
case MDf_RIP_DISP32:
switch (t1.raw_type) {
case RT_I64:
case RT_U64:
case RT_F64:
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_PUSH,rip);
return;
}
break;
}
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);
ICU16(tmpi,0x5048+REG_RBX<<8);
}
U0 ICPushRegs(CIntermediateCode *tmpi,I64 mask)
{
I64 i;
for (i=0;i<REG_REGS_NUM;i++) {
if (Bt(&mask,i)) {
if (i>7)
ICU16(tmpi,0x5049+(i&7)<<8);
else
ICU8(tmpi,0x50+i);
}
}
}
U0 ICPop(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)
{
switch (Bsr(t1)) {
case MDf_REG:
if (r1>7)
ICU16(tmpi,0x5849+(r1&7)<<8);
else
ICU8(tmpi,0x58+r1);
break;
case MDf_DISP:
case MDf_RIP_DISP32:
case MDf_SIB:
if (t1.raw_type<RT_I64) {
ICU8(tmpi,0x58+REG_RBX);
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
} else
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_POP,rip);
break;
case MDf_STK:
case MDf_IMM:
ICU8(tmpi,0x58+REG_RBX);
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
break;
default:
ICAddRSP(tmpi,8);
}
}
U0 ICPopRegs(CIntermediateCode *tmpi,I64 mask)
{
I64 i;
for (i=REG_REGS_NUM-1;i>=0;i--) {
if (Bt(&mask,i)) {
if (i>7)
ICU16(tmpi,0x5849+(i&7)<<8);
else
ICU8(tmpi,0x58+i);
}
}
}
U0 ICZero(CIntermediateCode *tmpi,I64 r)
{
if (r>7) {
r&=7;
ICU24(tmpi,0xC0334D+r<<16+r<<19);
} else
ICU16(tmpi,0xC033+r<<8+r<<11);
}
U0 ICTest(CIntermediateCode *tmpi,I64 r)
{
I64 i=0xC08548; //TEST R,R
if (r>7) {
i+=5;
r&=7;
}
ICU24(tmpi,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 (GetOption(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 *tmpi,
CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip)
{
I64 i,cnt1,cnt2,b1_rex,b2_rex,b1,b2,b1_modr,b2_modr,
b1_r1,b1_r2,b2_r1,b2_r2,last_start=tmpi->ic_cnt;
CIntermediateCode *tmpil1;
Bool old_lock=Btr(&tmpi->ic_flags,ICf_LOCK);
switch (Bsr(t1)) {
case MDf_REG:
if (t2&MDF_IMM) {
if (!d2)
ICZero(tmpi,r1);
else if (0<=d2<=U8_MAX) {
ICZero(tmpi,r1);
if (r1>7)
ICU24(tmpi,d2<<16+(0xB0+r1&7)<<8+0x41);
else if (r1>3)
ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);
else
ICU16(tmpi,d2<<8+0xB0+r1);
} else if (I8_MIN<=d2<0) {
if (r1>7) {
r1&=7;
ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x41);
ICU32(tmpi,0xC0BE0F4D+r1<<24+r1<<27);
} else {
if (r1>3)
ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);
else
ICU16(tmpi,d2<<8+0xB0+r1);
ICU32(tmpi,0xC0BE0F48+r1<<24+r1<<27);
}
} else if (0<=d2<=U32_MAX) {
if (r1>7) {
r1&=7;
ICU16(tmpi,(0xB8+r1)<<8+0x41);
ICU32(tmpi,d2);
} else {
ICU8(tmpi,0xB8+r1);
ICU32(tmpi,d2);
}
} else if (I32_MIN<=d2<0) {
if (r1>7) {
r1&=7;
ICU16(tmpi,(0xB8+r1)<<8+0x41);
ICU32(tmpi,d2);
ICU24(tmpi,0xC0634D+r1<<16+r1<<19);
} else {
ICU8(tmpi,0xB8+r1);
ICU32(tmpi,d2);
ICU24(tmpi,0xC06348+r1<<16+r1<<19);
}
} else {
i=0xB848;
if (r1>7) {
i++;
r1&=7;
}
ICU16(tmpi,i+r1<<8);
ICU64(tmpi,d2);
}
} else if (t2&MDF_STK)
ICPop(tmpi,t1,r1,d1,rip);
else {
if (r1==r2 && t2&MDF_REG)
goto move_done;
if (t2&MDF_REG)
t2=MDF_REG+RT_I64;
i=ICModr1(r1,t2,r2,d2);
if (t2.raw_type!=RT_U32)
i|=0x4800;
ICRex(tmpi,i.u8[1]);
switch (t2.raw_type) {
case RT_I8:
ICU24(tmpi,i.u8[2]<<16+0xBE0F);
break;
case RT_I16:
ICU24(tmpi,i.u8[2]<<16+0xBF0F);
break;
case RT_I32:
ICU16(tmpi,i.u8[2]<<8+0x63);
break;
case RT_U8:
ICU24(tmpi,i.u8[2]<<16+0xB60F);
break;
case RT_U16:
ICU24(tmpi,i.u8[2]<<16+0xB70F);
break;
default:
ICU16(tmpi,i.u8[2]<<8+0x8B);
}
ICModr2(tmpi,i,,d2,rip);
}
break;
case MDf_STK:
if (tmpi->ic_flags&ICF_PUSH_CMP)
ICPopRegs(tmpi,1<<REG_RBX);
if (t1.raw_type<t2.raw_type)
ICPush(tmpi,t2&MDG_MASK+t1.raw_type,r2,d2,rip);
else
ICPush(tmpi,t2,r2,d2,rip);
if (tmpi->ic_flags&ICF_PUSH_CMP)
ICPushRegs(tmpi,1<<REG_RBX);
break;
case MDf_DISP:
case MDf_RIP_DISP32:
case MDf_SIB:
if (t2&MDF_IMM && (t1.raw_type<RT_I64 || (I32_MIN<=d2<=I32_MAX))) {
ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_MOV_IMM,rip);
switch (t1.raw_type) {
case RT_I8:
case RT_U8:
ICU8(tmpi,d2);
break;
case RT_I16:
case RT_U16:
ICU16(tmpi,d2);
break;
default:
ICU32(tmpi,d2);
}
} else {
if (t2&MDF_REG)
ICSlashOp(tmpi,t1,r1,d1,r2+SLASH_OP_MOV,rip);
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t2,r2,d2,rip);
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
}
}
break;
}
move_done:
if (!((t1|t2)&(MDF_STK|MDF_RIP_DISP32))) {
tmpil1=tmpi;
if (tmpi->ic_last_start<0 && (tmpil1=OptLag1(tmpi)) &&
tmpil1->ic_last_start<0)
tmpil1=NULL;
if (tmpil1) {
if (tmpil1==tmpi)
cnt1=last_start-tmpil1->ic_last_start;
else {
if (!(tmpil1->ic_flags&ICF_CODE_FINAL))
tmpi->ic_flags&=~ICF_CODE_FINAL;
if (last_start)
cnt1=0;
else
cnt1=tmpil1->ic_cnt-tmpil1->ic_last_start;
}
cnt2=tmpi->ic_cnt-last_start;
if (cnt1 && cnt1==cnt2) {
b1_rex=tmpil1->ic_body[tmpil1->ic_last_start];
b2_rex=tmpi->ic_body[last_start];
if (b1_rex&0x48==0x48 && b2_rex&0x48==0x48) {
for (i=1;i<cnt1;i++)
if ((b1=tmpil1->ic_body[tmpil1->ic_last_start+i])==
(b2=tmpi->ic_body[last_start+i])) {
if (i==1 && (b2==0x89 || b2==0x8B)) {
b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];
b1_r1=b1_modr&7 +Bt(&b1_rex,0)<<3;
b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;
b2_modr=tmpi->ic_body[last_start+2];
b2_r1=b2_modr&7 +Bt(&b2_rex,0)<<3;
b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;
if (cnt1==3 && b2_modr&0xC0==0xC0) {
if (b2_r1==b2_r2)
goto move_redundant;
if (b1_modr&0xC0==0xC0) {
if (b1_r1==b2_r2 && b2_r1==b1_r2)
goto move_redundant;
}
} else if (b1_rex!=b2_rex || b1_r1==b1_r2 || (t1|t2)&MDF_SIB)
break;
} else if (b1_rex!=b2_rex)
break;
} else if (i!=1)
break;
else if (b2!=0x89 && b2!=0x8B)
break;
else {
b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];
b1_r1=b1_modr&7 +Bt(&b1_rex,0)<<3;
b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;
b2_modr=tmpi->ic_body[last_start+2];
b2_r1=b2_modr&7 +Bt(&b2_rex,0)<<3;
b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;
if (cnt1==3 && b2_modr&0xC0==0xC0) {
if (b2_r1==b2_r2)
goto move_redundant;
if (b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89) {
if (b1_modr&0xC0==0xC0) {
if (b1_r1==b2_r1 && b1_r2==b2_r2 ||
b1_r1==b2_r2 && b2_r1==b1_r2)
goto move_redundant;
}
if (b1_rex!=b2_rex)
break;
} else
break;
} else if (b1_r1==b1_r2 || (t1|t2)&MDF_SIB || b1_rex!=b2_rex ||
!(b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89))
break;
}
if (i==cnt1) {
move_redundant:
tmpi->ic_cnt=last_start;
}
}
}
}
}
if (tmpi->ic_cnt>last_start>tmpi->ic_last_start)
tmpi->ic_last_start=last_start;
BEqu(&tmpi->ic_flags,ICf_LOCK,old_lock);
}
U0 ICLea(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
CICType t2,I64 r2,I64 d2,CCmpCtrl *cc,U8 *buf,I64 rip)
{
I64 i;
CAOTAbsAddr *tmpa;
switch (Bsr(t1)) {
case MDf_REG:
i=ICModr1(r1,t2,r2,d2);
i.u8[1]|=0x48;
ICU24(tmpi,i.u8[2]<<16+0x8D00+i.u8[1]);
ICModr2(tmpi,i,,d2,rip);
break;
case MDf_STK:
if (t2&MDF_RIP_DISP32) {
ICU8(tmpi,0x68);
ICU32(tmpi,d2);
if (cc->flags&CCF_AOT_COMPILE && buf && !(cc->flags&CCF_NO_ABSS)) {
tmpa=CAlloc(sizeof(CAOTAbsAddr));
tmpa->next=cc->aotc->abss;
tmpa->type=AAT_ADD_U32;
cc->aotc->abss=tmpa;
tmpa->rip=rip+tmpi->ic_cnt-4;
}
tmpi->ic_flags&=~ICF_CODE_FINAL;
break;
} // Fall thru
default:
ICLea(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,cc,buf,rip);
ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RCX,0,rip);
}
}
U0 ICDeref(CIntermediateCode *tmpi,I64 rip)
{
CICType t;
t=tmpi->res.type.raw_type;
if (t>tmpi->arg1_type_pointed_to)
t=tmpi->arg1_type_pointed_to;
if (tmpi->arg1.type&MDF_REG)
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_DISP+t,tmpi->arg1.reg,tmpi->arg1.disp,rip);
else {
ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
MDF_DISP+t,REG_RCX,0,rip);
}
}
+253
View File
@@ -0,0 +1,253 @@
U0 LexPutToken(CCmpCtrl *cc)
{//Print cur token to StdOut. (Crude)
'"';
if (cc->token==TK_IDENT || cc->token==TK_STR)
"%s",cc->cur_str;
else if (cc->token==TK_I64)
"INT:%X",cc->cur_i64;
else if (cc->token==TK_CHAR_CONST)
"U8:%X",cc->cur_i64;
else if (cc->token==TK_F64)
"FLOAT:%e",cc->cur_f64;
else if (cc->token=='\n')
"<NEW_LINE>";
else if (Bt(char_bmp_displayable,cc->token))
'' cc->token;
else {
"T:%X",cc->token;
}
"\" ";
}
U8 *LexPutLine(CCmpCtrl *cc,U8 *start)
{//Print cur pos to end of line to StdOut.
I64 ch;
U8 *ptr;
if (!start) return NULL;
if (cc->lex_include_stk->flags&LFSF_DOC)
return DocPutLine(cc->lex_include_stk->doc,start);
else {
ptr=start;
while (ch=*ptr++) {
if (ch=='\n') {
if (*ptr=='\r')
ptr++;
break;
} else if (ch=='\r') {
if (*ptr=='\n')
ptr++;
break;
}
'' ch;
}
if (!ch) ptr--;
'\n';
return ptr;
}
return NULL;
}
U0 LexPutPos(CCmpCtrl *cc)
{//Print token, line link and, then, $LK,"LexPutLine",A="MN:LexPutLine"$().
LexPutToken(cc);
FixSet(cc->lex_include_stk->full_name,cc->lex_include_stk->line_num);
if (IsRaw)
"%s,%d ",cc->lex_include_stk->full_name,cc->lex_include_stk->line_num;
else {
PutFileLink(cc->lex_include_stk->full_name,,cc->lex_include_stk->line_num);
AdamErr("%s,%d\n",
cc->lex_include_stk->full_name,cc->lex_include_stk->line_num);
'' CH_SPACE;
}
LexPutLine(cc,cc->lex_include_stk->line_start);
}
U0 LexWarn(CCmpCtrl *cc,U8 *str=NULL)
{//Print warn msg, then, $LK,"LexPutPos",A="MN:LexPutPos"$().
if (str) PrintWarn(str);
if (cc->htc.fun) {
"in fun '%s'.\n",cc->htc.fun->str;
if (IsRaw)
"%s\n",cc->htc.fun->src_link;
else {
"$$LK,\"%s\"$$\n",cc->htc.fun->src_link;
AdamErr("%s\n",cc->htc.fun->src_link);
}
} else
LexPutPos(cc);
cc->warning_cnt++;
}
U0 LexExcept(CCmpCtrl *cc,U8 *str=NULL)
{//Print err msg, $LK,"LexPutPos",A="MN:LexPutPos"$() and throw exception.
if (!Bt(&sys_run_level,RLf_ADAM_SERVER)) {
Raw(ON);
"Note: Still in boot phase.\n";
}
if (str) PrintErr(str);
if (!IsRaw)
AdamErr("Task:%08X %s\n",Fs,str);
LexPutPos(cc);
cc->error_cnt++;
FlushMsgs;
if (!Bt(&sys_run_level,RLf_ADAM_SERVER))
Dbg("Type \"Fix;\"");
throw('Compiler');
}
U0 UndefinedExtern()
{
PrintErr("Undefined Extern\nat %P\n",Caller);
throw('UndefExt');
}
U0 UnusedExternWarning(CCmpCtrl *cc,CHashClass *tmpc)
{
PrintWarn("Unused extern '%s'\n",tmpc->str);
cc->warning_cnt++;
}
U0 ParenWarning(CCmpCtrl *cc)
{
if (Bt(&cc->opts,OPTf_WARN_PAREN) &&
!(cc->lex_include_stk->flags&LFSF_DEFINE))
LexWarn(cc,"Unnecessary parenthesis ");
}
U0 ICClassPut(CHashClass *c)
{
I64 i;
if (!c) return;
if (c->ptr_stars_cnt>4) {
PrintErr("put_class ptrcnt=%d\n",c->ptr_stars_cnt);
while (TRUE)
//TODO:
Yield;
}
for (i=0;i<c->ptr_stars_cnt;i++)
'*';
c-=c->ptr_stars_cnt;
if (c->str)
"%s",c->str;
else {
PrintErr("put_class str=NULL\n");
while (TRUE)
//TODO:
Yield;
}
'' CH_SPACE;
}
U0 ICArgPut(CICArg *a,I64 type_pointed_to)
{
if (type_pointed_to)
"[%Z](%Z) %Z ",a->type.raw_type,"ST_RAW_TYPES",
type_pointed_to,"ST_RAW_TYPES",Bsr(a->type>>8)+1,"ST_TY_TYPES";
else
"%Z %Z ",a->type.raw_type,"ST_RAW_TYPES",
Bsr(a->type>>8)+1,"ST_TY_TYPES";
switch (Bsr(a->type)) {
case MDf_STK:
"STK";
break;
case MDf_IMM:
"#%X",a->disp;
break;
case MDf_REG:
"%Z",a->reg,"ST_U64_REGS";
break;
case MDf_DISP:
"%X[%Z]",a->disp,a->reg,"ST_U64_REGS";
break;
case MDf_RIP_DISP32:
"[%X]",a->disp;
break;
case MDf_SIB:
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;
}
'' CH_SPACE;
}
U0 ICPut(CCmpCtrl *cc,CIntermediateCode *tmpi)
{
I64 opcode=tmpi->ic_code,i;
if (opcode>=IC_END_EXP && opcode!=IC_NOP2) {
"%15ts %016X ",intermediate_code_table[opcode].name,tmpi->ic_data;
if (cc->pass) {
if (tmpi->res.type.mode) {
"$$PURPLE$$RES:$$FG$$";
ICArgPut(&tmpi->res,0);
}
if (tmpi->arg1.type.mode) {
"$$PURPLE$$ARG1:$$FG$$";
if (intermediate_code_table[tmpi->ic_code].type==IST_DEREF ||
intermediate_code_table[tmpi->ic_code].type==IST_ASSIGN)
ICArgPut(&tmpi->arg1,tmpi->arg1_type_pointed_to);
else
ICArgPut(&tmpi->arg1,0);
}
if (tmpi->arg2.type.mode) {
"$$PURPLE$$ARG2:$$FG$$";
ICArgPut(&tmpi->arg2,0);
}
"$$PURPLE$$:$$FG$$";
}
ICClassPut(tmpi->ic_class);
if (tmpi->ic_flags & ICF_LOCK)
"$$BROWN$$lock$$FG$$ ";
if (tmpi->ic_flags & ICF_ARG2_TO_F64)
"$$LTBLUE$$a2d$$FG$$ ";
if (tmpi->ic_flags & ICF_ARG2_TO_INT)
"$$GREEN$$a2i$$FG$$ ";
if (tmpi->ic_flags & ICF_ARG1_TO_F64)
"$$LTBLUE$$a1d$$FG$$ ";
if (tmpi->ic_flags & ICF_ARG1_TO_INT)
"$$GREEN$$a1i$$FG$$ ";
if (tmpi->ic_flags & ICF_RES_TO_F64)
"$$LTBLUE$$rd$$FG$$ ";
if (tmpi->ic_flags & ICF_RES_TO_INT)
"$$GREEN$$ri$$FG$$ ";
if (tmpi->ic_flags & ICF_USE_F64)
"[F64] ";
if (tmpi->ic_flags & ICF_USE_UNSIGNED)
"[unsigned] ";
if (tmpi->ic_flags & ICF_USE_INT)
"[int] ";
if (tmpi->ic_flags & ICF_RES_NOT_USED)
"NO_RES ";
if (tmpi->ic_flags & ICF_BY_VAL)
"BY_VAL ";
if (tmpi->ic_flags & ICF_PUSH_RES)
"PUSH ";
if (tmpi->ic_flags & ICF_PUSH_CMP)
"PUSH_CMP ";
if (tmpi->ic_flags & ICF_POP_CMP)
"POP_CMP ";
if (tmpi->ic_flags & ICF_DEL_PREV_INS)
"DEL_PREV ";
if (tmpi->ic_flags & ICF_PREV_DELETED)
"PREV_DEL ";
for (i=0;i<3;i++) {
if (Bt(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0+i))
"DONT_PUSH#%d ",i;
if (Bt(&tmpi->ic_flags,ICf_DONT_POP_FLOAT0+i))
"DONT_POP#%d ",i;
}
if (tmpi->ic_flags & ICF_ALT_TEMPLATE)
"ALT_TMP ";
'\n';
}
}
+46
View File
@@ -0,0 +1,46 @@
import U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e);
import U0 DocBinsValidate(CDoc *doc);
import U0 DocDel(CDoc *doc);
import U0 DocLoad(CDoc *doc,U8 *src2,I64 size);
import CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL);
import CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...);
import CDocEntry *DocPutLine(CDoc *doc,CDocEntry *doc_e);
import I64 DocSize(CDoc *doc);
import Bool DocWrite(CDoc *doc,Bool prompt=FALSE);
extern U8 *CmdLinePmt();
extern I64 HashEntrySize2(CHashSrcSym *tmph);
extern Bool IsLexExpression2Bin(CCmpCtrl *cc,U8 **_machine_code);
extern I64 Lex(CCmpCtrl *cc);
extern I64 LexExpression(CCmpCtrl *cc);
extern I64 LexGetChar(CCmpCtrl *cc);
extern CCodeMisc *OptLabelFwd(CCodeMisc *lb);
extern CIntermediateCode *OptPass012(CCmpCtrl *cc);
extern U0 OptPass3(CCmpCtrl *cc,COptReg *reg_offsets);
extern U0 OptPass4(CCmpCtrl *cc,COptReg *reg_offsets,I64 *_type);
extern U0 OptPass5(CCmpCtrl *cc);
extern U0 OptPass6(CCmpCtrl *cc);
extern I64 OptPass789A(
CCmpCtrl *cc,COptReg *reg_offsets,U8 *buf,CDbgInfo **_dbg);
extern CHashClass *PrsClass(
CCmpCtrl *cc,I64 keyword,I64 fsp_flags,Bool is_extern);
extern CHashFun *PrsFunJoin(
CCmpCtrl *cc,CHashClass *tmp_return,U8 *name,I64 fsp_flags);
extern I64 PrsKeyWord(CCmpCtrl *cc);
extern Bool PrsStmt(CCmpCtrl *cc,I64 try_cnt=0,
CCodeMisc *lb_break=NULL,I64 cmp_flags=CMPF_PRS_SEMICOLON);
extern U0 PrsStreamBlk(CCmpCtrl *cc);
extern CHashClass *PrsType(CCmpCtrl *cc,CHashClass **_tmpc1,
I64 *_mode,CMemberLst *tmpm,U8 **_ident,CHashFun **_fun_ptr,
CHashExport **_tmpex,CArrayDim *tmpad,I64 fsp_flags);
extern I64 PrsUnaryModifier(CCmpCtrl *cc,CPrsStk *ps,
CMemberLst **_local_var,CArrayDim **_tmpad,I64 *unary_post_prec);
extern I64 PrsUnaryTerm(
CCmpCtrl *cc,CPrsStk *ps,CMemberLst **_local_var,CArrayDim **_tmpad,
I64 *max_prec,I64 *unary_pre_prec,I64 *paren_prec);
extern U0 PrsVarInit2(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,
CArrayDim *tmpad,U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass);
_extern CMP_TEMPLATES U32 cmp_templates[1];
_extern CMP_TEMPLATES_DONT_POP U32 cmp_templates_dont_pop[1];
_extern CMP_TEMPLATES_DONT_PUSH2 U32 cmp_templates_dont_push2[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];
+141
View File
@@ -0,0 +1,141 @@
I64 HashEntrySize(CHashSrcSym *tmph)
{//Logical size of a std system hash entry.
CDbgInfo *dbg_info;
CBinFile *bfh;
switch (HashTypeNum(tmph)) {
case HTt_DEFINE_STR:
return MSize(tmph(CHashDefineStr *)->data);
case HTt_GLBL_VAR:
case HTt_CLASS:
case HTt_INTERNAL_TYPE:
return tmph(CHashClass *)->size;
case HTt_FUN:
if (dbg_info=tmph->dbg_info)
return dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
-dbg_info->body[0];
else
return -1;
case HTt_FILE:
return MSize(tmph(CHashGeneric *)->user_data0);
case HTt_MODULE:
if (StrCmp(tmph->str,KERNEL_MODULE_NAME))
return MSize(tmph(CHashGeneric *)->user_data0);
else {
bfh=mem_boot_base-sizeof(CBinFile);
return bfh->file_size;
}
case HTt_WORD:
return StrLen(tmph->str);
}
return -1;
}
I64 HashEntrySize2(CHashSrcSym *tmph)
{//Memory size of a std system hash entry.
CDbgInfo *dbg_info;
I64 res=MSize2(tmph);
if (!(tmph->type&HTT_DICT_WORD))
res+=MSize2(tmph->str);
if (tmph->type & HTG_SRC_SYM) {
res+=MSize2(tmph->src_link);
res+=MSize2(tmph->idx);
res+=MSize2(tmph->import_name);
res+=LinkedLstSize(tmph->ie_lst);
if (tmph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM))
res+=MSize2(tmph->dbg_info);
if (tmph->type & HTT_CLASS)
res+=MemberLstSize(tmph);
else if (tmph->type & HTT_FUN) {
res+=MemberLstSize(tmph);
if (dbg_info=tmph->dbg_info)
//This should be $LK,"MSize",A="MN:MSize"$() but it would crash on AOT .BIN.Z file funs.
res+=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
-dbg_info->body[0];
} else if (tmph->type&HTT_DEFINE_STR)
res+=MSize2(tmph(CHashDefineStr *)->data);
else if (tmph->type & HTT_GLBL_VAR) {
res+=LinkedLstSize(tmph(CHashGlblVar *)->dim.next);
if (!(tmph(CHashGlblVar *)->flags&GVF_ALIAS))
res+=MSize2(tmph(CHashGlblVar *)->data_addr);
if (tmph(CHashGlblVar *)->fun_ptr)
res+=HashEntrySize2(tmph(CHashGlblVar *)->fun_ptr
-tmph(CHashGlblVar *)->fun_ptr->ptr_stars_cnt);
}
} else if (tmph->type & HTT_FILE)
res+=MSize2(tmph(CHashGeneric *)->user_data0);
else if (tmph->type & HTT_MODULE &&
StrCmp(tmph->str,KERNEL_MODULE_NAME))
res+=MSize2(tmph(CHashGeneric *)->user_data0);
return res;
}
I64 HashTableSize2(CHashTable *table)
{//Memory size of std system hash table and all entries.
I64 i,res=0;
CHashSrcSym *tmph;
if (!table)
return 0;
for (i=0;i<=table->mask;i++) {
tmph=table->body[i];
while (tmph) {
res+=HashEntrySize2(tmph);
tmph=tmph->next;
}
}
res+=MSize2(table->body);
res+=MSize2(table);
return res;
}
U0 MapFileWrite(CHashTable *h,U8 *map_name,U8 drv_let)
{
CHashSrcSym *tmph;
I64 i,size;
U8 *src_link;
CDoc *doc;
CDocBin *tmpb;
CDbgInfo *dbg_info;
doc=DocNew(map_name);
doc->flags|=DOCF_NO_CURSOR;
for (i=0;i<=h->mask;i++) {
tmph=h->body[i];
while (tmph) {
if (tmph->src_link && !(tmph->type & (HTF_IMPORT | HTF_PRIVATE))) {
src_link=StrNew(tmph->src_link);
if (drv_let && StrLen(src_link)>=4)
src_link[3]=drv_let;
if (dbg_info=tmph->dbg_info) {
size=offset(CDbgInfo.body)+
sizeof(U32)*(dbg_info->max_line+2-dbg_info->min_line);
if (size>MSize(dbg_info)) {
"Corrupt Map Entry\n";
dbg_info=NULL;
} else {
if (dbg_info->min_line<=dbg_info->max_line) {
tmpb=CAlloc(sizeof(CDocBin));
tmpb->size=size;
tmpb->data=MAlloc(size);
MemCpy(tmpb->data,dbg_info,size);
tmpb->num=doc->cur_bin_num++;
tmpb->use_cnt=1;
QueIns(tmpb,doc->bin_head.last);
} else
dbg_info=NULL;
}
}
if (dbg_info)
DocPrint(doc,"$$LK,\"%s\",A=\"%s\",BI=%d$$\n",
tmph->str,src_link,tmpb->num);
else
DocPrint(doc,"$$LK,\"%s\",A=\"%s\"$$\n",tmph->str,src_link);
Free(src_link);
}
tmph=tmph->next;
}
}
DocBinsValidate(doc);
DocWrite(doc);
DocDel(doc);
}
+330
View File
@@ -0,0 +1,330 @@
#define INTERNAL_TYPES_NUM 17
class CInternalType
{
U8 type,size,name[8];
} internal_types_table[INTERNAL_TYPES_NUM]={
{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"},
};
CIntermediateStruct intermediate_code_table[IC_ICS_NUM]={
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"END"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOP1"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"END_EXP"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOP2"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"LABEL"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"CALL_START"},
{IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"CALL_END"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"CALL_END2"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RETURN_VAL"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RETURN_VAL2"},
{IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"IMM_I64"},
{IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"IMM_F64"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"STR_CONST"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ABS_ADDR"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ADDR_IMPORT"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"HEAP_GLBL"},
{IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SIZEOF"},
{IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"TYPE"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"GET_LABEL"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"RBP"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"REG"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"FS"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV_FS"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GS"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV_GS"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"LEA"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_I64"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_F64"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_BOOL"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TOUPPER"},
{IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"HOLYC_TYPECAST"},
{IS_1_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ADDR"},
{IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"COM"},
{IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"NOT"},
{IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"UNARY_MINUS"},
{IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF"},
{IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF_PP"},
{IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF_MM"},
{IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"_PP"},
{IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"_MM"},
{IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"PP_"},
{IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"MM_"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SHL"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SHR"},
{IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SHL_CONST"},
{IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SHR_CONST"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"POWER"},
{IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"MUL"},
{IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"DIV"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"MOD"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"AND"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"OR"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"XOR"},
{IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ADD"},
{IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SUB"},
{IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"ADD_CONST"},
{IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SUB_CONST"},
{IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"EQU_EQU"},
{IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"NOT_EQU"},
{IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"LESS"},
{IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"GREATER_EQU"},
{IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"GREATER"},
{IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"LESS_EQU"},
{IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"PUSH_CMP"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"AND_AND"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"OR_OR"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"XOR_XOR"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN_PP"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN_MM"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SHL_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SHR_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"MUL_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"DIV_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"MOD_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"AND_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"OR_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"XOR_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ADD_EQU"},
{IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SUB_EQU"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"JMP"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SUB_CALL"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SWITCH"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOBOUND_SWITCH"},
{IS_V_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ADD_RSP"},
{IS_V_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ADD_RSP1"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ENTER"},
{IS_0_ARG,0,IST_ASSIGN,FALSE,FALSE,0,0,0,"PUSH_REGS"},
{IS_0_ARG,0,IST_ASSIGN,FALSE,FALSE,0,0,0,"POP_REGS"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"LEAVE"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RET"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_INDIRECT"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_INDIRECT2"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_IMPORT"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_EXTERN"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"ASM"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"PUSH"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"POP"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CLFLUSH"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"INVLPG"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U8"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U16"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U32"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U8"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U16"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U32"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RFLAGS"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CARRY"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RFLAGS"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RAX"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RAX"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RBP"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RBP"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RSP"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RSP"},
{IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"RIP"},
{IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"RDTSC"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BT"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTS"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTR"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTC"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTS"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTR"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTC"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BSF"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BSR"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INIT"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INS"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INS_REV"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_REM"},
{IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"STRLEN"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_ZERO"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_ZERO"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_CARRY"},
{IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_CARRY"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_EQU_EQU"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_EQU"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_LESS"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_GREATER_EQU"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_GREATER"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_LESS_EQU"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2EQU_EQU"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2NOT_EQU"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2LESS"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2GREATER_EQU"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2GREATER"},
{IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2LESS_EQU"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_ZERO"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_NOT_ZERO"},
{IS_1_ARG,0,IST_DEREF,FALSE,TRUE,0,0,0,"BR_MM_ZERO"},
{IS_1_ARG,0,IST_DEREF,FALSE,TRUE,0,0,0,"BR_MM_NOT_ZERO"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_AND_ZERO"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_AND_NOT_ZERO"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_OR_OR_ZERO"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_OR_OR_NOT_ZERO"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BT"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTS"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTR"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTC"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BT"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTS"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTR"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTC"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U8"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U16"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U32"},
{IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U64"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ABS_I64"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SIGN_I64"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"I64_MIN"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"U64_MIN"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"I64_MAX"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"U64_MAX"},
{IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"MOD_U64"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SQRI64"},
{IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SQRU64"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SQR"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ABS"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SQRT"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SIN"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"COS"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"TAN"},
{IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ATAN"},
};
U0 CmpLoadDefines()
{
DefineLstLoad("ST_RAW_TYPES",
" \0 \0I0\0U0\0I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0"
"F32\0UF32\0F64\0UF64\0");
DefineLstLoad("ST_NATURAL_TYPES",
"I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0F64\0String\0");
DefineLstLoad("ST_INT_SIZE_TYPES",
"I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0");
DefineLstLoad("ST_TY_TYPES","NULL\0STK\0IMM\0REG\0DISP\0SIB\0RIP\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_ARG_TYPES","NONE\0REL8\0REL16\0REL32\0"
"IMM8\0IMM16\0IMM32\0IMM64\0UIMM8\0UIMM16\0UIMM32\0UIMM64\0"
"R8\0R16\0R32\0R64\0RM8\0RM16\0RM32\0RM64\0"
"M8\0M16\0M32\0M64\0M1632\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");
}
U0 CmpFillTables()
{
I64 i;
U32 *d;
cmp.to_reg_vars_map=CAlloc(REG_REGS_NUM*sizeof(U8));
cmp.num_reg_vars=0;
cmp.reg_vars_mask=REGG_LOCAL_VARS;
for (i=0;i<REG_REGS_NUM;i++)
if (Bt(&cmp.reg_vars_mask,i))
cmp.to_reg_vars_map[cmp.num_reg_vars++]=i;
cmp.non_ptr_vars_map=CAlloc(REG_REGS_NUM*sizeof(U8));
cmp.num_non_ptr_vars=0;
cmp.non_ptr_vars_mask=REGG_LOCAL_NON_PTR_VARS;
for (i=0;i<REG_REGS_NUM;i++)
if (Bt(&cmp.non_ptr_vars_mask,i))
cmp.non_ptr_vars_map[cmp.num_non_ptr_vars++]=i;
cmp.dual_U16_tokens1=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
d['!']=TK_NOT_EQU<<16+'=';
d['&']=TK_AND_AND<<16+'&';
d['*']=TK_MUL_EQU<<16+'=';
d['+']=TK_PLUS_PLUS<<16+'+';
d['-']=TK_DEREFERENCE<<16+'>';
d['/']='*';
d[':']=TK_DBL_COLON<<16+':';
d['<']=TK_LESS_EQU<<16+'=';
d['=']=TK_EQU_EQU<<16+'=';
d['>']=TK_GREATER_EQU<<16+'=';
d['^']=TK_XOR_EQU<<16+'=';
d['|']=TK_OR_OR<<16+'|';
d['%']=TK_MOD_EQU<<16+'=';
cmp.dual_U16_tokens2=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
d['&']=TK_AND_EQU<<16+'=';
d['+']=TK_ADD_EQU<<16+'=';
d['-']=TK_MINUS_MINUS<<16+'-';
d['/']='/';
d['<']=TK_SHL<<16+'<';
d['>']=TK_SHR<<16+'>';
d['^']=TK_XOR_XOR<<16+'^';
d['|']=TK_OR_EQU<<16+'=';
cmp.dual_U16_tokens3=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
d['-']=TK_SUB_EQU<<16+'=';
d['/']=TK_DIV_EQU<<16+'=';
cmp.binary_ops=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
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_EQU] =PREC_CMP<<16+IC_LESS_EQU;
d[TK_GREATER_EQU] =PREC_CMP<<16+IC_GREATER_EQU;
d[TK_EQU_EQU] =PREC_CMP2<<16+IC_EQU_EQU;
d[TK_NOT_EQU] =PREC_CMP2<<16+IC_NOT_EQU;
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_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHL_EQU;
d[TK_SHR_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHR_EQU;
d[TK_MUL_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MUL_EQU;
d[TK_DIV_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_DIV_EQU;
d[TK_MOD_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MOD_EQU;
d[TK_AND_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_AND_EQU;
d[TK_OR_EQU] =(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_OR_EQU;
d[TK_XOR_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_XOR_EQU;
d[TK_ADD_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_ADD_EQU;
d[TK_SUB_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SUB_EQU;
}
+702
View File
@@ -0,0 +1,702 @@
U8 *LexStmt2Bin(CCmpCtrl *cc,I64 *_type,I64 cmp_flags=0)
{//Compile one cc stmt to bin code.
I64 size,i,j,k,*res=INVALID_PTR;
CCodeCtrl *tmpcbh;
if (_type) *_type=RT_I64;
Btr(&cc->flags,CCf_PASS_TRACE_PRESENT);
if (cc->aot_depth==2)
COCPush(cc);
COCInit(cc);
if (!PrsStmt(cc,,,cmp_flags)) {
if (cc->coc.coc_head.next!=&cc->coc.coc_head) {
cc->coc.coc_head.last->ic_flags&=~ICF_RES_NOT_USED;
ICAdd(cc,IC_RETURN_VAL2,0,0);
ICAdd(cc,IC_RET,0,0);
if (res=COCCompile(cc,&size,NULL,_type)) {
if (cc->flags&CCF_AOT_COMPILE) {
j=cc->aotc->rip;
k=(size+7)>>3;
for (i=0;i<k;i++)
AOTStoreCodeU64(cc,res[i]);
Free(res);
res=j;
}
}
} //TODO: else del misc?
} else //TODO: too dangerous to del Misc?
QueDel(&cc->coc.coc_head.next);
if (cc->aot_depth==2) {
tmpcbh=COCPopNoFree(cc);
COCAppend(cc,tmpcbh);
}
return res;
}
CAOT *CmpJoin(CCmpCtrl *cc,I64 cmp_flags,U8 *map_name=NULL,U8 mapfile_drv_let=0)
{
CAOTCtrl *aotc,*old_aot=cc->aotc;
I64 i,j,l;
U8 *buf;
CAOTBinBlk *tmpbin;
CAOTImportExport *tmpie;
Bool okay=TRUE;
CLexHashTableContext *htc=MAlloc(sizeof(CLexHashTableContext));
CAOT *res=CAlloc(sizeof(CAOT)),*parent;
if (parent=cc->aot) {
res->parent_aot=parent;
QueIns(res,parent->last);
} else
QueInit(res);
cc->aot=res;
res->next_ie=res->last_ie=&res->next_ie;
cc->aotc=aotc=CAlloc(sizeof(CAOTCtrl));
cc->aot_depth++;
aotc->bin=CAlloc(sizeof(CAOTBinBlk));
aotc->max_align_bits=0;
aotc->module_org=INVALID_PTR;
MemCpy(htc,&cc->htc,sizeof(CLexHashTableContext));
if (cc->htc.fun)
cc->htc.glbl_hash_table=HashTableNew(128);
else
cc->htc.glbl_hash_table=HashTableNew(1024);
if (cc->flags&CCF_AOT_COMPILE) {
cc->htc.define_hash_table=cc->htc.glbl_hash_table;
if (cc->aot_depth<=1)
cc->htc.glbl_hash_table->next=cmp.asm_hash;
else
cc->htc.glbl_hash_table->next=htc->glbl_hash_table;
} else
cc->htc.glbl_hash_table->next=Fs->hash_table;
cc->htc.hash_table_lst=cc->htc.local_hash_table=HashTableNew(16);
cc->htc.local_hash_table->next=cc->htc.glbl_hash_table;
cc->htc.local_var_lst=cc->htc.fun; //HolyC local vars
cc->htc.fun=NULL;
try {
if (cmp_flags&CMPF_LEX_FIRST)
Lex(cc);
if (!(cmp_flags&CMPF_ONE_ASM_INS))
cmp_flags|=CMPF_PRS_SEMICOLON;
if (cc->flags&CCF_AOT_COMPILE) {
while (cc->token!=TK_EOF) {
buf=LexStmt2Bin(cc,NULL,cmp_flags);
if (buf!=INVALID_PTR) {
tmpie=CAlloc(sizeof(CAOTImportExport));
tmpie->type=IET_MAIN;
tmpie->rip=buf;
QueIns(tmpie,res->last_ie);
}
if (cmp_flags&CMPF_ASM_BLK)
break;
}
} else
PrsStmt(cc,,,cmp_flags);
AOTGlblsResolve(cc,res);
} catch {
if (Fs->except_ch=='Compiler' && !(cmp_flags&CMPF_ASM_BLK)) {
LexPutPos(cc);
Fs->catch_except=TRUE;
}
okay=FALSE;
}
if (!okay) {
if (cc->error_cnt<1)
cc->error_cnt=1;
cc->aot=res->parent_aot;
Free(res);
LinkedLstDel(aotc->bin);
res=NULL;
} else {
if (map_name)
MapFileWrite(cc->htc.glbl_hash_table,map_name,mapfile_drv_let);
HashTableDel(cc->htc.local_hash_table);
HashTableDel(cc->htc.glbl_hash_table);
if (!aotc->num_bin_U8s)
res->buf=NULL;
else {
if (cc->flags&CCF_AOT_COMPILE)
res->buf=MAlloc(aotc->num_bin_U8s);
else {
if (aotc->module_org==INVALID_PTR)
res->buf=MAlloc(aotc->num_bin_U8s,Fs->code_heap);
else
res->buf=aotc->module_org;
}
res->aot_U8s=aotc->num_bin_U8s;
tmpbin=aotc->bin;
j=0;
l=aotc->num_bin_U8s;
while (tmpbin) {
i=l;
if (i>AOT_BIN_BLK_SIZE)
i=AOT_BIN_BLK_SIZE;
MemCpy(res->buf+j,tmpbin->body,i);
j+=i;
l-=i;
tmpbin=tmpbin->next;
}
}
LinkedLstDel(aotc->bin);
res->abss=aotc->abss;
res->heap_glbls=aotc->heap_glbls;
res->max_align_bits=aotc->max_align_bits;
res->module_org=aotc->module_org;
}
cc->aot=parent;
MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
Free(htc);
Free(aotc);
cc->aotc=old_aot;
cc->aot_depth--;
return res;
}
CAOT *CmpBuf(U8 *buf,U8 *map_name=NULL,
I64 *error_cnt=NULL, I64 *warning_cnt=NULL,U8 mapfile_drv_let=0)
{
CCmpCtrl *cc;
CAOT *res=NULL;
cc=CmpCtrlNew(buf,CCF_DONT_FREE_BUF);
cc->flags|=CCF_AOT_COMPILE;
QueIns(cc,Fs->last_cc);
res=CmpJoin(cc,CMPF_LEX_FIRST,map_name,mapfile_drv_let);
if (error_cnt) *error_cnt=cc->error_cnt;
if (warning_cnt) *warning_cnt=cc->warning_cnt;
QueRem(cc);
if (res)
CmpCtrlDel(cc);
return res;
}
U0 CmpFixUpJITAsm(CCmpCtrl *cc,CAOT *tmpaot)
{
I64 i,rip2=tmpaot->buf+tmpaot->rip,*str=NULL;
U8 *ptr;
CCodeMisc *g_lb;
CAOTAbsAddr *tmpa,*tmpa1;
CAOTImportExport *tmpie,*tmpie1;
CHashExport *tmpex;
tmpa=tmpaot->abss;
while (tmpa) {
tmpa1=tmpa->next;
ptr=rip2+tmpa->rip;
switch [tmpa->type] {
case AAT_ADD_U8: *ptr(U8 *) +=rip2; break;
case AAT_SUB_U8: *ptr(U8 *) -=rip2; break;
case AAT_ADD_U16: *ptr(U16 *)+=rip2; break;
case AAT_SUB_U16: *ptr(U16 *)-=rip2; break;
case AAT_ADD_U32: *ptr(U32 *)+=rip2; break;
case AAT_SUB_U32: *ptr(U32 *)-=rip2; break;
case AAT_ADD_U64: *ptr(I64 *)+=rip2; break;
case AAT_SUB_U64: *ptr(I64 *)-=rip2; break;
}
Free(tmpa);
tmpa=tmpa1;
}
tmpie=tmpaot->next_ie;
while (tmpie!=&tmpaot->next_ie) {
tmpie1=tmpie->next;
if (tmpie->str) {
Free(str);
str=tmpie->str;
}
switch (tmpie->type) {
case IET_REL32_EXPORT:
case IET_IMM32_EXPORT:
case IET_REL64_EXPORT:
case IET_IMM64_EXPORT:
tmpex=CAlloc(sizeof(CHashExport));
tmpex->str=str;
str=NULL;
tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
if (tmpie->type==IET_IMM32_EXPORT||tmpie->type==IET_IMM64_EXPORT)
tmpex->val=tmpie->rip;
else
tmpex->val=tmpie->rip+rip2;
tmpex->src_link=tmpie->src_link;
tmpie->src_link=NULL;
HashAdd(tmpex,Fs->hash_table);
SysSymImportsResolve(tmpex->str);
break;
case IET_REL_I0...IET_IMM_I64:
if (tmpie->str) {
if (tmpie->flags&IEF_GOTO_LABEL) {
if(!(g_lb=COCGoToLabelFind(cc,str)))
"Unresolved Reference:%s\n",str;
else {
g_lb->use_cnt++;
g_lb=OptLabelFwd(g_lb);
i=g_lb->addr+tmpaot->buf;
}
tmpex=NULL;
} else {
if (!(tmpex=HashFind(str,Fs->hash_table,
HTG_ALL-HTT_IMPORT_SYS_SYM)))
"Unresolved Reference:%s\n",str;
else {
if (tmpex->type & HTT_FUN)
i=tmpex(CHashFun *)->exe_addr;
else if (tmpex->type & HTT_GLBL_VAR)
i=tmpex(CHashGlblVar *)->data_addr;
else
i=tmpex->val;
}
g_lb=NULL;
}
}
if (tmpex || g_lb) {
ptr=tmpie->rip+rip2;
switch [tmpie->type] {
case IET_REL_I0:
case IET_IMM_U0:
break;
case IET_REL_I8:
if (!(I8_MIN<=i-ptr-1<=I8_MAX))
LexExcept(cc,"Branch out of range at ");
*ptr(U8 *) =i-ptr-1;
break;
case IET_IMM_U8:
*ptr(U8 *) =i;
break;
case IET_REL_I16:
if (!(I16_MIN<=i-ptr-2<=I16_MAX))
LexExcept(cc,"Branch out of range at ");
*ptr(U16 *)=i-ptr-2;
break;
case IET_IMM_U16:
*ptr(U16 *)=i;
break;
case IET_REL_I32:
if (!(I32_MIN<=i-ptr-4<=I32_MAX))
LexExcept(cc,"Branch out of range at ");
*ptr(U32 *)=i-ptr-4;
break;
case IET_IMM_U32:
*ptr(U32 *)=i;
break;
case IET_REL_I64:
*ptr(I64 *)=i-ptr-8;
break;
case IET_IMM_I64:
*ptr(I64 *)=i;
break;
}
}
break;
}
Free(tmpie->src_link);
Free(tmpie);
tmpie=tmpie1;
}
Free(str);
if (!cc->aot_depth && Bt(&cc->opts,OPTf_TRACE))
Un(rip2,tmpaot->aot_U8s,64);
QueRem(tmpaot);
Free(tmpaot);
}
U0 CmpFixUpAOTAsm(CCmpCtrl *cc,CAOT *tmpaot)
{
CAOTCtrl *aotc=cc->aotc;
I64 i,rip2=tmpaot->rip+cc->aotc->rip;
U8 *ptr;
CCodeMisc *g_lb=NULL;
CAOTAbsAddr *tmpa,*tmpa1;
CAOTImportExport *tmpie,*tmpie1;
tmpa=tmpaot->abss;
while (tmpa) {
tmpa1=tmpa->next;
tmpa->next=aotc->abss;
ptr=tmpaot->buf+tmpaot->rip+tmpa->rip;
switch [tmpa->type] {
case AAT_ADD_U8: *ptr(U8 *)+=rip2; break;
case AAT_SUB_U8: *ptr(U8 *)-=rip2; break;
case AAT_ADD_U16: *ptr(U16 *)+=rip2; break;
case AAT_SUB_U16: *ptr(U16 *)-=rip2; break;
case AAT_ADD_U32: *ptr(U32 *)+=rip2; break;
case AAT_SUB_U32: *ptr(U32 *)-=rip2; break;
case AAT_ADD_U64: *ptr(I64 *)+=rip2; break;
case AAT_SUB_U64: *ptr(I64 *)-=rip2; break;
}
aotc->abss=tmpa;
tmpa->rip+=rip2;
tmpa=tmpa1;
}
tmpie=tmpaot->next_ie;
while (tmpie!=&tmpaot->next_ie) {
tmpie1=tmpie->next;
QueRem(tmpie);
if (IET_REL_I0<=tmpie->type<=IET_IMM_I64) {
if (tmpie->str) {
if (tmpie->flags&IEF_GOTO_LABEL) {
if(!(g_lb=COCGoToLabelFind(cc,tmpie->str)))
"Unresolved Reference:%s\n",tmpie->str;
else {
g_lb->use_cnt++;
g_lb=OptLabelFwd(g_lb);
}
} else
g_lb=NULL;
}
} else
g_lb=NULL;
ptr=tmpaot->buf+tmpaot->rip+tmpie->rip;
if (g_lb) {
i=g_lb->addr+tmpaot->buf;
switch [tmpie->type] {
case IET_REL_I0:
case IET_IMM_U0:
break;
case IET_REL_I8:
if (!(I8_MIN<=i-ptr-1<=I8_MAX))
LexExcept(cc,"Branch out of range at ");
*ptr(U8 *) =i-ptr-1;
break;
case IET_IMM_U8:
*ptr(U8 *) =i;
break;
case IET_REL_I16:
if (!(I16_MIN<=i-ptr-2<=I16_MAX))
LexExcept(cc,"Branch out of range at ");
*ptr(U16 *)=i-ptr-2;
break;
case IET_IMM_U16:
*ptr(U16 *)=i;
break;
case IET_REL_I32:
if (!(I32_MIN<=i-ptr-4<=I32_MAX))
LexExcept(cc,"Branch out of range at ");
*ptr(U32 *)=i-ptr-4;
break;
case IET_IMM_U32:
*ptr(U32 *)=i;
break;
case IET_REL_I64:
*ptr(I64 *)=i-ptr-8;
break;
case IET_IMM_I64:
*ptr(I64 *)=i;
break;
}
Free(tmpie->src_link);
Free(tmpie);
} else {
switch (tmpie->type) {
start:
case IET_REL32_EXPORT:
case IET_IMM32_EXPORT:
case IET_REL64_EXPORT:
case IET_IMM64_EXPORT:
case IET_IMM_U0:
case IET_IMM_U8:
case IET_IMM_U16:
case IET_IMM_U32:
case IET_IMM_I64:
case IET_REL_I0:
break;
case IET_REL_I8: *ptr(U8 *) -=rip2; break;
case IET_REL_I16: *ptr(U16 *)-=rip2; break;
case IET_REL_I32: *ptr(U32 *)-=rip2; break;
case IET_REL_I64: *ptr(I64 *)-=rip2; break;
end:
tmpie->rip+=rip2;
break;
}
tmpie->aot=NULL;
QueIns(tmpie,tmpaot->parent_aot->last_ie);
}
tmpie=tmpie1;
}
}
I64 Cmp(U8 *filename,U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv_let=0)
{//AOT Compile HC or PRJ file a and output BIN file. Returns err_cnt.
U8 *ptr,*fbuf=NULL,*fbuf2=NULL,*fbuf3=NULL,
*patch_table=MAlloc(0x20000);
CAOT *tmpaot;
I64 i,cnt,size=0,error_cnt=0,warning_cnt=0,aot_U8s=0;
CBinFile *bfh;
CAOTImportExport *tmpie,*tmpie1;
CAOTAbsAddr *tmpa,*tmpa1;
CAOTHeapGlblRef *tmphgr,*tmphgr1;
CAOTHeapGlbl *tmphg,*tmphg1;
fbuf=DftExt(filename,"PRJ.Z");
fbuf2=MStrPrint("#include \"%s\"",fbuf);
if (map_name)
fbuf3=DftExt(map_name,"MAP.Z");
if (tmpaot=CmpBuf(fbuf2,fbuf3,&error_cnt,&warning_cnt,mapfile_drv_let)) {
aot_U8s=tmpaot->aot_U8s;
ptr=patch_table;
//See $LK,"Load",A="MN:Load"$()
cnt=0;
tmpa=tmpaot->abss;
while (tmpa) {
if (!(tmpa->type&IEF_IMM_NOT_REL))
cnt++;
tmpa=tmpa->next;
}
if (cnt) {
*ptr++=IET_ABS_ADDR;
*ptr(U32 *)++=cnt;
*ptr++=0;
tmpa=tmpaot->abss;
while (tmpa) {
tmpa1=tmpa->next;
if (!(tmpa->type&IEF_IMM_NOT_REL))
*ptr(U32 *)++ =tmpa->rip;
Free(tmpa);
tmpa=tmpa1;
}
}
tmphg=tmpaot->heap_glbls;
while (tmphg) {
tmphg1=tmphg->next;
cnt=0;
tmphgr=tmphg->references;
while (tmphgr) {
cnt++;
tmphgr=tmphgr->next;
}
if (cnt) {
*ptr++=IET_DATA_HEAP;
*ptr(U32 *)++=cnt;
if (tmphg->str) {
i=StrLen(tmphg->str);
MemCpy(ptr,tmphg->str,i+1);
Free(tmphg->str);
ptr+=i+1;
} else
*ptr++=0;
*ptr(I64 *)++=tmphg->size;
tmphgr=tmphg->references;
while (tmphgr) {
tmphgr1=tmphgr->next;
*ptr(U32 *)++=tmphgr->rip;
Free(tmphgr);
tmphgr=tmphgr1;
}
}
Free(tmphg);
tmphg=tmphg1;
}
//Do exports first
tmpie=tmpaot->next_ie;
while (tmpie!=&tmpaot->next_ie) {
tmpie1=tmpie->next;
if (!tmpie->type || IET_REL32_EXPORT<=tmpie->type<=IET_IMM64_EXPORT) {
QueRem(tmpie);
*ptr++=tmpie->type;
*ptr(U32 *)++=tmpie->rip;
if (tmpie->str) {
i=StrLen(tmpie->str);
MemCpy(ptr,tmpie->str,i+1);
Free(tmpie->str);
ptr+=i+1;
} else
*ptr++=0;
Free(tmpie->src_link);
Free(tmpie);
}
tmpie=tmpie1;
}
//Do imports second
tmpie=tmpaot->next_ie;
while (tmpie!=&tmpaot->next_ie) {
tmpie1=tmpie->next;
QueRem(tmpie);
*ptr++=tmpie->type;
if (tmpie->aot)
tmpie->rip+=tmpie->aot->rip2;
*ptr(U32 *)++=tmpie->rip;
if (tmpie->str) {
i=StrLen(tmpie->str);
MemCpy(ptr,tmpie->str,i+1);
Free(tmpie->str);
ptr+=i+1;
} else
*ptr++=0;
Free(tmpie->src_link);
Free(tmpie);
tmpie=tmpie1;
}
*ptr++=IET_END;
MemSet(ptr,0,16);
i=ptr-patch_table;
//Needs 16 ALIGN
size=(sizeof(CBinFile)+aot_U8s+i+15)&-16;
bfh=MAlloc(size);
bfh->jmp=0xEB+256*(sizeof(CBinFile)-2);
#assert sizeof(CBinFile)-2<=I8_MAX
bfh->reserved=0;
bfh->bin_signature=BIN_SIGNATURE_VAL;
bfh->module_org=tmpaot->module_org;
bfh->module_align_bits=tmpaot->max_align_bits;
bfh->patch_table_offset=sizeof(CBinFile)+aot_U8s;
bfh->file_size=size;
MemCpy(bfh(U8 *)+sizeof(CBinFile),tmpaot->buf,aot_U8s);
MemCpy(bfh(U8 *)+sizeof(CBinFile)+aot_U8s,patch_table,
size-aot_U8s-sizeof(CBinFile));
Free(fbuf2);
if (out_name)
fbuf2=DftExt(out_name,"BIN.Z");
else
fbuf2=ChgExt(fbuf,"BIN.Z");
FileWrite(fbuf2,bfh,size);
Free(bfh);
Free(tmpaot->buf);
QueDel(tmpaot);
Free(tmpaot);
}
Free(patch_table);
Free(fbuf);
Free(fbuf2);
Free(fbuf3);
Print("Errs:%d Warns:%d Code:%X Size:%X\n",
error_cnt,warning_cnt,aot_U8s,size);
return error_cnt;
}
I64 ExePutS(U8 *buf,U8 *filename=NULL,
I64 ccf_flags=0,CLexHashTableContext *htc=NULL)
{//JIT Compile and execute text from a puts("").
I64 res;
Bool okay=TRUE;
CCmpCtrl *cc;
if (!filename)
filename=blkdev.tmp_filename;
cc=CmpCtrlNew(buf,ccf_flags|CCF_DONT_FREE_BUF,filename);
if (Fs->last_cc!=&Fs->next_cc) {
cc->opts=Fs->last_cc->opts;
if (htc) {
cc->flags=cc->flags &~CCF_ASM_EXPRESSIONS |
htc->old_flags&CCF_ASM_EXPRESSIONS;
MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
}
}
QueIns(cc,Fs->last_cc);
try {
Lex(cc);
res=ExeCmdLine(cc);
} catch {
if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
Fs->catch_except=TRUE;
okay=FALSE;
res=0;
}
}
QueRem(cc);
if (okay)
CmpCtrlDel(cc); //TODO: can crash
return res;
}
I64 ExePrint(U8 *fmt,...)
{//JIT Compile and execute text from a printf().
I64 res;
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
res=ExePutS(buf);
Free(buf);
return res;
}
I64 ExeFile(U8 *name,I64 ccf_flags=0)
{//JIT Compile and execute a file.
I64 res;
U8 *name2=DftExt(name,"HC.Z"),
*st=MStrPrint("#include \"%s\";",name2);
res=ExePutS(st,name,ccf_flags);
Free(st);
Free(name2);
return res;
}
I64 RunFile(U8 *name,I64 ccf_flags=0,...)
{//$LK,"ExeFile",A="MN:ExeFile"$() with args using $LK,"LastFun",A="MN:LastFun"$().
ExeFile(name,ccf_flags);
return LastFun(argc,argv);
}
I64 ExePutS2(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0)
{//throws exceptions
I64 res;
CCmpCtrl *cc;
if (!filename)
filename=blkdev.tmp_filename;
cc=CmpCtrlNew(buf,ccf_flags|CCF_DONT_FREE_BUF,filename);
if (Fs->last_cc!=&Fs->next_cc)
cc->opts=Fs->last_cc->opts;
QueIns(cc,Fs->last_cc);
Lex(cc);
res=ExeCmdLine(cc);
QueRem(cc);
CmpCtrlDel(cc);
return res;
}
I64 ExePrint2(U8 *fmt,...)
{//throws exceptions
I64 res;
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
res=ExePutS2(buf);
Free(buf);
return res;
}
I64 ExeFile2(U8 *name,I64 ccf_flags=0)
{//throws exceptions
I64 res;
U8 *name2=DftExt(name,"HC.Z"),*st=MStrPrint("#include \"%s\";",name2);
res=ExePutS2(st,name,ccf_flags);
Free(st);
Free(name2);
return res;
}
I64 RunFile2(U8 *name,I64 ccf_flags=0,...)
{//$LK,"ExeFile2",A="MN:ExeFile2"$() with args using $LK,"LastFun",A="MN:LastFun"$(). throws exceptions.
ExeFile2(name,ccf_flags);
return LastFun(argc,argv);
}
I64 StreamExePrint(U8 *fmt,...)
{//Causes value from stream to be used in an #exe{} block.
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
I64 res=0;
CLexHashTableContext *htc;
CCmpCtrl *cc=Fs->last_cc;
if (cc==&Fs->next_cc)
PrintErr("Not Compiling\n");
else {
if (!(cc->flags&CCF_EXE_BLK))
LexExcept(cc,"StreamExePrint only allowed in AOT compiled #exe{} mode.");
if (htc=cc->htc.next)
res=ExePutS(buf,,,htc);
}
Free(buf);
return res;
}
U0 CInit()
{
CmpLoadDefines;
CmpFillTables;
QueInit(&cmp.ic_nop);
cmp.ic_nop.ic_class=cmp.internal_types[RT_I64];
cmp.ic_nop.ic_code=IC_NOP1;
AsmHashLoad;
UAsmHashLoad;
}
CInit;
+164
View File
@@ -0,0 +1,164 @@
Bool Option(I64 num,Bool val)
{//Set compiler $LK,"Option",A="FI:::/Doc/Options.DD"$ to val.
return BEqu(&Fs->last_cc->opts,num,val);
}
Bool GetOption(I64 num)
{//Get state of compiler $LK,"option",A="MN:OPTf_ECHO"$.
return Bt(&Fs->last_cc->opts,num);
}
asm {
_LAST_FUN:: //See $LK,"_CALL_IND",A="MN:_CALL_IND"$
PUSH RBP
MOV RBP,RSP
PUSH RSI
PUSH RDI
XOR RAX,RAX
MOV RAX,FS:CTask.last_fun[RAX]
TEST RAX,RAX
JZ @@10
MOV RDX,U64 CHashFun.exe_addr[RAX]
MOV RCX,U64 SF_ARG1[RBP] //argc
MOV RSI,U64 SF_ARG2[RBP] //argv
SHL RCX,3
SUB RSP,RCX
MOV RDI,RSP
REP_MOVSB
TEST RDX,RDX
JZ @@05
CALL RDX
POP RDI
POP RSI
POP RBP
RET1 16
@@05: MOV RCX,U64 SF_ARG1[RBP] //argc
SHL RCX,3
ADD RSP,RCX
XOR RAX,RAX
@@10: POP RDI
POP RSI
POP RBP
RET1 16
}
_extern _LAST_FUN I64 LastFun(I64 argc,I64 *argv); //Execute last fun with args.
I64 PassTrace(I64 i=0b10001111101)
{//Ctrls which optimizer passes are displayed.
I64 old=Fs->last_cc->pass_trace;
if (i) Fs->last_cc->saved_pass_trace=i;
Fs->last_cc->pass_trace=i;
return old;
}
Bool Trace(Bool val=ON)
{//Displays assembly code output from compiler.
return Option(OPTf_TRACE,val);
}
Bool Echo(Bool val)
{//Displays text as it is being compiled.
return Option(OPTf_ECHO,val);
}
U0 StreamPrint(U8 *fmt,...)
{//Injects text into the compile stream. Used in #exe{} blocks.
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st;
CCmpCtrl *cc=Fs->last_cc;
CStreamBlk *tmpe=cc->last_stream_blk;
if (tmpe!=&cc->next_stream_blk) {
st=MStrPrint("%s%s",tmpe->body,buf);
Free(tmpe->body);
tmpe->body=st;
} else
PrintErr("No exe{} blk\n");
Free(buf);
}
U0 StreamDir()
{
U8 *dirname;
if (dirname=DirFile(Fs->last_cc->lex_include_stk->full_name)) {
StreamPrint("\"%s\"",dirname);
Free(dirname);
}
}
CD2I32 *LexD2I32(CCmpCtrl *cc,CD2I32 *p)
{//Not HolyC. Sprite-like lex 2D point.
if (cc->token!='(')
LexExcept(cc,"Expecting '(' at ");
Lex(cc); //Skip (
p->x=LexExpressionI64(cc);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
p->y=LexExpressionI64(cc);
if (cc->token!=')')
LexExcept(cc,"Expecting ')' at ");
Lex(cc); //Skip )
return p;
}
CD3I32 *LexD3I32(CCmpCtrl *cc,CD3I32 *p)
{//Not HolyC. Sprite-like lex 3D point.
if (cc->token!='(')
LexExcept(cc,"Expecting '(' at ");
Lex(cc); //Skip (
p->x=LexExpressionI64(cc);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
p->y=LexExpressionI64(cc);
if (cc->token!=',')
LexExcept(cc,"Expecting ',' at ");
Lex(cc); //Skip ,
p->z=LexExpressionI64(cc);
if (cc->token!=')')
LexExcept(cc,"Expecting ')' at ");
Lex(cc); //Skip )
return p;
}
U8 *CmdLinePmt()
{
I64 i;
U8 *res,*st;
if (Fs->new_answer) {
if (Fs->answer_type==RT_F64)
"%8.6fs ansf=%15.7g\n",Fs->answer_time,Fs->answer;
else
"%8.6fs ans=0x%08X=%d\n",Fs->answer_time,Fs->answer,Fs->answer;
Fs->new_answer=FALSE;
}
if (st=CurDir) {
"%s",st;
Free(st);
}
'>';
if (IsDbgMode&&IsRaw)
RawDr;
LBts(&Fs->task_flags,TASKf_CMD_LINE_PMT);
st=GetStr(,,GSF_SHIFT_ESC_EXIT);
LBtr(&Fs->task_flags,TASKf_CMD_LINE_PMT);
i=StrLen(st);
res=MAlloc(i+1+2);
MemCpy(res,st,i+1);
i--;
while (i>=0 && Bt(char_bmp_white_space,res[i]))
i--;
i++;
if (i>0 && res[i-1]==';')
res[i++]=';'; //The Lex goes one beyond
res[i++]='\n';//#define goes to '\n'
res[i]=0;
Free(st);
return res;
}
Binary file not shown.
+423
View File
@@ -0,0 +1,423 @@
$LK,"LexPutPos",A="FL:::/Compiler/CExcept.HC.Z,50",BI=1$
$LK,"ICAssignPostIncDec",A="FL:::/Compiler/BackB.HC.Z,429",BI=2$
$LK,"CmpSetFloatOpPushPop",A="FL:::/Compiler/BackFA.HC.Z,62",BI=3$
$LK,"ICFCvt2",A="FL:::/Compiler/BackFA.HC.Z,169",BI=4$
$LK,"CmpMinTypePointed",A="FL:::/Compiler/OptLib.HC.Z,528",BI=5$
$LK,"CmpRawTypePointed",A="FL:::/Compiler/OptLib.HC.Z,517",BI=6$
$LK,"OptFixupBinaryOp1",A="FL:::/Compiler/OptLib.HC.Z,96",BI=7$
$LK,"OptFixupBinaryOp2",A="FL:::/Compiler/OptLib.HC.Z,182",BI=8$
$LK,"COCInit",A="FL:::/Compiler/PrsLib.HC.Z,99",BI=9$
$LK,"IsLexExpression2Bin",A="FL:::/Compiler/PrsExp.HC.Z,1135",BI=10$
$LK,"CSubSwitch",A="FL:::/Compiler/PrsStmt.HC.Z,566"$
$LK,"LexFilePop",A="FL:::/Compiler/Lex.HC.Z,11",BI=11$
$LK,"ExePutS",A="FL:::/Compiler/CMain.HC.Z,571",BI=12$
$LK,"PrsStaticInit",A="FL:::/Compiler/PrsVar.HC.Z,215",BI=13$
$LK,"LexPutLine",A="FL:::/Compiler/CExcept.HC.Z,22",BI=14$
$LK,"PrsKeyWord",A="FL:::/Compiler/PrsLib.HC.Z,31",BI=15$
$LK,"AsmLineLst",A="FL:::/Compiler/AsmLib.HC.Z,147",BI=16$
$LK,"ICOpSizeRex",A="FL:::/Compiler/BackLib.HC.Z,28",BI=17$
$LK,"CVI2",A="FL:::/Compiler/PrsVar.HC.Z,117"$
$LK,"ICU8",A="FL:::/Compiler/BackLib.HC.Z,17",BI=18$
$LK,"AsmStoreNum",A="FL:::/Compiler/Asm.HC.Z,268",BI=19$
$LK,"OptPass012",A="FL:::/Compiler/OptPass012.HC.Z,23",BI=20$
$LK,"MemberLstSize",A="FL:::/Compiler/LexLib.HC.Z,221",BI=21$
$LK,"ICQueIns",A="FL:::/Compiler/BackC.HC.Z,354",BI=22$
$LK,"ICAndBranch",A="FL:::/Compiler/BackC.HC.Z,1",BI=23$
$LK,"U",A="FL:::/Compiler/UAsm.HC.Z,653",BI=24$
$LK,"ICQueRem",A="FL:::/Compiler/BackC.HC.Z,402",BI=25$
$LK,"LastFun",A="FL:::/Compiler/CMisc.HC.Z,48"$
$LK,"OptLead1",A="FL:::/Compiler/OptLib.HC.Z,73",BI=26$
$LK,"CmpNoteFloatOp",A="FL:::/Compiler/BackFA.HC.Z,6",BI=27$
$LK,"AOTGlblsResolve",A="FL:::/Compiler/AsmResolve.HC.Z,77",BI=28$
$LK,"ExePutS2",A="FL:::/Compiler/CMain.HC.Z,631",BI=29$
$LK,"HashEntrySize",A="FL:::/Compiler/CHash.HC.Z,1",BI=30$
$LK,"COCPush",A="FL:::/Compiler/PrsLib.HC.Z,107",BI=31$
$LK,"SLASH_OP_DEC",A="FL:::/Compiler/BackLib.HC.Z,259"$
$LK,"MODR_SIB_D32_INDIRECT_REG",A="FL:::/Compiler/BackLib.HC.Z,132"$
$LK,"ICPushRegs",A="FL:::/Compiler/BackLib.HC.Z,350",BI=32$
$LK,"PE_POP_HIGHER",A="FL:::/Compiler/PrsExp.HC.Z,10"$
$LK,"SLASH_OP_FLD",A="FL:::/Compiler/BackLib.HC.Z,277"$
$LK,"ICU32",A="FL:::/Compiler/BackLib.HC.Z,47",BI=33$
$LK,"ICU24",A="FL:::/Compiler/BackLib.HC.Z,41",BI=34$
$LK,"ICU16",A="FL:::/Compiler/BackLib.HC.Z,35",BI=35$
$LK,"SLASH_OP_DIV",A="FL:::/Compiler/BackLib.HC.Z,266"$
$LK,"CmpFillTables",A="FL:::/Compiler/CInit.HC.Z,239",BI=36$
$LK,"AOTStoreCodeU32",A="FL:::/Compiler/AsmLib.HC.Z,30",BI=37$
$LK,"ICU64",A="FL:::/Compiler/BackLib.HC.Z,53",BI=38$
$LK,"SLASH_OP_INC",A="FL:::/Compiler/BackLib.HC.Z,258"$
$LK,"AOTStoreCodeU64",A="FL:::/Compiler/AsmLib.HC.Z,68",BI=39$
$LK,"LexPopNoRestore",A="FL:::/Compiler/LexLib.HC.Z,38",BI=40$
$LK,"ExePrint",A="FL:::/Compiler/CMain.HC.Z,605",BI=41$
$LK,"SLASH_OP_NEG",A="FL:::/Compiler/BackLib.HC.Z,261"$
$LK,"PrsVarLst",A="FL:::/Compiler/PrsVar.HC.Z,416",BI=42$
$LK,"PrsAsmDefine",A="FL:::/Compiler/Asm.HC.Z,814",BI=43$
$LK,"PrsAddOp",A="FL:::/Compiler/PrsExp.HC.Z,15",BI=44$
$LK,"LexWarn",A="FL:::/Compiler/CExcept.HC.Z,65",BI=45$
$LK,"PE_POP_ALL1",A="FL:::/Compiler/PrsExp.HC.Z,12"$
$LK,"PE_POP_ALL2",A="FL:::/Compiler/PrsExp.HC.Z,13"$
$LK,"COCAppend",A="FL:::/Compiler/PrsLib.HC.Z,126",BI=46$
$LK,"LexFilePush",A="FL:::/Compiler/Lex.HC.Z,1",BI=47$
$LK,"PrsUnaryModifier",A="FL:::/Compiler/PrsExp.HC.Z,960",BI=48$
$LK,"OptFixupUnaryOp",A="FL:::/Compiler/OptLib.HC.Z,196",BI=49$
$LK,"LexPush",A="FL:::/Compiler/LexLib.HC.Z,12",BI=50$
$LK,"SLASH_OP_MOV",A="FL:::/Compiler/BackLib.HC.Z,267"$
$LK,"ICPopRegs",A="FL:::/Compiler/BackLib.HC.Z,391",BI=51$
$LK,"SLASH_OP_MUL",A="FL:::/Compiler/BackLib.HC.Z,264"$
$LK,"SLASH_OP_NOT",A="FL:::/Compiler/BackLib.HC.Z,260"$
$LK,"SLASH_OP_POP",A="FL:::/Compiler/BackLib.HC.Z,270"$
$LK,"ICFOp",A="FL:::/Compiler/BackFA.HC.Z,339",BI=52$
$LK,"CN_A1",A="FL:::/Compiler/BackFA.HC.Z,2"$
$LK,"CN_A2",A="FL:::/Compiler/BackFA.HC.Z,1"$
$LK,"LexExpressionF64",A="FL:::/Compiler/PrsExp.HC.Z,1154",BI=53$
$LK,"ICAdd",A="FL:::/Compiler/PrsLib.HC.Z,79",BI=54$
$LK,"CmpRawType",A="FL:::/Compiler/OptLib.HC.Z,508",BI=55$
$LK,"ICFOpEqu",A="FL:::/Compiler/BackFB.HC.Z,1",BI=56$
$LK,"LexExpressionI64",A="FL:::/Compiler/PrsExp.HC.Z,1140",BI=57$
$LK,"ICQueInsRev",A="FL:::/Compiler/BackC.HC.Z,378",BI=58$
$LK,"LexExpression",A="FL:::/Compiler/PrsExp.HC.Z,1168",BI=59$
$LK,"PrsExpression",A="FL:::/Compiler/PrsExp.HC.Z,264",BI=60$
$LK,"PrsClassNew",A="FL:::/Compiler/PrsLib.HC.Z,40",BI=61$
$LK,"LexInStr",A="FL:::/Compiler/Lex.HC.Z,367",BI=62$
$LK,"internal_types_table",A="FL:::/Compiler/CInit.HC.Z,6"$
$LK,"CN_INST",A="FL:::/Compiler/BackFA.HC.Z,3"$
$LK,"OptPass3",A="FL:::/Compiler/OptPass3.HC.Z,1",BI=63$
$LK,"OptPass4",A="FL:::/Compiler/OptPass4.HC.Z,133",BI=64$
$LK,"OptPass5",A="FL:::/Compiler/OptPass5.HC.Z,1",BI=65$
$LK,"OptPass6",A="FL:::/Compiler/OptPass6.HC.Z,96",BI=66$
$LK,"MODR_REG",A="FL:::/Compiler/BackLib.HC.Z,126"$
$LK,"Echo",A="FL:::/Compiler/CMisc.HC.Z,63",BI=67$
$LK,"PrsGlblVarLst",A="FL:::/Compiler/PrsStmt.HC.Z,209",BI=68$
$LK,"ICQueInit",A="FL:::/Compiler/BackC.HC.Z,340",BI=69$
$LK,"ICCmp",A="FL:::/Compiler/BackB.HC.Z,102",BI=70$
$LK,"ICAddRSP",A="FL:::/Compiler/BackLib.HC.Z,59",BI=71$
$LK,"ICDiv",A="FL:::/Compiler/BackA.HC.Z,355",BI=72$
$LK,"ICDeref",A="FL:::/Compiler/BackLib.HC.Z,693",BI=73$
$LK,"ICLea",A="FL:::/Compiler/BackLib.HC.Z,661",BI=74$
$LK,"CmpBuf",A="FL:::/Compiler/CMain.HC.Z,157",BI=75$
$LK,"CMP_TEMPLATES_DONT_PUSH_POP",A="FL:::/Compiler/Templates.HC.Z,385"$
$LK,"ICAddEct",A="FL:::/Compiler/BackA.HC.Z,1",BI=76$
$LK,"ICToF64",A="FL:::/Compiler/BackB.HC.Z,283",BI=77$
$LK,"PrsBinFile",A="FL:::/Compiler/Asm.HC.Z,888",BI=78$
$LK,"HashTableSize2",A="FL:::/Compiler/CHash.HC.Z,72",BI=79$
$LK,"HashEntrySize2",A="FL:::/Compiler/CHash.HC.Z,33",BI=80$
$LK,"Ui",A="FL:::/Compiler/UAsm.HC.Z,245",BI=81$
$LK,"ICSlashOp",A="FL:::/Compiler/BackLib.HC.Z,282",BI=82$
$LK,"OptBrZero",A="FL:::/Compiler/OptLib.HC.Z,230",BI=83$
$LK,"Un",A="FL:::/Compiler/UAsm.HC.Z,668",BI=84$
$LK,"PrsSizeOf",A="FL:::/Compiler/PrsExp.HC.Z,303",BI=85$
$LK,"ICToI64",A="FL:::/Compiler/BackB.HC.Z,277",BI=86$
$LK,"ICMod",A="FL:::/Compiler/BackA.HC.Z,425",BI=87$
$LK,"OptSetNOP1",A="FL:::/Compiler/OptLib.HC.Z,17",BI=88$
$LK,"OptPass789A",A="FL:::/Compiler/OptPass789A.HC.Z,1",BI=89$
$LK,"OptSetNOP2",A="FL:::/Compiler/OptLib.HC.Z,25",BI=90$
$LK,"FBO1_F64",A="FL:::/Compiler/OptLib.HC.Z,94"$
$LK,"ICXorEqu",A="FL:::/Compiler/BackC.HC.Z,581",BI=91$
$LK,"ICToUpper",A="FL:::/Compiler/BackB.HC.Z,266",BI=92$
$LK,"AsmLexExpression",A="FL:::/Compiler/AsmLib.HC.Z,127",BI=93$
$LK,"ICMov",A="FL:::/Compiler/BackLib.HC.Z,445",BI=94$
$LK,"ICNot",A="FL:::/Compiler/BackB.HC.Z,10",BI=95$
$LK,"ICMul",A="FL:::/Compiler/BackA.HC.Z,224",BI=96$
$LK,"ICRex",A="FL:::/Compiler/BackLib.HC.Z,22",BI=97$
$LK,"ICPop",A="FL:::/Compiler/BackLib.HC.Z,363",BI=98$
$LK,"SLASH_OP_FADD",A="FL:::/Compiler/BackLib.HC.Z,271"$
$LK,"MODR_RIP_REL",A="FL:::/Compiler/BackLib.HC.Z,133"$
$LK,"LexStmt2Bin",A="FL:::/Compiler/CMain.HC.Z,1",BI=99$
$LK,"ICSub",A="FL:::/Compiler/BackA.HC.Z,166",BI=100$
$LK,"COCFloatConstFind",A="FL:::/Compiler/PrsLib.HC.Z,164",BI=101$
$LK,"ICPut",A="FL:::/Compiler/CExcept.HC.Z,184",BI=102$
$LK,"PrsArrayDims",A="FL:::/Compiler/PrsVar.HC.Z,247",BI=103$
$LK,"ICSqr",A="FL:::/Compiler/BackC.HC.Z,456",BI=104$
$LK,"FBO1_NOT_CONST",A="FL:::/Compiler/OptLib.HC.Z,92"$
$LK,"CMP_TEMPLATES_DONT_POP",A="FL:::/Compiler/Templates.HC.Z,173"$
$LK,"PrsClass",A="FL:::/Compiler/PrsStmt.HC.Z,1",BI=105$
$LK,"SLASH_OP_MOV_IMM",A="FL:::/Compiler/BackLib.HC.Z,268"$
$LK,"MemberMetaData",A="FL:::/Compiler/LexLib.HC.Z,45",BI=106$
$LK,"ICSwitch",A="FL:::/Compiler/BackC.HC.Z,602",BI=107$
$LK,"OptBrNotZero",A="FL:::/Compiler/OptLib.HC.Z,357",BI=108$
$LK,"LexPutToken",A="FL:::/Compiler/CExcept.HC.Z,1",BI=109$
$LK,"SLASH_OP_FDIV",A="FL:::/Compiler/BackLib.HC.Z,275"$
$LK,"AsmHashLoad",A="FL:::/Compiler/AsmInit.HC.Z,50",BI=110$
$LK,"UAsmHashLoad",A="FL:::/Compiler/UAsm.HC.Z,195",BI=111$
$LK,"UnusedExternWarning",A="FL:::/Compiler/CExcept.HC.Z,104",BI=112$
$LK,"SLASH_OP_FILD",A="FL:::/Compiler/BackLib.HC.Z,280"$
$LK,"ICXorXor",A="FL:::/Compiler/BackB.HC.Z,75",BI=113$
$LK,"PrsTryBlk",A="FL:::/Compiler/PrsStmt.HC.Z,842",BI=114$
$LK,"CInit",A="FL:::/Compiler/CMain.HC.Z,691",BI=115$
$LK,"MemberMetaFind",A="FL:::/Compiler/LexLib.HC.Z,56",BI=116$
$LK,"ExePrint2",A="FL:::/Compiler/CMain.HC.Z,648",BI=117$
$LK,"FBO1_INT",A="FL:::/Compiler/OptLib.HC.Z,93"$
$LK,"PE_DO_UNARY_OP",A="FL:::/Compiler/PrsExp.HC.Z,8"$
$LK,"PrsVarInit",A="FL:::/Compiler/PrsVar.HC.Z,1",BI=118$
$LK,"ICOrEqu",A="FL:::/Compiler/BackC.HC.Z,560",BI=119$
$LK,"ICModr1",A="FL:::/Compiler/BackLib.HC.Z,136",BI=120$
$LK,"ICModr2",A="FL:::/Compiler/BackLib.HC.Z,214",BI=121$
$LK,"SLASH_OP_FMUL",A="FL:::/Compiler/BackLib.HC.Z,274"$
$LK,"ICPreIncDec",A="FL:::/Compiler/BackB.HC.Z,304",BI=122$
$LK,"PrsUnaryTerm",A="FL:::/Compiler/PrsExp.HC.Z,593",BI=123$
$LK,"MemberLstDel",A="FL:::/Compiler/LexLib.HC.Z,183",BI=124$
$LK,"SLASH_OP_FSUB",A="FL:::/Compiler/BackLib.HC.Z,272"$
$LK,"ICAndAnd",A="FL:::/Compiler/BackB.HC.Z,30",BI=125$
$LK,"InstEntriesCompare",A="FL:::/Compiler/UAsm.HC.Z,1",BI=126$
$LK,"SLASH_OP_IMUL",A="FL:::/Compiler/BackLib.HC.Z,265"$
$LK,"MemberLstCmp",A="FL:::/Compiler/LexLib.HC.Z,157",BI=127$
$LK,"SLASH_OP_FSTP",A="FL:::/Compiler/BackLib.HC.Z,278"$
$LK,"COCDel",A="FL:::/Compiler/PrsLib.HC.Z,186",BI=128$
$LK,"PE_UNARY_TERM1",A="FL:::/Compiler/PrsExp.HC.Z,1"$
$LK,"ICFAdd",A="FL:::/Compiler/BackFB.HC.Z,515",BI=129$
$LK,"PE_UNARY_TERM2",A="FL:::/Compiler/PrsExp.HC.Z,2"$
$LK,"CmdLinePmt",A="FL:::/Compiler/CMisc.HC.Z,127",BI=130$
$LK,"AsmMakeArgMask",A="FL:::/Compiler/Asm.HC.Z,177",BI=131$
$LK,"COCHeaderPut",A="FL:::/Compiler/PrsLib.HC.Z,229",BI=132$
$LK,"PrsGlblInit",A="FL:::/Compiler/PrsVar.HC.Z,206",BI=133$
$LK,"ICAndEqu",A="FL:::/Compiler/BackC.HC.Z,539",BI=134$
$LK,"LexD2I32",A="FL:::/Compiler/CMisc.HC.Z,91",BI=135$
$LK,"MemberLstNew",A="FL:::/Compiler/LexLib.HC.Z,150",BI=136$
$LK,"LexD3I32",A="FL:::/Compiler/CMisc.HC.Z,107",BI=137$
$LK,"OptClassFwd",A="FL:::/Compiler/OptLib.HC.Z,9",BI=138$
$LK,"ICFCmp",A="FL:::/Compiler/BackFA.HC.Z,519",BI=139$
$LK,"PrsSwitch",A="FL:::/Compiler/PrsStmt.HC.Z,578",BI=140$
$LK,"ICFDiv",A="FL:::/Compiler/BackFB.HC.Z,504",BI=141$
$LK,"AOTStoreCodeU8At",A="FL:::/Compiler/AsmLib.HC.Z,106",BI=142$
$LK,"PE_PUSH_LOWER",A="FL:::/Compiler/PrsExp.HC.Z,11"$
$LK,"OptPass6Lag",A="FL:::/Compiler/OptPass6.HC.Z,28",BI=143$
$LK,"OptLag1",A="FL:::/Compiler/OptLib.HC.Z,51",BI=144$
$LK,"OptLag2",A="FL:::/Compiler/OptLib.HC.Z,62",BI=145$
$LK,"StreamPrint",A="FL:::/Compiler/CMisc.HC.Z,68",BI=146$
$LK,"_LAST_FUN",A="FL:::/Compiler/CMisc.HC.Z,12"$
$LK,"ICFCvt",A="FL:::/Compiler/BackFA.HC.Z,123",BI=147$
$LK,"StreamDir",A="FL:::/Compiler/CMisc.HC.Z,82",BI=148$
$LK,"PrsOffsetOf",A="FL:::/Compiler/PrsExp.HC.Z,353",BI=149$
$LK,"GetOption",A="FL:::/Compiler/CMisc.HC.Z,6",BI=150$
$LK,"PrsDoWhile",A="FL:::/Compiler/PrsStmt.HC.Z,506",BI=151$
$LK,"ICShift",A="FL:::/Compiler/BackA.HC.Z,573",BI=152$
$LK,"ICFMod",A="FL:::/Compiler/BackFA.HC.Z,242",BI=153$
$LK,"COCPop",A="FL:::/Compiler/PrsLib.HC.Z,121",BI=154$
$LK,"PrsExpression2",A="FL:::/Compiler/PrsExp.HC.Z,65",BI=155$
$LK,"SLASH_OP_PUSH",A="FL:::/Compiler/BackLib.HC.Z,269"$
$LK,"PE_DEREFERENCE",A="FL:::/Compiler/PrsExp.HC.Z,5"$
$LK,"LexPopRestore",A="FL:::/Compiler/LexLib.HC.Z,23",BI=156$
$LK,"ICUnaries",A="FL:::/Compiler/BackB.HC.Z,1",BI=157$
$LK,"ICFMul",A="FL:::/Compiler/BackFB.HC.Z,488",BI=158$
$LK,"ICShiftEqu",A="FL:::/Compiler/BackA.HC.Z,603",BI=159$
$LK,"LexExpression2Bin",A="FL:::/Compiler/PrsExp.HC.Z,1117",BI=160$
$LK,"ICFPow",A="FL:::/Compiler/BackFA.HC.Z,266",BI=161$
$LK,"MapFileWrite",A="FL:::/Compiler/CHash.HC.Z,90",BI=162$
$LK,"ICFSub",A="FL:::/Compiler/BackFB.HC.Z,551",BI=163$
$LK,"ICFModEqu",A="FL:::/Compiler/BackFA.HC.Z,549",BI=164$
$LK,"CmpF1PushPop",A="FL:::/Compiler/OptLib.HC.Z,535",BI=165$
$LK,"OptFree",A="FL:::/Compiler/OptLib.HC.Z,33",BI=166$
$LK,"CMP_TEMPLATES_DONT_PUSH2",A="FL:::/Compiler/Templates.HC.Z,447"$
$LK,"CInternalType",A="FL:::/Compiler/CInit.HC.Z,3"$
$LK,"LexDollar",A="FL:::/Compiler/Lex.HC.Z,93",BI=167$
$LK,"AsmUnresolvedAdd",A="FL:::/Compiler/AsmResolve.HC.Z,189",BI=168$
$LK,"AOTStoreCodeU8",A="FL:::/Compiler/AsmLib.HC.Z,1",BI=169$
$LK,"ICBitOps",A="FL:::/Compiler/BackB.HC.Z,202",BI=170$
$LK,"lex_zeros",A="FL:::/Compiler/Lex.HC.Z,91"$
$LK,"ClassMemberLstDel",A="FL:::/Compiler/LexLib.HC.Z,209",BI=171$
$LK,"CSwitchCase",A="FL:::/Compiler/PrsStmt.HC.Z,571"$
$LK,"AsmResolve",A="FL:::/Compiler/AsmResolve.HC.Z,1",BI=172$
$LK,"PrsAsmInst",A="FL:::/Compiler/Asm.HC.Z,395",BI=173$
$LK,"COCCompile",A="FL:::/Compiler/PrsLib.HC.Z,249",BI=174$
$LK,"RunFile2",A="FL:::/Compiler/CMain.HC.Z,667",BI=175$
$LK,"Cmp",A="FL:::/Compiler/CMain.HC.Z,419",BI=176$
$LK,"PrsPush2",A="FL:::/Compiler/PrsLib.HC.Z,11",BI=177$
$LK,"ICArgPut",A="FL:::/Compiler/CExcept.HC.Z,141",BI=178$
$LK,"UndefinedExtern",A="FL:::/Compiler/CExcept.HC.Z,98",BI=179$
$LK,"CN_RES",A="FL:::/Compiler/BackFA.HC.Z,4"$
$LK,"OptIC4",A="FL:::/Compiler/OptPass4.HC.Z,1",BI=180$
$LK,"OptIC6",A="FL:::/Compiler/OptPass6.HC.Z,1",BI=181$
$LK,"ICCmpAndBranch",A="FL:::/Compiler/BackB.HC.Z,468",BI=182$
$LK,"ICDivEqu",A="FL:::/Compiler/BackA.HC.Z,372",BI=183$
$LK,"PrsWhile",A="FL:::/Compiler/PrsStmt.HC.Z,486",BI=184$
$LK,"ICFCmpAndBranch",A="FL:::/Compiler/BackFB.HC.Z,226",BI=185$
$LK,"Lex",A="FL:::/Compiler/Lex.HC.Z,441",BI=186$
$LK,"ICTestAndBranch",A="FL:::/Compiler/BackB.HC.Z,640",BI=187$
$LK,"uasm",A="FL:::/Compiler/Compiler.PRJ.Z,21"$
$LK,"MODR_INDIRECT_REG",A="FL:::/Compiler/BackLib.HC.Z,127"$
$LK,"PE_MAYBE_MODIFIERS",A="FL:::/Compiler/PrsExp.HC.Z,3"$
$LK,"PE_UNARY_MODIFIERS",A="FL:::/Compiler/PrsExp.HC.Z,4"$
$LK,"AOTLocalsResolve",A="FL:::/Compiler/AsmResolve.HC.Z,43",BI=188$
$LK,"PE_DO_BINARY_OP",A="FL:::/Compiler/PrsExp.HC.Z,9"$
$LK,"CmpFixUpAOTAsm",A="FL:::/Compiler/CMain.HC.Z,302",BI=189$
$LK,"OptLabelFwd",A="FL:::/Compiler/OptLib.HC.Z,1",BI=190$
$LK,"ICOrOr",A="FL:::/Compiler/BackB.HC.Z,51",BI=191$
$LK,"LexExcept",A="FL:::/Compiler/CExcept.HC.Z,81",BI=192$
$LK,"cmp_templates",A="FL:::/Compiler/CExts.HC.Z,42"$
$LK,"CmpF2PushPop",A="FL:::/Compiler/OptLib.HC.Z,542",BI=193$
$LK,"INTERNAL_TYPES_NUM",A="FL:::/Compiler/CInit.HC.Z,1"$
$LK,"CmpJoin",A="FL:::/Compiler/CMain.HC.Z,35",BI=194$
$LK,"PrsPop2",A="FL:::/Compiler/PrsLib.HC.Z,16",BI=195$
$LK,"CMP_TEMPLATES",A="FL:::/Compiler/Templates.HC.Z,4"$
$LK,"MODR_D8_INDIRECT_REG",A="FL:::/Compiler/BackLib.HC.Z,128"$
$LK,"PrsAsmBlk",A="FL:::/Compiler/Asm.HC.Z,904",BI=196$
$LK,"PrsAsmArg",A="FL:::/Compiler/Asm.HC.Z,35",BI=197$
$LK,"LexFirstRem",A="FL:::/Compiler/Lex.HC.Z,271",BI=198$
$LK,"MemberClassBaseFind",A="FL:::/Compiler/LexLib.HC.Z,87",BI=199$
$LK,"MemberFind",A="FL:::/Compiler/LexLib.HC.Z,67",BI=200$
$LK,"cmp",A="FL:::/Compiler/Compiler.PRJ.Z,16"$
$LK,"OptLag",A="FL:::/Compiler/OptLib.HC.Z,40",BI=201$
$LK,"ICPostIncDec",A="FL:::/Compiler/BackB.HC.Z,345",BI=202$
$LK,"ICFPostIncDec",A="FL:::/Compiler/BackFB.HC.Z,593",BI=203$
$LK,"ICTest",A="FL:::/Compiler/BackLib.HC.Z,413",BI=204$
$LK,"ICModU64",A="FL:::/Compiler/BackC.HC.Z,463",BI=205$
$LK,"PrsAsmImm",A="FL:::/Compiler/Asm.HC.Z,1",BI=206$
$LK,"LexExtStr",A="FL:::/Compiler/LexLib.HC.Z,248",BI=207$
$LK,"ICAddSubEctEqu",A="FL:::/Compiler/BackA.HC.Z,442",BI=208$
$LK,"ICAddSubEctImm",A="FL:::/Compiler/BackA.HC.Z,56",BI=209$
$LK,"ICPush",A="FL:::/Compiler/BackLib.HC.Z,312",BI=210$
$LK,"ICSwap",A="FL:::/Compiler/BackC.HC.Z,490",BI=211$
$LK,"CMP_TEMPLATES_DONT_PUSH",A="FL:::/Compiler/Templates.HC.Z,260"$
$LK,"intermediate_code_table",A="FL:::/Compiler/CInit.HC.Z,16"$
$LK,"ICZero",A="FL:::/Compiler/BackLib.HC.Z,404",BI=212$
$LK,"CmpCtrlDel",A="FL:::/Compiler/Lex.HC.Z,58",BI=213$
$LK,"ICClassPut",A="FL:::/Compiler/CExcept.HC.Z,117",BI=214$
$LK,"ICAssign",A="FL:::/Compiler/BackC.HC.Z,159",BI=215$
$LK,"ICFTemplateFun",A="FL:::/Compiler/BackFB.HC.Z,617",BI=216$
$LK,"RunFile",A="FL:::/Compiler/CMain.HC.Z,625",BI=217$
$LK,"MemberAdd",A="FL:::/Compiler/LexLib.HC.Z,103",BI=218$
$LK,"PrsPush",A="FL:::/Compiler/PrsLib.HC.Z,1",BI=219$
$LK,"SLASH_OP_FDIVR",A="FL:::/Compiler/BackLib.HC.Z,276"$
$LK,"SLASH_OP_FISTTP",A="FL:::/Compiler/BackLib.HC.Z,279"$
$LK,"CmpCtrlSize",A="FL:::/Compiler/Lex.HC.Z,70",BI=220$
$LK,"ICLocalVarInit",A="FL:::/Compiler/BackC.HC.Z,761",BI=221$
$LK,"PrsFor",A="FL:::/Compiler/PrsStmt.HC.Z,529",BI=222$
$LK,"PassTrace",A="FL:::/Compiler/CMisc.HC.Z,50",BI=223$
$LK,"PrsPopDeref",A="FL:::/Compiler/PrsLib.HC.Z,21",BI=224$
$LK,"ICCopyTemplate",A="FL:::/Compiler/BackFA.HC.Z,77",BI=225$
$LK,"PrsStmt",A="FL:::/Compiler/PrsStmt.HC.Z,904",BI=226$
$LK,"PrsFun",A="FL:::/Compiler/PrsStmt.HC.Z,140",BI=227$
$LK,"LexIncludeStr",A="FL:::/Compiler/Lex.HC.Z,293",BI=228$
$LK,"PrsType",A="FL:::/Compiler/PrsVar.HC.Z,287",BI=229$
$LK,"CmpCtrlNew",A="FL:::/Compiler/Lex.HC.Z,28",BI=230$
$LK,"MODR_SIB_D8_INDIRECT_REG",A="FL:::/Compiler/BackLib.HC.Z,131"$
$LK,"cmp_type_flags_src_code",A="FL:::/Compiler/Lex.HC.Z,322"$
$LK,"PrsVarInit2",A="FL:::/Compiler/PrsVar.HC.Z,123",BI=231$
$LK,"PrsPop",A="FL:::/Compiler/PrsLib.HC.Z,6",BI=232$
$LK,"asm_seg_prefixes",A="FL:::/Compiler/Asm.HC.Z,393"$
$LK,"ICMinMax",A="FL:::/Compiler/BackC.HC.Z,418",BI=233$
$LK,"CmpLoadDefines",A="FL:::/Compiler/CInit.HC.Z,204",BI=234$
$LK,"PrsIf",A="FL:::/Compiler/PrsStmt.HC.Z,459",BI=235$
$LK,"ICBuiltInFloatConst",A="FL:::/Compiler/BackLib.HC.Z,423",BI=236$
$LK,"ICFUnaryMinus",A="FL:::/Compiler/BackFA.HC.Z,194",BI=237$
$LK,"LexDocRead",A="FL:::/Compiler/Lex.HC.Z,305",BI=238$
$LK,"CmpFixUpJITAsm",A="FL:::/Compiler/CMain.HC.Z,174",BI=239$
$LK,"COCPopNoFree",A="FL:::/Compiler/PrsLib.HC.Z,114",BI=240$
$LK,"ParenWarning",A="FL:::/Compiler/CExcept.HC.Z,110",BI=241$
$LK,"PrsFunCall",A="FL:::/Compiler/PrsExp.HC.Z,383",BI=242$
$LK,"SLASH_OP_IMM_U32",A="FL:::/Compiler/BackLib.HC.Z,263"$
$LK,"ICDerefPostIncDec",A="FL:::/Compiler/BackB.HC.Z,384",BI=243$
$LK,"Option",A="FL:::/Compiler/CMisc.HC.Z,1",BI=244$
$LK,"ExeFile2",A="FL:::/Compiler/CMain.HC.Z,657",BI=245$
$LK,"COptMemberVar",A="FL:::/Compiler/OptLib.HC.Z,556"$
$LK,"PE_CHECK_BINARY_OPS1",A="FL:::/Compiler/PrsExp.HC.Z,6"$
$LK,"PE_CHECK_BINARY_OPS2",A="FL:::/Compiler/PrsExp.HC.Z,7"$
$LK,"LexBackupLastChar",A="FL:::/Compiler/LexLib.HC.Z,1",BI=246$
$LK,"Trace",A="FL:::/Compiler/CMisc.HC.Z,58",BI=247$
$LK,"ICBrBitOps",A="FL:::/Compiler/BackC.HC.Z,208",BI=248$
$LK,"MODR_D32_INDIRECT_REG",A="FL:::/Compiler/BackLib.HC.Z,129"$
$LK,"LexGetChar",A="FL:::/Compiler/Lex.HC.Z,107",BI=249$
$LK,"LexSkipEol",A="FL:::/Compiler/Lex.HC.Z,264",BI=250$
$LK,"ICFlagBranch",A="FL:::/Compiler/BackB.HC.Z,688",BI=251$
$LK,"SLASH_OP_FSUBR",A="FL:::/Compiler/BackLib.HC.Z,273"$
$LK,"ICFPreIncDec",A="FL:::/Compiler/BackFB.HC.Z,573",BI=252$
$LK,"MODR_SIB_INDIRECT_REG",A="FL:::/Compiler/BackLib.HC.Z,130"$
$LK,"SLASH_OP_IMM_U8",A="FL:::/Compiler/BackLib.HC.Z,262"$
$LK,"ExeFile",A="FL:::/Compiler/CMain.HC.Z,614",BI=253$
$LK,"COCMiscNew",A="FL:::/Compiler/PrsLib.HC.Z,143",BI=254$
$LK,"cmp_templates_dont_pop",A="FL:::/Compiler/CExts.HC.Z,43"$
$LK,"CmpOffset2Reg",A="FL:::/Compiler/OptLib.HC.Z,83",BI=255$
$LK,"PrsFunNew",A="FL:::/Compiler/PrsLib.HC.Z,62",BI=256$
$LK,"StreamExePrint",A="FL:::/Compiler/CMain.HC.Z,673",BI=257$
$LK,"COCGoToLabelFind",A="FL:::/Compiler/PrsLib.HC.Z,152",BI=258$
$LK,"OptMVCompare",A="FL:::/Compiler/OptLib.HC.Z,562",BI=259$
$LK,"ICToBool",A="FL:::/Compiler/BackB.HC.Z,289",BI=260$
$LK,"PrsFunJoin",A="FL:::/Compiler/PrsStmt.HC.Z,62",BI=261$
$LK,"OptFixSizeOf",A="FL:::/Compiler/OptLib.HC.Z,484",BI=262$
$LK,"cmp_templates_dont_push",A="FL:::/Compiler/CExts.HC.Z,45"$
$LK,"cmp_templates_dont_push_pop",A="FL:::/Compiler/CExts.HC.Z,46"$
$LK,"LexAttachDoc",A="FL:::/Compiler/Lex.HC.Z,325",BI=263$
$LK,"PrsStreamBlk",A="FL:::/Compiler/PrsStmt.HC.Z,805",BI=264$
$LK,"MODR_RIP_REL_IMM_U32",A="FL:::/Compiler/BackLib.HC.Z,134"$
$LK,"cmp_templates_dont_push2",A="FL:::/Compiler/CExts.HC.Z,44"$
$LK,"InstEntryFind",A="FL:::/Compiler/UAsm.HC.Z,66",BI=265$
$LK,"PrsDotDotDot",A="FL:::/Compiler/PrsVar.HC.Z,381",BI=266$
$LK,"ICMulEqu",A="FL:::/Compiler/BackA.HC.Z,285",BI=267$
$LK,"AsmPrsInsFlags",A="FL:::/Compiler/AsmInit.HC.Z,1",BI=268$
$LK,"PrsNoWarn",A="FL:::/Compiler/PrsStmt.HC.Z,791",BI=269$
H2@2#2#;#A#\#a#Œ#�#Ã#­#Ó#Ú#ë#ş#¨­Óç`ç`ı`aaa<aaKaQaQa{a‚a­a»a»aèa
b"bb1b]bJbtb{b¦b¦b­bÑbçbçbçbñbH>L×ı×ıñıûıÿışş
ş"ş:ş:şDşp©Áçç &(.4J]lqsx‚—­Àå÷(åå2åSåWåWå_å8îäîä÷äüäåååååd`µÖØÖØôØøØÙÙÙÙ"Ù"Ù/Ù1Ù>Ù@ÙLÙLÙgÙuÙuـهٖ١٧٬ٮٺÙÁÙĞÙÛÙáÙæÙèÙôÙ$ÚJÚZÚjÚzÚ|ڌڜڬڬڱÚÄÚËÚÒÚÒÚÒÚÒÚÙÚïÚûÚÛÛ␍ÛÛÛÛ>ÛEÛ[ÛgÛmÛsÛyÛ{Û{Û‰ÛDÃ�Û�Û¤Û§ÛªÛ·Û½ÛÊÛÍÛĞÛÖÛØÛâÛ ,cjàŠàŠîŠøŠ‹‹‹‹
os��¬ÁÇ P ‚7‚7�7Ÿ7»7Á7Ó7Ó7Ş7ç7í7ô7ú7 ”;\?L?LGLKLdL~L›L¼LÅLÖLúLMM0M?MHMUM\M�MŸM£M«M«M¾MÎMÒMÖM␍Œ×ö6>BPV\\ˆ�²À×İéîü ! 1 3 : : @ @ P |1’"’"¨"±"¼"Ö"Ö"Ù"è"î"÷"ù"ÿ"#
###!#$#$#.#0 '(‰(‰6‰V‰\‰b‰b‰h‰„“°È¡È¡Ü¡ã¡ê¡î¡¢%¢,¢=¢b¢m¢x¢z¢…¢ª¢µ¢À¢Â¢É¢Ò¢Ô¢ß¢æ¢£("ÿàÿàá%á@á@áFá ŸàŸà®àÄàÊà ˆP´P´u´|´“´Ÿ´ª´¼´Í´¾´¼´í´µµµ!µ-µ7µ>µEµIµKµQµ]µgµnµuµyµyµƒµˆµ“µ¥µ¶µ§µ¥µÖµ÷µ
&¶-¶4¶8¶:¶@¶L¶V¶]¶d¶h¶h¶u¶ƒ¶“¶¥¶¶¶§¶¥¶Ö¶÷¶·
···&·-·4·8·:·@·L·V·]·d·h·h·r·‚·”·¥·–·”·Å·Ì·Ò·Ş·è·ï·ö·ú·ü·¸¸¸ ¸&¸*¸*¸4¸B¸K¸d¸p¸t¸t¸w¸€¸ö¸Ô·ƒ·ƒÔƒ¢©܃냄„+„2„C„K„O„R„`„d„�„�„¥„§„§„³„»„¿„̄̄؄à„ä„ñ„ñ„ñ„␍……)…)….…F…U…Z…`…k…p…p…u…�…œ…¡…§…²…·…·…Å…Î…Ú…â…ê…ò…õ…û…† ††$†5†E†E†J†R†Z†]†c†c†h†h†h†n†q†x†ƒ†˜†½†Ô†á†é†ñ†ı† ‡‡‡ ‡#‡&‡2‡8‡?‡D‡D‡R‡b‡b‡o‡o‡w‡‡ˆ‡—‡œ‡œ‡£‡®‡´‡¼‡‡͇Ò‡Ò‡á‡ì‡ş‡ˆ ˆˆˆ"ˆ4ˆ:ˆBˆHˆMˆMˆaˆgˆrˆxˆzˆŠˆ�ˆ�ˆµˆ܈áˆáˆõˆûˆ‰"‰(‰-‰F‰L‰\‰d‰l‰r‰w‰w‰‹‰‘‰§‰¸‰¾‰É܉â‰ò‰ú‰ŠŠ␍Š␍Š#Š)Š?ŠPŠVŠ[ŠjŠpŠ�ЉБЗŠ�Š£Š£Š¹Š¿ŠÕŠæŠìŠîŠıŠ‹␍‹‹‹#‹*‹*‹*‹<‹E‹V‹f‹f‹k‹k‹y‹�‹’‹¥‹¬‹²‹º‹À‹Ğ‹Ö‹Ş‹ä‹ä‹ä‹é‹é‹é‹é‹é‹ŒŒŒŒ(Œ1Œ<ŒEŒPŒ[Œ`Œ`ŒvŒ|Œ’Œ£Œ©Œ®ŒÀŒÆŒËŒäŒ�������$�*�/�/�S�[�c�s�y�����®�®�³�³�¿�Ç�Ê�Ñ�×�Ü�Ü�ü����!�?�N�V�n�v�y�€�†���¦�¾�Æ�É�Ğ�Ö�Ö�Ö�õ�����#�)�9�H�T�o�w�z���‡�Ÿ�«�Æ�Î�Ñ�Ø�Ş�Ş�Ş�Ş�ã�ã�ì�ü���0�C�I�N�`�f�k�‡���™�¡�¤�«�±�Ú�â�ò�ø�ÿ�ÿ�ÿ�‘‘␍‘%‘;‘A‘Y‘l‘r‘w‘¢‘¨‘»‘ò‘’!’)’/’4’4’N’Z’f’q’q’v’v’�’œ’¨’³’³’¸’¸’Ò’Ş’ê’õ’õ’ú’ú’““"“(“-“?“E“J“Y“e“q“w“}“„“—“¢“«“·“¿““È“ΓÓ“ç“ö“ş“””!”'”-”E”M”m”‡”�”’”˜”�”�”¯”¸”Ĕ̔ϔ֔ܔá”ó”•
•"•*•-•4•:•R•Z•y•“•›•�•¥•«•«•»•ĕЕؕەá•ç•ì•–––1–9–<–B–H–`–h–Š–¦–®–±–·–½–½–Ζ×–ã–ë–î–õ–û–——!—)—D—L—O—V—\—t—|—�—»—ׯ—͗ӗӗӗӗӗؗؗî—ô—˜˜ ˜˜#˜(˜6˜B˜K˜W˜_˜b˜i˜o˜t˜†˜•˜�˜µ˜½˜À˜ǘ͘å˜í˜ ™&™.™1™8™>™>™>™O™X™d™l™o™v™|™“™¢™®™É™Ñ™Ô™Û™á™ù™š'šDšLšOšVš\š\š\š\š\šašaštš�š•š š¥š¥š¸šΚÔšßšášášôš››(›(›:›C›T›Y›k›{›{›€›€›“›©›¯›½›Ì›Ñ›Ñ›ä›ú›œœœ"œ"œ8œ>œ[œsœsœ�œ£œ¨œ´œ½œÌœÌœÑœÑœçœíœ
�"�"�L�R�W�c�l�{�{�€�€�–�œ�¹�Ñ�Ñ�û�����*�*�/�/�E�K�h�€�€�ª�°�²�¾�Ç�Ò�Ò�Ò�Ò�×�å�î�ÿ�ŸŸ Ÿ Ÿ Ÿ0Ÿ@ŸEŸiŸuŸvŸ{Ÿ�Ÿ­Ÿ½ŸáŸñŸ÷Ÿ÷Ÿ÷ŸüŸ  ) g w }  „ • ¤ Ö Ş ä æ ë ò ò û ␍¡ ¡)¡8¡8¡=¡B¡Q¡Z¡e¡g¡p¡{¡{¡œ¡£¡©¡±¡¼¡¡Ò¡Ø¡à¡ë¡ñ¡ñ¡ö¡û¡¢ ¢¢¢ ¢/¢/¢/¢4¢4¢4¢F¢K¢K¢]¢h¢p¢x¢~¢~¢~¢ƒ¢ƒ¢�¢Ÿ¢¢¢®¢·¢âʢТբբà¢ñ¢ô¢£ £££"£'£'£'£'£,£1£1£<£@£@£L£U£X£X£c£e£{£‚£ˆ£—£¢£­£³£¿£ããϣأۣۣæ£è£ş£¤ ¤¤¤)¤/¤9¤<¤@¤@¤H¤O¤R¤T¤_¤c¤l¤o¤o¤z¤|¤š¤¡¤¬¤·¤º¤À¤ŤŤФÔ¤Ô¤à¤é¤ì¤ì¤÷¤ù¤¥¥¥+¥6¥A¥G¥S¥W¥W¥c¥l¥o¥o¥z¥|¥’¥™¥Ÿ¥§¥²¥½¥Ã¥Í¥Ğ¥Ô¥Ô¥Ü¥ã¥æ¥è¥ó¥÷¥¦¦¦¦¦.¦5¦@¦K¦N¦T¦Y¦Y¦k¦o¦o¦{¦„¦‡¦‡¦’¦”¦ª¦±¦·¦ɦÔ¦ߦå¦ê¦ê¦õ¦ú¦ú¦§
§
§§§§#§(§-§2§2§F§K§K§X§\§m§u§y§�§”§˜§˜§¥§±§¹§¿§ϧÓ§ä§ö§¨¨¨¨¨"¨(¨(¨(¨(¨(¨*¨*¨8¨?¨L¨X¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨f¨h¨h¨¨‡¨“¨“¨´¨èÛ¨ݨé¨ö¨ö¨©&©1©:©C©N©U©U©_©_©b©t©’©�©�©É«xİ÷Z5Z5l5n5r5{5‡5“5¨5¨5×5Û5à5ì5ÿ5 6 666"6,6lby¯|¯|Å|Ô|Ù|î|Û|ı|}}␍}"}}1}7}P}i}‚}›}´}¾}„�ïlïl␍mmm"m)m+m.m5m<m<mMmQmWmWmlmvmvm~m—mºmÛmàmnnnn"n2n5nInOnTnZn\nbnenknpnsn{n„n”n·nÅnİnânæn oo#o1oIoNoRowo‡oªo½oÂoÈoÍoĞoÒoØoŞoäoéoïo÷o÷op
pp0p5p9p^pnp‘p¤p©p¹pÜpêpqq q0qCqCq^q^q^qlq„q†q†q†q”q¬q®q®q¼qÔqÔqåqåqîqûqr1rKrSr^rqrururur|r‚rœr¤r¯rÊrÌrÒrìrôrÿr␍sss2sH�›x†x†�†¥†µ†¼†Ó†î†‡‡G‡L’¡Ï~Ï~ã~ğ~ò~0IT_g4IR^Ø^ØgØgØjØx؆؉Ø�Øì=·û·ûßûâûüü(ü(üCüIüNüNüiüoütütü}ü‹ü¨üÀüÅüÌüÒüÔüñüıı␍ıııı(ı.ı.ı.ı>ı3ıOı_ıqıvıvıvı}ı„ı‹ı ı§ıÃıÃıÕıÌM¼ˆ¦ˆ¦¢¦­¦¸¦Á¦É¦Ì¦Ó¦×¦à¦ó¦÷¦ı¦ §(§5§D§I§U§Z§a§m§r§u§§w§�§˜§©§§§Ÿ§·§À§Æ§Æ§Ô§×§ë§ô§ı§¨¨␍¨$¨<¨E¨S¨o¨{¨{¨“¨¤¨¤¨«¨Ä¨Ğ¨Ø¨ë¨ò¨©©©©%©*©1©N©{©‚©†©ˆ©“©Ÿ©£©¸©º©Ë©Õ©à©ê©ù©ª!ª!ª$ª,ª1ª³ªPw‡×N×NóNOO.OKOfOlOuOƒO‰OŒO˜OŒ xbxbˆb¬b¬bºbºbºbºbÃbÃbÊbåbúbcc␍c␍cc+c+c9c?c?cWcWc]cƒc (kq ‹ ‹.‹:‹J‹Q‹W‹ @^jëë�ë•ëœë»ëÈëÈëËëÍëÓë!$/4§á§á´áÉáÎáÔá"$).wáwá„á™á�á¤á#$#(GáGáVáláqáwá$€ïK**4DZbl‡Œœ²ºÄßäú   " , 6 @ J T ^ h r | ’ œ ¦ ° º Ä Î Ø â ø  " , 6 @ J T ^ h r | † � š ¤ ® ¸ Â Ì Ö à ê ô ş !!!&!0!:!D!N!\!%¤CÈ�È�Ş�å�ú� �� �&�,�<�G�Q�\�s�v�x�Š��� �ª�´�»�Æ�Û�ã�ã�ù�ù�ù�␍Ÿ&$5:×á×áåáúáÿáâ'¤DiŸŸ&Ÿ-Ÿ4ŸBŸSŸeŸgŸnŸtŸ„Ÿ�Ÿ™Ÿ¤Ÿ»Ÿ¾ŸÀŸÒŸÙŸéŸóŸıŸ  # + + A A A V ((&,ú/ú/000 0%0)0]e×M×MíMNNNN N*ø Úv%v%˜% %¦%³%º%Ö%Ü%Ü%ç%ñ%ñ%ş%&&!&'&1&7&H&H&S&]&]&o&u&…&‹&�&—&—&¸&¾&Ğ&ã&é&ì&ò&ò&ô&ú&''''''"'"'7'A'A'U'^'d'j'€'…'�'£'§'§'¯'µ'»'Å'Ì'Ó'Ü'î'î'(((#(5(H(N(R(X(^(d(d(f(j(p(v(|(�(�(�(�(¬(½(½(Ô(á(å(í(ÿ( ) )%)(),)2)2)D)U)j)~)†)—)›)¡)®)°)¼)Ú)à)ë)** *%*+*4*:*L*]*e*i*o*|*~*Š*¨*®*´*º*Ã*É*æ*Ù*+ +++$+)+)+0+:+O+T+T+T+q+s+�+’+¯+µ+½+Á+È+ë+ñ+÷+,,!,',2,7,7,>,B,L,Z,\,d,i,q,|,‚,‘,–,œ,¡,©,®,½,Ô,ä,ñ,ü,--6-6-=-R-W-`-m-r-x-}-}-„-ˆ-’- -¢-ª-®-²-½-Ç-Ç-Ñ-İ-ä-è-ğ-ø-.. .%.1.1.9.9.\.\.j.p.u.y.~.~.~.~.„.†.†.©.¯.µ.¼.Ò.Ô.Ô.Ô.ß.ß.ß.ä.␍0+4.w6Ê6ÊPÊTÊlÊtÊ|Ê†ÊŠÊ‘Ê—Ê«Ê³Ê¸Ê»ÊÆÊÑÊÙÊäÊïÊñÊËËË Ë+Ë-Ë8ËCËEËQËZËZËpË{˓˙ˢ˳˹ËÂËÔËÚËÚËâËæËñËöËÌÌÌ%Ì'Ì+Ì:Ì:Ì:ÌKÌKÌPÌbÌhÌÖÌ,Ô@fæfæ|æƒæ†æªæªæÇæÚæíæççç#ç1çDçWç_ç_çaçaçaçtçvçvçvç}ç�ç£ç£ç£ç¶çÁçÔçêçïçóçúçè"è)è)è,èQè-LAP$$$!$-$H$M$m$o$Š$¥$¥$­$´$Û$.P~�¨‹¨‹¶‹Ã‹Ñ‹ã‹î‹ü‹ ŒŒ)Œ4ŒBŒHŒNŒ/4
"7"707<7M7_7h7v7|70€À\� � À Ç Õ à       D K K Z i … � � � ¥  ¿ İ è ê ␍ ␍␍$␍6␍?␍J␍O␍U␍\␍„␍‰␍—␍ ␍ ␍§␍¶␍Í␍Í␍Ü␍å␍ù␍ %KT[`kw†šŸ§³ÅÅáèğ!!06JO_s…Šš­µÉçş%ASYdp€�–ŸŸ±µÁØô #3CU[[`bbggv|‚‚†ÿ1ŒÄãæÛæÛÜÜÜÜÜ$Ü3Ü>ÜDÜIÜKÜWÜ^ÜfÜlÜrÜvÜv܅܌ܔܚܠܢܢܮÜ28 2/2/@/F/R/]/n/x//…/3@‡“ßìßìíìøìÿìí+í+í.í0í6í4ÜSgg� §®µ»½ÄËÎÎààòı  " * / 5 K [ p u � ¦ ª ª ¯ ¸  Ö Ş ç ï ô û 

2
4
M
e
i
i
}
…
�
–
›
¡
·
Ç
Ü
á
ú
  ) ) ) ; . ] P r } ƒ › ³ ¸ Ã × ß è ğ ò ø 
 / 1 J b f f z ‚ ‹ “ ˜ Ÿ µ Å Ú ß ø ␍␍'␍'␍'␍9␍,␍[␍N␍p␍{␍�␍™␍±␍±␍±␍½␍Ã␍Í␍Ø␍ê␍ú␍(?VVi„„„¥µÃÃÌÖãı %'FUNm}——°5D‚�&&6JSYkkorz6\Ob8Š8ŠXŠgŠpŠyŠ}Š�Š�ВЗЗЍЬдŠÌŠÏŠÛŠ70üÆäÆäÏäÔäİäääæäëä8�á''IPWbxxŠ££®²½êÑÄù!59>Skpx|��­ÁÅÅÊèÛ#
ı2P[au�’¦®·¿ÄËİí6::Ogltx‡z¦º¾ÍÍÍÍàæğ÷
%%AQ__s��¤·¼Ûêã*PAvx¤¤¤¼¯íòı0J7Yp�œ°´¹×Êùì!0NY_s‹�¤¬µ½ÂÉÛë4888Zs‡‹ššš­³½Ä×òòò,,@Ng\z�’±À¹Øèù99@cccƒ9Dt�ÎÎŞòû":lz‘¿}¿}Õ}ä}é}ş}ë}␍~~~~2~ ~A~G~`~y~’~«~Ä~Î~;<�›~~�Ÿ¨®²½<¨.ïïï"ï.ï?ïAïQï\ïnïyï„ï“ï¤ï«ïÄïÈïÙïÙïãïêïıïğ␍ğ(ğ7ğNğNğjğoğ›ğ=d(=h‰h‰t‰ˆ‰‹‰Ÿ‰§‰«‰µ‰¿‰Ç‰Ê‰Ğ‰>4o¸GG.G1G5GBGKGVGfGnGxG G G°GµGµGÅGÊGÊGÚGßGßGïGôGôGH H HHHH.H3H3HCHHHHHXH]H]H]H`HiH‚H�H§HºH¼HÂHÄHÇHØHİHİHãHóHóHşHII3I;IAIAIUIUI^IaI!J?Ä nϫϫì«ô«÷«¬¬(¬1¬L¬e¬w¬‚¬“¬—¬©¬¬¬·¬À¬̬߬­­ë¬ ­7­K­W­e­†­›­¿­Ó­Õ­ö­Ü­®®®®®#®9®@®M®R®a®n®�®�®™®�®Ê®Ê®â®ç®ç®÷®û® ¯¯'¯1¯D¯I¯I¯Y¯]¯n¯x¯‰¯“¯¦¯²¯·¯·¯·¯Ù¯ê¯ï¯ü¯°°° °/°4°:°?°?°D°N°]°b°h°m°m°s°y°~°~°†°™°¥°²°¾°Ͱ×°ݰæ°ı°±"±/±4±L±_±v±ƒ±‹±š±¤±ª±³±¼±¼±Á±Á±Á±Á±Á±ѱѱѱé±ÿ±²"²3²@²B²O²T²T²T²_²m²r²r²y²‡²Œ²¤²°²²βÔ²ܲâ²ë²³³#³)³8³@³H³u³†³“³•³£³£³¨³¨³¯³½³³Õ³á³í³ó³ù³´´´´´´ ´$´$´$´$´$´5´5´5´5´5´5´5´5´5´5´M´c´k´†´—´¤´¦´³´ôÈ´È´È´Ñ´ë´÷´ü´µ*µ*µ/µ/µ/µ/µ/µ/µ/µ/µDµIµIµIµZµaµfµfµqµƒµ›µ°µѵòµıµB¶K¶\¶b¶ƒ¶œ¶¤¶¬¶º¶ä¶í¶ó¶·-·-·-·-·-·O·ˆ·‘·—·�·¢·«·´·¹·¹·¹·¹·È·Ü·ú·
¸¸¸¸(¸<¸b¸u¸{¸{¸€¸€¸�¸£¸Á¸Ѹ׸ܸܸ︹)¹<¹B¹B¹G¹G¹G¹_¹u¹}¹˜¹©¹¶¹¸¹ǹɹɹɹɹɹݹݹݹݹݹݹݹݹݹݹݹݹݹݹݹݹì¹û¹ºººººº'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º'º)º)º@ºHºTºTºXº]ºmº‰º¡º°º¼ºÒºìºïºùº»+»K»k»�»‘»¤»Ò»ª»í»í»ğ»¼¼#¼4¼7¼Q¼_¼k¼ƒ¼ƒ¼®¼±¼À¼Ô¼õ¼ ½%½½A½V½t½©½§½œ½‘½‚½·½·½·½º½¿½½ܽê½¾:¾:¾e¾h¾w¾‹¾¬¾À¾ܾȾø¾ø¾¿K¿I¿>¿3¿$¿Y¿Y¿Y¿\¿a¿a¿h¿x¿™¿¥¿öÂ@Ä…²wÇwÇ�ǑǜǣǮÇÂÇÂÇÍÇŞÇåÇòÇşÇ ÈÈ È È)È.È6ÈFÈTÈcÈnÈ�È�șșȴÈàÈàÈôÈöÈöÈÉÉÉÉÉÉÉ+É+É+É1É9É?ÉDÉDÉJÉRÉVÉ\ÉaÉaÉwɇɑɠɥɭɭɲɲɹÉÏÉßÉéÉñÉ÷ÉÊ ÊÊÊÊÊ%Ê0ÊdÊsÊ}ʅʋʠʦʫʫʫʫʫʫʫʫʫʶÊÄÊÔÊÚÊâÊñÊöÊË ËËËËË!Ë*Ë7Ë?ËKËVˊ˒ˡ˫ËÅËËËĞËĞË×ËêËòËÌÌÌ,Ì.Ì9ÌAÌVÌVÌ^ÌoÌwÌ~̄̊Ì�Ì—ÌœÌÀÌÌÌÔÌéÌõÌúÌÍÍÍÍÍ,ÍIÍNÍVÍgÍoÍw͌͑ͤ͜͹;;ÍâÍîÍöÍ ÎÎÎ(Î3Î8Î8Î8Î8Î8Î8ÎCÎCÎCÎCÎCÎCÎCÎCÎCÎCÎCÎCÎNÎ]Î`ÎnÎ~΄ΌΛΠΨΰβκÎÉÎÏÎ×ÎßÎáÎéÎÏÏÏ Ï&Ï:ÏCÏLÏTÏ^ÏhÏpÏ~σψϚÏÎÏÖÏåÏïÏ ĞĞĞĞĞ Ğ(Ğ+Ğ5ĞCĞUĞWĞiĞ{Ğ{Ğ{Ğ†Ğ‹Ğ¨Ğ­Ğ­Ğ¶Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»Ğ»ĞÆĞÒĞêĞıĞÑÑÑ!Ñ(Ñ5Ñ>ÑGÑOÑVÑ[Ñ[ÑcÑkщёєіѦѰѰѰѲÑÇÑØÑÛÑŞÑæÑëÑëÑôÑùÑÒÒÒ*Ò1ÒBÒNÒkÒ„Ò™Ò®ÒµÒµÒºÒºÒºÒºÒºÒºÒºÒÂÒÍÒÙÒèÒíÒíÒõÒıÒ
ÓÓÓÓÓÓÓ(Ó-Ó-Ó-Ó9Ó@ÓFÓPÓUÓlÓ{ӃӔӜӿÓÅÓÌÓÎÓÔÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓÛÓİÓİÓøÓÔÔÔÔ Ô'ÔCÔPÔPÔPÔTÔ_Ô}Ô‹ÔÖAx[ÖÖ•ÖœÖ£Ö®ÖµÖÆÖĞÖ×ÖáÖôÖüÖüÖ×1×7×@×G×J×U×^×e×h×m×xׂהךװ׷׿×Õ×Ü×Ü×Ü×êרØ"Ø4Ø<Ø<Ø<ØGØQØcØiØØ†Ø�ؕتػػØÂØÂØÂØĞØ÷ØÙ␍ÙÙ'Ù/Ù/Ù/Ù=ÙEÙEÙHÙSÙmÙyÙ¾ÙBx`ºÏÜÏÜçÜ÷ÜşÜİİ#İ&İ.İ5İ8İHİVİaİlİoİzİ�ݛݦݱݼİÃİÖİâİÿİŞŞ0Ş3Ş9Ş>ŞMŞSŞ[ŞjŞpŞxŞxބޒޡީ޸ŞÀŞãŞéŞïŞñŞ÷ŞıŞıŞıŞ"ß'ßDßGßGßNß[ß_ßjß„ß�ß ß³ßÏßäßìßößà)à)à�àC ?C/1/191A1F1DôÑʯZ¯ZĞZÛZìZÛZ[[[$[-[4[8[A[A[I[M[m[{[‡[�[˜[¼[¼[Í[Ø[Ş[å[ê[ê[ı[\\$\/\6\@\M\M\_\d\d\r\w\w\ˆ\ˆ\›\ \±\·\À\Õ\é\é\î\î\ü\]]]␍]]]]&]-]-]<]B]O]V]^]‚]‚]Š]™]¤]«]­]Á]Ğ]Õ]Ú]Ú]Ú]í]ò]^^^&^:^:^?^?^G^]^b^v^}^‚^‚^�^�^¯^¾^Ù^ä^ş^_"_1_P_[_`_o_ƒ_Š_‘_¤_¦_´_Ç_É_×_å_õ_ü_``&`3`3`>`R`_`g`i`}`�`–`§`µ`×`Ş`ê`aaaaa a'a+a3a:aJaUasaxa�aŒa•a�a¢a¢a±a¾aÌa×aâağaöaüab bb b8b8bIbTbVbbb€b†bŒb’b›b¬bÓbÛbåbób ccc-cBcBcOcTcfclclclclcvdEDTa/|/|C|P|f|R|u|w|�|§|¯|FœfɯR¯RÑRÛRSSS6S;S?SGSPS_SfSoStS‰SšS¹SÁSÃSâSêSùST TTT T&T(T9T>TTT@TcTiTiTqTzT‰T¨T¯T±TĞT×T×T×TîT÷TUUU+U UCUHUYU^UtU`UƒU‰U�U˜U�U U±U¶UÌU¸UÛUáUáUéUòUòUüUüUVDVMVYV]VkV�VvV™V™V«VG ;zââ&â/â2âDâZâ\âeâjâ‹â©â¸âÖâêâã ã/ãMã\ãyãŠã¡ã¥ã¥ã©ã®ã³ã½ãÀãÊãÏãèãëãëãëãëãğãöãä ä,ä5äIäQäZävä�ä�ä–äªäªä¹ä¾ä¾äÌäHPcs‡@‡@¨@•@Ê@·@Ù@è@ğ@û@ı@AAA5A;AIPµÅûûû û/û/û6ûcûyûeû–ûˆû®û¶ûJŒ•´‡ù‡ùºùæùæùùùıù ú/ú4ú4ú;úCúKú`úlú}ú‚ú“ú§ú¬ú®ú®ú®úÊúèúèúûKP�­g=g=�=’= =¦=Á=Ğ=ß=î=ü=>
>>Lè7?/?/j/m/p/v/{/’/©/À/ä/00"0<0N0[0q0‚0‡0’0š0š0¤0¤0¯0´0É0Ï0î0␍11$1*1I1h1p1{1{1…1…1—1Õ1í1ÿ1M$ WZWZ‚ZkZŒZ”ZNLx‡ÖÌÖÌèÌıÌÍ Í&Í.Í>ÍIÍZÍ`Í’ÍOTHY0e0eBeDeMeVedeiereuezeˆe’e•eŸeP¨!Gˆcˆc˜c¡c´cÁcÍcÙcåcñcddd"d+d2d;dRdidnd€d�d›d­d­d¶dÙdÙdÛdîdğd
eee0eQlõŒ p p9pDpTp�p¤p¸p¿pÇpÏpØpàpèpêpòpúpqq'q?qHqHq}q§q°qÒqìq r3r?rarcrjrqrqr”r°r×rórs6s]sys s¼sãsÿs&t&t5tBtGtGtVtcththtotztŒt¤t¼tÔtÖtÖtÖtİtİtêtïtïtïtuu!u6uruyuyuyu�u�u¬uÊuÓuÜuéu÷uv-v-v-v?vMviv‡v‡v‡v’v•vÄvÆvİvãvôvıvÿv wwww*w*wNwPwWwhwqwsw�wƒw‘w“w¡w¡wÁwÁwÁwÁwáwx;xCxGxOxSxaxoxqxyx}x�x‰x—x¥x¥x¿xÊxàxôxy-y8yByIybynyuy�y�y y¥y§y­y¾yÏyŞyåyöyÿyzzz z!z/z/z/zSzSzrzyz€zƒz�z’z z¤z²z¶zÄzÈzÈzázèzízûz{{0{P{c{r{t{ƒ{…{”{�{�{¬{µ{Ë{Ò{÷{ü{%|U|Z|h|j|x|�|›|�|Ÿ|¦|·|À|Â|Ğ|Ò|à|â|ğ|ğ|}}}}}/}/}/}:}V}{}”}™}™}™}»}À}À}À}à}å}å}å}~ ~ ~~~~~~~#~#~&~+~J~`~…~¡~µ~º~º~Õ~â~ä~ó~ü~>@@HCƒƒƒ¢¢¢ÃÈÈÈêïï€€3€8€8€S€a€c€r€{€•€—€—€œ€—€½€¿€¿€Ç€Â€���␍�␍�7�7�a�y�‘�œ�²�Æ�ß�÷�‚-‚/‚@‚]‚t‚{‚s†R„7wèwè•è£è¹èÓèáèÿè
é&é&é&é3éNéPéPéPé]éxézézéˆé•é°é°éÕéÙéíéÿéSæd®Ü®ÜÈÜÑÜñÜñÜ÷ÜÿÜİİİİ*İ*İDİIİIİOİTİTİZİ_İ_İeİjİj݂ݕݛݠݠݩİÉİÉİÉİĞİÒİÒİÙİÛİÛİáİáİèİêİêİğİğİ÷İùİùİÿİÿİŞŞŞŞŞ"Ş"Ş"Ş"Ş.Ş6Ş>ŞFŞNŞVŞ^ŞdŞ|ދޕޘޘޢިޮޮ޲޺ŞÁŞÅŞÍŞÕŞÛŞãŞêŞòŞúŞşŞßßß"ß.ß4ß<ß@ßGßOßWß[ßaßißpßx߀߄ߊߕߚ߰ßÁ߯ßÉßnàTLœ«H‡H‡a‡c‡j‡€‡�‡–‡®‡Æ‡É‡Û‡#ˆUÔ/`�ğ�ğ²ğÇğÖğÚğèğñğññññ%ñ0ñ7ñGñ^ñuñ{ñ€ñ„ñ—ñ—ñ­ñ¯ñ¹ñİñèñêñòòòòò!ò0ò8òKòµòV$ZZBZ+ZLZTZWP©¹¯C¯CĞC½CòCßCDDD#D%D0D;D;D]DcDX,>×>×G×M×U×^×g×l×Y�¿�¿�à�õ���C�P�b�‚�’�’�Ÿ�Ÿ�¦�¹�·�Ç�Ç�Ò�Ü�â�è�ë�ù��� �"�7�<�G�R�l�†�—���£�ª�Á�°�Ñ�×�İ�å�‘í�‘‘‘"‘"‘)‘@‘/‘P‘V‘\‘d‘„‘l‘�‘“‘™‘¡‘¡‘¡‘·‘·‘·‘·‘‘̑Ցõ‘’’’(’<’A’A’L’T’_’h’t’ˆ’˜’­’Â’ß’ä’ä’ï’÷’““ “.“K“`“u“€“…“…“�“¦“»“Ǔؓݓ”␍””%”*”*”9”>”>”M”R”R”c”h”h”y”~”~”‘” ”¥”¥”¸”ǔ̔ڔ̔î”ó”•ó”••(••<•A•O•A•c•h•h•…•Š•¬•±•¿•±•ӕؕؕõ•ú•–!–/–!–C–H–H–e–j–Œ–‘–Ÿ–‘–³–¸–¸–Õ–Ú–ü–———#—(—(—C—H—H—c—h—h—ƒ—ˆ—ˆ—£—¨—¨—×È—È—ã—è—è—˜˜˜#˜(˜(˜9˜>˜>˜O˜T˜T˜`˜k˜€˜…˜…˜‘˜ª˜¯˜Õ˜ܘæ˜ë˜ü˜™™&™+™<™G™O™T™T™X™\™c™m™w™w™Š™�™�™�™“™¬™µ™µ™Û™à™à™è™ü™š š,š7šBšMš_škštšyšyšyšŠš§š²š¼šÇšÌšךßšäšäšïš÷š› ››3›K›_›d›d›o›‚›Œ›—›¸›Ä›Õ›Ú›ë›ï›ô›ô›œœœœ'œ7œFœcœxœ�œ˜œ�œ¨œ°œµœÀœĞœßœüœ�&�&�&�&�+�0�0�<�M�M�r�t�‘�‘�›�¯�¹�»�Ç�Ï�ì�ı���5�F�W�h�s�‹�›� � �«�°�°�¸�Ã�È�È�Ğ�Û�à�à�è� Ÿò�ğ�!Ÿ&Ÿ&Ÿ.ŸOŸ8Ÿ6ŸgŸlŸ€ŸlŸ˜Ÿ�Ÿ�ŸªŸ¯Ÿ¯Ÿ·Ÿ¼Ÿ¼ŸΟàŸåŸåŸùŸåŸ    # # 6 ; ; N S S m } ‚ ‚ œ ¬ ± ± Ë Û à à ú 
¡¡&¡¡>¡C¡C¡N¡S¡�¡}¡k¡S¡§¡¬¡è¡Ö¡Ä¡¬¡¢¢¢¢$¢)¢)¢8¢H¢M¢M¢\¢j¢o¢—¢…¢o¢¯¢´¢Ü¢Ê¢´¢ô¢ù¢!££ù¢9£>£>£[£E£…£•£š£š£µ£¡£ߣï£ô£ô£¤¤¤¤¤¤)¤9¤>¤>¤Q¤a¤f¤f¤y¤‰¤�¤�¤¡¤±¤¶¤¶¤¾¤ääˤФФؤݤݤå¤ê¤ê¤ı¤¥¥¥¥h¥V¥D¥2¥¥u¥z¥È¥¶¥¤¥’¥z¥Õ¥Ú¥Ú¥é¥¦ ¦ ¦¦5¦:¦:¦K¦Y¦^¦^¦f¦k¦k¦s¦x¦x¦€¦…¦…¦½¦«¦™¦Œ¦ܦ÷¦ü¦ü¦4§"§§§S§n§s§¨§–§‹§s§À§ŧú§è§ݧŧ¨¨1¨¨¨I¨N¨k¨U¨N¨ƒ¨ˆ¨ˆ¨”¨­¨½¨ΨΨó¨õ¨ ©©©.©;©l©�©‹©À©È©È©È©Ô©Ù©Ù©ì©÷©ªªªª ª ª:ª?ª?ªGªLª`ªLªoªzªª“ªª¢ª­ª²ª²ª½ªΪÓªÓªުéªîªîªÿª«««)«.«9«.«H«M«a«M«p«u«€«u«�«”«¨«”«·«¼«¼«Ğ«¼«ß«ß«ß«ä«ğ«ä«¬¬¬¬¬'¬,¬,¬8¬,¬K¬P¬P¬\¬P¬o¬t¬ˆ¬t¬—¬£¬®¬¹¬¾¬Ò¬¾¬á¬í¬ø¬­­­­3­+­<­A­A­I­N­N­W­\­\­e­j­j­s­x­x­ƒ­ˆ­ˆ­“­˜­˜­£­¨­¨­³­¸­¸­íȭȭӭححã­è­ü­è­ ®®!®,®1®1®;®@®@®J®O®O®Y®^®^®h®m®m®u®z®z®‡®Œ®Œ®™®�®�®�®�®�®¦®«®«®³®¸®¸®À®Å®Å®Í®Ò®Ò®Ú®ß®ó®ß®¯¯¯¯ ¯*¯J¯O¯e¯p¯‰¯u¯˜¯£¯®¯³¯³¯º¯ůå¯ê¯° °$°°3°>°I°N°N°U°`°€°…°›°¦°¿°«°ΰÙ°ä°é°é°±ğ°±3±8±N±Y±r±^±•±�±¤±¯±´±´±ϱ»±ޱş±²²$²=²)²`²L²o²z²²²š²†²©²ɲβä²ï²³ô²+³³:³E³J³J³Y³^³^³m³r³r³r³x³}³}³}³‡³‰³‰³“³š³½³¿³¿³ɳɳɳɳɳ˳˳â³é³ô³ô³ÿ³´ ´´"´-´'´H´e´Z´}´}´‹´…´±´¦´É´É´É´Ò´Ù´ì´ñ´ÿ´µµ1µ<µSµsµsµsµ”µ¤µ¹µ˵ÛµÛµ(¶(¶,¶1¶8¶H¶g¶g¶k¶‚¶‰¶��’¶�©¶·¶ä¶í¶ş¶ ·?·K·P·f·~·Š·›· ·±·Ğ·ş·'¸*¸:¸<¸<¸@¸_¸j¸j¸m¸~¸¯¸Ò¸Ò¸Õ¸úºZ, n×n×|ׂ׆×�ט×�×[`EYφφå†ó†ú†ş†␍‡&‡*‡0‡F‡c‡e‡e‡–‡„‡e‡µ‡¿‡\8
§Y§YÈYµY×YâYíYøYZZZ]\’¡¡¡ ¡+¡3¡>¡I¡T¡V¡l¡l¡~¡Š¡“¡–¡Å¡^l½”§î§îÌîÑîŞî
ï
ïï"ï@ïHïuïzï£ïÃïßïåïéï ğ2ğ7ğ`ğ}ğ£ğºğÀğÄğİğåğêğûğñ"ñ(ñ,ñEñMñlñqñ‚ñŠñ©ñ®ñ¶ñ¼ñÀñÄñÖñŞñãñòòòòò%ò=òLòYòyòyò�ò•ò•ò¬ò®ò®òÂòÄòÄòÛòİòİòôòöòöò␍ó␍ó ó$ó$ó3ó3óló…ó…ó˜ó�ó�ó�ó�óÀóÜóøóøóøóôôôô␍ôôôôôôFôHôhôˆôˆôˆôˆôˆô¢ô¥ôºôÁôÃôÌôßôáôíôíôõôõõõ&õ=õGõoõ�õ�õ½õŞõöõö;öJöhö�ö¥ö´öËöçöìöìö ÷%÷%÷8÷8÷D÷V÷[÷[÷s÷’÷¸÷Ç÷å÷
ø*ø9øgøzø„ø¦ø¨ø¨ø¨ø´ø´ø´øÒøùùùùùùùùùù/ù4ùGù†ù_\
÷N÷N O O;OHO_OtOO”O�O£O«O¶OÌOÂOäOêO`à7:7:U:X:_:f:m:q:s:z:�:…:‰:œ:Ä:ß:Ì:÷:ü: ; ;,;4;C;};‚;¯;·;¼;Å;Ñ;Ù;à;<<*<,<N<m<Z<|<‚<‰<‰<�<’<–<§<§<Ê<Ü<a$ÏàÏàŞàùàùàÿàb|k†×ë×ëñëìì<ìLìNìNìNìNìUì]ìxì‘ì“ì“ì“ì›ì¶ì¸ì¸ìÂìÂìÚìc”"§5§5É5Ó5ß5ä5ô5ú56#636A6O6f6n6x6‡6�6œ6¤6§6§6§6©6¸6Â6Ë6Ó6Ö6è6dô¦ß'7'7P7]7`7i7o7†7�7´7¿7õ788 8*8D8V8c8y8‹8¢8§8¹8¾8Á8á89 99969V9^9f9h9ˆ9�9•9š9¥9¥9°9°9¼9¼9Î9:':':7:ed¤¹����#�)�1�?�R�^�x�…�…�ˆ�–�¦�À�Ä�Ì�f(¸şr*r*ˆ*�*¡*Ğ*à*ç*÷*+
++8+b+s+�+�+ˆ+˜+¤+´+½+Ô+Ô+ê+ê+,,,,,,,,B,B,X,X,n,n,„,„,›,›,²,²,É,É,à,à,÷,÷,--%-%-<-D-O-`-k-|--�-˜-Ÿ-æ.g¬÷V V p v } … � � › ­ ­ Ä Ë Î Ğ Ü í í ğ ø    " % , 0 8 F X k n ½ h(ÈÎÿ€ÿ€&��5�G�O�i=ÏQÏQòQR RRR$R1R7R@RFRKRjRƒRˆR�R�R’RŸRŸR¤R­RµR¾RÆRÈRĞRØRàRíRóRşRSS S/SPSWSbSkS|S€SˆSˆSœS¬S´S·STj8-7*0*0>0B0G0R0]0`0d0l0kˆZø¿‡¿‡Ù‡ô‡ú‡ˆˆˆ-ˆ2ˆ=ˆ[ˆEˆjˆ}ˆ�ˆ˜ˆ ˆªˆȈÚˆãˆëˆõˆ‰úˆ ‰1‰;‰C‰[‰E‰€‰j‰�‰¡‰«‰³‰³‰¼‰ĉÚ‰ó‰ŠŠŠŠ Š$ŠBŠDŠIŠTŠjŠjŠjŠnŠzЛХНЏŠÙŠãŠíŠïŠïŠ ‹‹(‹+‹D‹H‹c‹g‹†‹Š‹¥‹©‹©‹©‹¯‹½‹Ç‹à‹æ‹ñ‹ı‹ÿ‹Œ␍Œ&Œ1Œ?ŒIŒbŒeŒmŒyŒ{ŒƒŒ†ŒŸŒ¡Œ­Œ¯Œ·Œ½ŒÖŒîŒúŒ��)�9�R�c�c�n�y�‘���²�·�Ì�Ü�õ��� �� �-�4�F�leãnànàˆà‘à±à±à·à¿àÇàÏà×àİàêàêàøàıàıàááááááááá6áIáOáTáTá]á}á}á}á„á†á†á�á�á�á•á•áœá�á�á¤á¤á«á­á­á³á³áºáºáÂáÈáÎáÖáÖáÖáÖáâáêáòáúáâ
âââ0â?âIâLâLâVâ\âbâbâfânâuâ}â…â‰â�â—â�â¦â®â²â¸âÃâÉâÖâââèâğâôâûâã ãããã$ã,ã4ã8ã>ãIãNãdãuãzã}ã"äm`b!b!k!r!†!š!Ÿ!½!Â!à!â!"""-"6"8"L"\"�"n�2Ò8•8•N•_•p•�•’•£•¶•¾•Ì•ê•õ•û•–––0–A–G–\–w–w–ƒ–‹–“–™–®–¶–º––Ж֖ۖۖ𖗠———"—E—X—d—h—r—‹—‘—“— —¢—´—´—»—×՗՗˜˜'˜+˜5˜9˜E˜I˜U˜Y˜e˜i˜i˜˜’˜˜˜œ˜¦˜ª˜¹˜½˜Ì˜Ğ˜ã˜ç˜ç˜ç˜ç˜ş˜ ™™!™8™H™V™a™w™„™“™›™¨™Ã™Ó™ã™è™è™è™è™õ™š šš'š6šKš\šlšršršrš„šŠš–šœš©šÄšÔšàšæšóš››5›¿œoÔÃô0n0nBnSn^nin‚n”n¬n±nÀnÇnÔnÛnénğnònõnúnünoo6oLodoioxooŒo£oÁoÈoÊoÍoÒoõop pp$hm&& &4&;&U&qxKe¿Q¿QçQÓQöQRıQ R%R,R4R;RFRQRYRaRlRwR�R‚R¥R­RrJ‡·t·tÓtÚtòt
uu u u$u/u;uFuTudutu{u�u–u«u«u¿uÇu×uäuóuvv"v0v>vEvKv`vuvuv‰v–v§v·vÀvÑvÑv×våvövwwuws8³½QQƒQˆQ�Q�Q¬QµQºQ¿QÁQt88Br0r0†0Š0�0š0¤0§0«0³0u0ˆ�ŸOŸOµOÈOÕOÛOŞOæOvÜt¾¾àëöÿ!'-3I8]jmu‡�’µÈÌÒéïÿ $2KYbrt{€ˆ§µÁÛú  &,2Hi}‰ «ºÈ×äô%*8Tf}†Œ—œ¢¹ÄÑØØæõ÷&&.Q\�w`0DÏ…Ï…å…÷…ş…††0†4†:†P†m†o†o† †�†o†¿†ɆxDˆÕÏäÏäáäéäôäúäååå4å4å;å>åCåUåYå€å„å‰å‰å�å“å˜å¤åµå¹åÊåÜåàåâåôåøåææææ1æ4æBæLæSæyæ„æˆæ�æÃæÜæçæëæüæç ç␍çççç0ç4ç6ç6çAçEçYç]ç]ç]çaçƒçy¼Ö‡ç‡ç›ç±ç±ç±ç¶ç¶ç½çÂçÂçÉçÎçÎçÛçàçàçíçôçöçöçè
è è è(è(è(è+è-è-è-è1è3è3è7è7è7èSèXèXèqèz°0X[[ ['[2[–[|[q[W[@[œ[®[�[Î[Î[å[Ù[\\(\=\*\L\R\Y\}\l\`\”\–\²\²\¹\ã\ã\ã\ï\{ÈQ¿FüFüdüoüzü ü ü¢ü¯üºüÀüÑüàüïüüüüüıı ı"ı5ı@ıDıVıcıkıvırı�ı›ı›ı›ı¦ıÁı¬ıÉıÜıŞıúıæışşşş.ş.ş5ş;şDşKşNşpş„şwşŒş’ş›ş›ş›ş®ş³ş³ş»ş»şÆşÛşäşäşäşäşÿÿÿ"ÿ"ÿ7ÿ=ÿBÿBÿNÿkÿ‹ÿ�ÿ•ÿ•ÿ¡ÿ¾ÿÍÿÜÿäÿéÿïÿôÿôÿûÿ%BDLavv||‰’’°ÆÑÖãî÷ÿ&&66HN}††ˆ�””¡¬²»»ÎÛíø>GRW^fy�“š§®ÀÕÜâëëô(8FFLS\\o�„„•�¥±ÎÕâäëÿ888EEZew„��¨·¾¾×êìû 55;DDQWiivy„–�¨­µ¼ÇÌáãı!2@RRX_hm‘šš ©©ÈÈÕØáêòı  -09BJUgmxx…ˆ‘šœ¾Ñæì÷ "› |t·ĞR4R4d4m4p4y4‚4”4”4À4Ä4É4Ì4Õ4ä4ê4í4õ4ø4ı45}`2ïOïOPP&PKP7PZP_PfPnPuP€PˆP“P©P�PÁPÉP~À-¸g¸gÖgægğgğgúgúghh#h&h(h1h>h>hLh`h`h„h‘h‘h¡h®h®hÑhŞhŞhóhi*iLiUibibi…i�i�iÂiõiûiûiûi␍jt�Z3Z3n3�3¡3µ3¼3È3â3ë3ñ34␍4␍4!4!4$4'4<4B4D4D4L4€¸ºäĞ�Ğ�è�ê�ö�ú��
�$�$�$�*�.�6�A�U�a�c�c�l�n�n�w�y�y�‚�„�„�����–�œ�Ÿ�©�º�À�Ì�Ì�4��œ&ï(ï(␍))6)=)Y)N)q)‘)}) )±)¶)×)Ã)ï) **/*$*G*g*S*v*‡*�*‰*µ*Â*Â*Ú*Ú*ä*‚¨¥Ç3Ç3Ó3ã3î34H4Y4j4|4ƒ4Š4�4¥4¥4´4Â4Ñ4é4ø455!5$5)5@5P5`5d5k5¡5ƒx± (±(±>±E±L±k±z±‰±˜±§±¶±À±À±Å±Ì±ß±î±ó±²(²(²>²P²T²b²i²n²n²u²‡²�²’² ²²²²²²²Ä²Ï²á²ì²ù²ş²³³#³/³4³A³F³V³[³k³m³}³³�³‘³¢³«³«³­³½³Ä³Ô³Ô³ï³´´%´5´5´5´8´K´„\åø8�8�S�Z�_�m�‚�‰�“�¡�¤�¦�°�Â�Â�É�ÿ�…0ÎÖ��öêÀ¾
†`/ττå„÷„ş„……0…4…:…P…m…o…o… …�…o…¿…É…‡L[j?2?2M2_2e2m22…2�2 2¦2©2å2ˆ(–œ*3*383G3K3N3T3‰\k~ç2ç2õ23␍33'3-363H3N3W3i3o3r3À3Š, ××$×+×3×8×>׋„$··Õçîõ ++0RgTv…‡©©©¸ÔÊìöŒ`B?i?i\idiki�i�i i®i»iÁiÌiãiòiıij jj j+jBjYjljƒj�j›j­j¯j½jÏjÏjØjéjïjÿjÿjkk<k<kAkAkJkVkckok„k›kªkµkÇkÓkêkl#l#l,l1l1l1l1lAlJlRlWlelslƒlˆlˆl–l–l›l›l¥l°lÂlÈlÔlälïlùlılm m"m2m9mWm`m`momm�m–mœm¨m°m»mÂmÆmÙmßmìm÷mım␍nnnJnhntn|n‡n�n™n©n¹n¹nÉnÎnÎnØnãnõnûn oo#o-o1o:oSoVofomororo†o†o‹o�oŸo¨oºoÀoÂoÂoĞoÖoßoğoùoppppp2p2pApDpXpvp�pªp¼pÇpÙpİpâpépûp q&q-q1q7q?qJqYr�8øO(O(i(~(”(µ(¢(Í(å(å(ï(�`j~X X x  ‡ ’ œ § ¯ ¾ È Ë ğ ò ¡¡¡�_×Ú×ÚùÚÛÛ Û#Û5Û?ÛEÛWÛ\ÛhÛpÛsÛuÛÛ‰Û‰Û�Û•Û�Û¥Û¯Û¸ÛÀÛÃÛÌÛçÛøÛÿÛÜÜÜÜ$Ü$Ü+Ü.Ü3ÜBÜHÜPÜPÜ^ÜaÜfÜu܀܈܈ܓܧܮܵÜÌÜ�83=ö×ö×ÿ×ÿ×␍ØØ Ø"Ø'Ø‘8>H.Ø.Ø7Ø7ØEØIØPØSØXØ’DDQG1G1a1t1~1…1‘1©1²1¶1È1Î1í1“Ä{¨©¬³¸¾ÀÅËËİäú␍"$+1;;OQX^hhh‘˜§©¿ÒÒä”0RZï1ï1ø12/25252=2•„a~¶ò¶òÈòİòçòğòòòùò óóó ó ó)ó:ó=ó=óaólónó‡ó�ó’ó¡ó´óô– 
>0>0G0d0i0—hú—f—f­f¸fÃfÑfÜfåföfÿfgg"g9g9gKg\gigrgƒg‰g×g˜„=Z—J—JÇJÍJÖJâJêJñJõJşJşJK
K"KLKQKuK}KK—K¯KÓKòKL™lò §§¿ÑØß%:'\Ikk}„¦¦®š y}ˆ‹ˆ‹‘‹�‹¢‹›(AVèVèxè€è†è�è�è�è¡è¡è¡è©è±èÃèÒèÃèçèéèéèééééé0é5é5é5éJéLéYé[éhéjéwéé‡é�é¢é¯é±éÂéÏéÏéÏéØéêéıéê ê␍êêê/ê/ê/ê:êDê\êaêaêaêoêuêzê‚ê�êŸêªê¯ê¯ê¶êºêÈêÌêÕêÜêúêëëë3ë8ë8ë8ë8ë@ëKëYëYëyëyëyë€ë�ë�ë°ëÃëÅëÅëÅëØëØëßëæëëëñëì␍ì)ìSìYìYìmìrì–ì�ì©ìÇìÚìåìììğìğìğìğìûìíí5í@í]ígígíuí“íÃíÖíçíşíîîîîî)î;îFîKîKîKî]î‡î�î�î�î˜î¢î®î¹î»î»î»îÀîÌîÌîïœH%Š/Š/˜/Ÿ/ª/·/Â/Ê/Ê/â/ì/ò/ø/�0 NN¦N“NµNÑNÇNéNñN�Lè÷?'?'Y'n'„'¥'’'½'Â'í'(û'&(>(>(H(Ÿğ[“LL<LELQLYLdLƒLƒL�L�LªL’L¹L¹LÇLÑLØLøLúLMMM7M7M^McM‚M›M¸M»MÃMÊMêMìMN␍N␍N)N)NFNFNmNN T]n)/5FTbtx~Œ�™¡0
R¯¯ŞÓÿë"1=BN^er}‰”œ¡­²ÆÍÑÜáì 3:>>C\az�¡¦±¹¹¹»Ôéôş  .#Ff¢àZ� e eºeÈeÍeÚeèeñe ff?fHfXfsf~f�f�f’fœf¨f¬f¹fÅf×fßf÷fûfûfûfûfgg8g8g?gBgJgVg_gµg£d'<ç*ç*++.+5+Q+F+i+‰+u+˜+©+¿+«+×+ä+ä+ü+ü+,¤ü%`÷÷!,Y?3h‰�‹Ó¹­âÿÿÿ..czn¬±Ä¸ìÚû4!OCwe†£££µÒÒóú$¥(fåfåtå—å�å¢å¢å¨å¦(!'�×�×§×µ×»×½×Â×§D]j : :::A:J:V:k:s:y::�:�:‘:¨„½Ú¸ª¸ªëª÷ªûª« ««««"«&«.«3«7«H«Y«[«_«p«�«�«£«««¶«¶«¶«È«©€ÀœÀœÙœàœçœîœôœ���$�;�>�@�[�e�o�v���“�›�›�±�±�Ã�ª Ê ¯V¯VÕVòVúVWWW"W=WSWlWrWzW}W’W—W©WËWÑWÙWŞWäWçWıWXX*X2XGXLX[X}XƒXˆXˆXˆX•X¦X±X¾XÊXİXêX÷XY#Y-Y/YFYVY[YfYmY�Y�Y�Y¢Y«<ÑÜ
5
555$5,545<5C5S5S5X5¬´*££3£@£E£I£R£a£m£x£ƒ£‹£–£�£¡£­£µ£Ï£õ£ï£¤¤C¤/¤S¤S¤k¤v¤’¤™¤½¤Ä¤ö¤ö¤ö¤ö¤W¥­˜‹-ş¸ş¸¹"¹*¹5¹L¹V¹V¹m¹w¹’¹¨¹¶¹º¹Ú¹î¹º º␍º&º0ºAºNºNºUº\ºaºfºkºrºyº“ºšºªº®º®º¸ºÎºÒºÒºãºöº » »»»!»)»4»;»C»N»U»U»`»~»‚»š»‹»µ»µ»»»Â»Ñ»Û»é»ğ»ô»ö»¼¼¼¼"¼H¼V¼V¼Z¼o¼w¼‡¼’¼§¼¬¼º¼É¼Ó¼á¼ì¼ğ¼õ¼ı¼½½½!½#½2½4½C½J½N½b½l½z½�½…½•½ ½¥½Ã½Í½Û½â½æ½ğ½ş½¾ ¾¾'¾/¾:¾>¾>¾>¾I¾T¾d¾p¾†¾�¾™¾¨¾°¾»¾À¾È¾Ó¾ß¾ã¾î¾ó¾¿¿¿¿¿¿7¿T¿`¿h¿x¿ˆ¿¦¿ª¿Ù¿Î¿¿¿é¿é¿ó¿ú¿ ÀÀ"À0À7À;À=ÀLÀVÀdÀkÀoÀoÀqÀƒÀƒÀ•À•À•À›À§À¹ÀÁÀÙÀÁÁÁ5Á<ÁCÁNÁdÁiÁpÁƒÁ�Á›Á¢Á¦Á¨Á»ÁÅÁÓÁÚÁŞÁŞÁŞÁŞÁìÁ÷ÁÂÂÂ)Â-Â-Â2Â:Â>ÂMÂOÂ^Â`ÂoÂq€‡‹Ÿ©·¾ÂÂÂÒÂİÂâÂÃ
Ãà Ã#Ã-Ã;ÃBÃFÃPÃdÃlÃwÃ{Ã{Ã{ÆÃ�ÛõÃÅÃĞÃåÃêÃõÃÄÄ'Ä/Ä:ÄIÄQÄ\ÄaÄiÄtĀĄÄ�ĔĨİĻĻĻĻÄÏÄßÄôÄÅÅÅ*Å?ÅLÅPÅ^ÅsŃŚųÅÌÅÎÅÙÅáÅáÅêÅÆÆ/ÆHÆVÆaÆmÆuÆwƂƊƊƊƧƵÆÃÆÚÆñÆÇ␍Ç-Ç4Ç4ÇDÇXÇrÇrÇvnjǛǶÇÁÇØÇàÇàÇÈÈÈ3È<ÈSÈmÈ|ȉȩȷÈÍÈéÈùÈÉÉ)É)É5ÉPÉhÉqÉqÉqÉ}É�ɦɯɯɶɿÉÅÉÑÉ0Ê®<ùD��%�1�<�F�L�V�\�f�t�~���š� �ª�°�º�Á�Í�Ó�Ü�‘‘‘‘%‘7‘A‘S‘]‘r‘r‘u‘‘”‘™‘©‘´‘¹‘͑ϑà‘’’␍’"’0’9’A’O’`’p’�’�’�’›’›’£’±’ø’¯$› _P_PsP{P†PŒP°l£:§F§FÀFØFèFGG2GMGMGwGGƒG†GŠG�G™GœG£G©G°G¶GºG¿GÉGÚGáGèGêGîG÷GHHHHH/H:H@HGHPHiHzHƒHŒH”HŸHªH¶HÇHØHäHòHôHûHII II IBIPIZIdImI†I—I I©I±IºIÀIÄIÉIÍIÚIáIïIùIJJ!J:JKJTJ]JeJnJtJxJ}JƒJ�J—J¶JÄJÊJÏJ×JßJçJôJüJKK0K9KTKhK{K‚K‹K”K›K¤K­K¶KÏK¿KßKãK=L±  €ˆ€ˆ�ˆ°ˆ¶ˆ²¸�·z'z'ˆ'�'È'Ê'ÿ'*(*(:(?(?(S(X(X(t(y(y(™(�(�(²(·(·(Ô(Ô(â(),)L)^)p)‚)’)’)’)’)™)r*³$bgÊ%Ê%Î%æ%ø%&´„÷Â÷ ÃÃÃÃ$Ã0Ã0ÃFÃ\ÃnÃuÃyÉéûÃÁÃĞÃÙÃİÃãÃìÃÄÄ#ÄAÄSÄYÄhÄzĆĈĔĜĠĦįįįÄÁÄÌÄÒÄèÄïÄ÷Ä␍ÅÅÅÅ"ÅIÅRÅZÅlÅtÅ}ňÅ�ŤūųźÅÏÅàÅàÅçÅçÅçÅõÅÆ)Æ2Æ:ÆLÆTÆ]Æ]ÆhÆoÆ}Æ�Æ�ƥƭƳÆÂÆËÆÏÆׯàÆàÆîÆöÆüÆÇ"Ç*Ç0Ç6Ç6Ç6Ç=ÇDÇSÇ[ÇaÇgÇgÇiÇsǵx¿Ù¿ÙÍÙâÙéÙôÙ
Ú4ÚPÚWÚoÚuÚ„Ú�Ú•Ú�ÚŸÚ¥Ú«ÚºÚÂÚÈÚÊÚĞÚ¼Ô÷b÷bc"c2c:c^cucyc�c‰c�c˜c¤c¬c¬c´cäc#dşcFdKdSdcdzded“d™d¢d©d±d¹dÅdÍdÕdèdğdõdÿd e&e(e2eAeaehejeŠe‘e‘e‘eše¡eºeÀeÈeÈeÍeÑeİeæeïeûefAf,fZf]fyf†fšf°f´fÓfáfgífg!g8g#gQgTgTgpg}g‘g§g¯g³g¾gÆgÖgígØgh hh!h8h#hQhWhWhahahlh�h¥h¥h¥h¥h®hºhĞhéhühiiii)i-i-i-i4i9iLiSi_ififi€i‚i‡iši¡i­i´i´iÁiËiËiĞióióij·àt¨?A?ATArA_A§A�A�A¶AÅAÍAØAÚAåAğAğAõA*B/BdB|BiB�B‹B²B­BÎBİBåBğBòBıBCC C.C0CQCQCXC]CC�C£C£C£C«C¸\æù§e§e½eÏeÕeàeîeúeff#f)f4fDfOf]fjf–f¹$â燇¥¸¿ÆÍÑÓÚáååí   $ / = N R W k o x | � ‡ ¤ ¤ ² É Î ç ø ü ü ü     0 4 9 M U ^ b d k } � ¤ ¦ ¿ Ò Ö Ö Ö ê î ÷ û !!#!#!1!H!M!f!w!{!�!�!�!’!¡!£!Å!Å!ç!ò!ø!" "$"/"C"G"P"T"V"\"u"u"ƒ"š"œ"µ"Æ"Ê"Ê"Ñ"ä"è"ú"ÿ"##$#(#-#4#J#Z#q#v#�#¢#¦#¸#¸#¸#¸#Ê#½#ß#î#ğ#$$#$9$J$J$J$Q$d$}$}$}$Œ$Œ$Ÿ$¶$Á$Ò$×$İ$ç$é$õ$õ$ü$%%%)%>%J%L%W%c%s%z%�%‹%“%—%›%�%¢%ª%®%À%Â%Ç%Ï%Ó%Õ%Õ%Ş%ë%&!&;&I&U&\&\&o&s&s&s&z&&™&§&³&º&º&Ô&Ö&Û&õ&''''#'-'-'?'º¤ ¹�(J(JEJTJTJTJqJqJ‚J‚JˆJŠJŠJ�J’J’J˜JšJšJ¡J¥JªJªJªJªJªJªJ²JÊJÊJßJêJôJKKK:K<K[K`KK„KŠKŠK£K¦KÍKÚKòKLLL L>L,LDLSLXL_LhL{LƒL‹L�L�L�L™L²L¸L¸LÑLßLüLMM M%M-M2M2M8M8MAMRMTMiMkMsMyM�M†M†M†M†M”M«M­MÁMÁMÉMÏM×MÜMåMíMöMüMNNNN N NN1N5N7NCNEN`NfNnNsN|N‡N‹N‘N•N�N¡N¡N¯NÀNÂNêNO OOO#O(O(O-O/O7O7OROdOiOuO{O~O•O—OšOªO®OµO¾OÍOÛOáOéOîOöOûOûOPPP4P9PCPkPvP�PŒP—P¢P­P¸PÃPÎPÎPÎPÖPßPøPQ#Q<Q>QDQFQIQTQVQVQ\QbQbQjQsQyQ…Q…QŒQ�Q®Q¹QÁQÉQÎQÎQÕQÙQŞQğQõQÿQ R RR=R=RFRTReRqRxR†R•R«R±R¶R¶R»RÑRİRåRõRÿRSSS S(S(S2S@SLScSyS�S–S˜S¯S´S´SÔSÔSæSìSõSûSTTTT.T4T6TATSTiTiT}T�TŸT¤T°T¶T¹TĞTÒTÕTåTïTòTòTUU*U/U;UAUDU[U]U`UpUtU|UŠU�U”U”UšU¢U§U§U­U­U»UÁUÇUÑUÛUéUşUVV V VVVV!V&V&V,V4V9V9V>VIVNVSV^VcV‰V‹V�V•VšVŸV¤V©V®V®V³V¸VÔVŞVòVW WWW"W(W.W8WBWPWeWhWjWtWƒWˆWˆWˆW�W•W�W�W£W£W©W±W¶W¶W»WÆWËWĞWÕWäWäWõWûWûW XXX X)X7XLXOXQX[XjXoXoXoXwX|X…XŠXŠX�X˜X�X�X¢X­X²X·X¼XËXËXÜXâXâXğXöXüXYYY3Y6Y8YBYQYVYVYVY^YcYlYqYqYwYY„Y„Y‘Y—Y—Y¥Y«Y±Y»YÅYÓYèYëYíY÷YZ Z Z ZZZ!Z&Z&Z,Z4Z9Z9ZFZLZLZZZ`ZfZpZzZˆZ�Z Z¢Z¬Z»ZÀZÀZÀZÈZÍZÖZÛZÛZåZíZòZòZòZøZ[[[![!['[1[7[<[<[E[S[\[j[o[o[x[†[’[£[°[·[¿[É[×[×[Ü[Ü[ç[ç[ç[ë[ğ[ğ[÷[û[\\\\\(\0\5\;\;\C\L\Z\e\j\p\x\}\}\}\}\}\}\}\}\}\}\–\œ\¥\«\³\¸\½\Æ\Ñ\Ú\â\ç\ç\ç\í\õ\ú\ú\ş\]] ]]&]/]5]5]>]T]T]Z]c]y]y]‚]„]Š]“]©]©]²]Line truncated
77$787G7d7q7ƒ7¥7Í7Û7÷7 8!888C8d8‚8‘8¬8·8Ò8ë8ë89/9I9d9v9…9”9”9Ÿ9²9Ã9Ö9æ9ó9ÿ9:+:+:3:3:3:D:Q:X:w:€:‘:•:�:¨:À:Ø:á:ñ:ù:ş:";2;B;M;a;f;n;”;–;¡;Ô;î;î;<<<,<5<=<O<q<y<�<Œ<�<�<¶<Î<æ<ş<='=0=9=K=Y=]=a=à ¸ˆ¸ˆÁˆàˆåˆÄ\ˆ[–͖ͰͷÍÄÍÏÍÔÍÚÍìÍòÍ
ÎÎ.ÎDÎOÎUÎwÎw·ΜÎ�ΡέενÎÅÎÓÎÙÎâÎîÎîÎğÎÏÏ␍Ï␍Ï$Ï$ÏBÏBÏUÏbÏgÏgÏ~χϖϬϷÏÅÏĞÏàÏíÏÿÏĞĞĞ(Ğ*Ğ*Ğ2Ğ7Ğ7Ğ?ĞDĞDĞLĞQĞQĞYĞ^Ğ^ĞdĞiĞiĞpĞuĞuĞ|Ğ�Ğ�ЌББМССЬббммĞ×ĞŞĞäĞçĞòĞõĞ ÑÑ%Ñ,Ñ/ÑAÑCÑIÑ]ÑjÑyÑyÑyÑyуÑ�ѲÑÄÑÕÑŞÑïÑõÑúÑÒÒ(Ò7Ò=ÒNÒYÒcÒsÒ‚ÒˆÒ“Ò™Ò®Ò´ÒÅÒĞÒÖÒæÒæÒöÒ ÓÓÓ-Ó4Ó:ÓKÓVÓ[ÓxÓ�Ó›Ó«Ó·ÓÉÓÔÓãÓåÓ÷ÓÿÓÔ ÔÔÔ'Ô-Ô7Ô=ÔHÔNÔPÔ]ÔjÔtÔ�Ô›Ô›Ô¡Ô¨ÔìÖÅD#°ø¬ø¬­9­A­A­O­b­|­­ˆ­¤­¤­¤­¬­®­®­¶­¸­¸­À­Â­Â­Ê­Ê­Ó­Ù­Ş­Ş­ç­ö­ú­ÿ­®
®
®
®
®®®!®&®&®+®8®Q®p®s®‰®¨®¨®¨®°®²®²®²®º®¼®¼®¼®Ä®Æ®Æ®Æ®Î®Ğ®Ğ®Û®Û®á®æ®æ®æ®æ®í®ø®
¯¯&¯0¯0¯0¯@¯@¯G¯K¯Q¯i¯w¯Š¯—¯À¯Ã¯Ì¯Ó¯ç¯ï¯ø¯°°°°°°° °&°;°C°I°T°k°‚°�°”°™°™° °«°«°°°Â°È°È°È°È°$±Æd$àCàCD DDDD,D.D;D=DHD\DdDtDyDD‡DŠDœDÇLWf"1"161:1?1J1J1T1Z1Z1^1f1È\CVº0º0Ğ0Ğ0Ô0Ù0ì0ï0ô0ô0ş011111É8(2Æ×Æ×Ï×Ï×İ×á×è×ë×ğ×ʨYï\ï\]]]-]!]_]Ã]©]�]„]m]É]Ş]Î]ş]^ ^%^:^'^I^O^O^V^€^«^�^Â^à^à^à^ì^ËlQh'-'-A-j-L-y-™-µ-«-Í-å-Ò-ô-␍.-.?.X.X._.�.�.‹.Ì4�¦—í—í«í°í¶íºí¾íİíåíÍxÏéO�O�z�g�‰�“�š�°�µ�º�¾�À�Æ�Ì�â�Ï�ñ�
‚‚$‚G‚=‚V‚b‚Δ"ȫȫ֫è«ì«ô«ü«¬¬¬%¬0¬5¬K¬R¬Y¬d¬o¬q¬|¬‡¬‰¬•¬ ¬«¬´¬¼¬¼¬À¬÷¬Ï€ø2626P6T6X6`6n6q6t6Š6�6’6¤6¨6¬6´6¼6È6İ6î6õ6ü6ü6 77к<gDgD—D¢DÇD©DáDEEE E)EAEPEREZE|E�E¯E¼E×EçEìEFFFF.FUFgFtF�F«F¡FÅFËFËFÔFôFGGG G
G/G/GAGAGOGYG„GzG�G�G£G¦G¼GÈGİGH HH!HIH8HXHZHlH€H”HŠH©H¯H¾HæHÕHõH÷H II'I1I:IQI[I]IqI{I{IšI I I I©IÉIñIàIJJJ JJJ@J_J_J_J…J…J—JÑÄ8¥ÿ1ÿ162=2E2N2Y2`2x2}2€2ƒ2Œ2š2¤2©2Ñ2Ö2ã233!3A3F3U3�3‰3�3£3Ï3×3Ü3Ü3ï3444;4K4P4P4|4|4|4|4|4�4¨4­4°4³4³4à4å4å4ò4ö45,5:5E5a5a5a5n5…5‡5‡5‡5”5«5­5­5º5Ñ5Ñ5á5æ5 6,64696U6u6ƒ6‘6›6�6�6�6¹6Á6Ã6Ã6ë6!7Ò¤8]ÿéÿéêEêEêdêtêyêyêˆêšê´ê¼êÃêÈêãêëêëêëêíêíêíêíê ë ë ë ë ë"ë"ë"ë"ë=ëHë}ëÓĞêg‚g‚}‚‰‚�‚�‚š‚Ÿ‚¤‚¯‚´‚´‚´‚é‚Ö‚ø‚ ƒ ƒ8ƒQƒjƒƒƒˆƒˆƒ¡ƒºƒÓƒìƒñƒñƒ
„#„<„U„W„W„p„‰„¢„»„»„»„Í„Ô0”œ7í7íEíKíOíní�í�í•íÕ<:E"9"9+969D9P9\9e9n9w9}9‚9ÖluŒª&ª&¸&Â&É&à&à&å&ç&ó&ı& '('*':':'?'A'H'z'×ĞŸÏ7s7sKsusjsVs•sÇs­s sòs÷stt t.t6tSt¬tŸt”t€t²t½tétîtötuuBu7u#uUunuZu‘u}u¨u¯uÛuÛuÛuÛuãuØLix�.�.­.¿.Æ.è.è.ú.//␍///9/Ù$qv§N§N»NÃNÎNÔNÚÈg•j1j1�1’1±1Ó1ß1æ1ñ1ÿ1 2222$2<2G2W2c2j2u2†2ˆ2™2›2�2�2�2¥2¥2¯2¯2·2¿2Ç2Ï2Ó2Ş2*3Û (ˆ(ˆ6ˆMˆSˆÜ`FZ‚9‚9’9™9›9 9¯9µ9Ê9Ê9Ø9Ø9ä9í9ğ9ş9: ::İ<ùG�G�P�[�f�q�|�†�¤�¯�¿�Ş 5×g×gïghhhh,h8hOhZhjh|h‚hˆh�h¡h§h°h¶hÈhÎhÙháhïhüh9iß,29¿0¿0Í0Ş0÷0 111à4èˆèˆöˆ‰ ‰‰‰!‰!‰'‰áÄMzGşGşsşvş{şˆş�şŸş¡ş¥ş©ş¬ş¿şØşşşÿÿÿ2ÿXÿ]ÿvÿœÿ¡ÿ¨ÿÁÿçÿéÿ(((@Zi{â ˆÇwwww•w˜w�w²wºwËwØwŞwãwãwğwùwÿwxx x>xRxYxexuxuxƒx–x¡x¥x¶x¶x¶x»x»xÇxÖxéxïxôxyyy(y.y0y?yLyRyXy]ycyiypy|yƒy…yŠy’y”y™y¥y§y¬y´y¶y»yÃyÅyÊyÒyÔyÙyáyáyáyñyñyñyzzz z$z=zCzNzVz`zdzjzƒz�z™zŸz¬z±z¶z¶zËzÓzİzåzíz{{${0{*{9{B{G{L{a{h{q{}{ƒ{�{“{˜{�{¨{³{¾{À{Æ{Ó{Ø{İ{ö{| | || |!|&|/|H|S|^|d|q|q|u|z|z|‹|�|�| |¢|¢|µ|·|·|Ê|Ì|Ì|ß|á|á|ó|ó|ù|ş|ş|})}}6}>}E}K}S}f}q}h}�}�}ƒ}›}�} }¯}Á}Ñ}İ}ô}~~'~7~J~O~O~X~l~~~‰~‘~™~�~«~±~¶~¶~¼~Ğ~à~å~å~ë~ñ~ö~ö~ö~ü~ +/448==BMYs‰••›¨ª·ÃÒååòşşşş€€€*€5€=€E€G€Y€^€l€{€�€�€�€¥€µ€µ€É€Õ€×€à€ì€�� ���*�*�5�5�5�5�5�±ƒã ŒĞ×V×VõVWW WDWJWOWUWcWjWyW~WŠWœWœWºWÅWØWßWùWX"X=XUXqXzX‰X‘X�X§X¬X¼XÊXêXïX÷XY"Y2Y8YCYLYRY˜Y‚YsY¨YãYÍY¾YóYöYZªZä<%0 D DÁDÇDĞDâDûDEE)Eå„ |¾ ¾ à ë ò ú ı ı ␍!!!!"!)!/!5!;!B!H!Y!Y![!d!p!v!›!Ÿ!¢!²!º!¿!¿!Æ!Ï!à!æ!ï!ú! " """#"*"1"9"?"A"O"f"i"x"…"’"’"’"’"˜"ª"³"Ä"å"ö"## #'#.#.#7#>#J#Z#e#e#e#y#�#�# #[$æ„9ú7ú78%8,808F8s8‰8š8£8±8Ã8Ü8Ü8î8999 9çX{Í––ÁËŞéû  '/EM`u…�‘¡±ºÀÅÌÒØŞéô÷ş :O\_gk}Œ“›Ó×àçù )@NTXZgggi€††˜è 
XˆXˆaˆuˆzˆé¤¢Çggƒ‰› ¦©­­ĞÕ€î€*€€9€O€;€^€f€k€q€t€x€z€“€€¢€¢€¢€½€ì€ø€ê˜Ìîââëææúõ ""11@@OO^^m�|‹‹š©¸#ëxËåwdwd•d§d­d¹dĞdĞdâdèdódeeee$e/e=eJeVedesese£eìd§¼çíçíëíşíşíî î+î+îBîBîYîYîpîpî‡î‡î�î î î¤îíÌÂñ÷÷ +AAS^rv{�‡™¥º¼Õäèèèû",7EL[]v��¢îP1A0E0EFEREZE^EoE}EƒE�E—E¢E¨E«EµEï ®- > >9>D>H>Q>X>_>u>†>—>©>»>Ê>Ù>ê>ù>ù>??␍??!?*?1?5?U?U?U?U?U?a?e?h?p?~?†?“?›?£?´?¿?Ä?Ä?Ñ?×?æ?ı?ÿ?
@@"@%@+@'@?@V@X@f@h@s@y@y@�@�@“@š@°@°@°@µ@µ@Í@Û@æ@ë@ë@î@ó@ó@A A-A/A/A3A5A5ATAbAnApApAsAuAuA‚A„A„A‡A‡A‡A‡A‡A�A–AšA¦AÆAÓAáAèA°Bğ(rxX‹X‹f‹m‹}‹€‹†‹ñ(ntZ&Z&c&m&~&‰&‰&§&òTPôô,ô2ô5ô>ôHô`ôpôyôô‚ô†ôˆô ô°ô½ôÃôÇôÍôÏôÒôÖôÖôùôıôõõ
õ1õFõYõlõrõyõ„õ�õ’õ•õœõ¢õ¦õ¬õ½õÃõÈõÍõÚõÜõîõğõ÷õööööööö<öGöSöjöjöö‹ö¨öÌöæöëö÷÷÷,÷1÷7÷H÷]÷c÷s÷€÷”÷›÷§÷¿÷Ë÷Ë÷Ë÷Ñ÷Ô÷×÷ğ÷ö÷
øøø ø ø%ø2ø?ø?øEøSøjøpøsøvø}ø†ø�ø�ø’øŸø¬ø¬ø²øÀø×øİøàøãøêøêøûøùùùù#ù-ù4ù:ùAùLù`ù`ùzùù†ù�ù•ù¥ù©ù²ùÊùÏùÖùøùú úú*ú>ú>úYúYúsú�úˆú�ú±úÄúèúêúôúûûû/û;ûLûkûoûDüóÀ€¬ï^ï^_ __ _*_6_W_8_f_k_k_�_Á_¤_—_ä_é_``#`D`%`S`X`q`x`›`±`±`×`×`ã`ô 00060<0õ4‘šçOçOÿO"P/P5P;P>P^Pö8 ê.ê.ø.ÿ.
/// /%/%/+/÷ :>11!1)1.1øĞSçuçuvv v6vSvbv†v´vºvÀvÈvÊvÒvçvêvõvww4wCwgw•w›w¡w©w®w¶wËwÎwÙwåwêwğwöwşwxxx6xDxrxxx}x…x•x—x»xéxïxôxôxyyy8yPy\ydyryrywyŠy¡y£yÀyØyäyìyúyúyÿyz z)z@zYzrz„z‘z³zÊzãzñzóz
{ { {){5{K{d{w{‚{•{™{™{™{ {¥{¸{Ã{İ{ß{ä{÷{||||+|ù€k˜:˜:®:º:º:Ğ:Û:İ:ı:ı:ı:;;;;;;";&;<;<;r;~;�; ;·;¼;¿;Ä;Ä;Ä;à;ç;ô;û;<<<$<0<8<=<=<Y<e<n<v<~<Š< <«<Î<Ò<à<è<í<í< =#=-=9=A=F=F=e=q=ƒ=ˆ=¤=°=¿=Ä=Ó=à=å=å=å=å=è=í=í=í= >>*>,>/>4>4>4>>>F>M>U>^>i>o>|>Š>Š>”>�>¥>Ú>à>ç>ö>???(?0?0?2?2?7?7?>?D?H?O?S?S?S?S?b?b?‡?�?�?”?¯Cú(°C°C¾CÇCÕCÛCû�°Ğßkßkıkll'l<lJlUldljljljloltl‚l�l¦l¨l­l»lÆlÓlÚlèlü\=P,,!,F,(,U,q,g,‰,�,‹,­,Æ,Ø,ñ,ñ,ø,--$-ı8fp'N'N?NNNbNqNwN}N€N Nş0�—PŒPŒdŒpŒ~Œ�Œ™ŒœŒ¤Œÿ0S[�Ø�آتطØÁØÔØP>NЉЉ܉ğ‰ó‰ŠŠŠŠ'Š/Š2Š8ŠT¡²�P�P©P¼P¿PÉPÖPëPíPÿP QQQ#Q&QzQ<˜£¨Œ¨Œ¼ŒÃŒÏŒÛŒëŒğŒóŒ÷ŒÿŒ 26FæFæTæ`æH!/—Z—Z«Z·ZÍZ¹ZÜZŞZåZğZüZ[D>‹ T TATLTQTYTsTzT|T|T˜T�T T«T²T²T¶TÅTÎTÖTßTçTîTõTùTUUUUU2U6ULU_UeUyU~U‹U‹UŸUªU±UºUÈUÑUôUúUşUVV VVV&V/VCVJV\VpVwVwV~V�VÓVläû&ä&ä:äPä^äiämätäxä�ä�ä’ä’ä¦ä¨ä±ä·ä·ä·ä·ä¿ä´EnÀEÀEæE÷EüEF␍F␍FF(F,F1FFFHFKFOFVFjFnFvF‚F‰F�F•F—FŸF­FµF·FºFÓFÛFãFñFõFG %I÷r÷rss s/sGsMs[slsts{s”sÁsÛsèsõst t␍tt@tGtMt[tctyt„tŠt�t³t BÂjj*j-j4j?jNjPj[jjjjjwj…jˆjŠjŠj�j”j�j¨j®j·jÊjÏjäjïjùjùjkk<kFkPkgkmkrkykk†k‹k‹k‘k—kœkœk¯k½kËkÕkÛkàkêkôkşklll"l=lClHlHlslxlxl£lÊlÏlÏlÏlÒlÙlßlælëlëlñl÷lülülmm'm-m;mPmVmfmrmxm†m�m�m™m£m©m°m°m²m²m²m·m½mÂmÆmÈmËmÖmåmèmêmîmîmómómn+n
˜}Ÿ^$^$z$$†$�$–$¡$±$¹$Á$Æ$Ñ$Û$á$ì$ü$%%%#%+%3%;%@%K%Y%Y%o% $bß<ß<÷<ş<=9=D=Q=_=S=ˆ=ˆ=”=œ=«=å=ç=>>>Q>i>V>Š>x>™>Ÿ>®>Ã>Å>Ğ>Ø>Ø>ù>ş>???9?&?n?T?H?}?š?…?º?Ò?¿?ô?á?@@$@6@,@M@M@M@T@v@v@‚@ Ğ1ø’ø’ “ “2“2“R“V“[“[“[“g“l“|“�“�“�“†“†“Ÿ“¦“µ“Ó̓ܓå“ç“ç“ç“ç“î“õ“ü“”
””” ” ”!”!”'”,”3•␍D$_r_rmrwr�r‘r–rŸr«r­r¿r¿rÁrñr
+46
View File
@@ -0,0 +1,46 @@
#exe {
Cd(__DIR__);;
Option(OPTf_WARN_PAREN,ON);
Option(OPTf_WARN_DUP_TYPES,ON);
Option(OPTf_KEEP_PRIVATE,ON);
}
#include "/Kernel/KernelA.HH"
#include "/Compiler/CompilerA.HH"
#exe {Option(OPTf_EXTERNS_TO_IMPORTS,ON);};
#include "/Kernel/KernelB.HH"
#include "/Kernel/KernelC.HH"
#exe {Option(OPTf_EXTERNS_TO_IMPORTS,OFF);};
#exe {Option(OPTf_KEEP_PRIVATE,OFF);};
#include "Templates"
#include "CExts"
CCmpGlbls cmp;
#include "CInit"
#include "CExcept"
#include "LexLib"
#include "Lex"
CUAsmGlbls uasm;
#include "CHash"
#include "UAsm"
#include "PrsLib"
#include "AsmInit"
#include "AsmLib"
#include "AsmResolve"
#include "Asm"
#include "OptLib"
#include "PrsExp"
#include "PrsVar"
#include "CMisc"
#include "CMain"
#include "PrsStmt"
#include "OptPass012"
#include "OptPass3"
#include "OptPass4"
#include "OptPass5"
#include "OptPass6"
#include "BackLib"
#include "BackFA"
#include "BackFB"
#include "BackA"
#include "BackB"
#include "BackC"
#include "OptPass789A"
+406
View File
@@ -0,0 +1,406 @@
#help_index "Compiler/Internal"
//Intermediate compiler codes
#define IS_0_ARG 0
#define IS_1_ARG 1
#define IS_2_ARG 2
#define IS_V_ARG 3 //Variable Arg Cnt
#define IST_NULL 0
#define IST_DEREF 1
#define IST_ASSIGN 2
#define IST_CMP 3
class CIntermediateStruct
{
U8 arg_cnt,res_cnt,type;
Bool fpop,not_const,pad[3];
U8 *name;
};
#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_I64 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_EQU_EQU 0x3A
#define IC_NOT_EQU 0x3B
#define IC_LESS 0x3C
#define IC_GREATER_EQU 0x3D
#define IC_GREATER 0x3E
#define IC_LESS_EQU 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_EQU 0x47
#define IC_SHR_EQU 0x48
#define IC_MUL_EQU 0x49
#define IC_DIV_EQU 0x4A
#define IC_MOD_EQU 0x4B
#define IC_AND_EQU 0x4C
#define IC_OR_EQU 0x4D
#define IC_XOR_EQU 0x4E
#define IC_ADD_EQU 0x4F
#define IC_SUB_EQU 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_PUSH 0x62
#define IC_POP 0x63
#define IC_CLFLUSH 0x64
#define IC_INVLPG 0x65
#define IC_IN_U8 0x66
#define IC_IN_U16 0x67
#define IC_IN_U32 0x68
#define IC_OUT_U8 0x69
#define IC_OUT_U16 0x6A
#define IC_OUT_U32 0x6B
#define IC_GET_RFLAGS 0x6C
#define IC_CARRY 0x6D
#define IC_SET_RFLAGS 0x6E
#define IC_GET_RAX 0x6F
#define IC_SET_RAX 0x70
#define IC_GET_RBP 0x71
#define IC_SET_RBP 0x72
#define IC_GET_RSP 0x73
#define IC_SET_RSP 0x74
#define IC_RIP 0x75
#define IC_RDTSC 0x76
#define IC_BT 0x77
#define IC_BTS 0x78
#define IC_BTR 0x79
#define IC_BTC 0x7A
#define IC_LBTS 0x7B
#define IC_LBTR 0x7C
#define IC_LBTC 0x7D
#define IC_BSF 0x7E
#define IC_BSR 0x7F
#define IC_QUE_INIT 0x80
#define IC_QUE_INS 0x81
#define IC_QUE_INS_REV 0x82
#define IC_QUE_REM 0x83
#define IC_STRLEN 0x84
#define IC_BR_ZERO 0x85
#define IC_BR_NOT_ZERO 0x86
#define IC_BR_CARRY 0x87
#define IC_BR_NOT_CARRY 0x88
#define IC_BR_EQU_EQU 0x89
#define IC_BR_NOT_EQU 0x8A
#define IC_BR_LESS 0x8B
#define IC_BR_GREATER_EQU 0x8C
#define IC_BR_GREATER 0x8D
#define IC_BR_LESS_EQU 0x8E
#define IC_BR_EQU_EQU2 0x8F
#define IC_BR_NOT_EQU2 0x90
#define IC_BR_LESS2 0x91
#define IC_BR_GREATER_EQU2 0x92
#define IC_BR_GREATER2 0x93
#define IC_BR_LESS_EQU2 0x94
#define IC_BR_AND_ZERO 0x95
#define IC_BR_AND_NOT_ZERO 0x96
#define IC_BR_MM_ZERO 0x97
#define IC_BR_MM_NOT_ZERO 0x98
#define IC_BR_AND_AND_ZERO 0x99
#define IC_BR_AND_AND_NOT_ZERO 0x9A
#define IC_BR_OR_OR_ZERO 0x9B
#define IC_BR_OR_OR_NOT_ZERO 0x9C
#define IC_BR_BT 0x9D
#define IC_BR_BTS 0x9E
#define IC_BR_BTR 0x9F
#define IC_BR_BTC 0xA0
#define IC_BR_NOT_BT 0xA1
#define IC_BR_NOT_BTS 0xA2
#define IC_BR_NOT_BTR 0xA3
#define IC_BR_NOT_BTC 0xA4
#define IC_SWAP_U8 0xA5
#define IC_SWAP_U16 0xA6
#define IC_SWAP_U32 0xA7
#define IC_SWAP_I64 0xA8
#define IC_ABS_I64 0xA9
#define IC_SIGN_I64 0xAA
#define IC_MIN_I64 0xAB
#define IC_MIN_U64 0xAC
#define IC_MAX_I64 0xAD
#define IC_MAX_U64 0xAE
#define IC_MOD_U64 0xAF
#define IC_SQR_I64 0xB0
#define IC_SQR_U64 0xB1
#define IC_SQR 0xB2
#define IC_ABS 0xB3
#define IC_SQRT 0xB4
#define IC_SIN 0xB5
#define IC_COS 0xB6
#define IC_TAN 0xB7
#define IC_ATAN 0xB8
#define IC_ICS_NUM 0xB9
#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_START 21
#define KW_END 22
#define KW_CASE 23
#define KW_DFT 24
#define KW_PUBLIC 25
#define KW_OFFSET 26
#define KW_IMPORT 27
#define KW__IMPORT 28
#define KW_IFDEF 29
#define KW_IFNDEF 30
#define KW_IFAOT 31
#define KW_IFJIT 32
#define KW_ENDIF 33
#define KW_ASSERT 34
#define KW_REG 35
#define KW_NOREG 36
#define KW_LASTCLASS 37
#define KW_NO_WARN 38
#define KW_HELP_INDEX 39
#define KW_HELP_FILE 40
#define KW_STATIC 41
#define KW_LOCK 42
#define KW_DEFINED 43
#define KW_INTERRUPT 44
#define KW_HASERRCODE 45
#define KW_ARGPOP 46
#define KW_NOARGPOP 47
#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_KWS_NUM 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_EQU 0x05
#define CMP_TEMPLATE_GREATER_EQU 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_SQR 0x0C
#define CMP_TEMPLATE_ABS 0x0D
#define CMP_TEMPLATE_SQRT 0x0E
#define CMP_TEMPLATE_SIN 0x0F
#define CMP_TEMPLATE_COS 0x10
#define CMP_TEMPLATE_TAN 0x11
#define CMP_TEMPLATE_ATAN 0x12
#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__ 0x08
#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 PRS1B__EXTERN_IMPORT 5
#define PRS1_NOT_REALLY__EXTERN 0x000500
#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
#help_index ""
+78
View File
@@ -0,0 +1,78 @@
#help_index "Compiler"
extern U0 CInit(Bool first);
public extern I64 ExeFile(U8 *name,I64 ccf_flags=0);
public extern I64 ExeFile2(U8 *name,I64 ccf_flags=0);
public extern I64 ExePrint(U8 *fmt,...);
public extern I64 ExePrint2(U8 *fmt,...);
public extern I64 ExePutS(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0,
CLexHashTableContext *htc=NULL);
public extern I64 ExePutS2(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0);
public _extern _LAST_FUN I64 LastFun(I64 argc,I64 *argv);
public extern I64 RunFile(U8 *name,I64 ccf_flags=0,...);
public extern I64 RunFile2(U8 *name,I64 ccf_flags=0,...);
public extern CCmpGlbls cmp;
#help_index "Compiler/Directive"
#help_file "::/Doc/Directives"
public extern Bool Echo(Bool val);
public extern Bool GetOption(I64 num);
public extern I64 PassTrace(I64 i=0b1001111101);
extern U0 StreamDir();
public extern I64 StreamExePrint(U8 *fmt,...);
public extern U0 StreamPrint(U8 *fmt,...);
public extern Bool Trace(Bool val=ON);
#help_index "Compiler/Lex"
#help_file "::/Doc/Lex"
extern U0 ClassMemberLstDel(CHashClass *c);
public extern U0 CmpCtrlDel(CCmpCtrl *cc);
public extern CCmpCtrl *CmpCtrlNew(U8 *buf=NULL,I64 flags=0,U8 *filename=NULL);
public extern I64 CmpCtrlSize(CCmpCtrl *cc);
public extern I64 IsLexExpression2Bin(
CCmpCtrl *cc,U8 **machine_code); //FALSE=no err
public extern I64 Lex(CCmpCtrl *cc);
public extern U0 LexAttachDoc(CCmpCtrl *cc,CLexFile *tmpf=NULL,
CDoc *doc=NULL,U8 *abs_filename=NULL,CDocEntry *doc_e=NULL,I64 col=0);
public extern CD2I32 *LexD2I32(CCmpCtrl *cc,CD2I32 *p);
public extern CD3I32 *LexD3I32(CCmpCtrl *cc,CD3I32 *p);
public extern U0 LexExcept(CCmpCtrl *cc,U8 *str=NULL);
public extern I64 LexExpression(CCmpCtrl *cc);
public extern U8 *LexExpression2Bin(CCmpCtrl *cc,I64 *_type=NULL);
public extern F64 LexExpressionF64(CCmpCtrl *cc);
public extern I64 LexExpressionI64(CCmpCtrl *cc);
public extern U8 *LexExtStr(CCmpCtrl *cc,I64 *_size=NULL,Bool lex_next=TRUE);
public extern U8 *LexFirstRem(CCmpCtrl *cc,U8 *marker,I64 _len=NULL);
public extern I64 LexGetChar(CCmpCtrl *cc);
public extern U0 LexPopNoRestore(CCmpCtrl *cc);
public extern U0 LexPopRestore(CCmpCtrl *cc);
public extern U0 LexPush(CCmpCtrl *cc);
public extern U0 LexPutLine(CCmpCtrl *cc,U8 *start);
public extern U0 LexPutPos(CCmpCtrl *cc);
public extern U0 LexPutToken(CCmpCtrl *cc);
public extern U0 LexSkipEol(CCmpCtrl *cc);
public extern U8 *LexStmt2Bin(
CCmpCtrl *cc,I64 *_type,I64 cmp_flags=CMPF_PRS_SEMICOLON);
public extern U0 LexWarn(CCmpCtrl *cc,U8 *str=NULL);
extern CMemberLst *MemberClassBaseFind(
CHashClass *needle_class,CHashClass *haystack_class);
public extern CMemberLst *MemberFind(U8 *needle_str,CHashClass *haystack_class);
extern U0 MemberLstDel(CMemberLst *tmpm);
public extern I64 MemberMetaData(U8 *st,CMemberLst *ml);
public extern CMemberLstMeta *MemberMetaFind(U8 *st,CMemberLst *ml);
public extern CHashClass *OptClassFwd(CHashClass *tmpc);
public extern I64 PrsKeyWord(CCmpCtrl *cc);
#help_index "Compiler;Cmd Line (Typically)"
extern I64 Cmp(U8 *filename,
U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv_let=0);
#help_index "Debugging/Unassemble"
public extern U8 *U(U8 *rip,I64 cnt=20,I64 seg_size=64);
public extern U0 Ui(U8 *buf,U8 **_rip,I64 seg_size=64,
I64 *_jmp_dst=NULL,Bool just_ins=FALSE);
public extern I64 Un(U8 *rip,I64 cnt=0x80,I64 seg_size=64);
extern CUAsmGlbls uasm;
#help_index "Hash/System"
public extern I64 HashEntrySize(CHashSrcSym *tmph);
public extern I64 HashEntrySize2(CHashSrcSym *tmph);
public extern I64 HashTableSize2(CHashTable *table);
File diff suppressed because it is too large. Load diff
+275
View File
@@ -0,0 +1,275 @@
U0 LexBackupLastChar(CCmpCtrl *cc)
{
CLexFile *tmpf=cc->lex_include_stk;
tmpf->buf_ptr=cc->cur_buf_ptr;
if (cc->flags & CCF_USE_LAST_U16) {
tmpf->last_U16=cc->last_U16;
cc->flags&=~CCF_USE_LAST_U16;
} else
tmpf->last_U16=0;
}
U0 LexPush(CCmpCtrl *cc)
{//Create token-stream save point.
CLexFile *tmpf;
LexBackupLastChar(cc);
if (cc->lex_include_stk->last_U16)
cc->flags|=CCF_USE_LAST_U16;
tmpf=MAllocIdent(cc->lex_include_stk);
tmpf->next=cc->lex_prs_stk;
cc->lex_prs_stk=tmpf;
}
U0 LexPopRestore(CCmpCtrl *cc)
{//Restore token-stream saved-point.
//Bad things can happen if you cross an #include file boundary.
CLexFile *tmpf=cc->lex_prs_stk;
cc->cur_buf_ptr=tmpf->buf_ptr;
if (cc->last_U16=tmpf->last_U16)
cc->flags|=CCF_USE_LAST_U16;
else
cc->flags&=~CCF_USE_LAST_U16;
MemCpy(cc->lex_include_stk(U8 *)+sizeof(U8 *),tmpf(U8 *)+sizeof(U8 *),
sizeof(CLexFile)-sizeof(U8 *));
cc->lex_prs_stk=tmpf->next;
Free(tmpf);
}
U0 LexPopNoRestore(CCmpCtrl *cc)
{//Don't restore token-stream saved-point.
CLexFile *tmpf=cc->lex_prs_stk;
cc->lex_prs_stk=tmpf->next;
Free(tmpf);
}
I64 MemberMetaData(U8 *needle_str,CMemberLst *haystack_member_lst)
{//Find meta data name, return meta data val. See $LK,"::/Demo/ClassMeta.HC"$.
CMemberLstMeta *meta=haystack_member_lst->meta;
while (meta) {
if (!StrCmp(meta->str,needle_str))
return meta->user_data;
meta=meta->next;
}
return 0;
}
CMemberLstMeta *MemberMetaFind(U8 *needle_str,CMemberLst *haystack_member_lst)
{//Find meta data name, return meta data struct. See $LK,"::/Demo/ClassMeta.HC"$.
CMemberLstMeta *meta=haystack_member_lst->meta;
while (meta) {
if (!StrCmp(meta->str,needle_str))
return meta;
meta=meta->next;
}
return NULL;
}
CMemberLst *MemberFind(U8 *needle_str,CHashClass *haystack_class)
{//Find class member. See $LK,"ClassRep",A="MN:ClassRep"$() and $LK,"DocForm",A="MN:DocForm"$().
I64 i;
CMemberLst *tmpm;
do {
tmpm=haystack_class->member_lst_and_root;
while (tmpm) {
if (!(i=StrCmp(tmpm->str,needle_str))) {
tmpm->use_cnt++;
return tmpm;
}
if (i<=0)
tmpm=tmpm->left;
else
tmpm=tmpm->right;
}
} while (haystack_class=haystack_class->base_class);
return NULL;
}
CMemberLst *MemberClassBaseFind(CHashClass *needle_class,
CHashClass *haystack_class)
{//Find class member class base. For finding dup class local vars.
CMemberLst *tmpm;
tmpm=haystack_class->member_class_base_root;
while (tmpm) {
if (needle_class==tmpm->member_class_base)
return tmpm;
if (needle_class<tmpm->member_class_base)
tmpm=tmpm->left_class_base;
else
tmpm=tmpm->right_class_base;
}
return NULL;
}
U0 MemberAdd(CCmpCtrl *cc,CMemberLst *tmpm,CHashClass *tmpc,I64 mode)
{
U8 *st=tmpm->str;
CMemberLst **tmpm1,*tmpm2;
if (MemberFind(st,tmpc) && StrCmp(st,"pad") &&
StrCmp(st,"reserved") && StrCmp(st,"_anon_"))
LexExcept(cc,"Duplicate member at ");
tmpm1=&tmpc->member_lst_and_root;
while (tmpm2=*tmpm1) {
if (StrCmp(tmpm2->str,st)<=0)
tmpm1=&tmpm2->left;
else
tmpm1=&tmpm2->right;
}
*tmpm1=tmpm;
if (mode==PRS1B_LOCAL_VAR) {
tmpm->member_class_base=
tmpm->member_class-tmpm->member_class->ptr_stars_cnt;
if (Bt(&cc->opts,OPTf_WARN_DUP_TYPES) &&
MemberClassBaseFind(tmpm->member_class_base,tmpc))
LexWarn(cc,"Duplicate type at ");
tmpm1=&tmpc->member_class_base_root;
while (tmpm2=*tmpm1) {
if (tmpm->member_class_base<tmpm2->member_class_base)
tmpm1=&tmpm2->left_class_base;
else if (tmpm->member_class_base>tmpm2->member_class_base)
tmpm1=&tmpm2->right_class_base;
else {
tmpm1=NULL;
break;
}
}
if (tmpm1)
*tmpm1=tmpm;
} else
tmpm->member_class_base=NULL;
tmpm->left=NULL;
tmpm->right=NULL;
tmpm->left_class_base=NULL;
tmpm->right_class_base=NULL;
tmpm2=tmpc->last_in_member_lst;
tmpm2->next=tmpc->last_in_member_lst=tmpm;
}
CMemberLst *MemberLstNew(I64 _reg)
{
CMemberLst *res=CAlloc(sizeof(CMemberLst));
res->reg=_reg;
return res;
}
Bool MemberLstCmp(CMemberLst *tmpm1,CMemberLst *tmpm2,I64 cnt=I64_MAX)
{
while (tmpm1 && tmpm2 && cnt--) {
if (StrCmp(tmpm1->str,tmpm2->str) ||
tmpm1->member_class!=tmpm2->member_class ||
tmpm1->member_class_base!=tmpm2->member_class_base)
return FALSE;
if (tmpm1->flags&MLF_DFT_AVAILABLE || tmpm2->flags&MLF_DFT_AVAILABLE) {
if (tmpm1->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE)!=
tmpm2->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE))
return FALSE;
if (tmpm1->flags&MLF_STR_DFT_AVAILABLE) {
if (StrCmp(tmpm1->dft_val,tmpm2->dft_val))
return FALSE;
} else if (tmpm1->dft_val!=tmpm2->dft_val)
return FALSE;
}
tmpm1=tmpm1->next;
tmpm2=tmpm2->next;
}
if (cnt<0 || !tmpm1 && !tmpm2)
return TRUE;
else
return FALSE;
}
U0 MemberLstDel(CMemberLst *tmpm)
{
CMemberLst *tmpm1;
CMemberLstMeta *tmp_meta,*tmp_meta1;
while (tmpm) {
tmpm1=tmpm->next;
Free(tmpm->str);
LinkedLstDel(tmpm->dim.next);
if (tmpm->flags & MLF_STR_DFT_AVAILABLE)
Free(tmpm->dft_val);
if (tmpm->flags & MLF_FUN)
HashDel(tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
tmp_meta=tmpm->meta;
while (tmp_meta) {
tmp_meta1=tmp_meta->next;
Free(tmp_meta->str);
if (tmp_meta->flags&MLMF_IS_STR)
Free(tmp_meta->user_data);
Free(tmp_meta);
tmp_meta=tmp_meta1;
}
Free(tmpm);
tmpm=tmpm1;
}
}
U0 ClassMemberLstDel(CHashClass *tmpc)
{
MemberLstDel(tmpc->member_lst_and_root);
tmpc->size=0;
tmpc->last_in_member_lst=&tmpc->member_lst_and_root;
tmpc->member_lst_and_root=NULL;
tmpc->member_class_base_root=NULL;
tmpc->member_cnt=0;
if (tmpc->type&HTT_FUN)
tmpc(CHashFun *)->arg_cnt=0;
}
I64 MemberLstSize(CHashClass *tmpc)
{
CMemberLst *tmpm;
CMemberLstMeta *tmp_meta;
I64 res=0;
tmpm=tmpc->member_lst_and_root;
while (tmpm) {
res+=MSize2(tmpm->str);
res+=LinkedLstSize(tmpm->dim.next);
if (tmpm->flags & MLF_STR_DFT_AVAILABLE)
res+=MSize2(tmpm->dft_val);
if (tmpm->flags & MLF_FUN)
res+=HashEntrySize2(tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
tmp_meta=tmpm->meta;
while (tmp_meta) {
res+=MSize2(tmp_meta->str);
if (tmp_meta->flags&MLMF_IS_STR)
res+=MSize2(tmp_meta->user_data);
res+=MSize2(tmp_meta);
tmp_meta=tmp_meta->next;
}
res+=MSize2(tmpm);
tmpm=tmpm->next;
}
return res;
}
U8 *LexExtStr(CCmpCtrl *cc,I64 *_size=NULL,Bool lex_next=TRUE)
{//Lex $LK,"TK_STR",A="MN:TK_STR"$'s to one combined str. _size includes terminator.
I64 len=cc->cur_str_len,len1,len2;
U8 *st=cc->cur_str,*st1,*st2;
cc->cur_str=NULL;
while (cc->token==TK_STR) {
st1=st;
len1=len;
if (!lex_next && LexGetChar(cc)!='\\') {
cc->flags|=CCF_USE_LAST_U16;
break;
}
if (Lex(cc)==TK_STR) {
len2=cc->cur_str_len;
st2=cc->cur_str;
cc->cur_str=NULL;
len=len1+len2-1;
st=MAlloc(len);
if (len1>1)
MemCpy(st,st1,len1-1);
MemCpy(st+len1-1,st2,len2);
Free(st1);
Free(st2);
}
}
if (_size) *_size=len;
return st;
}
File diff suppressed because it is too large. Load diff
+565
View File
@@ -0,0 +1,565 @@
CCodeMisc *OptLabelFwd(CCodeMisc *lb)
{
CCodeMisc *lb1;
while (lb1=lb->fwd)
lb=lb1;
return lb;
}
CHashClass *OptClassFwd(CHashClass *tmpc)
{//Class forwarding for unions and subclasses.
CHashClass *tmpc1;
while (tmpc1=tmpc->fwd_class)
tmpc=tmpc1;
return tmpc;
}
U0 OptSetNOP1(CIntermediateCode *tmpi)
{
tmpi->ic_code=IC_NOP1;
tmpi->ic_flags=0;
tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;
tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;
}
U0 OptSetNOP2(CIntermediateCode *tmpi,I64 stk_delta=1)
{
tmpi->ic_code=IC_NOP2;
tmpi->ic_data=stk_delta;
tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;
tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;
}
CIntermediateCode *OptFree(CIntermediateCode *tmpi)
{//We might access freed entries in CICTreeLinks
QueRem(tmpi);
Free(tmpi);
return NULL;
}
CIntermediateCode *OptLag(CIntermediateCode *tmpi)
{
do {
if (!tmpi->ic_code)
return NULL;
else
tmpi=tmpi->last;
} while (tmpi->ic_code<=IC_END_EXP);
return tmpi;
}
CIntermediateCode *OptLag1(CIntermediateCode *tmpi)
{
do {
if (!tmpi->ic_code)
return NULL;
else
tmpi=tmpi->last;
} while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);
return tmpi;
}
CIntermediateCode *OptLag2(CIntermediateCode *tmpi)
{
do {
if (!tmpi->ic_code)
return NULL;
else
tmpi=tmpi->last;
} while (tmpi->ic_code<IC_END_EXP);
return tmpi;
}
CIntermediateCode *OptLead1(CIntermediateCode *tmpi)
{
do {
tmpi=tmpi->next;
if (!tmpi->ic_code)
return NULL;
} while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);
return tmpi;
}
I64 CmpOffset2Reg(I64 offset,COptReg *reg_offsets)
{
I64 i;
for (i=0;i<REG_REGS_NUM;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 *tmpi,
CIntermediateCode *tmpi1,CIntermediateCode *tmpi2,
Bool *is_unsigned)
{
CIntermediateCode *tmpii;
CHashClass *tmpc=tmpi->ic_class,*tmpc1,*tmpc2;
if (tmpi1->ic_flags&ICF_RES_TO_INT)
tmpc1=cmp.internal_types[RT_I64];
else if (tmpi1->ic_flags&ICF_RES_TO_F64)
tmpc1=cmp.internal_types[RT_F64];
else {
tmpc1=OptClassFwd(tmpi1->ic_class);
}
if (tmpi2->ic_flags&ICF_RES_TO_INT)
tmpc2=cmp.internal_types[RT_I64];
else if (tmpi2->ic_flags&ICF_RES_TO_F64)
tmpc2=cmp.internal_types[RT_F64];
else {
tmpc2=OptClassFwd(tmpi2->ic_class);
}
if (tmpc1->raw_type>tmpc2->raw_type)
tmpc=tmpi->ic_class=tmpc1;
else
tmpc=tmpi->ic_class=tmpc2;
if (tmpc->raw_type==RT_F64) {
if (tmpi1->ic_code==IC_IMM_I64) {
tmpi1->ic_data(F64)=tmpi1->ic_data;
tmpi1->ic_class=cmp.internal_types[RT_F64];
tmpi1->ic_code=IC_IMM_F64;
tmpi1->ic_flags&=~ICF_RES_TO_F64;
} else
if (tmpc1->raw_type!=RT_F64)
tmpi1->ic_flags|=ICF_RES_TO_F64;
if (tmpi2->ic_code==IC_IMM_I64) {
tmpi2->ic_data(F64)=tmpi2->ic_data;
tmpi2->ic_class=cmp.internal_types[RT_F64];
tmpi2->ic_code=IC_IMM_F64;
tmpi2->ic_flags&=~ICF_RES_TO_F64;
} else
if (tmpc2->raw_type!=RT_F64)
tmpi2->ic_flags|=ICF_RES_TO_F64;
if (IC_LESS<=tmpi->ic_code<=IC_GREATER_EQU && (tmpii=OptLead1(tmpi)) &&
tmpii->ic_code!=IC_PUSH_CMP && tmpii->ic_code!=IC_AND_AND) {
//We are looking for float comparisons to zero to convert to int.
if (tmpi1->ic_code==IC_IMM_F64 && !tmpi1->ic_data &&
tmpi2->ic_code==IC_DEREF && tmpc2==cmp.internal_types[RT_F64]) {
tmpi1->ic_code==IC_IMM_I64;
goto fb_here1;
} else if (tmpi2->ic_code==IC_IMM_F64 && !tmpi2->ic_data &&
tmpi1->ic_code==IC_DEREF && tmpc1==cmp.internal_types[RT_F64]) {
tmpi2->ic_code==IC_IMM_I64;
fb_here1:
tmpi1->ic_flags&=~ICF_RES_TO_F64;
tmpi->ic_class=tmpi1->ic_class=tmpi2->ic_class=
cmp.internal_types[RT_I64];
*is_unsigned=FALSE;
return FBO1_NOT_CONST;
}
goto fb_here2;
} else {
fb_here2:
if (tmpi1->ic_code==IC_IMM_F64 && tmpi2->ic_code==IC_IMM_F64 &&
!(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
OptSetNOP1(tmpi1);
OptSetNOP1(tmpi2);
return FBO1_F64;
} else
return FBO1_NOT_CONST;
}
}
*is_unsigned=tmpc1->raw_type&RTF_UNSIGNED || tmpc2->raw_type&RTF_UNSIGNED;
if (tmpi1->ic_code==IC_IMM_I64 && tmpi2->ic_code==IC_IMM_I64 &&
!(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
OptSetNOP1(tmpi1);
OptSetNOP1(tmpi2);
return FBO1_INT;
} else
return FBO1_NOT_CONST;
}
Bool OptFixupBinaryOp2(CIntermediateCode **tmpi1,CIntermediateCode **tmpi2)
{
CIntermediateCode *tmpii1=*tmpi1,
*tmpii2=*tmpi2;
if (tmpii1->ic_code==IC_IMM_I64 && !(tmpii1->ic_flags & ICF_RES_TO_F64))
return TRUE;
if (tmpii2->ic_code==IC_IMM_I64 && !(tmpii2->ic_flags & ICF_RES_TO_F64)) {
*tmpi1=tmpii2;
*tmpi2=tmpii1;
return TRUE;
}
return FALSE;
}
Bool OptFixupUnaryOp(CIntermediateCode *tmpi, CIntermediateCode *tmpi1,
Bool *is_unsigned)
{
CHashClass *tmpc,*tmpc1;
tmpc1=OptClassFwd(tmpi1->ic_class);
tmpi->ic_class=tmpc1;
tmpc=tmpi->ic_class;
if (tmpc->raw_type==RT_F64) {
if (tmpi1->ic_code==IC_IMM_I64) {
tmpi1->ic_data(F64)=tmpi1->ic_data;
tmpi1->ic_class=cmp.internal_types[RT_F64];
tmpi1->ic_code=IC_IMM_F64;
tmpi1->ic_flags&=~ICF_RES_TO_F64;
} else
if (tmpc1->raw_type!=RT_F64)
tmpi1->ic_flags|=ICF_RES_TO_F64;
if (tmpi1->ic_code==IC_IMM_F64) {
tmpi->ic_flags|=tmpi1->ic_flags;
OptSetNOP1(tmpi1);
return FBO1_F64;
} else
return FBO1_NOT_CONST;
}
*is_unsigned=tmpc1->raw_type&RTF_UNSIGNED;
if (tmpi1->ic_code==IC_IMM_I64) {
tmpi->ic_flags|=tmpi1->ic_flags;
OptSetNOP1(tmpi1);
return FBO1_INT;
} else
return FBO1_NOT_CONST;
}
extern CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi);
CIntermediateCode *OptBrZero(CCmpCtrl *cc,CIntermediateCode *tmpi)
{
CCodeMisc *lb_true,*lb_false;
CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;
switch (tmpii->ic_code) {
case IC_NOT:
tmpi->ic_code=IC_BR_NOT_ZERO;
tmpi->ic_class=tmpii->ic_class;
tmpi->ic_flags|=tmpii->ic_flags;
tmpi->t.arg1_class=tmpii->t.arg1_class;
tmpi->t.arg1_tree=tmpii->t.arg1_tree;
OptFree(tmpii);
return OptBrNotZero(cc,tmpi);
case IC_EQU_EQU...IC_LESS_EQU:
tmpi->ic_code=(tmpii->ic_code-IC_EQU_EQU)^1+IC_BR_EQU_EQU;
break;
case IC_OR_OR:
tmpi->ic_code=IC_BR_OR_OR_ZERO;
break;
case IC_AND_AND:
tmpi->ic_code=IC_BR_AND_AND_ZERO;
break;
case IC_AND:
tmpi->ic_code=IC_BR_AND_ZERO;
break;
case IC_MM_:
if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&
tmpii->ic_class->raw_type!=RT_F64)
tmpi->ic_code=IC_BR_MM_ZERO;
break;
case IC_CALL_END:
tmpii2=OptLag(tmpii);
switch (tmpii2->ic_code) {
start:
case IC_CARRY:
tmpii2->ic_code=IC_BR_NOT_CARRY;
break;
case IC_BT:
tmpii2->ic_code=IC_BR_NOT_BT;
break;
case IC_LBTS:
tmpii2->ic_flags|=ICF_LOCK;
case IC_BTS:
tmpii2->ic_code=IC_BR_NOT_BTS;
break;
case IC_LBTR:
tmpii2->ic_flags|=ICF_LOCK;
case IC_BTR:
tmpii2->ic_code=IC_BR_NOT_BTR;
break;
case IC_LBTC:
tmpii2->ic_flags|=ICF_LOCK;
case IC_BTC:
tmpii2->ic_code=IC_BR_NOT_BTC;
break;
end:
tmpii2->ic_data=tmpi->ic_data;
tmpii->ic_code=IC_CALL_END2;
OptSetNOP1(tmpi);
return tmpii;
}
break;
}
if (tmpi->ic_code!=IC_BR_ZERO) {
tmpi->ic_class=tmpii->ic_class;
tmpi->ic_flags|=tmpii->ic_flags;
tmpi->t.arg1_class=tmpii->t.arg1_class;
tmpi->t.arg2_class=tmpii->t.arg2_class;
tmpi->t.arg1_tree=tmpii->t.arg1_tree;
tmpi->t.arg2_tree=tmpii->t.arg2_tree;
OptFree(tmpii);
if (tmpi->ic_flags&ICF_PUSH_CMP &&
IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&
!(tmpi->ic_flags&ICF_USE_F64)) {
tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;
tmpi->ic_flags&=~ICF_PUSH_CMP;
tmpii=tmpi->next; //IC_PUSH_CMP inst
while (tmpii->ic_code!=IC_PUSH_CMP)
tmpii=tmpii->next;
tmpii->t.arg1_tree=tmpi;
OptSetNOP1(tmpii);
}
lb_true=tmpi->ic_data;
if (tmpi->ic_code==IC_BR_AND_AND_ZERO) {
tmpii=tmpi->t.arg1_tree->next;
tmpii->ic_data=lb_true;
tmpii->t.arg1_tree=tmpi->t.arg1_tree;
tmpii->t.arg1_class=tmpi->t.arg1_class;
tmpii->ic_code=IC_BR_ZERO;
OptBrZero(cc,tmpii);
tmpii=tmpi->t.arg2_tree->next;
tmpii->t.arg1_tree=tmpi->t.arg2_tree;
tmpii->t.arg1_class=tmpi->t.arg2_class;
tmpii->ic_data=lb_true;
tmpii->ic_code=IC_BR_ZERO;
tmpii=OptBrZero(cc,tmpii);
OptSetNOP1(tmpi);
} else if (tmpi->ic_code==IC_BR_OR_OR_ZERO) {
lb_false=COCMiscNew(cc,CMT_LABEL);
tmpi->ic_code=IC_LABEL;
tmpi->ic_flags=0;
tmpi->ic_data=lb_false;
tmpii=tmpi->t.arg1_tree->next;
tmpii->t.arg1_tree=tmpi->t.arg1_tree;
tmpii->t.arg1_class=tmpi->t.arg1_class;
tmpii->ic_data=lb_false;
tmpii->ic_code=IC_BR_NOT_ZERO;
OptBrNotZero(cc,tmpii);
tmpii=tmpi->t.arg2_tree->next;
tmpii->t.arg1_tree=tmpi->t.arg2_tree;
tmpii->t.arg1_class=tmpi->t.arg2_class;
tmpii->ic_data=lb_true;
tmpii->ic_code=IC_BR_ZERO;
tmpii=OptBrZero(cc,tmpii);
} else
tmpii=tmpi;
if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {
tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;
tmpi->ic_flags&=~ICF_POP_CMP;
}
return tmpii;
}
return tmpi;
}
CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi)
{
CCodeMisc *lb_true,*lb_false;
CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;
switch (tmpii->ic_code) {
case IC_NOT:
tmpi->ic_code=IC_BR_ZERO;
tmpi->ic_class=tmpii->ic_class;
tmpi->ic_flags|=tmpii->ic_flags;
tmpi->t.arg1_class=tmpii->t.arg1_class;
tmpi->t.arg1_tree=tmpii->t.arg1_tree;
OptFree(tmpii);
return OptBrZero(cc,tmpi);
case IC_EQU_EQU...IC_LESS_EQU:
tmpi->ic_code=tmpii->ic_code+IC_BR_EQU_EQU-IC_EQU_EQU;
break;
case IC_OR_OR:
tmpi->ic_code=IC_BR_OR_OR_NOT_ZERO;
break;
case IC_AND_AND:
tmpi->ic_code=IC_BR_AND_AND_NOT_ZERO;
break;
case IC_AND:
tmpi->ic_code=IC_BR_AND_NOT_ZERO;
break;
case IC_MM_:
if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&
tmpii->ic_class->raw_type!=RT_F64)
tmpi->ic_code=IC_BR_MM_NOT_ZERO;
break;
case IC_CALL_END:
tmpii2=OptLag(tmpii);
switch (tmpii2->ic_code) {
start:
case IC_CARRY:
tmpii2->ic_code=IC_BR_CARRY;
break;
case IC_BT:
tmpii2->ic_code=IC_BR_BT;
break;
case IC_LBTS:
tmpii2->ic_flags|=ICF_LOCK;
case IC_BTS:
tmpii2->ic_code=IC_BR_BTS;
break;
case IC_LBTR:
tmpii2->ic_flags|=ICF_LOCK;
case IC_BTR:
tmpii2->ic_code=IC_BR_BTR;
break;
case IC_LBTC:
tmpii2->ic_flags|=ICF_LOCK;
case IC_BTC:
tmpii2->ic_code=IC_BR_BTC;
break;
end:
tmpii2->ic_data=tmpi->ic_data;
tmpii->ic_code=IC_CALL_END2;
OptSetNOP1(tmpi);
return tmpii;
}
break;
}
if (tmpi->ic_code!=IC_BR_NOT_ZERO) {
tmpi->ic_class=tmpii->ic_class;
tmpi->ic_flags|=tmpii->ic_flags;
tmpi->t.arg1_class=tmpii->t.arg1_class;
tmpi->t.arg2_class=tmpii->t.arg2_class;
tmpi->t.arg1_tree=tmpii->t.arg1_tree;
tmpi->t.arg2_tree=tmpii->t.arg2_tree;
OptFree(tmpii);
if (tmpi->ic_flags&ICF_PUSH_CMP &&
IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&
!(tmpi->ic_flags&ICF_USE_F64)) {
tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;
tmpi->ic_flags&=~ICF_PUSH_CMP;
tmpii=tmpi->next; //IC_PUSH_CMP inst
while (tmpii->ic_code!=IC_PUSH_CMP)
tmpii=tmpii->next;
tmpii->t.arg1_tree=tmpi;
OptSetNOP1(tmpii);
}
lb_true=tmpi->ic_data;
if (tmpi->ic_code==IC_BR_OR_OR_NOT_ZERO) {
tmpii=tmpi->t.arg1_tree->next;
tmpii->t.arg1_tree=tmpi->t.arg1_tree;
tmpii->t.arg1_class=tmpi->t.arg1_class;
tmpii->ic_data=lb_true;
tmpii->ic_code=IC_BR_NOT_ZERO;
OptBrNotZero(cc,tmpii);
tmpii=tmpi->t.arg2_tree->next;
tmpii->t.arg1_tree=tmpi->t.arg2_tree;
tmpii->t.arg1_class=tmpi->t.arg2_class;
tmpii->ic_data=lb_true;
tmpii->ic_code=IC_BR_NOT_ZERO;
tmpii=OptBrNotZero(cc,tmpii);
OptSetNOP1(tmpi);
} else if (tmpi->ic_code==IC_BR_AND_AND_NOT_ZERO) {
lb_false=COCMiscNew(cc,CMT_LABEL);
tmpi->ic_code=IC_LABEL;
tmpi->ic_flags=0;
tmpi->ic_data=lb_false;
tmpii=tmpi->t.arg1_tree->next;
tmpii->t.arg1_tree=tmpi->t.arg1_tree;
tmpii->t.arg1_class=tmpi->t.arg1_class;
tmpii->ic_data=lb_false;
tmpii->ic_code=IC_BR_ZERO;
OptBrZero(cc,tmpii);
tmpii=tmpi->t.arg2_tree->next;
tmpii->t.arg1_tree=tmpi->t.arg2_tree;
tmpii->t.arg1_class=tmpi->t.arg2_class;
tmpii->ic_data=lb_true;
tmpii->ic_code=IC_BR_NOT_ZERO;
tmpii=OptBrNotZero(cc,tmpii);
} else
tmpii=tmpi;
if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {
tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;
tmpi->ic_flags&=~ICF_POP_CMP;
}
return tmpii;
}
return tmpi;
}
U0 OptFixSizeOf(CIntermediateCode *tmpi1,
CIntermediateCode *tmpi_push,CHashClass *tmpcc)
{
if (tmpi1->ic_code==IC_MUL && tmpi1->t.arg2_tree->ic_code==IC_SIZEOF) {
tmpi1->t.arg2_tree->ic_code=IC_IMM_I64;
tmpi1->t.arg2_tree->ic_class=tmpcc;
tmpi_push->ic_class=tmpcc;
if (tmpcc->ptr_stars_cnt) {
tmpcc--;
if (tmpcc->size==1)
goto here;
tmpi1->t.arg2_tree->ic_data=tmpcc->size;
} else {
here:
if (tmpi_push==tmpi1)
tmpi1->t.arg2_tree->ic_data=1;
else {
OptSetNOP1(tmpi1->t.arg2_tree);
OptSetNOP1(tmpi1);
}
}
}
}
I64 CmpRawType(CHashClass *tmpc)
{
if (tmpc) {
tmpc=OptClassFwd(tmpc);
return tmpc->raw_type;
}
return 0;
}
I64 CmpRawTypePointed(CHashClass *tmpc)
{
if (tmpc) {
if (tmpc->ptr_stars_cnt)
tmpc--;
tmpc=OptClassFwd(tmpc);
return tmpc->raw_type;
}
return 0;
}
U0 CmpMinTypePointed(CIntermediateCode *tmpi,I64 pt1)
{
I64 pt;
if ((pt=tmpi->arg1_type_pointed_to) && pt!=RT_F64 && 0<pt1<pt)
tmpi->arg1_type_pointed_to=pt;
}
U0 CmpF1PushPop(CIntermediateCode *tmpi,CIntermediateCode *tmpi2)
{
if (intermediate_code_table[tmpi2->ic_code].fpop||
tmpi2->ic_flags&ICF_RES_TO_F64)
Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
}
U0 CmpF2PushPop(CIntermediateCode *tmpi,
CIntermediateCode *tmpi1,CIntermediateCode *tmpi2)
{
if ((tmpi2->ic_code==IC_MOV || tmpi2->ic_code==IC_IMM_F64) &&
!(tmpi2->ic_flags&ICF_RES_TO_F64) &&
(intermediate_code_table[tmpi1->ic_code].fpop ||
tmpi1->ic_flags&ICF_RES_TO_F64))
Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
else if ((intermediate_code_table[tmpi2->ic_code].fpop ||
tmpi2->ic_flags&ICF_RES_TO_F64)&&
!(tmpi1->ic_flags&ICF_RES_TO_F64))
Bts(&tmpi->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
+622
View File
@@ -0,0 +1,622 @@
U0 OptPass3(CCmpCtrl *cc,COptReg *reg_offsets)
{
CHashClass *tmpc,*tmpc1,*tmpc2;
CCodeMisc *lb;
CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpi_next,
*tmpil1,*tmpil2;
I64 code,i,j,l,member_cnt,used_reg_mask=0;
CMemberLst *tmpm;
COptMemberVar *mv=NULL;
CAOT *tmpaot;
CAOTImportExport *tmpie;
CPrsStk *ps=cc->ps;
ps->ptr=0;
ps->ptr2=0;
for (i=0;i<REG_REGS_NUM;i++) {
reg_offsets[i].offset=I64_MAX;
reg_offsets[i].m=NULL;
}
if (cc->htc.fun) {
member_cnt=cc->htc.fun->member_cnt;
if (Bt(&cc->htc.fun->flags,Ff_DOT_DOT_DOT))
member_cnt+=2;
mv=CAlloc(member_cnt*sizeof(COptMemberVar));
member_cnt=0;
tmpm=cc->htc.fun->member_lst_and_root;
while (tmpm) {
tmpc=OptClassFwd(tmpm->member_class);
if (0<=tmpm->reg<REG_REGS_NUM) {
if (Bts(&used_reg_mask,tmpm->reg))
PrintWarn("Reg in use\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stk->full_name,
cc->lex_include_stk->line_num,tmpm->str,cc->htc.fun->str);
reg_offsets[tmpm->reg].offset=tmpm->offset;
reg_offsets[tmpm->reg].m=tmpm;
} else if (tmpc->raw_type!=RT_F64 && tmpm->reg!=REG_NONE ||
tmpm->reg==REG_ALLOC) {
if (tmpm->reg==REG_ALLOC)
mv[member_cnt].score=I64_MAX/2; //big but not too big
mv[member_cnt].offset_start=tmpm->offset;
mv[member_cnt].offset_end=tmpm->offset+MaxI64(1,tmpm->size);
mv[member_cnt++].m=tmpm;
} else if (tmpm->reg==REG_ALLOC)
PrintWarn("Can't reg var\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stk->full_name,
cc->lex_include_stk->line_num,tmpm->str,cc->htc.fun->str);
tmpm=tmpm->next;
}
} else
member_cnt=0;
tmpi=cc->coc.coc_head.next;
while (code=tmpi->ic_code) {
tmpi_next=tmpi->next;
if (code==IC_NOP1)
OptFree(tmpi);
else {
if (tmpil1=OptLag(tmpi)) {
if (!(tmpil2=OptLag(tmpil1)))
tmpil2=&cmp.ic_nop;
} else
tmpil1=tmpil2=&cmp.ic_nop;
tmpc=tmpi->ic_class;
switch [intermediate_code_table[code].arg_cnt] {
case IS_V_ARG:
ps->ptr-=tmpi->ic_data>>3;
break;
case IS_2_ARG:
tmpi2=PrsPop(ps);
if (tmpi2->ic_flags&ICF_RES_TO_F64)
tmpc2=cmp.internal_types[RT_F64];
else if (tmpi2->ic_flags & ICF_RES_TO_INT)
tmpc2=cmp.internal_types[RT_I64];
else
tmpc2=tmpi->t.arg2_class;
tmpi->arg2.type=MDF_STK+CmpRawType(tmpc2);
tmpi->ic_flags|=ICF_ARG2_WAS_STK;
case IS_1_ARG:
tmpi1=PrsPop(ps);
if (tmpi1->ic_flags&ICF_RES_TO_F64)
tmpc1=cmp.internal_types[RT_F64];
else if (tmpi1->ic_flags & ICF_RES_TO_INT)
tmpc1=cmp.internal_types[RT_I64];
else
tmpc1=tmpi->t.arg1_class;
tmpi->arg1.type=MDF_STK+CmpRawType(tmpc1);
tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc1);
tmpi->ic_flags|=ICF_ARG1_WAS_STK;
break;
case IS_0_ARG: //nobound switch
break;
}
if (intermediate_code_table[code].res_cnt) {
tmpi->res.type=MDF_STK+CmpRawType(tmpc);
tmpi->ic_flags|=ICF_RES_WAS_STK;
PrsPush(ps,tmpi);
}
switch [code] {
case IC_IMM_F64:
tmpi->ic_flags&=~ICF_RES_TO_F64;
if (tmpi->ic_flags&ICF_RES_TO_INT) {
tmpi->ic_data=ToI64(tmpi->ic_data(F64));
tmpi->ic_flags&=~ICF_RES_TO_INT;
tmpi->ic_code=IC_IMM_I64;
}
break;
case IC_IMM_I64:
tmpi->ic_flags&=~ICF_RES_TO_INT;
if (tmpi->ic_flags&ICF_RES_TO_F64) {
tmpi->ic_data(F64)=ToF64(tmpi->ic_data);
tmpi->ic_flags&=~ICF_RES_TO_F64;
tmpi->ic_code=IC_IMM_F64;
}
break;
case IC_RBP:
tmpi->ic_code=IC_REG;
tmpi->arg1.reg=REG_RBP;
break;
case IC_DEREF:
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
if (tmpi1->ic_code==IC_LEA) {
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->arg1.reg=tmpi1->arg1.reg;
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type;
tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc);
tmpi->ic_code=IC_MOV;
OptFree(tmpi1);
if (tmpi->arg1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tmpi->arg1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
} else if (tmpil1->ic_code==IC_ADD_CONST) {
if (tmpil2->ic_code==IC_REG) {
tmpi->ic_flags|=tmpil2->ic_flags|tmpil1->ic_flags;
tmpi->arg1.reg=tmpil2->arg1.reg;
tmpi->arg1.disp=tmpi->ic_data;
tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type;
tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc);
tmpi->ic_code=IC_MOV;
OptFree(tmpil2);
OptFree(tmpil1);
}
}
break;
case IC__PP:
case IC__MM:
case IC_PP_:
case IC_MM_:
CmpMinTypePointed(tmpi,CmpRawTypePointed(tmpi->t.arg1_class));
case IC_DEREF_PP:
case IC_DEREF_MM:
if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
tmpi1->arg1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tmpi1->arg1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
break;
case IC_MUL:
case IC_DIV:
if (tmpc->raw_type==RT_F64) {
CmpF2PushPop(tmpi,tmpi1,tmpi2);
break;
}
break;
case IC_ADD:
if (tmpc->raw_type==RT_F64) {
CmpF2PushPop(tmpi,tmpi1,tmpi2);
break;
}
if (OptFixupBinaryOp2(&tmpi1,&tmpi2)) {
tmpi->ic_flags|=tmpi1->ic_flags;
if (tmpi->t.arg1_tree!=tmpi2)
tmpi->t.arg1_class=tmpi->t.arg2_class;
tmpi->ic_data=tmpi1->ic_data;
tmpi->ic_code=IC_ADD_CONST;
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
tmpi->arg2.type=MDF_NULL;
OptFree(tmpi1);
if (tmpil2->ic_code==IC_REG && tmpil2->arg1.reg==REG_RBP) {
tmpi->ic_flags|=tmpil2->ic_flags;
tmpi->ic_code=IC_LEA;
tmpi->arg1.reg=REG_RBP;
tmpi->arg1.type=MDF_DISP+tmpi->arg1.type.raw_type;
tmpi->arg1.disp=tmpi->ic_data;
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start<=tmpi->ic_data<mv[i].offset_end) {
mv[i].lea_balance++;
mv[i].score++;
break;
}
OptFree(tmpil2);
}
}
break;
case IC_SUB:
if (tmpc->raw_type==RT_F64) {
CmpF2PushPop(tmpi,tmpi1,tmpi2);
break;
}
if (tmpi2->ic_code==IC_IMM_I64) {
tmpi->ic_flags|=tmpi2->ic_flags;
tmpi->ic_data=tmpi2->ic_data;
tmpi->ic_code=IC_SUB_CONST;
tmpi->arg2.type=MDF_NULL;
OptFree(tmpi2);
}
break;
case IC_LESS:
case IC_GREATER_EQU:
case IC_GREATER:
case IC_LESS_EQU:
if (tmpi->ic_flags&ICF_USE_F64)
CmpF2PushPop(tmpi,tmpi1,tmpi2);
break;
case IC_MUL_EQU:
case IC_DIV_EQU:
case IC_ADD_EQU:
case IC_SUB_EQU:
if (tmpc->raw_type==RT_F64)
CmpF1PushPop(tmpi,tmpi2);
case IC_ASSIGN_PP:
case IC_ASSIGN_MM:
case IC_ASSIGN:
case IC_SHL_EQU:
case IC_SHR_EQU:
case IC_MOD_EQU:
case IC_AND_EQU:
case IC_OR_EQU:
case IC_XOR_EQU:
if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
tmpi1->arg1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tmpi1->arg1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
CmpMinTypePointed(tmpi,CmpRawTypePointed(tmpi->t.arg1_class));
break;
case IC_RETURN_VAL:
case IC_RETURN_VAL2:
if (tmpc) {
if (tmpc->raw_type==RT_F64 && tmpil1->ic_class->raw_type!=RT_F64)
tmpil1->ic_flags|=ICF_RES_TO_F64;
else if (tmpc->raw_type!=RT_F64 &&
tmpil1->ic_class->raw_type==RT_F64)
tmpil1->ic_flags|=ICF_RES_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 (tmpc->raw_type==RT_F64)
CmpF1PushPop(tmpi,tmpi1);
break;
case IC_NOBOUND_SWITCH:
case IC_SWITCH:
lb=OptLabelFwd(tmpi->ic_data(CCodeMisc *)->dft);
lb->use_cnt++;
break;
case IC_ASM:
tmpaot=tmpi->ic_data;
tmpie=tmpaot->next_ie;
while (tmpie!=&tmpaot->next_ie) {
if (IET_REL_I0<=tmpie->type<=IET_IMM_I64 &&
tmpie->str && tmpie->flags&IEF_GOTO_LABEL &&
(lb=COCGoToLabelFind(cc,tmpie->str)))
lb->use_cnt++; //Prevent deadcode elimination.
tmpie=tmpie->next;
}
break;
case IC_BR_NOT_EQU:
case IC_BR_EQU_EQU:
if ((tmpi1->ic_code==IC_IMM_I64 ||
tmpi1->ic_code==IC_IMM_F64) && !tmpi1->ic_data) {
OptFree(tmpi1);
MemCpy(&tmpi->arg1,&tmpi->arg2,sizeof(CICArg));
tmpi->arg2.type=MDF_NULL;
if (code==IC_BR_EQU_EQU)
code=tmpi->ic_code=IC_BR_ZERO;
else
code=tmpi->ic_code=IC_BR_NOT_ZERO;
tmpi1=tmpi2;
tmpc1=tmpc2;
} else if ((tmpi2->ic_code==IC_IMM_I64 ||
tmpi2->ic_code==IC_IMM_F64) && !tmpi2->ic_data) {
OptFree(tmpi2);
tmpi->arg2.type=MDF_NULL;
if (code==IC_BR_EQU_EQU)
code=tmpi->ic_code=IC_BR_ZERO;
else
code=tmpi->ic_code=IC_BR_NOT_ZERO;
} else
goto here1;
case IC_BR_ZERO:
case IC_BR_NOT_ZERO:
if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) {
if (code==IC_BR_ZERO ^^ tmpi1->ic_data) {
OptFree(tmpi1);
tmpi->arg1.type=MDF_NULL;
tmpi->ic_code=IC_JMP;
} else {
OptFree(tmpi1);
tmpi=OptFree(tmpi);
break;
}
}
goto here1;
case IC_BR_AND_ZERO:
if (tmpi1->ic_code==IC_IMM_I64) {
i=Bsr(tmpi1->ic_data);
if (0<=i==Bsf(tmpi1->ic_data)) {
tmpi1->ic_data=i;
tmpi->ic_flags|=ICF_BY_VAL;
tmpi->ic_code=IC_BR_NOT_BT;
goto here1;
}
}
if (tmpi2->ic_code==IC_IMM_I64) {
i=Bsr(tmpi2->ic_data);
if (0<=i==Bsf(tmpi2->ic_data)) {
tmpi2->ic_data=i;
tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL;
tmpi->ic_code=IC_BR_NOT_BT;
}
}
goto here1;
case IC_BR_AND_NOT_ZERO:
if (tmpi1->ic_code==IC_IMM_I64) {
i=Bsr(tmpi1->ic_data);
if (0<=i==Bsf(tmpi1->ic_data)) {
tmpi1->ic_data=i;
tmpi->ic_flags|=ICF_BY_VAL;
tmpi->ic_code=IC_BR_BT;
goto here1;
}
}
if (tmpi2->ic_code==IC_IMM_I64) {
i=Bsr(tmpi2->ic_data);
if (0<=i==Bsf(tmpi2->ic_data)) {
tmpi2->ic_data=i;
tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL;
tmpi->ic_code=IC_BR_BT;
}
}
goto here1;
case IC_BR_MM_ZERO:
case IC_BR_MM_NOT_ZERO:
if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
tmpi1->arg1.reg==REG_RBP)
for (i=0;i<member_cnt;i++)
if (mv[i].offset_start==tmpi1->arg1.disp) {
mv[i].lea_balance--;
mv[i].score++;
break;
}
tmpi->arg1_type_pointed_to=CmpRawType(tmpc);
goto here1;
case IC_BR_LESS:
case IC_BR_GREATER_EQU:
case IC_BR_GREATER:
case IC_BR_LESS_EQU:
if (tmpi->ic_flags&ICF_USE_F64)
CmpF2PushPop(tmpi,tmpi1,tmpi2);
case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
case IC_BR_CARRY:
case IC_BR_NOT_CARRY:
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_JMP:
case IC_SUB_CALL:
here1:
if (tmpi->ic_flags&ICF_PUSH_CMP)
lb=tmpi->ic_data;
else
lb=OptLabelFwd(tmpi->ic_data);
lb->use_cnt++;
break;
case IC_NOP1:
tmpi=OptFree(tmpi);
break;
case IC_NOP2:
ps->ptr+=tmpi->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_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_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_I64:
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_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_EQU_EQU:
case IC_NOT_EQU:
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 hndlr\n",cc->pass;
ICPut(cc,tmpi);
LexExcept(cc,"Compiler Optimization Error at ");
}
}
tmpi=tmpi_next;
}
/* REGISTER VARIABLE ASSIGNMENT
We just scored num occurrences of each [RBP] offset in the code to help decide
which variables should be assigned to register variables.
We counted the times each offset was added to RBP as a plus LEA and we subtract
the times the offset is dereferenced. If the address was calculated more times
than the offset was dereferenced, the variable's address was passed or assigned
and we cannot use a register because you can't take address of a reg var.
RAX,RBX,RCX,RDX, R8 are free to be clobbered by each intermediate code.
RAX and R8 links intermediate codes together. R9 is used for stack machine
temporaries. RBP is used as stack frame.
RSI,RDI,R10,R11,R12,R13,R14,R15 are used for reg vars. R12 and R13, however,
have a unusual ModR addressing mode in the x86_64 architecture, so I only use
R12 and R13 as non-pointer register variables, such as index variables i,j,k.
*/
if (cc->htc.fun) {
cc->htc.fun->used_reg_mask=cc->htc.fun->used_reg_mask&
~(REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS)|used_reg_mask;
if (!Bt(&cc->opts,OPTf_NO_REG_VAR) &&
!(cc->flags & CCF_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",
cc->lex_include_stk->full_name,
cc->lex_include_stk->line_num,mv[i].m->str,cc->htc.fun->str);
}
}
if (j>0) {
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
"Fun:%s\n",cc->htc.fun->str;
if (j>cmp.num_reg_vars) {
l=0;
for (i=0;i<j && l<cmp.num_non_ptr_vars;i++) {
tmpm=mv[i].m;
tmpc=OptClassFwd(tmpm->member_class);
if (!tmpc->ptr_stars_cnt && !tmpm->dim.next) {
while (l<cmp.num_non_ptr_vars &&
Bts(&cc->htc.fun->used_reg_mask,cmp.non_ptr_vars_map[l]))
l++;
if (l<cmp.num_non_ptr_vars) {
tmpm->reg=cmp.non_ptr_vars_map[l++];
reg_offsets[tmpm->reg].offset=mv[i].offset_start;
reg_offsets[tmpm->reg].m=tmpm;
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
"Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS",
tmpm->str,reg_offsets[tmpm->reg].offset;
mv[i].offset_start=0; //flag as reg var
if (tmpm->size<8 &&
!StrIMatch("Bool",tmpm->member_class->str) &&
tmpm->member_class->type&HTT_INTERNAL_TYPE)
PrintWarn("Using 64-bit reg var.\n "
"$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stk->full_name,
cc->lex_include_stk->line_num,
tmpm->str,cc->htc.fun->str);
}
}
}
}
l=0;
for (i=0;i<j && l<cmp.num_reg_vars;i++) {
tmpm=mv[i].m;
//if not just flagged as reg var
if (mv[i].offset_start && (!mv[i].m->dim.next||
tmpm->offset>0 && StrCmp(tmpm->str,"argv"))) {
while (l<cmp.num_reg_vars &&
Bts(&cc->htc.fun->used_reg_mask,cmp.to_reg_vars_map[l]))
l++;
if (l<cmp.num_reg_vars) {
tmpm->reg=cmp.to_reg_vars_map[l++];
reg_offsets[tmpm->reg].offset=mv[i].offset_start;
reg_offsets[tmpm->reg].m=tmpm;
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
"Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS",
tmpm->str,reg_offsets[tmpm->reg].offset;
if (tmpm->size<8 &&
!StrIMatch("Bool",tmpm->member_class->str) &&
tmpm->member_class->type&HTT_INTERNAL_TYPE)
PrintWarn("Using 64-bit reg var.\n "
"$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stk->full_name,
cc->lex_include_stk->line_num,
tmpm->str,cc->htc.fun->str);
}
}
}
}
}
Free(mv);
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
LexExcept(cc,"Compiler Optimization Error at ");
}
}
+689
View File
@@ -0,0 +1,689 @@
Bool OptIC4(CIntermediateCode *tmpi)
{
I64 i;
CIntermediateCode *tmpil1,*tmpil2;
if (tmpi->ic_code<IC_IMM_I64) return FALSE;
tmpil1=tmpi;
if (!(tmpil2=OptLag1(tmpil1)))
return FALSE;
if (tmpil2->res.type&MDF_STK && !(tmpil2->ic_flags&ICF_PUSH_RES)) {
if (tmpil1->ic_code==IC_ADD_CONST && tmpil1->arg1.type&MDF_STK) {
if ((tmpil2->ic_code==IC_REG || tmpil2->ic_code==IC_MOV) &&
tmpil2->arg1.type&MDF_REG) {
i=tmpil1->ic_data;
if (I32_MIN<=i<=I32_MAX &&
!Bt(&cmp.non_ptr_vars_mask,tmpil2->arg1.reg)) {
tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
tmpil1->ic_code=IC_LEA;
tmpil1->arg1.type=MDF_DISP+tmpil1->arg1.type.raw_type;
tmpil1->arg1.reg=tmpil2->arg1.reg;
tmpil1->arg1.disp=i;
OptFree(tmpil2);
return TRUE;
}
} else if (tmpil2->ic_code==IC_SHL_CONST && tmpil2->arg1.type&MDF_REG) {
i=tmpil1->ic_data;
if (I32_MIN<=i<=I32_MAX && tmpil2->arg1.reg!=REG_RSP &&
1<=tmpil2->ic_data<=3) {
tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
tmpil1->ic_code=IC_LEA;
tmpil1->arg1.type=MDF_SIB+tmpil1->arg1.type.raw_type;
tmpil1->arg1.reg=tmpil2->arg1.reg<<8+REG_NONE;
if (tmpil2->ic_data==1)
tmpil1->arg1.reg|=0x4000;
else if (tmpil2->ic_data==2)
tmpil1->arg1.reg|=0x8000;
else
tmpil1->arg1.reg|=0xC000;
tmpil1->arg1.disp=i;
OptFree(tmpil2);
return TRUE;
}
}
}
if (tmpil2->ic_code==IC_MOV || tmpil2->ic_code==IC_REG) {
if (tmpil1->arg2.type&MDF_STK) {
if (tmpil2->ic_flags & ICF_RES_TO_INT) {
if (tmpil2->arg1.type&MDF_IMM)
tmpil2->arg1.disp=tmpil2->arg1.disp(F64);
else
tmpil1->ic_flags|=ICF_ARG2_TO_INT;
} else if (tmpil2->ic_flags&ICF_RES_TO_F64) {
if (tmpil2->arg1.type&MDF_IMM)
tmpil2->arg1.disp(F64)=tmpil2->arg1.disp;
else
tmpil1->ic_flags|=ICF_ARG2_TO_F64;
}
tmpil1->arg2.type=tmpil2->arg1.type&MDG_MASK+
MinI64(tmpil1->arg2.type.raw_type,
MinI64(tmpil2->res.type.raw_type,tmpil2->arg1.type.raw_type));
tmpil1->arg2.reg=tmpil2->arg1.reg;
tmpil1->arg2.disp=tmpil2->arg1.disp;
tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tmpil2);
return TRUE;
}
if (tmpil1->arg1.type&MDF_STK) {
if (tmpil2->ic_flags & ICF_RES_TO_INT) {
if (tmpil2->arg1.type&MDF_IMM)
tmpil2->arg1.disp=tmpil2->arg1.disp(F64);
else
tmpil1->ic_flags|=ICF_ARG1_TO_INT;
} else if (tmpil2->ic_flags&ICF_RES_TO_F64) {
if (tmpil2->arg1.type&MDF_IMM) {
if (tmpil2->arg1.type&RTF_UNSIGNED)
tmpil2->arg1.disp(F64)=tmpil2->arg1.disp(U64);
else
tmpil2->arg1.disp(F64)=tmpil2->arg1.disp(I64);
} else
tmpil1->ic_flags|=ICF_ARG1_TO_F64;
}
tmpil1->arg1.type=tmpil2->arg1.type&MDG_MASK+
MinI64(tmpil1->arg1.type.raw_type,
MinI64(tmpil2->res.type.raw_type,tmpil2->arg1.type.raw_type));
CmpMinTypePointed(tmpil1,tmpil2->arg1_type_pointed_to);
tmpil1->arg1.reg=tmpil2->arg1.reg;
tmpil1->arg1.disp=tmpil2->arg1.disp;
tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tmpil2);
return TRUE;
}
}
if (tmpil1->ic_code==IC_DEREF) {
if (tmpil2->ic_code==IC_ADD_CONST && tmpil2->arg1.type&MDF_REG &&
tmpil1->arg1.type&MDF_STK) {
i=tmpil2->ic_data;
if (I32_MIN<=i<=I32_MAX &&
!Bt(&cmp.non_ptr_vars_mask,tmpil2->arg1.reg)) {
tmpil1->ic_flags|=tmpil2->ic_flags;
tmpil1->ic_code=IC_MOV;
tmpil1->arg1.type=MDF_DISP+tmpil1->arg1_type_pointed_to;
tmpil1->arg1.reg=tmpil2->arg1.reg;
tmpil1->arg1.disp=i;
OptSetNOP2(tmpil2,-1);
return TRUE;
}
}
if (tmpil2->ic_code==IC_LEA && tmpil1->arg1.type&MDF_STK) {
tmpil1->ic_flags|=tmpil2->ic_flags;
tmpil1->ic_code=IC_MOV;
tmpil1->arg1.type=tmpil2->arg1.type&MDG_MASK+
tmpil1->arg1_type_pointed_to;
tmpil1->arg1.reg=tmpil2->arg1.reg;
tmpil1->arg1.disp=tmpil2->arg1.disp;
OptFree(tmpil2);
return TRUE;
}
}
}
if (tmpil1->ic_code==IC_DEREF) {
if (tmpil1->arg1.type&MDF_REG) {
tmpil1->arg1.type=MDF_DISP+tmpil1->arg1_type_pointed_to;
tmpil1->arg1.disp=0;
tmpil1->ic_code=IC_MOV;
return TRUE;
}
}
return FALSE;
}
U0 OptPass4(CCmpCtrl *cc,COptReg *reg_offsets,I64 *_type)
{
CHashClass *tmpc,*tmpc1,*tmpc2;
CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpil1,*tmpil2,*tmpil3,
*tmpi_next;
I64 code,i;
Bool dead_code=FALSE;
CCodeMisc *lb;
CPrsStk *ps=cc->ps;
ps->ptr=0;
ps->ptr2=0;
if (_type)
*_type=RT_I64;
tmpi=cc->coc.coc_head.next;
while (code=tmpi->ic_code) {
tmpi_next=tmpi->next;
if (dead_code&&code!=IC_LABEL) {
if (code==IC_JMP||code==IC_SUB_CALL) {
lb=OptLabelFwd(tmpi->ic_data);
if (lb->use_cnt>0)
lb->use_cnt--;
}
tmpi=OptFree(tmpi);
} else {
tmpc=tmpi->ic_class;
tmpi1=tmpi2=&cmp.ic_nop;
if (tmpil1=OptLag2(tmpi)) {
if (tmpil2=OptLag2(tmpil1)) {
if (!(tmpil3=OptLag2(tmpil2)))
tmpil3=&cmp.ic_nop;
} else
tmpil2=tmpil3=&cmp.ic_nop;
} else
tmpil1=tmpil2=tmpil3=&cmp.ic_nop;
switch [intermediate_code_table[code].arg_cnt] {
case IS_V_ARG:
ps->ptr-=tmpi->ic_data>>3;
break;
case IS_2_ARG:
tmpi2=PrsPop(ps);
tmpc2=tmpi2->ic_class;
case IS_1_ARG:
tmpi1=PrsPop(ps);
tmpc1=tmpi1->ic_class;
break;
case IS_0_ARG: //nobound switch
break;
}
switch [code] {
case IC_IMM_I64:
case IC_TYPE:
tmpi->arg1.type=MDF_IMM+RT_I64;
tmpi->arg1.disp=tmpi->ic_data;
tmpi->ic_code=IC_MOV;
break;
case IC_IMM_F64:
tmpi->arg1.type=MDF_IMM+RT_I64;
tmpi->arg1.disp=tmpi->ic_data;
tmpi->arg1_type_pointed_to=RT_F64;
tmpi->ic_code=IC_MOV;
break;
case IC_MOV:
if (tmpi->arg1.type&MDF_DISP && tmpi->arg1.reg==REG_RBP) {
i=CmpOffset2Reg(tmpi->arg1.disp,reg_offsets);
if (i>=0) {
tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
tmpi->arg1.reg=i;
tmpi->arg1.disp=0;
}
}
break;
case IC_DEREF:
if (tmpi1->ic_code==IC_LEA) {
if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
if (i>=0) {
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->ic_code=IC_REG;
tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
tmpi->arg1.reg=i;
tmpi->arg1.disp=0;
OptFree(tmpi1);
}
}
} else if ((tmpi1->ic_code==IC_ABS_ADDR ||
tmpi1->ic_code==IC_MOV &&
tmpi1->arg1.type==MDF_IMM+RT_I64 &&
0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
if (tmpi1->ic_code==IC_ABS_ADDR)
tmpi->arg1.disp=tmpi1->ic_data;
else
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->ic_code=IC_MOV;
tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1_type_pointed_to;
tmpi->arg1.reg=REG_RIP;
OptFree(tmpi1);
}
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 (tmpi1->ic_code==IC_LEA) {
if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
if (i>=0) {
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
tmpi->arg1.reg=i;
tmpi->arg1.disp=0;
tmpi->ic_flags|=ICF_BY_VAL;
OptSetNOP2(tmpi1);
} else
goto p4_lea_gone;
} else {
p4_lea_gone:
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->arg1.type=tmpi1->arg1.type;
tmpi->arg1.reg=tmpi1->arg1.reg;
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->ic_flags|=ICF_BY_VAL;
OptSetNOP2(tmpi1);
}
} else if ((tmpi1->ic_code==IC_ABS_ADDR || tmpi1->ic_code==IC_MOV &&
tmpi1->arg1.type==MDF_IMM+RT_I64 &&
0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
tmpi->ic_flags|=tmpi1->ic_flags;
if (tmpi1->ic_code==IC_ABS_ADDR)
tmpi->arg1.disp=tmpi1->ic_data;
else
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1_type_pointed_to;
tmpi->arg1.reg=REG_RIP;
tmpi->ic_flags|=ICF_BY_VAL;
OptFree(tmpi1);
}
break;
case IC_ADD:
if (tmpi1->ic_code==IC_MOV && tmpi1->arg1.type==MDF_REG+RT_I64 ||
tmpi1->ic_code==IC_REG) {
if (tmpi2->ic_code==IC_MOV && tmpi2->arg1.type==MDF_REG+RT_I64 ||
tmpi2->ic_code==IC_REG) {
if (tmpi2->arg1.reg!=REG_RSP) {
tmpi->arg1.disp=0;
tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
goto p4_sib;
} else if (tmpi1->arg1.reg!=REG_RSP) {
tmpi->arg1.disp=0;
tmpi->arg1.reg=tmpi2->arg1.reg+tmpi1->arg1.reg<<8;
p4_sib:
tmpi->ic_flags|=(tmpi1->ic_flags|tmpi2->ic_flags)
&ICG_NO_CVT_MASK;
OptSetNOP2(tmpi1);
OptFree(tmpi2);
tmpi->ic_code=IC_LEA;
tmpi->arg1.type=MDF_SIB+RT_I64;
tmpi->arg1_type_pointed_to=RT_I64;
tmpi->arg2.type=MDF_NULL+tmpi->arg2.type.raw_type;
}
} else if (tmpi2->ic_code==IC_SHL_CONST &&
tmpi2->arg1.type==MDF_REG+RT_I64 && tmpi2->ic_data<=3) {
if (tmpi2->arg1.reg!=REG_RSP) {
tmpi->arg1.disp=0;
tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
if (tmpi2->ic_data==1)
tmpi->arg1.reg|=0x4000;
else if (tmpi2->ic_data==2)
tmpi->arg1.reg|=0x8000;
else
tmpi->arg1.reg|=0xC000;
goto p4_sib;
}
}
} else if (tmpi1->ic_code==IC_LEA &&
tmpi1->arg1.type&MDF_DISP) {
if (tmpi1->arg1.reg==REG_RBP &&
CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets)>=0)
break;
if (tmpi2->ic_code==IC_MOV && tmpi2->arg1.type==MDF_REG+RT_I64 ||
tmpi2->ic_code==IC_REG) {
if (tmpi2->arg1.reg!=REG_RSP) {
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
goto p4_sib;
} else if (tmpi1->arg1.reg!=REG_RSP) {
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->arg1.reg=tmpi2->arg1.reg+tmpi1->arg1.reg<<8;
goto p4_sib;
}
} else if (tmpi2->ic_code==IC_SHL_CONST &&
tmpi2->arg1.type==MDF_REG+RT_I64 && tmpi2->ic_data<=3) {
if (tmpi2->arg1.reg!=REG_RSP) {
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
if (tmpi2->ic_data==1)
tmpi->arg1.reg|=0x4000;
else if (tmpi2->ic_data==2)
tmpi->arg1.reg|=0x8000;
else
tmpi->arg1.reg|=0xC000;
goto p4_sib;
}
}
}
break;
case IC_ASSIGN_PP:
case IC_ASSIGN_MM:
//this val was stashed during pass012 for pointer arithmetic
tmpi->ic_class2=tmpi->t.class2; //See $LK,"ic_class2",A="FF:::/Compiler/BackB.HC,ic_class2"$
case IC_ASSIGN:
case IC_SHL_EQU:
case IC_SHR_EQU:
case IC_MUL_EQU:
case IC_DIV_EQU:
case IC_MOD_EQU:
case IC_AND_EQU:
case IC_OR_EQU:
case IC_XOR_EQU:
case IC_ADD_EQU:
case IC_SUB_EQU:
if (tmpi1->ic_code==IC_LEA) {
if (tmpi1->arg1.type&(MDF_DISP|MDF_SIB)) {
tmpi2=tmpi->next;
if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
if (i>=0) {
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
tmpi->arg1.reg=i;
tmpi->arg1.disp=0;
OptSetNOP2(tmpi1);
} else {
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->arg1.type=MDF_DISP+tmpi->arg1.type.raw_type;
tmpi->arg1.reg=REG_RBP;
tmpi->arg1.disp=tmpi1->arg1.disp;
OptSetNOP2(tmpi1);
}
} else {
tmpi->ic_flags|=tmpi1->ic_flags;
tmpi->arg1.type=tmpi1->arg1.type&MDG_MASK+
tmpi->arg1.type.raw_type;
tmpi->arg1.reg=tmpi1->arg1.reg;
tmpi->arg1.disp=tmpi1->arg1.disp;
OptSetNOP2(tmpi1);
}
if (tmpi->res.type&MDF_STK && tmpi2->arg2.type&MDF_STK &&
code!=IC_ASSIGN_PP && code!=IC_ASSIGN_MM) {
tmpi->res.type=tmpi->arg1.type;
tmpi->res.reg=tmpi->arg1.reg;
tmpi->res.disp=tmpi->arg1.disp;
tmpi2->arg2.type=tmpi->arg1.type;
tmpi2->arg2.reg=tmpi->arg1.reg;
tmpi2->arg2.disp=tmpi->arg1.disp;
CmpMinTypePointed(tmpi2,tmpi->arg1_type_pointed_to);
}
tmpi->ic_flags|=ICF_BY_VAL;
}
} else if ((tmpi1->ic_code==IC_ABS_ADDR ||
tmpi1->ic_code==IC_MOV && tmpi1->arg1.type==MDF_IMM+RT_I64 &&
0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
tmpi->ic_flags|=tmpi1->ic_flags;
if (tmpi1->ic_code==IC_ABS_ADDR)
tmpi->arg1.disp=tmpi1->ic_data;
else
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1.type.raw_type;
tmpi->arg1.reg=REG_RIP;
tmpi->ic_flags|=ICF_BY_VAL;
OptSetNOP2(tmpi1);
}
break;
case IC_RETURN_VAL:
case IC_RETURN_VAL2:
if (!tmpi->ic_class) {
if (_type) {
tmpil1=tmpi;
while (tmpil1=OptLag1(tmpil1))
if (tmpil1->ic_class) {
if (tmpil1->ic_flags & ICF_RES_TO_F64)
*_type=RT_F64;
else if (tmpil1->ic_flags & ICF_RES_TO_INT)
*_type=RT_I64;
else
*_type=tmpil1->ic_class->raw_type;
break;
}
}
tmpi->ic_class=cmp.internal_types[RT_I64];
} else if (_type)
*_type=tmpi->ic_class->raw_type;
break;
case IC_NOP1:
tmpi=OptFree(tmpi);
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_BT:
case IC_BTS:
case IC_BTR:
case IC_BTC:
case IC_LBTS:
case IC_LBTR:
case IC_LBTC:
if (!(tmpi->ic_flags&ICF_BY_VAL)) {
if (tmpi2->ic_code==IC_ADDR) {
if (tmpi2->arg1.type&MDF_STK &&
tmpi2->res.type&MDF_STK) {
if (tmpil2=OptLag1(tmpi2)) {
if (tmpil2->ic_code==IC_LEA) {
if (tmpil2->arg1.type&(MDF_IMM|MDG_REG_DISP_SIB_RIP)) {
if (tmpi2) {
tmpi->ic_flags|=tmpi2->ic_flags;
OptFree(tmpi2);
}
tmpi->ic_flags|=tmpil2->ic_flags|ICF_BY_VAL;
tmpi->arg2.type=tmpil2->arg1.type;
tmpi->arg2.reg =tmpil2->arg1.reg;
tmpi->arg2.disp=tmpil2->arg1.disp;
OptFree(tmpil2);
}
break;
} else if (tmpil2->ic_code!=IC_ABS_ADDR &&
!(tmpil2->ic_code==IC_MOV &&
tmpil2->arg1.type==MDF_IMM+RT_I64 &&
0<=tmpil2->arg1.disp<=I32_MAX) ||
tmpil2->ic_flags&ICF_NO_RIP)
tmpil2=NULL;
else {
if (tmpil2->ic_code==IC_ABS_ADDR)
tmpi->arg2.disp=tmpil2->ic_data;
else
tmpi->arg2.disp=tmpil2->arg1.disp;
}
}
} else {
if (tmpi2->arg1.type==MDF_IMM+RT_I64 &&
0<=tmpi2->arg1.disp<=I32_MAX &&
!(tmpi2->ic_flags&ICF_NO_RIP)) {
tmpil2=tmpi2;
tmpi2=NULL;
tmpi->arg2.disp=tmpil2->arg1.disp;
} else
tmpil2=NULL;
}
if (tmpil2) {
if (tmpi2) {
tmpi->ic_flags|=tmpi2->ic_flags;
OptFree(tmpi2);
}
tmpi->ic_flags|=tmpil2->ic_flags|ICF_BY_VAL;
tmpi->arg2.type=MDF_RIP_DISP32+tmpi->arg2.type.raw_type;
tmpi->arg2.reg=REG_RIP;
OptFree(tmpil2);
}
} else if (tmpi2->ic_code==IC_MOV && tmpi2->res.type&MDF_STK &&
tmpi2->arg1.type==MDF_IMM+RT_I64 &&
0<=tmpi2->arg1.disp<=I32_MAX &&
!(tmpi2->ic_flags&ICF_NO_RIP)) {
tmpi->arg2.disp=tmpi2->arg1.disp;
tmpi->ic_flags|=tmpi2->ic_flags|ICF_BY_VAL;
tmpi->arg2.type=MDF_RIP_DISP32+tmpi->arg2.type.raw_type;
tmpi->arg2.reg=REG_RIP;
OptFree(tmpi2);
}
}
break;
case IC_BR_EQU_EQU ...IC_BR_LESS_EQU:
case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
case IC_BR_CARRY:
case IC_BR_NOT_CARRY:
case IC_BR_ZERO:
case IC_BR_NOT_ZERO:
lb=tmpi->ic_data;
if (tmpi->ic_flags&ICF_PUSH_CMP) {
lb->flags|=CMF_POP_CMP;
lb->fwd=NULL;
}
break;
case IC_LABEL:
lb=tmpi->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+=tmpi->ic_data;
break;
case IC_CALL_END:
case IC_END_EXP:
if (!(tmpil1->ic_flags&ICF_PUSH_RES)) {
if (tmpi->ic_flags&ICF_RES_NOT_USED) {
tmpil1->ic_flags|=ICF_RES_NOT_USED;
tmpil1->res.type=MDF_NULL+tmpil1->res.type.raw_type;
} else if (tmpi->arg1.type&MDF_STK &&
tmpil1->res.type&MDF_STK) {
tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
tmpi->arg1.disp=0;
tmpil1->res.type=MDF_REG+tmpil1->res.type.raw_type;
tmpil1->res.disp=0;
if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG) {
tmpi->arg1.reg=REG_R8;
tmpil1->res.reg=REG_R8;
} else {
tmpi->arg1.reg=REG_RAX;
tmpil1->res.reg=REG_RAX;
}
}
}
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_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_EQU_EQU...IC_LESS_EQU:
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_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_I64:
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 hndlr\n",cc->pass;
ICPut(cc,tmpi);
LexExcept(cc,"Compiler Optimization Error at ");
}
if (tmpi) {
while (OptIC4(tmpi));
code=tmpi->ic_code;
if (intermediate_code_table[code].res_cnt)
PrsPush(ps,tmpi);
}
}
tmpi=tmpi_next;
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
LexExcept(cc,"Compiler Optimization Error at ");
}
}
+90
View File
@@ -0,0 +1,90 @@
U0 OptPass5(CCmpCtrl *cc)
{
CIntermediateCode *tmpi,*tmpi1;
I64 code,i;
CPrsStk *ps=cc->ps;
ps->ptr=0;
ps->ptr2=0;
tmpi=cc->coc.coc_head.next;
while (code=tmpi->ic_code) {
if (code>IC_NOP2) {
if (tmpi->ic_flags&ICF_PASS_TRACE) {
if (Bt(&cc->saved_pass_trace,5)) {
"%2d:",ps->ptr;
ICPut(cc,tmpi);
}
}
if (intermediate_code_table[code].arg_cnt==IS_V_ARG)
ps->ptr-=tmpi->ic_data>>3;
if (code==IC_PUSH_REGS) {
for (i=0;i<REG_REGS_NUM;i++)
if (Bt(&tmpi->ic_data,i))
ps->ptr++;
} else if (code==IC_POP_REGS) {
for (i=0;i<REG_REGS_NUM;i++)
if (Bt(&tmpi->ic_data,i))
ps->ptr--;
}
if (tmpi->arg2.type&MDF_STK) {
tmpi1=PrsPop(ps);
if (tmpi1->ic_code==IC_MOV || tmpi1->ic_code==IC_REG) {
if (tmpi1->ic_flags & ICF_RES_TO_INT) {
if (tmpi1->arg1.type&MDF_IMM)
tmpi1->arg1.disp=tmpi1->arg1.disp(F64);
else
tmpi->ic_flags|=ICF_ARG2_TO_INT;
} else if (tmpi1->ic_flags&ICF_RES_TO_F64) {
if (tmpi1->arg1.type&MDF_IMM)
tmpi1->arg1.disp(F64)=tmpi1->arg1.disp;
else
tmpi->ic_flags|=ICF_ARG2_TO_F64;
}
tmpi->arg2.type=tmpi1->arg1.type&MDG_MASK+
MinI64(tmpi->arg2.type.raw_type,
MinI64(tmpi1->res.type.raw_type,tmpi1->arg1.type.raw_type));
tmpi->arg2.reg=tmpi1->arg1.reg;
tmpi->arg2.disp=tmpi1->arg1.disp;
tmpi->ic_flags|=tmpi1->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tmpi1);
}
}
if (tmpi->arg1.type&MDF_STK) {
tmpi1=PrsPop(ps);
if (tmpi1->ic_code==IC_MOV || tmpi1->ic_code==IC_REG) {
if (tmpi1->ic_flags & ICF_RES_TO_INT) {
if (tmpi1->arg1.type&MDF_IMM)
tmpi1->arg1.disp=tmpi1->arg1.disp(F64);
else
tmpi->ic_flags|=ICF_ARG1_TO_INT;
} else if (tmpi1->ic_flags&ICF_RES_TO_F64) {
if (tmpi1->arg1.type&MDF_IMM) {
if (tmpi1->arg1.type&RTF_UNSIGNED)
tmpi1->arg1.disp(F64)=tmpi1->arg1.disp(U64);
else
tmpi1->arg1.disp(F64)=tmpi1->arg1.disp(I64);
} else
tmpi->ic_flags|=ICF_ARG1_TO_F64;
}
tmpi->arg1.type=tmpi1->arg1.type&MDG_MASK+
MinI64(tmpi->arg1.type.raw_type,
MinI64(tmpi1->res.type.raw_type,tmpi1->arg1.type.raw_type));
CmpMinTypePointed(tmpi,tmpi1->arg1_type_pointed_to);
tmpi->arg1.reg=tmpi1->arg1.reg;
tmpi->arg1.disp=tmpi1->arg1.disp;
tmpi->ic_flags|=tmpi1->ic_flags&ICG_NO_CVT_MASK;
OptSetNOP2(tmpi1);
}
}
if (tmpi->res.type&MDF_STK &&
!(tmpi->ic_flags&ICF_RES_NOT_USED))
PrsPush(ps,tmpi);
}
tmpi=tmpi->next;
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
LexExcept(cc,"Compiler Optimization Error at ");
}
}
+185
View File
@@ -0,0 +1,185 @@
Bool OptIC6(CIntermediateCode *tmpi)
{
CIntermediateCode *tmpil1;
if (tmpi->ic_code<IC_IMM_I64 || !(tmpil1=OptLag1(tmpi)))
return FALSE;
if (tmpil1->ic_code==IC_ADD_CONST && tmpi->ic_code==IC_DEREF &&
tmpi->ic_flags&ICF_ARG1_WAS_STK && tmpi->arg1.type&MDF_REG &&
tmpil1->res.type&MDF_REG && I32_MIN<=tmpil1->ic_data<=I32_MAX &&
!Bt(&cmp.non_ptr_vars_mask,tmpil1->arg1.reg)) {
if (tmpil1->arg1.type&MDF_REG) {
tmpi->ic_flags=tmpi->ic_flags&~ICF_ARG1_WAS_STK | tmpil1->ic_flags;
tmpi->ic_code=IC_MOV;
tmpi->arg1.type=MDF_DISP+tmpi->arg1_type_pointed_to;
tmpi->arg1.reg=tmpil1->arg1.reg;
tmpi->arg1.disp=tmpil1->ic_data;
OptSetNOP2(tmpil1,-1);
} else {
tmpil1->ic_code=IC_MOV;
tmpi->ic_code=IC_MOV;
tmpi->arg1.type=MDF_DISP+tmpi->arg1_type_pointed_to;
tmpi->arg1.disp=tmpil1->ic_data;
}
return TRUE;
}
return FALSE;
}
U0 OptPass6Lag(CCmpCtrl *cc,CPrsStk *ps,CIntermediateCode *tmpi,
I64 *_stk_ptr,I64 reg_stk_size,I64 *_clobbered_reg_mask)
{
I64 stk_ptr=*_stk_ptr,code,
clobbered_stk_tmp_mask,clobbered_reg_mask=*_clobbered_reg_mask;
CHashFun *tmpf;
code=tmpi->ic_code;
if (tmpi->ic_flags&ICF_PASS_TRACE && Bt(&cc->saved_pass_trace,6)) {
"%2d:",stk_ptr;
ICPut(cc,tmpi);
}
if (code==IC_CALL_START) {
if (reg_stk_size==1 && stk_ptr>0)
clobbered_stk_tmp_mask=REGG_STK_TMP;
else
clobbered_stk_tmp_mask=0;
if (tmpf=tmpi->ic_data) {
if (Bt(&tmpf->flags,Ff_INTERNAL))
clobbered_stk_tmp_mask=0;
else {
clobbered_stk_tmp_mask&=tmpf->clobbered_reg_mask;
clobbered_reg_mask|=tmpf->clobbered_reg_mask;
}
}
tmpi->ic_data=clobbered_stk_tmp_mask;
PrsPush(ps,stk_ptr);
PrsPush(ps,clobbered_stk_tmp_mask);
} else if (code==IC_CALL_END) {
tmpi->ic_data=PrsPop(ps);
stk_ptr=PrsPop(ps);
} else if (code==IC_CALL_END2) {
ps->ptr--;
stk_ptr=PrsPop(ps);
}
if (intermediate_code_table[code].arg_cnt==IS_V_ARG)
stk_ptr-=tmpi->ic_data>>3;
if (tmpi->arg2.type&MDF_STK) {
stk_ptr--;
if (stk_ptr<reg_stk_size) {
tmpi->arg2.type=MDF_REG+tmpi->arg2.type.raw_type;
tmpi->arg2.reg=Bsf(REGG_STK_TMP);
tmpi->arg2.disp=0;
}
}
if (tmpi->arg1.type&MDF_STK) {
stk_ptr--;
if (stk_ptr<reg_stk_size) {
tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
tmpi->arg1.reg=Bsf(REGG_STK_TMP);
tmpi->arg1.disp=0;
}
}
if (tmpi->res.type&MDF_STK && !(tmpi->ic_flags & ICF_PUSH_RES)) {
stk_ptr++;
if (stk_ptr<=reg_stk_size) {
tmpi->res.type=MDF_REG+tmpi->res.type.raw_type;
tmpi->res.reg=Bsf(REGG_STK_TMP);
clobbered_reg_mask|=REGG_STK_TMP;
tmpi->res.disp=0;
}
}
while (OptIC6(tmpi));
if (tmpi->res.type.raw_type!=RT_F64 && !(tmpi->ic_flags&ICF_USE_F64))
tmpi->ic_flags|=ICF_USE_INT;
*_stk_ptr=stk_ptr;
*_clobbered_reg_mask=clobbered_reg_mask;
}
U0 OptPass6(CCmpCtrl *cc)
{
CIntermediateCode *tmpi,*tmpi_next,*tmpil1,*tmpil2,*old_tmpil2;
I64 stk_ptr=0,reg_stk_size,clobbered_reg_mask=REGG_CLOBBERED;
CPrsStk *ps=cc->ps;
ps->ptr=0;
ps->ptr2=0;
if (Bt(&cc->opts,OPTf_NO_REG_VAR) || cc->flags&CCF_NO_REG_OPT)
reg_stk_size=0;
else
reg_stk_size=1;
#assert REGG_STK_TMP==1<<9
tmpi=cc->coc.coc_head.next;
old_tmpil2=NULL;
tmpil1=tmpil2=&cmp.ic_nop;
while (tmpi->ic_code) {
if (tmpi->ic_code>IC_NOP2) {
if (tmpil1->ic_code>IC_NOP2)
tmpil2=tmpil1;
tmpil1=tmpi;
if (tmpi->arg2.type&MDF_STK) {
if (tmpil2->res.type&MDF_STK &&
!(tmpil2->ic_flags&ICF_PUSH_RES)) {
if (tmpi->ic_code==IC_ASSIGN && tmpi->ic_flags&ICF_BY_VAL &&
tmpi->ic_flags&ICF_RES_NOT_USED &&
tmpil2->ic_code!=IC_CALL_END &&
tmpil2->ic_code!=IC_CALL_END2 &&
tmpil2->ic_code!=IC_SET_RAX &&
!(tmpi->ic_flags&(ICF_ARG2_TO_F64|ICF_ARG2_TO_INT)) &&
!(tmpil2->ic_flags&(ICF_RES_TO_F64|ICF_RES_TO_INT))) {
tmpil2->res.type =tmpi->arg1.type&MDG_MASK+
tmpi->arg1_type_pointed_to;
tmpil2->res.reg =tmpi->arg1.reg;
tmpil2->res.disp =tmpi->arg1.disp;
tmpil2->ic_flags=tmpil2->ic_flags
&~(ICF_RES_NOT_USED|ICF_RES_WAS_STK)
|tmpi->ic_flags&~(ICF_BY_VAL|ICF_ARG1_WAS_STK|ICF_ARG2_WAS_STK);
old_tmpil2=NULL;
OptSetNOP1(tmpi);
} else {
tmpi->arg2.type=MDF_REG+tmpi->arg2.type.raw_type;
tmpi->arg2.reg=REG_RAX;
tmpi->arg2.disp=0;
tmpil2->res.type=MDF_REG+tmpil2->res.type.raw_type;
tmpil2->res.reg=REG_RAX;
tmpil2->res.disp=0;
}
}
} else if (tmpi->arg1.type&MDF_STK && tmpil2->res.type&MDF_STK &&
!(tmpil2->ic_flags&ICF_PUSH_RES)) {
tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
tmpi->arg1.disp=0;
tmpil2->res.type=MDF_REG+tmpil2->res.type.raw_type;
tmpil2->res.disp=0;
if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG) {
tmpi->arg1.reg=REG_R8;
tmpil2->res.reg=REG_R8;
} else {
tmpi->arg1.reg=REG_RAX;
tmpil2->res.reg=REG_RAX;
}
}
if (tmpi->ic_flags & ICF_PUSH_RES)
tmpi->res.type==MDF_STK+tmpi->res.type.raw_type;
if (old_tmpil2!=tmpil2) {
if (tmpil2->ic_code>IC_NOP2)
OptPass6Lag(cc,ps,tmpil2,&stk_ptr,reg_stk_size,&clobbered_reg_mask);
old_tmpil2=tmpil2;
}
}
tmpi_next=tmpi->next;
if (tmpi->ic_code<=IC_NOP2)
OptFree(tmpi);
tmpi=tmpi_next;
}
if (ps->ptr>2) {
"Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
LexExcept(cc,"Compiler Optimization Error at ");
}
if (cc->htc.fun) {
cc->htc.fun->used_reg_mask&=~REGG_STK_TMP;
cc->htc.fun->used_reg_mask|=clobbered_reg_mask;
cc->htc.fun->clobbered_reg_mask=clobbered_reg_mask;
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT) &&
Bt(&cc->saved_pass_trace,6)) {
"Used Reg Mask:%04X\n",cc->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
+323
View File
@@ -0,0 +1,323 @@
U0 PrsPush(CPrsStk *ps,I64 val)
{
ps->stk[++ps->ptr]=val;
}
I64 PrsPop(CPrsStk *ps)
{
return ps->stk[ps->ptr--];
}
U0 PrsPush2(CPrsStk *ps,I64 val)
{
ps->stk2[++ps->ptr2]=val;
}
I64 PrsPop2(CPrsStk *ps)
{
return ps->stk2[ps->ptr2--];
}
U0 PrsPopDeref(CPrsStk *ps)
{
I64 i=PrsPop(ps);
CHashClass *tmpc=PrsPop(ps);
if (i.u16[0]!=IC_DEREF) {
PrsPush(ps,tmpc);
PrsPush(ps,i);
}
}
I64 PrsKeyWord(CCmpCtrl *cc)
{//Cvt cur token to $LK,"KEYWORD",A="FF:::/Compiler/OpCodes.DD,KEYWORD"$ or -1.
CHashGeneric *tmph;
if (cc->token==TK_IDENT &&(tmph=cc->hash_entry) && tmph->type&HTT_KEYWORD)
return tmph->user_data0;
else
return -1;
}
CHashClass *PrsClassNew()
{/*Ptrs to classes are handled by
allocating 5 structures for each
new class and representing a pointer
to a class by advancing 1 struct fwd
for one * and two fwd for two **.
*/
I64 i;
CHashClass *res=CAlloc(sizeof(CHashClass)*(PTR_STARS_NUM+1),Fs->code_heap),
*tmpc=res;
for (i=0;i<=PTR_STARS_NUM;i++) {
tmpc->type=HTT_CLASS;
tmpc->raw_type=RT_PTR;
tmpc->size=sizeof(U8 *);
tmpc->ptr_stars_cnt=i;
tmpc++;
}
res->last_in_member_lst=&res->member_lst_and_root;
res->size=0;
return res;
}
CHashFun *PrsFunNew()
{
I64 i;
CHashFun *res=CAlloc(sizeof(CHashFun)*(PTR_STARS_NUM+1),Fs->code_heap),
*tmpf=res;
for (i=0;i<=PTR_STARS_NUM;i++) {
tmpf->type=HTT_FUN;
tmpf->raw_type=RT_PTR;
tmpf->size=sizeof(U8 *);
tmpf->ptr_stars_cnt=i;
tmpf++;
}
res->last_in_member_lst=&res->member_lst_and_root;
res->size=0;
return res;
}
CIntermediateCode *ICAdd(CCmpCtrl *cc,
I64 opcode_and_precedence,I64 arg, CHashClass *c,I64 flags=0)
{
CIntermediateCode *tmpi=MAlloc(sizeof(CIntermediateCode));
tmpi->ic_code=opcode_and_precedence.u16[0];
tmpi->ic_precedence=opcode_and_precedence.u16[1];
tmpi->ic_data=arg;
tmpi->ic_class=c;
if (cc->pass_trace) {
Bts(&cc->flags,CCf_PASS_TRACE_PRESENT);
flags|=ICF_PASS_TRACE;
}
if (cc->lock_cnt)
flags|=ICF_LOCK;
tmpi->ic_flags=flags;
tmpi->ic_line=cc->last_line_num;
QueIns(tmpi,cc->coc.coc_head.last);
return tmpi;
}
U0 COCInit(CCmpCtrl *cc)
{
CCodeCtrl *tmpcbh=&cc->coc;
QueInit(&tmpcbh->coc_head.next);
QueInit(&tmpcbh->coc_next_misc);
tmpcbh->coc_head.ic_code=IC_END;
}
U0 COCPush(CCmpCtrl *cc)
{
CCodeCtrl *tmpcbh=MAlloc(sizeof(CCodeCtrl));
MemCpy(tmpcbh,&cc->coc,sizeof(CCodeCtrl));
cc->coc.coc_next=tmpcbh;
}
CCmpCtrl *COCPopNoFree(CCmpCtrl *cc)
{
CCodeCtrl *tmpcbh=cc->coc.coc_next;
MemCpy(&cc->coc,tmpcbh,sizeof(CCodeCtrl));
return tmpcbh;
}
U0 COCPop(CCmpCtrl *cc)
{
Free(COCPopNoFree(cc));
}
U0 COCAppend(CCmpCtrl *cc, CCodeCtrl *tmpcbh)
{
if (tmpcbh->coc_head.next!=&cc->coc.coc_head.next) {
cc->coc.coc_head.last->next=tmpcbh->coc_head.next;
tmpcbh->coc_head.next->last=cc->coc.coc_head.last;
cc->coc.coc_head.last=tmpcbh->coc_head.last;
tmpcbh->coc_head.last->next=&cc->coc.coc_head.next;
}
if (tmpcbh->coc_next_misc!=&cc->coc.coc_next_misc) {
cc->coc.coc_last_misc->next=tmpcbh->coc_next_misc;
tmpcbh->coc_next_misc->last=cc->coc.coc_last_misc;
cc->coc.coc_last_misc=tmpcbh->coc_last_misc;
tmpcbh->coc_last_misc->next=&cc->coc.coc_next_misc;
}
Free(tmpcbh);
}
CCodeMisc *COCMiscNew(CCmpCtrl *cc,I64 ty)
{
CCodeMisc *res=CAlloc(sizeof(CCodeMisc));
res->addr=INVALID_PTR;
res->type=ty;
QueIns(res,cc->coc.coc_last_misc);
return res;
}
CCodeMisc *COCGoToLabelFind(CCmpCtrl *cc,U8 *name)
{
CCodeMisc *cm=cc->coc.coc_next_misc;
while (cm!=&cc->coc.coc_next_misc) {
if ((cm->type==CMT_GOTO_LABEL||cm->type==CMT_ASM_LABEL) &&
!StrCmp(cm->str,name))
return cm;
cm=cm->next;
}
return NULL;
}
I64 COCFloatConstFind(CCmpCtrl *cc,F64 d)
{
I64 i;
CCodeMisc *cm=cc->coc.coc_next_misc;
while (cm!=&cc->coc.coc_next_misc) {
if (cm->type==CMT_FLOAT_CONSTS) {
for (i=0;i<cm->num_consts;i++)
if (cm->float_consts[i]==d)
return cm->addr+i*sizeof(F64);
if (cm->num_consts<CM_CONSTS_NUM) {
cm->float_consts[cm->num_consts++]=d;
return cm->addr+i*sizeof(F64);
}
}
cm=cm->next;
}
cm=COCMiscNew(cc,CMT_FLOAT_CONSTS);
cm->float_consts=MAlloc(CM_CONSTS_NUM*sizeof(F64));
cm->float_consts[cm->num_consts++]=d;
return cm->addr;
}
U0 COCDel(CCmpCtrl *cc,CCodeCtrl *coc)
{
CCodeMisc *cm,*cm1;
U8 *undef=NULL;
QueDel(&coc->coc_head.next);
cm=coc->coc_next_misc;
while (cm!=&coc->coc_next_misc) {
cm1=cm->next;
switch (cm->type) {
case CMT_GOTO_LABEL:
case CMT_ASM_LABEL:
if (!(cm->flags&CMF_DEFINED)) {
undef=cm->str;
cm->str=NULL;
} else if (!cm->use_cnt) {
PrintWarn("Unused label %s\n",cm->str);
LexWarn(cc,"Unused label at ");
}
break;
case CMT_JMP_TABLE:
Free(cm->jmp_table);
break;
case CMT_FLOAT_CONSTS:
Free(cm->float_consts);
break;
case CMT_ARRAY_DIM:
LinkedLstDel(cm->dim);
break;
case CMT_HASH_ENTRY:
HashDel(cm->h);
break;
}
Free(cm->str);
Free(cm);
cm=cm1;
}
if (undef) {
PrintErr("Undefined goto label %s\n",undef);
Free(undef);
LexExcept(cc,"Undefined goto label at ");
}
}
U0 COCHeaderPut(CCmpCtrl *cc,I64 pass,Bool put)
{
CIntermediateCode *tmpi;
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT)) {
if (put) {
if (Bt(&cc->saved_pass_trace,pass-1)) {
"$$IV,1$$Pass %d:$$IV,0$$\n",pass-1;
tmpi=cc->coc.coc_head.next;
while (tmpi->ic_code) {
if (tmpi->ic_flags&ICF_PASS_TRACE)
ICPut(cc,tmpi);
tmpi=tmpi->next;
}
}
} else if (Bt(&cc->saved_pass_trace,pass))
"$$IV,1$$Pass %d:$$IV,0$$\n",pass;
}
cc->pass=pass;
}
U8 *COCCompile(CCmpCtrl *cc,I64 *_code_size,CDbgInfo **_dbg,I64 *_type)
{
U8 *res;
CCodeMisc *lb;
I64 i,code_size,last_code_size;
COptReg reg_offsets[REG_REGS_NUM];
if (_dbg) *_dbg=NULL;
cc->pass=0;
COCHeaderPut(cc,1,TRUE);
OptPass012(cc);
COCHeaderPut(cc,2,TRUE);
OptPass012(cc);
COCHeaderPut(cc,3,TRUE);
OptPass3(cc,reg_offsets);
COCHeaderPut(cc,4,TRUE);
OptPass4(cc,reg_offsets,_type);
COCHeaderPut(cc,5,TRUE);
OptPass5(cc);
COCHeaderPut(cc,6,TRUE);
OptPass6(cc);
COCHeaderPut(cc,7,TRUE);
lb=cc->coc.coc_next_misc;
while (lb!=&cc->coc.coc_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;
}
COCHeaderPut(cc,7,FALSE);
OptPass789A(cc,reg_offsets,NULL,NULL);
COCHeaderPut(cc,8,FALSE);
OptPass789A(cc,reg_offsets,NULL,NULL);
COCHeaderPut(cc,9,FALSE);
code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
do {
last_code_size=code_size;
COCHeaderPut(cc,9,FALSE);
code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
if (code_size>last_code_size) {
"Pass:9 Code Size\n";
LexExcept(cc,"Compiler Optimization Error at ");
}
} while (code_size<last_code_size);
if (cc->flags&CCF_AOT_COMPILE)
res=MAlloc(code_size);
else {
res=MAlloc(code_size,Fs->code_heap);
if (cc->htc.fun)
Fs->last_fun=cc->htc.fun;
}
COCHeaderPut(cc,10,FALSE);
code_size=OptPass789A(cc,reg_offsets,res,_dbg);
COCDel(cc,&cc->coc);
if (Bt(&cc->opts,OPTf_TRACE)) {
if (cc->flags&CCF_AOT_COMPILE) {
if (cc->aotc->seg_size==16)
Un(res,code_size,16);
else if (cc->aotc->seg_size==64)
Un(res,code_size,64);
else
Un(res,code_size,32);
} else
Un(res,code_size,64);
}
if (_code_size) *_code_size=code_size;
cc->saved_pass_trace=cc->pass_trace;
return res;
}
File diff suppressed because it is too large. Load diff
+729
View File
@@ -0,0 +1,729 @@
U0 PrsVarInit(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,CArrayDim *tmpad,
U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass)
{
U8 *dst=*_dst,*machine_code;
I64 i,j,r,old_flags,type,size;
CMemberLst *tmpm;
CIntermediateCode *tmpi;
CAOTCtrl *aotc=cc->aotc;
CAOTAbsAddr *tmpa;
CAOTImportExport *tmpie;
Bool is_str;
tmpc=OptClassFwd(tmpc);
if (tmpm=tmpc->member_lst_and_root) {
if (cc->token!='{')
LexExcept(cc,"Expecting '{' at ");
LexPopNoRestore(cc);
LexPush(cc);
Lex(cc);
while (tmpm) {
PrsVarInit2(cc,&dst,tmpm->member_class,&tmpm->dim,
data_addr_rip,_base,data_heap,pass);
if (cc->token==',')
Lex(cc);
tmpm=tmpm->next;
}
LexPopNoRestore(cc);
if (cc->token!='}')
LexExcept(cc,"Missing '}' at ");
Lex(cc);
} else {
if (tmpc->ptr_stars_cnt==1 &&
((tmpc-1)->raw_type==RT_I8 || (tmpc-1)->raw_type==RT_U8) &&
!tmpad && cc->token==TK_STR)
is_str=TRUE;
else
is_str=FALSE;
if (cc->flags&CCF_AOT_COMPILE && is_str) {
LexPopNoRestore(cc);
machine_code=LexExtStr(cc,&i);
if (pass==2) {
tmpa=CAlloc(sizeof(CAOTAbsAddr));
tmpa->next=aotc->abss;
tmpa->type=AAT_ADD_U64;
aotc->abss=tmpa;
tmpa->rip=data_addr_rip+dst-*_base;
*dst(I64 *)=aotc->rip;
for (j=0;j<i;j++)
AOTStoreCodeU8(cc,machine_code[j]);
}
Free(machine_code);
} else {
old_flags=cc->flags;
cc->flags=CCF_NO_ABSS | cc->flags &
~(CCF_AOT_COMPILE|CCF_HAS_MISC_DATA|CCF_NOT_CONST);
machine_code=LexExpression2Bin(cc,&type);
if (old_flags&CCF_AOT_COMPILE &&
cc->flags&CCF_NOT_CONST &&
!Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)) {
cc->flags=cc->flags&~CCF_NO_ABSS|CCF_AOT_COMPILE;
Free(machine_code);
if (pass==2) {
MemSet(dst,0,tmpc->size);
LexPopRestore(cc);
Lex(cc);
COCPush(cc);
COCInit(cc);
ICAdd(cc,IC_ABS_ADDR,data_addr_rip,tmpc+1);
ICAdd(cc,IC_IMM_I64,dst-*_base,tmpc+1);
ICAdd(cc,IC_ADD,0,tmpc+1);
if (!PrsExpression(cc,NULL,TRUE))
throw('Compiler');
tmpi=cc->coc.coc_head.last;
if (tmpi->ic_code==IC_END_EXP) {
tmpi->ic_code=IC_NOP1;
tmpi->ic_flags=0;
}
ICAdd(cc,IC_ASSIGN,0,tmpc);
ICAdd(cc,IC_END_EXP,0,tmpc,ICF_RES_NOT_USED);
ICAdd(cc,IC_RET,0,0);
if (machine_code=COCCompile(cc,&size,NULL,NULL)) {
tmpie=CAlloc(sizeof(CAOTImportExport));
tmpie->type=IET_MAIN;
tmpie->rip=cc->aotc->rip;
QueIns(tmpie,cc->aot->last_ie);
for (i=0;i<size;i++)
AOTStoreCodeU8(cc,machine_code[i]);
Free(machine_code);
}
COCPop(cc);
} else
LexPopNoRestore(cc);
} else {
LexPopNoRestore(cc);
if (!machine_code)
throw('Compiler');
r=Call(machine_code);
if (!(cc->flags & CCF_HAS_MISC_DATA)||pass==1)
Free(machine_code);
if (type==RT_F64 &&
tmpc->raw_type!=RT_F64)
r=r(F64);
else if (type!=RT_F64 &&
tmpc->raw_type==RT_F64)
r(F64)=r;
MemCpy(dst,&r,tmpc->size);
}
}
dst+=tmpc->size;
cc->flags=cc->flags&
~CCF_NO_ABSS|old_flags&(CCF_HAS_MISC_DATA|CCF_AOT_COMPILE);
}
*_dst=dst;
}
class CVI2
{
CVI2 *next,*last;
U0 base;
};
U0 PrsVarInit2(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,
CArrayDim *tmpad,U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass)
{
I64 i,j,cnt;
U8 *st,*_b;
CVI2 head,*tmpvi,*tmpvi1;
CArrayDim *tmpad1;
tmpc=OptClassFwd(tmpc);
if (tmpad1=tmpad->next) {
if (!tmpc->ptr_stars_cnt &&
(tmpc->raw_type==RT_I8 || tmpc->raw_type==RT_U8) &&
cc->token==TK_STR) {
LexPopNoRestore(cc);
st=LexExtStr(cc,&i);
if (tmpad1->cnt<0) {//[]
tmpad1->cnt=i;
tmpad->total_cnt=i*tmpad1->total_cnt;
Free(*_base);
if (data_heap)
*_base=MAlloc(i);
else
*_base=MAlloc(i,Fs->code_heap);
MemCpy(*_base,st,i);
*_dst=*_base+i;
} else {
MemCpy(*_dst,st,tmpad1->cnt);
*_dst+=tmpad1->cnt;
}
Free(st);
LexPush(cc);
} else {
if (cc->token=='{') {
LexPopNoRestore(cc);
LexPush(cc);
Lex(cc);
}
if (tmpad1->cnt<0) {//[]
QueInit(&head);
cnt=0;
while (cc->token!='}') {
tmpvi=MAlloc(offset(CVI2.base)+tmpad1->total_cnt*tmpc->size);
_b=&tmpvi->base;
PrsVarInit2(cc,&_b,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
QueIns(tmpvi,head.last);
if (cc->token==',')
Lex(cc);
cnt++;
}
Lex(cc); //skip '}'
tmpad1->cnt=cnt;
tmpad->total_cnt=cnt*tmpad1->total_cnt;
j=tmpad1->total_cnt*tmpc->size;
i=cnt*j;
Free(*_base);
if (data_heap)
*_base=_b=MAlloc(i);
else
*_base=_b=MAlloc(i,Fs->code_heap);
tmpvi=head.next;
while (tmpvi!=&head) {
tmpvi1=tmpvi->next;
MemCpy(_b,&tmpvi->base,j);
_b+=j;
Free(tmpvi);
tmpvi=tmpvi1;
}
*_dst=_b;
} else {
for (i=0;i<tmpad1->cnt;i++) {
PrsVarInit2(cc,_dst,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
if (tmpad1->cnt>1 && cc->token==',')
Lex(cc);
}
if (cc->token=='}')
Lex(cc);
}
}
} else {
PrsVarInit(cc,_dst,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
LexPush(cc);
}
}
U0 PrsGlblInit(CCmpCtrl *cc,CHashGlblVar *tmpg,I64 pass)
{
U8 *dst=tmpg->data_addr;
PrsVarInit2(cc,&dst,tmpg->var_class,&tmpg->dim,
tmpg->data_addr_rip,&tmpg->data_addr,
Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)||
Bt(&cc->flags,CCf_AOT_COMPILE),pass);
}
U0 PrsStaticInit(CCmpCtrl *cc,CMemberLst *tmpm,I64 pass)
{
U8 *machine_code,*dst=tmpm->static_data;
CHashClass *tmpc=tmpm->member_class;
I64 i,size;
CAOTImportExport *tmpie;
if (cc->flags&CCF_AOT_COMPILE && pass==2) {
COCPush(cc);
COCInit(cc);
}
PrsVarInit2(cc,&dst,tmpc,&tmpm->dim,tmpm->static_data_rip,
&tmpm->static_data,Bt(&cc->flags,CCf_AOT_COMPILE),pass);
if (cc->flags&CCF_AOT_COMPILE && pass==2) {
if (cc->coc.coc_head.next!=&cc->coc.coc_head) {
ICAdd(cc,IC_RET,0,0);
if (machine_code=COCCompile(cc,&size,NULL,NULL)) {
if (pass==2) {
tmpie=CAlloc(sizeof(CAOTImportExport));
tmpie->type=IET_MAIN;
tmpie->rip=cc->aotc->rip;
QueIns(tmpie,cc->aot->last_ie);
for (i=0;i<size;i++)
AOTStoreCodeU8(cc,machine_code[i]);
}
Free(machine_code);
}
} //TODO: else del misc?
COCPop(cc);
}
}
Bool PrsArrayDims(CCmpCtrl *cc,I64 mode,CArrayDim *dim)
{//Returns false on empty []
//dim->next!=0 for array
CArrayDim *tmpad,*tmpad1;
I64 j;
Bool res=TRUE;
dim->next=NULL;
dim->cnt=0;
dim->total_cnt=1;
tmpad1=&dim->next;
if (cc->token=='[') {
if (mode.u8[1]==PRS1B_FUN_ARG)
LexExcept(cc,"No arrays in fun args at ");
do {
if (Lex(cc)==']' && !dim->next) {
j=-1;
res=FALSE;
} else {
if ((j=LexExpressionI64(cc))<0)
LexExcept(cc,"Invalid array size at ");
}
tmpad1=&dim->next;
while (tmpad1->next) {
tmpad1->next->total_cnt*=j;
tmpad1=tmpad1->next;
}
tmpad=MAlloc(sizeof(CArrayDim));
tmpad1->next=tmpad;
tmpad1=tmpad;
tmpad->next=NULL;
tmpad->cnt=j;
tmpad->total_cnt=1;
dim->total_cnt*=j;
if (cc->token!=']')
LexExcept(cc,"Missing ']' at ");
} while (Lex(cc)=='[');
}
return res;
}
CHashClass *PrsType(CCmpCtrl *cc,CHashClass **_tmpc1,
I64 *_mode,CMemberLst *tmpm,U8 **_ident,CHashFun **_fun_ptr,
CHashExport **_tmpex,CArrayDim *tmpad,I64 fsp_flags)
{
I64 k,ptr_stars_cnt,mode=*_mode;
CHashClass *tmpc1=*_tmpc1,*tmpc2;
CHashFun *fun_ptr=NULL;
CHashExport *tmpex=NULL;
CArrayDim *tmpad2;
pt_start:
if (!tmpc1 || !(tmpc1->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
LexExcept(cc,"Invalid class at ");
ptr_stars_cnt=0;
while (cc->token=='*') {
if (mode.u8[1]) {
LexPopNoRestore(cc);
LexPush(cc);
}
Lex(cc);
tmpc1++;
if (++ptr_stars_cnt>PTR_STARS_NUM)
LexExcept(cc,"Too many *'s at ");
}
k=PrsKeyWord(cc);
if (k==KW_UNION || k==KW_CLASS) {
Lex(cc);
tmpc2=PrsClass(cc,k,fsp_flags,mode&255==PRS0_EXTERN);
tmpc2->fwd_class=tmpc1;
tmpc1=tmpc2;
if (_tmpc1) *_tmpc1=tmpc1;
mode=PRS0_NULL|PRS1_NULL;
goto pt_start;
}
if (cc->token=='(') {
if (Lex(cc)!='*')
LexExcept(cc,"Expecting '*' at ");
ptr_stars_cnt=1; //fun_ptr
while (Lex(cc)=='*')
ptr_stars_cnt++; //fun_ptr
if (ptr_stars_cnt>PTR_STARS_NUM)
LexExcept(cc,"Too many *'s at ");
} else
ptr_stars_cnt=-1; //fun_ptr
if (_ident) {
if (cc->token==TK_IDENT) {
tmpex=cc->hash_entry;
*_ident=cc->cur_str;
cc->cur_str=NULL;
Lex(cc);
} else {
if (!mode.u8[1])
*_ident=NULL;
else if (cc->token==',' || cc->token==';' || cc->token==')') {
tmpex=NULL;
*_ident=StrNew("_anon_");
tmpm->flags|=MLF_NO_UNUSED_WARN;
} else
LexExcept(cc,"Expecting identifier at ");
}
}
if (ptr_stars_cnt>=0) { //fun_ptr
if (cc->token!=')')
LexExcept(cc,"Missing ')' at ");
if (Lex(cc)!='(')
LexExcept(cc,"Expecting '(' at ");
fun_ptr=PrsFunJoin(cc,tmpc1,NULL,fsp_flags)+ptr_stars_cnt;
tmpc1=cmp.internal_types[RT_PTR]+ptr_stars_cnt;
}
if (!PrsArrayDims(cc,mode,tmpad) && cc->token!='=') {
tmpc1++;
tmpad2=tmpad->next->next;
Free(tmpad->next);
tmpad->next=tmpad2;
}
tmpc2=OptClassFwd(tmpc1);
if (tmpc2->ptr_stars_cnt) {
tmpc2-=tmpc2->ptr_stars_cnt;
if (tmpc2->type&HTT_INTERNAL_TYPE && !tmpc2->size)
LexWarn(cc,"use \"U8 *\" instead of \"U0 *\" at ");
}
if (_mode) *_mode=mode;
if (_fun_ptr) *_fun_ptr=fun_ptr;
if (_tmpex) *_tmpex=tmpex;
return tmpc1;
}
U0 PrsDotDotDot(CCmpCtrl *cc,CHashFun *tmpf,I64 _reg)
{
CMemberLst *tmpm;
CArrayDim *tmpad;
Bts(&tmpf->flags,Ff_DOT_DOT_DOT);
Lex(cc);
tmpm=MemberLstNew(_reg);
tmpm->flags=MLF_DOT_DOT_DOT;
tmpm->member_class=cmp.internal_types[RT_I64];
tmpm->str=StrNew("argc");
tmpm->offset=tmpf->size;
tmpm->size=8;
tmpf->size+=8;
MemberAdd(cc,tmpm,tmpf,PRS1B_FUN_ARG);
tmpm=MemberLstNew(_reg);
tmpm->flags=MLF_DOT_DOT_DOT;
tmpm->member_class=cmp.internal_types[RT_I64];
tmpm->str=StrNew("argv");
tmpm->dim.total_cnt=127; //arbitrary
tmpm->dim.next=tmpad=MAlloc(sizeof(CArrayDim));
tmpad->next=NULL;
tmpad->cnt=127; //arbitrary
tmpad->total_cnt=1;
tmpm->offset=tmpf->size;
tmpm->size=8; //Close enough
tmpf->size+=8;//Close enough
MemberAdd(cc,tmpm,tmpf,PRS1B_FUN_ARG);
if (cc->token==')')
Lex(cc);
}
U0 PrsVarLst(CCmpCtrl *cc,CHashClass *tmpc,I64 mode,I64 union_base=0)
{
I64 i,k,old_flags=cc->flags,old_flags2,type,_reg;
CHashClass *tmpc1,*tmpc2;
CHash *tmph;
CMemberLst *tmpm;
CMemberLstMeta *tmp_meta;
U8 *machine_code;
Bool undef_array_size,first;
cc->flags|=CCF_DONT_MAKE_RES;
if (mode.u8[1]==PRS1B_CLASS)
cc->flags|=CCF_CLASS_DOL_OFFSET;
if ((mode.u8[1]!=PRS1B_LOCAL_VAR && mode.u8[1]!=PRS1B_STATIC_LOCAL_VAR ||
mode&PRSF_UNION) && (cc->token=='(' || cc->token=='{'))
Lex(cc);
while (TRUE) {
if (mode&PRSF_UNION)
cc->class_dol_offset=union_base;
else
cc->class_dol_offset=tmpc->size;
while (cc->token==';')
Lex(cc);
while (cc->token=='$$') {
if (Lex(cc)!='=') //skip $$
LexExcept(cc,"Expecting '=' at ");
Lex(cc); //skip =
cc->class_dol_offset=LexExpression(cc);
if (-cc->class_dol_offset>tmpc->neg_offset)
tmpc->neg_offset=-cc->class_dol_offset;
if (mode&PRSF_UNION)
union_base=cc->class_dol_offset;
else
tmpc->size=cc->class_dol_offset;
if (cc->token!=';')
LexExcept(cc,"Missing ';' at");
Lex(cc); //skip ;
}
if (cc->token==')' || cc->token=='}') {
Lex(cc);
goto pvl_done;
}
_reg=REG_UNDEF;
pvl_restart1:
switch (PrsKeyWord(cc)) {
case KW_REG:
_reg=REG_ALLOC;
if (Lex(cc)==TK_IDENT) {
k=DefineMatch(cc->cur_str,"ST_U64_REGS");
if (k>=0) {
_reg=k;
Lex(cc);
}
}
goto pvl_restart1;
case KW_NOREG:
_reg=REG_NONE;
Lex(cc);
goto pvl_restart1;
}
if (cc->token==TK_ELLIPSIS && mode.u8[1]==PRS1B_FUN_ARG) {
PrsDotDotDot(cc,tmpc,_reg);
goto pvl_done;
}
if (cc->token==TK_IDENT)
tmph=cc->hash_entry;
else
tmph=NULL;
if (!tmph)
LexExcept(cc,"Expecting type at ");
k=PrsKeyWord(cc);
if (k==KW_UNION) {
Lex(cc);
PrsVarLst(cc,tmpc,mode|PRSF_UNION,tmpc->size);
} else {
if (!(tmph->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
LexExcept(cc,"Expecting type at ");
first=TRUE;
pvl_restart2:
tmpc1=tmph;
LexPush(cc);
Lex(cc); //skip type or ','
tmpm=MemberLstNew(_reg);
_reg=REG_UNDEF;
if (mode.u8[1]==PRS1B_STATIC_LOCAL_VAR) {
tmpm->flags|=MLF_STATIC;
tmpm->reg=REG_NONE;
}
if (mode.u8[1]==PRS1B_FUN_ARG || mode.u8[1]==PRS1B_LOCAL_VAR) {
pvl_restart3:
switch (PrsKeyWord(cc)) {
case KW_REG:
tmpm->reg=REG_ALLOC;
LexPopNoRestore(cc);
LexPush(cc);
if (Lex(cc)==TK_IDENT) {
k=DefineMatch(cc->cur_str,"ST_U64_REGS");
if (k>=0) {
tmpm->reg=k;
LexPopNoRestore(cc);
LexPush(cc);
Lex(cc);
}
}
goto pvl_restart3;
case KW_NOREG:
tmpm->reg=REG_NONE;
LexPopNoRestore(cc);
LexPush(cc);
Lex(cc);
goto pvl_restart3;
}
}
tmpm->member_class=PrsType(cc,&tmpc1,&mode,tmpm,&tmpm->str,
&tmpm->fun_ptr,NULL,&tmpm->dim,0);
if (tmpm->fun_ptr)
tmpm->flags|=MLF_FUN;
if (first)
MemberAdd(cc,tmpm,tmpc,mode.u8[1]);
else
MemberAdd(cc,tmpm,tmpc,PRS1B_NULL);
tmpc->member_cnt++;
tmpc2=tmpm->member_class;
i=tmpc2->size*tmpm->dim.total_cnt;
switch (mode.u8[1]) {
case PRS1B_STATIC_LOCAL_VAR:
if (i<0) {
i=0;
undef_array_size=TRUE;
} else
undef_array_size=FALSE;
if (mode&PRSF_UNION)
LexExcept(cc,"Static unions are not implemented ");
k=(i+7)&~7;
if (cc->flags&CCF_AOT_COMPILE)
tmpm->static_data=MAlloc(k);
else
tmpm->static_data=MAlloc(k,Fs->code_heap);
if (cc->flags&CCF_AOT_COMPILE) {
tmpm->static_data_rip=cc->aotc->rip;
k>>=3;
while (k--)
AOTStoreCodeU64(cc,0);
} else
if (sys_var_init_flag)
MemSet(tmpm->static_data,sys_var_init_val,k);
LexPopNoRestore(cc);
if (cc->token=='=') {
cc->flags=cc->flags&
~CCF_DONT_MAKE_RES|old_flags&CCF_DONT_MAKE_RES;
if (undef_array_size) {
LexPush(cc);
LexPush(cc);
Lex(cc); //skip =
PrsStaticInit(cc,tmpm,1);
LexPopNoRestore(cc);
i=tmpc2->size*tmpm->dim.total_cnt;
k=(i+7)&~7;
if (cc->flags&CCF_AOT_COMPILE) {
k>>=3;
while (k--)
AOTStoreCodeU64(cc,0);
} else
if (sys_var_init_flag)
MemSet(tmpm->static_data,sys_var_init_val,k);
LexPopRestore(cc);
}
LexPush(cc);
Lex(cc); //skip =
PrsStaticInit(cc,tmpm,2);
LexPopNoRestore(cc);
if (cc->flags&CCF_AOT_COMPILE)
for (k=0;k<i;k++)
AOTStoreCodeU8At(cc,tmpm->static_data_rip+k,
tmpm->static_data[k]);
tmpm->use_cnt=0;
cc->flags|=CCF_DONT_MAKE_RES;
}
if (cc->flags&CCF_AOT_COMPILE)
Free(tmpm->static_data);
break;
case PRS1B_LOCAL_VAR:
if (mode&PRSF_UNION) {
if (union_base-tmpc->size<i)
i=union_base-i-tmpc->size;
else
i=0;
}
if (i>=8)
tmpc->size=(tmpc->size-i)&~7;
else if (i>=4)
tmpc->size=(tmpc->size-i)&~3;
else if (i>=2)
tmpc->size=(tmpc->size-i)&~1;
else
tmpc->size-=i;
tmpm->offset=tmpc->size;
tmpm->size=i;
if (cc->token=='=') {
cc->flags=cc->flags&~CCF_DONT_MAKE_RES|
old_flags&CCF_DONT_MAKE_RES;
LexPopRestore(cc);
Lex(cc);
if (!PrsExpression(cc,NULL,TRUE))
throw('Compiler');
tmpm->use_cnt=0;
cc->flags|=CCF_DONT_MAKE_RES;
} else
LexPopNoRestore(cc);
break;
case PRS1B_FUN_ARG:
if (mode&PRSF_UNION) {
tmpm->offset=union_base;
if (tmpc->size-union_base<8)
tmpc->size=8+union_base;
} else {
tmpm->offset=tmpc->size;
tmpc->size+=8;
}
tmpm->size=8;
if (cc->token=='=') {
Lex(cc);
if (PrsKeyWord(cc)==KW_LASTCLASS) {
tmpm->flags|=MLF_LASTCLASS;
Lex(cc);
} else {
old_flags2=cc->flags;
cc->flags&=~CCF_HAS_MISC_DATA;
machine_code=LexExpression2Bin(cc,&type);
if (!machine_code)
throw('Compiler');
tmpm->dft_val=Call(machine_code);
tmpc2=OptClassFwd(tmpc2);
if (tmpc2->raw_type==RT_F64) {
if (type!=RT_F64)
tmpm->dft_val(F64)=tmpm->dft_val;
} else {
if (type==RT_F64)
tmpm->dft_val=tmpm->dft_val(F64);
}
if (cc->flags & CCF_HAS_MISC_DATA) {
tmpm->dft_val=StrNew(tmpm->dft_val);
tmpm->flags|=MLF_STR_DFT_AVAILABLE;
}
Free(machine_code);
cc->flags|=old_flags2&CCF_HAS_MISC_DATA;
}
tmpm->flags|=MLF_DFT_AVAILABLE;
}
LexPopNoRestore(cc);
break;
case PRS1B_CLASS:
if (mode&PRSF_UNION) {
tmpm->offset=union_base;
if (tmpc->size-union_base<i)
tmpc->size=i+union_base;
} else {
tmpm->offset=tmpc->size;
tmpc->size+=i;
}
tmpm->size=i;
if (mode&PRSF_UNION)
cc->class_dol_offset=union_base;
else
cc->class_dol_offset=tmpc->size;
while (cc->token==TK_IDENT) {
tmp_meta=MAlloc(sizeof(CMemberLstMeta));
tmp_meta->next=tmpm->meta;
tmpm->meta=tmp_meta;
tmp_meta->str=cc->cur_str;
tmp_meta->flags=0;
cc->cur_str=NULL;
if (Lex(cc)==TK_STR) {
tmp_meta->user_data=LexExtStr(cc);
tmp_meta->flags|=MLMF_IS_STR;
} else
tmp_meta->user_data=LexExpression(cc);
}
LexPopNoRestore(cc);
break;
}
switch (cc->token) {
case ',':
if (mode.u8[1]==PRS1B_FUN_ARG && !(mode&PRSF_UNION))
Lex(cc);
else {
first=FALSE;
goto pvl_restart2;
}
break;
case ')':
case '}':
Lex(cc);
goto pvl_done;
case ';':
cc->flags=cc->flags&~CCF_DONT_MAKE_RES|
old_flags&CCF_DONT_MAKE_RES;
Lex(cc);
cc->flags|=CCF_DONT_MAKE_RES;
if ((mode.u8[1]==PRS1B_LOCAL_VAR||mode.u8[1]==
PRS1B_STATIC_LOCAL_VAR) && !(mode&PRSF_UNION))
goto pvl_done;
break;
default:
LexExcept(cc,"Missing ';' at");
}
}
}
pvl_done:
cc->flags=cc->flags&~(CCF_CLASS_DOL_OFFSET|CCF_DONT_MAKE_RES)|
old_flags&(CCF_CLASS_DOL_OFFSET|CCF_DONT_MAKE_RES);
}
+512
View File
@@ -0,0 +1,512 @@
asm {
//************************************
CMP_TEMPLATES::
DU32 @@05,@@10,@@15,@@25,@@30,
@@35,@@40,@@45,@@55,@@60,
@@75,@@80,@@85,@@90,@@95,
@@100,@@105,@@110,@@120,@@130;
@@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_EQU
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_EQU
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: //Sqr
PUSH RAX
FLD U64 [RSP]
FMUL ST0,ST0
FSTP U64 [RSP]
POP RAX
@@90: //Abs
PUSH RAX
FLD U64 [RSP]
FABS
FSTP U64 [RSP]
POP RAX
@@95: //Sqrt
PUSH RAX
FLD U64 [RSP]
FSQRT
FSTP U64 [RSP]
POP RAX
@@100: //Sin
PUSH RAX
FLD U64 [RSP]
FSIN
FSTP U64 [RSP]
POP RAX
@@105: //Cos
PUSH RAX
FLD U64 [RSP]
FCOS
FSTP U64 [RSP]
POP RAX
@@110: //Tan
PUSH RAX
FLD U64 [RSP]
@@115: FPTAN
FSTSW
TEST AX,0x400
JNZ @@115
FFREE ST0
FINCSTP
FSTP U64 [RSP]
POP RAX
@@120: //Atan
PUSH RAX
FLD U64 [RSP]
FLD1
@@125: FPATAN
FSTSW
TEST AX,0x400
JNZ @@125
FSTP U64 [RSP]
POP RAX
@@130:
//************************************
CMP_TEMPLATES_DONT_POP::
DU32 @@05,@@10,@@15,@@20,@@25,
@@30,@@35,@@40,@@45,@@50,
@@55,@@60,@@65,@@70,@@75,
@@80,@@85,@@90,@@100,@@110;
@@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: //Sqr
PUSH RAX
FLD U64 [RSP]
FMUL ST0,ST0
ADD RSP,8
@@70: //Abs
PUSH RAX
FLD U64 [RSP]
FABS
ADD RSP,8
@@75: //Sqrt
PUSH RAX
FLD U64 [RSP]
FSQRT
ADD RSP,8
@@80: //Sin
PUSH RAX
FLD U64 [RSP]
FSIN
ADD RSP,8
@@85: //Cos
PUSH RAX
FLD U64 [RSP]
FCOS
ADD RSP,8
@@90: //Tan
PUSH RAX
FLD U64 [RSP]
@@95: FPTAN
FSTSW
TEST AX,0x400
JNZ @@95
FFREE ST0
FINCSTP
ADD RSP,8
@@100: //Atan
PUSH RAX
FLD U64 [RSP]
FLD1
@@105: FPATAN
FSTSW
TEST AX,0x400
JNZ @@105
ADD RSP,8
@@110:
//************************************
CMP_TEMPLATES_DONT_PUSH::
DU32 @@05,@@10,@@15,@@20,@@30,
@@35,@@40,@@50,@@55,@@60,
@@65,@@70,@@75,@@80,@@85,
@@90,@@95,@@100,@@110,@@120;
@@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_EQU
PUSH RAX
FLD U64 [RSP]
FCOMIP ST0,ST1
MOV RAX,1
SBB RAX,0
FFREE ST0
FINCSTP
ADD RSP,8
@@40: //GREATER_EQU
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: //Sqr
SUB RSP,8
FMUL ST0,ST0
FSTP U64 [RSP]
POP RAX
@@80: //Abs
SUB RSP,8
FABS
FSTP U64 [RSP]
POP RAX
@@85: //Sqrt
SUB RSP,8
FSQRT
FSTP U64 [RSP]
POP RAX
@@90: //Sin
SUB RSP,8
FSIN
FSTP U64 [RSP]
POP RAX
@@95: //Cos
SUB RSP,8
FCOS
FSTP U64 [RSP]
POP RAX
@@100: //Tan
SUB RSP,8
@@105: FPTAN
FSTSW
TEST AX,0x400
JNZ @@105
FFREE ST0
FINCSTP
FSTP U64 [RSP]
POP RAX
@@110: //Atan
SUB RSP,8
FLD1
@@115: FPATAN
FSTSW
TEST AX,0x400
JNZ @@115
FSTP U64 [RSP]
POP RAX
@@120:
//************************************
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,@@105;
@@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: //Sqr
FMUL ST0,ST0
@@70: //Abs
FABS
@@75: //Sqrt
FSQRT
@@80: //Sin
FSIN
@@85: //Cos
FCOS
@@90: //Tan
FPTAN
FSTSW
TEST AX,0x400
JNZ @@90
FFREE ST0
FINCSTP
@@95: //Atan
FLD1
@@100: FPATAN
FSTSW
TEST AX,0x400
JNZ @@100
@@105:
//************************************
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;
@@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_EQU
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_EQU
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:
}
+682
View File
@@ -0,0 +1,682 @@
I64 InstEntriesCompare(CInst *tmpins1,CInst *tmpins2)
{
I64 i1,i2,j=0,res=0,oc_cnt1=tmpins1->opcode_cnt,oc_cnt2=tmpins2->opcode_cnt;
if (tmpins1->flags&IEF_STI_LIKE)
oc_cnt1--;
if (tmpins2->flags&IEF_STI_LIKE)
oc_cnt2--;
while (TRUE) {
if (j<oc_cnt1 && j<oc_cnt2) {
if (res=tmpins1->opcode[j]-tmpins2->opcode[j])
return res;
j++;
} else {
if (res=oc_cnt1-oc_cnt2)
return res;
if (tmpins1->flags&IEF_STI_LIKE && tmpins2->flags&IEF_STI_LIKE)
return tmpins1->opcode[j]-tmpins2->opcode[j];
if (res=tmpins1->flags&IEF_STI_LIKE - tmpins2->flags&IEF_STI_LIKE)
return res;
if (res=tmpins1->slash_val-tmpins2->slash_val)
return res;
if (res=tmpins1->flags&IEF_OP_SIZE32 - tmpins2->flags&IEF_OP_SIZE32)
return res;
i1=Bt(&uasm.ins64_arg_mask,tmpins1->arg1) ||
Bt(&uasm.ins64_arg_mask,tmpins1->arg2);
i2=Bt(&uasm.ins64_arg_mask,tmpins2->arg1) ||
Bt(&uasm.ins64_arg_mask,tmpins2->arg2);
if (res=i1-i2)
return res;
if (res=tmpins1->flags&IEF_48_REX - tmpins2->flags&IEF_48_REX)
return res;
i1=tmpins1->arg2==ARGT_IMM64 || tmpins1->arg2==ARGT_UIMM64;
i2=tmpins2->arg2==ARGT_IMM64 || tmpins2->arg2==ARGT_UIMM64;
return i1-i2;
}
}
}
/*
U0 DumpUAsmIns(CInst *tmpins)
{
CHashOpcode *tmpo=tmpins(U8 *)-tmpins->ins_entry_num*sizeof(CInst)
-offset(CHashOpcode.ins);
"%10s:%02d,%02d SV:%02d\n",tmpo->str,
tmpins->arg1,tmpins->arg2,tmpins->slash_val;
}
U0 DumpUAsmTables()
{
I64 k;
"16/32 Bit Table\n";
for (k=0;k<uasm.table_16_32_entries;k++)
DumpUAsmIns(uasm.table_16_32[k]);
"\n\n\n\n64 Bit Table\n";
for (k=0;k<uasm.table_64_entries;k++)
DumpUAsmIns(uasm.table_64[k]);
}
*/
CInst *InstEntryFind(U8 *rip,I64 opsize,I64 seg_size)
{//Binary Search
I64 i,j,n,m,k,arg1,arg2,o1,o2,oc_cnt;
CInst *tmpins,**table;
i=0;
if (seg_size==64) {
table=uasm.table_64;
j=uasm.table_64_entries-1;
} else {
table=uasm.table_16_32;
j=uasm.table_16_32_entries-1;
}
while (TRUE) {
k=(i+j)>>1; //binary search
tmpins=table[k];
//DumpUAsmIns(tmpins);
m=0;
n=0;
while (TRUE) { //ief_compare_start
arg1=tmpins->arg1;
arg2=tmpins->arg2;
oc_cnt=tmpins->opcode_cnt;
if (tmpins->flags&IEF_STI_LIKE)
oc_cnt--;
if (n<oc_cnt) {
o1=rip[n];
if (n==tmpins->opcode_cnt-1 && tmpins->flags & IEF_PLUS_OPCODE)
o1&=-8;
o2=tmpins->opcode[n++];
if (m=o1-o2)
goto ief_compare_done;
} else
switch [tmpins->uasm_slash_val] {
case 0...7:
if (!(m=rip[n]>>3&7-tmpins->slash_val)) {
if ((Bt(&uasm.mem_arg_mask,arg1) ||
Bt(&uasm.mem_arg_mask,arg2)) &&
rip[n]&0xC0==0xC0) {
m=1;
goto ief_compare_done;
}
if (opsize==16) {
if (tmpins->flags & IEF_OP_SIZE32) {
m=-1;
goto ief_compare_done;
}
} else {
if (tmpins->flags & IEF_OP_SIZE16) {
m=1;
goto ief_compare_done;
}
}
if (opsize==64||arg1==ARGT_M64||arg2==ARGT_M64) {
if (!Bt(&uasm.ins64_arg_mask,arg1)&&
!Bt(&uasm.ins64_arg_mask,arg2)&&
!(tmpins->flags&IEF_48_REX))
m=1;
} else {
if (Bt(&uasm.ins64_arg_mask,arg1)||
Bt(&uasm.ins64_arg_mask,arg2) ||
tmpins->flags&IEF_48_REX)
m=-1;
}
} else if ((Bt(&uasm.mem_arg_mask,arg1)||
Bt(&uasm.mem_arg_mask,arg2)) &&
rip[n]&0xC0==0xC0)
m=1;
goto ief_compare_done;
case SV_I_REG:
m=rip[n]>>3-tmpins->opcode[tmpins->opcode_cnt-1]>>3;
goto ief_compare_done;
case SV_STI_LIKE:
if (!(m=rip[n]>>3-tmpins->opcode[tmpins->opcode_cnt-1]>>3))
m=rip[n]-tmpins->opcode[tmpins->opcode_cnt-1];
goto ief_compare_done;
case SV_R_REG:
case SV_NONE:
m=0;
if (opsize==16) {
if (tmpins->flags & IEF_OP_SIZE32) {
m=-1;
goto ief_compare_done;
}
} else {
if (tmpins->flags & IEF_OP_SIZE16) {
m=1;
goto ief_compare_done;
}
}
if (opsize==64 || arg1==ARGT_M64 || arg2==ARGT_M64) {
if (!Bt(&uasm.ins64_arg_mask,arg1) &&
!Bt(&uasm.ins64_arg_mask,arg2) &&
!(tmpins->flags&IEF_48_REX)&& !(arg2==ARGT_NONE &&
(ARGT_UIMM8<=arg1<=ARGT_UIMM64 ||
ARGT_IMM8<=arg1<=ARGT_IMM64)))
m=1;
else if (tmpins->arg2==ARGT_IMM64 || tmpins->arg2==ARGT_UIMM64) {
if (arg2!=ARGT_IMM64&&arg2!=ARGT_UIMM64)
m=1;
} else if (arg2==ARGT_IMM64||arg2==ARGT_UIMM64)
m=-1;
} else {
if (Bt(&uasm.ins64_arg_mask,arg1) ||
Bt(&uasm.ins64_arg_mask,arg2) ||
tmpins->flags&IEF_48_REX)
m=-1;
}
goto ief_compare_done;
}
}
ief_compare_done:
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 table[k];
}
U0 UAsmHashLoad()
{
CHashOpcode *tmph;
CInst *tmpins;
I64 i,j1,j2,k;
uasm.ins64_arg_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_arg_mask=1<<ARGT_M8+1<<ARGT_M16+1<<ARGT_M32+1<<ARGT_M64;
uasm.table_16_32_entries=uasm.table_64_entries=0;
for (i=0;i<=cmp.asm_hash->mask;i++) {
tmph=cmp.asm_hash->body[i];
while (tmph) {
if (tmph->type==HTT_OPCODE && !(tmph->oc_flags&OCF_ALIAS)) {
tmpins=&tmph->ins;
for (k=0;k<tmph->inst_entry_cnt;k++) {
uasm.table_16_32_entries++;
if (!(tmpins->flags&IEF_NOT_IN_64_BIT))
uasm.table_64_entries++;
tmpins++;
}
}
tmph=tmph->next;
}
}
j1=j2=0;
uasm.table_16_32=MAlloc(uasm.table_16_32_entries*sizeof(U8 *));
uasm.table_64 =MAlloc(uasm.table_64_entries *sizeof(U8 *));
for (i=0;i<=cmp.asm_hash->mask;i++) {
tmph=cmp.asm_hash->body[i];
while (tmph) {
if (tmph->type==HTT_OPCODE && !(tmph->oc_flags&OCF_ALIAS)) {
tmpins=&tmph->ins;
for (k=0;k<tmph->inst_entry_cnt;k++) {
uasm.table_16_32[j1++]=tmpins;
if (!(tmpins->flags&IEF_NOT_IN_64_BIT))
uasm.table_64[j2++]=tmpins;
tmpins++;
}
}
tmph=tmph->next;
}
}
QSortI64(uasm.table_16_32,uasm.table_16_32_entries,&InstEntriesCompare);
QSortI64(uasm.table_64 ,uasm.table_64_entries ,&InstEntriesCompare);
}
U0 Ui(U8 *buf,U8 **_rip,I64 seg_size=64,I64 *_jmp_dst=NULL,Bool just_ins=FALSE)
{//Unassembles one inst
I64 i,disp,imm,opsize,opadd,
arg1,arg2,reloced_arg1,reloced_arg2,
arg1_size=0,arg2_size=0,reloced_arg1_size,reloced_arg2_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;
CInst *tmpins,*tmpins2;
CHashOpcode *tmpo;
U8 *rip=*_rip,*ptr,*reloced_arg1_st,*reloced_arg2_st,
*bin_data_area1,*bin_data_area2,
line1[512],line2[512],buf2[512],arg1_st[512],
arg2_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;
}
*arg1_st=0;
*arg2_st=0;
if (!IsRaw && PutSrcLink(rip,1,line1))
CatPrint(line1,"\n");
else
*line1=0;
StrPrint(line1+StrLen(line1),"%24tp ",rip);
bin_data_area1=line1+StrLen(line1);
for (i=0;i<6;i++)
CatPrint(line1,"%02X",rip[i]);
CatPrint(line1," ");
StrPrint(line2,"%24tp ",rip+6);
bin_data_area2=line2+StrLen(line2);
for (i=6;i<12;i++)
CatPrint(line2,"%02X",rip[i]);
*seg_overrides=0;
cont=TRUE;
while (TRUE) {
switch (*rip) {
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;
case 0x40...0x4F:
if (seg_size==64) {
REX=*rip;
if (REX>=0x48)
opsize=64;
REX_b=Bt(&REX,0)<<3;
REX_x=Bt(&REX,1)<<3;
REX_r=Bt(&REX,2)<<3;
break;
} //Fall thru if !64
default:
cont=FALSE;
}
if (cont)
rip++;
else
break;
}
tmpins=InstEntryFind(rip,opsize,seg_size);
if (opsize==32 && seg_size==64) {
tmpins2=InstEntryFind(rip,64,seg_size);
if (tmpins2!=tmpins && tmpins2->flags&IEF_REX_ONLY_R8_R15 ||
tmpins2->flags&IEF_REX_XOR_LIKE&& rip[1]>>3&7==rip[1]&7)
tmpins=tmpins2;
}
rip+=tmpins->opcode_cnt;
tmpo=tmpins(U8 *)-tmpins->ins_entry_num*sizeof(CInst)
-offset(CHashOpcode.ins);
if (just_ins)
*line1=0;
CatPrint(line1,tmpo->str);
arg1=tmpins->arg1;
arg2=tmpins->arg2;
if (arg1_size=tmpins->size1) {
if (Bt(&uasm.signed_arg_mask,arg1))
CatPrint(arg1_st,"I%d ",arg1_size);
else
CatPrint(arg1_st,"U%d ",arg1_size);
}
if (arg2_size=tmpins->size2) {
if (Bt(&uasm.signed_arg_mask,arg2))
CatPrint(arg2_st,"I%d ",arg2_size);
else
CatPrint(arg2_st,"U%d ",arg2_size);
}
if (tmpins->flags & IEF_PLUS_OPCODE) {
rip--;
RM1=*rip++ - tmpins->opcode[tmpins->opcode_cnt-1]+REX_b;
ptr=NULL;
if (ARGT_R8<=arg1<=ARGT_R64) {
if (arg1_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (arg1_size==16)
ptr="ST_U16_REGS";
else if (arg1_size==32)
ptr="ST_U32_REGS";
else if (arg1_size==64)
ptr="ST_U64_REGS";
if (ptr)
CatPrint(arg1_st,"%Z",RM1,ptr);
} else {
if (arg2_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (arg2_size==16)
ptr="ST_U16_REGS";
else if (arg2_size==32)
ptr="ST_U32_REGS";
else if (arg2_size==64)
ptr="ST_U64_REGS";
if (ptr)
CatPrint(arg2_st,"%Z",RM1,ptr);
}
}
if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_M8<=arg1<=ARGT_M64 ||
ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
if (ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
reloced_arg1=arg2;
reloced_arg2=arg1;
reloced_arg1_size=arg2_size;
reloced_arg2_size=arg1_size;
reloced_arg1_st=arg2_st;
reloced_arg2_st=arg1_st;
} else {
reloced_arg1=arg1;
reloced_arg2=arg2;
reloced_arg1_size=arg1_size;
reloced_arg2_size=arg2_size;
reloced_arg1_st=arg1_st;
reloced_arg2_st=arg2_st;
}
CatPrint(reloced_arg1_st,seg_overrides);
ModrM=*rip++;
Mod=ModrM>>6 & 3;
RM1=ModrM & 7+REX_b;
RM2=ModrM>>3 & 7+REX_r;
if (Mod<3 && RM1&7==4)
SIB=*rip++;
if (Mod==1) {
disp=*rip(U8 *)++;
CatPrint(reloced_arg1_st,"%02X",disp);
} else if (Mod==2) {
disp=*rip(U32 *)++;
CatPrint(reloced_arg1_st,"%08X",disp);
}
if (tmpins->slash_val<8)
RM2=-1;
else {
ptr=NULL;
if (reloced_arg2==ARGT_SREG) {
if (RM2<=5)
ptr="ST_SEG_REGS";
} else if (!(ARGT_IMM8<=reloced_arg2<=ARGT_IMM64) &&
!(ARGT_UIMM8<=reloced_arg2<=ARGT_UIMM64)) {
if (reloced_arg2_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (reloced_arg2_size==16)
ptr="ST_U16_REGS";
else if (reloced_arg2_size==32)
ptr="ST_U32_REGS";
else if (reloced_arg2_size==64)
ptr="ST_U64_REGS";
}
if (ptr)
CatPrint(reloced_arg2_st,"%Z",RM2,ptr);
}
if (RM1&7==5 && !Mod) {
disp=*rip(I32 *)++;
if (seg_size==64) {
disp+=rip;
if (reloced_arg2==ARGT_IMM8 || reloced_arg2==ARGT_UIMM8)
disp++;
else if (reloced_arg2==ARGT_IMM16 || reloced_arg2==ARGT_UIMM16)
disp+=2;
else if (reloced_arg2==ARGT_IMM32 || reloced_arg2==ARGT_UIMM32)
disp+=4;
else if (reloced_arg2==ARGT_IMM64 || reloced_arg2==ARGT_UIMM64)
disp+=8;
}
CatPrint(reloced_arg1_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=*rip(U32 *)++;
CatPrint(reloced_arg1_st,"%08X[%Z*%d]",disp,r2,ptr,scale);
} else if (r2==4)
CatPrint(reloced_arg1_st,"[%Z]",r1,ptr);
else
CatPrint(reloced_arg1_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_arg1_st,"[%Z]",RM1,ptr);
}
} else {
ptr=NULL;
if (reloced_arg1_size==8) {
if (REX!=-1)
ptr="ST_U8_REX_REGS";
else
ptr="ST_U8_REGS";
} else if (reloced_arg1_size==16)
ptr="ST_U16_REGS";
else if (reloced_arg1_size==32)
ptr="ST_U32_REGS";
else if (reloced_arg1_size==64)
ptr="ST_U64_REGS";
if (ptr)
CatPrint(reloced_arg1_st,DefineSub(RM1,ptr));
}
}
}
switch (arg1) {
case ARGT_IMM8:
case ARGT_UIMM8:
imm=*rip(U8 *)++;
CatPrint(arg1_st,"%02X",imm);
if (tmpins->opcode[0]==0xCD && (ptr=DefineSub(imm,"ST_INT_NAMES")))
CatPrint(arg1_st," %s",ptr);
break;
case ARGT_IMM16:
case ARGT_UIMM16:
CatPrint(arg1_st,"%04X",*rip(U16 *)++);
break;
case ARGT_IMM32:
case ARGT_UIMM32:
CatPrint(arg1_st,"%08X",*rip(U32 *)++);
break;
case ARGT_IMM64:
case ARGT_UIMM64:
CatPrint(arg1_st,"%016X",*rip(I64 *)++);
break;
start:
case ARGT_REL8:
disp=*rip(I8 *)++;
break;
case ARGT_REL16:
disp=*rip(I16 *)++;
break;
case ARGT_REL32:
disp=*rip(I32 *)++;
break;
end:
disp+=rip;
if (IsDbgMode)
CatPrint(arg1_st,"%p ",disp);
else if (PutSrcLink(disp,512,buf2))
CatPrint(arg1_st,"%s ",buf2);
else
CatPrint(arg1_st,"%P ",disp);
if (_jmp_dst) *_jmp_dst=disp;
break;
case ARGT_MOFFS8...ARGT_MOFFS64:
CatPrint(arg1_st,seg_overrides);
if (arg1_size==8)
disp=*rip(U8 *)++;
else if (opadd==16)
disp=*rip(U16 *)++;
else
disp=*rip(U32 *)++;
CatPrint(arg1_st,"[%X]",disp);
break;
case ARGT_AL ... ARGT_DX:
case ARGT_SS ... ARGT_ST0:
CatPrint(arg1_st,"%z",arg1-ARGT_AL,
"AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
break;
case ARGT_STI:
rip--;
CatPrint(arg1_st,"%Z",*rip++ - tmpins->opcode[tmpins->opcode_cnt-1],
"ST_FSTK_REGS");
break;
}
switch (arg2) {
case ARGT_IMM8:
case ARGT_UIMM8:
CatPrint(arg2_st,"%02X",*rip(U8 *)++);
break;
case ARGT_IMM16:
case ARGT_UIMM16:
CatPrint(arg2_st,"%04X",*rip(U16 *)++);
break;
case ARGT_IMM32:
case ARGT_UIMM32:
CatPrint(arg2_st,"%08X",*rip(U32 *)++);
break;
case ARGT_IMM64:
case ARGT_UIMM64:
CatPrint(arg2_st,"%016X",*rip(I64 *)++);
break;
case ARGT_MOFFS8...ARGT_MOFFS64:
CatPrint(arg2_st,seg_overrides);
if (arg2_size==8)
disp=*rip(U8 *)++;
else if (opadd==16)
disp=*rip(U16 *)++;
else
disp=*rip(U32 *)++;
CatPrint(arg2_st,"[%X]",disp);
break;
case ARGT_AL ... ARGT_DX:
case ARGT_SS ... ARGT_ST0:
CatPrint(arg2_st,"%z",arg2-ARGT_AL,
"AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
break;
case ARGT_STI:
rip--;
CatPrint(arg2_st,"%Z",*rip++ -tmpins->opcode[tmpins->opcode_cnt-1],
"ST_FSTK_REGS");
break;
}
if (tmpins->flags&IEF_ENDING_ZERO)
rip++;
if (*arg1_st)
CatPrint(line1,"\t%s",arg1_st);
if (*arg2_st)
CatPrint(line1,",%s",arg2_st);
CatPrint(line1,"\n");
CatPrint(line2,"\n");
if (!just_ins) {
for (i=rip-(*_rip)(I64);i<6;i++) {
bin_data_area1[i<<1]=CH_SPACE;
bin_data_area1[i<<1+1]=CH_SPACE;
}
for (i=rip-(*_rip)(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 && rip-(*_rip)(I64)>6)
CatPrint(buf,line2);
*_rip=rip;
}
U8 *U(U8 *rip,I64 cnt=20,I64 seg_size=64)
{//Unassembles a num of insts.
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,&rip,seg_size);
"%s",buf;
}
"$$HL,0$$";
return rip;
}
I64 Un(U8 *rip,I64 cnt=0x80,I64 seg_size=64)
{//Unassembles a num of bytes
I64 i=0;
U8 buf[1024],*end_rip=rip(I64)+cnt;
if (seg_size==16)
PrintWarn("16-bit unassembly is not well supported.\n");
"$$HL,1$$";
while (rip<end_rip) {
Ui(buf,&rip,seg_size);
"%s",buf;
i++;
}
"$$HL,0$$";
return i;
}