Reformat OptPass3.CC

This commit is contained in:
TomAwezome 2020-07-25 19:00:42 -05:00 committed by VoidNV
parent 780974b6e1
commit 7f6c288b3f
3 changed files with 336 additions and 288 deletions

View file

@ -1,146 +1,165 @@
U0 OptPass3(CCompCtrl *cc,COptReg *reg_offsets) U0 OptPass3(CCompCtrl *cc, COptReg *reg_offsets)
{ {
CHashClass *tmpc,*tmpc1,*tmpc2; CHashClass *tmpc, *tmpc1, *tmpc2;
CCodeMisc *lb; CCodeMisc *lb;
CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpi_next, CIntermediateCode *tmpi,*tmpi1, *tmpi2, *tmpi_next, *tmpil1, *tmpil2;
*tmpil1,*tmpil2; I64 code, i, j, l, member_count, used_reg_mask = 0;
I64 code,i,j,l,member_count,used_reg_mask=0;
CMemberList *tmpm; CMemberList *tmpm;
COptMemberVar *mv=NULL; COptMemberVar *mv = NULL;
CAOT *tmpaot; CAOT *tmpaot;
CAOTImportExport *tmpie; CAOTImportExport *tmpie;
CParseStack *ps=cc->ps; CParseStack *ps = cc->ps;
ps->ptr=0; ps->ptr = 0;
ps->ptr2=0; ps->ptr2 = 0;
for (i=0;i<REG_REGS_NUM;i++) { for (i = 0; i < REG_REGS_NUM; i++)
reg_offsets[i].offset=I64_MAX; {
reg_offsets[i].m=NULL; reg_offsets[i].offset = I64_MAX;
reg_offsets[i].m = NULL;
} }
if (cc->htc.fun) { if (cc->htc.fun)
member_count=cc->htc.fun->member_count; {
if (Bt(&cc->htc.fun->flags,Ff_DOT_DOT_DOT)) member_count = cc->htc.fun->member_count;
member_count+=2; if (Bt(&cc->htc.fun->flags, Ff_DOT_DOT_DOT))
mv=CAlloc(member_count*sizeof(COptMemberVar)); member_count += 2;
member_count=0; mv = CAlloc(member_count * sizeof(COptMemberVar));
tmpm=cc->htc.fun->member_list_and_root; member_count = 0;
while (tmpm) { tmpm = cc->htc.fun->member_list_and_root;
tmpc=OptClassFwd(tmpm->member_class); while (tmpm)
if (0<=tmpm->reg<REG_REGS_NUM) { {
if (Bts(&used_reg_mask,tmpm->reg)) 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", PrintWarn("Reg in use\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stack->full_name, cc->lex_include_stack->full_name,
cc->lex_include_stack->line_num,tmpm->str,cc->htc.fun->str); cc->lex_include_stack->line_num, tmpm->str, cc->htc.fun->str);
reg_offsets[tmpm->reg].offset=tmpm->offset; reg_offsets[tmpm->reg].offset = tmpm->offset;
reg_offsets[tmpm->reg].m=tmpm; reg_offsets[tmpm->reg].m = tmpm;
} else if (tmpc->raw_type!=RT_F64 && tmpm->reg!=REG_NONE || }
tmpm->reg==REG_ALLOC) { else if (tmpc->raw_type != RT_F64 && tmpm->reg != REG_NONE || tmpm->reg == REG_ALLOC)
if (tmpm->reg==REG_ALLOC) {
mv[member_count].score=I64_MAX/2; //big but not too big if (tmpm->reg == REG_ALLOC)
mv[member_count].offset_start=tmpm->offset; mv[member_count].score = I64_MAX / 2; //big but not too big
mv[member_count].offset_end=tmpm->offset+MaxI64(1,tmpm->size); mv[member_count].offset_start = tmpm->offset;
mv[member_count++].m=tmpm; mv[member_count].offset_end = tmpm->offset + MaxI64(1, tmpm->size);
} else if (tmpm->reg==REG_ALLOC) mv[member_count++].m = tmpm;
}
else if (tmpm->reg == REG_ALLOC)
PrintWarn("Can't reg var\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n", PrintWarn("Can't reg var\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stack->full_name, cc->lex_include_stack->full_name,
cc->lex_include_stack->line_num,tmpm->str,cc->htc.fun->str); cc->lex_include_stack->line_num, tmpm->str, cc->htc.fun->str);
tmpm=tmpm->next; tmpm = tmpm->next;
} }
} else }
member_count=0; else
member_count = 0;
tmpi=cc->coc.coc_head.next; tmpi = cc->coc.coc_head.next;
while (code=tmpi->ic_code) { while (code = tmpi->ic_code)
tmpi_next=tmpi->next; {
if (code==IC_NOP1) tmpi_next = tmpi->next;
if (code == IC_NOP1)
OptFree(tmpi); OptFree(tmpi);
else { else
if (tmpil1=OptLag(tmpi)) { {
if (!(tmpil2=OptLag(tmpil1))) if (tmpil1 = OptLag(tmpi))
tmpil2=&cmp.ic_nop; {
} else if (!(tmpil2 = OptLag(tmpil1)))
tmpil1=tmpil2=&cmp.ic_nop; tmpil2 = &cmp.ic_nop;
tmpc=tmpi->ic_class; }
switch [intermediate_code_table[code].arg_count] { else
tmpil1 = tmpil2 = &cmp.ic_nop;
tmpc = tmpi->ic_class;
switch [intermediate_code_table[code].arg_count]
{
case IS_V_ARG: case IS_V_ARG:
ps->ptr-=tmpi->ic_data>>3; ps->ptr -= tmpi->ic_data >> 3;
break; break;
case IS_2_ARG: case IS_2_ARG:
tmpi2=ParsePop(ps); tmpi2 = ParsePop(ps);
if (tmpi2->ic_flags&ICF_RES_TO_F64) if (tmpi2->ic_flags & ICF_RES_TO_F64)
tmpc2=cmp.internal_types[RT_F64]; tmpc2 = cmp.internal_types[RT_F64];
else if (tmpi2->ic_flags & ICF_RES_TO_INT) else if (tmpi2->ic_flags & ICF_RES_TO_INT)
tmpc2=cmp.internal_types[RT_I64]; tmpc2 = cmp.internal_types[RT_I64];
else else
tmpc2=tmpi->t.arg2_class; tmpc2 = tmpi->t.arg2_class;
tmpi->arg2.type=MDF_STACK+CompRawType(tmpc2); tmpi->arg2.type = MDF_STACK + CompRawType(tmpc2);
tmpi->ic_flags|=ICF_ARG2_WAS_STACK; tmpi->ic_flags |= ICF_ARG2_WAS_STACK;
case IS_1_ARG: case IS_1_ARG:
tmpi1=ParsePop(ps); tmpi1 = ParsePop(ps);
if (tmpi1->ic_flags&ICF_RES_TO_F64) if (tmpi1->ic_flags & ICF_RES_TO_F64)
tmpc1=cmp.internal_types[RT_F64]; tmpc1 = cmp.internal_types[RT_F64];
else if (tmpi1->ic_flags & ICF_RES_TO_INT) else if (tmpi1->ic_flags & ICF_RES_TO_INT)
tmpc1=cmp.internal_types[RT_I64]; tmpc1 = cmp.internal_types[RT_I64];
else else
tmpc1=tmpi->t.arg1_class; tmpc1 = tmpi->t.arg1_class;
tmpi->arg1.type=MDF_STACK+CompRawType(tmpc1); tmpi->arg1.type = MDF_STACK + CompRawType(tmpc1);
tmpi->arg1_type_pointed_to=CompRawTypePointed(tmpc1); tmpi->arg1_type_pointed_to = CompRawTypePointed(tmpc1);
tmpi->ic_flags|=ICF_ARG1_WAS_STACK; tmpi->ic_flags |= ICF_ARG1_WAS_STACK;
break; break;
case IS_0_ARG: //nobound switch case IS_0_ARG: //nobound switch
break; break;
} }
if (intermediate_code_table[code].res_count) { if (intermediate_code_table[code].res_count)
tmpi->res.type=MDF_STACK+CompRawType(tmpc); {
tmpi->ic_flags|=ICF_RES_WAS_STACK; tmpi->res.type = MDF_STACK + CompRawType(tmpc);
ParsePush(ps,tmpi); tmpi->ic_flags |= ICF_RES_WAS_STACK;
ParsePush(ps, tmpi);
} }
switch [code] { switch [code]
{
case IC_IMM_F64: case IC_IMM_F64:
tmpi->ic_flags&=~ICF_RES_TO_F64; tmpi->ic_flags &= ~ICF_RES_TO_F64;
if (tmpi->ic_flags&ICF_RES_TO_INT) { 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_data = ToI64(tmpi->ic_data(F64));
tmpi->ic_code=IC_IMM_I64; tmpi->ic_flags &= ~ICF_RES_TO_INT;
tmpi->ic_code = IC_IMM_I64;
} }
break; break;
case IC_IMM_I64: case IC_IMM_I64:
tmpi->ic_flags&=~ICF_RES_TO_INT; tmpi->ic_flags &= ~ICF_RES_TO_INT;
if (tmpi->ic_flags&ICF_RES_TO_F64) { 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_data(F64) = ToF64(tmpi->ic_data);
tmpi->ic_code=IC_IMM_F64; tmpi->ic_flags &= ~ICF_RES_TO_F64;
tmpi->ic_code = IC_IMM_F64;
} }
break; break;
case IC_RBP: case IC_RBP:
tmpi->ic_code=IC_REG; tmpi->ic_code = IC_REG;
tmpi->arg1.reg=REG_RBP; tmpi->arg1.reg = REG_RBP;
break; break;
case IC_DEREF: case IC_DEREF:
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type; tmpi->arg1_type_pointed_to = tmpi->res.type.raw_type;
if (tmpi1->ic_code==IC_LEA) { if (tmpi1->ic_code == IC_LEA)
tmpi->ic_flags|=tmpi1->ic_flags; {
tmpi->arg1.reg=tmpi1->arg1.reg; tmpi->ic_flags |= tmpi1->ic_flags;
tmpi->arg1.disp=tmpi1->arg1.disp; tmpi->arg1.reg = tmpi1->arg1.reg;
tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type; tmpi->arg1.disp = tmpi1->arg1.disp;
tmpi->arg1_type_pointed_to=CompRawTypePointed(tmpc); tmpi->arg1.type = MDF_DISP + tmpi->res.type.raw_type;
tmpi->ic_code=IC_MOV; tmpi->arg1_type_pointed_to = CompRawTypePointed(tmpc);
tmpi->ic_code = IC_MOV;
OptFree(tmpi1); OptFree(tmpi1);
if (tmpi->arg1.reg==REG_RBP) if (tmpi->arg1.reg == REG_RBP)
for (i=0;i<member_count;i++) for (i = 0; i < member_count; i++)
if (mv[i].offset_start==tmpi->arg1.disp) { if (mv[i].offset_start == tmpi->arg1.disp)
{
mv[i].lea_balance--; mv[i].lea_balance--;
mv[i].score++; mv[i].score++;
break; break;
} }
} else if (tmpil1->ic_code==IC_ADD_CONST) { }
if (tmpil2->ic_code==IC_REG) { else if (tmpil1->ic_code == IC_ADD_CONST)
tmpi->ic_flags|=tmpil2->ic_flags|tmpil1->ic_flags; {
tmpi->arg1.reg=tmpil2->arg1.reg; if (tmpil2->ic_code == IC_REG) {
tmpi->arg1.disp=tmpi->ic_data; tmpi->ic_flags |= tmpil2->ic_flags | tmpil1->ic_flags;
tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type; tmpi->arg1.reg = tmpil2->arg1.reg;
tmpi->arg1_type_pointed_to=CompRawTypePointed(tmpc); tmpi->arg1.disp = tmpi->ic_data;
tmpi->ic_code=IC_MOV; tmpi->arg1.type = MDF_DISP + tmpi->res.type.raw_type;
tmpi->arg1_type_pointed_to = CompRawTypePointed(tmpc);
tmpi->ic_code = IC_MOV;
OptFree(tmpil2); OptFree(tmpil2);
OptFree(tmpil1); OptFree(tmpil1);
} }
@ -150,48 +169,53 @@ U0 OptPass3(CCompCtrl *cc,COptReg *reg_offsets)
case IC__MM: case IC__MM:
case IC_PP_: case IC_PP_:
case IC_MM_: case IC_MM_:
CompMinTypePointed(tmpi,CompRawTypePointed(tmpi->t.arg1_class)); CompMinTypePointed(tmpi, CompRawTypePointed(tmpi->t.arg1_class));
case IC_DEREF_PP: case IC_DEREF_PP:
case IC_DEREF_MM: case IC_DEREF_MM:
if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP && if (tmpi1->ic_code == IC_LEA && tmpi1->arg1.type & MDF_DISP && tmpi1->arg1.reg == REG_RBP)
tmpi1->arg1.reg==REG_RBP) for (i = 0; i < member_count; i++)
for (i=0;i<member_count;i++) if (mv[i].offset_start == tmpi1->arg1.disp)
if (mv[i].offset_start==tmpi1->arg1.disp) { {
mv[i].lea_balance--; mv[i].lea_balance--;
mv[i].score++; mv[i].score++;
break; break;
} }
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type; tmpi->arg1_type_pointed_to = tmpi->res.type.raw_type;
break; break;
case IC_MUL: case IC_MUL:
case IC_DIV: case IC_DIV:
if (tmpc->raw_type==RT_F64) { if (tmpc->raw_type == RT_F64)
CompF2PushPop(tmpi,tmpi1,tmpi2); {
CompF2PushPop(tmpi, tmpi1, tmpi2);
break; break;
} }
break; break;
case IC_ADD: case IC_ADD:
if (tmpc->raw_type==RT_F64) { if (tmpc->raw_type == RT_F64)
CompF2PushPop(tmpi,tmpi1,tmpi2); {
CompF2PushPop(tmpi, tmpi1, tmpi2);
break; break;
} }
if (OptFixupBinaryOp2(&tmpi1,&tmpi2)) { if (OptFixupBinaryOp2(&tmpi1, &tmpi2))
tmpi->ic_flags|=tmpi1->ic_flags; {
if (tmpi->t.arg1_tree!=tmpi2) tmpi->ic_flags |= tmpi1->ic_flags;
tmpi->t.arg1_class=tmpi->t.arg2_class; if (tmpi->t.arg1_tree != tmpi2)
tmpi->ic_data=tmpi1->ic_data; tmpi->t.arg1_class = tmpi->t.arg2_class;
tmpi->ic_code=IC_ADD_CONST; tmpi->ic_data = tmpi1->ic_data;
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type; tmpi->ic_code = IC_ADD_CONST;
tmpi->arg2.type=MDF_NULL; tmpi->arg1_type_pointed_to = tmpi->res.type.raw_type;
tmpi->arg2.type = MDF_NULL;
OptFree(tmpi1); OptFree(tmpi1);
if (tmpil2->ic_code==IC_REG && tmpil2->arg1.reg==REG_RBP) { if (tmpil2->ic_code == IC_REG && tmpil2->arg1.reg == REG_RBP)
tmpi->ic_flags|=tmpil2->ic_flags; {
tmpi->ic_code=IC_LEA; tmpi->ic_flags |= tmpil2->ic_flags;
tmpi->arg1.reg=REG_RBP; tmpi->ic_code = IC_LEA;
tmpi->arg1.type=MDF_DISP+tmpi->arg1.type.raw_type; tmpi->arg1.reg = REG_RBP;
tmpi->arg1.disp=tmpi->ic_data; tmpi->arg1.type = MDF_DISP + tmpi->arg1.type.raw_type;
for (i=0;i<member_count;i++) tmpi->arg1.disp = tmpi->ic_data;
if (mv[i].offset_start<=tmpi->ic_data<mv[i].offset_end) { for (i = 0; i < member_count; i++)
if (mv[i].offset_start <= tmpi->ic_data < mv[i].offset_end)
{
mv[i].lea_balance++; mv[i].lea_balance++;
mv[i].score++; mv[i].score++;
break; break;
@ -201,15 +225,17 @@ U0 OptPass3(CCompCtrl *cc,COptReg *reg_offsets)
} }
break; break;
case IC_SUB: case IC_SUB:
if (tmpc->raw_type==RT_F64) { if (tmpc->raw_type == RT_F64)
CompF2PushPop(tmpi,tmpi1,tmpi2); {
CompF2PushPop(tmpi, tmpi1, tmpi2);
break; break;
} }
if (tmpi2->ic_code==IC_IMM_I64) { if (tmpi2->ic_code == IC_IMM_I64)
tmpi->ic_flags|=tmpi2->ic_flags; {
tmpi->ic_data=tmpi2->ic_data; tmpi->ic_flags |= tmpi2->ic_flags;
tmpi->ic_code=IC_SUB_CONST; tmpi->ic_data = tmpi2->ic_data;
tmpi->arg2.type=MDF_NULL; tmpi->ic_code = IC_SUB_CONST;
tmpi->arg2.type = MDF_NULL;
OptFree(tmpi2); OptFree(tmpi2);
} }
break; break;
@ -217,15 +243,15 @@ U0 OptPass3(CCompCtrl *cc,COptReg *reg_offsets)
case IC_GREATER_EQU: case IC_GREATER_EQU:
case IC_GREATER: case IC_GREATER:
case IC_LESS_EQU: case IC_LESS_EQU:
if (tmpi->ic_flags&ICF_USE_F64) if (tmpi->ic_flags & ICF_USE_F64)
CompF2PushPop(tmpi,tmpi1,tmpi2); CompF2PushPop(tmpi, tmpi1, tmpi2);
break; break;
case IC_MUL_EQU: case IC_MUL_EQU:
case IC_DIV_EQU: case IC_DIV_EQU:
case IC_ADD_EQU: case IC_ADD_EQU:
case IC_SUB_EQU: case IC_SUB_EQU:
if (tmpc->raw_type==RT_F64) if (tmpc->raw_type == RT_F64)
CompF1PushPop(tmpi,tmpi2); CompF1PushPop(tmpi, tmpi2);
case IC_ASSIGN_PP: case IC_ASSIGN_PP:
case IC_ASSIGN_MM: case IC_ASSIGN_MM:
case IC_ASSIGN: case IC_ASSIGN:
@ -235,25 +261,25 @@ U0 OptPass3(CCompCtrl *cc,COptReg *reg_offsets)
case IC_AND_EQU: case IC_AND_EQU:
case IC_OR_EQU: case IC_OR_EQU:
case IC_XOR_EQU: case IC_XOR_EQU:
if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP && if (tmpi1->ic_code == IC_LEA && tmpi1->arg1.type & MDF_DISP && tmpi1->arg1.reg == REG_RBP)
tmpi1->arg1.reg==REG_RBP) for (i = 0; i < member_count; i++)
for (i=0;i<member_count;i++) if (mv[i].offset_start == tmpi1->arg1.disp)
if (mv[i].offset_start==tmpi1->arg1.disp) { {
mv[i].lea_balance--; mv[i].lea_balance--;
mv[i].score++; mv[i].score++;
break; break;
} }
tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type; tmpi->arg1_type_pointed_to = tmpi->res.type.raw_type;
CompMinTypePointed(tmpi,CompRawTypePointed(tmpi->t.arg1_class)); CompMinTypePointed(tmpi, CompRawTypePointed(tmpi->t.arg1_class));
break; break;
case IC_RETURN_VAL: case IC_RETURN_VAL:
case IC_RETURN_VAL2: case IC_RETURN_VAL2:
if (tmpc) { if (tmpc)
if (tmpc->raw_type==RT_F64 && tmpil1->ic_class->raw_type!=RT_F64) {
tmpil1->ic_flags|=ICF_RES_TO_F64; if (tmpc->raw_type == RT_F64 && tmpil1->ic_class->raw_type != RT_F64)
else if (tmpc->raw_type!=RT_F64 && tmpil1->ic_flags |= ICF_RES_TO_F64;
tmpil1->ic_class->raw_type==RT_F64) else if (tmpc->raw_type != RT_F64 && tmpil1->ic_class->raw_type == RT_F64)
tmpil1->ic_flags|=ICF_RES_TO_INT; tmpil1->ic_flags |= ICF_RES_TO_INT;
} }
break; break;
case IC_SQR: case IC_SQR:
@ -263,118 +289,132 @@ U0 OptPass3(CCompCtrl *cc,COptReg *reg_offsets)
case IC_COS: case IC_COS:
case IC_TAN: case IC_TAN:
case IC_ATAN: case IC_ATAN:
if (tmpc->raw_type==RT_F64) if (tmpc->raw_type == RT_F64)
CompF1PushPop(tmpi,tmpi1); CompF1PushPop(tmpi, tmpi1);
break; break;
case IC_NOBOUND_SWITCH: case IC_NOBOUND_SWITCH:
case IC_SWITCH: case IC_SWITCH:
lb=OptLabelFwd(tmpi->ic_data(CCodeMisc *)->default); lb = OptLabelFwd(tmpi->ic_data(CCodeMisc *)->default);
lb->use_count++; lb->use_count++;
break; break;
case IC_ASM: case IC_ASM:
tmpaot=tmpi->ic_data; tmpaot = tmpi->ic_data;
tmpie=tmpaot->next_ie; tmpie = tmpaot->next_ie;
while (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 && if (IET_REL_I0 <= tmpie->type <= IET_IMM_I64 && tmpie->str && tmpie->flags & IEF_GOTO_LABEL &&
(lb=COCGoToLabelFind(cc,tmpie->str))) (lb = COCGoToLabelFind(cc, tmpie->str)))
lb->use_count++; //Prevent deadcode elimination. lb->use_count++; //Prevent deadcode elimination.
tmpie=tmpie->next; tmpie = tmpie->next;
} }
break; break;
case IC_BR_NOT_EQU: case IC_BR_NOT_EQU:
case IC_BR_EQU_EQU: case IC_BR_EQU_EQU:
if ((tmpi1->ic_code==IC_IMM_I64 || if ((tmpi1->ic_code == IC_IMM_I64 || tmpi1->ic_code == IC_IMM_F64) && !tmpi1->ic_data)
tmpi1->ic_code==IC_IMM_F64) && !tmpi1->ic_data) { {
OptFree(tmpi1); OptFree(tmpi1);
MemCopy(&tmpi->arg1,&tmpi->arg2,sizeof(CICArg)); MemCopy(&tmpi->arg1, &tmpi->arg2, sizeof(CICArg));
tmpi->arg2.type=MDF_NULL; tmpi->arg2.type = MDF_NULL;
if (code==IC_BR_EQU_EQU) if (code == IC_BR_EQU_EQU)
code=tmpi->ic_code=IC_BR_ZERO; code = tmpi->ic_code = IC_BR_ZERO;
else else
code=tmpi->ic_code=IC_BR_NOT_ZERO; code = tmpi->ic_code = IC_BR_NOT_ZERO;
tmpi1=tmpi2; tmpi1 = tmpi2;
tmpc1=tmpc2; tmpc1 = tmpc2;
} else if ((tmpi2->ic_code==IC_IMM_I64 || }
tmpi2->ic_code==IC_IMM_F64) && !tmpi2->ic_data) { else if ((tmpi2->ic_code == IC_IMM_I64 || tmpi2->ic_code == IC_IMM_F64) && !tmpi2->ic_data)
{
OptFree(tmpi2); OptFree(tmpi2);
tmpi->arg2.type=MDF_NULL; tmpi->arg2.type = MDF_NULL;
if (code==IC_BR_EQU_EQU) if (code == IC_BR_EQU_EQU)
code=tmpi->ic_code=IC_BR_ZERO; code = tmpi->ic_code = IC_BR_ZERO;
else else
code=tmpi->ic_code=IC_BR_NOT_ZERO; code = tmpi->ic_code = IC_BR_NOT_ZERO;
} else }
else
goto here1; goto here1;
case IC_BR_ZERO: case IC_BR_ZERO:
case IC_BR_NOT_ZERO: case IC_BR_NOT_ZERO:
if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) { if (tmpi1->ic_code == IC_IMM_I64 || tmpi1->ic_code == IC_IMM_F64)
if (code==IC_BR_ZERO ^^ tmpi1->ic_data) { {
if (code == IC_BR_ZERO ^^ tmpi1->ic_data)
{
OptFree(tmpi1); OptFree(tmpi1);
tmpi->arg1.type=MDF_NULL; tmpi->arg1.type = MDF_NULL;
tmpi->ic_code=IC_JMP; tmpi->ic_code = IC_JMP;
} else { }
else
{
OptFree(tmpi1); OptFree(tmpi1);
tmpi=OptFree(tmpi); tmpi = OptFree(tmpi);
break; break;
} }
} }
goto here1; goto here1;
case IC_BR_AND_ZERO: case IC_BR_AND_ZERO:
if (tmpi1->ic_code==IC_IMM_I64) { if (tmpi1->ic_code == IC_IMM_I64)
i=Bsr(tmpi1->ic_data); {
if (0<=i==Bsf(tmpi1->ic_data)) { i = Bsr(tmpi1->ic_data);
tmpi1->ic_data=i; if (0 <= i == Bsf(tmpi1->ic_data))
tmpi->ic_flags|=ICF_BY_VAL; {
tmpi->ic_code=IC_BR_NOT_BT; tmpi1->ic_data = i;
tmpi->ic_flags |= ICF_BY_VAL;
tmpi->ic_code = IC_BR_NOT_BT;
goto here1; goto here1;
} }
} }
if (tmpi2->ic_code==IC_IMM_I64) { if (tmpi2->ic_code == IC_IMM_I64)
i=Bsr(tmpi2->ic_data); {
if (0<=i==Bsf(tmpi2->ic_data)) { i = Bsr(tmpi2->ic_data);
tmpi2->ic_data=i; if (0 <= i == Bsf(tmpi2->ic_data))
tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL; {
tmpi->ic_code=IC_BR_NOT_BT; tmpi2->ic_data = i;
tmpi->ic_flags |= ICF_SWAP|ICF_BY_VAL;
tmpi->ic_code = IC_BR_NOT_BT;
} }
} }
goto here1; goto here1;
case IC_BR_AND_NOT_ZERO: case IC_BR_AND_NOT_ZERO:
if (tmpi1->ic_code==IC_IMM_I64) { if (tmpi1->ic_code == IC_IMM_I64)
i=Bsr(tmpi1->ic_data); {
if (0<=i==Bsf(tmpi1->ic_data)) { i = Bsr(tmpi1->ic_data);
tmpi1->ic_data=i; if (0 <= i == Bsf(tmpi1->ic_data))
tmpi->ic_flags|=ICF_BY_VAL; {
tmpi->ic_code=IC_BR_BT; tmpi1->ic_data = i;
tmpi->ic_flags |= ICF_BY_VAL;
tmpi->ic_code = IC_BR_BT;
goto here1; goto here1;
} }
} }
if (tmpi2->ic_code==IC_IMM_I64) { if (tmpi2->ic_code == IC_IMM_I64)
i=Bsr(tmpi2->ic_data); {
if (0<=i==Bsf(tmpi2->ic_data)) { i = Bsr(tmpi2->ic_data);
tmpi2->ic_data=i; if (0 <= i == Bsf(tmpi2->ic_data))
tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL; {
tmpi->ic_code=IC_BR_BT; tmpi2->ic_data = i;
tmpi->ic_flags |= ICF_SWAP|ICF_BY_VAL;
tmpi->ic_code = IC_BR_BT;
} }
} }
goto here1; goto here1;
case IC_BR_MM_ZERO: case IC_BR_MM_ZERO:
case IC_BR_MM_NOT_ZERO: case IC_BR_MM_NOT_ZERO:
if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP && if (tmpi1->ic_code == IC_LEA && tmpi1->arg1.type & MDF_DISP && tmpi1->arg1.reg == REG_RBP)
tmpi1->arg1.reg==REG_RBP) for (i = 0; i < member_count; i++)
for (i=0;i<member_count;i++) if (mv[i].offset_start == tmpi1->arg1.disp)
if (mv[i].offset_start==tmpi1->arg1.disp) { {
mv[i].lea_balance--; mv[i].lea_balance--;
mv[i].score++; mv[i].score++;
break; break;
} }
tmpi->arg1_type_pointed_to=CompRawType(tmpc); tmpi->arg1_type_pointed_to = CompRawType(tmpc);
goto here1; goto here1;
case IC_BR_LESS: case IC_BR_LESS:
case IC_BR_GREATER_EQU: case IC_BR_GREATER_EQU:
case IC_BR_GREATER: case IC_BR_GREATER:
case IC_BR_LESS_EQU: case IC_BR_LESS_EQU:
if (tmpi->ic_flags&ICF_USE_F64) if (tmpi->ic_flags & ICF_USE_F64)
CompF2PushPop(tmpi,tmpi1,tmpi2); CompF2PushPop(tmpi, tmpi1, tmpi2);
case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2: case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
case IC_BR_CARRY: case IC_BR_CARRY:
case IC_BR_NOT_CARRY: case IC_BR_NOT_CARRY:
@ -390,17 +430,17 @@ U0 OptPass3(CCompCtrl *cc,COptReg *reg_offsets)
case IC_JMP: case IC_JMP:
case IC_SUB_CALL: case IC_SUB_CALL:
here1: here1:
if (tmpi->ic_flags&ICF_PUSH_CMP) if (tmpi->ic_flags & ICF_PUSH_CMP)
lb=tmpi->ic_data; lb = tmpi->ic_data;
else else
lb=OptLabelFwd(tmpi->ic_data); lb = OptLabelFwd(tmpi->ic_data);
lb->use_count++; lb->use_count++;
break; break;
case IC_NOP1: case IC_NOP1:
tmpi=OptFree(tmpi); tmpi = OptFree(tmpi);
break; break;
case IC_NOP2: case IC_NOP2:
ps->ptr+=tmpi->ic_data; ps->ptr += tmpi->ic_data;
break; break;
case IC_SHL_CONST: case IC_SHL_CONST:
case IC_SHR_CONST: case IC_SHR_CONST:
@ -505,12 +545,12 @@ here1:
case IC_LABEL: case IC_LABEL:
break; break;
default: default:
"Pass:%d Missing IC handler\n",cc->pass; "Pass:%d Missing IC handler\n", cc->pass;
ICPut(cc,tmpi); ICPut(cc, tmpi);
LexExcept(cc,"Compiler Optimization Error at "); LexExcept(cc,"Compiler Optimization Error at ");
} }
} }
tmpi=tmpi_next; tmpi = tmpi_next;
} }
/* REGISTER VARIABLE ASSIGNMENT /* REGISTER VARIABLE ASSIGNMENT
@ -522,92 +562,98 @@ 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 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. 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, 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 RAX and R8 links intermediate codes together. R9 is used for stack machine
temporaries. RBP is used as stack frame. temporaries. RBP is used as stack frame.
RSI,RDI,R10,R11,R12,R13,R14,R15 are used for reg vars. R12 and R13, however, 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 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. R12 and R13 as non-pointer register variables, such as index variables i, j, k.
*/ */
if (cc->htc.fun) { 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; cc->htc.fun->used_reg_mask = cc->htc.fun->used_reg_mask &
if (!Bt(&cc->opts,OPTf_NO_REG_VAR) && ~(REGG_LOCAL_VARS | REGG_LOCAL_NON_PTR_VARS) | used_reg_mask;
!(cc->flags & CCF_NO_REG_OPT)) { if (!Bt(&cc->opts, OPTf_NO_REG_VAR) && !(cc->flags & CCF_NO_REG_OPT))
QuickSort(mv,member_count,sizeof(COptMemberVar),&OptMVCompare); {
while (member_count && !mv[member_count-1].score) QuickSort(mv, member_count, sizeof(COptMemberVar), &OptMVCompare);
while (member_count && !mv[member_count - 1].score)
member_count--; member_count--;
j=0; j = 0;
for (i=0;i<member_count;i++) { for (i = 0; i < member_count; i++)
if (!mv[i].lea_balance && mv[i].offset_start) {//addr operator cancels {
mv[j].m=mv[i].m; if (!mv[i].lea_balance && mv[i].offset_start)
mv[j].offset_start=mv[i].offset_start; {//addr operator cancels
mv[j++].offset_end=mv[i].offset_end; mv[j].m = mv[i].m;
} else { mv[j].offset_start = mv[i].offset_start;
if (mv[i].m->reg==REG_ALLOC) 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", PrintWarn("Can't reg var\n $$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stack->full_name, cc->lex_include_stack->full_name,
cc->lex_include_stack->line_num,mv[i].m->str,cc->htc.fun->str); cc->lex_include_stack->line_num, mv[i].m->str, cc->htc.fun->str);
} }
} }
if (j>0) { if (j > 0)
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT)) {
"Fun:%s\n",cc->htc.fun->str; if (Bt(&cc->flags, CCf_PASS_TRACE_PRESENT))
if (j>cmp.num_reg_vars) { "Fun:%s\n", cc->htc.fun->str;
l=0; if (j > cmp.num_reg_vars)
for (i=0;i<j && l<cmp.num_non_ptr_vars;i++) { {
tmpm=mv[i].m; l = 0;
tmpc=OptClassFwd(tmpm->member_class); for (i = 0; i < j && l < cmp.num_non_ptr_vars; i++)
if (!tmpc->ptr_stars_count && !tmpm->dim.next) { {
while (l<cmp.num_non_ptr_vars && tmpm = mv[i].m;
Bts(&cc->htc.fun->used_reg_mask,cmp.non_ptr_vars_map[l])) tmpc = OptClassFwd(tmpm->member_class);
if (!tmpc->ptr_stars_count && !tmpm->dim.next)
{
while (l < cmp.num_non_ptr_vars && Bts(&cc->htc.fun->used_reg_mask, cmp.non_ptr_vars_map[l]))
l++; l++;
if (l<cmp.num_non_ptr_vars) { if (l < cmp.num_non_ptr_vars)
tmpm->reg=cmp.non_ptr_vars_map[l++]; {
reg_offsets[tmpm->reg].offset=mv[i].offset_start; tmpm->reg = cmp.non_ptr_vars_map[l++];
reg_offsets[tmpm->reg].m=tmpm; reg_offsets[tmpm->reg].offset = mv[i].offset_start;
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT)) reg_offsets[tmpm->reg].m = tmpm;
"Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS", if (Bt(&cc->flags, CCf_PASS_TRACE_PRESENT))
tmpm->str,reg_offsets[tmpm->reg].offset; "Reg %Z Var \"%-15ts\" %016X[RBP]\n", tmpm->reg, "ST_U64_REGS",
mv[i].offset_start=0; //flag as reg var tmpm->str, reg_offsets[tmpm->reg].offset;
if (tmpm->size<8 && mv[i].offset_start = 0; //flag as reg var
!StrIMatch("Bool",tmpm->member_class->str) && if (tmpm->size < 8 && !StrIMatch("Bool", tmpm->member_class->str) &&
tmpm->member_class->type&HTT_INTERNAL_TYPE) tmpm->member_class->type & HTT_INTERNAL_TYPE)
PrintWarn("Using 64-bit reg var.\n " PrintWarn("Using 64-bit reg var.\n "
"$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n", "$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stack->full_name, cc->lex_include_stack->full_name,
cc->lex_include_stack->line_num, cc->lex_include_stack->line_num, tmpm->str, cc->htc.fun->str);
tmpm->str,cc->htc.fun->str);
} }
} }
} }
} }
l=0; l = 0;
for (i=0;i<j && l<cmp.num_reg_vars;i++) { for (i = 0; i < j && l < cmp.num_reg_vars;i++)
tmpm=mv[i].m; {
tmpm = mv[i].m;
//if not just flagged as reg var //if not just flagged as reg var
if (mv[i].offset_start && (!mv[i].m->dim.next|| if (mv[i].offset_start && (!mv[i].m->dim.next || tmpm->offset > 0 && StrCompare(tmpm->str, "argv")))
tmpm->offset>0 && StrCompare(tmpm->str,"argv"))) { {
while (l<cmp.num_reg_vars && while (l < cmp.num_reg_vars && Bts(&cc->htc.fun->used_reg_mask, cmp.to_reg_vars_map[l]))
Bts(&cc->htc.fun->used_reg_mask,cmp.to_reg_vars_map[l]))
l++; l++;
if (l<cmp.num_reg_vars) { if (l < cmp.num_reg_vars)
tmpm->reg=cmp.to_reg_vars_map[l++]; {
reg_offsets[tmpm->reg].offset=mv[i].offset_start; tmpm->reg = cmp.to_reg_vars_map[l++];
reg_offsets[tmpm->reg].m=tmpm; reg_offsets[tmpm->reg].offset = mv[i].offset_start;
if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT)) 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", "Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS",
tmpm->str,reg_offsets[tmpm->reg].offset; tmpm->str, reg_offsets[tmpm->reg].offset;
if (tmpm->size<8 && if (tmpm->size < 8 && !StrIMatch("Bool", tmpm->member_class->str) &&
!StrIMatch("Bool",tmpm->member_class->str) && tmpm->member_class->type & HTT_INTERNAL_TYPE)
tmpm->member_class->type&HTT_INTERNAL_TYPE)
PrintWarn("Using 64-bit reg var.\n " PrintWarn("Using 64-bit reg var.\n "
"$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n", "$$LK,\"FL:%s,%d\"$$ '%s' in '%s'\n",
cc->lex_include_stack->full_name, cc->lex_include_stack->full_name,
cc->lex_include_stack->line_num, cc->lex_include_stack->line_num, tmpm->str, cc->htc.fun->str);
tmpm->str,cc->htc.fun->str);
} }
} }
} }
@ -615,9 +661,10 @@ R12 and R13 as non-pointer register variables, such as index variables i,j,k.
} }
Free(mv); Free(mv);
} }
if (ps->ptr>2) { if (ps->ptr > 2)
"Pass:%d Stack:%08X\n",cc->pass,ps->ptr; {
LexExcept(cc,"Compiler Optimization Error at "); "Pass:%d Stack:%08X\n", cc->pass, ps->ptr;
LexExcept(cc, "Compiler Optimization Error at ");
} }
} }

View file

@ -57,6 +57,7 @@ StartOS.CC
LexLib.CC LexLib.CC
OptLib.CC OptLib.CC
OptPass012.CC OptPass012.CC
OptPass3.CC
OpCodes.DD OpCodes.DD
CompilerA.HH CompilerA.HH
CompilerB.HH CompilerB.HH