Skip to content

Commit

Permalink
Merge pull request #4904 from WalterBright/moreSETcc
Browse files Browse the repository at this point in the history
more SETcc improvements to backend
  • Loading branch information
MartinNowak committed Aug 18, 2015
2 parents e8d0eb0 + 13ba5ff commit 6125dee
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 42 deletions.
14 changes: 9 additions & 5 deletions src/backend/cgelem.c
Expand Up @@ -4067,6 +4067,7 @@ STATIC elem * elcmp(elem *e, goal_t goal)

STATIC elem * elbool(elem *e, goal_t goal)
{
//printf("elbool()\n");
if (OTlogical(e->E1->Eoper) ||
// bool bool => bool
(tybasic(e->E1->Ety) == TYbool && tysize(e->Ety) == 1)
Expand Down Expand Up @@ -4236,11 +4237,10 @@ STATIC elem * elvptrfptr(elem *e, goal_t goal)
*/

STATIC elem * ellngsht(elem *e, goal_t goal)
{ elem *e1;
tym_t ty;

ty = e->Ety;
e1 = e->E1;
{
//printf("ellngsht()\n");
tym_t ty = e->Ety;
elem *e1 = e->E1;
switch (e1->Eoper)
{ case OPs16_32:
case OPu16_32:
Expand Down Expand Up @@ -4284,6 +4284,10 @@ STATIC elem * ellngsht(elem *e, goal_t goal)
break;
#endif

case OPbtst:
e = el_selecte1(e);
break;

default: /* operator */
case_default:
/* Attempt to replace (lngsht)(a op b) with */
Expand Down
109 changes: 72 additions & 37 deletions src/backend/cod4.c
Expand Up @@ -2373,11 +2373,14 @@ code *cdcmp(elem *e,regm_t *pretregs)
cg = gen2(cg,0x0F90 + (jop & 0x0F),modregrmx(3,0,reg)); // SETcc reg
if (I64 && reg >= 4)
code_orrex(cg,REX);
genregs(cg,0x0FB6,reg,reg); // MOVZX reg,reg
if (I64 && sz == 8)
code_orrex(cg,REX_W);
if (I64 && reg >= 4)
code_orrex(cg,REX);
if (tysize(e->Ety) > 1)
{
genregs(cg,0x0FB6,reg,reg); // MOVZX reg,reg
if (I64 && sz == 8)
code_orrex(cg,REX_W);
if (I64 && reg >= 4)
code_orrex(cg,REX);
}
*pretregs &= ~mPSW;
c = cat3(c,cg,fixresult(e,resregs,pretregs));
}
Expand Down Expand Up @@ -3479,27 +3482,40 @@ code *cdbtst(elem *e, regm_t *pretregs)

if ((retregs = (*pretregs & (ALLREGS | mBP))) != 0) // if return result in register
{
code *nop = CNIL;
regm_t save = regcon.immed.mval;
code *cg = allocreg(&retregs,&reg,TYint);
regcon.immed.mval = save;
if ((*pretregs & mPSW) == 0)
if (tysize(e->Ety) == 1)
{
cg = cat(cg,getregs(retregs));
cg = genregs(cg,0x19,reg,reg); // SBB reg,reg
cg = gen2(cg,0xF7,modregrmx(3,3,reg)); // NEG reg
assert(I64 || retregs & BYTEREGS);
code *cg = allocreg(&retregs,&reg,TYint);
cg = gen2(cg,0x0F92,modregrmx(3,0,reg)); // SETC reg
if (I64 && reg >= 4)
code_orrex(cg, REX);
*pretregs = retregs;
c2 = cat(c2,cg);
}
else
{
cg = movregconst(cg,reg,1,8); // MOV reg,1
nop = gennop(nop);
cg = genjmp(cg,JC,FLcode,(block *) nop); // Jtrue nop
// MOV reg,0
movregconst(cg,reg,0,8);
regcon.immed.mval &= ~mask[reg];
code *nop = CNIL;
regm_t save = regcon.immed.mval;
code *cg = allocreg(&retregs,&reg,TYint);
regcon.immed.mval = save;
if ((*pretregs & mPSW) == 0)
{
cg = cat(cg,getregs(retregs));
cg = genregs(cg,0x19,reg,reg); // SBB reg,reg
cg = gen2(cg,0xF7,modregrmx(3,3,reg)); // NEG reg
}
else
{
cg = movregconst(cg,reg,1,8); // MOV reg,1
nop = gennop(nop);
cg = genjmp(cg,JC,FLcode,(block *) nop); // Jtrue nop
// MOV reg,0
movregconst(cg,reg,0,8);
regcon.immed.mval &= ~mask[reg];
}
*pretregs = retregs;
c2 = cat3(c2,cg,nop);
}
*pretregs = retregs;
c2 = cat3(c2,cg,nop);
}

return cat(c,c2);
Expand All @@ -3511,6 +3527,8 @@ code *cdbtst(elem *e, regm_t *pretregs)

code *cdbt(elem *e, regm_t *pretregs)
{
//printf("cdbt(%p, %s)\n", e, regm_str(*pretregs));

elem *e1;
elem *e2;
code *c;
Expand Down Expand Up @@ -3586,27 +3604,40 @@ code *cdbt(elem *e, regm_t *pretregs)

if ((retregs = (*pretregs & (ALLREGS | mBP))) != 0) // if return result in register
{
code *nop = CNIL;
regm_t save = regcon.immed.mval;
code *cg = allocreg(&retregs,&reg,TYint);
regcon.immed.mval = save;
if ((*pretregs & mPSW) == 0)
if (tysize[e->Ety] == 1)
{
cg = cat(cg,getregs(retregs));
cg = genregs(cg,0x19,reg,reg); // SBB reg,reg
cg = gen2(cg,0xF7,modregrmx(3,3,reg)); // NEG reg
assert(I64 || retregs & BYTEREGS);
code *cg = allocreg(&retregs,&reg,TYint);
cg = gen2(cg,0x0F92,modregrmx(3,0,reg)); // SETC reg
if (I64 && reg >= 4)
code_orrex(cg, REX);
*pretregs = retregs;
c2 = cat(c2,cg);
}
else
{
cg = movregconst(cg,reg,1,8); // MOV reg,1
nop = gennop(nop);
cg = genjmp(cg,JC,FLcode,(block *) nop); // Jtrue nop
// MOV reg,0
movregconst(cg,reg,0,8);
regcon.immed.mval &= ~mask[reg];
code *nop = CNIL;
regm_t save = regcon.immed.mval;
code *cg = allocreg(&retregs,&reg,TYint);
regcon.immed.mval = save;
if ((*pretregs & mPSW) == 0)
{
cg = cat(cg,getregs(retregs));
cg = genregs(cg,0x19,reg,reg); // SBB reg,reg
cg = gen2(cg,0xF7,modregrmx(3,3,reg)); // NEG reg
}
else
{
cg = movregconst(cg,reg,1,8); // MOV reg,1
nop = gennop(nop);
cg = genjmp(cg,JC,FLcode,(block *) nop); // Jtrue nop
// MOV reg,0
movregconst(cg,reg,0,8);
regcon.immed.mval &= ~mask[reg];
}
*pretregs = retregs;
c2 = cat3(c2,cg,nop);
}
*pretregs = retregs;
c2 = cat3(c2,cg,nop);
}

return cat(c,c2);
Expand Down Expand Up @@ -3837,9 +3868,13 @@ code *cdcmpxchg(elem *e, regm_t *pretregs)
regm_t retregs;
if ((retregs = (*pretregs & (ALLREGS | mBP))) != 0) // if return result in register
{
assert(tysize(e->Ety) == 1);
assert(I64 || retregs & BYTEREGS);
unsigned reg;
code *cg = allocreg(&retregs,&reg,TYint);
cg = gen2(cg,0x0F94,modregrmx(3,0,reg)); // SETZ reg
if (I64 && reg >= 4)
code_orrex(cg, REX);
*pretregs = retregs;
c = cat(c,cg);
}
Expand Down

0 comments on commit 6125dee

Please sign in to comment.